diff options
Diffstat (limited to 'target/linux/octeon/patches-2.6.30')
20 files changed, 0 insertions, 63769 deletions
diff --git a/target/linux/octeon/patches-2.6.30/001-handle_removal_h_constraint.patch b/target/linux/octeon/patches-2.6.30/001-handle_removal_h_constraint.patch deleted file mode 100644 index ea19508ce7..0000000000 --- a/target/linux/octeon/patches-2.6.30/001-handle_removal_h_constraint.patch +++ /dev/null @@ -1,25 +0,0 @@ -This is an incomplete proof of concept that I applied to be able to -build a 64 bit kernel with GCC-4.4. It doesn't handle the 32 bit case -or the R4000_WAR case. - -Comments welcome. - -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - arch/mips/include/asm/compiler.h | 7 +++++++ - 2 files changed, 11 insertions(+), 0 deletions(-) - ---- a/arch/mips/include/asm/compiler.h -+++ b/arch/mips/include/asm/compiler.h -@@ -16,4 +16,11 @@ - #define GCC_REG_ACCUM "accum" - #endif - -+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) -+#define GCC_NO_H_CONSTRAINT -+#ifdef CONFIG_64BIT -+typedef unsigned int uint128_t __attribute__((mode(TI))); -+#endif -+#endif -+ - #endif /* _ASM_COMPILER_H */ diff --git a/target/linux/octeon/patches-2.6.30/002-register_defs_pci.patch b/target/linux/octeon/patches-2.6.30/002-register_defs_pci.patch deleted file mode 100644 index 85a910dd94..0000000000 --- a/target/linux/octeon/patches-2.6.30/002-register_defs_pci.patch +++ /dev/null @@ -1,9383 +0,0 @@ -Here we add the register definitions for the processor blocks used by -the following PCI support patch. - -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - arch/mips/include/asm/octeon/cvmx-npei-defs.h | 2560 ++++++++++++++++++++++ - arch/mips/include/asm/octeon/cvmx-npi-defs.h | 1735 +++++++++++++++ - arch/mips/include/asm/octeon/cvmx-pci-defs.h | 1645 ++++++++++++++ - arch/mips/include/asm/octeon/cvmx-pcieep-defs.h | 1365 ++++++++++++ - arch/mips/include/asm/octeon/cvmx-pciercx-defs.h | 1397 ++++++++++++ - arch/mips/include/asm/octeon/cvmx-pescx-defs.h | 410 ++++ - arch/mips/include/asm/octeon/cvmx-pexp-defs.h | 229 ++ - 7 files changed, 9341 insertions(+), 0 deletions(-) - create mode 100644 arch/mips/include/asm/octeon/cvmx-npei-defs.h - create mode 100644 arch/mips/include/asm/octeon/cvmx-npi-defs.h - create mode 100644 arch/mips/include/asm/octeon/cvmx-pci-defs.h - create mode 100644 arch/mips/include/asm/octeon/cvmx-pcieep-defs.h - create mode 100644 arch/mips/include/asm/octeon/cvmx-pciercx-defs.h - create mode 100644 arch/mips/include/asm/octeon/cvmx-pescx-defs.h - create mode 100644 arch/mips/include/asm/octeon/cvmx-pexp-defs.h - ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-npei-defs.h -@@ -0,0 +1,2560 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_NPEI_DEFS_H__ -+#define __CVMX_NPEI_DEFS_H__ -+ -+#define CVMX_NPEI_BAR1_INDEXX(offset) \ -+ (0x0000000000000000ull + (((offset) & 31) * 16)) -+#define CVMX_NPEI_BIST_STATUS \ -+ (0x0000000000000580ull) -+#define CVMX_NPEI_BIST_STATUS2 \ -+ (0x0000000000000680ull) -+#define CVMX_NPEI_CTL_PORT0 \ -+ (0x0000000000000250ull) -+#define CVMX_NPEI_CTL_PORT1 \ -+ (0x0000000000000260ull) -+#define CVMX_NPEI_CTL_STATUS \ -+ (0x0000000000000570ull) -+#define CVMX_NPEI_CTL_STATUS2 \ -+ (0x0000000000003C00ull) -+#define CVMX_NPEI_DATA_OUT_CNT \ -+ (0x00000000000005F0ull) -+#define CVMX_NPEI_DBG_DATA \ -+ (0x0000000000000510ull) -+#define CVMX_NPEI_DBG_SELECT \ -+ (0x0000000000000500ull) -+#define CVMX_NPEI_DMA0_INT_LEVEL \ -+ (0x00000000000005C0ull) -+#define CVMX_NPEI_DMA1_INT_LEVEL \ -+ (0x00000000000005D0ull) -+#define CVMX_NPEI_DMAX_COUNTS(offset) \ -+ (0x0000000000000450ull + (((offset) & 7) * 16)) -+#define CVMX_NPEI_DMAX_DBELL(offset) \ -+ (0x00000000000003B0ull + (((offset) & 7) * 16)) -+#define CVMX_NPEI_DMAX_IBUFF_SADDR(offset) \ -+ (0x0000000000000400ull + (((offset) & 7) * 16)) -+#define CVMX_NPEI_DMAX_NADDR(offset) \ -+ (0x00000000000004A0ull + (((offset) & 7) * 16)) -+#define CVMX_NPEI_DMA_CNTS \ -+ (0x00000000000005E0ull) -+#define CVMX_NPEI_DMA_CONTROL \ -+ (0x00000000000003A0ull) -+#define CVMX_NPEI_INT_A_ENB \ -+ (0x0000000000000560ull) -+#define CVMX_NPEI_INT_A_ENB2 \ -+ (0x0000000000003CE0ull) -+#define CVMX_NPEI_INT_A_SUM \ -+ (0x0000000000000550ull) -+#define CVMX_NPEI_INT_ENB \ -+ (0x0000000000000540ull) -+#define CVMX_NPEI_INT_ENB2 \ -+ (0x0000000000003CD0ull) -+#define CVMX_NPEI_INT_INFO \ -+ (0x0000000000000590ull) -+#define CVMX_NPEI_INT_SUM \ -+ (0x0000000000000530ull) -+#define CVMX_NPEI_INT_SUM2 \ -+ (0x0000000000003CC0ull) -+#define CVMX_NPEI_LAST_WIN_RDATA0 \ -+ (0x0000000000000600ull) -+#define CVMX_NPEI_LAST_WIN_RDATA1 \ -+ (0x0000000000000610ull) -+#define CVMX_NPEI_MEM_ACCESS_CTL \ -+ (0x00000000000004F0ull) -+#define CVMX_NPEI_MEM_ACCESS_SUBIDX(offset) \ -+ (0x0000000000000340ull + (((offset) & 31) * 16) - 16 * 12) -+#define CVMX_NPEI_MSI_ENB0 \ -+ (0x0000000000003C50ull) -+#define CVMX_NPEI_MSI_ENB1 \ -+ (0x0000000000003C60ull) -+#define CVMX_NPEI_MSI_ENB2 \ -+ (0x0000000000003C70ull) -+#define CVMX_NPEI_MSI_ENB3 \ -+ (0x0000000000003C80ull) -+#define CVMX_NPEI_MSI_RCV0 \ -+ (0x0000000000003C10ull) -+#define CVMX_NPEI_MSI_RCV1 \ -+ (0x0000000000003C20ull) -+#define CVMX_NPEI_MSI_RCV2 \ -+ (0x0000000000003C30ull) -+#define CVMX_NPEI_MSI_RCV3 \ -+ (0x0000000000003C40ull) -+#define CVMX_NPEI_MSI_RD_MAP \ -+ (0x0000000000003CA0ull) -+#define CVMX_NPEI_MSI_W1C_ENB0 \ -+ (0x0000000000003CF0ull) -+#define CVMX_NPEI_MSI_W1C_ENB1 \ -+ (0x0000000000003D00ull) -+#define CVMX_NPEI_MSI_W1C_ENB2 \ -+ (0x0000000000003D10ull) -+#define CVMX_NPEI_MSI_W1C_ENB3 \ -+ (0x0000000000003D20ull) -+#define CVMX_NPEI_MSI_W1S_ENB0 \ -+ (0x0000000000003D30ull) -+#define CVMX_NPEI_MSI_W1S_ENB1 \ -+ (0x0000000000003D40ull) -+#define CVMX_NPEI_MSI_W1S_ENB2 \ -+ (0x0000000000003D50ull) -+#define CVMX_NPEI_MSI_W1S_ENB3 \ -+ (0x0000000000003D60ull) -+#define CVMX_NPEI_MSI_WR_MAP \ -+ (0x0000000000003C90ull) -+#define CVMX_NPEI_PCIE_CREDIT_CNT \ -+ (0x0000000000003D70ull) -+#define CVMX_NPEI_PCIE_MSI_RCV \ -+ (0x0000000000003CB0ull) -+#define CVMX_NPEI_PCIE_MSI_RCV_B1 \ -+ (0x0000000000000650ull) -+#define CVMX_NPEI_PCIE_MSI_RCV_B2 \ -+ (0x0000000000000660ull) -+#define CVMX_NPEI_PCIE_MSI_RCV_B3 \ -+ (0x0000000000000670ull) -+#define CVMX_NPEI_PKTX_CNTS(offset) \ -+ (0x0000000000002400ull + (((offset) & 31) * 16)) -+#define CVMX_NPEI_PKTX_INSTR_BADDR(offset) \ -+ (0x0000000000002800ull + (((offset) & 31) * 16)) -+#define CVMX_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) \ -+ (0x0000000000002C00ull + (((offset) & 31) * 16)) -+#define CVMX_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) \ -+ (0x0000000000003000ull + (((offset) & 31) * 16)) -+#define CVMX_NPEI_PKTX_INSTR_HEADER(offset) \ -+ (0x0000000000003400ull + (((offset) & 31) * 16)) -+#define CVMX_NPEI_PKTX_IN_BP(offset) \ -+ (0x0000000000003800ull + (((offset) & 31) * 16)) -+#define CVMX_NPEI_PKTX_SLIST_BADDR(offset) \ -+ (0x0000000000001400ull + (((offset) & 31) * 16)) -+#define CVMX_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) \ -+ (0x0000000000001800ull + (((offset) & 31) * 16)) -+#define CVMX_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) \ -+ (0x0000000000001C00ull + (((offset) & 31) * 16)) -+#define CVMX_NPEI_PKT_CNT_INT \ -+ (0x0000000000001110ull) -+#define CVMX_NPEI_PKT_CNT_INT_ENB \ -+ (0x0000000000001130ull) -+#define CVMX_NPEI_PKT_DATA_OUT_ES \ -+ (0x00000000000010B0ull) -+#define CVMX_NPEI_PKT_DATA_OUT_NS \ -+ (0x00000000000010A0ull) -+#define CVMX_NPEI_PKT_DATA_OUT_ROR \ -+ (0x0000000000001090ull) -+#define CVMX_NPEI_PKT_DPADDR \ -+ (0x0000000000001080ull) -+#define CVMX_NPEI_PKT_INPUT_CONTROL \ -+ (0x0000000000001150ull) -+#define CVMX_NPEI_PKT_INSTR_ENB \ -+ (0x0000000000001000ull) -+#define CVMX_NPEI_PKT_INSTR_RD_SIZE \ -+ (0x0000000000001190ull) -+#define CVMX_NPEI_PKT_INSTR_SIZE \ -+ (0x0000000000001020ull) -+#define CVMX_NPEI_PKT_INT_LEVELS \ -+ (0x0000000000001100ull) -+#define CVMX_NPEI_PKT_IN_BP \ -+ (0x00000000000006B0ull) -+#define CVMX_NPEI_PKT_IN_DONEX_CNTS(offset) \ -+ (0x0000000000002000ull + (((offset) & 31) * 16)) -+#define CVMX_NPEI_PKT_IN_INSTR_COUNTS \ -+ (0x00000000000006A0ull) -+#define CVMX_NPEI_PKT_IN_PCIE_PORT \ -+ (0x00000000000011A0ull) -+#define CVMX_NPEI_PKT_IPTR \ -+ (0x0000000000001070ull) -+#define CVMX_NPEI_PKT_OUTPUT_WMARK \ -+ (0x0000000000001160ull) -+#define CVMX_NPEI_PKT_OUT_BMODE \ -+ (0x00000000000010D0ull) -+#define CVMX_NPEI_PKT_OUT_ENB \ -+ (0x0000000000001010ull) -+#define CVMX_NPEI_PKT_PCIE_PORT \ -+ (0x00000000000010E0ull) -+#define CVMX_NPEI_PKT_PORT_IN_RST \ -+ (0x0000000000000690ull) -+#define CVMX_NPEI_PKT_SLIST_ES \ -+ (0x0000000000001050ull) -+#define CVMX_NPEI_PKT_SLIST_ID_SIZE \ -+ (0x0000000000001180ull) -+#define CVMX_NPEI_PKT_SLIST_NS \ -+ (0x0000000000001040ull) -+#define CVMX_NPEI_PKT_SLIST_ROR \ -+ (0x0000000000001030ull) -+#define CVMX_NPEI_PKT_TIME_INT \ -+ (0x0000000000001120ull) -+#define CVMX_NPEI_PKT_TIME_INT_ENB \ -+ (0x0000000000001140ull) -+#define CVMX_NPEI_RSL_INT_BLOCKS \ -+ (0x0000000000000520ull) -+#define CVMX_NPEI_SCRATCH_1 \ -+ (0x0000000000000270ull) -+#define CVMX_NPEI_STATE1 \ -+ (0x0000000000000620ull) -+#define CVMX_NPEI_STATE2 \ -+ (0x0000000000000630ull) -+#define CVMX_NPEI_STATE3 \ -+ (0x0000000000000640ull) -+#define CVMX_NPEI_WINDOW_CTL \ -+ (0x0000000000000380ull) -+#define CVMX_NPEI_WIN_RD_ADDR \ -+ (0x0000000000000210ull) -+#define CVMX_NPEI_WIN_RD_DATA \ -+ (0x0000000000000240ull) -+#define CVMX_NPEI_WIN_WR_ADDR \ -+ (0x0000000000000200ull) -+#define CVMX_NPEI_WIN_WR_DATA \ -+ (0x0000000000000220ull) -+#define CVMX_NPEI_WIN_WR_MASK \ -+ (0x0000000000000230ull) -+ -+union cvmx_npei_bar1_indexx { -+ uint32_t u32; -+ struct cvmx_npei_bar1_indexx_s { -+ uint32_t reserved_18_31:14; -+ uint32_t addr_idx:14; -+ uint32_t ca:1; -+ uint32_t end_swp:2; -+ uint32_t addr_v:1; -+ } s; -+ struct cvmx_npei_bar1_indexx_s cn52xx; -+ struct cvmx_npei_bar1_indexx_s cn52xxp1; -+ struct cvmx_npei_bar1_indexx_s cn56xx; -+ struct cvmx_npei_bar1_indexx_s cn56xxp1; -+}; -+ -+union cvmx_npei_bist_status { -+ uint64_t u64; -+ struct cvmx_npei_bist_status_s { -+ uint64_t pkt_rdf:1; -+ uint64_t pkt_pmem:1; -+ uint64_t pkt_p1:1; -+ uint64_t reserved_60_60:1; -+ uint64_t pcr_gim:1; -+ uint64_t pkt_pif:1; -+ uint64_t pcsr_int:1; -+ uint64_t pcsr_im:1; -+ uint64_t pcsr_cnt:1; -+ uint64_t pcsr_id:1; -+ uint64_t pcsr_sl:1; -+ uint64_t reserved_50_52:3; -+ uint64_t pkt_ind:1; -+ uint64_t pkt_slm:1; -+ uint64_t reserved_36_47:12; -+ uint64_t d0_pst:1; -+ uint64_t d1_pst:1; -+ uint64_t d2_pst:1; -+ uint64_t d3_pst:1; -+ uint64_t reserved_31_31:1; -+ uint64_t n2p0_c:1; -+ uint64_t n2p0_o:1; -+ uint64_t n2p1_c:1; -+ uint64_t n2p1_o:1; -+ uint64_t cpl_p0:1; -+ uint64_t cpl_p1:1; -+ uint64_t p2n1_po:1; -+ uint64_t p2n1_no:1; -+ uint64_t p2n1_co:1; -+ uint64_t p2n0_po:1; -+ uint64_t p2n0_no:1; -+ uint64_t p2n0_co:1; -+ uint64_t p2n0_c0:1; -+ uint64_t p2n0_c1:1; -+ uint64_t p2n0_n:1; -+ uint64_t p2n0_p0:1; -+ uint64_t p2n0_p1:1; -+ uint64_t p2n1_c0:1; -+ uint64_t p2n1_c1:1; -+ uint64_t p2n1_n:1; -+ uint64_t p2n1_p0:1; -+ uint64_t p2n1_p1:1; -+ uint64_t csm0:1; -+ uint64_t csm1:1; -+ uint64_t dif0:1; -+ uint64_t dif1:1; -+ uint64_t dif2:1; -+ uint64_t dif3:1; -+ uint64_t reserved_2_2:1; -+ uint64_t msi:1; -+ uint64_t ncb_cmd:1; -+ } s; -+ struct cvmx_npei_bist_status_cn52xx { -+ uint64_t pkt_rdf:1; -+ uint64_t pkt_pmem:1; -+ uint64_t pkt_p1:1; -+ uint64_t reserved_60_60:1; -+ uint64_t pcr_gim:1; -+ uint64_t pkt_pif:1; -+ uint64_t pcsr_int:1; -+ uint64_t pcsr_im:1; -+ uint64_t pcsr_cnt:1; -+ uint64_t pcsr_id:1; -+ uint64_t pcsr_sl:1; -+ uint64_t pkt_imem:1; -+ uint64_t pkt_pfm:1; -+ uint64_t pkt_pof:1; -+ uint64_t reserved_48_49:2; -+ uint64_t pkt_pop0:1; -+ uint64_t pkt_pop1:1; -+ uint64_t d0_mem:1; -+ uint64_t d1_mem:1; -+ uint64_t d2_mem:1; -+ uint64_t d3_mem:1; -+ uint64_t d4_mem:1; -+ uint64_t ds_mem:1; -+ uint64_t reserved_36_39:4; -+ uint64_t d0_pst:1; -+ uint64_t d1_pst:1; -+ uint64_t d2_pst:1; -+ uint64_t d3_pst:1; -+ uint64_t d4_pst:1; -+ uint64_t n2p0_c:1; -+ uint64_t n2p0_o:1; -+ uint64_t n2p1_c:1; -+ uint64_t n2p1_o:1; -+ uint64_t cpl_p0:1; -+ uint64_t cpl_p1:1; -+ uint64_t p2n1_po:1; -+ uint64_t p2n1_no:1; -+ uint64_t p2n1_co:1; -+ uint64_t p2n0_po:1; -+ uint64_t p2n0_no:1; -+ uint64_t p2n0_co:1; -+ uint64_t p2n0_c0:1; -+ uint64_t p2n0_c1:1; -+ uint64_t p2n0_n:1; -+ uint64_t p2n0_p0:1; -+ uint64_t p2n0_p1:1; -+ uint64_t p2n1_c0:1; -+ uint64_t p2n1_c1:1; -+ uint64_t p2n1_n:1; -+ uint64_t p2n1_p0:1; -+ uint64_t p2n1_p1:1; -+ uint64_t csm0:1; -+ uint64_t csm1:1; -+ uint64_t dif0:1; -+ uint64_t dif1:1; -+ uint64_t dif2:1; -+ uint64_t dif3:1; -+ uint64_t dif4:1; -+ uint64_t msi:1; -+ uint64_t ncb_cmd:1; -+ } cn52xx; -+ struct cvmx_npei_bist_status_cn52xxp1 { -+ uint64_t reserved_46_63:18; -+ uint64_t d0_mem0:1; -+ uint64_t d1_mem1:1; -+ uint64_t d2_mem2:1; -+ uint64_t d3_mem3:1; -+ uint64_t dr0_mem:1; -+ uint64_t d0_mem:1; -+ uint64_t d1_mem:1; -+ uint64_t d2_mem:1; -+ uint64_t d3_mem:1; -+ uint64_t dr1_mem:1; -+ uint64_t d0_pst:1; -+ uint64_t d1_pst:1; -+ uint64_t d2_pst:1; -+ uint64_t d3_pst:1; -+ uint64_t dr2_mem:1; -+ uint64_t n2p0_c:1; -+ uint64_t n2p0_o:1; -+ uint64_t n2p1_c:1; -+ uint64_t n2p1_o:1; -+ uint64_t cpl_p0:1; -+ uint64_t cpl_p1:1; -+ uint64_t p2n1_po:1; -+ uint64_t p2n1_no:1; -+ uint64_t p2n1_co:1; -+ uint64_t p2n0_po:1; -+ uint64_t p2n0_no:1; -+ uint64_t p2n0_co:1; -+ uint64_t p2n0_c0:1; -+ uint64_t p2n0_c1:1; -+ uint64_t p2n0_n:1; -+ uint64_t p2n0_p0:1; -+ uint64_t p2n0_p1:1; -+ uint64_t p2n1_c0:1; -+ uint64_t p2n1_c1:1; -+ uint64_t p2n1_n:1; -+ uint64_t p2n1_p0:1; -+ uint64_t p2n1_p1:1; -+ uint64_t csm0:1; -+ uint64_t csm1:1; -+ uint64_t dif0:1; -+ uint64_t dif1:1; -+ uint64_t dif2:1; -+ uint64_t dif3:1; -+ uint64_t dr3_mem:1; -+ uint64_t msi:1; -+ uint64_t ncb_cmd:1; -+ } cn52xxp1; -+ struct cvmx_npei_bist_status_cn56xx { -+ uint64_t pkt_rdf:1; -+ uint64_t reserved_60_62:3; -+ uint64_t pcr_gim:1; -+ uint64_t pkt_pif:1; -+ uint64_t pcsr_int:1; -+ uint64_t pcsr_im:1; -+ uint64_t pcsr_cnt:1; -+ uint64_t pcsr_id:1; -+ uint64_t pcsr_sl:1; -+ uint64_t pkt_imem:1; -+ uint64_t pkt_pfm:1; -+ uint64_t pkt_pof:1; -+ uint64_t reserved_48_49:2; -+ uint64_t pkt_pop0:1; -+ uint64_t pkt_pop1:1; -+ uint64_t d0_mem:1; -+ uint64_t d1_mem:1; -+ uint64_t d2_mem:1; -+ uint64_t d3_mem:1; -+ uint64_t d4_mem:1; -+ uint64_t ds_mem:1; -+ uint64_t reserved_36_39:4; -+ uint64_t d0_pst:1; -+ uint64_t d1_pst:1; -+ uint64_t d2_pst:1; -+ uint64_t d3_pst:1; -+ uint64_t d4_pst:1; -+ uint64_t n2p0_c:1; -+ uint64_t n2p0_o:1; -+ uint64_t n2p1_c:1; -+ uint64_t n2p1_o:1; -+ uint64_t cpl_p0:1; -+ uint64_t cpl_p1:1; -+ uint64_t p2n1_po:1; -+ uint64_t p2n1_no:1; -+ uint64_t p2n1_co:1; -+ uint64_t p2n0_po:1; -+ uint64_t p2n0_no:1; -+ uint64_t p2n0_co:1; -+ uint64_t p2n0_c0:1; -+ uint64_t p2n0_c1:1; -+ uint64_t p2n0_n:1; -+ uint64_t p2n0_p0:1; -+ uint64_t p2n0_p1:1; -+ uint64_t p2n1_c0:1; -+ uint64_t p2n1_c1:1; -+ uint64_t p2n1_n:1; -+ uint64_t p2n1_p0:1; -+ uint64_t p2n1_p1:1; -+ uint64_t csm0:1; -+ uint64_t csm1:1; -+ uint64_t dif0:1; -+ uint64_t dif1:1; -+ uint64_t dif2:1; -+ uint64_t dif3:1; -+ uint64_t dif4:1; -+ uint64_t msi:1; -+ uint64_t ncb_cmd:1; -+ } cn56xx; -+ struct cvmx_npei_bist_status_cn56xxp1 { -+ uint64_t reserved_58_63:6; -+ uint64_t pcsr_int:1; -+ uint64_t pcsr_im:1; -+ uint64_t pcsr_cnt:1; -+ uint64_t pcsr_id:1; -+ uint64_t pcsr_sl:1; -+ uint64_t pkt_pout:1; -+ uint64_t pkt_imem:1; -+ uint64_t pkt_cntm:1; -+ uint64_t pkt_ind:1; -+ uint64_t pkt_slm:1; -+ uint64_t pkt_odf:1; -+ uint64_t pkt_oif:1; -+ uint64_t pkt_out:1; -+ uint64_t pkt_i0:1; -+ uint64_t pkt_i1:1; -+ uint64_t pkt_s0:1; -+ uint64_t pkt_s1:1; -+ uint64_t d0_mem:1; -+ uint64_t d1_mem:1; -+ uint64_t d2_mem:1; -+ uint64_t d3_mem:1; -+ uint64_t d4_mem:1; -+ uint64_t d0_pst:1; -+ uint64_t d1_pst:1; -+ uint64_t d2_pst:1; -+ uint64_t d3_pst:1; -+ uint64_t d4_pst:1; -+ uint64_t n2p0_c:1; -+ uint64_t n2p0_o:1; -+ uint64_t n2p1_c:1; -+ uint64_t n2p1_o:1; -+ uint64_t cpl_p0:1; -+ uint64_t cpl_p1:1; -+ uint64_t p2n1_po:1; -+ uint64_t p2n1_no:1; -+ uint64_t p2n1_co:1; -+ uint64_t p2n0_po:1; -+ uint64_t p2n0_no:1; -+ uint64_t p2n0_co:1; -+ uint64_t p2n0_c0:1; -+ uint64_t p2n0_c1:1; -+ uint64_t p2n0_n:1; -+ uint64_t p2n0_p0:1; -+ uint64_t p2n0_p1:1; -+ uint64_t p2n1_c0:1; -+ uint64_t p2n1_c1:1; -+ uint64_t p2n1_n:1; -+ uint64_t p2n1_p0:1; -+ uint64_t p2n1_p1:1; -+ uint64_t csm0:1; -+ uint64_t csm1:1; -+ uint64_t dif0:1; -+ uint64_t dif1:1; -+ uint64_t dif2:1; -+ uint64_t dif3:1; -+ uint64_t dif4:1; -+ uint64_t msi:1; -+ uint64_t ncb_cmd:1; -+ } cn56xxp1; -+}; -+ -+union cvmx_npei_bist_status2 { -+ uint64_t u64; -+ struct cvmx_npei_bist_status2_s { -+ uint64_t reserved_5_63:59; -+ uint64_t psc_p0:1; -+ uint64_t psc_p1:1; -+ uint64_t pkt_gd:1; -+ uint64_t pkt_gl:1; -+ uint64_t pkt_blk:1; -+ } s; -+ struct cvmx_npei_bist_status2_s cn52xx; -+ struct cvmx_npei_bist_status2_s cn56xx; -+}; -+ -+union cvmx_npei_ctl_port0 { -+ uint64_t u64; -+ struct cvmx_npei_ctl_port0_s { -+ uint64_t reserved_21_63:43; -+ uint64_t waitl_com:1; -+ uint64_t intd:1; -+ uint64_t intc:1; -+ uint64_t intb:1; -+ uint64_t inta:1; -+ uint64_t intd_map:2; -+ uint64_t intc_map:2; -+ uint64_t intb_map:2; -+ uint64_t inta_map:2; -+ uint64_t ctlp_ro:1; -+ uint64_t reserved_6_6:1; -+ uint64_t ptlp_ro:1; -+ uint64_t bar2_enb:1; -+ uint64_t bar2_esx:2; -+ uint64_t bar2_cax:1; -+ uint64_t wait_com:1; -+ } s; -+ struct cvmx_npei_ctl_port0_s cn52xx; -+ struct cvmx_npei_ctl_port0_s cn52xxp1; -+ struct cvmx_npei_ctl_port0_s cn56xx; -+ struct cvmx_npei_ctl_port0_s cn56xxp1; -+}; -+ -+union cvmx_npei_ctl_port1 { -+ uint64_t u64; -+ struct cvmx_npei_ctl_port1_s { -+ uint64_t reserved_21_63:43; -+ uint64_t waitl_com:1; -+ uint64_t intd:1; -+ uint64_t intc:1; -+ uint64_t intb:1; -+ uint64_t inta:1; -+ uint64_t intd_map:2; -+ uint64_t intc_map:2; -+ uint64_t intb_map:2; -+ uint64_t inta_map:2; -+ uint64_t ctlp_ro:1; -+ uint64_t reserved_6_6:1; -+ uint64_t ptlp_ro:1; -+ uint64_t bar2_enb:1; -+ uint64_t bar2_esx:2; -+ uint64_t bar2_cax:1; -+ uint64_t wait_com:1; -+ } s; -+ struct cvmx_npei_ctl_port1_s cn52xx; -+ struct cvmx_npei_ctl_port1_s cn52xxp1; -+ struct cvmx_npei_ctl_port1_s cn56xx; -+ struct cvmx_npei_ctl_port1_s cn56xxp1; -+}; -+ -+union cvmx_npei_ctl_status { -+ uint64_t u64; -+ struct cvmx_npei_ctl_status_s { -+ uint64_t reserved_44_63:20; -+ uint64_t p1_ntags:6; -+ uint64_t p0_ntags:6; -+ uint64_t cfg_rtry:16; -+ uint64_t ring_en:1; -+ uint64_t lnk_rst:1; -+ uint64_t arb:1; -+ uint64_t pkt_bp:4; -+ uint64_t host_mode:1; -+ uint64_t chip_rev:8; -+ } s; -+ struct cvmx_npei_ctl_status_s cn52xx; -+ struct cvmx_npei_ctl_status_cn52xxp1 { -+ uint64_t reserved_44_63:20; -+ uint64_t p1_ntags:6; -+ uint64_t p0_ntags:6; -+ uint64_t cfg_rtry:16; -+ uint64_t reserved_15_15:1; -+ uint64_t lnk_rst:1; -+ uint64_t arb:1; -+ uint64_t reserved_9_12:4; -+ uint64_t host_mode:1; -+ uint64_t chip_rev:8; -+ } cn52xxp1; -+ struct cvmx_npei_ctl_status_s cn56xx; -+ struct cvmx_npei_ctl_status_cn56xxp1 { -+ uint64_t reserved_16_63:48; -+ uint64_t ring_en:1; -+ uint64_t lnk_rst:1; -+ uint64_t arb:1; -+ uint64_t pkt_bp:4; -+ uint64_t host_mode:1; -+ uint64_t chip_rev:8; -+ } cn56xxp1; -+}; -+ -+union cvmx_npei_ctl_status2 { -+ uint64_t u64; -+ struct cvmx_npei_ctl_status2_s { -+ uint64_t reserved_16_63:48; -+ uint64_t mps:1; -+ uint64_t mrrs:3; -+ uint64_t c1_w_flt:1; -+ uint64_t c0_w_flt:1; -+ uint64_t c1_b1_s:3; -+ uint64_t c0_b1_s:3; -+ uint64_t c1_wi_d:1; -+ uint64_t c1_b0_d:1; -+ uint64_t c0_wi_d:1; -+ uint64_t c0_b0_d:1; -+ } s; -+ struct cvmx_npei_ctl_status2_s cn52xx; -+ struct cvmx_npei_ctl_status2_s cn52xxp1; -+ struct cvmx_npei_ctl_status2_s cn56xx; -+ struct cvmx_npei_ctl_status2_s cn56xxp1; -+}; -+ -+union cvmx_npei_data_out_cnt { -+ uint64_t u64; -+ struct cvmx_npei_data_out_cnt_s { -+ uint64_t reserved_44_63:20; -+ uint64_t p1_ucnt:16; -+ uint64_t p1_fcnt:6; -+ uint64_t p0_ucnt:16; -+ uint64_t p0_fcnt:6; -+ } s; -+ struct cvmx_npei_data_out_cnt_s cn52xx; -+ struct cvmx_npei_data_out_cnt_s cn52xxp1; -+ struct cvmx_npei_data_out_cnt_s cn56xx; -+ struct cvmx_npei_data_out_cnt_s cn56xxp1; -+}; -+ -+union cvmx_npei_dbg_data { -+ uint64_t u64; -+ struct cvmx_npei_dbg_data_s { -+ uint64_t reserved_28_63:36; -+ uint64_t qlm0_rev_lanes:1; -+ uint64_t reserved_25_26:2; -+ uint64_t qlm1_spd:2; -+ uint64_t c_mul:5; -+ uint64_t dsel_ext:1; -+ uint64_t data:17; -+ } s; -+ struct cvmx_npei_dbg_data_cn52xx { -+ uint64_t reserved_29_63:35; -+ uint64_t qlm0_link_width:1; -+ uint64_t qlm0_rev_lanes:1; -+ uint64_t qlm1_mode:2; -+ uint64_t qlm1_spd:2; -+ uint64_t c_mul:5; -+ uint64_t dsel_ext:1; -+ uint64_t data:17; -+ } cn52xx; -+ struct cvmx_npei_dbg_data_cn52xx cn52xxp1; -+ struct cvmx_npei_dbg_data_cn56xx { -+ uint64_t reserved_29_63:35; -+ uint64_t qlm2_rev_lanes:1; -+ uint64_t qlm0_rev_lanes:1; -+ uint64_t qlm3_spd:2; -+ uint64_t qlm1_spd:2; -+ uint64_t c_mul:5; -+ uint64_t dsel_ext:1; -+ uint64_t data:17; -+ } cn56xx; -+ struct cvmx_npei_dbg_data_cn56xx cn56xxp1; -+}; -+ -+union cvmx_npei_dbg_select { -+ uint64_t u64; -+ struct cvmx_npei_dbg_select_s { -+ uint64_t reserved_16_63:48; -+ uint64_t dbg_sel:16; -+ } s; -+ struct cvmx_npei_dbg_select_s cn52xx; -+ struct cvmx_npei_dbg_select_s cn52xxp1; -+ struct cvmx_npei_dbg_select_s cn56xx; -+ struct cvmx_npei_dbg_select_s cn56xxp1; -+}; -+ -+union cvmx_npei_dmax_counts { -+ uint64_t u64; -+ struct cvmx_npei_dmax_counts_s { -+ uint64_t reserved_39_63:25; -+ uint64_t fcnt:7; -+ uint64_t dbell:32; -+ } s; -+ struct cvmx_npei_dmax_counts_s cn52xx; -+ struct cvmx_npei_dmax_counts_s cn52xxp1; -+ struct cvmx_npei_dmax_counts_s cn56xx; -+ struct cvmx_npei_dmax_counts_s cn56xxp1; -+}; -+ -+union cvmx_npei_dmax_dbell { -+ uint32_t u32; -+ struct cvmx_npei_dmax_dbell_s { -+ uint32_t reserved_16_31:16; -+ uint32_t dbell:16; -+ } s; -+ struct cvmx_npei_dmax_dbell_s cn52xx; -+ struct cvmx_npei_dmax_dbell_s cn52xxp1; -+ struct cvmx_npei_dmax_dbell_s cn56xx; -+ struct cvmx_npei_dmax_dbell_s cn56xxp1; -+}; -+ -+union cvmx_npei_dmax_ibuff_saddr { -+ uint64_t u64; -+ struct cvmx_npei_dmax_ibuff_saddr_s { -+ uint64_t reserved_37_63:27; -+ uint64_t idle:1; -+ uint64_t saddr:29; -+ uint64_t reserved_0_6:7; -+ } s; -+ struct cvmx_npei_dmax_ibuff_saddr_cn52xx { -+ uint64_t reserved_36_63:28; -+ uint64_t saddr:29; -+ uint64_t reserved_0_6:7; -+ } cn52xx; -+ struct cvmx_npei_dmax_ibuff_saddr_cn52xx cn52xxp1; -+ struct cvmx_npei_dmax_ibuff_saddr_s cn56xx; -+ struct cvmx_npei_dmax_ibuff_saddr_cn52xx cn56xxp1; -+}; -+ -+union cvmx_npei_dmax_naddr { -+ uint64_t u64; -+ struct cvmx_npei_dmax_naddr_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_npei_dmax_naddr_s cn52xx; -+ struct cvmx_npei_dmax_naddr_s cn52xxp1; -+ struct cvmx_npei_dmax_naddr_s cn56xx; -+ struct cvmx_npei_dmax_naddr_s cn56xxp1; -+}; -+ -+union cvmx_npei_dma0_int_level { -+ uint64_t u64; -+ struct cvmx_npei_dma0_int_level_s { -+ uint64_t time:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_npei_dma0_int_level_s cn52xx; -+ struct cvmx_npei_dma0_int_level_s cn52xxp1; -+ struct cvmx_npei_dma0_int_level_s cn56xx; -+ struct cvmx_npei_dma0_int_level_s cn56xxp1; -+}; -+ -+union cvmx_npei_dma1_int_level { -+ uint64_t u64; -+ struct cvmx_npei_dma1_int_level_s { -+ uint64_t time:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_npei_dma1_int_level_s cn52xx; -+ struct cvmx_npei_dma1_int_level_s cn52xxp1; -+ struct cvmx_npei_dma1_int_level_s cn56xx; -+ struct cvmx_npei_dma1_int_level_s cn56xxp1; -+}; -+ -+union cvmx_npei_dma_cnts { -+ uint64_t u64; -+ struct cvmx_npei_dma_cnts_s { -+ uint64_t dma1:32; -+ uint64_t dma0:32; -+ } s; -+ struct cvmx_npei_dma_cnts_s cn52xx; -+ struct cvmx_npei_dma_cnts_s cn52xxp1; -+ struct cvmx_npei_dma_cnts_s cn56xx; -+ struct cvmx_npei_dma_cnts_s cn56xxp1; -+}; -+ -+union cvmx_npei_dma_control { -+ uint64_t u64; -+ struct cvmx_npei_dma_control_s { -+ uint64_t reserved_39_63:25; -+ uint64_t dma4_enb:1; -+ uint64_t dma3_enb:1; -+ uint64_t dma2_enb:1; -+ uint64_t dma1_enb:1; -+ uint64_t dma0_enb:1; -+ uint64_t b0_lend:1; -+ uint64_t dwb_denb:1; -+ uint64_t dwb_ichk:9; -+ uint64_t fpa_que:3; -+ uint64_t o_add1:1; -+ uint64_t o_ro:1; -+ uint64_t o_ns:1; -+ uint64_t o_es:2; -+ uint64_t o_mode:1; -+ uint64_t csize:14; -+ } s; -+ struct cvmx_npei_dma_control_s cn52xx; -+ struct cvmx_npei_dma_control_cn52xxp1 { -+ uint64_t reserved_38_63:26; -+ uint64_t dma3_enb:1; -+ uint64_t dma2_enb:1; -+ uint64_t dma1_enb:1; -+ uint64_t dma0_enb:1; -+ uint64_t b0_lend:1; -+ uint64_t dwb_denb:1; -+ uint64_t dwb_ichk:9; -+ uint64_t fpa_que:3; -+ uint64_t o_add1:1; -+ uint64_t o_ro:1; -+ uint64_t o_ns:1; -+ uint64_t o_es:2; -+ uint64_t o_mode:1; -+ uint64_t csize:14; -+ } cn52xxp1; -+ struct cvmx_npei_dma_control_s cn56xx; -+ struct cvmx_npei_dma_control_s cn56xxp1; -+}; -+ -+union cvmx_npei_int_a_enb { -+ uint64_t u64; -+ struct cvmx_npei_int_a_enb_s { -+ uint64_t reserved_10_63:54; -+ uint64_t pout_err:1; -+ uint64_t pin_bp:1; -+ uint64_t p1_rdlk:1; -+ uint64_t p0_rdlk:1; -+ uint64_t pgl_err:1; -+ uint64_t pdi_err:1; -+ uint64_t pop_err:1; -+ uint64_t pins_err:1; -+ uint64_t dma1_cpl:1; -+ uint64_t dma0_cpl:1; -+ } s; -+ struct cvmx_npei_int_a_enb_cn52xx { -+ uint64_t reserved_8_63:56; -+ uint64_t p1_rdlk:1; -+ uint64_t p0_rdlk:1; -+ uint64_t pgl_err:1; -+ uint64_t pdi_err:1; -+ uint64_t pop_err:1; -+ uint64_t pins_err:1; -+ uint64_t dma1_cpl:1; -+ uint64_t dma0_cpl:1; -+ } cn52xx; -+ struct cvmx_npei_int_a_enb_cn52xxp1 { -+ uint64_t reserved_2_63:62; -+ uint64_t dma1_cpl:1; -+ uint64_t dma0_cpl:1; -+ } cn52xxp1; -+ struct cvmx_npei_int_a_enb_s cn56xx; -+}; -+ -+union cvmx_npei_int_a_enb2 { -+ uint64_t u64; -+ struct cvmx_npei_int_a_enb2_s { -+ uint64_t reserved_10_63:54; -+ uint64_t pout_err:1; -+ uint64_t pin_bp:1; -+ uint64_t p1_rdlk:1; -+ uint64_t p0_rdlk:1; -+ uint64_t pgl_err:1; -+ uint64_t pdi_err:1; -+ uint64_t pop_err:1; -+ uint64_t pins_err:1; -+ uint64_t dma1_cpl:1; -+ uint64_t dma0_cpl:1; -+ } s; -+ struct cvmx_npei_int_a_enb2_cn52xx { -+ uint64_t reserved_8_63:56; -+ uint64_t p1_rdlk:1; -+ uint64_t p0_rdlk:1; -+ uint64_t pgl_err:1; -+ uint64_t pdi_err:1; -+ uint64_t pop_err:1; -+ uint64_t pins_err:1; -+ uint64_t reserved_0_1:2; -+ } cn52xx; -+ struct cvmx_npei_int_a_enb2_cn52xxp1 { -+ uint64_t reserved_2_63:62; -+ uint64_t dma1_cpl:1; -+ uint64_t dma0_cpl:1; -+ } cn52xxp1; -+ struct cvmx_npei_int_a_enb2_s cn56xx; -+}; -+ -+union cvmx_npei_int_a_sum { -+ uint64_t u64; -+ struct cvmx_npei_int_a_sum_s { -+ uint64_t reserved_10_63:54; -+ uint64_t pout_err:1; -+ uint64_t pin_bp:1; -+ uint64_t p1_rdlk:1; -+ uint64_t p0_rdlk:1; -+ uint64_t pgl_err:1; -+ uint64_t pdi_err:1; -+ uint64_t pop_err:1; -+ uint64_t pins_err:1; -+ uint64_t dma1_cpl:1; -+ uint64_t dma0_cpl:1; -+ } s; -+ struct cvmx_npei_int_a_sum_cn52xx { -+ uint64_t reserved_8_63:56; -+ uint64_t p1_rdlk:1; -+ uint64_t p0_rdlk:1; -+ uint64_t pgl_err:1; -+ uint64_t pdi_err:1; -+ uint64_t pop_err:1; -+ uint64_t pins_err:1; -+ uint64_t dma1_cpl:1; -+ uint64_t dma0_cpl:1; -+ } cn52xx; -+ struct cvmx_npei_int_a_sum_cn52xxp1 { -+ uint64_t reserved_2_63:62; -+ uint64_t dma1_cpl:1; -+ uint64_t dma0_cpl:1; -+ } cn52xxp1; -+ struct cvmx_npei_int_a_sum_s cn56xx; -+}; -+ -+union cvmx_npei_int_enb { -+ uint64_t u64; -+ struct cvmx_npei_int_enb_s { -+ uint64_t mio_inta:1; -+ uint64_t reserved_62_62:1; -+ uint64_t int_a:1; -+ uint64_t c1_ldwn:1; -+ uint64_t c0_ldwn:1; -+ uint64_t c1_exc:1; -+ uint64_t c0_exc:1; -+ uint64_t c1_up_wf:1; -+ uint64_t c0_up_wf:1; -+ uint64_t c1_un_wf:1; -+ uint64_t c0_un_wf:1; -+ uint64_t c1_un_bx:1; -+ uint64_t c1_un_wi:1; -+ uint64_t c1_un_b2:1; -+ uint64_t c1_un_b1:1; -+ uint64_t c1_un_b0:1; -+ uint64_t c1_up_bx:1; -+ uint64_t c1_up_wi:1; -+ uint64_t c1_up_b2:1; -+ uint64_t c1_up_b1:1; -+ uint64_t c1_up_b0:1; -+ uint64_t c0_un_bx:1; -+ uint64_t c0_un_wi:1; -+ uint64_t c0_un_b2:1; -+ uint64_t c0_un_b1:1; -+ uint64_t c0_un_b0:1; -+ uint64_t c0_up_bx:1; -+ uint64_t c0_up_wi:1; -+ uint64_t c0_up_b2:1; -+ uint64_t c0_up_b1:1; -+ uint64_t c0_up_b0:1; -+ uint64_t c1_hpint:1; -+ uint64_t c1_pmei:1; -+ uint64_t c1_wake:1; -+ uint64_t crs1_dr:1; -+ uint64_t c1_se:1; -+ uint64_t crs1_er:1; -+ uint64_t c1_aeri:1; -+ uint64_t c0_hpint:1; -+ uint64_t c0_pmei:1; -+ uint64_t c0_wake:1; -+ uint64_t crs0_dr:1; -+ uint64_t c0_se:1; -+ uint64_t crs0_er:1; -+ uint64_t c0_aeri:1; -+ uint64_t ptime:1; -+ uint64_t pcnt:1; -+ uint64_t pidbof:1; -+ uint64_t psldbof:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t dma1fi:1; -+ uint64_t dma0fi:1; -+ uint64_t dma4dbo:1; -+ uint64_t dma3dbo:1; -+ uint64_t dma2dbo:1; -+ uint64_t dma1dbo:1; -+ uint64_t dma0dbo:1; -+ uint64_t iob2big:1; -+ uint64_t bar0_to:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } s; -+ struct cvmx_npei_int_enb_s cn52xx; -+ struct cvmx_npei_int_enb_cn52xxp1 { -+ uint64_t mio_inta:1; -+ uint64_t reserved_62_62:1; -+ uint64_t int_a:1; -+ uint64_t c1_ldwn:1; -+ uint64_t c0_ldwn:1; -+ uint64_t c1_exc:1; -+ uint64_t c0_exc:1; -+ uint64_t c1_up_wf:1; -+ uint64_t c0_up_wf:1; -+ uint64_t c1_un_wf:1; -+ uint64_t c0_un_wf:1; -+ uint64_t c1_un_bx:1; -+ uint64_t c1_un_wi:1; -+ uint64_t c1_un_b2:1; -+ uint64_t c1_un_b1:1; -+ uint64_t c1_un_b0:1; -+ uint64_t c1_up_bx:1; -+ uint64_t c1_up_wi:1; -+ uint64_t c1_up_b2:1; -+ uint64_t c1_up_b1:1; -+ uint64_t c1_up_b0:1; -+ uint64_t c0_un_bx:1; -+ uint64_t c0_un_wi:1; -+ uint64_t c0_un_b2:1; -+ uint64_t c0_un_b1:1; -+ uint64_t c0_un_b0:1; -+ uint64_t c0_up_bx:1; -+ uint64_t c0_up_wi:1; -+ uint64_t c0_up_b2:1; -+ uint64_t c0_up_b1:1; -+ uint64_t c0_up_b0:1; -+ uint64_t c1_hpint:1; -+ uint64_t c1_pmei:1; -+ uint64_t c1_wake:1; -+ uint64_t crs1_dr:1; -+ uint64_t c1_se:1; -+ uint64_t crs1_er:1; -+ uint64_t c1_aeri:1; -+ uint64_t c0_hpint:1; -+ uint64_t c0_pmei:1; -+ uint64_t c0_wake:1; -+ uint64_t crs0_dr:1; -+ uint64_t c0_se:1; -+ uint64_t crs0_er:1; -+ uint64_t c0_aeri:1; -+ uint64_t ptime:1; -+ uint64_t pcnt:1; -+ uint64_t pidbof:1; -+ uint64_t psldbof:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t dma1fi:1; -+ uint64_t dma0fi:1; -+ uint64_t reserved_8_8:1; -+ uint64_t dma3dbo:1; -+ uint64_t dma2dbo:1; -+ uint64_t dma1dbo:1; -+ uint64_t dma0dbo:1; -+ uint64_t iob2big:1; -+ uint64_t bar0_to:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } cn52xxp1; -+ struct cvmx_npei_int_enb_s cn56xx; -+ struct cvmx_npei_int_enb_cn56xxp1 { -+ uint64_t mio_inta:1; -+ uint64_t reserved_61_62:2; -+ uint64_t c1_ldwn:1; -+ uint64_t c0_ldwn:1; -+ uint64_t c1_exc:1; -+ uint64_t c0_exc:1; -+ uint64_t c1_up_wf:1; -+ uint64_t c0_up_wf:1; -+ uint64_t c1_un_wf:1; -+ uint64_t c0_un_wf:1; -+ uint64_t c1_un_bx:1; -+ uint64_t c1_un_wi:1; -+ uint64_t c1_un_b2:1; -+ uint64_t c1_un_b1:1; -+ uint64_t c1_un_b0:1; -+ uint64_t c1_up_bx:1; -+ uint64_t c1_up_wi:1; -+ uint64_t c1_up_b2:1; -+ uint64_t c1_up_b1:1; -+ uint64_t c1_up_b0:1; -+ uint64_t c0_un_bx:1; -+ uint64_t c0_un_wi:1; -+ uint64_t c0_un_b2:1; -+ uint64_t c0_un_b1:1; -+ uint64_t c0_un_b0:1; -+ uint64_t c0_up_bx:1; -+ uint64_t c0_up_wi:1; -+ uint64_t c0_up_b2:1; -+ uint64_t c0_up_b1:1; -+ uint64_t c0_up_b0:1; -+ uint64_t c1_hpint:1; -+ uint64_t c1_pmei:1; -+ uint64_t c1_wake:1; -+ uint64_t reserved_29_29:1; -+ uint64_t c1_se:1; -+ uint64_t reserved_27_27:1; -+ uint64_t c1_aeri:1; -+ uint64_t c0_hpint:1; -+ uint64_t c0_pmei:1; -+ uint64_t c0_wake:1; -+ uint64_t reserved_22_22:1; -+ uint64_t c0_se:1; -+ uint64_t reserved_20_20:1; -+ uint64_t c0_aeri:1; -+ uint64_t ptime:1; -+ uint64_t pcnt:1; -+ uint64_t pidbof:1; -+ uint64_t psldbof:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t dma1fi:1; -+ uint64_t dma0fi:1; -+ uint64_t dma4dbo:1; -+ uint64_t dma3dbo:1; -+ uint64_t dma2dbo:1; -+ uint64_t dma1dbo:1; -+ uint64_t dma0dbo:1; -+ uint64_t iob2big:1; -+ uint64_t bar0_to:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } cn56xxp1; -+}; -+ -+union cvmx_npei_int_enb2 { -+ uint64_t u64; -+ struct cvmx_npei_int_enb2_s { -+ uint64_t reserved_62_63:2; -+ uint64_t int_a:1; -+ uint64_t c1_ldwn:1; -+ uint64_t c0_ldwn:1; -+ uint64_t c1_exc:1; -+ uint64_t c0_exc:1; -+ uint64_t c1_up_wf:1; -+ uint64_t c0_up_wf:1; -+ uint64_t c1_un_wf:1; -+ uint64_t c0_un_wf:1; -+ uint64_t c1_un_bx:1; -+ uint64_t c1_un_wi:1; -+ uint64_t c1_un_b2:1; -+ uint64_t c1_un_b1:1; -+ uint64_t c1_un_b0:1; -+ uint64_t c1_up_bx:1; -+ uint64_t c1_up_wi:1; -+ uint64_t c1_up_b2:1; -+ uint64_t c1_up_b1:1; -+ uint64_t c1_up_b0:1; -+ uint64_t c0_un_bx:1; -+ uint64_t c0_un_wi:1; -+ uint64_t c0_un_b2:1; -+ uint64_t c0_un_b1:1; -+ uint64_t c0_un_b0:1; -+ uint64_t c0_up_bx:1; -+ uint64_t c0_up_wi:1; -+ uint64_t c0_up_b2:1; -+ uint64_t c0_up_b1:1; -+ uint64_t c0_up_b0:1; -+ uint64_t c1_hpint:1; -+ uint64_t c1_pmei:1; -+ uint64_t c1_wake:1; -+ uint64_t crs1_dr:1; -+ uint64_t c1_se:1; -+ uint64_t crs1_er:1; -+ uint64_t c1_aeri:1; -+ uint64_t c0_hpint:1; -+ uint64_t c0_pmei:1; -+ uint64_t c0_wake:1; -+ uint64_t crs0_dr:1; -+ uint64_t c0_se:1; -+ uint64_t crs0_er:1; -+ uint64_t c0_aeri:1; -+ uint64_t ptime:1; -+ uint64_t pcnt:1; -+ uint64_t pidbof:1; -+ uint64_t psldbof:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t dma1fi:1; -+ uint64_t dma0fi:1; -+ uint64_t dma4dbo:1; -+ uint64_t dma3dbo:1; -+ uint64_t dma2dbo:1; -+ uint64_t dma1dbo:1; -+ uint64_t dma0dbo:1; -+ uint64_t iob2big:1; -+ uint64_t bar0_to:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } s; -+ struct cvmx_npei_int_enb2_s cn52xx; -+ struct cvmx_npei_int_enb2_cn52xxp1 { -+ uint64_t reserved_62_63:2; -+ uint64_t int_a:1; -+ uint64_t c1_ldwn:1; -+ uint64_t c0_ldwn:1; -+ uint64_t c1_exc:1; -+ uint64_t c0_exc:1; -+ uint64_t c1_up_wf:1; -+ uint64_t c0_up_wf:1; -+ uint64_t c1_un_wf:1; -+ uint64_t c0_un_wf:1; -+ uint64_t c1_un_bx:1; -+ uint64_t c1_un_wi:1; -+ uint64_t c1_un_b2:1; -+ uint64_t c1_un_b1:1; -+ uint64_t c1_un_b0:1; -+ uint64_t c1_up_bx:1; -+ uint64_t c1_up_wi:1; -+ uint64_t c1_up_b2:1; -+ uint64_t c1_up_b1:1; -+ uint64_t c1_up_b0:1; -+ uint64_t c0_un_bx:1; -+ uint64_t c0_un_wi:1; -+ uint64_t c0_un_b2:1; -+ uint64_t c0_un_b1:1; -+ uint64_t c0_un_b0:1; -+ uint64_t c0_up_bx:1; -+ uint64_t c0_up_wi:1; -+ uint64_t c0_up_b2:1; -+ uint64_t c0_up_b1:1; -+ uint64_t c0_up_b0:1; -+ uint64_t c1_hpint:1; -+ uint64_t c1_pmei:1; -+ uint64_t c1_wake:1; -+ uint64_t crs1_dr:1; -+ uint64_t c1_se:1; -+ uint64_t crs1_er:1; -+ uint64_t c1_aeri:1; -+ uint64_t c0_hpint:1; -+ uint64_t c0_pmei:1; -+ uint64_t c0_wake:1; -+ uint64_t crs0_dr:1; -+ uint64_t c0_se:1; -+ uint64_t crs0_er:1; -+ uint64_t c0_aeri:1; -+ uint64_t ptime:1; -+ uint64_t pcnt:1; -+ uint64_t pidbof:1; -+ uint64_t psldbof:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t dma1fi:1; -+ uint64_t dma0fi:1; -+ uint64_t reserved_8_8:1; -+ uint64_t dma3dbo:1; -+ uint64_t dma2dbo:1; -+ uint64_t dma1dbo:1; -+ uint64_t dma0dbo:1; -+ uint64_t iob2big:1; -+ uint64_t bar0_to:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } cn52xxp1; -+ struct cvmx_npei_int_enb2_s cn56xx; -+ struct cvmx_npei_int_enb2_cn56xxp1 { -+ uint64_t reserved_61_63:3; -+ uint64_t c1_ldwn:1; -+ uint64_t c0_ldwn:1; -+ uint64_t c1_exc:1; -+ uint64_t c0_exc:1; -+ uint64_t c1_up_wf:1; -+ uint64_t c0_up_wf:1; -+ uint64_t c1_un_wf:1; -+ uint64_t c0_un_wf:1; -+ uint64_t c1_un_bx:1; -+ uint64_t c1_un_wi:1; -+ uint64_t c1_un_b2:1; -+ uint64_t c1_un_b1:1; -+ uint64_t c1_un_b0:1; -+ uint64_t c1_up_bx:1; -+ uint64_t c1_up_wi:1; -+ uint64_t c1_up_b2:1; -+ uint64_t c1_up_b1:1; -+ uint64_t c1_up_b0:1; -+ uint64_t c0_un_bx:1; -+ uint64_t c0_un_wi:1; -+ uint64_t c0_un_b2:1; -+ uint64_t c0_un_b1:1; -+ uint64_t c0_un_b0:1; -+ uint64_t c0_up_bx:1; -+ uint64_t c0_up_wi:1; -+ uint64_t c0_up_b2:1; -+ uint64_t c0_up_b1:1; -+ uint64_t c0_up_b0:1; -+ uint64_t c1_hpint:1; -+ uint64_t c1_pmei:1; -+ uint64_t c1_wake:1; -+ uint64_t reserved_29_29:1; -+ uint64_t c1_se:1; -+ uint64_t reserved_27_27:1; -+ uint64_t c1_aeri:1; -+ uint64_t c0_hpint:1; -+ uint64_t c0_pmei:1; -+ uint64_t c0_wake:1; -+ uint64_t reserved_22_22:1; -+ uint64_t c0_se:1; -+ uint64_t reserved_20_20:1; -+ uint64_t c0_aeri:1; -+ uint64_t ptime:1; -+ uint64_t pcnt:1; -+ uint64_t pidbof:1; -+ uint64_t psldbof:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t dma1fi:1; -+ uint64_t dma0fi:1; -+ uint64_t dma4dbo:1; -+ uint64_t dma3dbo:1; -+ uint64_t dma2dbo:1; -+ uint64_t dma1dbo:1; -+ uint64_t dma0dbo:1; -+ uint64_t iob2big:1; -+ uint64_t bar0_to:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } cn56xxp1; -+}; -+ -+union cvmx_npei_int_info { -+ uint64_t u64; -+ struct cvmx_npei_int_info_s { -+ uint64_t reserved_12_63:52; -+ uint64_t pidbof:6; -+ uint64_t psldbof:6; -+ } s; -+ struct cvmx_npei_int_info_s cn52xx; -+ struct cvmx_npei_int_info_s cn56xx; -+ struct cvmx_npei_int_info_s cn56xxp1; -+}; -+ -+union cvmx_npei_int_sum { -+ uint64_t u64; -+ struct cvmx_npei_int_sum_s { -+ uint64_t mio_inta:1; -+ uint64_t reserved_62_62:1; -+ uint64_t int_a:1; -+ uint64_t c1_ldwn:1; -+ uint64_t c0_ldwn:1; -+ uint64_t c1_exc:1; -+ uint64_t c0_exc:1; -+ uint64_t c1_up_wf:1; -+ uint64_t c0_up_wf:1; -+ uint64_t c1_un_wf:1; -+ uint64_t c0_un_wf:1; -+ uint64_t c1_un_bx:1; -+ uint64_t c1_un_wi:1; -+ uint64_t c1_un_b2:1; -+ uint64_t c1_un_b1:1; -+ uint64_t c1_un_b0:1; -+ uint64_t c1_up_bx:1; -+ uint64_t c1_up_wi:1; -+ uint64_t c1_up_b2:1; -+ uint64_t c1_up_b1:1; -+ uint64_t c1_up_b0:1; -+ uint64_t c0_un_bx:1; -+ uint64_t c0_un_wi:1; -+ uint64_t c0_un_b2:1; -+ uint64_t c0_un_b1:1; -+ uint64_t c0_un_b0:1; -+ uint64_t c0_up_bx:1; -+ uint64_t c0_up_wi:1; -+ uint64_t c0_up_b2:1; -+ uint64_t c0_up_b1:1; -+ uint64_t c0_up_b0:1; -+ uint64_t c1_hpint:1; -+ uint64_t c1_pmei:1; -+ uint64_t c1_wake:1; -+ uint64_t crs1_dr:1; -+ uint64_t c1_se:1; -+ uint64_t crs1_er:1; -+ uint64_t c1_aeri:1; -+ uint64_t c0_hpint:1; -+ uint64_t c0_pmei:1; -+ uint64_t c0_wake:1; -+ uint64_t crs0_dr:1; -+ uint64_t c0_se:1; -+ uint64_t crs0_er:1; -+ uint64_t c0_aeri:1; -+ uint64_t ptime:1; -+ uint64_t pcnt:1; -+ uint64_t pidbof:1; -+ uint64_t psldbof:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t dma1fi:1; -+ uint64_t dma0fi:1; -+ uint64_t dma4dbo:1; -+ uint64_t dma3dbo:1; -+ uint64_t dma2dbo:1; -+ uint64_t dma1dbo:1; -+ uint64_t dma0dbo:1; -+ uint64_t iob2big:1; -+ uint64_t bar0_to:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } s; -+ struct cvmx_npei_int_sum_s cn52xx; -+ struct cvmx_npei_int_sum_cn52xxp1 { -+ uint64_t mio_inta:1; -+ uint64_t reserved_62_62:1; -+ uint64_t int_a:1; -+ uint64_t c1_ldwn:1; -+ uint64_t c0_ldwn:1; -+ uint64_t c1_exc:1; -+ uint64_t c0_exc:1; -+ uint64_t c1_up_wf:1; -+ uint64_t c0_up_wf:1; -+ uint64_t c1_un_wf:1; -+ uint64_t c0_un_wf:1; -+ uint64_t c1_un_bx:1; -+ uint64_t c1_un_wi:1; -+ uint64_t c1_un_b2:1; -+ uint64_t c1_un_b1:1; -+ uint64_t c1_un_b0:1; -+ uint64_t c1_up_bx:1; -+ uint64_t c1_up_wi:1; -+ uint64_t c1_up_b2:1; -+ uint64_t c1_up_b1:1; -+ uint64_t c1_up_b0:1; -+ uint64_t c0_un_bx:1; -+ uint64_t c0_un_wi:1; -+ uint64_t c0_un_b2:1; -+ uint64_t c0_un_b1:1; -+ uint64_t c0_un_b0:1; -+ uint64_t c0_up_bx:1; -+ uint64_t c0_up_wi:1; -+ uint64_t c0_up_b2:1; -+ uint64_t c0_up_b1:1; -+ uint64_t c0_up_b0:1; -+ uint64_t c1_hpint:1; -+ uint64_t c1_pmei:1; -+ uint64_t c1_wake:1; -+ uint64_t crs1_dr:1; -+ uint64_t c1_se:1; -+ uint64_t crs1_er:1; -+ uint64_t c1_aeri:1; -+ uint64_t c0_hpint:1; -+ uint64_t c0_pmei:1; -+ uint64_t c0_wake:1; -+ uint64_t crs0_dr:1; -+ uint64_t c0_se:1; -+ uint64_t crs0_er:1; -+ uint64_t c0_aeri:1; -+ uint64_t reserved_15_18:4; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t dma1fi:1; -+ uint64_t dma0fi:1; -+ uint64_t reserved_8_8:1; -+ uint64_t dma3dbo:1; -+ uint64_t dma2dbo:1; -+ uint64_t dma1dbo:1; -+ uint64_t dma0dbo:1; -+ uint64_t iob2big:1; -+ uint64_t bar0_to:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } cn52xxp1; -+ struct cvmx_npei_int_sum_s cn56xx; -+ struct cvmx_npei_int_sum_cn56xxp1 { -+ uint64_t mio_inta:1; -+ uint64_t reserved_61_62:2; -+ uint64_t c1_ldwn:1; -+ uint64_t c0_ldwn:1; -+ uint64_t c1_exc:1; -+ uint64_t c0_exc:1; -+ uint64_t c1_up_wf:1; -+ uint64_t c0_up_wf:1; -+ uint64_t c1_un_wf:1; -+ uint64_t c0_un_wf:1; -+ uint64_t c1_un_bx:1; -+ uint64_t c1_un_wi:1; -+ uint64_t c1_un_b2:1; -+ uint64_t c1_un_b1:1; -+ uint64_t c1_un_b0:1; -+ uint64_t c1_up_bx:1; -+ uint64_t c1_up_wi:1; -+ uint64_t c1_up_b2:1; -+ uint64_t c1_up_b1:1; -+ uint64_t c1_up_b0:1; -+ uint64_t c0_un_bx:1; -+ uint64_t c0_un_wi:1; -+ uint64_t c0_un_b2:1; -+ uint64_t c0_un_b1:1; -+ uint64_t c0_un_b0:1; -+ uint64_t c0_up_bx:1; -+ uint64_t c0_up_wi:1; -+ uint64_t c0_up_b2:1; -+ uint64_t c0_up_b1:1; -+ uint64_t c0_up_b0:1; -+ uint64_t c1_hpint:1; -+ uint64_t c1_pmei:1; -+ uint64_t c1_wake:1; -+ uint64_t reserved_29_29:1; -+ uint64_t c1_se:1; -+ uint64_t reserved_27_27:1; -+ uint64_t c1_aeri:1; -+ uint64_t c0_hpint:1; -+ uint64_t c0_pmei:1; -+ uint64_t c0_wake:1; -+ uint64_t reserved_22_22:1; -+ uint64_t c0_se:1; -+ uint64_t reserved_20_20:1; -+ uint64_t c0_aeri:1; -+ uint64_t ptime:1; -+ uint64_t pcnt:1; -+ uint64_t pidbof:1; -+ uint64_t psldbof:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t dma1fi:1; -+ uint64_t dma0fi:1; -+ uint64_t dma4dbo:1; -+ uint64_t dma3dbo:1; -+ uint64_t dma2dbo:1; -+ uint64_t dma1dbo:1; -+ uint64_t dma0dbo:1; -+ uint64_t iob2big:1; -+ uint64_t bar0_to:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } cn56xxp1; -+}; -+ -+union cvmx_npei_int_sum2 { -+ uint64_t u64; -+ struct cvmx_npei_int_sum2_s { -+ uint64_t mio_inta:1; -+ uint64_t reserved_62_62:1; -+ uint64_t int_a:1; -+ uint64_t c1_ldwn:1; -+ uint64_t c0_ldwn:1; -+ uint64_t c1_exc:1; -+ uint64_t c0_exc:1; -+ uint64_t c1_up_wf:1; -+ uint64_t c0_up_wf:1; -+ uint64_t c1_un_wf:1; -+ uint64_t c0_un_wf:1; -+ uint64_t c1_un_bx:1; -+ uint64_t c1_un_wi:1; -+ uint64_t c1_un_b2:1; -+ uint64_t c1_un_b1:1; -+ uint64_t c1_un_b0:1; -+ uint64_t c1_up_bx:1; -+ uint64_t c1_up_wi:1; -+ uint64_t c1_up_b2:1; -+ uint64_t c1_up_b1:1; -+ uint64_t c1_up_b0:1; -+ uint64_t c0_un_bx:1; -+ uint64_t c0_un_wi:1; -+ uint64_t c0_un_b2:1; -+ uint64_t c0_un_b1:1; -+ uint64_t c0_un_b0:1; -+ uint64_t c0_up_bx:1; -+ uint64_t c0_up_wi:1; -+ uint64_t c0_up_b2:1; -+ uint64_t c0_up_b1:1; -+ uint64_t c0_up_b0:1; -+ uint64_t c1_hpint:1; -+ uint64_t c1_pmei:1; -+ uint64_t c1_wake:1; -+ uint64_t crs1_dr:1; -+ uint64_t c1_se:1; -+ uint64_t crs1_er:1; -+ uint64_t c1_aeri:1; -+ uint64_t c0_hpint:1; -+ uint64_t c0_pmei:1; -+ uint64_t c0_wake:1; -+ uint64_t crs0_dr:1; -+ uint64_t c0_se:1; -+ uint64_t crs0_er:1; -+ uint64_t c0_aeri:1; -+ uint64_t reserved_15_18:4; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t dma1fi:1; -+ uint64_t dma0fi:1; -+ uint64_t reserved_8_8:1; -+ uint64_t dma3dbo:1; -+ uint64_t dma2dbo:1; -+ uint64_t dma1dbo:1; -+ uint64_t dma0dbo:1; -+ uint64_t iob2big:1; -+ uint64_t bar0_to:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } s; -+ struct cvmx_npei_int_sum2_s cn52xx; -+ struct cvmx_npei_int_sum2_s cn52xxp1; -+ struct cvmx_npei_int_sum2_s cn56xx; -+}; -+ -+union cvmx_npei_last_win_rdata0 { -+ uint64_t u64; -+ struct cvmx_npei_last_win_rdata0_s { -+ uint64_t data:64; -+ } s; -+ struct cvmx_npei_last_win_rdata0_s cn52xx; -+ struct cvmx_npei_last_win_rdata0_s cn52xxp1; -+ struct cvmx_npei_last_win_rdata0_s cn56xx; -+ struct cvmx_npei_last_win_rdata0_s cn56xxp1; -+}; -+ -+union cvmx_npei_last_win_rdata1 { -+ uint64_t u64; -+ struct cvmx_npei_last_win_rdata1_s { -+ uint64_t data:64; -+ } s; -+ struct cvmx_npei_last_win_rdata1_s cn52xx; -+ struct cvmx_npei_last_win_rdata1_s cn52xxp1; -+ struct cvmx_npei_last_win_rdata1_s cn56xx; -+ struct cvmx_npei_last_win_rdata1_s cn56xxp1; -+}; -+ -+union cvmx_npei_mem_access_ctl { -+ uint64_t u64; -+ struct cvmx_npei_mem_access_ctl_s { -+ uint64_t reserved_14_63:50; -+ uint64_t max_word:4; -+ uint64_t timer:10; -+ } s; -+ struct cvmx_npei_mem_access_ctl_s cn52xx; -+ struct cvmx_npei_mem_access_ctl_s cn52xxp1; -+ struct cvmx_npei_mem_access_ctl_s cn56xx; -+ struct cvmx_npei_mem_access_ctl_s cn56xxp1; -+}; -+ -+union cvmx_npei_mem_access_subidx { -+ uint64_t u64; -+ struct cvmx_npei_mem_access_subidx_s { -+ uint64_t reserved_42_63:22; -+ uint64_t zero:1; -+ uint64_t port:2; -+ uint64_t nmerge:1; -+ uint64_t esr:2; -+ uint64_t esw:2; -+ uint64_t nsr:1; -+ uint64_t nsw:1; -+ uint64_t ror:1; -+ uint64_t row:1; -+ uint64_t ba:30; -+ } s; -+ struct cvmx_npei_mem_access_subidx_s cn52xx; -+ struct cvmx_npei_mem_access_subidx_s cn52xxp1; -+ struct cvmx_npei_mem_access_subidx_s cn56xx; -+ struct cvmx_npei_mem_access_subidx_s cn56xxp1; -+}; -+ -+union cvmx_npei_msi_enb0 { -+ uint64_t u64; -+ struct cvmx_npei_msi_enb0_s { -+ uint64_t enb:64; -+ } s; -+ struct cvmx_npei_msi_enb0_s cn52xx; -+ struct cvmx_npei_msi_enb0_s cn52xxp1; -+ struct cvmx_npei_msi_enb0_s cn56xx; -+ struct cvmx_npei_msi_enb0_s cn56xxp1; -+}; -+ -+union cvmx_npei_msi_enb1 { -+ uint64_t u64; -+ struct cvmx_npei_msi_enb1_s { -+ uint64_t enb:64; -+ } s; -+ struct cvmx_npei_msi_enb1_s cn52xx; -+ struct cvmx_npei_msi_enb1_s cn52xxp1; -+ struct cvmx_npei_msi_enb1_s cn56xx; -+ struct cvmx_npei_msi_enb1_s cn56xxp1; -+}; -+ -+union cvmx_npei_msi_enb2 { -+ uint64_t u64; -+ struct cvmx_npei_msi_enb2_s { -+ uint64_t enb:64; -+ } s; -+ struct cvmx_npei_msi_enb2_s cn52xx; -+ struct cvmx_npei_msi_enb2_s cn52xxp1; -+ struct cvmx_npei_msi_enb2_s cn56xx; -+ struct cvmx_npei_msi_enb2_s cn56xxp1; -+}; -+ -+union cvmx_npei_msi_enb3 { -+ uint64_t u64; -+ struct cvmx_npei_msi_enb3_s { -+ uint64_t enb:64; -+ } s; -+ struct cvmx_npei_msi_enb3_s cn52xx; -+ struct cvmx_npei_msi_enb3_s cn52xxp1; -+ struct cvmx_npei_msi_enb3_s cn56xx; -+ struct cvmx_npei_msi_enb3_s cn56xxp1; -+}; -+ -+union cvmx_npei_msi_rcv0 { -+ uint64_t u64; -+ struct cvmx_npei_msi_rcv0_s { -+ uint64_t intr:64; -+ } s; -+ struct cvmx_npei_msi_rcv0_s cn52xx; -+ struct cvmx_npei_msi_rcv0_s cn52xxp1; -+ struct cvmx_npei_msi_rcv0_s cn56xx; -+ struct cvmx_npei_msi_rcv0_s cn56xxp1; -+}; -+ -+union cvmx_npei_msi_rcv1 { -+ uint64_t u64; -+ struct cvmx_npei_msi_rcv1_s { -+ uint64_t intr:64; -+ } s; -+ struct cvmx_npei_msi_rcv1_s cn52xx; -+ struct cvmx_npei_msi_rcv1_s cn52xxp1; -+ struct cvmx_npei_msi_rcv1_s cn56xx; -+ struct cvmx_npei_msi_rcv1_s cn56xxp1; -+}; -+ -+union cvmx_npei_msi_rcv2 { -+ uint64_t u64; -+ struct cvmx_npei_msi_rcv2_s { -+ uint64_t intr:64; -+ } s; -+ struct cvmx_npei_msi_rcv2_s cn52xx; -+ struct cvmx_npei_msi_rcv2_s cn52xxp1; -+ struct cvmx_npei_msi_rcv2_s cn56xx; -+ struct cvmx_npei_msi_rcv2_s cn56xxp1; -+}; -+ -+union cvmx_npei_msi_rcv3 { -+ uint64_t u64; -+ struct cvmx_npei_msi_rcv3_s { -+ uint64_t intr:64; -+ } s; -+ struct cvmx_npei_msi_rcv3_s cn52xx; -+ struct cvmx_npei_msi_rcv3_s cn52xxp1; -+ struct cvmx_npei_msi_rcv3_s cn56xx; -+ struct cvmx_npei_msi_rcv3_s cn56xxp1; -+}; -+ -+union cvmx_npei_msi_rd_map { -+ uint64_t u64; -+ struct cvmx_npei_msi_rd_map_s { -+ uint64_t reserved_16_63:48; -+ uint64_t rd_int:8; -+ uint64_t msi_int:8; -+ } s; -+ struct cvmx_npei_msi_rd_map_s cn52xx; -+ struct cvmx_npei_msi_rd_map_s cn52xxp1; -+ struct cvmx_npei_msi_rd_map_s cn56xx; -+ struct cvmx_npei_msi_rd_map_s cn56xxp1; -+}; -+ -+union cvmx_npei_msi_w1c_enb0 { -+ uint64_t u64; -+ struct cvmx_npei_msi_w1c_enb0_s { -+ uint64_t clr:64; -+ } s; -+ struct cvmx_npei_msi_w1c_enb0_s cn52xx; -+ struct cvmx_npei_msi_w1c_enb0_s cn56xx; -+}; -+ -+union cvmx_npei_msi_w1c_enb1 { -+ uint64_t u64; -+ struct cvmx_npei_msi_w1c_enb1_s { -+ uint64_t clr:64; -+ } s; -+ struct cvmx_npei_msi_w1c_enb1_s cn52xx; -+ struct cvmx_npei_msi_w1c_enb1_s cn56xx; -+}; -+ -+union cvmx_npei_msi_w1c_enb2 { -+ uint64_t u64; -+ struct cvmx_npei_msi_w1c_enb2_s { -+ uint64_t clr:64; -+ } s; -+ struct cvmx_npei_msi_w1c_enb2_s cn52xx; -+ struct cvmx_npei_msi_w1c_enb2_s cn56xx; -+}; -+ -+union cvmx_npei_msi_w1c_enb3 { -+ uint64_t u64; -+ struct cvmx_npei_msi_w1c_enb3_s { -+ uint64_t clr:64; -+ } s; -+ struct cvmx_npei_msi_w1c_enb3_s cn52xx; -+ struct cvmx_npei_msi_w1c_enb3_s cn56xx; -+}; -+ -+union cvmx_npei_msi_w1s_enb0 { -+ uint64_t u64; -+ struct cvmx_npei_msi_w1s_enb0_s { -+ uint64_t set:64; -+ } s; -+ struct cvmx_npei_msi_w1s_enb0_s cn52xx; -+ struct cvmx_npei_msi_w1s_enb0_s cn56xx; -+}; -+ -+union cvmx_npei_msi_w1s_enb1 { -+ uint64_t u64; -+ struct cvmx_npei_msi_w1s_enb1_s { -+ uint64_t set:64; -+ } s; -+ struct cvmx_npei_msi_w1s_enb1_s cn52xx; -+ struct cvmx_npei_msi_w1s_enb1_s cn56xx; -+}; -+ -+union cvmx_npei_msi_w1s_enb2 { -+ uint64_t u64; -+ struct cvmx_npei_msi_w1s_enb2_s { -+ uint64_t set:64; -+ } s; -+ struct cvmx_npei_msi_w1s_enb2_s cn52xx; -+ struct cvmx_npei_msi_w1s_enb2_s cn56xx; -+}; -+ -+union cvmx_npei_msi_w1s_enb3 { -+ uint64_t u64; -+ struct cvmx_npei_msi_w1s_enb3_s { -+ uint64_t set:64; -+ } s; -+ struct cvmx_npei_msi_w1s_enb3_s cn52xx; -+ struct cvmx_npei_msi_w1s_enb3_s cn56xx; -+}; -+ -+union cvmx_npei_msi_wr_map { -+ uint64_t u64; -+ struct cvmx_npei_msi_wr_map_s { -+ uint64_t reserved_16_63:48; -+ uint64_t ciu_int:8; -+ uint64_t msi_int:8; -+ } s; -+ struct cvmx_npei_msi_wr_map_s cn52xx; -+ struct cvmx_npei_msi_wr_map_s cn52xxp1; -+ struct cvmx_npei_msi_wr_map_s cn56xx; -+ struct cvmx_npei_msi_wr_map_s cn56xxp1; -+}; -+ -+union cvmx_npei_pcie_credit_cnt { -+ uint64_t u64; -+ struct cvmx_npei_pcie_credit_cnt_s { -+ uint64_t reserved_48_63:16; -+ uint64_t p1_ccnt:8; -+ uint64_t p1_ncnt:8; -+ uint64_t p1_pcnt:8; -+ uint64_t p0_ccnt:8; -+ uint64_t p0_ncnt:8; -+ uint64_t p0_pcnt:8; -+ } s; -+ struct cvmx_npei_pcie_credit_cnt_s cn52xx; -+ struct cvmx_npei_pcie_credit_cnt_s cn56xx; -+}; -+ -+union cvmx_npei_pcie_msi_rcv { -+ uint64_t u64; -+ struct cvmx_npei_pcie_msi_rcv_s { -+ uint64_t reserved_8_63:56; -+ uint64_t intr:8; -+ } s; -+ struct cvmx_npei_pcie_msi_rcv_s cn52xx; -+ struct cvmx_npei_pcie_msi_rcv_s cn52xxp1; -+ struct cvmx_npei_pcie_msi_rcv_s cn56xx; -+ struct cvmx_npei_pcie_msi_rcv_s cn56xxp1; -+}; -+ -+union cvmx_npei_pcie_msi_rcv_b1 { -+ uint64_t u64; -+ struct cvmx_npei_pcie_msi_rcv_b1_s { -+ uint64_t reserved_16_63:48; -+ uint64_t intr:8; -+ uint64_t reserved_0_7:8; -+ } s; -+ struct cvmx_npei_pcie_msi_rcv_b1_s cn52xx; -+ struct cvmx_npei_pcie_msi_rcv_b1_s cn52xxp1; -+ struct cvmx_npei_pcie_msi_rcv_b1_s cn56xx; -+ struct cvmx_npei_pcie_msi_rcv_b1_s cn56xxp1; -+}; -+ -+union cvmx_npei_pcie_msi_rcv_b2 { -+ uint64_t u64; -+ struct cvmx_npei_pcie_msi_rcv_b2_s { -+ uint64_t reserved_24_63:40; -+ uint64_t intr:8; -+ uint64_t reserved_0_15:16; -+ } s; -+ struct cvmx_npei_pcie_msi_rcv_b2_s cn52xx; -+ struct cvmx_npei_pcie_msi_rcv_b2_s cn52xxp1; -+ struct cvmx_npei_pcie_msi_rcv_b2_s cn56xx; -+ struct cvmx_npei_pcie_msi_rcv_b2_s cn56xxp1; -+}; -+ -+union cvmx_npei_pcie_msi_rcv_b3 { -+ uint64_t u64; -+ struct cvmx_npei_pcie_msi_rcv_b3_s { -+ uint64_t reserved_32_63:32; -+ uint64_t intr:8; -+ uint64_t reserved_0_23:24; -+ } s; -+ struct cvmx_npei_pcie_msi_rcv_b3_s cn52xx; -+ struct cvmx_npei_pcie_msi_rcv_b3_s cn52xxp1; -+ struct cvmx_npei_pcie_msi_rcv_b3_s cn56xx; -+ struct cvmx_npei_pcie_msi_rcv_b3_s cn56xxp1; -+}; -+ -+union cvmx_npei_pktx_cnts { -+ uint64_t u64; -+ struct cvmx_npei_pktx_cnts_s { -+ uint64_t reserved_54_63:10; -+ uint64_t timer:22; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_npei_pktx_cnts_s cn52xx; -+ struct cvmx_npei_pktx_cnts_s cn56xx; -+ struct cvmx_npei_pktx_cnts_s cn56xxp1; -+}; -+ -+union cvmx_npei_pktx_in_bp { -+ uint64_t u64; -+ struct cvmx_npei_pktx_in_bp_s { -+ uint64_t wmark:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_npei_pktx_in_bp_s cn52xx; -+ struct cvmx_npei_pktx_in_bp_s cn56xx; -+ struct cvmx_npei_pktx_in_bp_s cn56xxp1; -+}; -+ -+union cvmx_npei_pktx_instr_baddr { -+ uint64_t u64; -+ struct cvmx_npei_pktx_instr_baddr_s { -+ uint64_t addr:61; -+ uint64_t reserved_0_2:3; -+ } s; -+ struct cvmx_npei_pktx_instr_baddr_s cn52xx; -+ struct cvmx_npei_pktx_instr_baddr_s cn56xx; -+ struct cvmx_npei_pktx_instr_baddr_s cn56xxp1; -+}; -+ -+union cvmx_npei_pktx_instr_baoff_dbell { -+ uint64_t u64; -+ struct cvmx_npei_pktx_instr_baoff_dbell_s { -+ uint64_t aoff:32; -+ uint64_t dbell:32; -+ } s; -+ struct cvmx_npei_pktx_instr_baoff_dbell_s cn52xx; -+ struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xx; -+ struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xxp1; -+}; -+ -+union cvmx_npei_pktx_instr_fifo_rsize { -+ uint64_t u64; -+ struct cvmx_npei_pktx_instr_fifo_rsize_s { -+ uint64_t max:9; -+ uint64_t rrp:9; -+ uint64_t wrp:9; -+ uint64_t fcnt:5; -+ uint64_t rsize:32; -+ } s; -+ struct cvmx_npei_pktx_instr_fifo_rsize_s cn52xx; -+ struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xx; -+ struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xxp1; -+}; -+ -+union cvmx_npei_pktx_instr_header { -+ uint64_t u64; -+ struct cvmx_npei_pktx_instr_header_s { -+ uint64_t reserved_44_63:20; -+ uint64_t pbp:1; -+ uint64_t rsv_f:5; -+ uint64_t rparmode:2; -+ uint64_t rsv_e:1; -+ uint64_t rskp_len:7; -+ uint64_t rsv_d:6; -+ uint64_t use_ihdr:1; -+ uint64_t rsv_c:5; -+ uint64_t par_mode:2; -+ uint64_t rsv_b:1; -+ uint64_t skp_len:7; -+ uint64_t rsv_a:6; -+ } s; -+ struct cvmx_npei_pktx_instr_header_s cn52xx; -+ struct cvmx_npei_pktx_instr_header_s cn56xx; -+ struct cvmx_npei_pktx_instr_header_s cn56xxp1; -+}; -+ -+union cvmx_npei_pktx_slist_baddr { -+ uint64_t u64; -+ struct cvmx_npei_pktx_slist_baddr_s { -+ uint64_t addr:60; -+ uint64_t reserved_0_3:4; -+ } s; -+ struct cvmx_npei_pktx_slist_baddr_s cn52xx; -+ struct cvmx_npei_pktx_slist_baddr_s cn56xx; -+ struct cvmx_npei_pktx_slist_baddr_s cn56xxp1; -+}; -+ -+union cvmx_npei_pktx_slist_baoff_dbell { -+ uint64_t u64; -+ struct cvmx_npei_pktx_slist_baoff_dbell_s { -+ uint64_t aoff:32; -+ uint64_t dbell:32; -+ } s; -+ struct cvmx_npei_pktx_slist_baoff_dbell_s cn52xx; -+ struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xx; -+ struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xxp1; -+}; -+ -+union cvmx_npei_pktx_slist_fifo_rsize { -+ uint64_t u64; -+ struct cvmx_npei_pktx_slist_fifo_rsize_s { -+ uint64_t reserved_32_63:32; -+ uint64_t rsize:32; -+ } s; -+ struct cvmx_npei_pktx_slist_fifo_rsize_s cn52xx; -+ struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xx; -+ struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_cnt_int { -+ uint64_t u64; -+ struct cvmx_npei_pkt_cnt_int_s { -+ uint64_t reserved_32_63:32; -+ uint64_t port:32; -+ } s; -+ struct cvmx_npei_pkt_cnt_int_s cn52xx; -+ struct cvmx_npei_pkt_cnt_int_s cn56xx; -+ struct cvmx_npei_pkt_cnt_int_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_cnt_int_enb { -+ uint64_t u64; -+ struct cvmx_npei_pkt_cnt_int_enb_s { -+ uint64_t reserved_32_63:32; -+ uint64_t port:32; -+ } s; -+ struct cvmx_npei_pkt_cnt_int_enb_s cn52xx; -+ struct cvmx_npei_pkt_cnt_int_enb_s cn56xx; -+ struct cvmx_npei_pkt_cnt_int_enb_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_data_out_es { -+ uint64_t u64; -+ struct cvmx_npei_pkt_data_out_es_s { -+ uint64_t es:64; -+ } s; -+ struct cvmx_npei_pkt_data_out_es_s cn52xx; -+ struct cvmx_npei_pkt_data_out_es_s cn56xx; -+ struct cvmx_npei_pkt_data_out_es_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_data_out_ns { -+ uint64_t u64; -+ struct cvmx_npei_pkt_data_out_ns_s { -+ uint64_t reserved_32_63:32; -+ uint64_t nsr:32; -+ } s; -+ struct cvmx_npei_pkt_data_out_ns_s cn52xx; -+ struct cvmx_npei_pkt_data_out_ns_s cn56xx; -+ struct cvmx_npei_pkt_data_out_ns_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_data_out_ror { -+ uint64_t u64; -+ struct cvmx_npei_pkt_data_out_ror_s { -+ uint64_t reserved_32_63:32; -+ uint64_t ror:32; -+ } s; -+ struct cvmx_npei_pkt_data_out_ror_s cn52xx; -+ struct cvmx_npei_pkt_data_out_ror_s cn56xx; -+ struct cvmx_npei_pkt_data_out_ror_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_dpaddr { -+ uint64_t u64; -+ struct cvmx_npei_pkt_dpaddr_s { -+ uint64_t reserved_32_63:32; -+ uint64_t dptr:32; -+ } s; -+ struct cvmx_npei_pkt_dpaddr_s cn52xx; -+ struct cvmx_npei_pkt_dpaddr_s cn56xx; -+ struct cvmx_npei_pkt_dpaddr_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_in_bp { -+ uint64_t u64; -+ struct cvmx_npei_pkt_in_bp_s { -+ uint64_t reserved_32_63:32; -+ uint64_t bp:32; -+ } s; -+ struct cvmx_npei_pkt_in_bp_s cn56xx; -+}; -+ -+union cvmx_npei_pkt_in_donex_cnts { -+ uint64_t u64; -+ struct cvmx_npei_pkt_in_donex_cnts_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_npei_pkt_in_donex_cnts_s cn52xx; -+ struct cvmx_npei_pkt_in_donex_cnts_s cn56xx; -+ struct cvmx_npei_pkt_in_donex_cnts_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_in_instr_counts { -+ uint64_t u64; -+ struct cvmx_npei_pkt_in_instr_counts_s { -+ uint64_t wr_cnt:32; -+ uint64_t rd_cnt:32; -+ } s; -+ struct cvmx_npei_pkt_in_instr_counts_s cn52xx; -+ struct cvmx_npei_pkt_in_instr_counts_s cn56xx; -+}; -+ -+union cvmx_npei_pkt_in_pcie_port { -+ uint64_t u64; -+ struct cvmx_npei_pkt_in_pcie_port_s { -+ uint64_t pp:64; -+ } s; -+ struct cvmx_npei_pkt_in_pcie_port_s cn52xx; -+ struct cvmx_npei_pkt_in_pcie_port_s cn56xx; -+}; -+ -+union cvmx_npei_pkt_input_control { -+ uint64_t u64; -+ struct cvmx_npei_pkt_input_control_s { -+ uint64_t reserved_23_63:41; -+ uint64_t pkt_rr:1; -+ uint64_t pbp_dhi:13; -+ uint64_t d_nsr:1; -+ uint64_t d_esr:2; -+ uint64_t d_ror:1; -+ uint64_t use_csr:1; -+ uint64_t nsr:1; -+ uint64_t esr:2; -+ uint64_t ror:1; -+ } s; -+ struct cvmx_npei_pkt_input_control_s cn52xx; -+ struct cvmx_npei_pkt_input_control_s cn56xx; -+ struct cvmx_npei_pkt_input_control_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_instr_enb { -+ uint64_t u64; -+ struct cvmx_npei_pkt_instr_enb_s { -+ uint64_t reserved_32_63:32; -+ uint64_t enb:32; -+ } s; -+ struct cvmx_npei_pkt_instr_enb_s cn52xx; -+ struct cvmx_npei_pkt_instr_enb_s cn56xx; -+ struct cvmx_npei_pkt_instr_enb_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_instr_rd_size { -+ uint64_t u64; -+ struct cvmx_npei_pkt_instr_rd_size_s { -+ uint64_t rdsize:64; -+ } s; -+ struct cvmx_npei_pkt_instr_rd_size_s cn52xx; -+ struct cvmx_npei_pkt_instr_rd_size_s cn56xx; -+}; -+ -+union cvmx_npei_pkt_instr_size { -+ uint64_t u64; -+ struct cvmx_npei_pkt_instr_size_s { -+ uint64_t reserved_32_63:32; -+ uint64_t is_64b:32; -+ } s; -+ struct cvmx_npei_pkt_instr_size_s cn52xx; -+ struct cvmx_npei_pkt_instr_size_s cn56xx; -+ struct cvmx_npei_pkt_instr_size_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_int_levels { -+ uint64_t u64; -+ struct cvmx_npei_pkt_int_levels_s { -+ uint64_t reserved_54_63:10; -+ uint64_t time:22; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_npei_pkt_int_levels_s cn52xx; -+ struct cvmx_npei_pkt_int_levels_s cn56xx; -+ struct cvmx_npei_pkt_int_levels_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_iptr { -+ uint64_t u64; -+ struct cvmx_npei_pkt_iptr_s { -+ uint64_t reserved_32_63:32; -+ uint64_t iptr:32; -+ } s; -+ struct cvmx_npei_pkt_iptr_s cn52xx; -+ struct cvmx_npei_pkt_iptr_s cn56xx; -+ struct cvmx_npei_pkt_iptr_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_out_bmode { -+ uint64_t u64; -+ struct cvmx_npei_pkt_out_bmode_s { -+ uint64_t reserved_32_63:32; -+ uint64_t bmode:32; -+ } s; -+ struct cvmx_npei_pkt_out_bmode_s cn52xx; -+ struct cvmx_npei_pkt_out_bmode_s cn56xx; -+ struct cvmx_npei_pkt_out_bmode_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_out_enb { -+ uint64_t u64; -+ struct cvmx_npei_pkt_out_enb_s { -+ uint64_t reserved_32_63:32; -+ uint64_t enb:32; -+ } s; -+ struct cvmx_npei_pkt_out_enb_s cn52xx; -+ struct cvmx_npei_pkt_out_enb_s cn56xx; -+ struct cvmx_npei_pkt_out_enb_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_output_wmark { -+ uint64_t u64; -+ struct cvmx_npei_pkt_output_wmark_s { -+ uint64_t reserved_32_63:32; -+ uint64_t wmark:32; -+ } s; -+ struct cvmx_npei_pkt_output_wmark_s cn52xx; -+ struct cvmx_npei_pkt_output_wmark_s cn56xx; -+}; -+ -+union cvmx_npei_pkt_pcie_port { -+ uint64_t u64; -+ struct cvmx_npei_pkt_pcie_port_s { -+ uint64_t pp:64; -+ } s; -+ struct cvmx_npei_pkt_pcie_port_s cn52xx; -+ struct cvmx_npei_pkt_pcie_port_s cn56xx; -+ struct cvmx_npei_pkt_pcie_port_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_port_in_rst { -+ uint64_t u64; -+ struct cvmx_npei_pkt_port_in_rst_s { -+ uint64_t in_rst:32; -+ uint64_t out_rst:32; -+ } s; -+ struct cvmx_npei_pkt_port_in_rst_s cn52xx; -+ struct cvmx_npei_pkt_port_in_rst_s cn56xx; -+}; -+ -+union cvmx_npei_pkt_slist_es { -+ uint64_t u64; -+ struct cvmx_npei_pkt_slist_es_s { -+ uint64_t es:64; -+ } s; -+ struct cvmx_npei_pkt_slist_es_s cn52xx; -+ struct cvmx_npei_pkt_slist_es_s cn56xx; -+ struct cvmx_npei_pkt_slist_es_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_slist_id_size { -+ uint64_t u64; -+ struct cvmx_npei_pkt_slist_id_size_s { -+ uint64_t reserved_23_63:41; -+ uint64_t isize:7; -+ uint64_t bsize:16; -+ } s; -+ struct cvmx_npei_pkt_slist_id_size_s cn52xx; -+ struct cvmx_npei_pkt_slist_id_size_s cn56xx; -+ struct cvmx_npei_pkt_slist_id_size_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_slist_ns { -+ uint64_t u64; -+ struct cvmx_npei_pkt_slist_ns_s { -+ uint64_t reserved_32_63:32; -+ uint64_t nsr:32; -+ } s; -+ struct cvmx_npei_pkt_slist_ns_s cn52xx; -+ struct cvmx_npei_pkt_slist_ns_s cn56xx; -+ struct cvmx_npei_pkt_slist_ns_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_slist_ror { -+ uint64_t u64; -+ struct cvmx_npei_pkt_slist_ror_s { -+ uint64_t reserved_32_63:32; -+ uint64_t ror:32; -+ } s; -+ struct cvmx_npei_pkt_slist_ror_s cn52xx; -+ struct cvmx_npei_pkt_slist_ror_s cn56xx; -+ struct cvmx_npei_pkt_slist_ror_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_time_int { -+ uint64_t u64; -+ struct cvmx_npei_pkt_time_int_s { -+ uint64_t reserved_32_63:32; -+ uint64_t port:32; -+ } s; -+ struct cvmx_npei_pkt_time_int_s cn52xx; -+ struct cvmx_npei_pkt_time_int_s cn56xx; -+ struct cvmx_npei_pkt_time_int_s cn56xxp1; -+}; -+ -+union cvmx_npei_pkt_time_int_enb { -+ uint64_t u64; -+ struct cvmx_npei_pkt_time_int_enb_s { -+ uint64_t reserved_32_63:32; -+ uint64_t port:32; -+ } s; -+ struct cvmx_npei_pkt_time_int_enb_s cn52xx; -+ struct cvmx_npei_pkt_time_int_enb_s cn56xx; -+ struct cvmx_npei_pkt_time_int_enb_s cn56xxp1; -+}; -+ -+union cvmx_npei_rsl_int_blocks { -+ uint64_t u64; -+ struct cvmx_npei_rsl_int_blocks_s { -+ uint64_t reserved_31_63:33; -+ uint64_t iob:1; -+ uint64_t lmc1:1; -+ uint64_t agl:1; -+ uint64_t reserved_24_27:4; -+ uint64_t asxpcs1:1; -+ uint64_t asxpcs0:1; -+ uint64_t reserved_21_21:1; -+ uint64_t pip:1; -+ uint64_t reserved_18_19:2; -+ uint64_t lmc0:1; -+ uint64_t l2c:1; -+ uint64_t usb1:1; -+ uint64_t rad:1; -+ uint64_t usb:1; -+ uint64_t pow:1; -+ uint64_t tim:1; -+ uint64_t pko:1; -+ uint64_t ipd:1; -+ uint64_t reserved_8_8:1; -+ uint64_t zip:1; -+ uint64_t reserved_6_6:1; -+ uint64_t fpa:1; -+ uint64_t key:1; -+ uint64_t npei:1; -+ uint64_t gmx1:1; -+ uint64_t gmx0:1; -+ uint64_t mio:1; -+ } s; -+ struct cvmx_npei_rsl_int_blocks_s cn52xx; -+ struct cvmx_npei_rsl_int_blocks_s cn52xxp1; -+ struct cvmx_npei_rsl_int_blocks_cn56xx { -+ uint64_t reserved_31_63:33; -+ uint64_t iob:1; -+ uint64_t lmc1:1; -+ uint64_t agl:1; -+ uint64_t reserved_24_27:4; -+ uint64_t asxpcs1:1; -+ uint64_t asxpcs0:1; -+ uint64_t reserved_21_21:1; -+ uint64_t pip:1; -+ uint64_t reserved_18_19:2; -+ uint64_t lmc0:1; -+ uint64_t l2c:1; -+ uint64_t reserved_15_15:1; -+ uint64_t rad:1; -+ uint64_t usb:1; -+ uint64_t pow:1; -+ uint64_t tim:1; -+ uint64_t pko:1; -+ uint64_t ipd:1; -+ uint64_t reserved_8_8:1; -+ uint64_t zip:1; -+ uint64_t reserved_6_6:1; -+ uint64_t fpa:1; -+ uint64_t key:1; -+ uint64_t npei:1; -+ uint64_t gmx1:1; -+ uint64_t gmx0:1; -+ uint64_t mio:1; -+ } cn56xx; -+ struct cvmx_npei_rsl_int_blocks_cn56xx cn56xxp1; -+}; -+ -+union cvmx_npei_scratch_1 { -+ uint64_t u64; -+ struct cvmx_npei_scratch_1_s { -+ uint64_t data:64; -+ } s; -+ struct cvmx_npei_scratch_1_s cn52xx; -+ struct cvmx_npei_scratch_1_s cn52xxp1; -+ struct cvmx_npei_scratch_1_s cn56xx; -+ struct cvmx_npei_scratch_1_s cn56xxp1; -+}; -+ -+union cvmx_npei_state1 { -+ uint64_t u64; -+ struct cvmx_npei_state1_s { -+ uint64_t cpl1:12; -+ uint64_t cpl0:12; -+ uint64_t arb:1; -+ uint64_t csr:39; -+ } s; -+ struct cvmx_npei_state1_s cn52xx; -+ struct cvmx_npei_state1_s cn52xxp1; -+ struct cvmx_npei_state1_s cn56xx; -+ struct cvmx_npei_state1_s cn56xxp1; -+}; -+ -+union cvmx_npei_state2 { -+ uint64_t u64; -+ struct cvmx_npei_state2_s { -+ uint64_t reserved_48_63:16; -+ uint64_t npei:1; -+ uint64_t rac:1; -+ uint64_t csm1:15; -+ uint64_t csm0:15; -+ uint64_t nnp0:8; -+ uint64_t nnd:8; -+ } s; -+ struct cvmx_npei_state2_s cn52xx; -+ struct cvmx_npei_state2_s cn52xxp1; -+ struct cvmx_npei_state2_s cn56xx; -+ struct cvmx_npei_state2_s cn56xxp1; -+}; -+ -+union cvmx_npei_state3 { -+ uint64_t u64; -+ struct cvmx_npei_state3_s { -+ uint64_t reserved_56_63:8; -+ uint64_t psm1:15; -+ uint64_t psm0:15; -+ uint64_t nsm1:13; -+ uint64_t nsm0:13; -+ } s; -+ struct cvmx_npei_state3_s cn52xx; -+ struct cvmx_npei_state3_s cn52xxp1; -+ struct cvmx_npei_state3_s cn56xx; -+ struct cvmx_npei_state3_s cn56xxp1; -+}; -+ -+union cvmx_npei_win_rd_addr { -+ uint64_t u64; -+ struct cvmx_npei_win_rd_addr_s { -+ uint64_t reserved_51_63:13; -+ uint64_t ld_cmd:2; -+ uint64_t iobit:1; -+ uint64_t rd_addr:48; -+ } s; -+ struct cvmx_npei_win_rd_addr_s cn52xx; -+ struct cvmx_npei_win_rd_addr_s cn52xxp1; -+ struct cvmx_npei_win_rd_addr_s cn56xx; -+ struct cvmx_npei_win_rd_addr_s cn56xxp1; -+}; -+ -+union cvmx_npei_win_rd_data { -+ uint64_t u64; -+ struct cvmx_npei_win_rd_data_s { -+ uint64_t rd_data:64; -+ } s; -+ struct cvmx_npei_win_rd_data_s cn52xx; -+ struct cvmx_npei_win_rd_data_s cn52xxp1; -+ struct cvmx_npei_win_rd_data_s cn56xx; -+ struct cvmx_npei_win_rd_data_s cn56xxp1; -+}; -+ -+union cvmx_npei_win_wr_addr { -+ uint64_t u64; -+ struct cvmx_npei_win_wr_addr_s { -+ uint64_t reserved_49_63:15; -+ uint64_t iobit:1; -+ uint64_t wr_addr:46; -+ uint64_t reserved_0_1:2; -+ } s; -+ struct cvmx_npei_win_wr_addr_s cn52xx; -+ struct cvmx_npei_win_wr_addr_s cn52xxp1; -+ struct cvmx_npei_win_wr_addr_s cn56xx; -+ struct cvmx_npei_win_wr_addr_s cn56xxp1; -+}; -+ -+union cvmx_npei_win_wr_data { -+ uint64_t u64; -+ struct cvmx_npei_win_wr_data_s { -+ uint64_t wr_data:64; -+ } s; -+ struct cvmx_npei_win_wr_data_s cn52xx; -+ struct cvmx_npei_win_wr_data_s cn52xxp1; -+ struct cvmx_npei_win_wr_data_s cn56xx; -+ struct cvmx_npei_win_wr_data_s cn56xxp1; -+}; -+ -+union cvmx_npei_win_wr_mask { -+ uint64_t u64; -+ struct cvmx_npei_win_wr_mask_s { -+ uint64_t reserved_8_63:56; -+ uint64_t wr_mask:8; -+ } s; -+ struct cvmx_npei_win_wr_mask_s cn52xx; -+ struct cvmx_npei_win_wr_mask_s cn52xxp1; -+ struct cvmx_npei_win_wr_mask_s cn56xx; -+ struct cvmx_npei_win_wr_mask_s cn56xxp1; -+}; -+ -+union cvmx_npei_window_ctl { -+ uint64_t u64; -+ struct cvmx_npei_window_ctl_s { -+ uint64_t reserved_32_63:32; -+ uint64_t time:32; -+ } s; -+ struct cvmx_npei_window_ctl_s cn52xx; -+ struct cvmx_npei_window_ctl_s cn52xxp1; -+ struct cvmx_npei_window_ctl_s cn56xx; -+ struct cvmx_npei_window_ctl_s cn56xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-npi-defs.h -@@ -0,0 +1,1735 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_NPI_DEFS_H__ -+#define __CVMX_NPI_DEFS_H__ -+ -+#define CVMX_NPI_BASE_ADDR_INPUT0 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000070ull) -+#define CVMX_NPI_BASE_ADDR_INPUT1 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000080ull) -+#define CVMX_NPI_BASE_ADDR_INPUT2 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000090ull) -+#define CVMX_NPI_BASE_ADDR_INPUT3 \ -+ CVMX_ADD_IO_SEG(0x00011F00000000A0ull) -+#define CVMX_NPI_BASE_ADDR_INPUTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000000070ull + (((offset) & 3) * 16)) -+#define CVMX_NPI_BASE_ADDR_OUTPUT0 \ -+ CVMX_ADD_IO_SEG(0x00011F00000000B8ull) -+#define CVMX_NPI_BASE_ADDR_OUTPUT1 \ -+ CVMX_ADD_IO_SEG(0x00011F00000000C0ull) -+#define CVMX_NPI_BASE_ADDR_OUTPUT2 \ -+ CVMX_ADD_IO_SEG(0x00011F00000000C8ull) -+#define CVMX_NPI_BASE_ADDR_OUTPUT3 \ -+ CVMX_ADD_IO_SEG(0x00011F00000000D0ull) -+#define CVMX_NPI_BASE_ADDR_OUTPUTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F00000000B8ull + (((offset) & 3) * 8)) -+#define CVMX_NPI_BIST_STATUS \ -+ CVMX_ADD_IO_SEG(0x00011F00000003F8ull) -+#define CVMX_NPI_BUFF_SIZE_OUTPUT0 \ -+ CVMX_ADD_IO_SEG(0x00011F00000000E0ull) -+#define CVMX_NPI_BUFF_SIZE_OUTPUT1 \ -+ CVMX_ADD_IO_SEG(0x00011F00000000E8ull) -+#define CVMX_NPI_BUFF_SIZE_OUTPUT2 \ -+ CVMX_ADD_IO_SEG(0x00011F00000000F0ull) -+#define CVMX_NPI_BUFF_SIZE_OUTPUT3 \ -+ CVMX_ADD_IO_SEG(0x00011F00000000F8ull) -+#define CVMX_NPI_BUFF_SIZE_OUTPUTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F00000000E0ull + (((offset) & 3) * 8)) -+#define CVMX_NPI_COMP_CTL \ -+ CVMX_ADD_IO_SEG(0x00011F0000000218ull) -+#define CVMX_NPI_CTL_STATUS \ -+ CVMX_ADD_IO_SEG(0x00011F0000000010ull) -+#define CVMX_NPI_DBG_SELECT \ -+ CVMX_ADD_IO_SEG(0x00011F0000000008ull) -+#define CVMX_NPI_DMA_CONTROL \ -+ CVMX_ADD_IO_SEG(0x00011F0000000128ull) -+#define CVMX_NPI_DMA_HIGHP_COUNTS \ -+ CVMX_ADD_IO_SEG(0x00011F0000000148ull) -+#define CVMX_NPI_DMA_HIGHP_NADDR \ -+ CVMX_ADD_IO_SEG(0x00011F0000000158ull) -+#define CVMX_NPI_DMA_LOWP_COUNTS \ -+ CVMX_ADD_IO_SEG(0x00011F0000000140ull) -+#define CVMX_NPI_DMA_LOWP_NADDR \ -+ CVMX_ADD_IO_SEG(0x00011F0000000150ull) -+#define CVMX_NPI_HIGHP_DBELL \ -+ CVMX_ADD_IO_SEG(0x00011F0000000120ull) -+#define CVMX_NPI_HIGHP_IBUFF_SADDR \ -+ CVMX_ADD_IO_SEG(0x00011F0000000110ull) -+#define CVMX_NPI_INPUT_CONTROL \ -+ CVMX_ADD_IO_SEG(0x00011F0000000138ull) -+#define CVMX_NPI_INT_ENB \ -+ CVMX_ADD_IO_SEG(0x00011F0000000020ull) -+#define CVMX_NPI_INT_SUM \ -+ CVMX_ADD_IO_SEG(0x00011F0000000018ull) -+#define CVMX_NPI_LOWP_DBELL \ -+ CVMX_ADD_IO_SEG(0x00011F0000000118ull) -+#define CVMX_NPI_LOWP_IBUFF_SADDR \ -+ CVMX_ADD_IO_SEG(0x00011F0000000108ull) -+#define CVMX_NPI_MEM_ACCESS_SUBID3 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000028ull) -+#define CVMX_NPI_MEM_ACCESS_SUBID4 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000030ull) -+#define CVMX_NPI_MEM_ACCESS_SUBID5 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000038ull) -+#define CVMX_NPI_MEM_ACCESS_SUBID6 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000040ull) -+#define CVMX_NPI_MEM_ACCESS_SUBIDX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000000028ull + (((offset) & 7) * 8) - 8 * 3) -+#define CVMX_NPI_MSI_RCV \ -+ (0x0000000000000190ull) -+#define CVMX_NPI_NPI_MSI_RCV \ -+ CVMX_ADD_IO_SEG(0x00011F0000001190ull) -+#define CVMX_NPI_NUM_DESC_OUTPUT0 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000050ull) -+#define CVMX_NPI_NUM_DESC_OUTPUT1 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000058ull) -+#define CVMX_NPI_NUM_DESC_OUTPUT2 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000060ull) -+#define CVMX_NPI_NUM_DESC_OUTPUT3 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000068ull) -+#define CVMX_NPI_NUM_DESC_OUTPUTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000000050ull + (((offset) & 3) * 8)) -+#define CVMX_NPI_OUTPUT_CONTROL \ -+ CVMX_ADD_IO_SEG(0x00011F0000000100ull) -+#define CVMX_NPI_P0_DBPAIR_ADDR \ -+ CVMX_ADD_IO_SEG(0x00011F0000000180ull) -+#define CVMX_NPI_P0_INSTR_ADDR \ -+ CVMX_ADD_IO_SEG(0x00011F00000001C0ull) -+#define CVMX_NPI_P0_INSTR_CNTS \ -+ CVMX_ADD_IO_SEG(0x00011F00000001A0ull) -+#define CVMX_NPI_P0_PAIR_CNTS \ -+ CVMX_ADD_IO_SEG(0x00011F0000000160ull) -+#define CVMX_NPI_P1_DBPAIR_ADDR \ -+ CVMX_ADD_IO_SEG(0x00011F0000000188ull) -+#define CVMX_NPI_P1_INSTR_ADDR \ -+ CVMX_ADD_IO_SEG(0x00011F00000001C8ull) -+#define CVMX_NPI_P1_INSTR_CNTS \ -+ CVMX_ADD_IO_SEG(0x00011F00000001A8ull) -+#define CVMX_NPI_P1_PAIR_CNTS \ -+ CVMX_ADD_IO_SEG(0x00011F0000000168ull) -+#define CVMX_NPI_P2_DBPAIR_ADDR \ -+ CVMX_ADD_IO_SEG(0x00011F0000000190ull) -+#define CVMX_NPI_P2_INSTR_ADDR \ -+ CVMX_ADD_IO_SEG(0x00011F00000001D0ull) -+#define CVMX_NPI_P2_INSTR_CNTS \ -+ CVMX_ADD_IO_SEG(0x00011F00000001B0ull) -+#define CVMX_NPI_P2_PAIR_CNTS \ -+ CVMX_ADD_IO_SEG(0x00011F0000000170ull) -+#define CVMX_NPI_P3_DBPAIR_ADDR \ -+ CVMX_ADD_IO_SEG(0x00011F0000000198ull) -+#define CVMX_NPI_P3_INSTR_ADDR \ -+ CVMX_ADD_IO_SEG(0x00011F00000001D8ull) -+#define CVMX_NPI_P3_INSTR_CNTS \ -+ CVMX_ADD_IO_SEG(0x00011F00000001B8ull) -+#define CVMX_NPI_P3_PAIR_CNTS \ -+ CVMX_ADD_IO_SEG(0x00011F0000000178ull) -+#define CVMX_NPI_PCI_BAR1_INDEXX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000001100ull + (((offset) & 31) * 4)) -+#define CVMX_NPI_PCI_BIST_REG \ -+ CVMX_ADD_IO_SEG(0x00011F00000011C0ull) -+#define CVMX_NPI_PCI_BURST_SIZE \ -+ CVMX_ADD_IO_SEG(0x00011F00000000D8ull) -+#define CVMX_NPI_PCI_CFG00 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001800ull) -+#define CVMX_NPI_PCI_CFG01 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001804ull) -+#define CVMX_NPI_PCI_CFG02 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001808ull) -+#define CVMX_NPI_PCI_CFG03 \ -+ CVMX_ADD_IO_SEG(0x00011F000000180Cull) -+#define CVMX_NPI_PCI_CFG04 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001810ull) -+#define CVMX_NPI_PCI_CFG05 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001814ull) -+#define CVMX_NPI_PCI_CFG06 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001818ull) -+#define CVMX_NPI_PCI_CFG07 \ -+ CVMX_ADD_IO_SEG(0x00011F000000181Cull) -+#define CVMX_NPI_PCI_CFG08 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001820ull) -+#define CVMX_NPI_PCI_CFG09 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001824ull) -+#define CVMX_NPI_PCI_CFG10 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001828ull) -+#define CVMX_NPI_PCI_CFG11 \ -+ CVMX_ADD_IO_SEG(0x00011F000000182Cull) -+#define CVMX_NPI_PCI_CFG12 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001830ull) -+#define CVMX_NPI_PCI_CFG13 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001834ull) -+#define CVMX_NPI_PCI_CFG15 \ -+ CVMX_ADD_IO_SEG(0x00011F000000183Cull) -+#define CVMX_NPI_PCI_CFG16 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001840ull) -+#define CVMX_NPI_PCI_CFG17 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001844ull) -+#define CVMX_NPI_PCI_CFG18 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001848ull) -+#define CVMX_NPI_PCI_CFG19 \ -+ CVMX_ADD_IO_SEG(0x00011F000000184Cull) -+#define CVMX_NPI_PCI_CFG20 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001850ull) -+#define CVMX_NPI_PCI_CFG21 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001854ull) -+#define CVMX_NPI_PCI_CFG22 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001858ull) -+#define CVMX_NPI_PCI_CFG56 \ -+ CVMX_ADD_IO_SEG(0x00011F00000018E0ull) -+#define CVMX_NPI_PCI_CFG57 \ -+ CVMX_ADD_IO_SEG(0x00011F00000018E4ull) -+#define CVMX_NPI_PCI_CFG58 \ -+ CVMX_ADD_IO_SEG(0x00011F00000018E8ull) -+#define CVMX_NPI_PCI_CFG59 \ -+ CVMX_ADD_IO_SEG(0x00011F00000018ECull) -+#define CVMX_NPI_PCI_CFG60 \ -+ CVMX_ADD_IO_SEG(0x00011F00000018F0ull) -+#define CVMX_NPI_PCI_CFG61 \ -+ CVMX_ADD_IO_SEG(0x00011F00000018F4ull) -+#define CVMX_NPI_PCI_CFG62 \ -+ CVMX_ADD_IO_SEG(0x00011F00000018F8ull) -+#define CVMX_NPI_PCI_CFG63 \ -+ CVMX_ADD_IO_SEG(0x00011F00000018FCull) -+#define CVMX_NPI_PCI_CNT_REG \ -+ CVMX_ADD_IO_SEG(0x00011F00000011B8ull) -+#define CVMX_NPI_PCI_CTL_STATUS_2 \ -+ CVMX_ADD_IO_SEG(0x00011F000000118Cull) -+#define CVMX_NPI_PCI_INT_ARB_CFG \ -+ CVMX_ADD_IO_SEG(0x00011F0000000130ull) -+#define CVMX_NPI_PCI_INT_ENB2 \ -+ CVMX_ADD_IO_SEG(0x00011F00000011A0ull) -+#define CVMX_NPI_PCI_INT_SUM2 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001198ull) -+#define CVMX_NPI_PCI_READ_CMD \ -+ CVMX_ADD_IO_SEG(0x00011F0000000048ull) -+#define CVMX_NPI_PCI_READ_CMD_6 \ -+ CVMX_ADD_IO_SEG(0x00011F0000001180ull) -+#define CVMX_NPI_PCI_READ_CMD_C \ -+ CVMX_ADD_IO_SEG(0x00011F0000001184ull) -+#define CVMX_NPI_PCI_READ_CMD_E \ -+ CVMX_ADD_IO_SEG(0x00011F0000001188ull) -+#define CVMX_NPI_PCI_SCM_REG \ -+ CVMX_ADD_IO_SEG(0x00011F00000011A8ull) -+#define CVMX_NPI_PCI_TSR_REG \ -+ CVMX_ADD_IO_SEG(0x00011F00000011B0ull) -+#define CVMX_NPI_PORT32_INSTR_HDR \ -+ CVMX_ADD_IO_SEG(0x00011F00000001F8ull) -+#define CVMX_NPI_PORT33_INSTR_HDR \ -+ CVMX_ADD_IO_SEG(0x00011F0000000200ull) -+#define CVMX_NPI_PORT34_INSTR_HDR \ -+ CVMX_ADD_IO_SEG(0x00011F0000000208ull) -+#define CVMX_NPI_PORT35_INSTR_HDR \ -+ CVMX_ADD_IO_SEG(0x00011F0000000210ull) -+#define CVMX_NPI_PORT_BP_CONTROL \ -+ CVMX_ADD_IO_SEG(0x00011F00000001F0ull) -+#define CVMX_NPI_PX_DBPAIR_ADDR(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000000180ull + (((offset) & 3) * 8)) -+#define CVMX_NPI_PX_INSTR_ADDR(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F00000001C0ull + (((offset) & 3) * 8)) -+#define CVMX_NPI_PX_INSTR_CNTS(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F00000001A0ull + (((offset) & 3) * 8)) -+#define CVMX_NPI_PX_PAIR_CNTS(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000000160ull + (((offset) & 3) * 8)) -+#define CVMX_NPI_RSL_INT_BLOCKS \ -+ CVMX_ADD_IO_SEG(0x00011F0000000000ull) -+#define CVMX_NPI_SIZE_INPUT0 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000078ull) -+#define CVMX_NPI_SIZE_INPUT1 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000088ull) -+#define CVMX_NPI_SIZE_INPUT2 \ -+ CVMX_ADD_IO_SEG(0x00011F0000000098ull) -+#define CVMX_NPI_SIZE_INPUT3 \ -+ CVMX_ADD_IO_SEG(0x00011F00000000A8ull) -+#define CVMX_NPI_SIZE_INPUTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000000078ull + (((offset) & 3) * 16)) -+#define CVMX_NPI_WIN_READ_TO \ -+ CVMX_ADD_IO_SEG(0x00011F00000001E0ull) -+ -+union cvmx_npi_base_addr_inputx { -+ uint64_t u64; -+ struct cvmx_npi_base_addr_inputx_s { -+ uint64_t baddr:61; -+ uint64_t reserved_0_2:3; -+ } s; -+ struct cvmx_npi_base_addr_inputx_s cn30xx; -+ struct cvmx_npi_base_addr_inputx_s cn31xx; -+ struct cvmx_npi_base_addr_inputx_s cn38xx; -+ struct cvmx_npi_base_addr_inputx_s cn38xxp2; -+ struct cvmx_npi_base_addr_inputx_s cn50xx; -+ struct cvmx_npi_base_addr_inputx_s cn58xx; -+ struct cvmx_npi_base_addr_inputx_s cn58xxp1; -+}; -+ -+union cvmx_npi_base_addr_outputx { -+ uint64_t u64; -+ struct cvmx_npi_base_addr_outputx_s { -+ uint64_t baddr:61; -+ uint64_t reserved_0_2:3; -+ } s; -+ struct cvmx_npi_base_addr_outputx_s cn30xx; -+ struct cvmx_npi_base_addr_outputx_s cn31xx; -+ struct cvmx_npi_base_addr_outputx_s cn38xx; -+ struct cvmx_npi_base_addr_outputx_s cn38xxp2; -+ struct cvmx_npi_base_addr_outputx_s cn50xx; -+ struct cvmx_npi_base_addr_outputx_s cn58xx; -+ struct cvmx_npi_base_addr_outputx_s cn58xxp1; -+}; -+ -+union cvmx_npi_bist_status { -+ uint64_t u64; -+ struct cvmx_npi_bist_status_s { -+ uint64_t reserved_20_63:44; -+ uint64_t csr_bs:1; -+ uint64_t dif_bs:1; -+ uint64_t rdp_bs:1; -+ uint64_t pcnc_bs:1; -+ uint64_t pcn_bs:1; -+ uint64_t rdn_bs:1; -+ uint64_t pcac_bs:1; -+ uint64_t pcad_bs:1; -+ uint64_t rdnl_bs:1; -+ uint64_t pgf_bs:1; -+ uint64_t pig_bs:1; -+ uint64_t pof0_bs:1; -+ uint64_t pof1_bs:1; -+ uint64_t pof2_bs:1; -+ uint64_t pof3_bs:1; -+ uint64_t pos_bs:1; -+ uint64_t nus_bs:1; -+ uint64_t dob_bs:1; -+ uint64_t pdf_bs:1; -+ uint64_t dpi_bs:1; -+ } s; -+ struct cvmx_npi_bist_status_cn30xx { -+ uint64_t reserved_20_63:44; -+ uint64_t csr_bs:1; -+ uint64_t dif_bs:1; -+ uint64_t rdp_bs:1; -+ uint64_t pcnc_bs:1; -+ uint64_t pcn_bs:1; -+ uint64_t rdn_bs:1; -+ uint64_t pcac_bs:1; -+ uint64_t pcad_bs:1; -+ uint64_t rdnl_bs:1; -+ uint64_t pgf_bs:1; -+ uint64_t pig_bs:1; -+ uint64_t pof0_bs:1; -+ uint64_t reserved_5_7:3; -+ uint64_t pos_bs:1; -+ uint64_t nus_bs:1; -+ uint64_t dob_bs:1; -+ uint64_t pdf_bs:1; -+ uint64_t dpi_bs:1; -+ } cn30xx; -+ struct cvmx_npi_bist_status_s cn31xx; -+ struct cvmx_npi_bist_status_s cn38xx; -+ struct cvmx_npi_bist_status_s cn38xxp2; -+ struct cvmx_npi_bist_status_cn50xx { -+ uint64_t reserved_20_63:44; -+ uint64_t csr_bs:1; -+ uint64_t dif_bs:1; -+ uint64_t rdp_bs:1; -+ uint64_t pcnc_bs:1; -+ uint64_t pcn_bs:1; -+ uint64_t rdn_bs:1; -+ uint64_t pcac_bs:1; -+ uint64_t pcad_bs:1; -+ uint64_t rdnl_bs:1; -+ uint64_t pgf_bs:1; -+ uint64_t pig_bs:1; -+ uint64_t pof0_bs:1; -+ uint64_t pof1_bs:1; -+ uint64_t reserved_5_6:2; -+ uint64_t pos_bs:1; -+ uint64_t nus_bs:1; -+ uint64_t dob_bs:1; -+ uint64_t pdf_bs:1; -+ uint64_t dpi_bs:1; -+ } cn50xx; -+ struct cvmx_npi_bist_status_s cn58xx; -+ struct cvmx_npi_bist_status_s cn58xxp1; -+}; -+ -+union cvmx_npi_buff_size_outputx { -+ uint64_t u64; -+ struct cvmx_npi_buff_size_outputx_s { -+ uint64_t reserved_23_63:41; -+ uint64_t isize:7; -+ uint64_t bsize:16; -+ } s; -+ struct cvmx_npi_buff_size_outputx_s cn30xx; -+ struct cvmx_npi_buff_size_outputx_s cn31xx; -+ struct cvmx_npi_buff_size_outputx_s cn38xx; -+ struct cvmx_npi_buff_size_outputx_s cn38xxp2; -+ struct cvmx_npi_buff_size_outputx_s cn50xx; -+ struct cvmx_npi_buff_size_outputx_s cn58xx; -+ struct cvmx_npi_buff_size_outputx_s cn58xxp1; -+}; -+ -+union cvmx_npi_comp_ctl { -+ uint64_t u64; -+ struct cvmx_npi_comp_ctl_s { -+ uint64_t reserved_10_63:54; -+ uint64_t pctl:5; -+ uint64_t nctl:5; -+ } s; -+ struct cvmx_npi_comp_ctl_s cn50xx; -+ struct cvmx_npi_comp_ctl_s cn58xx; -+ struct cvmx_npi_comp_ctl_s cn58xxp1; -+}; -+ -+union cvmx_npi_ctl_status { -+ uint64_t u64; -+ struct cvmx_npi_ctl_status_s { -+ uint64_t reserved_63_63:1; -+ uint64_t chip_rev:8; -+ uint64_t dis_pniw:1; -+ uint64_t out3_enb:1; -+ uint64_t out2_enb:1; -+ uint64_t out1_enb:1; -+ uint64_t out0_enb:1; -+ uint64_t ins3_enb:1; -+ uint64_t ins2_enb:1; -+ uint64_t ins1_enb:1; -+ uint64_t ins0_enb:1; -+ uint64_t ins3_64b:1; -+ uint64_t ins2_64b:1; -+ uint64_t ins1_64b:1; -+ uint64_t ins0_64b:1; -+ uint64_t pci_wdis:1; -+ uint64_t wait_com:1; -+ uint64_t reserved_37_39:3; -+ uint64_t max_word:5; -+ uint64_t reserved_10_31:22; -+ uint64_t timer:10; -+ } s; -+ struct cvmx_npi_ctl_status_cn30xx { -+ uint64_t reserved_63_63:1; -+ uint64_t chip_rev:8; -+ uint64_t dis_pniw:1; -+ uint64_t reserved_51_53:3; -+ uint64_t out0_enb:1; -+ uint64_t reserved_47_49:3; -+ uint64_t ins0_enb:1; -+ uint64_t reserved_43_45:3; -+ uint64_t ins0_64b:1; -+ uint64_t pci_wdis:1; -+ uint64_t wait_com:1; -+ uint64_t reserved_37_39:3; -+ uint64_t max_word:5; -+ uint64_t reserved_10_31:22; -+ uint64_t timer:10; -+ } cn30xx; -+ struct cvmx_npi_ctl_status_cn31xx { -+ uint64_t reserved_63_63:1; -+ uint64_t chip_rev:8; -+ uint64_t dis_pniw:1; -+ uint64_t reserved_52_53:2; -+ uint64_t out1_enb:1; -+ uint64_t out0_enb:1; -+ uint64_t reserved_48_49:2; -+ uint64_t ins1_enb:1; -+ uint64_t ins0_enb:1; -+ uint64_t reserved_44_45:2; -+ uint64_t ins1_64b:1; -+ uint64_t ins0_64b:1; -+ uint64_t pci_wdis:1; -+ uint64_t wait_com:1; -+ uint64_t reserved_37_39:3; -+ uint64_t max_word:5; -+ uint64_t reserved_10_31:22; -+ uint64_t timer:10; -+ } cn31xx; -+ struct cvmx_npi_ctl_status_s cn38xx; -+ struct cvmx_npi_ctl_status_s cn38xxp2; -+ struct cvmx_npi_ctl_status_cn31xx cn50xx; -+ struct cvmx_npi_ctl_status_s cn58xx; -+ struct cvmx_npi_ctl_status_s cn58xxp1; -+}; -+ -+union cvmx_npi_dbg_select { -+ uint64_t u64; -+ struct cvmx_npi_dbg_select_s { -+ uint64_t reserved_16_63:48; -+ uint64_t dbg_sel:16; -+ } s; -+ struct cvmx_npi_dbg_select_s cn30xx; -+ struct cvmx_npi_dbg_select_s cn31xx; -+ struct cvmx_npi_dbg_select_s cn38xx; -+ struct cvmx_npi_dbg_select_s cn38xxp2; -+ struct cvmx_npi_dbg_select_s cn50xx; -+ struct cvmx_npi_dbg_select_s cn58xx; -+ struct cvmx_npi_dbg_select_s cn58xxp1; -+}; -+ -+union cvmx_npi_dma_control { -+ uint64_t u64; -+ struct cvmx_npi_dma_control_s { -+ uint64_t reserved_36_63:28; -+ uint64_t b0_lend:1; -+ uint64_t dwb_denb:1; -+ uint64_t dwb_ichk:9; -+ uint64_t fpa_que:3; -+ uint64_t o_add1:1; -+ uint64_t o_ro:1; -+ uint64_t o_ns:1; -+ uint64_t o_es:2; -+ uint64_t o_mode:1; -+ uint64_t hp_enb:1; -+ uint64_t lp_enb:1; -+ uint64_t csize:14; -+ } s; -+ struct cvmx_npi_dma_control_s cn30xx; -+ struct cvmx_npi_dma_control_s cn31xx; -+ struct cvmx_npi_dma_control_s cn38xx; -+ struct cvmx_npi_dma_control_s cn38xxp2; -+ struct cvmx_npi_dma_control_s cn50xx; -+ struct cvmx_npi_dma_control_s cn58xx; -+ struct cvmx_npi_dma_control_s cn58xxp1; -+}; -+ -+union cvmx_npi_dma_highp_counts { -+ uint64_t u64; -+ struct cvmx_npi_dma_highp_counts_s { -+ uint64_t reserved_39_63:25; -+ uint64_t fcnt:7; -+ uint64_t dbell:32; -+ } s; -+ struct cvmx_npi_dma_highp_counts_s cn30xx; -+ struct cvmx_npi_dma_highp_counts_s cn31xx; -+ struct cvmx_npi_dma_highp_counts_s cn38xx; -+ struct cvmx_npi_dma_highp_counts_s cn38xxp2; -+ struct cvmx_npi_dma_highp_counts_s cn50xx; -+ struct cvmx_npi_dma_highp_counts_s cn58xx; -+ struct cvmx_npi_dma_highp_counts_s cn58xxp1; -+}; -+ -+union cvmx_npi_dma_highp_naddr { -+ uint64_t u64; -+ struct cvmx_npi_dma_highp_naddr_s { -+ uint64_t reserved_40_63:24; -+ uint64_t state:4; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_npi_dma_highp_naddr_s cn30xx; -+ struct cvmx_npi_dma_highp_naddr_s cn31xx; -+ struct cvmx_npi_dma_highp_naddr_s cn38xx; -+ struct cvmx_npi_dma_highp_naddr_s cn38xxp2; -+ struct cvmx_npi_dma_highp_naddr_s cn50xx; -+ struct cvmx_npi_dma_highp_naddr_s cn58xx; -+ struct cvmx_npi_dma_highp_naddr_s cn58xxp1; -+}; -+ -+union cvmx_npi_dma_lowp_counts { -+ uint64_t u64; -+ struct cvmx_npi_dma_lowp_counts_s { -+ uint64_t reserved_39_63:25; -+ uint64_t fcnt:7; -+ uint64_t dbell:32; -+ } s; -+ struct cvmx_npi_dma_lowp_counts_s cn30xx; -+ struct cvmx_npi_dma_lowp_counts_s cn31xx; -+ struct cvmx_npi_dma_lowp_counts_s cn38xx; -+ struct cvmx_npi_dma_lowp_counts_s cn38xxp2; -+ struct cvmx_npi_dma_lowp_counts_s cn50xx; -+ struct cvmx_npi_dma_lowp_counts_s cn58xx; -+ struct cvmx_npi_dma_lowp_counts_s cn58xxp1; -+}; -+ -+union cvmx_npi_dma_lowp_naddr { -+ uint64_t u64; -+ struct cvmx_npi_dma_lowp_naddr_s { -+ uint64_t reserved_40_63:24; -+ uint64_t state:4; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_npi_dma_lowp_naddr_s cn30xx; -+ struct cvmx_npi_dma_lowp_naddr_s cn31xx; -+ struct cvmx_npi_dma_lowp_naddr_s cn38xx; -+ struct cvmx_npi_dma_lowp_naddr_s cn38xxp2; -+ struct cvmx_npi_dma_lowp_naddr_s cn50xx; -+ struct cvmx_npi_dma_lowp_naddr_s cn58xx; -+ struct cvmx_npi_dma_lowp_naddr_s cn58xxp1; -+}; -+ -+union cvmx_npi_highp_dbell { -+ uint64_t u64; -+ struct cvmx_npi_highp_dbell_s { -+ uint64_t reserved_16_63:48; -+ uint64_t dbell:16; -+ } s; -+ struct cvmx_npi_highp_dbell_s cn30xx; -+ struct cvmx_npi_highp_dbell_s cn31xx; -+ struct cvmx_npi_highp_dbell_s cn38xx; -+ struct cvmx_npi_highp_dbell_s cn38xxp2; -+ struct cvmx_npi_highp_dbell_s cn50xx; -+ struct cvmx_npi_highp_dbell_s cn58xx; -+ struct cvmx_npi_highp_dbell_s cn58xxp1; -+}; -+ -+union cvmx_npi_highp_ibuff_saddr { -+ uint64_t u64; -+ struct cvmx_npi_highp_ibuff_saddr_s { -+ uint64_t reserved_36_63:28; -+ uint64_t saddr:36; -+ } s; -+ struct cvmx_npi_highp_ibuff_saddr_s cn30xx; -+ struct cvmx_npi_highp_ibuff_saddr_s cn31xx; -+ struct cvmx_npi_highp_ibuff_saddr_s cn38xx; -+ struct cvmx_npi_highp_ibuff_saddr_s cn38xxp2; -+ struct cvmx_npi_highp_ibuff_saddr_s cn50xx; -+ struct cvmx_npi_highp_ibuff_saddr_s cn58xx; -+ struct cvmx_npi_highp_ibuff_saddr_s cn58xxp1; -+}; -+ -+union cvmx_npi_input_control { -+ uint64_t u64; -+ struct cvmx_npi_input_control_s { -+ uint64_t reserved_23_63:41; -+ uint64_t pkt_rr:1; -+ uint64_t pbp_dhi:13; -+ uint64_t d_nsr:1; -+ uint64_t d_esr:2; -+ uint64_t d_ror:1; -+ uint64_t use_csr:1; -+ uint64_t nsr:1; -+ uint64_t esr:2; -+ uint64_t ror:1; -+ } s; -+ struct cvmx_npi_input_control_cn30xx { -+ uint64_t reserved_22_63:42; -+ uint64_t pbp_dhi:13; -+ uint64_t d_nsr:1; -+ uint64_t d_esr:2; -+ uint64_t d_ror:1; -+ uint64_t use_csr:1; -+ uint64_t nsr:1; -+ uint64_t esr:2; -+ uint64_t ror:1; -+ } cn30xx; -+ struct cvmx_npi_input_control_cn30xx cn31xx; -+ struct cvmx_npi_input_control_s cn38xx; -+ struct cvmx_npi_input_control_cn30xx cn38xxp2; -+ struct cvmx_npi_input_control_s cn50xx; -+ struct cvmx_npi_input_control_s cn58xx; -+ struct cvmx_npi_input_control_s cn58xxp1; -+}; -+ -+union cvmx_npi_int_enb { -+ uint64_t u64; -+ struct cvmx_npi_int_enb_s { -+ uint64_t reserved_62_63:2; -+ uint64_t q1_a_f:1; -+ uint64_t q1_s_e:1; -+ uint64_t pdf_p_f:1; -+ uint64_t pdf_p_e:1; -+ uint64_t pcf_p_f:1; -+ uint64_t pcf_p_e:1; -+ uint64_t rdx_s_e:1; -+ uint64_t rwx_s_e:1; -+ uint64_t pnc_a_f:1; -+ uint64_t pnc_s_e:1; -+ uint64_t com_a_f:1; -+ uint64_t com_s_e:1; -+ uint64_t q3_a_f:1; -+ uint64_t q3_s_e:1; -+ uint64_t q2_a_f:1; -+ uint64_t q2_s_e:1; -+ uint64_t pcr_a_f:1; -+ uint64_t pcr_s_e:1; -+ uint64_t fcr_a_f:1; -+ uint64_t fcr_s_e:1; -+ uint64_t iobdma:1; -+ uint64_t p_dperr:1; -+ uint64_t win_rto:1; -+ uint64_t i3_pperr:1; -+ uint64_t i2_pperr:1; -+ uint64_t i1_pperr:1; -+ uint64_t i0_pperr:1; -+ uint64_t p3_ptout:1; -+ uint64_t p2_ptout:1; -+ uint64_t p1_ptout:1; -+ uint64_t p0_ptout:1; -+ uint64_t p3_pperr:1; -+ uint64_t p2_pperr:1; -+ uint64_t p1_pperr:1; -+ uint64_t p0_pperr:1; -+ uint64_t g3_rtout:1; -+ uint64_t g2_rtout:1; -+ uint64_t g1_rtout:1; -+ uint64_t g0_rtout:1; -+ uint64_t p3_perr:1; -+ uint64_t p2_perr:1; -+ uint64_t p1_perr:1; -+ uint64_t p0_perr:1; -+ uint64_t p3_rtout:1; -+ uint64_t p2_rtout:1; -+ uint64_t p1_rtout:1; -+ uint64_t p0_rtout:1; -+ uint64_t i3_overf:1; -+ uint64_t i2_overf:1; -+ uint64_t i1_overf:1; -+ uint64_t i0_overf:1; -+ uint64_t i3_rtout:1; -+ uint64_t i2_rtout:1; -+ uint64_t i1_rtout:1; -+ uint64_t i0_rtout:1; -+ uint64_t po3_2sml:1; -+ uint64_t po2_2sml:1; -+ uint64_t po1_2sml:1; -+ uint64_t po0_2sml:1; -+ uint64_t pci_rsl:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } s; -+ struct cvmx_npi_int_enb_cn30xx { -+ uint64_t reserved_62_63:2; -+ uint64_t q1_a_f:1; -+ uint64_t q1_s_e:1; -+ uint64_t pdf_p_f:1; -+ uint64_t pdf_p_e:1; -+ uint64_t pcf_p_f:1; -+ uint64_t pcf_p_e:1; -+ uint64_t rdx_s_e:1; -+ uint64_t rwx_s_e:1; -+ uint64_t pnc_a_f:1; -+ uint64_t pnc_s_e:1; -+ uint64_t com_a_f:1; -+ uint64_t com_s_e:1; -+ uint64_t q3_a_f:1; -+ uint64_t q3_s_e:1; -+ uint64_t q2_a_f:1; -+ uint64_t q2_s_e:1; -+ uint64_t pcr_a_f:1; -+ uint64_t pcr_s_e:1; -+ uint64_t fcr_a_f:1; -+ uint64_t fcr_s_e:1; -+ uint64_t iobdma:1; -+ uint64_t p_dperr:1; -+ uint64_t win_rto:1; -+ uint64_t reserved_36_38:3; -+ uint64_t i0_pperr:1; -+ uint64_t reserved_32_34:3; -+ uint64_t p0_ptout:1; -+ uint64_t reserved_28_30:3; -+ uint64_t p0_pperr:1; -+ uint64_t reserved_24_26:3; -+ uint64_t g0_rtout:1; -+ uint64_t reserved_20_22:3; -+ uint64_t p0_perr:1; -+ uint64_t reserved_16_18:3; -+ uint64_t p0_rtout:1; -+ uint64_t reserved_12_14:3; -+ uint64_t i0_overf:1; -+ uint64_t reserved_8_10:3; -+ uint64_t i0_rtout:1; -+ uint64_t reserved_4_6:3; -+ uint64_t po0_2sml:1; -+ uint64_t pci_rsl:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } cn30xx; -+ struct cvmx_npi_int_enb_cn31xx { -+ uint64_t reserved_62_63:2; -+ uint64_t q1_a_f:1; -+ uint64_t q1_s_e:1; -+ uint64_t pdf_p_f:1; -+ uint64_t pdf_p_e:1; -+ uint64_t pcf_p_f:1; -+ uint64_t pcf_p_e:1; -+ uint64_t rdx_s_e:1; -+ uint64_t rwx_s_e:1; -+ uint64_t pnc_a_f:1; -+ uint64_t pnc_s_e:1; -+ uint64_t com_a_f:1; -+ uint64_t com_s_e:1; -+ uint64_t q3_a_f:1; -+ uint64_t q3_s_e:1; -+ uint64_t q2_a_f:1; -+ uint64_t q2_s_e:1; -+ uint64_t pcr_a_f:1; -+ uint64_t pcr_s_e:1; -+ uint64_t fcr_a_f:1; -+ uint64_t fcr_s_e:1; -+ uint64_t iobdma:1; -+ uint64_t p_dperr:1; -+ uint64_t win_rto:1; -+ uint64_t reserved_37_38:2; -+ uint64_t i1_pperr:1; -+ uint64_t i0_pperr:1; -+ uint64_t reserved_33_34:2; -+ uint64_t p1_ptout:1; -+ uint64_t p0_ptout:1; -+ uint64_t reserved_29_30:2; -+ uint64_t p1_pperr:1; -+ uint64_t p0_pperr:1; -+ uint64_t reserved_25_26:2; -+ uint64_t g1_rtout:1; -+ uint64_t g0_rtout:1; -+ uint64_t reserved_21_22:2; -+ uint64_t p1_perr:1; -+ uint64_t p0_perr:1; -+ uint64_t reserved_17_18:2; -+ uint64_t p1_rtout:1; -+ uint64_t p0_rtout:1; -+ uint64_t reserved_13_14:2; -+ uint64_t i1_overf:1; -+ uint64_t i0_overf:1; -+ uint64_t reserved_9_10:2; -+ uint64_t i1_rtout:1; -+ uint64_t i0_rtout:1; -+ uint64_t reserved_5_6:2; -+ uint64_t po1_2sml:1; -+ uint64_t po0_2sml:1; -+ uint64_t pci_rsl:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } cn31xx; -+ struct cvmx_npi_int_enb_s cn38xx; -+ struct cvmx_npi_int_enb_cn38xxp2 { -+ uint64_t reserved_42_63:22; -+ uint64_t iobdma:1; -+ uint64_t p_dperr:1; -+ uint64_t win_rto:1; -+ uint64_t i3_pperr:1; -+ uint64_t i2_pperr:1; -+ uint64_t i1_pperr:1; -+ uint64_t i0_pperr:1; -+ uint64_t p3_ptout:1; -+ uint64_t p2_ptout:1; -+ uint64_t p1_ptout:1; -+ uint64_t p0_ptout:1; -+ uint64_t p3_pperr:1; -+ uint64_t p2_pperr:1; -+ uint64_t p1_pperr:1; -+ uint64_t p0_pperr:1; -+ uint64_t g3_rtout:1; -+ uint64_t g2_rtout:1; -+ uint64_t g1_rtout:1; -+ uint64_t g0_rtout:1; -+ uint64_t p3_perr:1; -+ uint64_t p2_perr:1; -+ uint64_t p1_perr:1; -+ uint64_t p0_perr:1; -+ uint64_t p3_rtout:1; -+ uint64_t p2_rtout:1; -+ uint64_t p1_rtout:1; -+ uint64_t p0_rtout:1; -+ uint64_t i3_overf:1; -+ uint64_t i2_overf:1; -+ uint64_t i1_overf:1; -+ uint64_t i0_overf:1; -+ uint64_t i3_rtout:1; -+ uint64_t i2_rtout:1; -+ uint64_t i1_rtout:1; -+ uint64_t i0_rtout:1; -+ uint64_t po3_2sml:1; -+ uint64_t po2_2sml:1; -+ uint64_t po1_2sml:1; -+ uint64_t po0_2sml:1; -+ uint64_t pci_rsl:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } cn38xxp2; -+ struct cvmx_npi_int_enb_cn31xx cn50xx; -+ struct cvmx_npi_int_enb_s cn58xx; -+ struct cvmx_npi_int_enb_s cn58xxp1; -+}; -+ -+union cvmx_npi_int_sum { -+ uint64_t u64; -+ struct cvmx_npi_int_sum_s { -+ uint64_t reserved_62_63:2; -+ uint64_t q1_a_f:1; -+ uint64_t q1_s_e:1; -+ uint64_t pdf_p_f:1; -+ uint64_t pdf_p_e:1; -+ uint64_t pcf_p_f:1; -+ uint64_t pcf_p_e:1; -+ uint64_t rdx_s_e:1; -+ uint64_t rwx_s_e:1; -+ uint64_t pnc_a_f:1; -+ uint64_t pnc_s_e:1; -+ uint64_t com_a_f:1; -+ uint64_t com_s_e:1; -+ uint64_t q3_a_f:1; -+ uint64_t q3_s_e:1; -+ uint64_t q2_a_f:1; -+ uint64_t q2_s_e:1; -+ uint64_t pcr_a_f:1; -+ uint64_t pcr_s_e:1; -+ uint64_t fcr_a_f:1; -+ uint64_t fcr_s_e:1; -+ uint64_t iobdma:1; -+ uint64_t p_dperr:1; -+ uint64_t win_rto:1; -+ uint64_t i3_pperr:1; -+ uint64_t i2_pperr:1; -+ uint64_t i1_pperr:1; -+ uint64_t i0_pperr:1; -+ uint64_t p3_ptout:1; -+ uint64_t p2_ptout:1; -+ uint64_t p1_ptout:1; -+ uint64_t p0_ptout:1; -+ uint64_t p3_pperr:1; -+ uint64_t p2_pperr:1; -+ uint64_t p1_pperr:1; -+ uint64_t p0_pperr:1; -+ uint64_t g3_rtout:1; -+ uint64_t g2_rtout:1; -+ uint64_t g1_rtout:1; -+ uint64_t g0_rtout:1; -+ uint64_t p3_perr:1; -+ uint64_t p2_perr:1; -+ uint64_t p1_perr:1; -+ uint64_t p0_perr:1; -+ uint64_t p3_rtout:1; -+ uint64_t p2_rtout:1; -+ uint64_t p1_rtout:1; -+ uint64_t p0_rtout:1; -+ uint64_t i3_overf:1; -+ uint64_t i2_overf:1; -+ uint64_t i1_overf:1; -+ uint64_t i0_overf:1; -+ uint64_t i3_rtout:1; -+ uint64_t i2_rtout:1; -+ uint64_t i1_rtout:1; -+ uint64_t i0_rtout:1; -+ uint64_t po3_2sml:1; -+ uint64_t po2_2sml:1; -+ uint64_t po1_2sml:1; -+ uint64_t po0_2sml:1; -+ uint64_t pci_rsl:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } s; -+ struct cvmx_npi_int_sum_cn30xx { -+ uint64_t reserved_62_63:2; -+ uint64_t q1_a_f:1; -+ uint64_t q1_s_e:1; -+ uint64_t pdf_p_f:1; -+ uint64_t pdf_p_e:1; -+ uint64_t pcf_p_f:1; -+ uint64_t pcf_p_e:1; -+ uint64_t rdx_s_e:1; -+ uint64_t rwx_s_e:1; -+ uint64_t pnc_a_f:1; -+ uint64_t pnc_s_e:1; -+ uint64_t com_a_f:1; -+ uint64_t com_s_e:1; -+ uint64_t q3_a_f:1; -+ uint64_t q3_s_e:1; -+ uint64_t q2_a_f:1; -+ uint64_t q2_s_e:1; -+ uint64_t pcr_a_f:1; -+ uint64_t pcr_s_e:1; -+ uint64_t fcr_a_f:1; -+ uint64_t fcr_s_e:1; -+ uint64_t iobdma:1; -+ uint64_t p_dperr:1; -+ uint64_t win_rto:1; -+ uint64_t reserved_36_38:3; -+ uint64_t i0_pperr:1; -+ uint64_t reserved_32_34:3; -+ uint64_t p0_ptout:1; -+ uint64_t reserved_28_30:3; -+ uint64_t p0_pperr:1; -+ uint64_t reserved_24_26:3; -+ uint64_t g0_rtout:1; -+ uint64_t reserved_20_22:3; -+ uint64_t p0_perr:1; -+ uint64_t reserved_16_18:3; -+ uint64_t p0_rtout:1; -+ uint64_t reserved_12_14:3; -+ uint64_t i0_overf:1; -+ uint64_t reserved_8_10:3; -+ uint64_t i0_rtout:1; -+ uint64_t reserved_4_6:3; -+ uint64_t po0_2sml:1; -+ uint64_t pci_rsl:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } cn30xx; -+ struct cvmx_npi_int_sum_cn31xx { -+ uint64_t reserved_62_63:2; -+ uint64_t q1_a_f:1; -+ uint64_t q1_s_e:1; -+ uint64_t pdf_p_f:1; -+ uint64_t pdf_p_e:1; -+ uint64_t pcf_p_f:1; -+ uint64_t pcf_p_e:1; -+ uint64_t rdx_s_e:1; -+ uint64_t rwx_s_e:1; -+ uint64_t pnc_a_f:1; -+ uint64_t pnc_s_e:1; -+ uint64_t com_a_f:1; -+ uint64_t com_s_e:1; -+ uint64_t q3_a_f:1; -+ uint64_t q3_s_e:1; -+ uint64_t q2_a_f:1; -+ uint64_t q2_s_e:1; -+ uint64_t pcr_a_f:1; -+ uint64_t pcr_s_e:1; -+ uint64_t fcr_a_f:1; -+ uint64_t fcr_s_e:1; -+ uint64_t iobdma:1; -+ uint64_t p_dperr:1; -+ uint64_t win_rto:1; -+ uint64_t reserved_37_38:2; -+ uint64_t i1_pperr:1; -+ uint64_t i0_pperr:1; -+ uint64_t reserved_33_34:2; -+ uint64_t p1_ptout:1; -+ uint64_t p0_ptout:1; -+ uint64_t reserved_29_30:2; -+ uint64_t p1_pperr:1; -+ uint64_t p0_pperr:1; -+ uint64_t reserved_25_26:2; -+ uint64_t g1_rtout:1; -+ uint64_t g0_rtout:1; -+ uint64_t reserved_21_22:2; -+ uint64_t p1_perr:1; -+ uint64_t p0_perr:1; -+ uint64_t reserved_17_18:2; -+ uint64_t p1_rtout:1; -+ uint64_t p0_rtout:1; -+ uint64_t reserved_13_14:2; -+ uint64_t i1_overf:1; -+ uint64_t i0_overf:1; -+ uint64_t reserved_9_10:2; -+ uint64_t i1_rtout:1; -+ uint64_t i0_rtout:1; -+ uint64_t reserved_5_6:2; -+ uint64_t po1_2sml:1; -+ uint64_t po0_2sml:1; -+ uint64_t pci_rsl:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } cn31xx; -+ struct cvmx_npi_int_sum_s cn38xx; -+ struct cvmx_npi_int_sum_cn38xxp2 { -+ uint64_t reserved_42_63:22; -+ uint64_t iobdma:1; -+ uint64_t p_dperr:1; -+ uint64_t win_rto:1; -+ uint64_t i3_pperr:1; -+ uint64_t i2_pperr:1; -+ uint64_t i1_pperr:1; -+ uint64_t i0_pperr:1; -+ uint64_t p3_ptout:1; -+ uint64_t p2_ptout:1; -+ uint64_t p1_ptout:1; -+ uint64_t p0_ptout:1; -+ uint64_t p3_pperr:1; -+ uint64_t p2_pperr:1; -+ uint64_t p1_pperr:1; -+ uint64_t p0_pperr:1; -+ uint64_t g3_rtout:1; -+ uint64_t g2_rtout:1; -+ uint64_t g1_rtout:1; -+ uint64_t g0_rtout:1; -+ uint64_t p3_perr:1; -+ uint64_t p2_perr:1; -+ uint64_t p1_perr:1; -+ uint64_t p0_perr:1; -+ uint64_t p3_rtout:1; -+ uint64_t p2_rtout:1; -+ uint64_t p1_rtout:1; -+ uint64_t p0_rtout:1; -+ uint64_t i3_overf:1; -+ uint64_t i2_overf:1; -+ uint64_t i1_overf:1; -+ uint64_t i0_overf:1; -+ uint64_t i3_rtout:1; -+ uint64_t i2_rtout:1; -+ uint64_t i1_rtout:1; -+ uint64_t i0_rtout:1; -+ uint64_t po3_2sml:1; -+ uint64_t po2_2sml:1; -+ uint64_t po1_2sml:1; -+ uint64_t po0_2sml:1; -+ uint64_t pci_rsl:1; -+ uint64_t rml_wto:1; -+ uint64_t rml_rto:1; -+ } cn38xxp2; -+ struct cvmx_npi_int_sum_cn31xx cn50xx; -+ struct cvmx_npi_int_sum_s cn58xx; -+ struct cvmx_npi_int_sum_s cn58xxp1; -+}; -+ -+union cvmx_npi_lowp_dbell { -+ uint64_t u64; -+ struct cvmx_npi_lowp_dbell_s { -+ uint64_t reserved_16_63:48; -+ uint64_t dbell:16; -+ } s; -+ struct cvmx_npi_lowp_dbell_s cn30xx; -+ struct cvmx_npi_lowp_dbell_s cn31xx; -+ struct cvmx_npi_lowp_dbell_s cn38xx; -+ struct cvmx_npi_lowp_dbell_s cn38xxp2; -+ struct cvmx_npi_lowp_dbell_s cn50xx; -+ struct cvmx_npi_lowp_dbell_s cn58xx; -+ struct cvmx_npi_lowp_dbell_s cn58xxp1; -+}; -+ -+union cvmx_npi_lowp_ibuff_saddr { -+ uint64_t u64; -+ struct cvmx_npi_lowp_ibuff_saddr_s { -+ uint64_t reserved_36_63:28; -+ uint64_t saddr:36; -+ } s; -+ struct cvmx_npi_lowp_ibuff_saddr_s cn30xx; -+ struct cvmx_npi_lowp_ibuff_saddr_s cn31xx; -+ struct cvmx_npi_lowp_ibuff_saddr_s cn38xx; -+ struct cvmx_npi_lowp_ibuff_saddr_s cn38xxp2; -+ struct cvmx_npi_lowp_ibuff_saddr_s cn50xx; -+ struct cvmx_npi_lowp_ibuff_saddr_s cn58xx; -+ struct cvmx_npi_lowp_ibuff_saddr_s cn58xxp1; -+}; -+ -+union cvmx_npi_mem_access_subidx { -+ uint64_t u64; -+ struct cvmx_npi_mem_access_subidx_s { -+ uint64_t reserved_38_63:26; -+ uint64_t shortl:1; -+ uint64_t nmerge:1; -+ uint64_t esr:2; -+ uint64_t esw:2; -+ uint64_t nsr:1; -+ uint64_t nsw:1; -+ uint64_t ror:1; -+ uint64_t row:1; -+ uint64_t ba:28; -+ } s; -+ struct cvmx_npi_mem_access_subidx_s cn30xx; -+ struct cvmx_npi_mem_access_subidx_cn31xx { -+ uint64_t reserved_36_63:28; -+ uint64_t esr:2; -+ uint64_t esw:2; -+ uint64_t nsr:1; -+ uint64_t nsw:1; -+ uint64_t ror:1; -+ uint64_t row:1; -+ uint64_t ba:28; -+ } cn31xx; -+ struct cvmx_npi_mem_access_subidx_s cn38xx; -+ struct cvmx_npi_mem_access_subidx_cn31xx cn38xxp2; -+ struct cvmx_npi_mem_access_subidx_s cn50xx; -+ struct cvmx_npi_mem_access_subidx_s cn58xx; -+ struct cvmx_npi_mem_access_subidx_s cn58xxp1; -+}; -+ -+union cvmx_npi_msi_rcv { -+ uint64_t u64; -+ struct cvmx_npi_msi_rcv_s { -+ uint64_t int_vec:64; -+ } s; -+ struct cvmx_npi_msi_rcv_s cn30xx; -+ struct cvmx_npi_msi_rcv_s cn31xx; -+ struct cvmx_npi_msi_rcv_s cn38xx; -+ struct cvmx_npi_msi_rcv_s cn38xxp2; -+ struct cvmx_npi_msi_rcv_s cn50xx; -+ struct cvmx_npi_msi_rcv_s cn58xx; -+ struct cvmx_npi_msi_rcv_s cn58xxp1; -+}; -+ -+union cvmx_npi_num_desc_outputx { -+ uint64_t u64; -+ struct cvmx_npi_num_desc_outputx_s { -+ uint64_t reserved_32_63:32; -+ uint64_t size:32; -+ } s; -+ struct cvmx_npi_num_desc_outputx_s cn30xx; -+ struct cvmx_npi_num_desc_outputx_s cn31xx; -+ struct cvmx_npi_num_desc_outputx_s cn38xx; -+ struct cvmx_npi_num_desc_outputx_s cn38xxp2; -+ struct cvmx_npi_num_desc_outputx_s cn50xx; -+ struct cvmx_npi_num_desc_outputx_s cn58xx; -+ struct cvmx_npi_num_desc_outputx_s cn58xxp1; -+}; -+ -+union cvmx_npi_output_control { -+ uint64_t u64; -+ struct cvmx_npi_output_control_s { -+ uint64_t reserved_49_63:15; -+ uint64_t pkt_rr:1; -+ uint64_t p3_bmode:1; -+ uint64_t p2_bmode:1; -+ uint64_t p1_bmode:1; -+ uint64_t p0_bmode:1; -+ uint64_t o3_es:2; -+ uint64_t o3_ns:1; -+ uint64_t o3_ro:1; -+ uint64_t o2_es:2; -+ uint64_t o2_ns:1; -+ uint64_t o2_ro:1; -+ uint64_t o1_es:2; -+ uint64_t o1_ns:1; -+ uint64_t o1_ro:1; -+ uint64_t o0_es:2; -+ uint64_t o0_ns:1; -+ uint64_t o0_ro:1; -+ uint64_t o3_csrm:1; -+ uint64_t o2_csrm:1; -+ uint64_t o1_csrm:1; -+ uint64_t o0_csrm:1; -+ uint64_t reserved_20_23:4; -+ uint64_t iptr_o3:1; -+ uint64_t iptr_o2:1; -+ uint64_t iptr_o1:1; -+ uint64_t iptr_o0:1; -+ uint64_t esr_sl3:2; -+ uint64_t nsr_sl3:1; -+ uint64_t ror_sl3:1; -+ uint64_t esr_sl2:2; -+ uint64_t nsr_sl2:1; -+ uint64_t ror_sl2:1; -+ uint64_t esr_sl1:2; -+ uint64_t nsr_sl1:1; -+ uint64_t ror_sl1:1; -+ uint64_t esr_sl0:2; -+ uint64_t nsr_sl0:1; -+ uint64_t ror_sl0:1; -+ } s; -+ struct cvmx_npi_output_control_cn30xx { -+ uint64_t reserved_45_63:19; -+ uint64_t p0_bmode:1; -+ uint64_t reserved_32_43:12; -+ uint64_t o0_es:2; -+ uint64_t o0_ns:1; -+ uint64_t o0_ro:1; -+ uint64_t reserved_25_27:3; -+ uint64_t o0_csrm:1; -+ uint64_t reserved_17_23:7; -+ uint64_t iptr_o0:1; -+ uint64_t reserved_4_15:12; -+ uint64_t esr_sl0:2; -+ uint64_t nsr_sl0:1; -+ uint64_t ror_sl0:1; -+ } cn30xx; -+ struct cvmx_npi_output_control_cn31xx { -+ uint64_t reserved_46_63:18; -+ uint64_t p1_bmode:1; -+ uint64_t p0_bmode:1; -+ uint64_t reserved_36_43:8; -+ uint64_t o1_es:2; -+ uint64_t o1_ns:1; -+ uint64_t o1_ro:1; -+ uint64_t o0_es:2; -+ uint64_t o0_ns:1; -+ uint64_t o0_ro:1; -+ uint64_t reserved_26_27:2; -+ uint64_t o1_csrm:1; -+ uint64_t o0_csrm:1; -+ uint64_t reserved_18_23:6; -+ uint64_t iptr_o1:1; -+ uint64_t iptr_o0:1; -+ uint64_t reserved_8_15:8; -+ uint64_t esr_sl1:2; -+ uint64_t nsr_sl1:1; -+ uint64_t ror_sl1:1; -+ uint64_t esr_sl0:2; -+ uint64_t nsr_sl0:1; -+ uint64_t ror_sl0:1; -+ } cn31xx; -+ struct cvmx_npi_output_control_s cn38xx; -+ struct cvmx_npi_output_control_cn38xxp2 { -+ uint64_t reserved_48_63:16; -+ uint64_t p3_bmode:1; -+ uint64_t p2_bmode:1; -+ uint64_t p1_bmode:1; -+ uint64_t p0_bmode:1; -+ uint64_t o3_es:2; -+ uint64_t o3_ns:1; -+ uint64_t o3_ro:1; -+ uint64_t o2_es:2; -+ uint64_t o2_ns:1; -+ uint64_t o2_ro:1; -+ uint64_t o1_es:2; -+ uint64_t o1_ns:1; -+ uint64_t o1_ro:1; -+ uint64_t o0_es:2; -+ uint64_t o0_ns:1; -+ uint64_t o0_ro:1; -+ uint64_t o3_csrm:1; -+ uint64_t o2_csrm:1; -+ uint64_t o1_csrm:1; -+ uint64_t o0_csrm:1; -+ uint64_t reserved_20_23:4; -+ uint64_t iptr_o3:1; -+ uint64_t iptr_o2:1; -+ uint64_t iptr_o1:1; -+ uint64_t iptr_o0:1; -+ uint64_t esr_sl3:2; -+ uint64_t nsr_sl3:1; -+ uint64_t ror_sl3:1; -+ uint64_t esr_sl2:2; -+ uint64_t nsr_sl2:1; -+ uint64_t ror_sl2:1; -+ uint64_t esr_sl1:2; -+ uint64_t nsr_sl1:1; -+ uint64_t ror_sl1:1; -+ uint64_t esr_sl0:2; -+ uint64_t nsr_sl0:1; -+ uint64_t ror_sl0:1; -+ } cn38xxp2; -+ struct cvmx_npi_output_control_cn50xx { -+ uint64_t reserved_49_63:15; -+ uint64_t pkt_rr:1; -+ uint64_t reserved_46_47:2; -+ uint64_t p1_bmode:1; -+ uint64_t p0_bmode:1; -+ uint64_t reserved_36_43:8; -+ uint64_t o1_es:2; -+ uint64_t o1_ns:1; -+ uint64_t o1_ro:1; -+ uint64_t o0_es:2; -+ uint64_t o0_ns:1; -+ uint64_t o0_ro:1; -+ uint64_t reserved_26_27:2; -+ uint64_t o1_csrm:1; -+ uint64_t o0_csrm:1; -+ uint64_t reserved_18_23:6; -+ uint64_t iptr_o1:1; -+ uint64_t iptr_o0:1; -+ uint64_t reserved_8_15:8; -+ uint64_t esr_sl1:2; -+ uint64_t nsr_sl1:1; -+ uint64_t ror_sl1:1; -+ uint64_t esr_sl0:2; -+ uint64_t nsr_sl0:1; -+ uint64_t ror_sl0:1; -+ } cn50xx; -+ struct cvmx_npi_output_control_s cn58xx; -+ struct cvmx_npi_output_control_s cn58xxp1; -+}; -+ -+union cvmx_npi_px_dbpair_addr { -+ uint64_t u64; -+ struct cvmx_npi_px_dbpair_addr_s { -+ uint64_t reserved_63_63:1; -+ uint64_t state:2; -+ uint64_t naddr:61; -+ } s; -+ struct cvmx_npi_px_dbpair_addr_s cn30xx; -+ struct cvmx_npi_px_dbpair_addr_s cn31xx; -+ struct cvmx_npi_px_dbpair_addr_s cn38xx; -+ struct cvmx_npi_px_dbpair_addr_s cn38xxp2; -+ struct cvmx_npi_px_dbpair_addr_s cn50xx; -+ struct cvmx_npi_px_dbpair_addr_s cn58xx; -+ struct cvmx_npi_px_dbpair_addr_s cn58xxp1; -+}; -+ -+union cvmx_npi_px_instr_addr { -+ uint64_t u64; -+ struct cvmx_npi_px_instr_addr_s { -+ uint64_t state:3; -+ uint64_t naddr:61; -+ } s; -+ struct cvmx_npi_px_instr_addr_s cn30xx; -+ struct cvmx_npi_px_instr_addr_s cn31xx; -+ struct cvmx_npi_px_instr_addr_s cn38xx; -+ struct cvmx_npi_px_instr_addr_s cn38xxp2; -+ struct cvmx_npi_px_instr_addr_s cn50xx; -+ struct cvmx_npi_px_instr_addr_s cn58xx; -+ struct cvmx_npi_px_instr_addr_s cn58xxp1; -+}; -+ -+union cvmx_npi_px_instr_cnts { -+ uint64_t u64; -+ struct cvmx_npi_px_instr_cnts_s { -+ uint64_t reserved_38_63:26; -+ uint64_t fcnt:6; -+ uint64_t avail:32; -+ } s; -+ struct cvmx_npi_px_instr_cnts_s cn30xx; -+ struct cvmx_npi_px_instr_cnts_s cn31xx; -+ struct cvmx_npi_px_instr_cnts_s cn38xx; -+ struct cvmx_npi_px_instr_cnts_s cn38xxp2; -+ struct cvmx_npi_px_instr_cnts_s cn50xx; -+ struct cvmx_npi_px_instr_cnts_s cn58xx; -+ struct cvmx_npi_px_instr_cnts_s cn58xxp1; -+}; -+ -+union cvmx_npi_px_pair_cnts { -+ uint64_t u64; -+ struct cvmx_npi_px_pair_cnts_s { -+ uint64_t reserved_37_63:27; -+ uint64_t fcnt:5; -+ uint64_t avail:32; -+ } s; -+ struct cvmx_npi_px_pair_cnts_s cn30xx; -+ struct cvmx_npi_px_pair_cnts_s cn31xx; -+ struct cvmx_npi_px_pair_cnts_s cn38xx; -+ struct cvmx_npi_px_pair_cnts_s cn38xxp2; -+ struct cvmx_npi_px_pair_cnts_s cn50xx; -+ struct cvmx_npi_px_pair_cnts_s cn58xx; -+ struct cvmx_npi_px_pair_cnts_s cn58xxp1; -+}; -+ -+union cvmx_npi_pci_burst_size { -+ uint64_t u64; -+ struct cvmx_npi_pci_burst_size_s { -+ uint64_t reserved_14_63:50; -+ uint64_t wr_brst:7; -+ uint64_t rd_brst:7; -+ } s; -+ struct cvmx_npi_pci_burst_size_s cn30xx; -+ struct cvmx_npi_pci_burst_size_s cn31xx; -+ struct cvmx_npi_pci_burst_size_s cn38xx; -+ struct cvmx_npi_pci_burst_size_s cn38xxp2; -+ struct cvmx_npi_pci_burst_size_s cn50xx; -+ struct cvmx_npi_pci_burst_size_s cn58xx; -+ struct cvmx_npi_pci_burst_size_s cn58xxp1; -+}; -+ -+union cvmx_npi_pci_int_arb_cfg { -+ uint64_t u64; -+ struct cvmx_npi_pci_int_arb_cfg_s { -+ uint64_t reserved_13_63:51; -+ uint64_t hostmode:1; -+ uint64_t pci_ovr:4; -+ uint64_t reserved_5_7:3; -+ uint64_t en:1; -+ uint64_t park_mod:1; -+ uint64_t park_dev:3; -+ } s; -+ struct cvmx_npi_pci_int_arb_cfg_cn30xx { -+ uint64_t reserved_5_63:59; -+ uint64_t en:1; -+ uint64_t park_mod:1; -+ uint64_t park_dev:3; -+ } cn30xx; -+ struct cvmx_npi_pci_int_arb_cfg_cn30xx cn31xx; -+ struct cvmx_npi_pci_int_arb_cfg_cn30xx cn38xx; -+ struct cvmx_npi_pci_int_arb_cfg_cn30xx cn38xxp2; -+ struct cvmx_npi_pci_int_arb_cfg_s cn50xx; -+ struct cvmx_npi_pci_int_arb_cfg_s cn58xx; -+ struct cvmx_npi_pci_int_arb_cfg_s cn58xxp1; -+}; -+ -+union cvmx_npi_pci_read_cmd { -+ uint64_t u64; -+ struct cvmx_npi_pci_read_cmd_s { -+ uint64_t reserved_11_63:53; -+ uint64_t cmd_size:11; -+ } s; -+ struct cvmx_npi_pci_read_cmd_s cn30xx; -+ struct cvmx_npi_pci_read_cmd_s cn31xx; -+ struct cvmx_npi_pci_read_cmd_s cn38xx; -+ struct cvmx_npi_pci_read_cmd_s cn38xxp2; -+ struct cvmx_npi_pci_read_cmd_s cn50xx; -+ struct cvmx_npi_pci_read_cmd_s cn58xx; -+ struct cvmx_npi_pci_read_cmd_s cn58xxp1; -+}; -+ -+union cvmx_npi_port32_instr_hdr { -+ uint64_t u64; -+ struct cvmx_npi_port32_instr_hdr_s { -+ uint64_t reserved_44_63:20; -+ uint64_t pbp:1; -+ uint64_t rsv_f:5; -+ uint64_t rparmode:2; -+ uint64_t rsv_e:1; -+ uint64_t rskp_len:7; -+ uint64_t rsv_d:6; -+ uint64_t use_ihdr:1; -+ uint64_t rsv_c:5; -+ uint64_t par_mode:2; -+ uint64_t rsv_b:1; -+ uint64_t skp_len:7; -+ uint64_t rsv_a:6; -+ } s; -+ struct cvmx_npi_port32_instr_hdr_s cn30xx; -+ struct cvmx_npi_port32_instr_hdr_s cn31xx; -+ struct cvmx_npi_port32_instr_hdr_s cn38xx; -+ struct cvmx_npi_port32_instr_hdr_s cn38xxp2; -+ struct cvmx_npi_port32_instr_hdr_s cn50xx; -+ struct cvmx_npi_port32_instr_hdr_s cn58xx; -+ struct cvmx_npi_port32_instr_hdr_s cn58xxp1; -+}; -+ -+union cvmx_npi_port33_instr_hdr { -+ uint64_t u64; -+ struct cvmx_npi_port33_instr_hdr_s { -+ uint64_t reserved_44_63:20; -+ uint64_t pbp:1; -+ uint64_t rsv_f:5; -+ uint64_t rparmode:2; -+ uint64_t rsv_e:1; -+ uint64_t rskp_len:7; -+ uint64_t rsv_d:6; -+ uint64_t use_ihdr:1; -+ uint64_t rsv_c:5; -+ uint64_t par_mode:2; -+ uint64_t rsv_b:1; -+ uint64_t skp_len:7; -+ uint64_t rsv_a:6; -+ } s; -+ struct cvmx_npi_port33_instr_hdr_s cn31xx; -+ struct cvmx_npi_port33_instr_hdr_s cn38xx; -+ struct cvmx_npi_port33_instr_hdr_s cn38xxp2; -+ struct cvmx_npi_port33_instr_hdr_s cn50xx; -+ struct cvmx_npi_port33_instr_hdr_s cn58xx; -+ struct cvmx_npi_port33_instr_hdr_s cn58xxp1; -+}; -+ -+union cvmx_npi_port34_instr_hdr { -+ uint64_t u64; -+ struct cvmx_npi_port34_instr_hdr_s { -+ uint64_t reserved_44_63:20; -+ uint64_t pbp:1; -+ uint64_t rsv_f:5; -+ uint64_t rparmode:2; -+ uint64_t rsv_e:1; -+ uint64_t rskp_len:7; -+ uint64_t rsv_d:6; -+ uint64_t use_ihdr:1; -+ uint64_t rsv_c:5; -+ uint64_t par_mode:2; -+ uint64_t rsv_b:1; -+ uint64_t skp_len:7; -+ uint64_t rsv_a:6; -+ } s; -+ struct cvmx_npi_port34_instr_hdr_s cn38xx; -+ struct cvmx_npi_port34_instr_hdr_s cn38xxp2; -+ struct cvmx_npi_port34_instr_hdr_s cn58xx; -+ struct cvmx_npi_port34_instr_hdr_s cn58xxp1; -+}; -+ -+union cvmx_npi_port35_instr_hdr { -+ uint64_t u64; -+ struct cvmx_npi_port35_instr_hdr_s { -+ uint64_t reserved_44_63:20; -+ uint64_t pbp:1; -+ uint64_t rsv_f:5; -+ uint64_t rparmode:2; -+ uint64_t rsv_e:1; -+ uint64_t rskp_len:7; -+ uint64_t rsv_d:6; -+ uint64_t use_ihdr:1; -+ uint64_t rsv_c:5; -+ uint64_t par_mode:2; -+ uint64_t rsv_b:1; -+ uint64_t skp_len:7; -+ uint64_t rsv_a:6; -+ } s; -+ struct cvmx_npi_port35_instr_hdr_s cn38xx; -+ struct cvmx_npi_port35_instr_hdr_s cn38xxp2; -+ struct cvmx_npi_port35_instr_hdr_s cn58xx; -+ struct cvmx_npi_port35_instr_hdr_s cn58xxp1; -+}; -+ -+union cvmx_npi_port_bp_control { -+ uint64_t u64; -+ struct cvmx_npi_port_bp_control_s { -+ uint64_t reserved_8_63:56; -+ uint64_t bp_on:4; -+ uint64_t enb:4; -+ } s; -+ struct cvmx_npi_port_bp_control_s cn30xx; -+ struct cvmx_npi_port_bp_control_s cn31xx; -+ struct cvmx_npi_port_bp_control_s cn38xx; -+ struct cvmx_npi_port_bp_control_s cn38xxp2; -+ struct cvmx_npi_port_bp_control_s cn50xx; -+ struct cvmx_npi_port_bp_control_s cn58xx; -+ struct cvmx_npi_port_bp_control_s cn58xxp1; -+}; -+ -+union cvmx_npi_rsl_int_blocks { -+ uint64_t u64; -+ struct cvmx_npi_rsl_int_blocks_s { -+ uint64_t reserved_32_63:32; -+ uint64_t rint_31:1; -+ uint64_t iob:1; -+ uint64_t reserved_28_29:2; -+ uint64_t rint_27:1; -+ uint64_t rint_26:1; -+ uint64_t rint_25:1; -+ uint64_t rint_24:1; -+ uint64_t asx1:1; -+ uint64_t asx0:1; -+ uint64_t rint_21:1; -+ uint64_t pip:1; -+ uint64_t spx1:1; -+ uint64_t spx0:1; -+ uint64_t lmc:1; -+ uint64_t l2c:1; -+ uint64_t rint_15:1; -+ uint64_t reserved_13_14:2; -+ uint64_t pow:1; -+ uint64_t tim:1; -+ uint64_t pko:1; -+ uint64_t ipd:1; -+ uint64_t rint_8:1; -+ uint64_t zip:1; -+ uint64_t dfa:1; -+ uint64_t fpa:1; -+ uint64_t key:1; -+ uint64_t npi:1; -+ uint64_t gmx1:1; -+ uint64_t gmx0:1; -+ uint64_t mio:1; -+ } s; -+ struct cvmx_npi_rsl_int_blocks_cn30xx { -+ uint64_t reserved_32_63:32; -+ uint64_t rint_31:1; -+ uint64_t iob:1; -+ uint64_t rint_29:1; -+ uint64_t rint_28:1; -+ uint64_t rint_27:1; -+ uint64_t rint_26:1; -+ uint64_t rint_25:1; -+ uint64_t rint_24:1; -+ uint64_t asx1:1; -+ uint64_t asx0:1; -+ uint64_t rint_21:1; -+ uint64_t pip:1; -+ uint64_t spx1:1; -+ uint64_t spx0:1; -+ uint64_t lmc:1; -+ uint64_t l2c:1; -+ uint64_t rint_15:1; -+ uint64_t rint_14:1; -+ uint64_t usb:1; -+ uint64_t pow:1; -+ uint64_t tim:1; -+ uint64_t pko:1; -+ uint64_t ipd:1; -+ uint64_t rint_8:1; -+ uint64_t zip:1; -+ uint64_t dfa:1; -+ uint64_t fpa:1; -+ uint64_t key:1; -+ uint64_t npi:1; -+ uint64_t gmx1:1; -+ uint64_t gmx0:1; -+ uint64_t mio:1; -+ } cn30xx; -+ struct cvmx_npi_rsl_int_blocks_cn30xx cn31xx; -+ struct cvmx_npi_rsl_int_blocks_cn38xx { -+ uint64_t reserved_32_63:32; -+ uint64_t rint_31:1; -+ uint64_t iob:1; -+ uint64_t rint_29:1; -+ uint64_t rint_28:1; -+ uint64_t rint_27:1; -+ uint64_t rint_26:1; -+ uint64_t rint_25:1; -+ uint64_t rint_24:1; -+ uint64_t asx1:1; -+ uint64_t asx0:1; -+ uint64_t rint_21:1; -+ uint64_t pip:1; -+ uint64_t spx1:1; -+ uint64_t spx0:1; -+ uint64_t lmc:1; -+ uint64_t l2c:1; -+ uint64_t rint_15:1; -+ uint64_t rint_14:1; -+ uint64_t rint_13:1; -+ uint64_t pow:1; -+ uint64_t tim:1; -+ uint64_t pko:1; -+ uint64_t ipd:1; -+ uint64_t rint_8:1; -+ uint64_t zip:1; -+ uint64_t dfa:1; -+ uint64_t fpa:1; -+ uint64_t key:1; -+ uint64_t npi:1; -+ uint64_t gmx1:1; -+ uint64_t gmx0:1; -+ uint64_t mio:1; -+ } cn38xx; -+ struct cvmx_npi_rsl_int_blocks_cn38xx cn38xxp2; -+ struct cvmx_npi_rsl_int_blocks_cn50xx { -+ uint64_t reserved_31_63:33; -+ uint64_t iob:1; -+ uint64_t lmc1:1; -+ uint64_t agl:1; -+ uint64_t reserved_24_27:4; -+ uint64_t asx1:1; -+ uint64_t asx0:1; -+ uint64_t reserved_21_21:1; -+ uint64_t pip:1; -+ uint64_t spx1:1; -+ uint64_t spx0:1; -+ uint64_t lmc:1; -+ uint64_t l2c:1; -+ uint64_t reserved_15_15:1; -+ uint64_t rad:1; -+ uint64_t usb:1; -+ uint64_t pow:1; -+ uint64_t tim:1; -+ uint64_t pko:1; -+ uint64_t ipd:1; -+ uint64_t reserved_8_8:1; -+ uint64_t zip:1; -+ uint64_t dfa:1; -+ uint64_t fpa:1; -+ uint64_t key:1; -+ uint64_t npi:1; -+ uint64_t gmx1:1; -+ uint64_t gmx0:1; -+ uint64_t mio:1; -+ } cn50xx; -+ struct cvmx_npi_rsl_int_blocks_cn38xx cn58xx; -+ struct cvmx_npi_rsl_int_blocks_cn38xx cn58xxp1; -+}; -+ -+union cvmx_npi_size_inputx { -+ uint64_t u64; -+ struct cvmx_npi_size_inputx_s { -+ uint64_t reserved_32_63:32; -+ uint64_t size:32; -+ } s; -+ struct cvmx_npi_size_inputx_s cn30xx; -+ struct cvmx_npi_size_inputx_s cn31xx; -+ struct cvmx_npi_size_inputx_s cn38xx; -+ struct cvmx_npi_size_inputx_s cn38xxp2; -+ struct cvmx_npi_size_inputx_s cn50xx; -+ struct cvmx_npi_size_inputx_s cn58xx; -+ struct cvmx_npi_size_inputx_s cn58xxp1; -+}; -+ -+union cvmx_npi_win_read_to { -+ uint64_t u64; -+ struct cvmx_npi_win_read_to_s { -+ uint64_t reserved_32_63:32; -+ uint64_t time:32; -+ } s; -+ struct cvmx_npi_win_read_to_s cn30xx; -+ struct cvmx_npi_win_read_to_s cn31xx; -+ struct cvmx_npi_win_read_to_s cn38xx; -+ struct cvmx_npi_win_read_to_s cn38xxp2; -+ struct cvmx_npi_win_read_to_s cn50xx; -+ struct cvmx_npi_win_read_to_s cn58xx; -+ struct cvmx_npi_win_read_to_s cn58xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-pci-defs.h -@@ -0,0 +1,1645 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_PCI_DEFS_H__ -+#define __CVMX_PCI_DEFS_H__ -+ -+#define CVMX_PCI_BAR1_INDEXX(offset) \ -+ (0x0000000000000100ull + (((offset) & 31) * 4)) -+#define CVMX_PCI_BIST_REG \ -+ (0x00000000000001C0ull) -+#define CVMX_PCI_CFG00 \ -+ (0x0000000000000000ull) -+#define CVMX_PCI_CFG01 \ -+ (0x0000000000000004ull) -+#define CVMX_PCI_CFG02 \ -+ (0x0000000000000008ull) -+#define CVMX_PCI_CFG03 \ -+ (0x000000000000000Cull) -+#define CVMX_PCI_CFG04 \ -+ (0x0000000000000010ull) -+#define CVMX_PCI_CFG05 \ -+ (0x0000000000000014ull) -+#define CVMX_PCI_CFG06 \ -+ (0x0000000000000018ull) -+#define CVMX_PCI_CFG07 \ -+ (0x000000000000001Cull) -+#define CVMX_PCI_CFG08 \ -+ (0x0000000000000020ull) -+#define CVMX_PCI_CFG09 \ -+ (0x0000000000000024ull) -+#define CVMX_PCI_CFG10 \ -+ (0x0000000000000028ull) -+#define CVMX_PCI_CFG11 \ -+ (0x000000000000002Cull) -+#define CVMX_PCI_CFG12 \ -+ (0x0000000000000030ull) -+#define CVMX_PCI_CFG13 \ -+ (0x0000000000000034ull) -+#define CVMX_PCI_CFG15 \ -+ (0x000000000000003Cull) -+#define CVMX_PCI_CFG16 \ -+ (0x0000000000000040ull) -+#define CVMX_PCI_CFG17 \ -+ (0x0000000000000044ull) -+#define CVMX_PCI_CFG18 \ -+ (0x0000000000000048ull) -+#define CVMX_PCI_CFG19 \ -+ (0x000000000000004Cull) -+#define CVMX_PCI_CFG20 \ -+ (0x0000000000000050ull) -+#define CVMX_PCI_CFG21 \ -+ (0x0000000000000054ull) -+#define CVMX_PCI_CFG22 \ -+ (0x0000000000000058ull) -+#define CVMX_PCI_CFG56 \ -+ (0x00000000000000E0ull) -+#define CVMX_PCI_CFG57 \ -+ (0x00000000000000E4ull) -+#define CVMX_PCI_CFG58 \ -+ (0x00000000000000E8ull) -+#define CVMX_PCI_CFG59 \ -+ (0x00000000000000ECull) -+#define CVMX_PCI_CFG60 \ -+ (0x00000000000000F0ull) -+#define CVMX_PCI_CFG61 \ -+ (0x00000000000000F4ull) -+#define CVMX_PCI_CFG62 \ -+ (0x00000000000000F8ull) -+#define CVMX_PCI_CFG63 \ -+ (0x00000000000000FCull) -+#define CVMX_PCI_CNT_REG \ -+ (0x00000000000001B8ull) -+#define CVMX_PCI_CTL_STATUS_2 \ -+ (0x000000000000018Cull) -+#define CVMX_PCI_DBELL_0 \ -+ (0x0000000000000080ull) -+#define CVMX_PCI_DBELL_1 \ -+ (0x0000000000000088ull) -+#define CVMX_PCI_DBELL_2 \ -+ (0x0000000000000090ull) -+#define CVMX_PCI_DBELL_3 \ -+ (0x0000000000000098ull) -+#define CVMX_PCI_DBELL_X(offset) \ -+ (0x0000000000000080ull + (((offset) & 3) * 8)) -+#define CVMX_PCI_DMA_CNT0 \ -+ (0x00000000000000A0ull) -+#define CVMX_PCI_DMA_CNT1 \ -+ (0x00000000000000A8ull) -+#define CVMX_PCI_DMA_CNTX(offset) \ -+ (0x00000000000000A0ull + (((offset) & 1) * 8)) -+#define CVMX_PCI_DMA_INT_LEV0 \ -+ (0x00000000000000A4ull) -+#define CVMX_PCI_DMA_INT_LEV1 \ -+ (0x00000000000000ACull) -+#define CVMX_PCI_DMA_INT_LEVX(offset) \ -+ (0x00000000000000A4ull + (((offset) & 1) * 8)) -+#define CVMX_PCI_DMA_TIME0 \ -+ (0x00000000000000B0ull) -+#define CVMX_PCI_DMA_TIME1 \ -+ (0x00000000000000B4ull) -+#define CVMX_PCI_DMA_TIMEX(offset) \ -+ (0x00000000000000B0ull + (((offset) & 1) * 4)) -+#define CVMX_PCI_INSTR_COUNT0 \ -+ (0x0000000000000084ull) -+#define CVMX_PCI_INSTR_COUNT1 \ -+ (0x000000000000008Cull) -+#define CVMX_PCI_INSTR_COUNT2 \ -+ (0x0000000000000094ull) -+#define CVMX_PCI_INSTR_COUNT3 \ -+ (0x000000000000009Cull) -+#define CVMX_PCI_INSTR_COUNTX(offset) \ -+ (0x0000000000000084ull + (((offset) & 3) * 8)) -+#define CVMX_PCI_INT_ENB \ -+ (0x0000000000000038ull) -+#define CVMX_PCI_INT_ENB2 \ -+ (0x00000000000001A0ull) -+#define CVMX_PCI_INT_SUM \ -+ (0x0000000000000030ull) -+#define CVMX_PCI_INT_SUM2 \ -+ (0x0000000000000198ull) -+#define CVMX_PCI_MSI_RCV \ -+ (0x00000000000000F0ull) -+#define CVMX_PCI_PKTS_SENT0 \ -+ (0x0000000000000040ull) -+#define CVMX_PCI_PKTS_SENT1 \ -+ (0x0000000000000050ull) -+#define CVMX_PCI_PKTS_SENT2 \ -+ (0x0000000000000060ull) -+#define CVMX_PCI_PKTS_SENT3 \ -+ (0x0000000000000070ull) -+#define CVMX_PCI_PKTS_SENTX(offset) \ -+ (0x0000000000000040ull + (((offset) & 3) * 16)) -+#define CVMX_PCI_PKTS_SENT_INT_LEV0 \ -+ (0x0000000000000048ull) -+#define CVMX_PCI_PKTS_SENT_INT_LEV1 \ -+ (0x0000000000000058ull) -+#define CVMX_PCI_PKTS_SENT_INT_LEV2 \ -+ (0x0000000000000068ull) -+#define CVMX_PCI_PKTS_SENT_INT_LEV3 \ -+ (0x0000000000000078ull) -+#define CVMX_PCI_PKTS_SENT_INT_LEVX(offset) \ -+ (0x0000000000000048ull + (((offset) & 3) * 16)) -+#define CVMX_PCI_PKTS_SENT_TIME0 \ -+ (0x000000000000004Cull) -+#define CVMX_PCI_PKTS_SENT_TIME1 \ -+ (0x000000000000005Cull) -+#define CVMX_PCI_PKTS_SENT_TIME2 \ -+ (0x000000000000006Cull) -+#define CVMX_PCI_PKTS_SENT_TIME3 \ -+ (0x000000000000007Cull) -+#define CVMX_PCI_PKTS_SENT_TIMEX(offset) \ -+ (0x000000000000004Cull + (((offset) & 3) * 16)) -+#define CVMX_PCI_PKT_CREDITS0 \ -+ (0x0000000000000044ull) -+#define CVMX_PCI_PKT_CREDITS1 \ -+ (0x0000000000000054ull) -+#define CVMX_PCI_PKT_CREDITS2 \ -+ (0x0000000000000064ull) -+#define CVMX_PCI_PKT_CREDITS3 \ -+ (0x0000000000000074ull) -+#define CVMX_PCI_PKT_CREDITSX(offset) \ -+ (0x0000000000000044ull + (((offset) & 3) * 16)) -+#define CVMX_PCI_READ_CMD_6 \ -+ (0x0000000000000180ull) -+#define CVMX_PCI_READ_CMD_C \ -+ (0x0000000000000184ull) -+#define CVMX_PCI_READ_CMD_E \ -+ (0x0000000000000188ull) -+#define CVMX_PCI_READ_TIMEOUT \ -+ CVMX_ADD_IO_SEG(0x00011F00000000B0ull) -+#define CVMX_PCI_SCM_REG \ -+ (0x00000000000001A8ull) -+#define CVMX_PCI_TSR_REG \ -+ (0x00000000000001B0ull) -+#define CVMX_PCI_WIN_RD_ADDR \ -+ (0x0000000000000008ull) -+#define CVMX_PCI_WIN_RD_DATA \ -+ (0x0000000000000020ull) -+#define CVMX_PCI_WIN_WR_ADDR \ -+ (0x0000000000000000ull) -+#define CVMX_PCI_WIN_WR_DATA \ -+ (0x0000000000000010ull) -+#define CVMX_PCI_WIN_WR_MASK \ -+ (0x0000000000000018ull) -+ -+union cvmx_pci_bar1_indexx { -+ uint32_t u32; -+ struct cvmx_pci_bar1_indexx_s { -+ uint32_t reserved_18_31:14; -+ uint32_t addr_idx:14; -+ uint32_t ca:1; -+ uint32_t end_swp:2; -+ uint32_t addr_v:1; -+ } s; -+ struct cvmx_pci_bar1_indexx_s cn30xx; -+ struct cvmx_pci_bar1_indexx_s cn31xx; -+ struct cvmx_pci_bar1_indexx_s cn38xx; -+ struct cvmx_pci_bar1_indexx_s cn38xxp2; -+ struct cvmx_pci_bar1_indexx_s cn50xx; -+ struct cvmx_pci_bar1_indexx_s cn58xx; -+ struct cvmx_pci_bar1_indexx_s cn58xxp1; -+}; -+ -+union cvmx_pci_bist_reg { -+ uint64_t u64; -+ struct cvmx_pci_bist_reg_s { -+ uint64_t reserved_10_63:54; -+ uint64_t rsp_bs:1; -+ uint64_t dma0_bs:1; -+ uint64_t cmd0_bs:1; -+ uint64_t cmd_bs:1; -+ uint64_t csr2p_bs:1; -+ uint64_t csrr_bs:1; -+ uint64_t rsp2p_bs:1; -+ uint64_t csr2n_bs:1; -+ uint64_t dat2n_bs:1; -+ uint64_t dbg2n_bs:1; -+ } s; -+ struct cvmx_pci_bist_reg_s cn50xx; -+}; -+ -+union cvmx_pci_cfg00 { -+ uint32_t u32; -+ struct cvmx_pci_cfg00_s { -+ uint32_t devid:16; -+ uint32_t vendid:16; -+ } s; -+ struct cvmx_pci_cfg00_s cn30xx; -+ struct cvmx_pci_cfg00_s cn31xx; -+ struct cvmx_pci_cfg00_s cn38xx; -+ struct cvmx_pci_cfg00_s cn38xxp2; -+ struct cvmx_pci_cfg00_s cn50xx; -+ struct cvmx_pci_cfg00_s cn58xx; -+ struct cvmx_pci_cfg00_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg01 { -+ uint32_t u32; -+ struct cvmx_pci_cfg01_s { -+ uint32_t dpe:1; -+ uint32_t sse:1; -+ uint32_t rma:1; -+ uint32_t rta:1; -+ uint32_t sta:1; -+ uint32_t devt:2; -+ uint32_t mdpe:1; -+ uint32_t fbb:1; -+ uint32_t reserved_22_22:1; -+ uint32_t m66:1; -+ uint32_t cle:1; -+ uint32_t i_stat:1; -+ uint32_t reserved_11_18:8; -+ uint32_t i_dis:1; -+ uint32_t fbbe:1; -+ uint32_t see:1; -+ uint32_t ads:1; -+ uint32_t pee:1; -+ uint32_t vps:1; -+ uint32_t mwice:1; -+ uint32_t scse:1; -+ uint32_t me:1; -+ uint32_t msae:1; -+ uint32_t isae:1; -+ } s; -+ struct cvmx_pci_cfg01_s cn30xx; -+ struct cvmx_pci_cfg01_s cn31xx; -+ struct cvmx_pci_cfg01_s cn38xx; -+ struct cvmx_pci_cfg01_s cn38xxp2; -+ struct cvmx_pci_cfg01_s cn50xx; -+ struct cvmx_pci_cfg01_s cn58xx; -+ struct cvmx_pci_cfg01_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg02 { -+ uint32_t u32; -+ struct cvmx_pci_cfg02_s { -+ uint32_t cc:24; -+ uint32_t rid:8; -+ } s; -+ struct cvmx_pci_cfg02_s cn30xx; -+ struct cvmx_pci_cfg02_s cn31xx; -+ struct cvmx_pci_cfg02_s cn38xx; -+ struct cvmx_pci_cfg02_s cn38xxp2; -+ struct cvmx_pci_cfg02_s cn50xx; -+ struct cvmx_pci_cfg02_s cn58xx; -+ struct cvmx_pci_cfg02_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg03 { -+ uint32_t u32; -+ struct cvmx_pci_cfg03_s { -+ uint32_t bcap:1; -+ uint32_t brb:1; -+ uint32_t reserved_28_29:2; -+ uint32_t bcod:4; -+ uint32_t ht:8; -+ uint32_t lt:8; -+ uint32_t cls:8; -+ } s; -+ struct cvmx_pci_cfg03_s cn30xx; -+ struct cvmx_pci_cfg03_s cn31xx; -+ struct cvmx_pci_cfg03_s cn38xx; -+ struct cvmx_pci_cfg03_s cn38xxp2; -+ struct cvmx_pci_cfg03_s cn50xx; -+ struct cvmx_pci_cfg03_s cn58xx; -+ struct cvmx_pci_cfg03_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg04 { -+ uint32_t u32; -+ struct cvmx_pci_cfg04_s { -+ uint32_t lbase:20; -+ uint32_t lbasez:8; -+ uint32_t pf:1; -+ uint32_t typ:2; -+ uint32_t mspc:1; -+ } s; -+ struct cvmx_pci_cfg04_s cn30xx; -+ struct cvmx_pci_cfg04_s cn31xx; -+ struct cvmx_pci_cfg04_s cn38xx; -+ struct cvmx_pci_cfg04_s cn38xxp2; -+ struct cvmx_pci_cfg04_s cn50xx; -+ struct cvmx_pci_cfg04_s cn58xx; -+ struct cvmx_pci_cfg04_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg05 { -+ uint32_t u32; -+ struct cvmx_pci_cfg05_s { -+ uint32_t hbase:32; -+ } s; -+ struct cvmx_pci_cfg05_s cn30xx; -+ struct cvmx_pci_cfg05_s cn31xx; -+ struct cvmx_pci_cfg05_s cn38xx; -+ struct cvmx_pci_cfg05_s cn38xxp2; -+ struct cvmx_pci_cfg05_s cn50xx; -+ struct cvmx_pci_cfg05_s cn58xx; -+ struct cvmx_pci_cfg05_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg06 { -+ uint32_t u32; -+ struct cvmx_pci_cfg06_s { -+ uint32_t lbase:5; -+ uint32_t lbasez:23; -+ uint32_t pf:1; -+ uint32_t typ:2; -+ uint32_t mspc:1; -+ } s; -+ struct cvmx_pci_cfg06_s cn30xx; -+ struct cvmx_pci_cfg06_s cn31xx; -+ struct cvmx_pci_cfg06_s cn38xx; -+ struct cvmx_pci_cfg06_s cn38xxp2; -+ struct cvmx_pci_cfg06_s cn50xx; -+ struct cvmx_pci_cfg06_s cn58xx; -+ struct cvmx_pci_cfg06_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg07 { -+ uint32_t u32; -+ struct cvmx_pci_cfg07_s { -+ uint32_t hbase:32; -+ } s; -+ struct cvmx_pci_cfg07_s cn30xx; -+ struct cvmx_pci_cfg07_s cn31xx; -+ struct cvmx_pci_cfg07_s cn38xx; -+ struct cvmx_pci_cfg07_s cn38xxp2; -+ struct cvmx_pci_cfg07_s cn50xx; -+ struct cvmx_pci_cfg07_s cn58xx; -+ struct cvmx_pci_cfg07_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg08 { -+ uint32_t u32; -+ struct cvmx_pci_cfg08_s { -+ uint32_t lbasez:28; -+ uint32_t pf:1; -+ uint32_t typ:2; -+ uint32_t mspc:1; -+ } s; -+ struct cvmx_pci_cfg08_s cn30xx; -+ struct cvmx_pci_cfg08_s cn31xx; -+ struct cvmx_pci_cfg08_s cn38xx; -+ struct cvmx_pci_cfg08_s cn38xxp2; -+ struct cvmx_pci_cfg08_s cn50xx; -+ struct cvmx_pci_cfg08_s cn58xx; -+ struct cvmx_pci_cfg08_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg09 { -+ uint32_t u32; -+ struct cvmx_pci_cfg09_s { -+ uint32_t hbase:25; -+ uint32_t hbasez:7; -+ } s; -+ struct cvmx_pci_cfg09_s cn30xx; -+ struct cvmx_pci_cfg09_s cn31xx; -+ struct cvmx_pci_cfg09_s cn38xx; -+ struct cvmx_pci_cfg09_s cn38xxp2; -+ struct cvmx_pci_cfg09_s cn50xx; -+ struct cvmx_pci_cfg09_s cn58xx; -+ struct cvmx_pci_cfg09_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg10 { -+ uint32_t u32; -+ struct cvmx_pci_cfg10_s { -+ uint32_t cisp:32; -+ } s; -+ struct cvmx_pci_cfg10_s cn30xx; -+ struct cvmx_pci_cfg10_s cn31xx; -+ struct cvmx_pci_cfg10_s cn38xx; -+ struct cvmx_pci_cfg10_s cn38xxp2; -+ struct cvmx_pci_cfg10_s cn50xx; -+ struct cvmx_pci_cfg10_s cn58xx; -+ struct cvmx_pci_cfg10_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg11 { -+ uint32_t u32; -+ struct cvmx_pci_cfg11_s { -+ uint32_t ssid:16; -+ uint32_t ssvid:16; -+ } s; -+ struct cvmx_pci_cfg11_s cn30xx; -+ struct cvmx_pci_cfg11_s cn31xx; -+ struct cvmx_pci_cfg11_s cn38xx; -+ struct cvmx_pci_cfg11_s cn38xxp2; -+ struct cvmx_pci_cfg11_s cn50xx; -+ struct cvmx_pci_cfg11_s cn58xx; -+ struct cvmx_pci_cfg11_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg12 { -+ uint32_t u32; -+ struct cvmx_pci_cfg12_s { -+ uint32_t erbar:16; -+ uint32_t erbarz:5; -+ uint32_t reserved_1_10:10; -+ uint32_t erbar_en:1; -+ } s; -+ struct cvmx_pci_cfg12_s cn30xx; -+ struct cvmx_pci_cfg12_s cn31xx; -+ struct cvmx_pci_cfg12_s cn38xx; -+ struct cvmx_pci_cfg12_s cn38xxp2; -+ struct cvmx_pci_cfg12_s cn50xx; -+ struct cvmx_pci_cfg12_s cn58xx; -+ struct cvmx_pci_cfg12_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg13 { -+ uint32_t u32; -+ struct cvmx_pci_cfg13_s { -+ uint32_t reserved_8_31:24; -+ uint32_t cp:8; -+ } s; -+ struct cvmx_pci_cfg13_s cn30xx; -+ struct cvmx_pci_cfg13_s cn31xx; -+ struct cvmx_pci_cfg13_s cn38xx; -+ struct cvmx_pci_cfg13_s cn38xxp2; -+ struct cvmx_pci_cfg13_s cn50xx; -+ struct cvmx_pci_cfg13_s cn58xx; -+ struct cvmx_pci_cfg13_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg15 { -+ uint32_t u32; -+ struct cvmx_pci_cfg15_s { -+ uint32_t ml:8; -+ uint32_t mg:8; -+ uint32_t inta:8; -+ uint32_t il:8; -+ } s; -+ struct cvmx_pci_cfg15_s cn30xx; -+ struct cvmx_pci_cfg15_s cn31xx; -+ struct cvmx_pci_cfg15_s cn38xx; -+ struct cvmx_pci_cfg15_s cn38xxp2; -+ struct cvmx_pci_cfg15_s cn50xx; -+ struct cvmx_pci_cfg15_s cn58xx; -+ struct cvmx_pci_cfg15_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg16 { -+ uint32_t u32; -+ struct cvmx_pci_cfg16_s { -+ uint32_t trdnpr:1; -+ uint32_t trdard:1; -+ uint32_t rdsati:1; -+ uint32_t trdrs:1; -+ uint32_t trtae:1; -+ uint32_t twsei:1; -+ uint32_t twsen:1; -+ uint32_t twtae:1; -+ uint32_t tmae:1; -+ uint32_t tslte:3; -+ uint32_t tilt:4; -+ uint32_t pbe:12; -+ uint32_t dppmr:1; -+ uint32_t reserved_2_2:1; -+ uint32_t tswc:1; -+ uint32_t mltd:1; -+ } s; -+ struct cvmx_pci_cfg16_s cn30xx; -+ struct cvmx_pci_cfg16_s cn31xx; -+ struct cvmx_pci_cfg16_s cn38xx; -+ struct cvmx_pci_cfg16_s cn38xxp2; -+ struct cvmx_pci_cfg16_s cn50xx; -+ struct cvmx_pci_cfg16_s cn58xx; -+ struct cvmx_pci_cfg16_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg17 { -+ uint32_t u32; -+ struct cvmx_pci_cfg17_s { -+ uint32_t tscme:32; -+ } s; -+ struct cvmx_pci_cfg17_s cn30xx; -+ struct cvmx_pci_cfg17_s cn31xx; -+ struct cvmx_pci_cfg17_s cn38xx; -+ struct cvmx_pci_cfg17_s cn38xxp2; -+ struct cvmx_pci_cfg17_s cn50xx; -+ struct cvmx_pci_cfg17_s cn58xx; -+ struct cvmx_pci_cfg17_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg18 { -+ uint32_t u32; -+ struct cvmx_pci_cfg18_s { -+ uint32_t tdsrps:32; -+ } s; -+ struct cvmx_pci_cfg18_s cn30xx; -+ struct cvmx_pci_cfg18_s cn31xx; -+ struct cvmx_pci_cfg18_s cn38xx; -+ struct cvmx_pci_cfg18_s cn38xxp2; -+ struct cvmx_pci_cfg18_s cn50xx; -+ struct cvmx_pci_cfg18_s cn58xx; -+ struct cvmx_pci_cfg18_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg19 { -+ uint32_t u32; -+ struct cvmx_pci_cfg19_s { -+ uint32_t mrbcm:1; -+ uint32_t mrbci:1; -+ uint32_t mdwe:1; -+ uint32_t mdre:1; -+ uint32_t mdrimc:1; -+ uint32_t mdrrmc:3; -+ uint32_t tmes:8; -+ uint32_t teci:1; -+ uint32_t tmei:1; -+ uint32_t tmse:1; -+ uint32_t tmdpes:1; -+ uint32_t tmapes:1; -+ uint32_t reserved_9_10:2; -+ uint32_t tibcd:1; -+ uint32_t tibde:1; -+ uint32_t reserved_6_6:1; -+ uint32_t tidomc:1; -+ uint32_t tdomc:5; -+ } s; -+ struct cvmx_pci_cfg19_s cn30xx; -+ struct cvmx_pci_cfg19_s cn31xx; -+ struct cvmx_pci_cfg19_s cn38xx; -+ struct cvmx_pci_cfg19_s cn38xxp2; -+ struct cvmx_pci_cfg19_s cn50xx; -+ struct cvmx_pci_cfg19_s cn58xx; -+ struct cvmx_pci_cfg19_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg20 { -+ uint32_t u32; -+ struct cvmx_pci_cfg20_s { -+ uint32_t mdsp:32; -+ } s; -+ struct cvmx_pci_cfg20_s cn30xx; -+ struct cvmx_pci_cfg20_s cn31xx; -+ struct cvmx_pci_cfg20_s cn38xx; -+ struct cvmx_pci_cfg20_s cn38xxp2; -+ struct cvmx_pci_cfg20_s cn50xx; -+ struct cvmx_pci_cfg20_s cn58xx; -+ struct cvmx_pci_cfg20_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg21 { -+ uint32_t u32; -+ struct cvmx_pci_cfg21_s { -+ uint32_t scmre:32; -+ } s; -+ struct cvmx_pci_cfg21_s cn30xx; -+ struct cvmx_pci_cfg21_s cn31xx; -+ struct cvmx_pci_cfg21_s cn38xx; -+ struct cvmx_pci_cfg21_s cn38xxp2; -+ struct cvmx_pci_cfg21_s cn50xx; -+ struct cvmx_pci_cfg21_s cn58xx; -+ struct cvmx_pci_cfg21_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg22 { -+ uint32_t u32; -+ struct cvmx_pci_cfg22_s { -+ uint32_t mac:7; -+ uint32_t reserved_19_24:6; -+ uint32_t flush:1; -+ uint32_t mra:1; -+ uint32_t mtta:1; -+ uint32_t mrv:8; -+ uint32_t mttv:8; -+ } s; -+ struct cvmx_pci_cfg22_s cn30xx; -+ struct cvmx_pci_cfg22_s cn31xx; -+ struct cvmx_pci_cfg22_s cn38xx; -+ struct cvmx_pci_cfg22_s cn38xxp2; -+ struct cvmx_pci_cfg22_s cn50xx; -+ struct cvmx_pci_cfg22_s cn58xx; -+ struct cvmx_pci_cfg22_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg56 { -+ uint32_t u32; -+ struct cvmx_pci_cfg56_s { -+ uint32_t reserved_23_31:9; -+ uint32_t most:3; -+ uint32_t mmbc:2; -+ uint32_t roe:1; -+ uint32_t dpere:1; -+ uint32_t ncp:8; -+ uint32_t pxcid:8; -+ } s; -+ struct cvmx_pci_cfg56_s cn30xx; -+ struct cvmx_pci_cfg56_s cn31xx; -+ struct cvmx_pci_cfg56_s cn38xx; -+ struct cvmx_pci_cfg56_s cn38xxp2; -+ struct cvmx_pci_cfg56_s cn50xx; -+ struct cvmx_pci_cfg56_s cn58xx; -+ struct cvmx_pci_cfg56_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg57 { -+ uint32_t u32; -+ struct cvmx_pci_cfg57_s { -+ uint32_t reserved_30_31:2; -+ uint32_t scemr:1; -+ uint32_t mcrsd:3; -+ uint32_t mostd:3; -+ uint32_t mmrbcd:2; -+ uint32_t dc:1; -+ uint32_t usc:1; -+ uint32_t scd:1; -+ uint32_t m133:1; -+ uint32_t w64:1; -+ uint32_t bn:8; -+ uint32_t dn:5; -+ uint32_t fn:3; -+ } s; -+ struct cvmx_pci_cfg57_s cn30xx; -+ struct cvmx_pci_cfg57_s cn31xx; -+ struct cvmx_pci_cfg57_s cn38xx; -+ struct cvmx_pci_cfg57_s cn38xxp2; -+ struct cvmx_pci_cfg57_s cn50xx; -+ struct cvmx_pci_cfg57_s cn58xx; -+ struct cvmx_pci_cfg57_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg58 { -+ uint32_t u32; -+ struct cvmx_pci_cfg58_s { -+ uint32_t pmes:5; -+ uint32_t d2s:1; -+ uint32_t d1s:1; -+ uint32_t auxc:3; -+ uint32_t dsi:1; -+ uint32_t reserved_20_20:1; -+ uint32_t pmec:1; -+ uint32_t pcimiv:3; -+ uint32_t ncp:8; -+ uint32_t pmcid:8; -+ } s; -+ struct cvmx_pci_cfg58_s cn30xx; -+ struct cvmx_pci_cfg58_s cn31xx; -+ struct cvmx_pci_cfg58_s cn38xx; -+ struct cvmx_pci_cfg58_s cn38xxp2; -+ struct cvmx_pci_cfg58_s cn50xx; -+ struct cvmx_pci_cfg58_s cn58xx; -+ struct cvmx_pci_cfg58_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg59 { -+ uint32_t u32; -+ struct cvmx_pci_cfg59_s { -+ uint32_t pmdia:8; -+ uint32_t bpccen:1; -+ uint32_t bd3h:1; -+ uint32_t reserved_16_21:6; -+ uint32_t pmess:1; -+ uint32_t pmedsia:2; -+ uint32_t pmds:4; -+ uint32_t pmeens:1; -+ uint32_t reserved_2_7:6; -+ uint32_t ps:2; -+ } s; -+ struct cvmx_pci_cfg59_s cn30xx; -+ struct cvmx_pci_cfg59_s cn31xx; -+ struct cvmx_pci_cfg59_s cn38xx; -+ struct cvmx_pci_cfg59_s cn38xxp2; -+ struct cvmx_pci_cfg59_s cn50xx; -+ struct cvmx_pci_cfg59_s cn58xx; -+ struct cvmx_pci_cfg59_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg60 { -+ uint32_t u32; -+ struct cvmx_pci_cfg60_s { -+ uint32_t reserved_24_31:8; -+ uint32_t m64:1; -+ uint32_t mme:3; -+ uint32_t mmc:3; -+ uint32_t msien:1; -+ uint32_t ncp:8; -+ uint32_t msicid:8; -+ } s; -+ struct cvmx_pci_cfg60_s cn30xx; -+ struct cvmx_pci_cfg60_s cn31xx; -+ struct cvmx_pci_cfg60_s cn38xx; -+ struct cvmx_pci_cfg60_s cn38xxp2; -+ struct cvmx_pci_cfg60_s cn50xx; -+ struct cvmx_pci_cfg60_s cn58xx; -+ struct cvmx_pci_cfg60_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg61 { -+ uint32_t u32; -+ struct cvmx_pci_cfg61_s { -+ uint32_t msi31t2:30; -+ uint32_t reserved_0_1:2; -+ } s; -+ struct cvmx_pci_cfg61_s cn30xx; -+ struct cvmx_pci_cfg61_s cn31xx; -+ struct cvmx_pci_cfg61_s cn38xx; -+ struct cvmx_pci_cfg61_s cn38xxp2; -+ struct cvmx_pci_cfg61_s cn50xx; -+ struct cvmx_pci_cfg61_s cn58xx; -+ struct cvmx_pci_cfg61_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg62 { -+ uint32_t u32; -+ struct cvmx_pci_cfg62_s { -+ uint32_t msi:32; -+ } s; -+ struct cvmx_pci_cfg62_s cn30xx; -+ struct cvmx_pci_cfg62_s cn31xx; -+ struct cvmx_pci_cfg62_s cn38xx; -+ struct cvmx_pci_cfg62_s cn38xxp2; -+ struct cvmx_pci_cfg62_s cn50xx; -+ struct cvmx_pci_cfg62_s cn58xx; -+ struct cvmx_pci_cfg62_s cn58xxp1; -+}; -+ -+union cvmx_pci_cfg63 { -+ uint32_t u32; -+ struct cvmx_pci_cfg63_s { -+ uint32_t reserved_16_31:16; -+ uint32_t msimd:16; -+ } s; -+ struct cvmx_pci_cfg63_s cn30xx; -+ struct cvmx_pci_cfg63_s cn31xx; -+ struct cvmx_pci_cfg63_s cn38xx; -+ struct cvmx_pci_cfg63_s cn38xxp2; -+ struct cvmx_pci_cfg63_s cn50xx; -+ struct cvmx_pci_cfg63_s cn58xx; -+ struct cvmx_pci_cfg63_s cn58xxp1; -+}; -+ -+union cvmx_pci_cnt_reg { -+ uint64_t u64; -+ struct cvmx_pci_cnt_reg_s { -+ uint64_t reserved_38_63:26; -+ uint64_t hm_pcix:1; -+ uint64_t hm_speed:2; -+ uint64_t ap_pcix:1; -+ uint64_t ap_speed:2; -+ uint64_t pcicnt:32; -+ } s; -+ struct cvmx_pci_cnt_reg_s cn50xx; -+ struct cvmx_pci_cnt_reg_s cn58xx; -+ struct cvmx_pci_cnt_reg_s cn58xxp1; -+}; -+ -+union cvmx_pci_ctl_status_2 { -+ uint32_t u32; -+ struct cvmx_pci_ctl_status_2_s { -+ uint32_t reserved_29_31:3; -+ uint32_t bb1_hole:3; -+ uint32_t bb1_siz:1; -+ uint32_t bb_ca:1; -+ uint32_t bb_es:2; -+ uint32_t bb1:1; -+ uint32_t bb0:1; -+ uint32_t erst_n:1; -+ uint32_t bar2pres:1; -+ uint32_t scmtyp:1; -+ uint32_t scm:1; -+ uint32_t en_wfilt:1; -+ uint32_t reserved_14_14:1; -+ uint32_t ap_pcix:1; -+ uint32_t ap_64ad:1; -+ uint32_t b12_bist:1; -+ uint32_t pmo_amod:1; -+ uint32_t pmo_fpc:3; -+ uint32_t tsr_hwm:3; -+ uint32_t bar2_enb:1; -+ uint32_t bar2_esx:2; -+ uint32_t bar2_cax:1; -+ } s; -+ struct cvmx_pci_ctl_status_2_s cn30xx; -+ struct cvmx_pci_ctl_status_2_cn31xx { -+ uint32_t reserved_20_31:12; -+ uint32_t erst_n:1; -+ uint32_t bar2pres:1; -+ uint32_t scmtyp:1; -+ uint32_t scm:1; -+ uint32_t en_wfilt:1; -+ uint32_t reserved_14_14:1; -+ uint32_t ap_pcix:1; -+ uint32_t ap_64ad:1; -+ uint32_t b12_bist:1; -+ uint32_t pmo_amod:1; -+ uint32_t pmo_fpc:3; -+ uint32_t tsr_hwm:3; -+ uint32_t bar2_enb:1; -+ uint32_t bar2_esx:2; -+ uint32_t bar2_cax:1; -+ } cn31xx; -+ struct cvmx_pci_ctl_status_2_s cn38xx; -+ struct cvmx_pci_ctl_status_2_cn31xx cn38xxp2; -+ struct cvmx_pci_ctl_status_2_s cn50xx; -+ struct cvmx_pci_ctl_status_2_s cn58xx; -+ struct cvmx_pci_ctl_status_2_s cn58xxp1; -+}; -+ -+union cvmx_pci_dbellx { -+ uint32_t u32; -+ struct cvmx_pci_dbellx_s { -+ uint32_t reserved_16_31:16; -+ uint32_t inc_val:16; -+ } s; -+ struct cvmx_pci_dbellx_s cn30xx; -+ struct cvmx_pci_dbellx_s cn31xx; -+ struct cvmx_pci_dbellx_s cn38xx; -+ struct cvmx_pci_dbellx_s cn38xxp2; -+ struct cvmx_pci_dbellx_s cn50xx; -+ struct cvmx_pci_dbellx_s cn58xx; -+ struct cvmx_pci_dbellx_s cn58xxp1; -+}; -+ -+union cvmx_pci_dma_cntx { -+ uint32_t u32; -+ struct cvmx_pci_dma_cntx_s { -+ uint32_t dma_cnt:32; -+ } s; -+ struct cvmx_pci_dma_cntx_s cn30xx; -+ struct cvmx_pci_dma_cntx_s cn31xx; -+ struct cvmx_pci_dma_cntx_s cn38xx; -+ struct cvmx_pci_dma_cntx_s cn38xxp2; -+ struct cvmx_pci_dma_cntx_s cn50xx; -+ struct cvmx_pci_dma_cntx_s cn58xx; -+ struct cvmx_pci_dma_cntx_s cn58xxp1; -+}; -+ -+union cvmx_pci_dma_int_levx { -+ uint32_t u32; -+ struct cvmx_pci_dma_int_levx_s { -+ uint32_t pkt_cnt:32; -+ } s; -+ struct cvmx_pci_dma_int_levx_s cn30xx; -+ struct cvmx_pci_dma_int_levx_s cn31xx; -+ struct cvmx_pci_dma_int_levx_s cn38xx; -+ struct cvmx_pci_dma_int_levx_s cn38xxp2; -+ struct cvmx_pci_dma_int_levx_s cn50xx; -+ struct cvmx_pci_dma_int_levx_s cn58xx; -+ struct cvmx_pci_dma_int_levx_s cn58xxp1; -+}; -+ -+union cvmx_pci_dma_timex { -+ uint32_t u32; -+ struct cvmx_pci_dma_timex_s { -+ uint32_t dma_time:32; -+ } s; -+ struct cvmx_pci_dma_timex_s cn30xx; -+ struct cvmx_pci_dma_timex_s cn31xx; -+ struct cvmx_pci_dma_timex_s cn38xx; -+ struct cvmx_pci_dma_timex_s cn38xxp2; -+ struct cvmx_pci_dma_timex_s cn50xx; -+ struct cvmx_pci_dma_timex_s cn58xx; -+ struct cvmx_pci_dma_timex_s cn58xxp1; -+}; -+ -+union cvmx_pci_instr_countx { -+ uint32_t u32; -+ struct cvmx_pci_instr_countx_s { -+ uint32_t icnt:32; -+ } s; -+ struct cvmx_pci_instr_countx_s cn30xx; -+ struct cvmx_pci_instr_countx_s cn31xx; -+ struct cvmx_pci_instr_countx_s cn38xx; -+ struct cvmx_pci_instr_countx_s cn38xxp2; -+ struct cvmx_pci_instr_countx_s cn50xx; -+ struct cvmx_pci_instr_countx_s cn58xx; -+ struct cvmx_pci_instr_countx_s cn58xxp1; -+}; -+ -+union cvmx_pci_int_enb { -+ uint64_t u64; -+ struct cvmx_pci_int_enb_s { -+ uint64_t reserved_34_63:30; -+ uint64_t ill_rd:1; -+ uint64_t ill_wr:1; -+ uint64_t win_wr:1; -+ uint64_t dma1_fi:1; -+ uint64_t dma0_fi:1; -+ uint64_t idtime1:1; -+ uint64_t idtime0:1; -+ uint64_t idcnt1:1; -+ uint64_t idcnt0:1; -+ uint64_t iptime3:1; -+ uint64_t iptime2:1; -+ uint64_t iptime1:1; -+ uint64_t iptime0:1; -+ uint64_t ipcnt3:1; -+ uint64_t ipcnt2:1; -+ uint64_t ipcnt1:1; -+ uint64_t ipcnt0:1; -+ uint64_t irsl_int:1; -+ uint64_t ill_rrd:1; -+ uint64_t ill_rwr:1; -+ uint64_t idperr:1; -+ uint64_t iaperr:1; -+ uint64_t iserr:1; -+ uint64_t itsr_abt:1; -+ uint64_t imsc_msg:1; -+ uint64_t imsi_mabt:1; -+ uint64_t imsi_tabt:1; -+ uint64_t imsi_per:1; -+ uint64_t imr_tto:1; -+ uint64_t imr_abt:1; -+ uint64_t itr_abt:1; -+ uint64_t imr_wtto:1; -+ uint64_t imr_wabt:1; -+ uint64_t itr_wabt:1; -+ } s; -+ struct cvmx_pci_int_enb_cn30xx { -+ uint64_t reserved_34_63:30; -+ uint64_t ill_rd:1; -+ uint64_t ill_wr:1; -+ uint64_t win_wr:1; -+ uint64_t dma1_fi:1; -+ uint64_t dma0_fi:1; -+ uint64_t idtime1:1; -+ uint64_t idtime0:1; -+ uint64_t idcnt1:1; -+ uint64_t idcnt0:1; -+ uint64_t reserved_22_24:3; -+ uint64_t iptime0:1; -+ uint64_t reserved_18_20:3; -+ uint64_t ipcnt0:1; -+ uint64_t irsl_int:1; -+ uint64_t ill_rrd:1; -+ uint64_t ill_rwr:1; -+ uint64_t idperr:1; -+ uint64_t iaperr:1; -+ uint64_t iserr:1; -+ uint64_t itsr_abt:1; -+ uint64_t imsc_msg:1; -+ uint64_t imsi_mabt:1; -+ uint64_t imsi_tabt:1; -+ uint64_t imsi_per:1; -+ uint64_t imr_tto:1; -+ uint64_t imr_abt:1; -+ uint64_t itr_abt:1; -+ uint64_t imr_wtto:1; -+ uint64_t imr_wabt:1; -+ uint64_t itr_wabt:1; -+ } cn30xx; -+ struct cvmx_pci_int_enb_cn31xx { -+ uint64_t reserved_34_63:30; -+ uint64_t ill_rd:1; -+ uint64_t ill_wr:1; -+ uint64_t win_wr:1; -+ uint64_t dma1_fi:1; -+ uint64_t dma0_fi:1; -+ uint64_t idtime1:1; -+ uint64_t idtime0:1; -+ uint64_t idcnt1:1; -+ uint64_t idcnt0:1; -+ uint64_t reserved_23_24:2; -+ uint64_t iptime1:1; -+ uint64_t iptime0:1; -+ uint64_t reserved_19_20:2; -+ uint64_t ipcnt1:1; -+ uint64_t ipcnt0:1; -+ uint64_t irsl_int:1; -+ uint64_t ill_rrd:1; -+ uint64_t ill_rwr:1; -+ uint64_t idperr:1; -+ uint64_t iaperr:1; -+ uint64_t iserr:1; -+ uint64_t itsr_abt:1; -+ uint64_t imsc_msg:1; -+ uint64_t imsi_mabt:1; -+ uint64_t imsi_tabt:1; -+ uint64_t imsi_per:1; -+ uint64_t imr_tto:1; -+ uint64_t imr_abt:1; -+ uint64_t itr_abt:1; -+ uint64_t imr_wtto:1; -+ uint64_t imr_wabt:1; -+ uint64_t itr_wabt:1; -+ } cn31xx; -+ struct cvmx_pci_int_enb_s cn38xx; -+ struct cvmx_pci_int_enb_s cn38xxp2; -+ struct cvmx_pci_int_enb_cn31xx cn50xx; -+ struct cvmx_pci_int_enb_s cn58xx; -+ struct cvmx_pci_int_enb_s cn58xxp1; -+}; -+ -+union cvmx_pci_int_enb2 { -+ uint64_t u64; -+ struct cvmx_pci_int_enb2_s { -+ uint64_t reserved_34_63:30; -+ uint64_t ill_rd:1; -+ uint64_t ill_wr:1; -+ uint64_t win_wr:1; -+ uint64_t dma1_fi:1; -+ uint64_t dma0_fi:1; -+ uint64_t rdtime1:1; -+ uint64_t rdtime0:1; -+ uint64_t rdcnt1:1; -+ uint64_t rdcnt0:1; -+ uint64_t rptime3:1; -+ uint64_t rptime2:1; -+ uint64_t rptime1:1; -+ uint64_t rptime0:1; -+ uint64_t rpcnt3:1; -+ uint64_t rpcnt2:1; -+ uint64_t rpcnt1:1; -+ uint64_t rpcnt0:1; -+ uint64_t rrsl_int:1; -+ uint64_t ill_rrd:1; -+ uint64_t ill_rwr:1; -+ uint64_t rdperr:1; -+ uint64_t raperr:1; -+ uint64_t rserr:1; -+ uint64_t rtsr_abt:1; -+ uint64_t rmsc_msg:1; -+ uint64_t rmsi_mabt:1; -+ uint64_t rmsi_tabt:1; -+ uint64_t rmsi_per:1; -+ uint64_t rmr_tto:1; -+ uint64_t rmr_abt:1; -+ uint64_t rtr_abt:1; -+ uint64_t rmr_wtto:1; -+ uint64_t rmr_wabt:1; -+ uint64_t rtr_wabt:1; -+ } s; -+ struct cvmx_pci_int_enb2_cn30xx { -+ uint64_t reserved_34_63:30; -+ uint64_t ill_rd:1; -+ uint64_t ill_wr:1; -+ uint64_t win_wr:1; -+ uint64_t dma1_fi:1; -+ uint64_t dma0_fi:1; -+ uint64_t rdtime1:1; -+ uint64_t rdtime0:1; -+ uint64_t rdcnt1:1; -+ uint64_t rdcnt0:1; -+ uint64_t reserved_22_24:3; -+ uint64_t rptime0:1; -+ uint64_t reserved_18_20:3; -+ uint64_t rpcnt0:1; -+ uint64_t rrsl_int:1; -+ uint64_t ill_rrd:1; -+ uint64_t ill_rwr:1; -+ uint64_t rdperr:1; -+ uint64_t raperr:1; -+ uint64_t rserr:1; -+ uint64_t rtsr_abt:1; -+ uint64_t rmsc_msg:1; -+ uint64_t rmsi_mabt:1; -+ uint64_t rmsi_tabt:1; -+ uint64_t rmsi_per:1; -+ uint64_t rmr_tto:1; -+ uint64_t rmr_abt:1; -+ uint64_t rtr_abt:1; -+ uint64_t rmr_wtto:1; -+ uint64_t rmr_wabt:1; -+ uint64_t rtr_wabt:1; -+ } cn30xx; -+ struct cvmx_pci_int_enb2_cn31xx { -+ uint64_t reserved_34_63:30; -+ uint64_t ill_rd:1; -+ uint64_t ill_wr:1; -+ uint64_t win_wr:1; -+ uint64_t dma1_fi:1; -+ uint64_t dma0_fi:1; -+ uint64_t rdtime1:1; -+ uint64_t rdtime0:1; -+ uint64_t rdcnt1:1; -+ uint64_t rdcnt0:1; -+ uint64_t reserved_23_24:2; -+ uint64_t rptime1:1; -+ uint64_t rptime0:1; -+ uint64_t reserved_19_20:2; -+ uint64_t rpcnt1:1; -+ uint64_t rpcnt0:1; -+ uint64_t rrsl_int:1; -+ uint64_t ill_rrd:1; -+ uint64_t ill_rwr:1; -+ uint64_t rdperr:1; -+ uint64_t raperr:1; -+ uint64_t rserr:1; -+ uint64_t rtsr_abt:1; -+ uint64_t rmsc_msg:1; -+ uint64_t rmsi_mabt:1; -+ uint64_t rmsi_tabt:1; -+ uint64_t rmsi_per:1; -+ uint64_t rmr_tto:1; -+ uint64_t rmr_abt:1; -+ uint64_t rtr_abt:1; -+ uint64_t rmr_wtto:1; -+ uint64_t rmr_wabt:1; -+ uint64_t rtr_wabt:1; -+ } cn31xx; -+ struct cvmx_pci_int_enb2_s cn38xx; -+ struct cvmx_pci_int_enb2_s cn38xxp2; -+ struct cvmx_pci_int_enb2_cn31xx cn50xx; -+ struct cvmx_pci_int_enb2_s cn58xx; -+ struct cvmx_pci_int_enb2_s cn58xxp1; -+}; -+ -+union cvmx_pci_int_sum { -+ uint64_t u64; -+ struct cvmx_pci_int_sum_s { -+ uint64_t reserved_34_63:30; -+ uint64_t ill_rd:1; -+ uint64_t ill_wr:1; -+ uint64_t win_wr:1; -+ uint64_t dma1_fi:1; -+ uint64_t dma0_fi:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t ptime3:1; -+ uint64_t ptime2:1; -+ uint64_t ptime1:1; -+ uint64_t ptime0:1; -+ uint64_t pcnt3:1; -+ uint64_t pcnt2:1; -+ uint64_t pcnt1:1; -+ uint64_t pcnt0:1; -+ uint64_t rsl_int:1; -+ uint64_t ill_rrd:1; -+ uint64_t ill_rwr:1; -+ uint64_t dperr:1; -+ uint64_t aperr:1; -+ uint64_t serr:1; -+ uint64_t tsr_abt:1; -+ uint64_t msc_msg:1; -+ uint64_t msi_mabt:1; -+ uint64_t msi_tabt:1; -+ uint64_t msi_per:1; -+ uint64_t mr_tto:1; -+ uint64_t mr_abt:1; -+ uint64_t tr_abt:1; -+ uint64_t mr_wtto:1; -+ uint64_t mr_wabt:1; -+ uint64_t tr_wabt:1; -+ } s; -+ struct cvmx_pci_int_sum_cn30xx { -+ uint64_t reserved_34_63:30; -+ uint64_t ill_rd:1; -+ uint64_t ill_wr:1; -+ uint64_t win_wr:1; -+ uint64_t dma1_fi:1; -+ uint64_t dma0_fi:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t reserved_22_24:3; -+ uint64_t ptime0:1; -+ uint64_t reserved_18_20:3; -+ uint64_t pcnt0:1; -+ uint64_t rsl_int:1; -+ uint64_t ill_rrd:1; -+ uint64_t ill_rwr:1; -+ uint64_t dperr:1; -+ uint64_t aperr:1; -+ uint64_t serr:1; -+ uint64_t tsr_abt:1; -+ uint64_t msc_msg:1; -+ uint64_t msi_mabt:1; -+ uint64_t msi_tabt:1; -+ uint64_t msi_per:1; -+ uint64_t mr_tto:1; -+ uint64_t mr_abt:1; -+ uint64_t tr_abt:1; -+ uint64_t mr_wtto:1; -+ uint64_t mr_wabt:1; -+ uint64_t tr_wabt:1; -+ } cn30xx; -+ struct cvmx_pci_int_sum_cn31xx { -+ uint64_t reserved_34_63:30; -+ uint64_t ill_rd:1; -+ uint64_t ill_wr:1; -+ uint64_t win_wr:1; -+ uint64_t dma1_fi:1; -+ uint64_t dma0_fi:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t reserved_23_24:2; -+ uint64_t ptime1:1; -+ uint64_t ptime0:1; -+ uint64_t reserved_19_20:2; -+ uint64_t pcnt1:1; -+ uint64_t pcnt0:1; -+ uint64_t rsl_int:1; -+ uint64_t ill_rrd:1; -+ uint64_t ill_rwr:1; -+ uint64_t dperr:1; -+ uint64_t aperr:1; -+ uint64_t serr:1; -+ uint64_t tsr_abt:1; -+ uint64_t msc_msg:1; -+ uint64_t msi_mabt:1; -+ uint64_t msi_tabt:1; -+ uint64_t msi_per:1; -+ uint64_t mr_tto:1; -+ uint64_t mr_abt:1; -+ uint64_t tr_abt:1; -+ uint64_t mr_wtto:1; -+ uint64_t mr_wabt:1; -+ uint64_t tr_wabt:1; -+ } cn31xx; -+ struct cvmx_pci_int_sum_s cn38xx; -+ struct cvmx_pci_int_sum_s cn38xxp2; -+ struct cvmx_pci_int_sum_cn31xx cn50xx; -+ struct cvmx_pci_int_sum_s cn58xx; -+ struct cvmx_pci_int_sum_s cn58xxp1; -+}; -+ -+union cvmx_pci_int_sum2 { -+ uint64_t u64; -+ struct cvmx_pci_int_sum2_s { -+ uint64_t reserved_34_63:30; -+ uint64_t ill_rd:1; -+ uint64_t ill_wr:1; -+ uint64_t win_wr:1; -+ uint64_t dma1_fi:1; -+ uint64_t dma0_fi:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t ptime3:1; -+ uint64_t ptime2:1; -+ uint64_t ptime1:1; -+ uint64_t ptime0:1; -+ uint64_t pcnt3:1; -+ uint64_t pcnt2:1; -+ uint64_t pcnt1:1; -+ uint64_t pcnt0:1; -+ uint64_t rsl_int:1; -+ uint64_t ill_rrd:1; -+ uint64_t ill_rwr:1; -+ uint64_t dperr:1; -+ uint64_t aperr:1; -+ uint64_t serr:1; -+ uint64_t tsr_abt:1; -+ uint64_t msc_msg:1; -+ uint64_t msi_mabt:1; -+ uint64_t msi_tabt:1; -+ uint64_t msi_per:1; -+ uint64_t mr_tto:1; -+ uint64_t mr_abt:1; -+ uint64_t tr_abt:1; -+ uint64_t mr_wtto:1; -+ uint64_t mr_wabt:1; -+ uint64_t tr_wabt:1; -+ } s; -+ struct cvmx_pci_int_sum2_cn30xx { -+ uint64_t reserved_34_63:30; -+ uint64_t ill_rd:1; -+ uint64_t ill_wr:1; -+ uint64_t win_wr:1; -+ uint64_t dma1_fi:1; -+ uint64_t dma0_fi:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t reserved_22_24:3; -+ uint64_t ptime0:1; -+ uint64_t reserved_18_20:3; -+ uint64_t pcnt0:1; -+ uint64_t rsl_int:1; -+ uint64_t ill_rrd:1; -+ uint64_t ill_rwr:1; -+ uint64_t dperr:1; -+ uint64_t aperr:1; -+ uint64_t serr:1; -+ uint64_t tsr_abt:1; -+ uint64_t msc_msg:1; -+ uint64_t msi_mabt:1; -+ uint64_t msi_tabt:1; -+ uint64_t msi_per:1; -+ uint64_t mr_tto:1; -+ uint64_t mr_abt:1; -+ uint64_t tr_abt:1; -+ uint64_t mr_wtto:1; -+ uint64_t mr_wabt:1; -+ uint64_t tr_wabt:1; -+ } cn30xx; -+ struct cvmx_pci_int_sum2_cn31xx { -+ uint64_t reserved_34_63:30; -+ uint64_t ill_rd:1; -+ uint64_t ill_wr:1; -+ uint64_t win_wr:1; -+ uint64_t dma1_fi:1; -+ uint64_t dma0_fi:1; -+ uint64_t dtime1:1; -+ uint64_t dtime0:1; -+ uint64_t dcnt1:1; -+ uint64_t dcnt0:1; -+ uint64_t reserved_23_24:2; -+ uint64_t ptime1:1; -+ uint64_t ptime0:1; -+ uint64_t reserved_19_20:2; -+ uint64_t pcnt1:1; -+ uint64_t pcnt0:1; -+ uint64_t rsl_int:1; -+ uint64_t ill_rrd:1; -+ uint64_t ill_rwr:1; -+ uint64_t dperr:1; -+ uint64_t aperr:1; -+ uint64_t serr:1; -+ uint64_t tsr_abt:1; -+ uint64_t msc_msg:1; -+ uint64_t msi_mabt:1; -+ uint64_t msi_tabt:1; -+ uint64_t msi_per:1; -+ uint64_t mr_tto:1; -+ uint64_t mr_abt:1; -+ uint64_t tr_abt:1; -+ uint64_t mr_wtto:1; -+ uint64_t mr_wabt:1; -+ uint64_t tr_wabt:1; -+ } cn31xx; -+ struct cvmx_pci_int_sum2_s cn38xx; -+ struct cvmx_pci_int_sum2_s cn38xxp2; -+ struct cvmx_pci_int_sum2_cn31xx cn50xx; -+ struct cvmx_pci_int_sum2_s cn58xx; -+ struct cvmx_pci_int_sum2_s cn58xxp1; -+}; -+ -+union cvmx_pci_msi_rcv { -+ uint32_t u32; -+ struct cvmx_pci_msi_rcv_s { -+ uint32_t reserved_6_31:26; -+ uint32_t intr:6; -+ } s; -+ struct cvmx_pci_msi_rcv_s cn30xx; -+ struct cvmx_pci_msi_rcv_s cn31xx; -+ struct cvmx_pci_msi_rcv_s cn38xx; -+ struct cvmx_pci_msi_rcv_s cn38xxp2; -+ struct cvmx_pci_msi_rcv_s cn50xx; -+ struct cvmx_pci_msi_rcv_s cn58xx; -+ struct cvmx_pci_msi_rcv_s cn58xxp1; -+}; -+ -+union cvmx_pci_pkt_creditsx { -+ uint32_t u32; -+ struct cvmx_pci_pkt_creditsx_s { -+ uint32_t pkt_cnt:16; -+ uint32_t ptr_cnt:16; -+ } s; -+ struct cvmx_pci_pkt_creditsx_s cn30xx; -+ struct cvmx_pci_pkt_creditsx_s cn31xx; -+ struct cvmx_pci_pkt_creditsx_s cn38xx; -+ struct cvmx_pci_pkt_creditsx_s cn38xxp2; -+ struct cvmx_pci_pkt_creditsx_s cn50xx; -+ struct cvmx_pci_pkt_creditsx_s cn58xx; -+ struct cvmx_pci_pkt_creditsx_s cn58xxp1; -+}; -+ -+union cvmx_pci_pkts_sentx { -+ uint32_t u32; -+ struct cvmx_pci_pkts_sentx_s { -+ uint32_t pkt_cnt:32; -+ } s; -+ struct cvmx_pci_pkts_sentx_s cn30xx; -+ struct cvmx_pci_pkts_sentx_s cn31xx; -+ struct cvmx_pci_pkts_sentx_s cn38xx; -+ struct cvmx_pci_pkts_sentx_s cn38xxp2; -+ struct cvmx_pci_pkts_sentx_s cn50xx; -+ struct cvmx_pci_pkts_sentx_s cn58xx; -+ struct cvmx_pci_pkts_sentx_s cn58xxp1; -+}; -+ -+union cvmx_pci_pkts_sent_int_levx { -+ uint32_t u32; -+ struct cvmx_pci_pkts_sent_int_levx_s { -+ uint32_t pkt_cnt:32; -+ } s; -+ struct cvmx_pci_pkts_sent_int_levx_s cn30xx; -+ struct cvmx_pci_pkts_sent_int_levx_s cn31xx; -+ struct cvmx_pci_pkts_sent_int_levx_s cn38xx; -+ struct cvmx_pci_pkts_sent_int_levx_s cn38xxp2; -+ struct cvmx_pci_pkts_sent_int_levx_s cn50xx; -+ struct cvmx_pci_pkts_sent_int_levx_s cn58xx; -+ struct cvmx_pci_pkts_sent_int_levx_s cn58xxp1; -+}; -+ -+union cvmx_pci_pkts_sent_timex { -+ uint32_t u32; -+ struct cvmx_pci_pkts_sent_timex_s { -+ uint32_t pkt_time:32; -+ } s; -+ struct cvmx_pci_pkts_sent_timex_s cn30xx; -+ struct cvmx_pci_pkts_sent_timex_s cn31xx; -+ struct cvmx_pci_pkts_sent_timex_s cn38xx; -+ struct cvmx_pci_pkts_sent_timex_s cn38xxp2; -+ struct cvmx_pci_pkts_sent_timex_s cn50xx; -+ struct cvmx_pci_pkts_sent_timex_s cn58xx; -+ struct cvmx_pci_pkts_sent_timex_s cn58xxp1; -+}; -+ -+union cvmx_pci_read_cmd_6 { -+ uint32_t u32; -+ struct cvmx_pci_read_cmd_6_s { -+ uint32_t reserved_9_31:23; -+ uint32_t min_data:6; -+ uint32_t prefetch:3; -+ } s; -+ struct cvmx_pci_read_cmd_6_s cn30xx; -+ struct cvmx_pci_read_cmd_6_s cn31xx; -+ struct cvmx_pci_read_cmd_6_s cn38xx; -+ struct cvmx_pci_read_cmd_6_s cn38xxp2; -+ struct cvmx_pci_read_cmd_6_s cn50xx; -+ struct cvmx_pci_read_cmd_6_s cn58xx; -+ struct cvmx_pci_read_cmd_6_s cn58xxp1; -+}; -+ -+union cvmx_pci_read_cmd_c { -+ uint32_t u32; -+ struct cvmx_pci_read_cmd_c_s { -+ uint32_t reserved_9_31:23; -+ uint32_t min_data:6; -+ uint32_t prefetch:3; -+ } s; -+ struct cvmx_pci_read_cmd_c_s cn30xx; -+ struct cvmx_pci_read_cmd_c_s cn31xx; -+ struct cvmx_pci_read_cmd_c_s cn38xx; -+ struct cvmx_pci_read_cmd_c_s cn38xxp2; -+ struct cvmx_pci_read_cmd_c_s cn50xx; -+ struct cvmx_pci_read_cmd_c_s cn58xx; -+ struct cvmx_pci_read_cmd_c_s cn58xxp1; -+}; -+ -+union cvmx_pci_read_cmd_e { -+ uint32_t u32; -+ struct cvmx_pci_read_cmd_e_s { -+ uint32_t reserved_9_31:23; -+ uint32_t min_data:6; -+ uint32_t prefetch:3; -+ } s; -+ struct cvmx_pci_read_cmd_e_s cn30xx; -+ struct cvmx_pci_read_cmd_e_s cn31xx; -+ struct cvmx_pci_read_cmd_e_s cn38xx; -+ struct cvmx_pci_read_cmd_e_s cn38xxp2; -+ struct cvmx_pci_read_cmd_e_s cn50xx; -+ struct cvmx_pci_read_cmd_e_s cn58xx; -+ struct cvmx_pci_read_cmd_e_s cn58xxp1; -+}; -+ -+union cvmx_pci_read_timeout { -+ uint64_t u64; -+ struct cvmx_pci_read_timeout_s { -+ uint64_t reserved_32_63:32; -+ uint64_t enb:1; -+ uint64_t cnt:31; -+ } s; -+ struct cvmx_pci_read_timeout_s cn30xx; -+ struct cvmx_pci_read_timeout_s cn31xx; -+ struct cvmx_pci_read_timeout_s cn38xx; -+ struct cvmx_pci_read_timeout_s cn38xxp2; -+ struct cvmx_pci_read_timeout_s cn50xx; -+ struct cvmx_pci_read_timeout_s cn58xx; -+ struct cvmx_pci_read_timeout_s cn58xxp1; -+}; -+ -+union cvmx_pci_scm_reg { -+ uint64_t u64; -+ struct cvmx_pci_scm_reg_s { -+ uint64_t reserved_32_63:32; -+ uint64_t scm:32; -+ } s; -+ struct cvmx_pci_scm_reg_s cn30xx; -+ struct cvmx_pci_scm_reg_s cn31xx; -+ struct cvmx_pci_scm_reg_s cn38xx; -+ struct cvmx_pci_scm_reg_s cn38xxp2; -+ struct cvmx_pci_scm_reg_s cn50xx; -+ struct cvmx_pci_scm_reg_s cn58xx; -+ struct cvmx_pci_scm_reg_s cn58xxp1; -+}; -+ -+union cvmx_pci_tsr_reg { -+ uint64_t u64; -+ struct cvmx_pci_tsr_reg_s { -+ uint64_t reserved_36_63:28; -+ uint64_t tsr:36; -+ } s; -+ struct cvmx_pci_tsr_reg_s cn30xx; -+ struct cvmx_pci_tsr_reg_s cn31xx; -+ struct cvmx_pci_tsr_reg_s cn38xx; -+ struct cvmx_pci_tsr_reg_s cn38xxp2; -+ struct cvmx_pci_tsr_reg_s cn50xx; -+ struct cvmx_pci_tsr_reg_s cn58xx; -+ struct cvmx_pci_tsr_reg_s cn58xxp1; -+}; -+ -+union cvmx_pci_win_rd_addr { -+ uint64_t u64; -+ struct cvmx_pci_win_rd_addr_s { -+ uint64_t reserved_49_63:15; -+ uint64_t iobit:1; -+ uint64_t reserved_0_47:48; -+ } s; -+ struct cvmx_pci_win_rd_addr_cn30xx { -+ uint64_t reserved_49_63:15; -+ uint64_t iobit:1; -+ uint64_t rd_addr:46; -+ uint64_t reserved_0_1:2; -+ } cn30xx; -+ struct cvmx_pci_win_rd_addr_cn30xx cn31xx; -+ struct cvmx_pci_win_rd_addr_cn38xx { -+ uint64_t reserved_49_63:15; -+ uint64_t iobit:1; -+ uint64_t rd_addr:45; -+ uint64_t reserved_0_2:3; -+ } cn38xx; -+ struct cvmx_pci_win_rd_addr_cn38xx cn38xxp2; -+ struct cvmx_pci_win_rd_addr_cn30xx cn50xx; -+ struct cvmx_pci_win_rd_addr_cn38xx cn58xx; -+ struct cvmx_pci_win_rd_addr_cn38xx cn58xxp1; -+}; -+ -+union cvmx_pci_win_rd_data { -+ uint64_t u64; -+ struct cvmx_pci_win_rd_data_s { -+ uint64_t rd_data:64; -+ } s; -+ struct cvmx_pci_win_rd_data_s cn30xx; -+ struct cvmx_pci_win_rd_data_s cn31xx; -+ struct cvmx_pci_win_rd_data_s cn38xx; -+ struct cvmx_pci_win_rd_data_s cn38xxp2; -+ struct cvmx_pci_win_rd_data_s cn50xx; -+ struct cvmx_pci_win_rd_data_s cn58xx; -+ struct cvmx_pci_win_rd_data_s cn58xxp1; -+}; -+ -+union cvmx_pci_win_wr_addr { -+ uint64_t u64; -+ struct cvmx_pci_win_wr_addr_s { -+ uint64_t reserved_49_63:15; -+ uint64_t iobit:1; -+ uint64_t wr_addr:45; -+ uint64_t reserved_0_2:3; -+ } s; -+ struct cvmx_pci_win_wr_addr_s cn30xx; -+ struct cvmx_pci_win_wr_addr_s cn31xx; -+ struct cvmx_pci_win_wr_addr_s cn38xx; -+ struct cvmx_pci_win_wr_addr_s cn38xxp2; -+ struct cvmx_pci_win_wr_addr_s cn50xx; -+ struct cvmx_pci_win_wr_addr_s cn58xx; -+ struct cvmx_pci_win_wr_addr_s cn58xxp1; -+}; -+ -+union cvmx_pci_win_wr_data { -+ uint64_t u64; -+ struct cvmx_pci_win_wr_data_s { -+ uint64_t wr_data:64; -+ } s; -+ struct cvmx_pci_win_wr_data_s cn30xx; -+ struct cvmx_pci_win_wr_data_s cn31xx; -+ struct cvmx_pci_win_wr_data_s cn38xx; -+ struct cvmx_pci_win_wr_data_s cn38xxp2; -+ struct cvmx_pci_win_wr_data_s cn50xx; -+ struct cvmx_pci_win_wr_data_s cn58xx; -+ struct cvmx_pci_win_wr_data_s cn58xxp1; -+}; -+ -+union cvmx_pci_win_wr_mask { -+ uint64_t u64; -+ struct cvmx_pci_win_wr_mask_s { -+ uint64_t reserved_8_63:56; -+ uint64_t wr_mask:8; -+ } s; -+ struct cvmx_pci_win_wr_mask_s cn30xx; -+ struct cvmx_pci_win_wr_mask_s cn31xx; -+ struct cvmx_pci_win_wr_mask_s cn38xx; -+ struct cvmx_pci_win_wr_mask_s cn38xxp2; -+ struct cvmx_pci_win_wr_mask_s cn50xx; -+ struct cvmx_pci_win_wr_mask_s cn58xx; -+ struct cvmx_pci_win_wr_mask_s cn58xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h -@@ -0,0 +1,1365 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_PCIEEP_DEFS_H__ -+#define __CVMX_PCIEEP_DEFS_H__ -+ -+#define CVMX_PCIEEP_CFG000 \ -+ (0x0000000000000000ull) -+#define CVMX_PCIEEP_CFG001 \ -+ (0x0000000000000004ull) -+#define CVMX_PCIEEP_CFG002 \ -+ (0x0000000000000008ull) -+#define CVMX_PCIEEP_CFG003 \ -+ (0x000000000000000Cull) -+#define CVMX_PCIEEP_CFG004 \ -+ (0x0000000000000010ull) -+#define CVMX_PCIEEP_CFG004_MASK \ -+ (0x0000000080000010ull) -+#define CVMX_PCIEEP_CFG005 \ -+ (0x0000000000000014ull) -+#define CVMX_PCIEEP_CFG005_MASK \ -+ (0x0000000080000014ull) -+#define CVMX_PCIEEP_CFG006 \ -+ (0x0000000000000018ull) -+#define CVMX_PCIEEP_CFG006_MASK \ -+ (0x0000000080000018ull) -+#define CVMX_PCIEEP_CFG007 \ -+ (0x000000000000001Cull) -+#define CVMX_PCIEEP_CFG007_MASK \ -+ (0x000000008000001Cull) -+#define CVMX_PCIEEP_CFG008 \ -+ (0x0000000000000020ull) -+#define CVMX_PCIEEP_CFG008_MASK \ -+ (0x0000000080000020ull) -+#define CVMX_PCIEEP_CFG009 \ -+ (0x0000000000000024ull) -+#define CVMX_PCIEEP_CFG009_MASK \ -+ (0x0000000080000024ull) -+#define CVMX_PCIEEP_CFG010 \ -+ (0x0000000000000028ull) -+#define CVMX_PCIEEP_CFG011 \ -+ (0x000000000000002Cull) -+#define CVMX_PCIEEP_CFG012 \ -+ (0x0000000000000030ull) -+#define CVMX_PCIEEP_CFG012_MASK \ -+ (0x0000000080000030ull) -+#define CVMX_PCIEEP_CFG013 \ -+ (0x0000000000000034ull) -+#define CVMX_PCIEEP_CFG015 \ -+ (0x000000000000003Cull) -+#define CVMX_PCIEEP_CFG016 \ -+ (0x0000000000000040ull) -+#define CVMX_PCIEEP_CFG017 \ -+ (0x0000000000000044ull) -+#define CVMX_PCIEEP_CFG020 \ -+ (0x0000000000000050ull) -+#define CVMX_PCIEEP_CFG021 \ -+ (0x0000000000000054ull) -+#define CVMX_PCIEEP_CFG022 \ -+ (0x0000000000000058ull) -+#define CVMX_PCIEEP_CFG023 \ -+ (0x000000000000005Cull) -+#define CVMX_PCIEEP_CFG028 \ -+ (0x0000000000000070ull) -+#define CVMX_PCIEEP_CFG029 \ -+ (0x0000000000000074ull) -+#define CVMX_PCIEEP_CFG030 \ -+ (0x0000000000000078ull) -+#define CVMX_PCIEEP_CFG031 \ -+ (0x000000000000007Cull) -+#define CVMX_PCIEEP_CFG032 \ -+ (0x0000000000000080ull) -+#define CVMX_PCIEEP_CFG033 \ -+ (0x0000000000000084ull) -+#define CVMX_PCIEEP_CFG034 \ -+ (0x0000000000000088ull) -+#define CVMX_PCIEEP_CFG037 \ -+ (0x0000000000000094ull) -+#define CVMX_PCIEEP_CFG038 \ -+ (0x0000000000000098ull) -+#define CVMX_PCIEEP_CFG039 \ -+ (0x000000000000009Cull) -+#define CVMX_PCIEEP_CFG040 \ -+ (0x00000000000000A0ull) -+#define CVMX_PCIEEP_CFG041 \ -+ (0x00000000000000A4ull) -+#define CVMX_PCIEEP_CFG042 \ -+ (0x00000000000000A8ull) -+#define CVMX_PCIEEP_CFG064 \ -+ (0x0000000000000100ull) -+#define CVMX_PCIEEP_CFG065 \ -+ (0x0000000000000104ull) -+#define CVMX_PCIEEP_CFG066 \ -+ (0x0000000000000108ull) -+#define CVMX_PCIEEP_CFG067 \ -+ (0x000000000000010Cull) -+#define CVMX_PCIEEP_CFG068 \ -+ (0x0000000000000110ull) -+#define CVMX_PCIEEP_CFG069 \ -+ (0x0000000000000114ull) -+#define CVMX_PCIEEP_CFG070 \ -+ (0x0000000000000118ull) -+#define CVMX_PCIEEP_CFG071 \ -+ (0x000000000000011Cull) -+#define CVMX_PCIEEP_CFG072 \ -+ (0x0000000000000120ull) -+#define CVMX_PCIEEP_CFG073 \ -+ (0x0000000000000124ull) -+#define CVMX_PCIEEP_CFG074 \ -+ (0x0000000000000128ull) -+#define CVMX_PCIEEP_CFG448 \ -+ (0x0000000000000700ull) -+#define CVMX_PCIEEP_CFG449 \ -+ (0x0000000000000704ull) -+#define CVMX_PCIEEP_CFG450 \ -+ (0x0000000000000708ull) -+#define CVMX_PCIEEP_CFG451 \ -+ (0x000000000000070Cull) -+#define CVMX_PCIEEP_CFG452 \ -+ (0x0000000000000710ull) -+#define CVMX_PCIEEP_CFG453 \ -+ (0x0000000000000714ull) -+#define CVMX_PCIEEP_CFG454 \ -+ (0x0000000000000718ull) -+#define CVMX_PCIEEP_CFG455 \ -+ (0x000000000000071Cull) -+#define CVMX_PCIEEP_CFG456 \ -+ (0x0000000000000720ull) -+#define CVMX_PCIEEP_CFG458 \ -+ (0x0000000000000728ull) -+#define CVMX_PCIEEP_CFG459 \ -+ (0x000000000000072Cull) -+#define CVMX_PCIEEP_CFG460 \ -+ (0x0000000000000730ull) -+#define CVMX_PCIEEP_CFG461 \ -+ (0x0000000000000734ull) -+#define CVMX_PCIEEP_CFG462 \ -+ (0x0000000000000738ull) -+#define CVMX_PCIEEP_CFG463 \ -+ (0x000000000000073Cull) -+#define CVMX_PCIEEP_CFG464 \ -+ (0x0000000000000740ull) -+#define CVMX_PCIEEP_CFG465 \ -+ (0x0000000000000744ull) -+#define CVMX_PCIEEP_CFG466 \ -+ (0x0000000000000748ull) -+#define CVMX_PCIEEP_CFG467 \ -+ (0x000000000000074Cull) -+#define CVMX_PCIEEP_CFG468 \ -+ (0x0000000000000750ull) -+#define CVMX_PCIEEP_CFG490 \ -+ (0x00000000000007A8ull) -+#define CVMX_PCIEEP_CFG491 \ -+ (0x00000000000007ACull) -+#define CVMX_PCIEEP_CFG492 \ -+ (0x00000000000007B0ull) -+#define CVMX_PCIEEP_CFG516 \ -+ (0x0000000000000810ull) -+#define CVMX_PCIEEP_CFG517 \ -+ (0x0000000000000814ull) -+ -+union cvmx_pcieep_cfg000 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg000_s { -+ uint32_t devid:16; -+ uint32_t vendid:16; -+ } s; -+ struct cvmx_pcieep_cfg000_s cn52xx; -+ struct cvmx_pcieep_cfg000_s cn52xxp1; -+ struct cvmx_pcieep_cfg000_s cn56xx; -+ struct cvmx_pcieep_cfg000_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg001 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg001_s { -+ uint32_t dpe:1; -+ uint32_t sse:1; -+ uint32_t rma:1; -+ uint32_t rta:1; -+ uint32_t sta:1; -+ uint32_t devt:2; -+ uint32_t mdpe:1; -+ uint32_t fbb:1; -+ uint32_t reserved_22_22:1; -+ uint32_t m66:1; -+ uint32_t cl:1; -+ uint32_t i_stat:1; -+ uint32_t reserved_11_18:8; -+ uint32_t i_dis:1; -+ uint32_t fbbe:1; -+ uint32_t see:1; -+ uint32_t ids_wcc:1; -+ uint32_t per:1; -+ uint32_t vps:1; -+ uint32_t mwice:1; -+ uint32_t scse:1; -+ uint32_t me:1; -+ uint32_t msae:1; -+ uint32_t isae:1; -+ } s; -+ struct cvmx_pcieep_cfg001_s cn52xx; -+ struct cvmx_pcieep_cfg001_s cn52xxp1; -+ struct cvmx_pcieep_cfg001_s cn56xx; -+ struct cvmx_pcieep_cfg001_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg002 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg002_s { -+ uint32_t bcc:8; -+ uint32_t sc:8; -+ uint32_t pi:8; -+ uint32_t rid:8; -+ } s; -+ struct cvmx_pcieep_cfg002_s cn52xx; -+ struct cvmx_pcieep_cfg002_s cn52xxp1; -+ struct cvmx_pcieep_cfg002_s cn56xx; -+ struct cvmx_pcieep_cfg002_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg003 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg003_s { -+ uint32_t bist:8; -+ uint32_t mfd:1; -+ uint32_t chf:7; -+ uint32_t lt:8; -+ uint32_t cls:8; -+ } s; -+ struct cvmx_pcieep_cfg003_s cn52xx; -+ struct cvmx_pcieep_cfg003_s cn52xxp1; -+ struct cvmx_pcieep_cfg003_s cn56xx; -+ struct cvmx_pcieep_cfg003_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg004 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg004_s { -+ uint32_t lbab:18; -+ uint32_t reserved_4_13:10; -+ uint32_t pf:1; -+ uint32_t typ:2; -+ uint32_t mspc:1; -+ } s; -+ struct cvmx_pcieep_cfg004_s cn52xx; -+ struct cvmx_pcieep_cfg004_s cn52xxp1; -+ struct cvmx_pcieep_cfg004_s cn56xx; -+ struct cvmx_pcieep_cfg004_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg004_mask { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg004_mask_s { -+ uint32_t lmask:31; -+ uint32_t enb:1; -+ } s; -+ struct cvmx_pcieep_cfg004_mask_s cn52xx; -+ struct cvmx_pcieep_cfg004_mask_s cn52xxp1; -+ struct cvmx_pcieep_cfg004_mask_s cn56xx; -+ struct cvmx_pcieep_cfg004_mask_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg005 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg005_s { -+ uint32_t ubab:32; -+ } s; -+ struct cvmx_pcieep_cfg005_s cn52xx; -+ struct cvmx_pcieep_cfg005_s cn52xxp1; -+ struct cvmx_pcieep_cfg005_s cn56xx; -+ struct cvmx_pcieep_cfg005_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg005_mask { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg005_mask_s { -+ uint32_t umask:32; -+ } s; -+ struct cvmx_pcieep_cfg005_mask_s cn52xx; -+ struct cvmx_pcieep_cfg005_mask_s cn52xxp1; -+ struct cvmx_pcieep_cfg005_mask_s cn56xx; -+ struct cvmx_pcieep_cfg005_mask_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg006 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg006_s { -+ uint32_t lbab:6; -+ uint32_t reserved_4_25:22; -+ uint32_t pf:1; -+ uint32_t typ:2; -+ uint32_t mspc:1; -+ } s; -+ struct cvmx_pcieep_cfg006_s cn52xx; -+ struct cvmx_pcieep_cfg006_s cn52xxp1; -+ struct cvmx_pcieep_cfg006_s cn56xx; -+ struct cvmx_pcieep_cfg006_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg006_mask { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg006_mask_s { -+ uint32_t lmask:31; -+ uint32_t enb:1; -+ } s; -+ struct cvmx_pcieep_cfg006_mask_s cn52xx; -+ struct cvmx_pcieep_cfg006_mask_s cn52xxp1; -+ struct cvmx_pcieep_cfg006_mask_s cn56xx; -+ struct cvmx_pcieep_cfg006_mask_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg007 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg007_s { -+ uint32_t ubab:32; -+ } s; -+ struct cvmx_pcieep_cfg007_s cn52xx; -+ struct cvmx_pcieep_cfg007_s cn52xxp1; -+ struct cvmx_pcieep_cfg007_s cn56xx; -+ struct cvmx_pcieep_cfg007_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg007_mask { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg007_mask_s { -+ uint32_t umask:32; -+ } s; -+ struct cvmx_pcieep_cfg007_mask_s cn52xx; -+ struct cvmx_pcieep_cfg007_mask_s cn52xxp1; -+ struct cvmx_pcieep_cfg007_mask_s cn56xx; -+ struct cvmx_pcieep_cfg007_mask_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg008 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg008_s { -+ uint32_t reserved_4_31:28; -+ uint32_t pf:1; -+ uint32_t typ:2; -+ uint32_t mspc:1; -+ } s; -+ struct cvmx_pcieep_cfg008_s cn52xx; -+ struct cvmx_pcieep_cfg008_s cn52xxp1; -+ struct cvmx_pcieep_cfg008_s cn56xx; -+ struct cvmx_pcieep_cfg008_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg008_mask { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg008_mask_s { -+ uint32_t lmask:31; -+ uint32_t enb:1; -+ } s; -+ struct cvmx_pcieep_cfg008_mask_s cn52xx; -+ struct cvmx_pcieep_cfg008_mask_s cn52xxp1; -+ struct cvmx_pcieep_cfg008_mask_s cn56xx; -+ struct cvmx_pcieep_cfg008_mask_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg009 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg009_s { -+ uint32_t ubab:25; -+ uint32_t reserved_0_6:7; -+ } s; -+ struct cvmx_pcieep_cfg009_s cn52xx; -+ struct cvmx_pcieep_cfg009_s cn52xxp1; -+ struct cvmx_pcieep_cfg009_s cn56xx; -+ struct cvmx_pcieep_cfg009_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg009_mask { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg009_mask_s { -+ uint32_t umask:32; -+ } s; -+ struct cvmx_pcieep_cfg009_mask_s cn52xx; -+ struct cvmx_pcieep_cfg009_mask_s cn52xxp1; -+ struct cvmx_pcieep_cfg009_mask_s cn56xx; -+ struct cvmx_pcieep_cfg009_mask_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg010 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg010_s { -+ uint32_t cisp:32; -+ } s; -+ struct cvmx_pcieep_cfg010_s cn52xx; -+ struct cvmx_pcieep_cfg010_s cn52xxp1; -+ struct cvmx_pcieep_cfg010_s cn56xx; -+ struct cvmx_pcieep_cfg010_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg011 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg011_s { -+ uint32_t ssid:16; -+ uint32_t ssvid:16; -+ } s; -+ struct cvmx_pcieep_cfg011_s cn52xx; -+ struct cvmx_pcieep_cfg011_s cn52xxp1; -+ struct cvmx_pcieep_cfg011_s cn56xx; -+ struct cvmx_pcieep_cfg011_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg012 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg012_s { -+ uint32_t eraddr:16; -+ uint32_t reserved_1_15:15; -+ uint32_t er_en:1; -+ } s; -+ struct cvmx_pcieep_cfg012_s cn52xx; -+ struct cvmx_pcieep_cfg012_s cn52xxp1; -+ struct cvmx_pcieep_cfg012_s cn56xx; -+ struct cvmx_pcieep_cfg012_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg012_mask { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg012_mask_s { -+ uint32_t mask:31; -+ uint32_t enb:1; -+ } s; -+ struct cvmx_pcieep_cfg012_mask_s cn52xx; -+ struct cvmx_pcieep_cfg012_mask_s cn52xxp1; -+ struct cvmx_pcieep_cfg012_mask_s cn56xx; -+ struct cvmx_pcieep_cfg012_mask_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg013 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg013_s { -+ uint32_t reserved_8_31:24; -+ uint32_t cp:8; -+ } s; -+ struct cvmx_pcieep_cfg013_s cn52xx; -+ struct cvmx_pcieep_cfg013_s cn52xxp1; -+ struct cvmx_pcieep_cfg013_s cn56xx; -+ struct cvmx_pcieep_cfg013_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg015 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg015_s { -+ uint32_t ml:8; -+ uint32_t mg:8; -+ uint32_t inta:8; -+ uint32_t il:8; -+ } s; -+ struct cvmx_pcieep_cfg015_s cn52xx; -+ struct cvmx_pcieep_cfg015_s cn52xxp1; -+ struct cvmx_pcieep_cfg015_s cn56xx; -+ struct cvmx_pcieep_cfg015_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg016 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg016_s { -+ uint32_t pmes:5; -+ uint32_t d2s:1; -+ uint32_t d1s:1; -+ uint32_t auxc:3; -+ uint32_t dsi:1; -+ uint32_t reserved_20_20:1; -+ uint32_t pme_clock:1; -+ uint32_t pmsv:3; -+ uint32_t ncp:8; -+ uint32_t pmcid:8; -+ } s; -+ struct cvmx_pcieep_cfg016_s cn52xx; -+ struct cvmx_pcieep_cfg016_s cn52xxp1; -+ struct cvmx_pcieep_cfg016_s cn56xx; -+ struct cvmx_pcieep_cfg016_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg017 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg017_s { -+ uint32_t pmdia:8; -+ uint32_t bpccee:1; -+ uint32_t bd3h:1; -+ uint32_t reserved_16_21:6; -+ uint32_t pmess:1; -+ uint32_t pmedsia:2; -+ uint32_t pmds:4; -+ uint32_t pmeens:1; -+ uint32_t reserved_4_7:4; -+ uint32_t nsr:1; -+ uint32_t reserved_2_2:1; -+ uint32_t ps:2; -+ } s; -+ struct cvmx_pcieep_cfg017_s cn52xx; -+ struct cvmx_pcieep_cfg017_s cn52xxp1; -+ struct cvmx_pcieep_cfg017_s cn56xx; -+ struct cvmx_pcieep_cfg017_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg020 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg020_s { -+ uint32_t reserved_24_31:8; -+ uint32_t m64:1; -+ uint32_t mme:3; -+ uint32_t mmc:3; -+ uint32_t msien:1; -+ uint32_t ncp:8; -+ uint32_t msicid:8; -+ } s; -+ struct cvmx_pcieep_cfg020_s cn52xx; -+ struct cvmx_pcieep_cfg020_s cn52xxp1; -+ struct cvmx_pcieep_cfg020_s cn56xx; -+ struct cvmx_pcieep_cfg020_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg021 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg021_s { -+ uint32_t lmsi:30; -+ uint32_t reserved_0_1:2; -+ } s; -+ struct cvmx_pcieep_cfg021_s cn52xx; -+ struct cvmx_pcieep_cfg021_s cn52xxp1; -+ struct cvmx_pcieep_cfg021_s cn56xx; -+ struct cvmx_pcieep_cfg021_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg022 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg022_s { -+ uint32_t umsi:32; -+ } s; -+ struct cvmx_pcieep_cfg022_s cn52xx; -+ struct cvmx_pcieep_cfg022_s cn52xxp1; -+ struct cvmx_pcieep_cfg022_s cn56xx; -+ struct cvmx_pcieep_cfg022_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg023 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg023_s { -+ uint32_t reserved_16_31:16; -+ uint32_t msimd:16; -+ } s; -+ struct cvmx_pcieep_cfg023_s cn52xx; -+ struct cvmx_pcieep_cfg023_s cn52xxp1; -+ struct cvmx_pcieep_cfg023_s cn56xx; -+ struct cvmx_pcieep_cfg023_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg028 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg028_s { -+ uint32_t reserved_30_31:2; -+ uint32_t imn:5; -+ uint32_t si:1; -+ uint32_t dpt:4; -+ uint32_t pciecv:4; -+ uint32_t ncp:8; -+ uint32_t pcieid:8; -+ } s; -+ struct cvmx_pcieep_cfg028_s cn52xx; -+ struct cvmx_pcieep_cfg028_s cn52xxp1; -+ struct cvmx_pcieep_cfg028_s cn56xx; -+ struct cvmx_pcieep_cfg028_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg029 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg029_s { -+ uint32_t reserved_28_31:4; -+ uint32_t cspls:2; -+ uint32_t csplv:8; -+ uint32_t reserved_16_17:2; -+ uint32_t rber:1; -+ uint32_t reserved_12_14:3; -+ uint32_t el1al:3; -+ uint32_t el0al:3; -+ uint32_t etfs:1; -+ uint32_t pfs:2; -+ uint32_t mpss:3; -+ } s; -+ struct cvmx_pcieep_cfg029_s cn52xx; -+ struct cvmx_pcieep_cfg029_s cn52xxp1; -+ struct cvmx_pcieep_cfg029_s cn56xx; -+ struct cvmx_pcieep_cfg029_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg030 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg030_s { -+ uint32_t reserved_22_31:10; -+ uint32_t tp:1; -+ uint32_t ap_d:1; -+ uint32_t ur_d:1; -+ uint32_t fe_d:1; -+ uint32_t nfe_d:1; -+ uint32_t ce_d:1; -+ uint32_t reserved_15_15:1; -+ uint32_t mrrs:3; -+ uint32_t ns_en:1; -+ uint32_t ap_en:1; -+ uint32_t pf_en:1; -+ uint32_t etf_en:1; -+ uint32_t mps:3; -+ uint32_t ro_en:1; -+ uint32_t ur_en:1; -+ uint32_t fe_en:1; -+ uint32_t nfe_en:1; -+ uint32_t ce_en:1; -+ } s; -+ struct cvmx_pcieep_cfg030_s cn52xx; -+ struct cvmx_pcieep_cfg030_s cn52xxp1; -+ struct cvmx_pcieep_cfg030_s cn56xx; -+ struct cvmx_pcieep_cfg030_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg031 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg031_s { -+ uint32_t pnum:8; -+ uint32_t reserved_22_23:2; -+ uint32_t lbnc:1; -+ uint32_t dllarc:1; -+ uint32_t sderc:1; -+ uint32_t cpm:1; -+ uint32_t l1el:3; -+ uint32_t l0el:3; -+ uint32_t aslpms:2; -+ uint32_t mlw:6; -+ uint32_t mls:4; -+ } s; -+ struct cvmx_pcieep_cfg031_s cn52xx; -+ struct cvmx_pcieep_cfg031_s cn52xxp1; -+ struct cvmx_pcieep_cfg031_s cn56xx; -+ struct cvmx_pcieep_cfg031_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg032 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg032_s { -+ uint32_t reserved_30_31:2; -+ uint32_t dlla:1; -+ uint32_t scc:1; -+ uint32_t lt:1; -+ uint32_t reserved_26_26:1; -+ uint32_t nlw:6; -+ uint32_t ls:4; -+ uint32_t reserved_10_15:6; -+ uint32_t hawd:1; -+ uint32_t ecpm:1; -+ uint32_t es:1; -+ uint32_t ccc:1; -+ uint32_t rl:1; -+ uint32_t ld:1; -+ uint32_t rcb:1; -+ uint32_t reserved_2_2:1; -+ uint32_t aslpc:2; -+ } s; -+ struct cvmx_pcieep_cfg032_s cn52xx; -+ struct cvmx_pcieep_cfg032_s cn52xxp1; -+ struct cvmx_pcieep_cfg032_s cn56xx; -+ struct cvmx_pcieep_cfg032_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg033 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg033_s { -+ uint32_t ps_num:13; -+ uint32_t nccs:1; -+ uint32_t emip:1; -+ uint32_t sp_ls:2; -+ uint32_t sp_lv:8; -+ uint32_t hp_c:1; -+ uint32_t hp_s:1; -+ uint32_t pip:1; -+ uint32_t aip:1; -+ uint32_t mrlsp:1; -+ uint32_t pcp:1; -+ uint32_t abp:1; -+ } s; -+ struct cvmx_pcieep_cfg033_s cn52xx; -+ struct cvmx_pcieep_cfg033_s cn52xxp1; -+ struct cvmx_pcieep_cfg033_s cn56xx; -+ struct cvmx_pcieep_cfg033_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg034 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg034_s { -+ uint32_t reserved_25_31:7; -+ uint32_t dlls_c:1; -+ uint32_t emis:1; -+ uint32_t pds:1; -+ uint32_t mrlss:1; -+ uint32_t ccint_d:1; -+ uint32_t pd_c:1; -+ uint32_t mrls_c:1; -+ uint32_t pf_d:1; -+ uint32_t abp_d:1; -+ uint32_t reserved_13_15:3; -+ uint32_t dlls_en:1; -+ uint32_t emic:1; -+ uint32_t pcc:1; -+ uint32_t pic:2; -+ uint32_t aic:2; -+ uint32_t hpint_en:1; -+ uint32_t ccint_en:1; -+ uint32_t pd_en:1; -+ uint32_t mrls_en:1; -+ uint32_t pf_en:1; -+ uint32_t abp_en:1; -+ } s; -+ struct cvmx_pcieep_cfg034_s cn52xx; -+ struct cvmx_pcieep_cfg034_s cn52xxp1; -+ struct cvmx_pcieep_cfg034_s cn56xx; -+ struct cvmx_pcieep_cfg034_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg037 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg037_s { -+ uint32_t reserved_5_31:27; -+ uint32_t ctds:1; -+ uint32_t ctrs:4; -+ } s; -+ struct cvmx_pcieep_cfg037_s cn52xx; -+ struct cvmx_pcieep_cfg037_s cn52xxp1; -+ struct cvmx_pcieep_cfg037_s cn56xx; -+ struct cvmx_pcieep_cfg037_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg038 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg038_s { -+ uint32_t reserved_5_31:27; -+ uint32_t ctd:1; -+ uint32_t ctv:4; -+ } s; -+ struct cvmx_pcieep_cfg038_s cn52xx; -+ struct cvmx_pcieep_cfg038_s cn52xxp1; -+ struct cvmx_pcieep_cfg038_s cn56xx; -+ struct cvmx_pcieep_cfg038_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg039 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg039_s { -+ uint32_t reserved_0_31:32; -+ } s; -+ struct cvmx_pcieep_cfg039_s cn52xx; -+ struct cvmx_pcieep_cfg039_s cn52xxp1; -+ struct cvmx_pcieep_cfg039_s cn56xx; -+ struct cvmx_pcieep_cfg039_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg040 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg040_s { -+ uint32_t reserved_0_31:32; -+ } s; -+ struct cvmx_pcieep_cfg040_s cn52xx; -+ struct cvmx_pcieep_cfg040_s cn52xxp1; -+ struct cvmx_pcieep_cfg040_s cn56xx; -+ struct cvmx_pcieep_cfg040_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg041 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg041_s { -+ uint32_t reserved_0_31:32; -+ } s; -+ struct cvmx_pcieep_cfg041_s cn52xx; -+ struct cvmx_pcieep_cfg041_s cn52xxp1; -+ struct cvmx_pcieep_cfg041_s cn56xx; -+ struct cvmx_pcieep_cfg041_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg042 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg042_s { -+ uint32_t reserved_0_31:32; -+ } s; -+ struct cvmx_pcieep_cfg042_s cn52xx; -+ struct cvmx_pcieep_cfg042_s cn52xxp1; -+ struct cvmx_pcieep_cfg042_s cn56xx; -+ struct cvmx_pcieep_cfg042_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg064 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg064_s { -+ uint32_t nco:12; -+ uint32_t cv:4; -+ uint32_t pcieec:16; -+ } s; -+ struct cvmx_pcieep_cfg064_s cn52xx; -+ struct cvmx_pcieep_cfg064_s cn52xxp1; -+ struct cvmx_pcieep_cfg064_s cn56xx; -+ struct cvmx_pcieep_cfg064_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg065 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg065_s { -+ uint32_t reserved_21_31:11; -+ uint32_t ures:1; -+ uint32_t ecrces:1; -+ uint32_t mtlps:1; -+ uint32_t ros:1; -+ uint32_t ucs:1; -+ uint32_t cas:1; -+ uint32_t cts:1; -+ uint32_t fcpes:1; -+ uint32_t ptlps:1; -+ uint32_t reserved_6_11:6; -+ uint32_t sdes:1; -+ uint32_t dlpes:1; -+ uint32_t reserved_0_3:4; -+ } s; -+ struct cvmx_pcieep_cfg065_s cn52xx; -+ struct cvmx_pcieep_cfg065_s cn52xxp1; -+ struct cvmx_pcieep_cfg065_s cn56xx; -+ struct cvmx_pcieep_cfg065_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg066 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg066_s { -+ uint32_t reserved_21_31:11; -+ uint32_t urem:1; -+ uint32_t ecrcem:1; -+ uint32_t mtlpm:1; -+ uint32_t rom:1; -+ uint32_t ucm:1; -+ uint32_t cam:1; -+ uint32_t ctm:1; -+ uint32_t fcpem:1; -+ uint32_t ptlpm:1; -+ uint32_t reserved_6_11:6; -+ uint32_t sdem:1; -+ uint32_t dlpem:1; -+ uint32_t reserved_0_3:4; -+ } s; -+ struct cvmx_pcieep_cfg066_s cn52xx; -+ struct cvmx_pcieep_cfg066_s cn52xxp1; -+ struct cvmx_pcieep_cfg066_s cn56xx; -+ struct cvmx_pcieep_cfg066_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg067 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg067_s { -+ uint32_t reserved_21_31:11; -+ uint32_t ures:1; -+ uint32_t ecrces:1; -+ uint32_t mtlps:1; -+ uint32_t ros:1; -+ uint32_t ucs:1; -+ uint32_t cas:1; -+ uint32_t cts:1; -+ uint32_t fcpes:1; -+ uint32_t ptlps:1; -+ uint32_t reserved_6_11:6; -+ uint32_t sdes:1; -+ uint32_t dlpes:1; -+ uint32_t reserved_0_3:4; -+ } s; -+ struct cvmx_pcieep_cfg067_s cn52xx; -+ struct cvmx_pcieep_cfg067_s cn52xxp1; -+ struct cvmx_pcieep_cfg067_s cn56xx; -+ struct cvmx_pcieep_cfg067_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg068 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg068_s { -+ uint32_t reserved_14_31:18; -+ uint32_t anfes:1; -+ uint32_t rtts:1; -+ uint32_t reserved_9_11:3; -+ uint32_t rnrs:1; -+ uint32_t bdllps:1; -+ uint32_t btlps:1; -+ uint32_t reserved_1_5:5; -+ uint32_t res:1; -+ } s; -+ struct cvmx_pcieep_cfg068_s cn52xx; -+ struct cvmx_pcieep_cfg068_s cn52xxp1; -+ struct cvmx_pcieep_cfg068_s cn56xx; -+ struct cvmx_pcieep_cfg068_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg069 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg069_s { -+ uint32_t reserved_14_31:18; -+ uint32_t anfem:1; -+ uint32_t rttm:1; -+ uint32_t reserved_9_11:3; -+ uint32_t rnrm:1; -+ uint32_t bdllpm:1; -+ uint32_t btlpm:1; -+ uint32_t reserved_1_5:5; -+ uint32_t rem:1; -+ } s; -+ struct cvmx_pcieep_cfg069_s cn52xx; -+ struct cvmx_pcieep_cfg069_s cn52xxp1; -+ struct cvmx_pcieep_cfg069_s cn56xx; -+ struct cvmx_pcieep_cfg069_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg070 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg070_s { -+ uint32_t reserved_9_31:23; -+ uint32_t ce:1; -+ uint32_t cc:1; -+ uint32_t ge:1; -+ uint32_t gc:1; -+ uint32_t fep:5; -+ } s; -+ struct cvmx_pcieep_cfg070_s cn52xx; -+ struct cvmx_pcieep_cfg070_s cn52xxp1; -+ struct cvmx_pcieep_cfg070_s cn56xx; -+ struct cvmx_pcieep_cfg070_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg071 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg071_s { -+ uint32_t dword1:32; -+ } s; -+ struct cvmx_pcieep_cfg071_s cn52xx; -+ struct cvmx_pcieep_cfg071_s cn52xxp1; -+ struct cvmx_pcieep_cfg071_s cn56xx; -+ struct cvmx_pcieep_cfg071_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg072 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg072_s { -+ uint32_t dword2:32; -+ } s; -+ struct cvmx_pcieep_cfg072_s cn52xx; -+ struct cvmx_pcieep_cfg072_s cn52xxp1; -+ struct cvmx_pcieep_cfg072_s cn56xx; -+ struct cvmx_pcieep_cfg072_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg073 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg073_s { -+ uint32_t dword3:32; -+ } s; -+ struct cvmx_pcieep_cfg073_s cn52xx; -+ struct cvmx_pcieep_cfg073_s cn52xxp1; -+ struct cvmx_pcieep_cfg073_s cn56xx; -+ struct cvmx_pcieep_cfg073_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg074 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg074_s { -+ uint32_t dword4:32; -+ } s; -+ struct cvmx_pcieep_cfg074_s cn52xx; -+ struct cvmx_pcieep_cfg074_s cn52xxp1; -+ struct cvmx_pcieep_cfg074_s cn56xx; -+ struct cvmx_pcieep_cfg074_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg448 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg448_s { -+ uint32_t rtl:16; -+ uint32_t rtltl:16; -+ } s; -+ struct cvmx_pcieep_cfg448_s cn52xx; -+ struct cvmx_pcieep_cfg448_s cn52xxp1; -+ struct cvmx_pcieep_cfg448_s cn56xx; -+ struct cvmx_pcieep_cfg448_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg449 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg449_s { -+ uint32_t omr:32; -+ } s; -+ struct cvmx_pcieep_cfg449_s cn52xx; -+ struct cvmx_pcieep_cfg449_s cn52xxp1; -+ struct cvmx_pcieep_cfg449_s cn56xx; -+ struct cvmx_pcieep_cfg449_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg450 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg450_s { -+ uint32_t lpec:8; -+ uint32_t reserved_22_23:2; -+ uint32_t link_state:6; -+ uint32_t force_link:1; -+ uint32_t reserved_8_14:7; -+ uint32_t link_num:8; -+ } s; -+ struct cvmx_pcieep_cfg450_s cn52xx; -+ struct cvmx_pcieep_cfg450_s cn52xxp1; -+ struct cvmx_pcieep_cfg450_s cn56xx; -+ struct cvmx_pcieep_cfg450_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg451 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg451_s { -+ uint32_t reserved_30_31:2; -+ uint32_t l1el:3; -+ uint32_t l0el:3; -+ uint32_t n_fts_cc:8; -+ uint32_t n_fts:8; -+ uint32_t ack_freq:8; -+ } s; -+ struct cvmx_pcieep_cfg451_s cn52xx; -+ struct cvmx_pcieep_cfg451_s cn52xxp1; -+ struct cvmx_pcieep_cfg451_s cn56xx; -+ struct cvmx_pcieep_cfg451_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg452 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg452_s { -+ uint32_t reserved_26_31:6; -+ uint32_t eccrc:1; -+ uint32_t reserved_22_24:3; -+ uint32_t lme:6; -+ uint32_t reserved_8_15:8; -+ uint32_t flm:1; -+ uint32_t reserved_6_6:1; -+ uint32_t dllle:1; -+ uint32_t reserved_4_4:1; -+ uint32_t ra:1; -+ uint32_t le:1; -+ uint32_t sd:1; -+ uint32_t omr:1; -+ } s; -+ struct cvmx_pcieep_cfg452_s cn52xx; -+ struct cvmx_pcieep_cfg452_s cn52xxp1; -+ struct cvmx_pcieep_cfg452_s cn56xx; -+ struct cvmx_pcieep_cfg452_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg453 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg453_s { -+ uint32_t dlld:1; -+ uint32_t reserved_26_30:5; -+ uint32_t ack_nak:1; -+ uint32_t fcd:1; -+ uint32_t ilst:24; -+ } s; -+ struct cvmx_pcieep_cfg453_s cn52xx; -+ struct cvmx_pcieep_cfg453_s cn52xxp1; -+ struct cvmx_pcieep_cfg453_s cn56xx; -+ struct cvmx_pcieep_cfg453_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg454 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg454_s { -+ uint32_t reserved_29_31:3; -+ uint32_t tmfcwt:5; -+ uint32_t tmanlt:5; -+ uint32_t tmrt:5; -+ uint32_t reserved_11_13:3; -+ uint32_t nskps:3; -+ uint32_t reserved_4_7:4; -+ uint32_t ntss:4; -+ } s; -+ struct cvmx_pcieep_cfg454_s cn52xx; -+ struct cvmx_pcieep_cfg454_s cn52xxp1; -+ struct cvmx_pcieep_cfg454_s cn56xx; -+ struct cvmx_pcieep_cfg454_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg455 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg455_s { -+ uint32_t m_cfg0_filt:1; -+ uint32_t m_io_filt:1; -+ uint32_t msg_ctrl:1; -+ uint32_t m_cpl_ecrc_filt:1; -+ uint32_t m_ecrc_filt:1; -+ uint32_t m_cpl_len_err:1; -+ uint32_t m_cpl_attr_err:1; -+ uint32_t m_cpl_tc_err:1; -+ uint32_t m_cpl_fun_err:1; -+ uint32_t m_cpl_rid_err:1; -+ uint32_t m_cpl_tag_err:1; -+ uint32_t m_lk_filt:1; -+ uint32_t m_cfg1_filt:1; -+ uint32_t m_bar_match:1; -+ uint32_t m_pois_filt:1; -+ uint32_t m_fun:1; -+ uint32_t dfcwt:1; -+ uint32_t reserved_11_14:4; -+ uint32_t skpiv:11; -+ } s; -+ struct cvmx_pcieep_cfg455_s cn52xx; -+ struct cvmx_pcieep_cfg455_s cn52xxp1; -+ struct cvmx_pcieep_cfg455_s cn56xx; -+ struct cvmx_pcieep_cfg455_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg456 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg456_s { -+ uint32_t reserved_2_31:30; -+ uint32_t m_vend1_drp:1; -+ uint32_t m_vend0_drp:1; -+ } s; -+ struct cvmx_pcieep_cfg456_s cn52xx; -+ struct cvmx_pcieep_cfg456_s cn52xxp1; -+ struct cvmx_pcieep_cfg456_s cn56xx; -+ struct cvmx_pcieep_cfg456_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg458 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg458_s { -+ uint32_t dbg_info_l32:32; -+ } s; -+ struct cvmx_pcieep_cfg458_s cn52xx; -+ struct cvmx_pcieep_cfg458_s cn52xxp1; -+ struct cvmx_pcieep_cfg458_s cn56xx; -+ struct cvmx_pcieep_cfg458_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg459 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg459_s { -+ uint32_t dbg_info_u32:32; -+ } s; -+ struct cvmx_pcieep_cfg459_s cn52xx; -+ struct cvmx_pcieep_cfg459_s cn52xxp1; -+ struct cvmx_pcieep_cfg459_s cn56xx; -+ struct cvmx_pcieep_cfg459_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg460 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg460_s { -+ uint32_t reserved_20_31:12; -+ uint32_t tphfcc:8; -+ uint32_t tpdfcc:12; -+ } s; -+ struct cvmx_pcieep_cfg460_s cn52xx; -+ struct cvmx_pcieep_cfg460_s cn52xxp1; -+ struct cvmx_pcieep_cfg460_s cn56xx; -+ struct cvmx_pcieep_cfg460_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg461 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg461_s { -+ uint32_t reserved_20_31:12; -+ uint32_t tchfcc:8; -+ uint32_t tcdfcc:12; -+ } s; -+ struct cvmx_pcieep_cfg461_s cn52xx; -+ struct cvmx_pcieep_cfg461_s cn52xxp1; -+ struct cvmx_pcieep_cfg461_s cn56xx; -+ struct cvmx_pcieep_cfg461_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg462 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg462_s { -+ uint32_t reserved_20_31:12; -+ uint32_t tchfcc:8; -+ uint32_t tcdfcc:12; -+ } s; -+ struct cvmx_pcieep_cfg462_s cn52xx; -+ struct cvmx_pcieep_cfg462_s cn52xxp1; -+ struct cvmx_pcieep_cfg462_s cn56xx; -+ struct cvmx_pcieep_cfg462_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg463 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg463_s { -+ uint32_t reserved_3_31:29; -+ uint32_t rqne:1; -+ uint32_t trbne:1; -+ uint32_t rtlpfccnr:1; -+ } s; -+ struct cvmx_pcieep_cfg463_s cn52xx; -+ struct cvmx_pcieep_cfg463_s cn52xxp1; -+ struct cvmx_pcieep_cfg463_s cn56xx; -+ struct cvmx_pcieep_cfg463_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg464 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg464_s { -+ uint32_t wrr_vc3:8; -+ uint32_t wrr_vc2:8; -+ uint32_t wrr_vc1:8; -+ uint32_t wrr_vc0:8; -+ } s; -+ struct cvmx_pcieep_cfg464_s cn52xx; -+ struct cvmx_pcieep_cfg464_s cn52xxp1; -+ struct cvmx_pcieep_cfg464_s cn56xx; -+ struct cvmx_pcieep_cfg464_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg465 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg465_s { -+ uint32_t wrr_vc7:8; -+ uint32_t wrr_vc6:8; -+ uint32_t wrr_vc5:8; -+ uint32_t wrr_vc4:8; -+ } s; -+ struct cvmx_pcieep_cfg465_s cn52xx; -+ struct cvmx_pcieep_cfg465_s cn52xxp1; -+ struct cvmx_pcieep_cfg465_s cn56xx; -+ struct cvmx_pcieep_cfg465_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg466 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg466_s { -+ uint32_t rx_queue_order:1; -+ uint32_t type_ordering:1; -+ uint32_t reserved_24_29:6; -+ uint32_t queue_mode:3; -+ uint32_t reserved_20_20:1; -+ uint32_t header_credits:8; -+ uint32_t data_credits:12; -+ } s; -+ struct cvmx_pcieep_cfg466_s cn52xx; -+ struct cvmx_pcieep_cfg466_s cn52xxp1; -+ struct cvmx_pcieep_cfg466_s cn56xx; -+ struct cvmx_pcieep_cfg466_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg467 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg467_s { -+ uint32_t reserved_24_31:8; -+ uint32_t queue_mode:3; -+ uint32_t reserved_20_20:1; -+ uint32_t header_credits:8; -+ uint32_t data_credits:12; -+ } s; -+ struct cvmx_pcieep_cfg467_s cn52xx; -+ struct cvmx_pcieep_cfg467_s cn52xxp1; -+ struct cvmx_pcieep_cfg467_s cn56xx; -+ struct cvmx_pcieep_cfg467_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg468 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg468_s { -+ uint32_t reserved_24_31:8; -+ uint32_t queue_mode:3; -+ uint32_t reserved_20_20:1; -+ uint32_t header_credits:8; -+ uint32_t data_credits:12; -+ } s; -+ struct cvmx_pcieep_cfg468_s cn52xx; -+ struct cvmx_pcieep_cfg468_s cn52xxp1; -+ struct cvmx_pcieep_cfg468_s cn56xx; -+ struct cvmx_pcieep_cfg468_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg490 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg490_s { -+ uint32_t reserved_26_31:6; -+ uint32_t header_depth:10; -+ uint32_t reserved_14_15:2; -+ uint32_t data_depth:14; -+ } s; -+ struct cvmx_pcieep_cfg490_s cn52xx; -+ struct cvmx_pcieep_cfg490_s cn52xxp1; -+ struct cvmx_pcieep_cfg490_s cn56xx; -+ struct cvmx_pcieep_cfg490_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg491 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg491_s { -+ uint32_t reserved_26_31:6; -+ uint32_t header_depth:10; -+ uint32_t reserved_14_15:2; -+ uint32_t data_depth:14; -+ } s; -+ struct cvmx_pcieep_cfg491_s cn52xx; -+ struct cvmx_pcieep_cfg491_s cn52xxp1; -+ struct cvmx_pcieep_cfg491_s cn56xx; -+ struct cvmx_pcieep_cfg491_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg492 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg492_s { -+ uint32_t reserved_26_31:6; -+ uint32_t header_depth:10; -+ uint32_t reserved_14_15:2; -+ uint32_t data_depth:14; -+ } s; -+ struct cvmx_pcieep_cfg492_s cn52xx; -+ struct cvmx_pcieep_cfg492_s cn52xxp1; -+ struct cvmx_pcieep_cfg492_s cn56xx; -+ struct cvmx_pcieep_cfg492_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg516 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg516_s { -+ uint32_t phy_stat:32; -+ } s; -+ struct cvmx_pcieep_cfg516_s cn52xx; -+ struct cvmx_pcieep_cfg516_s cn52xxp1; -+ struct cvmx_pcieep_cfg516_s cn56xx; -+ struct cvmx_pcieep_cfg516_s cn56xxp1; -+}; -+ -+union cvmx_pcieep_cfg517 { -+ uint32_t u32; -+ struct cvmx_pcieep_cfg517_s { -+ uint32_t phy_ctrl:32; -+ } s; -+ struct cvmx_pcieep_cfg517_s cn52xx; -+ struct cvmx_pcieep_cfg517_s cn52xxp1; -+ struct cvmx_pcieep_cfg517_s cn56xx; -+ struct cvmx_pcieep_cfg517_s cn56xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h -@@ -0,0 +1,1397 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_PCIERCX_DEFS_H__ -+#define __CVMX_PCIERCX_DEFS_H__ -+ -+#define CVMX_PCIERCX_CFG000(offset) \ -+ (0x0000000000000000ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG001(offset) \ -+ (0x0000000000000004ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG002(offset) \ -+ (0x0000000000000008ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG003(offset) \ -+ (0x000000000000000Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG004(offset) \ -+ (0x0000000000000010ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG005(offset) \ -+ (0x0000000000000014ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG006(offset) \ -+ (0x0000000000000018ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG007(offset) \ -+ (0x000000000000001Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG008(offset) \ -+ (0x0000000000000020ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG009(offset) \ -+ (0x0000000000000024ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG010(offset) \ -+ (0x0000000000000028ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG011(offset) \ -+ (0x000000000000002Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG012(offset) \ -+ (0x0000000000000030ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG013(offset) \ -+ (0x0000000000000034ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG014(offset) \ -+ (0x0000000000000038ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG015(offset) \ -+ (0x000000000000003Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG016(offset) \ -+ (0x0000000000000040ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG017(offset) \ -+ (0x0000000000000044ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG020(offset) \ -+ (0x0000000000000050ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG021(offset) \ -+ (0x0000000000000054ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG022(offset) \ -+ (0x0000000000000058ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG023(offset) \ -+ (0x000000000000005Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG028(offset) \ -+ (0x0000000000000070ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG029(offset) \ -+ (0x0000000000000074ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG030(offset) \ -+ (0x0000000000000078ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG031(offset) \ -+ (0x000000000000007Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG032(offset) \ -+ (0x0000000000000080ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG033(offset) \ -+ (0x0000000000000084ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG034(offset) \ -+ (0x0000000000000088ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG035(offset) \ -+ (0x000000000000008Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG036(offset) \ -+ (0x0000000000000090ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG037(offset) \ -+ (0x0000000000000094ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG038(offset) \ -+ (0x0000000000000098ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG039(offset) \ -+ (0x000000000000009Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG040(offset) \ -+ (0x00000000000000A0ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG041(offset) \ -+ (0x00000000000000A4ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG042(offset) \ -+ (0x00000000000000A8ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG064(offset) \ -+ (0x0000000000000100ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG065(offset) \ -+ (0x0000000000000104ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG066(offset) \ -+ (0x0000000000000108ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG067(offset) \ -+ (0x000000000000010Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG068(offset) \ -+ (0x0000000000000110ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG069(offset) \ -+ (0x0000000000000114ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG070(offset) \ -+ (0x0000000000000118ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG071(offset) \ -+ (0x000000000000011Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG072(offset) \ -+ (0x0000000000000120ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG073(offset) \ -+ (0x0000000000000124ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG074(offset) \ -+ (0x0000000000000128ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG075(offset) \ -+ (0x000000000000012Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG076(offset) \ -+ (0x0000000000000130ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG077(offset) \ -+ (0x0000000000000134ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG448(offset) \ -+ (0x0000000000000700ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG449(offset) \ -+ (0x0000000000000704ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG450(offset) \ -+ (0x0000000000000708ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG451(offset) \ -+ (0x000000000000070Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG452(offset) \ -+ (0x0000000000000710ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG453(offset) \ -+ (0x0000000000000714ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG454(offset) \ -+ (0x0000000000000718ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG455(offset) \ -+ (0x000000000000071Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG456(offset) \ -+ (0x0000000000000720ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG458(offset) \ -+ (0x0000000000000728ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG459(offset) \ -+ (0x000000000000072Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG460(offset) \ -+ (0x0000000000000730ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG461(offset) \ -+ (0x0000000000000734ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG462(offset) \ -+ (0x0000000000000738ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG463(offset) \ -+ (0x000000000000073Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG464(offset) \ -+ (0x0000000000000740ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG465(offset) \ -+ (0x0000000000000744ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG466(offset) \ -+ (0x0000000000000748ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG467(offset) \ -+ (0x000000000000074Cull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG468(offset) \ -+ (0x0000000000000750ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG490(offset) \ -+ (0x00000000000007A8ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG491(offset) \ -+ (0x00000000000007ACull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG492(offset) \ -+ (0x00000000000007B0ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG516(offset) \ -+ (0x0000000000000810ull + (((offset) & 1) * 0)) -+#define CVMX_PCIERCX_CFG517(offset) \ -+ (0x0000000000000814ull + (((offset) & 1) * 0)) -+ -+union cvmx_pciercx_cfg000 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg000_s { -+ uint32_t devid:16; -+ uint32_t vendid:16; -+ } s; -+ struct cvmx_pciercx_cfg000_s cn52xx; -+ struct cvmx_pciercx_cfg000_s cn52xxp1; -+ struct cvmx_pciercx_cfg000_s cn56xx; -+ struct cvmx_pciercx_cfg000_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg001 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg001_s { -+ uint32_t dpe:1; -+ uint32_t sse:1; -+ uint32_t rma:1; -+ uint32_t rta:1; -+ uint32_t sta:1; -+ uint32_t devt:2; -+ uint32_t mdpe:1; -+ uint32_t fbb:1; -+ uint32_t reserved_22_22:1; -+ uint32_t m66:1; -+ uint32_t cl:1; -+ uint32_t i_stat:1; -+ uint32_t reserved_11_18:8; -+ uint32_t i_dis:1; -+ uint32_t fbbe:1; -+ uint32_t see:1; -+ uint32_t ids_wcc:1; -+ uint32_t per:1; -+ uint32_t vps:1; -+ uint32_t mwice:1; -+ uint32_t scse:1; -+ uint32_t me:1; -+ uint32_t msae:1; -+ uint32_t isae:1; -+ } s; -+ struct cvmx_pciercx_cfg001_s cn52xx; -+ struct cvmx_pciercx_cfg001_s cn52xxp1; -+ struct cvmx_pciercx_cfg001_s cn56xx; -+ struct cvmx_pciercx_cfg001_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg002 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg002_s { -+ uint32_t bcc:8; -+ uint32_t sc:8; -+ uint32_t pi:8; -+ uint32_t rid:8; -+ } s; -+ struct cvmx_pciercx_cfg002_s cn52xx; -+ struct cvmx_pciercx_cfg002_s cn52xxp1; -+ struct cvmx_pciercx_cfg002_s cn56xx; -+ struct cvmx_pciercx_cfg002_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg003 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg003_s { -+ uint32_t bist:8; -+ uint32_t mfd:1; -+ uint32_t chf:7; -+ uint32_t lt:8; -+ uint32_t cls:8; -+ } s; -+ struct cvmx_pciercx_cfg003_s cn52xx; -+ struct cvmx_pciercx_cfg003_s cn52xxp1; -+ struct cvmx_pciercx_cfg003_s cn56xx; -+ struct cvmx_pciercx_cfg003_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg004 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg004_s { -+ uint32_t reserved_0_31:32; -+ } s; -+ struct cvmx_pciercx_cfg004_s cn52xx; -+ struct cvmx_pciercx_cfg004_s cn52xxp1; -+ struct cvmx_pciercx_cfg004_s cn56xx; -+ struct cvmx_pciercx_cfg004_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg005 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg005_s { -+ uint32_t reserved_0_31:32; -+ } s; -+ struct cvmx_pciercx_cfg005_s cn52xx; -+ struct cvmx_pciercx_cfg005_s cn52xxp1; -+ struct cvmx_pciercx_cfg005_s cn56xx; -+ struct cvmx_pciercx_cfg005_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg006 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg006_s { -+ uint32_t slt:8; -+ uint32_t subbnum:8; -+ uint32_t sbnum:8; -+ uint32_t pbnum:8; -+ } s; -+ struct cvmx_pciercx_cfg006_s cn52xx; -+ struct cvmx_pciercx_cfg006_s cn52xxp1; -+ struct cvmx_pciercx_cfg006_s cn56xx; -+ struct cvmx_pciercx_cfg006_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg007 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg007_s { -+ uint32_t dpe:1; -+ uint32_t sse:1; -+ uint32_t rma:1; -+ uint32_t rta:1; -+ uint32_t sta:1; -+ uint32_t devt:2; -+ uint32_t mdpe:1; -+ uint32_t fbb:1; -+ uint32_t reserved_22_22:1; -+ uint32_t m66:1; -+ uint32_t reserved_16_20:5; -+ uint32_t lio_limi:4; -+ uint32_t reserved_9_11:3; -+ uint32_t io32b:1; -+ uint32_t lio_base:4; -+ uint32_t reserved_1_3:3; -+ uint32_t io32a:1; -+ } s; -+ struct cvmx_pciercx_cfg007_s cn52xx; -+ struct cvmx_pciercx_cfg007_s cn52xxp1; -+ struct cvmx_pciercx_cfg007_s cn56xx; -+ struct cvmx_pciercx_cfg007_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg008 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg008_s { -+ uint32_t ml_addr:12; -+ uint32_t reserved_16_19:4; -+ uint32_t mb_addr:12; -+ uint32_t reserved_0_3:4; -+ } s; -+ struct cvmx_pciercx_cfg008_s cn52xx; -+ struct cvmx_pciercx_cfg008_s cn52xxp1; -+ struct cvmx_pciercx_cfg008_s cn56xx; -+ struct cvmx_pciercx_cfg008_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg009 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg009_s { -+ uint32_t lmem_limit:12; -+ uint32_t reserved_17_19:3; -+ uint32_t mem64b:1; -+ uint32_t lmem_base:12; -+ uint32_t reserved_1_3:3; -+ uint32_t mem64a:1; -+ } s; -+ struct cvmx_pciercx_cfg009_s cn52xx; -+ struct cvmx_pciercx_cfg009_s cn52xxp1; -+ struct cvmx_pciercx_cfg009_s cn56xx; -+ struct cvmx_pciercx_cfg009_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg010 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg010_s { -+ uint32_t umem_base:32; -+ } s; -+ struct cvmx_pciercx_cfg010_s cn52xx; -+ struct cvmx_pciercx_cfg010_s cn52xxp1; -+ struct cvmx_pciercx_cfg010_s cn56xx; -+ struct cvmx_pciercx_cfg010_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg011 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg011_s { -+ uint32_t umem_limit:32; -+ } s; -+ struct cvmx_pciercx_cfg011_s cn52xx; -+ struct cvmx_pciercx_cfg011_s cn52xxp1; -+ struct cvmx_pciercx_cfg011_s cn56xx; -+ struct cvmx_pciercx_cfg011_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg012 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg012_s { -+ uint32_t uio_limit:16; -+ uint32_t uio_base:16; -+ } s; -+ struct cvmx_pciercx_cfg012_s cn52xx; -+ struct cvmx_pciercx_cfg012_s cn52xxp1; -+ struct cvmx_pciercx_cfg012_s cn56xx; -+ struct cvmx_pciercx_cfg012_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg013 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg013_s { -+ uint32_t reserved_8_31:24; -+ uint32_t cp:8; -+ } s; -+ struct cvmx_pciercx_cfg013_s cn52xx; -+ struct cvmx_pciercx_cfg013_s cn52xxp1; -+ struct cvmx_pciercx_cfg013_s cn56xx; -+ struct cvmx_pciercx_cfg013_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg014 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg014_s { -+ uint32_t reserved_0_31:32; -+ } s; -+ struct cvmx_pciercx_cfg014_s cn52xx; -+ struct cvmx_pciercx_cfg014_s cn52xxp1; -+ struct cvmx_pciercx_cfg014_s cn56xx; -+ struct cvmx_pciercx_cfg014_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg015 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg015_s { -+ uint32_t reserved_28_31:4; -+ uint32_t dtsees:1; -+ uint32_t dts:1; -+ uint32_t sdt:1; -+ uint32_t pdt:1; -+ uint32_t fbbe:1; -+ uint32_t sbrst:1; -+ uint32_t mam:1; -+ uint32_t vga16d:1; -+ uint32_t vgae:1; -+ uint32_t isae:1; -+ uint32_t see:1; -+ uint32_t pere:1; -+ uint32_t inta:8; -+ uint32_t il:8; -+ } s; -+ struct cvmx_pciercx_cfg015_s cn52xx; -+ struct cvmx_pciercx_cfg015_s cn52xxp1; -+ struct cvmx_pciercx_cfg015_s cn56xx; -+ struct cvmx_pciercx_cfg015_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg016 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg016_s { -+ uint32_t pmes:5; -+ uint32_t d2s:1; -+ uint32_t d1s:1; -+ uint32_t auxc:3; -+ uint32_t dsi:1; -+ uint32_t reserved_20_20:1; -+ uint32_t pme_clock:1; -+ uint32_t pmsv:3; -+ uint32_t ncp:8; -+ uint32_t pmcid:8; -+ } s; -+ struct cvmx_pciercx_cfg016_s cn52xx; -+ struct cvmx_pciercx_cfg016_s cn52xxp1; -+ struct cvmx_pciercx_cfg016_s cn56xx; -+ struct cvmx_pciercx_cfg016_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg017 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg017_s { -+ uint32_t pmdia:8; -+ uint32_t bpccee:1; -+ uint32_t bd3h:1; -+ uint32_t reserved_16_21:6; -+ uint32_t pmess:1; -+ uint32_t pmedsia:2; -+ uint32_t pmds:4; -+ uint32_t pmeens:1; -+ uint32_t reserved_4_7:4; -+ uint32_t nsr:1; -+ uint32_t reserved_2_2:1; -+ uint32_t ps:2; -+ } s; -+ struct cvmx_pciercx_cfg017_s cn52xx; -+ struct cvmx_pciercx_cfg017_s cn52xxp1; -+ struct cvmx_pciercx_cfg017_s cn56xx; -+ struct cvmx_pciercx_cfg017_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg020 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg020_s { -+ uint32_t reserved_24_31:8; -+ uint32_t m64:1; -+ uint32_t mme:3; -+ uint32_t mmc:3; -+ uint32_t msien:1; -+ uint32_t ncp:8; -+ uint32_t msicid:8; -+ } s; -+ struct cvmx_pciercx_cfg020_s cn52xx; -+ struct cvmx_pciercx_cfg020_s cn52xxp1; -+ struct cvmx_pciercx_cfg020_s cn56xx; -+ struct cvmx_pciercx_cfg020_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg021 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg021_s { -+ uint32_t lmsi:30; -+ uint32_t reserved_0_1:2; -+ } s; -+ struct cvmx_pciercx_cfg021_s cn52xx; -+ struct cvmx_pciercx_cfg021_s cn52xxp1; -+ struct cvmx_pciercx_cfg021_s cn56xx; -+ struct cvmx_pciercx_cfg021_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg022 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg022_s { -+ uint32_t umsi:32; -+ } s; -+ struct cvmx_pciercx_cfg022_s cn52xx; -+ struct cvmx_pciercx_cfg022_s cn52xxp1; -+ struct cvmx_pciercx_cfg022_s cn56xx; -+ struct cvmx_pciercx_cfg022_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg023 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg023_s { -+ uint32_t reserved_16_31:16; -+ uint32_t msimd:16; -+ } s; -+ struct cvmx_pciercx_cfg023_s cn52xx; -+ struct cvmx_pciercx_cfg023_s cn52xxp1; -+ struct cvmx_pciercx_cfg023_s cn56xx; -+ struct cvmx_pciercx_cfg023_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg028 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg028_s { -+ uint32_t reserved_30_31:2; -+ uint32_t imn:5; -+ uint32_t si:1; -+ uint32_t dpt:4; -+ uint32_t pciecv:4; -+ uint32_t ncp:8; -+ uint32_t pcieid:8; -+ } s; -+ struct cvmx_pciercx_cfg028_s cn52xx; -+ struct cvmx_pciercx_cfg028_s cn52xxp1; -+ struct cvmx_pciercx_cfg028_s cn56xx; -+ struct cvmx_pciercx_cfg028_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg029 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg029_s { -+ uint32_t reserved_28_31:4; -+ uint32_t cspls:2; -+ uint32_t csplv:8; -+ uint32_t reserved_16_17:2; -+ uint32_t rber:1; -+ uint32_t reserved_12_14:3; -+ uint32_t el1al:3; -+ uint32_t el0al:3; -+ uint32_t etfs:1; -+ uint32_t pfs:2; -+ uint32_t mpss:3; -+ } s; -+ struct cvmx_pciercx_cfg029_s cn52xx; -+ struct cvmx_pciercx_cfg029_s cn52xxp1; -+ struct cvmx_pciercx_cfg029_s cn56xx; -+ struct cvmx_pciercx_cfg029_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg030 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg030_s { -+ uint32_t reserved_22_31:10; -+ uint32_t tp:1; -+ uint32_t ap_d:1; -+ uint32_t ur_d:1; -+ uint32_t fe_d:1; -+ uint32_t nfe_d:1; -+ uint32_t ce_d:1; -+ uint32_t reserved_15_15:1; -+ uint32_t mrrs:3; -+ uint32_t ns_en:1; -+ uint32_t ap_en:1; -+ uint32_t pf_en:1; -+ uint32_t etf_en:1; -+ uint32_t mps:3; -+ uint32_t ro_en:1; -+ uint32_t ur_en:1; -+ uint32_t fe_en:1; -+ uint32_t nfe_en:1; -+ uint32_t ce_en:1; -+ } s; -+ struct cvmx_pciercx_cfg030_s cn52xx; -+ struct cvmx_pciercx_cfg030_s cn52xxp1; -+ struct cvmx_pciercx_cfg030_s cn56xx; -+ struct cvmx_pciercx_cfg030_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg031 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg031_s { -+ uint32_t pnum:8; -+ uint32_t reserved_22_23:2; -+ uint32_t lbnc:1; -+ uint32_t dllarc:1; -+ uint32_t sderc:1; -+ uint32_t cpm:1; -+ uint32_t l1el:3; -+ uint32_t l0el:3; -+ uint32_t aslpms:2; -+ uint32_t mlw:6; -+ uint32_t mls:4; -+ } s; -+ struct cvmx_pciercx_cfg031_s cn52xx; -+ struct cvmx_pciercx_cfg031_s cn52xxp1; -+ struct cvmx_pciercx_cfg031_s cn56xx; -+ struct cvmx_pciercx_cfg031_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg032 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg032_s { -+ uint32_t lab:1; -+ uint32_t lbm:1; -+ uint32_t dlla:1; -+ uint32_t scc:1; -+ uint32_t lt:1; -+ uint32_t reserved_26_26:1; -+ uint32_t nlw:6; -+ uint32_t ls:4; -+ uint32_t reserved_12_15:4; -+ uint32_t lab_int_enb:1; -+ uint32_t lbm_int_enb:1; -+ uint32_t hawd:1; -+ uint32_t ecpm:1; -+ uint32_t es:1; -+ uint32_t ccc:1; -+ uint32_t rl:1; -+ uint32_t ld:1; -+ uint32_t rcb:1; -+ uint32_t reserved_2_2:1; -+ uint32_t aslpc:2; -+ } s; -+ struct cvmx_pciercx_cfg032_s cn52xx; -+ struct cvmx_pciercx_cfg032_s cn52xxp1; -+ struct cvmx_pciercx_cfg032_s cn56xx; -+ struct cvmx_pciercx_cfg032_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg033 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg033_s { -+ uint32_t ps_num:13; -+ uint32_t nccs:1; -+ uint32_t emip:1; -+ uint32_t sp_ls:2; -+ uint32_t sp_lv:8; -+ uint32_t hp_c:1; -+ uint32_t hp_s:1; -+ uint32_t pip:1; -+ uint32_t aip:1; -+ uint32_t mrlsp:1; -+ uint32_t pcp:1; -+ uint32_t abp:1; -+ } s; -+ struct cvmx_pciercx_cfg033_s cn52xx; -+ struct cvmx_pciercx_cfg033_s cn52xxp1; -+ struct cvmx_pciercx_cfg033_s cn56xx; -+ struct cvmx_pciercx_cfg033_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg034 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg034_s { -+ uint32_t reserved_25_31:7; -+ uint32_t dlls_c:1; -+ uint32_t emis:1; -+ uint32_t pds:1; -+ uint32_t mrlss:1; -+ uint32_t ccint_d:1; -+ uint32_t pd_c:1; -+ uint32_t mrls_c:1; -+ uint32_t pf_d:1; -+ uint32_t abp_d:1; -+ uint32_t reserved_13_15:3; -+ uint32_t dlls_en:1; -+ uint32_t emic:1; -+ uint32_t pcc:1; -+ uint32_t pic:2; -+ uint32_t aic:2; -+ uint32_t hpint_en:1; -+ uint32_t ccint_en:1; -+ uint32_t pd_en:1; -+ uint32_t mrls_en:1; -+ uint32_t pf_en:1; -+ uint32_t abp_en:1; -+ } s; -+ struct cvmx_pciercx_cfg034_s cn52xx; -+ struct cvmx_pciercx_cfg034_s cn52xxp1; -+ struct cvmx_pciercx_cfg034_s cn56xx; -+ struct cvmx_pciercx_cfg034_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg035 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg035_s { -+ uint32_t reserved_17_31:15; -+ uint32_t crssv:1; -+ uint32_t reserved_5_15:11; -+ uint32_t crssve:1; -+ uint32_t pmeie:1; -+ uint32_t sefee:1; -+ uint32_t senfee:1; -+ uint32_t secee:1; -+ } s; -+ struct cvmx_pciercx_cfg035_s cn52xx; -+ struct cvmx_pciercx_cfg035_s cn52xxp1; -+ struct cvmx_pciercx_cfg035_s cn56xx; -+ struct cvmx_pciercx_cfg035_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg036 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg036_s { -+ uint32_t reserved_18_31:14; -+ uint32_t pme_pend:1; -+ uint32_t pme_stat:1; -+ uint32_t pme_rid:16; -+ } s; -+ struct cvmx_pciercx_cfg036_s cn52xx; -+ struct cvmx_pciercx_cfg036_s cn52xxp1; -+ struct cvmx_pciercx_cfg036_s cn56xx; -+ struct cvmx_pciercx_cfg036_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg037 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg037_s { -+ uint32_t reserved_5_31:27; -+ uint32_t ctds:1; -+ uint32_t ctrs:4; -+ } s; -+ struct cvmx_pciercx_cfg037_s cn52xx; -+ struct cvmx_pciercx_cfg037_s cn52xxp1; -+ struct cvmx_pciercx_cfg037_s cn56xx; -+ struct cvmx_pciercx_cfg037_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg038 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg038_s { -+ uint32_t reserved_5_31:27; -+ uint32_t ctd:1; -+ uint32_t ctv:4; -+ } s; -+ struct cvmx_pciercx_cfg038_s cn52xx; -+ struct cvmx_pciercx_cfg038_s cn52xxp1; -+ struct cvmx_pciercx_cfg038_s cn56xx; -+ struct cvmx_pciercx_cfg038_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg039 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg039_s { -+ uint32_t reserved_0_31:32; -+ } s; -+ struct cvmx_pciercx_cfg039_s cn52xx; -+ struct cvmx_pciercx_cfg039_s cn52xxp1; -+ struct cvmx_pciercx_cfg039_s cn56xx; -+ struct cvmx_pciercx_cfg039_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg040 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg040_s { -+ uint32_t reserved_0_31:32; -+ } s; -+ struct cvmx_pciercx_cfg040_s cn52xx; -+ struct cvmx_pciercx_cfg040_s cn52xxp1; -+ struct cvmx_pciercx_cfg040_s cn56xx; -+ struct cvmx_pciercx_cfg040_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg041 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg041_s { -+ uint32_t reserved_0_31:32; -+ } s; -+ struct cvmx_pciercx_cfg041_s cn52xx; -+ struct cvmx_pciercx_cfg041_s cn52xxp1; -+ struct cvmx_pciercx_cfg041_s cn56xx; -+ struct cvmx_pciercx_cfg041_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg042 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg042_s { -+ uint32_t reserved_0_31:32; -+ } s; -+ struct cvmx_pciercx_cfg042_s cn52xx; -+ struct cvmx_pciercx_cfg042_s cn52xxp1; -+ struct cvmx_pciercx_cfg042_s cn56xx; -+ struct cvmx_pciercx_cfg042_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg064 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg064_s { -+ uint32_t nco:12; -+ uint32_t cv:4; -+ uint32_t pcieec:16; -+ } s; -+ struct cvmx_pciercx_cfg064_s cn52xx; -+ struct cvmx_pciercx_cfg064_s cn52xxp1; -+ struct cvmx_pciercx_cfg064_s cn56xx; -+ struct cvmx_pciercx_cfg064_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg065 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg065_s { -+ uint32_t reserved_21_31:11; -+ uint32_t ures:1; -+ uint32_t ecrces:1; -+ uint32_t mtlps:1; -+ uint32_t ros:1; -+ uint32_t ucs:1; -+ uint32_t cas:1; -+ uint32_t cts:1; -+ uint32_t fcpes:1; -+ uint32_t ptlps:1; -+ uint32_t reserved_6_11:6; -+ uint32_t sdes:1; -+ uint32_t dlpes:1; -+ uint32_t reserved_0_3:4; -+ } s; -+ struct cvmx_pciercx_cfg065_s cn52xx; -+ struct cvmx_pciercx_cfg065_s cn52xxp1; -+ struct cvmx_pciercx_cfg065_s cn56xx; -+ struct cvmx_pciercx_cfg065_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg066 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg066_s { -+ uint32_t reserved_21_31:11; -+ uint32_t urem:1; -+ uint32_t ecrcem:1; -+ uint32_t mtlpm:1; -+ uint32_t rom:1; -+ uint32_t ucm:1; -+ uint32_t cam:1; -+ uint32_t ctm:1; -+ uint32_t fcpem:1; -+ uint32_t ptlpm:1; -+ uint32_t reserved_6_11:6; -+ uint32_t sdem:1; -+ uint32_t dlpem:1; -+ uint32_t reserved_0_3:4; -+ } s; -+ struct cvmx_pciercx_cfg066_s cn52xx; -+ struct cvmx_pciercx_cfg066_s cn52xxp1; -+ struct cvmx_pciercx_cfg066_s cn56xx; -+ struct cvmx_pciercx_cfg066_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg067 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg067_s { -+ uint32_t reserved_21_31:11; -+ uint32_t ures:1; -+ uint32_t ecrces:1; -+ uint32_t mtlps:1; -+ uint32_t ros:1; -+ uint32_t ucs:1; -+ uint32_t cas:1; -+ uint32_t cts:1; -+ uint32_t fcpes:1; -+ uint32_t ptlps:1; -+ uint32_t reserved_6_11:6; -+ uint32_t sdes:1; -+ uint32_t dlpes:1; -+ uint32_t reserved_0_3:4; -+ } s; -+ struct cvmx_pciercx_cfg067_s cn52xx; -+ struct cvmx_pciercx_cfg067_s cn52xxp1; -+ struct cvmx_pciercx_cfg067_s cn56xx; -+ struct cvmx_pciercx_cfg067_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg068 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg068_s { -+ uint32_t reserved_14_31:18; -+ uint32_t anfes:1; -+ uint32_t rtts:1; -+ uint32_t reserved_9_11:3; -+ uint32_t rnrs:1; -+ uint32_t bdllps:1; -+ uint32_t btlps:1; -+ uint32_t reserved_1_5:5; -+ uint32_t res:1; -+ } s; -+ struct cvmx_pciercx_cfg068_s cn52xx; -+ struct cvmx_pciercx_cfg068_s cn52xxp1; -+ struct cvmx_pciercx_cfg068_s cn56xx; -+ struct cvmx_pciercx_cfg068_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg069 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg069_s { -+ uint32_t reserved_14_31:18; -+ uint32_t anfem:1; -+ uint32_t rttm:1; -+ uint32_t reserved_9_11:3; -+ uint32_t rnrm:1; -+ uint32_t bdllpm:1; -+ uint32_t btlpm:1; -+ uint32_t reserved_1_5:5; -+ uint32_t rem:1; -+ } s; -+ struct cvmx_pciercx_cfg069_s cn52xx; -+ struct cvmx_pciercx_cfg069_s cn52xxp1; -+ struct cvmx_pciercx_cfg069_s cn56xx; -+ struct cvmx_pciercx_cfg069_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg070 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg070_s { -+ uint32_t reserved_9_31:23; -+ uint32_t ce:1; -+ uint32_t cc:1; -+ uint32_t ge:1; -+ uint32_t gc:1; -+ uint32_t fep:5; -+ } s; -+ struct cvmx_pciercx_cfg070_s cn52xx; -+ struct cvmx_pciercx_cfg070_s cn52xxp1; -+ struct cvmx_pciercx_cfg070_s cn56xx; -+ struct cvmx_pciercx_cfg070_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg071 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg071_s { -+ uint32_t dword1:32; -+ } s; -+ struct cvmx_pciercx_cfg071_s cn52xx; -+ struct cvmx_pciercx_cfg071_s cn52xxp1; -+ struct cvmx_pciercx_cfg071_s cn56xx; -+ struct cvmx_pciercx_cfg071_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg072 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg072_s { -+ uint32_t dword2:32; -+ } s; -+ struct cvmx_pciercx_cfg072_s cn52xx; -+ struct cvmx_pciercx_cfg072_s cn52xxp1; -+ struct cvmx_pciercx_cfg072_s cn56xx; -+ struct cvmx_pciercx_cfg072_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg073 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg073_s { -+ uint32_t dword3:32; -+ } s; -+ struct cvmx_pciercx_cfg073_s cn52xx; -+ struct cvmx_pciercx_cfg073_s cn52xxp1; -+ struct cvmx_pciercx_cfg073_s cn56xx; -+ struct cvmx_pciercx_cfg073_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg074 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg074_s { -+ uint32_t dword4:32; -+ } s; -+ struct cvmx_pciercx_cfg074_s cn52xx; -+ struct cvmx_pciercx_cfg074_s cn52xxp1; -+ struct cvmx_pciercx_cfg074_s cn56xx; -+ struct cvmx_pciercx_cfg074_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg075 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg075_s { -+ uint32_t reserved_3_31:29; -+ uint32_t fere:1; -+ uint32_t nfere:1; -+ uint32_t cere:1; -+ } s; -+ struct cvmx_pciercx_cfg075_s cn52xx; -+ struct cvmx_pciercx_cfg075_s cn52xxp1; -+ struct cvmx_pciercx_cfg075_s cn56xx; -+ struct cvmx_pciercx_cfg075_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg076 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg076_s { -+ uint32_t aeimn:5; -+ uint32_t reserved_7_26:20; -+ uint32_t femr:1; -+ uint32_t nfemr:1; -+ uint32_t fuf:1; -+ uint32_t multi_efnfr:1; -+ uint32_t efnfr:1; -+ uint32_t multi_ecr:1; -+ uint32_t ecr:1; -+ } s; -+ struct cvmx_pciercx_cfg076_s cn52xx; -+ struct cvmx_pciercx_cfg076_s cn52xxp1; -+ struct cvmx_pciercx_cfg076_s cn56xx; -+ struct cvmx_pciercx_cfg076_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg077 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg077_s { -+ uint32_t efnfsi:16; -+ uint32_t ecsi:16; -+ } s; -+ struct cvmx_pciercx_cfg077_s cn52xx; -+ struct cvmx_pciercx_cfg077_s cn52xxp1; -+ struct cvmx_pciercx_cfg077_s cn56xx; -+ struct cvmx_pciercx_cfg077_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg448 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg448_s { -+ uint32_t rtl:16; -+ uint32_t rtltl:16; -+ } s; -+ struct cvmx_pciercx_cfg448_s cn52xx; -+ struct cvmx_pciercx_cfg448_s cn52xxp1; -+ struct cvmx_pciercx_cfg448_s cn56xx; -+ struct cvmx_pciercx_cfg448_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg449 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg449_s { -+ uint32_t omr:32; -+ } s; -+ struct cvmx_pciercx_cfg449_s cn52xx; -+ struct cvmx_pciercx_cfg449_s cn52xxp1; -+ struct cvmx_pciercx_cfg449_s cn56xx; -+ struct cvmx_pciercx_cfg449_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg450 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg450_s { -+ uint32_t lpec:8; -+ uint32_t reserved_22_23:2; -+ uint32_t link_state:6; -+ uint32_t force_link:1; -+ uint32_t reserved_8_14:7; -+ uint32_t link_num:8; -+ } s; -+ struct cvmx_pciercx_cfg450_s cn52xx; -+ struct cvmx_pciercx_cfg450_s cn52xxp1; -+ struct cvmx_pciercx_cfg450_s cn56xx; -+ struct cvmx_pciercx_cfg450_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg451 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg451_s { -+ uint32_t reserved_30_31:2; -+ uint32_t l1el:3; -+ uint32_t l0el:3; -+ uint32_t n_fts_cc:8; -+ uint32_t n_fts:8; -+ uint32_t ack_freq:8; -+ } s; -+ struct cvmx_pciercx_cfg451_s cn52xx; -+ struct cvmx_pciercx_cfg451_s cn52xxp1; -+ struct cvmx_pciercx_cfg451_s cn56xx; -+ struct cvmx_pciercx_cfg451_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg452 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg452_s { -+ uint32_t reserved_26_31:6; -+ uint32_t eccrc:1; -+ uint32_t reserved_22_24:3; -+ uint32_t lme:6; -+ uint32_t reserved_8_15:8; -+ uint32_t flm:1; -+ uint32_t reserved_6_6:1; -+ uint32_t dllle:1; -+ uint32_t reserved_4_4:1; -+ uint32_t ra:1; -+ uint32_t le:1; -+ uint32_t sd:1; -+ uint32_t omr:1; -+ } s; -+ struct cvmx_pciercx_cfg452_s cn52xx; -+ struct cvmx_pciercx_cfg452_s cn52xxp1; -+ struct cvmx_pciercx_cfg452_s cn56xx; -+ struct cvmx_pciercx_cfg452_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg453 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg453_s { -+ uint32_t dlld:1; -+ uint32_t reserved_26_30:5; -+ uint32_t ack_nak:1; -+ uint32_t fcd:1; -+ uint32_t ilst:24; -+ } s; -+ struct cvmx_pciercx_cfg453_s cn52xx; -+ struct cvmx_pciercx_cfg453_s cn52xxp1; -+ struct cvmx_pciercx_cfg453_s cn56xx; -+ struct cvmx_pciercx_cfg453_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg454 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg454_s { -+ uint32_t reserved_29_31:3; -+ uint32_t tmfcwt:5; -+ uint32_t tmanlt:5; -+ uint32_t tmrt:5; -+ uint32_t reserved_11_13:3; -+ uint32_t nskps:3; -+ uint32_t reserved_4_7:4; -+ uint32_t ntss:4; -+ } s; -+ struct cvmx_pciercx_cfg454_s cn52xx; -+ struct cvmx_pciercx_cfg454_s cn52xxp1; -+ struct cvmx_pciercx_cfg454_s cn56xx; -+ struct cvmx_pciercx_cfg454_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg455 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg455_s { -+ uint32_t m_cfg0_filt:1; -+ uint32_t m_io_filt:1; -+ uint32_t msg_ctrl:1; -+ uint32_t m_cpl_ecrc_filt:1; -+ uint32_t m_ecrc_filt:1; -+ uint32_t m_cpl_len_err:1; -+ uint32_t m_cpl_attr_err:1; -+ uint32_t m_cpl_tc_err:1; -+ uint32_t m_cpl_fun_err:1; -+ uint32_t m_cpl_rid_err:1; -+ uint32_t m_cpl_tag_err:1; -+ uint32_t m_lk_filt:1; -+ uint32_t m_cfg1_filt:1; -+ uint32_t m_bar_match:1; -+ uint32_t m_pois_filt:1; -+ uint32_t m_fun:1; -+ uint32_t dfcwt:1; -+ uint32_t reserved_11_14:4; -+ uint32_t skpiv:11; -+ } s; -+ struct cvmx_pciercx_cfg455_s cn52xx; -+ struct cvmx_pciercx_cfg455_s cn52xxp1; -+ struct cvmx_pciercx_cfg455_s cn56xx; -+ struct cvmx_pciercx_cfg455_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg456 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg456_s { -+ uint32_t reserved_2_31:30; -+ uint32_t m_vend1_drp:1; -+ uint32_t m_vend0_drp:1; -+ } s; -+ struct cvmx_pciercx_cfg456_s cn52xx; -+ struct cvmx_pciercx_cfg456_s cn52xxp1; -+ struct cvmx_pciercx_cfg456_s cn56xx; -+ struct cvmx_pciercx_cfg456_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg458 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg458_s { -+ uint32_t dbg_info_l32:32; -+ } s; -+ struct cvmx_pciercx_cfg458_s cn52xx; -+ struct cvmx_pciercx_cfg458_s cn52xxp1; -+ struct cvmx_pciercx_cfg458_s cn56xx; -+ struct cvmx_pciercx_cfg458_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg459 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg459_s { -+ uint32_t dbg_info_u32:32; -+ } s; -+ struct cvmx_pciercx_cfg459_s cn52xx; -+ struct cvmx_pciercx_cfg459_s cn52xxp1; -+ struct cvmx_pciercx_cfg459_s cn56xx; -+ struct cvmx_pciercx_cfg459_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg460 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg460_s { -+ uint32_t reserved_20_31:12; -+ uint32_t tphfcc:8; -+ uint32_t tpdfcc:12; -+ } s; -+ struct cvmx_pciercx_cfg460_s cn52xx; -+ struct cvmx_pciercx_cfg460_s cn52xxp1; -+ struct cvmx_pciercx_cfg460_s cn56xx; -+ struct cvmx_pciercx_cfg460_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg461 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg461_s { -+ uint32_t reserved_20_31:12; -+ uint32_t tchfcc:8; -+ uint32_t tcdfcc:12; -+ } s; -+ struct cvmx_pciercx_cfg461_s cn52xx; -+ struct cvmx_pciercx_cfg461_s cn52xxp1; -+ struct cvmx_pciercx_cfg461_s cn56xx; -+ struct cvmx_pciercx_cfg461_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg462 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg462_s { -+ uint32_t reserved_20_31:12; -+ uint32_t tchfcc:8; -+ uint32_t tcdfcc:12; -+ } s; -+ struct cvmx_pciercx_cfg462_s cn52xx; -+ struct cvmx_pciercx_cfg462_s cn52xxp1; -+ struct cvmx_pciercx_cfg462_s cn56xx; -+ struct cvmx_pciercx_cfg462_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg463 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg463_s { -+ uint32_t reserved_3_31:29; -+ uint32_t rqne:1; -+ uint32_t trbne:1; -+ uint32_t rtlpfccnr:1; -+ } s; -+ struct cvmx_pciercx_cfg463_s cn52xx; -+ struct cvmx_pciercx_cfg463_s cn52xxp1; -+ struct cvmx_pciercx_cfg463_s cn56xx; -+ struct cvmx_pciercx_cfg463_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg464 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg464_s { -+ uint32_t wrr_vc3:8; -+ uint32_t wrr_vc2:8; -+ uint32_t wrr_vc1:8; -+ uint32_t wrr_vc0:8; -+ } s; -+ struct cvmx_pciercx_cfg464_s cn52xx; -+ struct cvmx_pciercx_cfg464_s cn52xxp1; -+ struct cvmx_pciercx_cfg464_s cn56xx; -+ struct cvmx_pciercx_cfg464_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg465 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg465_s { -+ uint32_t wrr_vc7:8; -+ uint32_t wrr_vc6:8; -+ uint32_t wrr_vc5:8; -+ uint32_t wrr_vc4:8; -+ } s; -+ struct cvmx_pciercx_cfg465_s cn52xx; -+ struct cvmx_pciercx_cfg465_s cn52xxp1; -+ struct cvmx_pciercx_cfg465_s cn56xx; -+ struct cvmx_pciercx_cfg465_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg466 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg466_s { -+ uint32_t rx_queue_order:1; -+ uint32_t type_ordering:1; -+ uint32_t reserved_24_29:6; -+ uint32_t queue_mode:3; -+ uint32_t reserved_20_20:1; -+ uint32_t header_credits:8; -+ uint32_t data_credits:12; -+ } s; -+ struct cvmx_pciercx_cfg466_s cn52xx; -+ struct cvmx_pciercx_cfg466_s cn52xxp1; -+ struct cvmx_pciercx_cfg466_s cn56xx; -+ struct cvmx_pciercx_cfg466_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg467 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg467_s { -+ uint32_t reserved_24_31:8; -+ uint32_t queue_mode:3; -+ uint32_t reserved_20_20:1; -+ uint32_t header_credits:8; -+ uint32_t data_credits:12; -+ } s; -+ struct cvmx_pciercx_cfg467_s cn52xx; -+ struct cvmx_pciercx_cfg467_s cn52xxp1; -+ struct cvmx_pciercx_cfg467_s cn56xx; -+ struct cvmx_pciercx_cfg467_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg468 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg468_s { -+ uint32_t reserved_24_31:8; -+ uint32_t queue_mode:3; -+ uint32_t reserved_20_20:1; -+ uint32_t header_credits:8; -+ uint32_t data_credits:12; -+ } s; -+ struct cvmx_pciercx_cfg468_s cn52xx; -+ struct cvmx_pciercx_cfg468_s cn52xxp1; -+ struct cvmx_pciercx_cfg468_s cn56xx; -+ struct cvmx_pciercx_cfg468_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg490 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg490_s { -+ uint32_t reserved_26_31:6; -+ uint32_t header_depth:10; -+ uint32_t reserved_14_15:2; -+ uint32_t data_depth:14; -+ } s; -+ struct cvmx_pciercx_cfg490_s cn52xx; -+ struct cvmx_pciercx_cfg490_s cn52xxp1; -+ struct cvmx_pciercx_cfg490_s cn56xx; -+ struct cvmx_pciercx_cfg490_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg491 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg491_s { -+ uint32_t reserved_26_31:6; -+ uint32_t header_depth:10; -+ uint32_t reserved_14_15:2; -+ uint32_t data_depth:14; -+ } s; -+ struct cvmx_pciercx_cfg491_s cn52xx; -+ struct cvmx_pciercx_cfg491_s cn52xxp1; -+ struct cvmx_pciercx_cfg491_s cn56xx; -+ struct cvmx_pciercx_cfg491_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg492 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg492_s { -+ uint32_t reserved_26_31:6; -+ uint32_t header_depth:10; -+ uint32_t reserved_14_15:2; -+ uint32_t data_depth:14; -+ } s; -+ struct cvmx_pciercx_cfg492_s cn52xx; -+ struct cvmx_pciercx_cfg492_s cn52xxp1; -+ struct cvmx_pciercx_cfg492_s cn56xx; -+ struct cvmx_pciercx_cfg492_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg516 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg516_s { -+ uint32_t phy_stat:32; -+ } s; -+ struct cvmx_pciercx_cfg516_s cn52xx; -+ struct cvmx_pciercx_cfg516_s cn52xxp1; -+ struct cvmx_pciercx_cfg516_s cn56xx; -+ struct cvmx_pciercx_cfg516_s cn56xxp1; -+}; -+ -+union cvmx_pciercx_cfg517 { -+ uint32_t u32; -+ struct cvmx_pciercx_cfg517_s { -+ uint32_t phy_ctrl:32; -+ } s; -+ struct cvmx_pciercx_cfg517_s cn52xx; -+ struct cvmx_pciercx_cfg517_s cn52xxp1; -+ struct cvmx_pciercx_cfg517_s cn56xx; -+ struct cvmx_pciercx_cfg517_s cn56xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h -@@ -0,0 +1,410 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_PESCX_DEFS_H__ -+#define __CVMX_PESCX_DEFS_H__ -+ -+#define CVMX_PESCX_BIST_STATUS(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000018ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_BIST_STATUS2(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000418ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_CFG_RD(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000030ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_CFG_WR(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000028ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_CPL_LUT_VALID(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000098ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_CTL_STATUS(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000000ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_CTL_STATUS2(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000400ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_DBG_INFO(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000008ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_DBG_INFO_EN(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C80000A0ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_DIAG_STATUS(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000020ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_P2N_BAR0_START(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000080ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_P2N_BAR1_START(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000088ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_P2N_BAR2_START(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000090ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_P2P_BARX_END(offset,block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000048ull + (((offset) & 3) * 16) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_P2P_BARX_START(offset,block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000040ull + (((offset) & 3) * 16) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PESCX_TLP_CREDITS(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800C8000038ull + (((block_id) & 1) * 0x8000000ull)) -+ -+union cvmx_pescx_bist_status { -+ uint64_t u64; -+ struct cvmx_pescx_bist_status_s { -+ uint64_t reserved_13_63:51; -+ uint64_t rqdata5:1; -+ uint64_t ctlp_or:1; -+ uint64_t ntlp_or:1; -+ uint64_t ptlp_or:1; -+ uint64_t retry:1; -+ uint64_t rqdata0:1; -+ uint64_t rqdata1:1; -+ uint64_t rqdata2:1; -+ uint64_t rqdata3:1; -+ uint64_t rqdata4:1; -+ uint64_t rqhdr1:1; -+ uint64_t rqhdr0:1; -+ uint64_t sot:1; -+ } s; -+ struct cvmx_pescx_bist_status_s cn52xx; -+ struct cvmx_pescx_bist_status_cn52xxp1 { -+ uint64_t reserved_12_63:52; -+ uint64_t ctlp_or:1; -+ uint64_t ntlp_or:1; -+ uint64_t ptlp_or:1; -+ uint64_t retry:1; -+ uint64_t rqdata0:1; -+ uint64_t rqdata1:1; -+ uint64_t rqdata2:1; -+ uint64_t rqdata3:1; -+ uint64_t rqdata4:1; -+ uint64_t rqhdr1:1; -+ uint64_t rqhdr0:1; -+ uint64_t sot:1; -+ } cn52xxp1; -+ struct cvmx_pescx_bist_status_s cn56xx; -+ struct cvmx_pescx_bist_status_cn52xxp1 cn56xxp1; -+}; -+ -+union cvmx_pescx_bist_status2 { -+ uint64_t u64; -+ struct cvmx_pescx_bist_status2_s { -+ uint64_t reserved_14_63:50; -+ uint64_t cto_p2e:1; -+ uint64_t e2p_cpl:1; -+ uint64_t e2p_n:1; -+ uint64_t e2p_p:1; -+ uint64_t e2p_rsl:1; -+ uint64_t dbg_p2e:1; -+ uint64_t peai_p2e:1; -+ uint64_t rsl_p2e:1; -+ uint64_t pef_tpf1:1; -+ uint64_t pef_tpf0:1; -+ uint64_t pef_tnf:1; -+ uint64_t pef_tcf1:1; -+ uint64_t pef_tc0:1; -+ uint64_t ppf:1; -+ } s; -+ struct cvmx_pescx_bist_status2_s cn52xx; -+ struct cvmx_pescx_bist_status2_s cn52xxp1; -+ struct cvmx_pescx_bist_status2_s cn56xx; -+ struct cvmx_pescx_bist_status2_s cn56xxp1; -+}; -+ -+union cvmx_pescx_cfg_rd { -+ uint64_t u64; -+ struct cvmx_pescx_cfg_rd_s { -+ uint64_t data:32; -+ uint64_t addr:32; -+ } s; -+ struct cvmx_pescx_cfg_rd_s cn52xx; -+ struct cvmx_pescx_cfg_rd_s cn52xxp1; -+ struct cvmx_pescx_cfg_rd_s cn56xx; -+ struct cvmx_pescx_cfg_rd_s cn56xxp1; -+}; -+ -+union cvmx_pescx_cfg_wr { -+ uint64_t u64; -+ struct cvmx_pescx_cfg_wr_s { -+ uint64_t data:32; -+ uint64_t addr:32; -+ } s; -+ struct cvmx_pescx_cfg_wr_s cn52xx; -+ struct cvmx_pescx_cfg_wr_s cn52xxp1; -+ struct cvmx_pescx_cfg_wr_s cn56xx; -+ struct cvmx_pescx_cfg_wr_s cn56xxp1; -+}; -+ -+union cvmx_pescx_cpl_lut_valid { -+ uint64_t u64; -+ struct cvmx_pescx_cpl_lut_valid_s { -+ uint64_t reserved_32_63:32; -+ uint64_t tag:32; -+ } s; -+ struct cvmx_pescx_cpl_lut_valid_s cn52xx; -+ struct cvmx_pescx_cpl_lut_valid_s cn52xxp1; -+ struct cvmx_pescx_cpl_lut_valid_s cn56xx; -+ struct cvmx_pescx_cpl_lut_valid_s cn56xxp1; -+}; -+ -+union cvmx_pescx_ctl_status { -+ uint64_t u64; -+ struct cvmx_pescx_ctl_status_s { -+ uint64_t reserved_28_63:36; -+ uint64_t dnum:5; -+ uint64_t pbus:8; -+ uint64_t qlm_cfg:2; -+ uint64_t lane_swp:1; -+ uint64_t pm_xtoff:1; -+ uint64_t pm_xpme:1; -+ uint64_t ob_p_cmd:1; -+ uint64_t reserved_7_8:2; -+ uint64_t nf_ecrc:1; -+ uint64_t dly_one:1; -+ uint64_t lnk_enb:1; -+ uint64_t ro_ctlp:1; -+ uint64_t reserved_2_2:1; -+ uint64_t inv_ecrc:1; -+ uint64_t inv_lcrc:1; -+ } s; -+ struct cvmx_pescx_ctl_status_s cn52xx; -+ struct cvmx_pescx_ctl_status_s cn52xxp1; -+ struct cvmx_pescx_ctl_status_cn56xx { -+ uint64_t reserved_28_63:36; -+ uint64_t dnum:5; -+ uint64_t pbus:8; -+ uint64_t qlm_cfg:2; -+ uint64_t reserved_12_12:1; -+ uint64_t pm_xtoff:1; -+ uint64_t pm_xpme:1; -+ uint64_t ob_p_cmd:1; -+ uint64_t reserved_7_8:2; -+ uint64_t nf_ecrc:1; -+ uint64_t dly_one:1; -+ uint64_t lnk_enb:1; -+ uint64_t ro_ctlp:1; -+ uint64_t reserved_2_2:1; -+ uint64_t inv_ecrc:1; -+ uint64_t inv_lcrc:1; -+ } cn56xx; -+ struct cvmx_pescx_ctl_status_cn56xx cn56xxp1; -+}; -+ -+union cvmx_pescx_ctl_status2 { -+ uint64_t u64; -+ struct cvmx_pescx_ctl_status2_s { -+ uint64_t reserved_2_63:62; -+ uint64_t pclk_run:1; -+ uint64_t pcierst:1; -+ } s; -+ struct cvmx_pescx_ctl_status2_s cn52xx; -+ struct cvmx_pescx_ctl_status2_cn52xxp1 { -+ uint64_t reserved_1_63:63; -+ uint64_t pcierst:1; -+ } cn52xxp1; -+ struct cvmx_pescx_ctl_status2_s cn56xx; -+ struct cvmx_pescx_ctl_status2_cn52xxp1 cn56xxp1; -+}; -+ -+union cvmx_pescx_dbg_info { -+ uint64_t u64; -+ struct cvmx_pescx_dbg_info_s { -+ uint64_t reserved_31_63:33; -+ uint64_t ecrc_e:1; -+ uint64_t rawwpp:1; -+ uint64_t racpp:1; -+ uint64_t ramtlp:1; -+ uint64_t rarwdns:1; -+ uint64_t caar:1; -+ uint64_t racca:1; -+ uint64_t racur:1; -+ uint64_t rauc:1; -+ uint64_t rqo:1; -+ uint64_t fcuv:1; -+ uint64_t rpe:1; -+ uint64_t fcpvwt:1; -+ uint64_t dpeoosd:1; -+ uint64_t rtwdle:1; -+ uint64_t rdwdle:1; -+ uint64_t mre:1; -+ uint64_t rte:1; -+ uint64_t acto:1; -+ uint64_t rvdm:1; -+ uint64_t rumep:1; -+ uint64_t rptamrc:1; -+ uint64_t rpmerc:1; -+ uint64_t rfemrc:1; -+ uint64_t rnfemrc:1; -+ uint64_t rcemrc:1; -+ uint64_t rpoison:1; -+ uint64_t recrce:1; -+ uint64_t rtlplle:1; -+ uint64_t rtlpmal:1; -+ uint64_t spoison:1; -+ } s; -+ struct cvmx_pescx_dbg_info_s cn52xx; -+ struct cvmx_pescx_dbg_info_s cn52xxp1; -+ struct cvmx_pescx_dbg_info_s cn56xx; -+ struct cvmx_pescx_dbg_info_s cn56xxp1; -+}; -+ -+union cvmx_pescx_dbg_info_en { -+ uint64_t u64; -+ struct cvmx_pescx_dbg_info_en_s { -+ uint64_t reserved_31_63:33; -+ uint64_t ecrc_e:1; -+ uint64_t rawwpp:1; -+ uint64_t racpp:1; -+ uint64_t ramtlp:1; -+ uint64_t rarwdns:1; -+ uint64_t caar:1; -+ uint64_t racca:1; -+ uint64_t racur:1; -+ uint64_t rauc:1; -+ uint64_t rqo:1; -+ uint64_t fcuv:1; -+ uint64_t rpe:1; -+ uint64_t fcpvwt:1; -+ uint64_t dpeoosd:1; -+ uint64_t rtwdle:1; -+ uint64_t rdwdle:1; -+ uint64_t mre:1; -+ uint64_t rte:1; -+ uint64_t acto:1; -+ uint64_t rvdm:1; -+ uint64_t rumep:1; -+ uint64_t rptamrc:1; -+ uint64_t rpmerc:1; -+ uint64_t rfemrc:1; -+ uint64_t rnfemrc:1; -+ uint64_t rcemrc:1; -+ uint64_t rpoison:1; -+ uint64_t recrce:1; -+ uint64_t rtlplle:1; -+ uint64_t rtlpmal:1; -+ uint64_t spoison:1; -+ } s; -+ struct cvmx_pescx_dbg_info_en_s cn52xx; -+ struct cvmx_pescx_dbg_info_en_s cn52xxp1; -+ struct cvmx_pescx_dbg_info_en_s cn56xx; -+ struct cvmx_pescx_dbg_info_en_s cn56xxp1; -+}; -+ -+union cvmx_pescx_diag_status { -+ uint64_t u64; -+ struct cvmx_pescx_diag_status_s { -+ uint64_t reserved_4_63:60; -+ uint64_t pm_dst:1; -+ uint64_t pm_stat:1; -+ uint64_t pm_en:1; -+ uint64_t aux_en:1; -+ } s; -+ struct cvmx_pescx_diag_status_s cn52xx; -+ struct cvmx_pescx_diag_status_s cn52xxp1; -+ struct cvmx_pescx_diag_status_s cn56xx; -+ struct cvmx_pescx_diag_status_s cn56xxp1; -+}; -+ -+union cvmx_pescx_p2n_bar0_start { -+ uint64_t u64; -+ struct cvmx_pescx_p2n_bar0_start_s { -+ uint64_t addr:50; -+ uint64_t reserved_0_13:14; -+ } s; -+ struct cvmx_pescx_p2n_bar0_start_s cn52xx; -+ struct cvmx_pescx_p2n_bar0_start_s cn52xxp1; -+ struct cvmx_pescx_p2n_bar0_start_s cn56xx; -+ struct cvmx_pescx_p2n_bar0_start_s cn56xxp1; -+}; -+ -+union cvmx_pescx_p2n_bar1_start { -+ uint64_t u64; -+ struct cvmx_pescx_p2n_bar1_start_s { -+ uint64_t addr:38; -+ uint64_t reserved_0_25:26; -+ } s; -+ struct cvmx_pescx_p2n_bar1_start_s cn52xx; -+ struct cvmx_pescx_p2n_bar1_start_s cn52xxp1; -+ struct cvmx_pescx_p2n_bar1_start_s cn56xx; -+ struct cvmx_pescx_p2n_bar1_start_s cn56xxp1; -+}; -+ -+union cvmx_pescx_p2n_bar2_start { -+ uint64_t u64; -+ struct cvmx_pescx_p2n_bar2_start_s { -+ uint64_t addr:25; -+ uint64_t reserved_0_38:39; -+ } s; -+ struct cvmx_pescx_p2n_bar2_start_s cn52xx; -+ struct cvmx_pescx_p2n_bar2_start_s cn52xxp1; -+ struct cvmx_pescx_p2n_bar2_start_s cn56xx; -+ struct cvmx_pescx_p2n_bar2_start_s cn56xxp1; -+}; -+ -+union cvmx_pescx_p2p_barx_end { -+ uint64_t u64; -+ struct cvmx_pescx_p2p_barx_end_s { -+ uint64_t addr:52; -+ uint64_t reserved_0_11:12; -+ } s; -+ struct cvmx_pescx_p2p_barx_end_s cn52xx; -+ struct cvmx_pescx_p2p_barx_end_s cn52xxp1; -+ struct cvmx_pescx_p2p_barx_end_s cn56xx; -+ struct cvmx_pescx_p2p_barx_end_s cn56xxp1; -+}; -+ -+union cvmx_pescx_p2p_barx_start { -+ uint64_t u64; -+ struct cvmx_pescx_p2p_barx_start_s { -+ uint64_t addr:52; -+ uint64_t reserved_0_11:12; -+ } s; -+ struct cvmx_pescx_p2p_barx_start_s cn52xx; -+ struct cvmx_pescx_p2p_barx_start_s cn52xxp1; -+ struct cvmx_pescx_p2p_barx_start_s cn56xx; -+ struct cvmx_pescx_p2p_barx_start_s cn56xxp1; -+}; -+ -+union cvmx_pescx_tlp_credits { -+ uint64_t u64; -+ struct cvmx_pescx_tlp_credits_s { -+ uint64_t reserved_0_63:64; -+ } s; -+ struct cvmx_pescx_tlp_credits_cn52xx { -+ uint64_t reserved_56_63:8; -+ uint64_t peai_ppf:8; -+ uint64_t pesc_cpl:8; -+ uint64_t pesc_np:8; -+ uint64_t pesc_p:8; -+ uint64_t npei_cpl:8; -+ uint64_t npei_np:8; -+ uint64_t npei_p:8; -+ } cn52xx; -+ struct cvmx_pescx_tlp_credits_cn52xxp1 { -+ uint64_t reserved_38_63:26; -+ uint64_t peai_ppf:8; -+ uint64_t pesc_cpl:5; -+ uint64_t pesc_np:5; -+ uint64_t pesc_p:5; -+ uint64_t npei_cpl:5; -+ uint64_t npei_np:5; -+ uint64_t npei_p:5; -+ } cn52xxp1; -+ struct cvmx_pescx_tlp_credits_cn52xx cn56xx; -+ struct cvmx_pescx_tlp_credits_cn52xxp1 cn56xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h -@@ -0,0 +1,229 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * cvmx-pexp-defs.h -+ * -+ * Configuration and status register (CSR) definitions for -+ * OCTEON PEXP. -+ * -+ */ -+#ifndef __CVMX_PEXP_DEFS_H__ -+#define __CVMX_PEXP_DEFS_H__ -+ -+#define CVMX_PEXP_NPEI_BAR1_INDEXX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000008000ull + (((offset) & 31) * 16)) -+#define CVMX_PEXP_NPEI_BIST_STATUS \ -+ CVMX_ADD_IO_SEG(0x00011F0000008580ull) -+#define CVMX_PEXP_NPEI_BIST_STATUS2 \ -+ CVMX_ADD_IO_SEG(0x00011F0000008680ull) -+#define CVMX_PEXP_NPEI_CTL_PORT0 \ -+ CVMX_ADD_IO_SEG(0x00011F0000008250ull) -+#define CVMX_PEXP_NPEI_CTL_PORT1 \ -+ CVMX_ADD_IO_SEG(0x00011F0000008260ull) -+#define CVMX_PEXP_NPEI_CTL_STATUS \ -+ CVMX_ADD_IO_SEG(0x00011F0000008570ull) -+#define CVMX_PEXP_NPEI_CTL_STATUS2 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BC00ull) -+#define CVMX_PEXP_NPEI_DATA_OUT_CNT \ -+ CVMX_ADD_IO_SEG(0x00011F00000085F0ull) -+#define CVMX_PEXP_NPEI_DBG_DATA \ -+ CVMX_ADD_IO_SEG(0x00011F0000008510ull) -+#define CVMX_PEXP_NPEI_DBG_SELECT \ -+ CVMX_ADD_IO_SEG(0x00011F0000008500ull) -+#define CVMX_PEXP_NPEI_DMA0_INT_LEVEL \ -+ CVMX_ADD_IO_SEG(0x00011F00000085C0ull) -+#define CVMX_PEXP_NPEI_DMA1_INT_LEVEL \ -+ CVMX_ADD_IO_SEG(0x00011F00000085D0ull) -+#define CVMX_PEXP_NPEI_DMAX_COUNTS(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000008450ull + (((offset) & 7) * 16)) -+#define CVMX_PEXP_NPEI_DMAX_DBELL(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F00000083B0ull + (((offset) & 7) * 16)) -+#define CVMX_PEXP_NPEI_DMAX_IBUFF_SADDR(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000008400ull + (((offset) & 7) * 16)) -+#define CVMX_PEXP_NPEI_DMAX_NADDR(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F00000084A0ull + (((offset) & 7) * 16)) -+#define CVMX_PEXP_NPEI_DMA_CNTS \ -+ CVMX_ADD_IO_SEG(0x00011F00000085E0ull) -+#define CVMX_PEXP_NPEI_DMA_CONTROL \ -+ CVMX_ADD_IO_SEG(0x00011F00000083A0ull) -+#define CVMX_PEXP_NPEI_INT_A_ENB \ -+ CVMX_ADD_IO_SEG(0x00011F0000008560ull) -+#define CVMX_PEXP_NPEI_INT_A_ENB2 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BCE0ull) -+#define CVMX_PEXP_NPEI_INT_A_SUM \ -+ CVMX_ADD_IO_SEG(0x00011F0000008550ull) -+#define CVMX_PEXP_NPEI_INT_ENB \ -+ CVMX_ADD_IO_SEG(0x00011F0000008540ull) -+#define CVMX_PEXP_NPEI_INT_ENB2 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BCD0ull) -+#define CVMX_PEXP_NPEI_INT_INFO \ -+ CVMX_ADD_IO_SEG(0x00011F0000008590ull) -+#define CVMX_PEXP_NPEI_INT_SUM \ -+ CVMX_ADD_IO_SEG(0x00011F0000008530ull) -+#define CVMX_PEXP_NPEI_INT_SUM2 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BCC0ull) -+#define CVMX_PEXP_NPEI_LAST_WIN_RDATA0 \ -+ CVMX_ADD_IO_SEG(0x00011F0000008600ull) -+#define CVMX_PEXP_NPEI_LAST_WIN_RDATA1 \ -+ CVMX_ADD_IO_SEG(0x00011F0000008610ull) -+#define CVMX_PEXP_NPEI_MEM_ACCESS_CTL \ -+ CVMX_ADD_IO_SEG(0x00011F00000084F0ull) -+#define CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000008280ull + (((offset) & 31) * 16) - 16 * 12) -+#define CVMX_PEXP_NPEI_MSI_ENB0 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BC50ull) -+#define CVMX_PEXP_NPEI_MSI_ENB1 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BC60ull) -+#define CVMX_PEXP_NPEI_MSI_ENB2 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BC70ull) -+#define CVMX_PEXP_NPEI_MSI_ENB3 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BC80ull) -+#define CVMX_PEXP_NPEI_MSI_RCV0 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BC10ull) -+#define CVMX_PEXP_NPEI_MSI_RCV1 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BC20ull) -+#define CVMX_PEXP_NPEI_MSI_RCV2 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BC30ull) -+#define CVMX_PEXP_NPEI_MSI_RCV3 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BC40ull) -+#define CVMX_PEXP_NPEI_MSI_RD_MAP \ -+ CVMX_ADD_IO_SEG(0x00011F000000BCA0ull) -+#define CVMX_PEXP_NPEI_MSI_W1C_ENB0 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BCF0ull) -+#define CVMX_PEXP_NPEI_MSI_W1C_ENB1 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BD00ull) -+#define CVMX_PEXP_NPEI_MSI_W1C_ENB2 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BD10ull) -+#define CVMX_PEXP_NPEI_MSI_W1C_ENB3 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BD20ull) -+#define CVMX_PEXP_NPEI_MSI_W1S_ENB0 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BD30ull) -+#define CVMX_PEXP_NPEI_MSI_W1S_ENB1 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BD40ull) -+#define CVMX_PEXP_NPEI_MSI_W1S_ENB2 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BD50ull) -+#define CVMX_PEXP_NPEI_MSI_W1S_ENB3 \ -+ CVMX_ADD_IO_SEG(0x00011F000000BD60ull) -+#define CVMX_PEXP_NPEI_MSI_WR_MAP \ -+ CVMX_ADD_IO_SEG(0x00011F000000BC90ull) -+#define CVMX_PEXP_NPEI_PCIE_CREDIT_CNT \ -+ CVMX_ADD_IO_SEG(0x00011F000000BD70ull) -+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV \ -+ CVMX_ADD_IO_SEG(0x00011F000000BCB0ull) -+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B1 \ -+ CVMX_ADD_IO_SEG(0x00011F0000008650ull) -+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B2 \ -+ CVMX_ADD_IO_SEG(0x00011F0000008660ull) -+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B3 \ -+ CVMX_ADD_IO_SEG(0x00011F0000008670ull) -+#define CVMX_PEXP_NPEI_PKTX_CNTS(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F000000A400ull + (((offset) & 31) * 16)) -+#define CVMX_PEXP_NPEI_PKTX_INSTR_BADDR(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F000000A800ull + (((offset) & 31) * 16)) -+#define CVMX_PEXP_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F000000AC00ull + (((offset) & 31) * 16)) -+#define CVMX_PEXP_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F000000B000ull + (((offset) & 31) * 16)) -+#define CVMX_PEXP_NPEI_PKTX_INSTR_HEADER(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F000000B400ull + (((offset) & 31) * 16)) -+#define CVMX_PEXP_NPEI_PKTX_IN_BP(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F000000B800ull + (((offset) & 31) * 16)) -+#define CVMX_PEXP_NPEI_PKTX_SLIST_BADDR(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000009400ull + (((offset) & 31) * 16)) -+#define CVMX_PEXP_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000009800ull + (((offset) & 31) * 16)) -+#define CVMX_PEXP_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F0000009C00ull + (((offset) & 31) * 16)) -+#define CVMX_PEXP_NPEI_PKT_CNT_INT \ -+ CVMX_ADD_IO_SEG(0x00011F0000009110ull) -+#define CVMX_PEXP_NPEI_PKT_CNT_INT_ENB \ -+ CVMX_ADD_IO_SEG(0x00011F0000009130ull) -+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ES \ -+ CVMX_ADD_IO_SEG(0x00011F00000090B0ull) -+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_NS \ -+ CVMX_ADD_IO_SEG(0x00011F00000090A0ull) -+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ROR \ -+ CVMX_ADD_IO_SEG(0x00011F0000009090ull) -+#define CVMX_PEXP_NPEI_PKT_DPADDR \ -+ CVMX_ADD_IO_SEG(0x00011F0000009080ull) -+#define CVMX_PEXP_NPEI_PKT_INPUT_CONTROL \ -+ CVMX_ADD_IO_SEG(0x00011F0000009150ull) -+#define CVMX_PEXP_NPEI_PKT_INSTR_ENB \ -+ CVMX_ADD_IO_SEG(0x00011F0000009000ull) -+#define CVMX_PEXP_NPEI_PKT_INSTR_RD_SIZE \ -+ CVMX_ADD_IO_SEG(0x00011F0000009190ull) -+#define CVMX_PEXP_NPEI_PKT_INSTR_SIZE \ -+ CVMX_ADD_IO_SEG(0x00011F0000009020ull) -+#define CVMX_PEXP_NPEI_PKT_INT_LEVELS \ -+ CVMX_ADD_IO_SEG(0x00011F0000009100ull) -+#define CVMX_PEXP_NPEI_PKT_IN_BP \ -+ CVMX_ADD_IO_SEG(0x00011F00000086B0ull) -+#define CVMX_PEXP_NPEI_PKT_IN_DONEX_CNTS(offset) \ -+ CVMX_ADD_IO_SEG(0x00011F000000A000ull + (((offset) & 31) * 16)) -+#define CVMX_PEXP_NPEI_PKT_IN_INSTR_COUNTS \ -+ CVMX_ADD_IO_SEG(0x00011F00000086A0ull) -+#define CVMX_PEXP_NPEI_PKT_IN_PCIE_PORT \ -+ CVMX_ADD_IO_SEG(0x00011F00000091A0ull) -+#define CVMX_PEXP_NPEI_PKT_IPTR \ -+ CVMX_ADD_IO_SEG(0x00011F0000009070ull) -+#define CVMX_PEXP_NPEI_PKT_OUTPUT_WMARK \ -+ CVMX_ADD_IO_SEG(0x00011F0000009160ull) -+#define CVMX_PEXP_NPEI_PKT_OUT_BMODE \ -+ CVMX_ADD_IO_SEG(0x00011F00000090D0ull) -+#define CVMX_PEXP_NPEI_PKT_OUT_ENB \ -+ CVMX_ADD_IO_SEG(0x00011F0000009010ull) -+#define CVMX_PEXP_NPEI_PKT_PCIE_PORT \ -+ CVMX_ADD_IO_SEG(0x00011F00000090E0ull) -+#define CVMX_PEXP_NPEI_PKT_PORT_IN_RST \ -+ CVMX_ADD_IO_SEG(0x00011F0000008690ull) -+#define CVMX_PEXP_NPEI_PKT_SLIST_ES \ -+ CVMX_ADD_IO_SEG(0x00011F0000009050ull) -+#define CVMX_PEXP_NPEI_PKT_SLIST_ID_SIZE \ -+ CVMX_ADD_IO_SEG(0x00011F0000009180ull) -+#define CVMX_PEXP_NPEI_PKT_SLIST_NS \ -+ CVMX_ADD_IO_SEG(0x00011F0000009040ull) -+#define CVMX_PEXP_NPEI_PKT_SLIST_ROR \ -+ CVMX_ADD_IO_SEG(0x00011F0000009030ull) -+#define CVMX_PEXP_NPEI_PKT_TIME_INT \ -+ CVMX_ADD_IO_SEG(0x00011F0000009120ull) -+#define CVMX_PEXP_NPEI_PKT_TIME_INT_ENB \ -+ CVMX_ADD_IO_SEG(0x00011F0000009140ull) -+#define CVMX_PEXP_NPEI_RSL_INT_BLOCKS \ -+ CVMX_ADD_IO_SEG(0x00011F0000008520ull) -+#define CVMX_PEXP_NPEI_SCRATCH_1 \ -+ CVMX_ADD_IO_SEG(0x00011F0000008270ull) -+#define CVMX_PEXP_NPEI_STATE1 \ -+ CVMX_ADD_IO_SEG(0x00011F0000008620ull) -+#define CVMX_PEXP_NPEI_STATE2 \ -+ CVMX_ADD_IO_SEG(0x00011F0000008630ull) -+#define CVMX_PEXP_NPEI_STATE3 \ -+ CVMX_ADD_IO_SEG(0x00011F0000008640ull) -+#define CVMX_PEXP_NPEI_WINDOW_CTL \ -+ CVMX_ADD_IO_SEG(0x00011F0000008380ull) -+ -+#endif diff --git a/target/linux/octeon/patches-2.6.30/003_pci_pcie_support.patch b/target/linux/octeon/patches-2.6.30/003_pci_pcie_support.patch deleted file mode 100644 index 32ba634c38..0000000000 --- a/target/linux/octeon/patches-2.6.30/003_pci_pcie_support.patch +++ /dev/null @@ -1,5002 +0,0 @@ -This patch adds support for PCI and PCIe to the base Cavium OCTEON -processor support. - -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - arch/mips/Kconfig | 2 + - arch/mips/cavium-octeon/Makefile | 4 + - arch/mips/cavium-octeon/dma-octeon.c | 310 ++++++- - arch/mips/cavium-octeon/executive/Makefile | 2 + - .../cavium-octeon/executive/cvmx-helper-errata.c | 379 +++++++ - .../cavium-octeon/executive/cvmx-helper-util.c | 502 ++++++++++ - arch/mips/cavium-octeon/executive/cvmx-pcie.c | 1053 ++++++++++++++++++++ - arch/mips/cavium-octeon/msi.c | 288 ++++++ - arch/mips/cavium-octeon/octeon-irq.c | 2 + - arch/mips/cavium-octeon/pci-common.c | 137 +++ - arch/mips/cavium-octeon/pci-common.h | 39 + - arch/mips/cavium-octeon/pci.c | 568 +++++++++++ - arch/mips/cavium-octeon/pcie.c | 441 ++++++++ - arch/mips/include/asm/octeon/cvmx-asm.h | 3 +- - arch/mips/include/asm/octeon/cvmx-helper-errata.h | 92 ++ - arch/mips/include/asm/octeon/cvmx-helper-util.h | 266 +++++ - arch/mips/include/asm/octeon/cvmx-packet.h | 16 +- - arch/mips/include/asm/octeon/cvmx-pcie.h | 284 ++++++ - arch/mips/include/asm/octeon/cvmx-wqe.h | 422 ++++++++ - arch/mips/include/asm/octeon/cvmx.h | 12 + - arch/mips/include/asm/octeon/octeon.h | 2 + - 21 files changed, 4816 insertions(+), 8 deletions(-) - create mode 100644 arch/mips/cavium-octeon/executive/cvmx-helper-errata.c - create mode 100644 arch/mips/cavium-octeon/executive/cvmx-helper-util.c - create mode 100644 arch/mips/cavium-octeon/executive/cvmx-pcie.c - create mode 100644 arch/mips/cavium-octeon/msi.c - create mode 100644 arch/mips/cavium-octeon/pci-common.c - create mode 100644 arch/mips/cavium-octeon/pci-common.h - create mode 100644 arch/mips/cavium-octeon/pci.c - create mode 100644 arch/mips/cavium-octeon/pcie.c - create mode 100644 arch/mips/include/asm/octeon/cvmx-helper-errata.h - create mode 100644 arch/mips/include/asm/octeon/cvmx-helper-util.h - create mode 100644 arch/mips/include/asm/octeon/cvmx-pcie.h - create mode 100644 arch/mips/include/asm/octeon/cvmx-wqe.h - ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -618,6 +618,8 @@ config CAVIUM_OCTEON_REFERENCE_BOARD - select SYS_HAS_EARLY_PRINTK - select SYS_HAS_CPU_CAVIUM_OCTEON - select SWAP_IO_SPACE -+ select HW_HAS_PCI -+ select ARCH_SUPPORTS_MSI - help - This option supports all of the Octeon reference boards from Cavium - Networks. It builds a kernel that dynamically determines the Octeon ---- a/arch/mips/cavium-octeon/Makefile -+++ b/arch/mips/cavium-octeon/Makefile -@@ -14,5 +14,9 @@ obj-y += dma-octeon.o flash_setup.o - obj-y += octeon-memcpy.o - - obj-$(CONFIG_SMP) += smp.o -+obj-$(CONFIG_PCI) += pci-common.o -+obj-$(CONFIG_PCI) += pci.o -+obj-$(CONFIG_PCI) += pcie.o -+obj-$(CONFIG_PCI_MSI) += msi.o - - EXTRA_CFLAGS += -Werror ---- a/arch/mips/cavium-octeon/dma-octeon.c -+++ b/arch/mips/cavium-octeon/dma-octeon.c -@@ -13,20 +13,326 @@ - */ - #include <linux/types.h> - #include <linux/mm.h> -+#include <linux/module.h> -+#include <linux/string.h> -+#include <linux/dma-mapping.h> -+#include <linux/platform_device.h> -+#include <linux/scatterlist.h> -+ -+#include <linux/cache.h> -+#include <linux/io.h> -+ -+#include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-npi-defs.h> -+#include <asm/octeon/cvmx-pci-defs.h> - - #include <dma-coherence.h> - -+#ifdef CONFIG_PCI -+#include "pci-common.h" -+#endif -+ -+#define BAR2_PCI_ADDRESS 0x8000000000ul -+ -+struct bar1_index_state { -+ int16_t ref_count; /* Number of PCI mappings using this index */ -+ uint16_t address_bits; /* Upper bits of physical address. This is -+ shifted 22 bits */ -+}; -+ -+#ifdef CONFIG_PCI -+static DEFINE_SPINLOCK(bar1_lock); -+static struct bar1_index_state bar1_state[32]; -+#endif -+ - dma_addr_t octeon_map_dma_mem(struct device *dev, void *ptr, size_t size) - { -+#ifndef CONFIG_PCI - /* Without PCI/PCIe this function can be called for Octeon internal - devices such as USB. These devices all support 64bit addressing */ - mb(); - return virt_to_phys(ptr); -+#else -+ unsigned long flags; -+ uint64_t dma_mask; -+ int64_t start_index; -+ dma_addr_t result = -1; -+ uint64_t physical = virt_to_phys(ptr); -+ int64_t index; -+ -+ mb(); -+ /* -+ * Use the DMA masks to determine the allowed memory -+ * region. For us it doesn't limit the actual memory, just the -+ * address visible over PCI. Devices with limits need to use -+ * lower indexed Bar1 entries. -+ */ -+ if (dev) { -+ dma_mask = dev->coherent_dma_mask; -+ if (dev->dma_mask) -+ dma_mask = *dev->dma_mask; -+ } else -+ dma_mask = 0xfffffffful; -+ -+ /* -+ * Platform devices, such as the internal USB, skip all -+ * translation and use Octeon physical addresses directly. -+ */ -+ if (dev->bus == &platform_bus_type) -+ return physical; -+ -+ switch (octeon_dma_bar_type) { -+ case OCTEON_DMA_BAR_TYPE_PCIE: -+ if (unlikely(physical < (16ul << 10))) -+ panic("dma_map_single: Not allowed to map first 16KB." -+ " It interferes with BAR0 special area\n"); -+ else if ((physical + size >= (256ul << 20)) && -+ (physical < (512ul << 20))) -+ panic("dma_map_single: Not allowed to map bootbus\n"); -+ else if ((physical + size >= 0x400000000ull) && -+ physical < 0x410000000ull) -+ panic("dma_map_single: " -+ "Attempt to map illegal memory address 0x%lx\n", -+ physical); -+ else if (physical >= 0x420000000ull) -+ panic("dma_map_single: " -+ "Attempt to map illegal memory address 0x%lx\n", -+ physical); -+ else if ((physical + size >= -+ (4ull<<30) - (OCTEON_PCI_BAR1_HOLE_SIZE<<20)) -+ && physical < (4ull<<30)) -+ pr_warning("dma_map_single: Warning: " -+ "Mapping memory address that might " -+ "conflict with devices 0x%lx-0x%lx\n", -+ physical, physical+size-1); -+ /* The 2nd 256MB is mapped at 256<<20 instead of 0x410000000 */ -+ if ((physical >= 0x410000000ull) && physical < 0x420000000ull) -+ result = physical - 0x400000000ull; -+ else -+ result = physical; -+ if (((result+size-1) & dma_mask) != result+size-1) -+ panic("dma_map_single: Attempt to map address " -+ "0x%lx-0x%lx, which can't be accessed according " -+ "to the dma mask 0x%lx\n", -+ physical, physical+size-1, dma_mask); -+ goto done; -+ -+ case OCTEON_DMA_BAR_TYPE_BIG: -+#ifdef CONFIG_64BIT -+ /* If the device supports 64bit addressing, then use BAR2 */ -+ if (dma_mask > BAR2_PCI_ADDRESS) { -+ result = physical + BAR2_PCI_ADDRESS; -+ goto done; -+ } -+#endif -+ if (unlikely(physical < (4ul << 10))) { -+ panic("dma_map_single: Not allowed to map first 4KB. " -+ "It interferes with BAR0 special area\n"); -+ } else if (physical < (256ul << 20)) { -+ if (unlikely(physical + size > (256ul << 20))) -+ panic("dma_map_single: Requested memory spans " -+ "Bar0 0:256MB and bootbus\n"); -+ result = physical; -+ goto done; -+ } else if (unlikely(physical < (512ul << 20))) { -+ panic("dma_map_single: Not allowed to map bootbus\n"); -+ } else if (physical < (2ul << 30)) { -+ if (unlikely(physical + size > (2ul << 30))) -+ panic("dma_map_single: Requested memory spans " -+ "Bar0 512MB:2GB and BAR1\n"); -+ result = physical; -+ goto done; -+ } else if (physical < (2ul << 30) + (128 << 20)) { -+ /* Fall through */ -+ } else if (physical < -+ (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20)) { -+ if (unlikely -+ (physical + size > -+ (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20))) -+ panic("dma_map_single: Requested memory " -+ "extends past Bar1 (4GB-%luMB)\n", -+ OCTEON_PCI_BAR1_HOLE_SIZE); -+ result = physical; -+ goto done; -+ } else if ((physical >= 0x410000000ull) && -+ (physical < 0x420000000ull)) { -+ if (unlikely(physical + size > 0x420000000ull)) -+ panic("dma_map_single: Requested memory spans " -+ "non existant memory\n"); -+ /* BAR0 fixed mapping 256MB:512MB -> -+ * 16GB+256MB:16GB+512MB */ -+ result = physical - 0x400000000ull; -+ goto done; -+ } else { -+ /* Continued below switch statement */ -+ } -+ break; -+ -+ case OCTEON_DMA_BAR_TYPE_SMALL: -+#ifdef CONFIG_64BIT -+ /* If the device supports 64bit addressing, then use BAR2 */ -+ if (dma_mask > BAR2_PCI_ADDRESS) { -+ result = physical + BAR2_PCI_ADDRESS; -+ goto done; -+ } -+#endif -+ /* Continued below switch statement */ -+ break; -+ -+ default: -+ panic("dma_map_single: Invalid octeon_dma_bar_type\n"); -+ } -+ -+ /* Don't allow mapping to span multiple Bar entries. The hardware guys -+ won't guarantee that DMA across boards work */ -+ if (unlikely((physical >> 22) != ((physical + size - 1) >> 22))) -+ panic("dma_map_single: " -+ "Requested memory spans more than one Bar1 entry\n"); -+ -+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) -+ start_index = 31; -+ else if (unlikely(dma_mask < (1ul << 27))) -+ start_index = (dma_mask >> 22); -+ else -+ start_index = 31; -+ -+ /* Only one processor can access the Bar register at once */ -+ spin_lock_irqsave(&bar1_lock, flags); -+ -+ /* Look through Bar1 for existing mapping that will work */ -+ for (index = start_index; index >= 0; index--) { -+ if ((bar1_state[index].address_bits == physical >> 22) && -+ (bar1_state[index].ref_count)) { -+ /* An existing mapping will work, use it */ -+ bar1_state[index].ref_count++; -+ if (unlikely(bar1_state[index].ref_count < 0)) -+ panic("dma_map_single: " -+ "Bar1[%d] reference count overflowed\n", -+ (int) index); -+ result = (index << 22) | (physical & ((1 << 22) - 1)); -+ /* Large BAR1 is offset at 2GB */ -+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) -+ result += 2ul << 30; -+ goto done_unlock; -+ } -+ } -+ -+ /* No existing mappings, look for a free entry */ -+ for (index = start_index; index >= 0; index--) { -+ if (unlikely(bar1_state[index].ref_count == 0)) { -+ union cvmx_pci_bar1_indexx bar1_index; -+ /* We have a free entry, use it */ -+ bar1_state[index].ref_count = 1; -+ bar1_state[index].address_bits = physical >> 22; -+ bar1_index.u32 = 0; -+ /* Address bits[35:22] sent to L2C */ -+ bar1_index.s.addr_idx = physical >> 22; -+ /* Don't put PCI accesses in L2. */ -+ bar1_index.s.ca = 1; -+ /* Endian Swap Mode */ -+ bar1_index.s.end_swp = 1; -+ /* Set '1' when the selected address range is valid. */ -+ bar1_index.s.addr_v = 1; -+ octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), -+ bar1_index.u32); -+ /* An existing mapping will work, use it */ -+ result = (index << 22) | (physical & ((1 << 22) - 1)); -+ /* Large BAR1 is offset at 2GB */ -+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) -+ result += 2ul << 30; -+ goto done_unlock; -+ } -+ } -+ -+ pr_err("dma_map_single: " -+ "Can't find empty BAR1 index for physical mapping 0x%llx\n", -+ (unsigned long long) physical); -+ -+done_unlock: -+ spin_unlock_irqrestore(&bar1_lock, flags); -+done: -+ pr_debug("dma_map_single 0x%lx->0x%lx\n", physical, result); -+ return result; -+#endif - } - - void octeon_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr) - { -- /* Without PCI/PCIe this function can be called for Octeon internal -- * devices such as USB. These devices all support 64bit addressing */ -+#ifndef CONFIG_PCI -+ /* -+ * Without PCI/PCIe this function can be called for Octeon internal -+ * devices such as USB. These devices all support 64bit addressing. -+ */ -+ return; -+#else -+ unsigned long flags; -+ uint64_t index; -+ -+ /* -+ * Platform devices, such as the internal USB, skip all -+ * translation and use Octeon physical addresses directly. -+ */ -+ if (dev->bus == &platform_bus_type) -+ return; -+ -+ switch (octeon_dma_bar_type) { -+ case OCTEON_DMA_BAR_TYPE_PCIE: -+ /* Nothing to do, all mappings are static */ -+ goto done; -+ -+ case OCTEON_DMA_BAR_TYPE_BIG: -+#ifdef CONFIG_64BIT -+ /* Nothing to do for addresses using BAR2 */ -+ if (dma_addr >= BAR2_PCI_ADDRESS) -+ goto done; -+#endif -+ if (unlikely(dma_addr < (4ul << 10))) -+ panic("dma_unmap_single: Unexpect DMA address 0x%lx\n", -+ dma_addr); -+ else if (dma_addr < (2ul << 30)) -+ /* Nothing to do for addresses using BAR0 */ -+ goto done; -+ else if (dma_addr < (2ul << 30) + (128ul << 20)) -+ /* Need to unmap, fall through */ -+ index = (dma_addr - (2ul << 30)) >> 22; -+ else if (dma_addr < -+ (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20)) -+ goto done; /* Nothing to do for the rest of BAR1 */ -+ else -+ panic("dma_unmap_single: Unexpect DMA address 0x%lx\n", -+ dma_addr); -+ /* Continued below switch statement */ -+ break; -+ -+ case OCTEON_DMA_BAR_TYPE_SMALL: -+#ifdef CONFIG_64BIT -+ /* Nothing to do for addresses using BAR2 */ -+ if (dma_addr >= BAR2_PCI_ADDRESS) -+ goto done; -+#endif -+ index = dma_addr >> 22; -+ /* Continued below switch statement */ -+ break; -+ -+ default: -+ panic("dma_unmap_single: Invalid octeon_dma_bar_type\n"); -+ } -+ -+ if (unlikely(index > 31)) -+ panic("dma_unmap_single: " -+ "Attempt to unmap an invalid address (0x%llx)\n", -+ (unsigned long long) dma_addr); -+ -+ spin_lock_irqsave(&bar1_lock, flags); -+ bar1_state[index].ref_count--; -+ if (bar1_state[index].ref_count == 0) -+ octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0); -+ else if (unlikely(bar1_state[index].ref_count < 0)) -+ panic("dma_unmap_single: Bar1[%u] reference count < 0\n", -+ (int) index); -+ spin_unlock_irqrestore(&bar1_lock, flags); -+done: -+ pr_debug("dma_unmap_single 0x%lx\n", dma_addr); - return; -+#endif - } ---- a/arch/mips/cavium-octeon/executive/Makefile -+++ b/arch/mips/cavium-octeon/executive/Makefile -@@ -11,3 +11,5 @@ - - obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o - -+obj-$(CONFIG_PCI) += cvmx-pcie.o -+obj-$(CONFIG_PCI) += cvmx-helper-errata.o cvmx-helper-util.o ---- /dev/null -+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c -@@ -0,0 +1,379 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * Fixes and workaround for Octeon chip errata. This file -+ * contains functions called by cvmx-helper to workaround known -+ * chip errata. For the most part, code doesn't need to call -+ * these functions directly. -+ * -+ */ -+#include <asm/octeon/octeon.h> -+ -+#include <asm/octeon/cvmx-helper-util.h> -+ -+#ifdef CVMX_ENABLE_PKO_FUNCTIONS -+ -+/** -+ * @INTERNAL -+ * Function to adjust internal IPD pointer alignments -+ * -+ * Returns 0 on success -+ * !0 on failure -+ */ -+int __cvmx_helper_errata_fix_ipd_ptr_alignment(void) -+{ -+#define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \ -+ (CVMX_FPA_PACKET_POOL_SIZE - 8 - CVMX_HELPER_FIRST_MBUFF_SKIP) -+#define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \ -+ (CVMX_FPA_PACKET_POOL_SIZE - 8 - CVMX_HELPER_NOT_FIRST_MBUFF_SKIP) -+#define FIX_IPD_OUTPORT 0 -+ /* Ports 0-15 are interface 0, 16-31 are interface 1 */ -+#define INTERFACE(port) (port >> 4) -+#define INDEX(port) (port & 0xf) -+ uint64_t *p64; -+ cvmx_pko_command_word0_t pko_command; -+ cvmx_buf_ptr_t g_buffer, pkt_buffer; -+ cvmx_wqe_t *work; -+ int size, num_segs = 0, wqe_pcnt, pkt_pcnt; -+ cvmx_gmxx_prtx_cfg_t gmx_cfg; -+ int retry_cnt; -+ int retry_loop_cnt; -+ int mtu; -+ int i; -+ cvmx_helper_link_info_t link_info; -+ -+ /* Save values for restore at end */ -+ uint64_t prtx_cfg = -+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT))); -+ uint64_t tx_ptr_en = -+ cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT))); -+ uint64_t rx_ptr_en = -+ cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT))); -+ uint64_t rxx_jabber = -+ cvmx_read_csr(CVMX_GMXX_RXX_JABBER(INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT))); -+ uint64_t frame_max = -+ cvmx_read_csr(CVMX_GMXX_RXX_FRM_MAX(INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT))); -+ -+ /* Configure port to gig FDX as required for loopback mode */ -+ cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT); -+ -+ /* -+ * Disable reception on all ports so if traffic is present it -+ * will not interfere. -+ */ -+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 0); -+ -+ cvmx_wait(100000000ull); -+ -+ for (retry_loop_cnt = 0; retry_loop_cnt < 10; retry_loop_cnt++) { -+ retry_cnt = 100000; -+ wqe_pcnt = cvmx_read_csr(CVMX_IPD_PTR_COUNT); -+ pkt_pcnt = (wqe_pcnt >> 7) & 0x7f; -+ wqe_pcnt &= 0x7f; -+ -+ num_segs = (2 + pkt_pcnt - wqe_pcnt) & 3; -+ -+ if (num_segs == 0) -+ goto fix_ipd_exit; -+ -+ num_segs += 1; -+ -+ size = -+ FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES + -+ ((num_segs - 1) * FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES) - -+ (FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES / 2); -+ -+ cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), -+ 1 << INDEX(FIX_IPD_OUTPORT)); -+ CVMX_SYNC; -+ -+ g_buffer.u64 = 0; -+ g_buffer.s.addr = -+ cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_WQE_POOL)); -+ if (g_buffer.s.addr == 0) { -+ cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT buffer " -+ "allocation failure.\n"); -+ goto fix_ipd_exit; -+ } -+ -+ g_buffer.s.pool = CVMX_FPA_WQE_POOL; -+ g_buffer.s.size = num_segs; -+ -+ pkt_buffer.u64 = 0; -+ pkt_buffer.s.addr = -+ cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL)); -+ if (pkt_buffer.s.addr == 0) { -+ cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT buffer " -+ "allocation failure.\n"); -+ goto fix_ipd_exit; -+ } -+ pkt_buffer.s.i = 1; -+ pkt_buffer.s.pool = CVMX_FPA_PACKET_POOL; -+ pkt_buffer.s.size = FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES; -+ -+ p64 = (uint64_t *) cvmx_phys_to_ptr(pkt_buffer.s.addr); -+ p64[0] = 0xffffffffffff0000ull; -+ p64[1] = 0x08004510ull; -+ p64[2] = ((uint64_t) (size - 14) << 48) | 0x5ae740004000ull; -+ p64[3] = 0x3a5fc0a81073c0a8ull; -+ -+ for (i = 0; i < num_segs; i++) { -+ if (i > 0) -+ pkt_buffer.s.size = -+ FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES; -+ -+ if (i == (num_segs - 1)) -+ pkt_buffer.s.i = 0; -+ -+ *(uint64_t *) cvmx_phys_to_ptr(g_buffer.s.addr + -+ 8 * i) = pkt_buffer.u64; -+ } -+ -+ /* Build the PKO command */ -+ pko_command.u64 = 0; -+ pko_command.s.segs = num_segs; -+ pko_command.s.total_bytes = size; -+ pko_command.s.dontfree = 0; -+ pko_command.s.gather = 1; -+ -+ gmx_cfg.u64 = -+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG -+ (INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT))); -+ gmx_cfg.s.en = 1; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG -+ (INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT)), gmx_cfg.u64); -+ cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), -+ 1 << INDEX(FIX_IPD_OUTPORT)); -+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), -+ 1 << INDEX(FIX_IPD_OUTPORT)); -+ -+ mtu = -+ cvmx_read_csr(CVMX_GMXX_RXX_JABBER -+ (INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT))); -+ cvmx_write_csr(CVMX_GMXX_RXX_JABBER -+ (INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4); -+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX -+ (INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4); -+ -+#if CVMX_PKO_USE_FAU_FOR_OUTPUT_QUEUES -+ cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT, -+ cvmx_pko_get_base_queue -+ (FIX_IPD_OUTPORT), -+ CVMX_PKO_LOCK_NONE); -+ cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT, -+ cvmx_pko_get_base_queue -+ (FIX_IPD_OUTPORT), pko_command, -+ g_buffer, CVMX_PKO_LOCK_NONE); -+#else -+ cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT, -+ cvmx_pko_get_base_queue -+ (FIX_IPD_OUTPORT), -+ CVMX_PKO_LOCK_CMD_QUEUE); -+ cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT, -+ cvmx_pko_get_base_queue -+ (FIX_IPD_OUTPORT), pko_command, -+ g_buffer, CVMX_PKO_LOCK_CMD_QUEUE); -+#endif -+ CVMX_SYNC; -+ -+ do { -+ work = cvmx_pow_work_request_sync(CVMX_POW_WAIT); -+ retry_cnt--; -+ } while ((work == NULL) && (retry_cnt > 0)); -+ -+ if (!retry_cnt) -+ cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT " -+ "get_work() timeout occured.\n"); -+ -+ /* Free packet */ -+ if (work) -+ cvmx_helper_free_packet_data(work); -+ } -+ -+fix_ipd_exit: -+ -+ /* Return CSR configs to saved values */ -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG -+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)), -+ prtx_cfg); -+ cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), -+ tx_ptr_en); -+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), -+ rx_ptr_en); -+ cvmx_write_csr(CVMX_GMXX_RXX_JABBER -+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)), -+ rxx_jabber); -+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX -+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)), -+ frame_max); -+ cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0); -+ /* Set link to down so autonegotiation will set it up again */ -+ link_info.u64 = 0; -+ cvmx_helper_link_set(FIX_IPD_OUTPORT, link_info); -+ -+ /* -+ * Bring the link back up as autonegotiation is not done in -+ * user applications. -+ */ -+ cvmx_helper_link_autoconf(FIX_IPD_OUTPORT); -+ -+ CVMX_SYNC; -+ if (num_segs) -+ cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n"); -+ -+ return !!num_segs; -+ -+} -+ -+/** -+ * @INTERNAL -+ * Workaround ASX setup errata with CN38XX pass1 -+ * -+ * @interface: Interface to setup -+ * @port: Port to setup (0..3) -+ * @cpu_clock_hz: -+ * Chip frequency in Hertz -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_errata_asx_pass1(int interface, int port, int cpu_clock_hz) -+{ -+ /* Set hi water mark as per errata GMX-4 */ -+ if (cpu_clock_hz >= 325000000 && cpu_clock_hz < 375000000) -+ cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 12); -+ else if (cpu_clock_hz >= 375000000 && cpu_clock_hz < 437000000) -+ cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 11); -+ else if (cpu_clock_hz >= 437000000 && cpu_clock_hz < 550000000) -+ cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 10); -+ else if (cpu_clock_hz >= 550000000 && cpu_clock_hz < 687000000) -+ cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 9); -+ else -+ cvmx_dprintf("Illegal clock frequency (%d). " -+ "CVMX_ASXX_TX_HI_WATERX not set\n", -+ cpu_clock_hz); -+ return 0; -+} -+ -+/** -+ * This function needs to be called on all Octeon chips with -+ * errata PKI-100. -+ * -+ * The Size field is 8 too large in WQE and next pointers -+ * -+ * The Size field generated by IPD is 8 larger than it should -+ * be. The Size field is <55:40> of both: -+ * - WORD3 in the work queue entry, and -+ * - the next buffer pointer (which precedes the packet data -+ * in each buffer). -+ * -+ * @work: Work queue entry to fix -+ * Returns Zero on success. Negative on failure -+ */ -+int cvmx_helper_fix_ipd_packet_chain(cvmx_wqe_t *work) -+{ -+ uint64_t number_buffers = work->word2.s.bufs; -+ -+ /* We only need to do this if the work has buffers */ -+ if (number_buffers) { -+ cvmx_buf_ptr_t buffer_ptr = work->packet_ptr; -+ /* Check for errata PKI-100 */ -+ if ((buffer_ptr.s.pool == 0) && -+ (((uint64_t) buffer_ptr.s.size + -+ ((uint64_t) buffer_ptr.s.back << 7) + -+ ((uint64_t) buffer_ptr.s.addr & 0x7F)) != -+ (CVMX_FPA_PACKET_POOL_SIZE + 8))) { -+ /* fix is not needed */ -+ return 0; -+ } -+ /* Decrement the work packet pointer */ -+ buffer_ptr.s.size -= 8; -+ work->packet_ptr = buffer_ptr; -+ -+ /* -+ * Now loop through decrementing the size for each -+ * additional buffer. -+ */ -+ while (--number_buffers) { -+ /* Chain pointers are 8 bytes before the data */ -+ cvmx_buf_ptr_t *ptr = -+ (cvmx_buf_ptr_t *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8); -+ buffer_ptr = *ptr; -+ buffer_ptr.s.size -= 8; -+ *ptr = buffer_ptr; -+ } -+ } -+ /* -+ * Make sure that these write go out before other operations -+ * such as FPA frees. -+ */ -+ CVMX_SYNCWS; -+ return 0; -+} -+ -+#endif /* CVMX_ENABLE_PKO_FUNCTIONS */ -+ -+/** -+ * Due to errata G-720, the 2nd order CDR circuit on CN52XX pass -+ * 1 doesn't work properly. The following code disables 2nd order -+ * CDR for the specified QLM. -+ * -+ * @qlm: QLM to disable 2nd order CDR for. -+ */ -+void __cvmx_helper_errata_qlm_disable_2nd_order_cdr(int qlm) -+{ -+ int lane; -+ cvmx_helper_qlm_jtag_init(); -+ /* We need to load all four lanes of the QLM, a total of 1072 bits */ -+ for (lane = 0; lane < 4; lane++) { -+ /* -+ * Each lane has 268 bits. We need to set -+ * cfg_cdr_incx<67:64> = 3 and cfg_cdr_secord<77> = -+ * 1. All other bits are zero. Bits go in LSB first, -+ * so start off with the zeros for bits <63:0>. -+ */ -+ cvmx_helper_qlm_jtag_shift_zeros(qlm, 63 - 0 + 1); -+ /* cfg_cdr_incx<67:64>=3 */ -+ cvmx_helper_qlm_jtag_shift(qlm, 67 - 64 + 1, 3); -+ /* Zeros for bits <76:68> */ -+ cvmx_helper_qlm_jtag_shift_zeros(qlm, 76 - 68 + 1); -+ /* cfg_cdr_secord<77>=1 */ -+ cvmx_helper_qlm_jtag_shift(qlm, 77 - 77 + 1, 1); -+ /* Zeros for bits <267:78> */ -+ cvmx_helper_qlm_jtag_shift_zeros(qlm, 267 - 78 + 1); -+ } -+ cvmx_helper_qlm_jtag_update(qlm); -+} ---- /dev/null -+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-util.c -@@ -0,0 +1,502 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * Small helper utilities. -+ * -+ */ -+ -+#include <asm/octeon/octeon.h> -+ -+#include <asm/octeon/cvmx-helper-util.h> -+ -+#ifdef CVMX_ENABLE_HELPER_FUNCTIONS -+ -+/** -+ * Get the version of the CVMX libraries. -+ * -+ * Returns Version string. Note this buffer is allocated statically -+ * and will be shared by all callers. -+ */ -+const char *cvmx_helper_get_version(void) -+{ -+ return OCTEON_SDK_VERSION_STRING; -+} -+ -+/** -+ * Convert a interface mode into a human readable string -+ * -+ * @mode: Mode to convert -+ * -+ * Returns String -+ */ -+const char *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t -+ mode) -+{ -+ switch (mode) { -+ case CVMX_HELPER_INTERFACE_MODE_DISABLED: -+ return "DISABLED"; -+ case CVMX_HELPER_INTERFACE_MODE_RGMII: -+ return "RGMII"; -+ case CVMX_HELPER_INTERFACE_MODE_GMII: -+ return "GMII"; -+ case CVMX_HELPER_INTERFACE_MODE_SPI: -+ return "SPI"; -+ case CVMX_HELPER_INTERFACE_MODE_PCIE: -+ return "PCIE"; -+ case CVMX_HELPER_INTERFACE_MODE_XAUI: -+ return "XAUI"; -+ case CVMX_HELPER_INTERFACE_MODE_SGMII: -+ return "SGMII"; -+ case CVMX_HELPER_INTERFACE_MODE_PICMG: -+ return "PICMG"; -+ case CVMX_HELPER_INTERFACE_MODE_NPI: -+ return "NPI"; -+ case CVMX_HELPER_INTERFACE_MODE_LOOP: -+ return "LOOP"; -+ } -+ return "UNKNOWN"; -+} -+ -+/** -+ * Debug routine to dump the packet structure to the console -+ * -+ * @work: Work queue entry containing the packet to dump -+ */ -+int cvmx_helper_dump_packet(cvmx_wqe_t *work) -+{ -+ uint64_t count; -+ uint64_t remaining_bytes; -+ cvmx_buf_ptr_t buffer_ptr; -+ uint64_t start_of_buffer; -+ uint8_t *data_address; -+ uint8_t *end_of_data; -+ -+ cvmx_dprintf("Packet Length: %u\n", work->len); -+ cvmx_dprintf(" Input Port: %u\n", work->ipprt); -+ cvmx_dprintf(" QoS: %u\n", work->qos); -+ cvmx_dprintf(" Buffers: %u\n", work->word2.s.bufs); -+ -+ if (work->word2.s.bufs == 0) { -+ cvmx_ipd_wqe_fpa_queue_t wqe_pool; -+ wqe_pool.u64 = cvmx_read_csr(CVMX_IPD_WQE_FPA_QUEUE); -+ buffer_ptr.u64 = 0; -+ buffer_ptr.s.pool = wqe_pool.s.wqe_pool; -+ buffer_ptr.s.size = 128; -+ buffer_ptr.s.addr = cvmx_ptr_to_phys(work->packet_data); -+ if (cvmx_likely(!work->word2.s.not_IP)) { -+ if (work->word2.s.is_v6) -+ buffer_ptr.s.addr += 2; -+ else -+ buffer_ptr.s.addr += 6; -+ } -+ } else -+ buffer_ptr = work->packet_ptr; -+ remaining_bytes = work->len; -+ -+ while (remaining_bytes) { -+ start_of_buffer = -+ ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7; -+ cvmx_dprintf(" Buffer Start:%llx\n", -+ (unsigned long long)start_of_buffer); -+ cvmx_dprintf(" Buffer I : %u\n", buffer_ptr.s.i); -+ cvmx_dprintf(" Buffer Back: %u\n", buffer_ptr.s.back); -+ cvmx_dprintf(" Buffer Pool: %u\n", buffer_ptr.s.pool); -+ cvmx_dprintf(" Buffer Data: %llx\n", -+ (unsigned long long)buffer_ptr.s.addr); -+ cvmx_dprintf(" Buffer Size: %u\n", buffer_ptr.s.size); -+ -+ cvmx_dprintf("\t\t"); -+ data_address = (uint8_t *) cvmx_phys_to_ptr(buffer_ptr.s.addr); -+ end_of_data = data_address + buffer_ptr.s.size; -+ count = 0; -+ while (data_address < end_of_data) { -+ if (remaining_bytes == 0) -+ break; -+ else -+ remaining_bytes--; -+ cvmx_dprintf("%02x", (unsigned int)*data_address); -+ data_address++; -+ if (remaining_bytes && (count == 7)) { -+ cvmx_dprintf("\n\t\t"); -+ count = 0; -+ } else -+ count++; -+ } -+ cvmx_dprintf("\n"); -+ -+ if (remaining_bytes) -+ buffer_ptr = -+ *(cvmx_buf_ptr_t *) cvmx_phys_to_ptr(buffer_ptr.s. -+ addr - 8); -+ } -+ return 0; -+} -+ -+/** -+ * Setup Random Early Drop on a specific input queue -+ * -+ * @queue: Input queue to setup RED on (0-7) -+ * @pass_thresh: -+ * Packets will begin slowly dropping when there are less than -+ * this many packet buffers free in FPA 0. -+ * @drop_thresh: -+ * All incomming packets will be dropped when there are less -+ * than this many free packet buffers in FPA 0. -+ * Returns Zero on success. Negative on failure -+ */ -+int cvmx_helper_setup_red_queue(int queue, int pass_thresh, int drop_thresh) -+{ -+ cvmx_ipd_qos_red_marks_t red_marks; -+ cvmx_ipd_red_quex_param_t red_param; -+ -+ /* -+ * Set RED to begin dropping packets when there are -+ * pass_thresh buffers left. It will linearly drop more -+ * packets until reaching drop_thresh buffers. -+ */ -+ red_marks.u64 = 0; -+ red_marks.s.drop = drop_thresh; -+ red_marks.s.pass = pass_thresh; -+ cvmx_write_csr(CVMX_IPD_QOSX_RED_MARKS(queue), red_marks.u64); -+ -+ /* Use the actual queue 0 counter, not the average */ -+ red_param.u64 = 0; -+ red_param.s.prb_con = -+ (255ul << 24) / (red_marks.s.pass - red_marks.s.drop); -+ red_param.s.avg_con = 1; -+ red_param.s.new_con = 255; -+ red_param.s.use_pcnt = 1; -+ cvmx_write_csr(CVMX_IPD_RED_QUEX_PARAM(queue), red_param.u64); -+ return 0; -+} -+ -+/** -+ * Setup Random Early Drop to automatically begin dropping packets. -+ * -+ * @pass_thresh: -+ * Packets will begin slowly dropping when there are less than -+ * this many packet buffers free in FPA 0. -+ * @drop_thresh: -+ * All incomming packets will be dropped when there are less -+ * than this many free packet buffers in FPA 0. -+ * Returns Zero on success. Negative on failure -+ */ -+int cvmx_helper_setup_red(int pass_thresh, int drop_thresh) -+{ -+ cvmx_ipd_portx_bp_page_cnt_t page_cnt; -+ cvmx_ipd_bp_prt_red_end_t ipd_bp_prt_red_end; -+ cvmx_ipd_red_port_enable_t red_port_enable; -+ int queue; -+ int interface; -+ int port; -+ -+ /* Disable backpressure based on queued buffers. It needs SW support */ -+ page_cnt.u64 = 0; -+ page_cnt.s.bp_enb = 0; -+ page_cnt.s.page_cnt = 100; -+ for (interface = 0; interface < 2; interface++) { -+ for (port = cvmx_helper_get_first_ipd_port(interface); -+ port < cvmx_helper_get_last_ipd_port(interface); port++) -+ cvmx_write_csr(CVMX_IPD_PORTX_BP_PAGE_CNT(port), -+ page_cnt.u64); -+ } -+ -+ for (queue = 0; queue < 8; queue++) -+ cvmx_helper_setup_red_queue(queue, pass_thresh, drop_thresh); -+ -+ /* Shutoff the dropping based on the per port page count. SW isn't -+ decrementing it right now */ -+ ipd_bp_prt_red_end.u64 = 0; -+ ipd_bp_prt_red_end.s.prt_enb = 0; -+ cvmx_write_csr(CVMX_IPD_BP_PRT_RED_END, ipd_bp_prt_red_end.u64); -+ -+ red_port_enable.u64 = 0; -+ red_port_enable.s.prt_enb = 0xfffffffffull; -+ red_port_enable.s.avg_dly = 10000; -+ red_port_enable.s.prb_dly = 10000; -+ cvmx_write_csr(CVMX_IPD_RED_PORT_ENABLE, red_port_enable.u64); -+ -+ return 0; -+} -+ -+/** -+ * Setup the common GMX settings that determine the number of -+ * ports. These setting apply to almost all configurations of all -+ * chips. -+ * -+ * @interface: Interface to configure -+ * @num_ports: Number of ports on the interface -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_setup_gmx(int interface, int num_ports) -+{ -+ cvmx_gmxx_tx_prts_t gmx_tx_prts; -+ cvmx_gmxx_rx_prts_t gmx_rx_prts; -+ cvmx_pko_reg_gmx_port_mode_t pko_mode; -+ -+ /* Tell GMX the number of TX ports on this interface */ -+ gmx_tx_prts.u64 = cvmx_read_csr(CVMX_GMXX_TX_PRTS(interface)); -+ gmx_tx_prts.s.prts = num_ports; -+ cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), gmx_tx_prts.u64); -+ -+ /* -+ * Tell GMX the number of RX ports on this interface. This only -+ * applies to *GMII and XAUI ports. -+ */ -+ if (cvmx_helper_interface_get_mode(interface) == -+ CVMX_HELPER_INTERFACE_MODE_RGMII -+ || cvmx_helper_interface_get_mode(interface) == -+ CVMX_HELPER_INTERFACE_MODE_SGMII -+ || cvmx_helper_interface_get_mode(interface) == -+ CVMX_HELPER_INTERFACE_MODE_GMII -+ || cvmx_helper_interface_get_mode(interface) == -+ CVMX_HELPER_INTERFACE_MODE_XAUI) { -+ if (num_ports > 4) { -+ cvmx_dprintf("__cvmx_helper_setup_gmx: " -+ "Illegal num_ports\n"); -+ return -1; -+ } -+ -+ gmx_rx_prts.u64 = cvmx_read_csr(CVMX_GMXX_RX_PRTS(interface)); -+ gmx_rx_prts.s.prts = num_ports; -+ cvmx_write_csr(CVMX_GMXX_RX_PRTS(interface), gmx_rx_prts.u64); -+ } -+ -+ /* Skip setting CVMX_PKO_REG_GMX_PORT_MODE on 30XX and 31XX */ -+ if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN31XX) -+ || OCTEON_IS_MODEL(OCTEON_CN50XX)) -+ return 0; -+ -+ /* Tell PKO the number of ports on this interface */ -+ pko_mode.u64 = cvmx_read_csr(CVMX_PKO_REG_GMX_PORT_MODE); -+ if (interface == 0) { -+ if (num_ports == 1) -+ pko_mode.s.mode0 = 4; -+ else if (num_ports == 2) -+ pko_mode.s.mode0 = 3; -+ else if (num_ports <= 4) -+ pko_mode.s.mode0 = 2; -+ else if (num_ports <= 8) -+ pko_mode.s.mode0 = 1; -+ else -+ pko_mode.s.mode0 = 0; -+ } else { -+ if (num_ports == 1) -+ pko_mode.s.mode1 = 4; -+ else if (num_ports == 2) -+ pko_mode.s.mode1 = 3; -+ else if (num_ports <= 4) -+ pko_mode.s.mode1 = 2; -+ else if (num_ports <= 8) -+ pko_mode.s.mode1 = 1; -+ else -+ pko_mode.s.mode1 = 0; -+ } -+ cvmx_write_csr(CVMX_PKO_REG_GMX_PORT_MODE, pko_mode.u64); -+ return 0; -+} -+ -+/** -+ * Returns the IPD/PKO port number for a port on the given -+ * interface. -+ * -+ * @interface: Interface to use -+ * @port: Port on the interface -+ * -+ * Returns IPD/PKO port number -+ */ -+int cvmx_helper_get_ipd_port(int interface, int port) -+{ -+ switch (interface) { -+ case 0: -+ return port; -+ case 1: -+ return port + 16; -+ case 2: -+ return port + 32; -+ case 3: -+ return port + 36; -+ } -+ return -1; -+} -+ -+#endif /* CVMX_ENABLE_HELPER_FUNCTIONS */ -+ -+/** -+ * Returns the interface number for an IPD/PKO port number. -+ * -+ * @ipd_port: IPD/PKO port number -+ * -+ * Returns Interface number -+ */ -+int cvmx_helper_get_interface_num(int ipd_port) -+{ -+ if (ipd_port < 16) -+ return 0; -+ else if (ipd_port < 32) -+ return 1; -+ else if (ipd_port < 36) -+ return 2; -+ else if (ipd_port < 40) -+ return 3; -+ else -+ cvmx_dprintf("cvmx_helper_get_interface_num: " -+ "Illegal IPD port number\n"); -+ -+ return -1; -+} -+ -+/** -+ * Returns the interface index number for an IPD/PKO port -+ * number. -+ * -+ * @ipd_port: IPD/PKO port number -+ * -+ * Returns Interface index number -+ */ -+int cvmx_helper_get_interface_index_num(int ipd_port) -+{ -+ if (ipd_port < 32) -+ return ipd_port & 15; -+ else if (ipd_port < 36) -+ return ipd_port & 3; -+ else if (ipd_port < 40) -+ return ipd_port & 3; -+ else -+ cvmx_dprintf("cvmx_helper_get_interface_index_num: " -+ "Illegal IPD port number\n"); -+ -+ return -1; -+} -+ -+/** -+ * Initialize the internal QLM JTAG logic to allow programming -+ * of the JTAG chain by the cvmx_helper_qlm_jtag_*() functions. -+ * These functions should only be used at the direction of Cavium -+ * Networks. Programming incorrect values into the JTAG chain -+ * can cause chip damage. -+ */ -+void cvmx_helper_qlm_jtag_init(void) -+{ -+ union cvmx_ciu_qlm_jtgc jtgc; -+ int clock_div = 0; -+ int divisor = cvmx_sysinfo_get()->cpu_clock_hz / (25 * 1000000); -+ divisor = (divisor - 1) >> 2; -+ /* Convert the divisor into a power of 2 shift */ -+ CVMX_CLZ(clock_div, divisor); -+ clock_div = 32 - clock_div; -+ -+ /* -+ * Clock divider for QLM JTAG operations. eclk is divided by -+ * 2^(CLK_DIV + 2). -+ */ -+ jtgc.u64 = 0; -+ jtgc.s.clk_div = clock_div; -+ jtgc.s.mux_sel = 0; -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) -+ jtgc.s.bypass = 0x3; -+ else -+ jtgc.s.bypass = 0xf; -+ cvmx_write_csr(CVMX_CIU_QLM_JTGC, jtgc.u64); -+ cvmx_read_csr(CVMX_CIU_QLM_JTGC); -+} -+ -+/** -+ * Write up to 32bits into the QLM jtag chain. Bits are shifted -+ * into the MSB and out the LSB, so you should shift in the low -+ * order bits followed by the high order bits. The JTAG chain is -+ * 4 * 268 bits long, or 1072. -+ * -+ * @qlm: QLM to shift value into -+ * @bits: Number of bits to shift in (1-32). -+ * @data: Data to shift in. Bit 0 enters the chain first, followed by -+ * bit 1, etc. -+ * -+ * Returns The low order bits of the JTAG chain that shifted out of the -+ * circle. -+ */ -+uint32_t cvmx_helper_qlm_jtag_shift(int qlm, int bits, uint32_t data) -+{ -+ union cvmx_ciu_qlm_jtgd jtgd; -+ jtgd.u64 = 0; -+ jtgd.s.shift = 1; -+ jtgd.s.shft_cnt = bits - 1; -+ jtgd.s.shft_reg = data; -+ if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)) -+ jtgd.s.select = 1 << qlm; -+ cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64); -+ do { -+ jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD); -+ } while (jtgd.s.shift); -+ return jtgd.s.shft_reg >> (32 - bits); -+} -+ -+/** -+ * Shift long sequences of zeros into the QLM JTAG chain. It is -+ * common to need to shift more than 32 bits of zeros into the -+ * chain. This function is a convience wrapper around -+ * cvmx_helper_qlm_jtag_shift() to shift more than 32 bits of -+ * zeros at a time. -+ * -+ * @qlm: QLM to shift zeros into -+ * @bits: -+ */ -+void cvmx_helper_qlm_jtag_shift_zeros(int qlm, int bits) -+{ -+ while (bits > 0) { -+ int n = bits; -+ if (n > 32) -+ n = 32; -+ cvmx_helper_qlm_jtag_shift(qlm, n, 0); -+ bits -= n; -+ } -+} -+ -+/** -+ * Program the QLM JTAG chain into all lanes of the QLM. You must -+ * have already shifted in 268*4, or 1072 bits into the JTAG -+ * chain. Updating invalid values can possibly cause chip damage. -+ * -+ * @qlm: QLM to program -+ */ -+void cvmx_helper_qlm_jtag_update(int qlm) -+{ -+ union cvmx_ciu_qlm_jtgd jtgd; -+ -+ /* Update the new data */ -+ jtgd.u64 = 0; -+ jtgd.s.update = 1; -+ if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)) -+ jtgd.s.select = 1 << qlm; -+ cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64); -+ do { -+ jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD); -+ } while (jtgd.s.update); -+} ---- /dev/null -+++ b/arch/mips/cavium-octeon/executive/cvmx-pcie.c -@@ -0,0 +1,1053 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+ * 02110-1301 USA or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * Interface to PCIe as a host(RC) or target(EP) -+ * -+ */ -+#include <linux/delay.h> -+#include <asm/byteorder.h> -+ -+#include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-npei-defs.h> -+#include <asm/octeon/cvmx-pciercx-defs.h> -+#include <asm/octeon/cvmx-pescx-defs.h> -+#include <asm/octeon/cvmx-pexp-defs.h> -+#include <asm/octeon/cvmx-pcieep-defs.h> -+#include <asm/octeon/cvmx-helper-errata.h> -+#include <asm/octeon/cvmx-pcie.h> -+ -+/** -+ * Return the Core virtual base address for PCIe IO access. IOs are -+ * read/written as an offset from this address. -+ * -+ * @pcie_port: PCIe port the IO is for -+ * -+ * Returns 64bit Octeon IO base address for read/write -+ */ -+uint64_t cvmx_pcie_get_io_base_address(int pcie_port) -+{ -+ union cvmx_pcie_address pcie_addr; -+ pcie_addr.u64 = 0; -+ pcie_addr.io.upper = 0; -+ pcie_addr.io.io = 1; -+ pcie_addr.io.did = 3; -+ pcie_addr.io.subdid = 2; -+ pcie_addr.io.es = 1; -+ pcie_addr.io.port = pcie_port; -+ return pcie_addr.u64; -+} -+ -+/** -+ * Size of the IO address region returned at address -+ * cvmx_pcie_get_io_base_address() -+ * -+ * @pcie_port: PCIe port the IO is for -+ * -+ * Returns Size of the IO window -+ */ -+uint64_t cvmx_pcie_get_io_size(int pcie_port) -+{ -+ return 1ull << 32; -+} -+ -+/** -+ * Return the Core virtual base address for PCIe MEM access. Memory is -+ * read/written as an offset from this address. -+ * -+ * @pcie_port: PCIe port the IO is for -+ * -+ * Returns 64bit Octeon IO base address for read/write -+ */ -+uint64_t cvmx_pcie_get_mem_base_address(int pcie_port) -+{ -+ union cvmx_pcie_address pcie_addr; -+ pcie_addr.u64 = 0; -+ pcie_addr.mem.upper = 0; -+ pcie_addr.mem.io = 1; -+ pcie_addr.mem.did = 3; -+ pcie_addr.mem.subdid = 3 + pcie_port; -+ return pcie_addr.u64; -+} -+ -+/** -+ * Size of the Mem address region returned at address -+ * cvmx_pcie_get_mem_base_address() -+ * -+ * @pcie_port: PCIe port the IO is for -+ * -+ * Returns Size of the Mem window -+ */ -+uint64_t cvmx_pcie_get_mem_size(int pcie_port) -+{ -+ return 1ull << 36; -+} -+ -+/** -+ * Initialize the RC config space CSRs -+ * -+ * @pcie_port: PCIe port to initialize -+ */ -+static void __cvmx_pcie_rc_initialize_config_space(int pcie_port) -+{ -+ union cvmx_pciercx_cfg030 pciercx_cfg030; -+ union cvmx_npei_ctl_status2 npei_ctl_status2; -+ union cvmx_pciercx_cfg070 pciercx_cfg070; -+ union cvmx_pciercx_cfg001 pciercx_cfg001; -+ union cvmx_pciercx_cfg032 pciercx_cfg032; -+ union cvmx_pciercx_cfg006 pciercx_cfg006; -+ union cvmx_pciercx_cfg008 pciercx_cfg008; -+ union cvmx_pciercx_cfg009 pciercx_cfg009; -+ union cvmx_pciercx_cfg010 pciercx_cfg010; -+ union cvmx_pciercx_cfg011 pciercx_cfg011; -+ union cvmx_pciercx_cfg035 pciercx_cfg035; -+ union cvmx_pciercx_cfg075 pciercx_cfg075; -+ union cvmx_pciercx_cfg034 pciercx_cfg034; -+ -+ /* Max Payload Size (PCIE*_CFG030[MPS]) */ -+ /* Max Read Request Size (PCIE*_CFG030[MRRS]) */ -+ /* Relaxed-order, no-snoop enables (PCIE*_CFG030[RO_EN,NS_EN] */ -+ /* Error Message Enables (PCIE*_CFG030[CE_EN,NFE_EN,FE_EN,UR_EN]) */ -+ pciercx_cfg030.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG030(pcie_port)); -+ /* -+ * Max payload size = 128 bytes for best Octeon DMA -+ * performance. -+ */ -+ pciercx_cfg030.s.mps = 0; -+ /* -+ * Max read request size = 128 bytes for best Octeon DMA -+ * performance. -+ */ -+ pciercx_cfg030.s.mrrs = 0; -+ /* Enable relaxed ordering. */ -+ pciercx_cfg030.s.ro_en = 1; -+ /* Enable no snoop. */ -+ pciercx_cfg030.s.ns_en = 1; -+ /* Correctable error reporting enable. */ -+ pciercx_cfg030.s.ce_en = 1; -+ /* Non-fatal error reporting enable. */ -+ pciercx_cfg030.s.nfe_en = 1; -+ /* Fatal error reporting enable. */ -+ pciercx_cfg030.s.fe_en = 1; -+ /* Unsupported request reporting enable. */ -+ pciercx_cfg030.s.ur_en = 1; -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG030(pcie_port), -+ pciercx_cfg030.u32); -+ -+ /* -+ * Max Payload Size (NPEI_CTL_STATUS2[MPS]) must match -+ * PCIE*_CFG030[MPS] -+ * -+ * Max Read Request Size (NPEI_CTL_STATUS2[MRRS]) must not -+ * exceed PCIE*_CFG030[MRRS]. -+ */ -+ npei_ctl_status2.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS2); -+ /* Max payload size = 128 bytes for best Octeon DMA performance */ -+ npei_ctl_status2.s.mps = 0; -+ /* Max read request size = 128 bytes for best Octeon DMA performance */ -+ npei_ctl_status2.s.mrrs = 0; -+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS2, npei_ctl_status2.u64); -+ -+ /* ECRC Generation (PCIE*_CFG070[GE,CE]) */ -+ pciercx_cfg070.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG070(pcie_port)); -+ pciercx_cfg070.s.ge = 1; /* ECRC generation enable. */ -+ pciercx_cfg070.s.ce = 1; /* ECRC check enable. */ -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG070(pcie_port), -+ pciercx_cfg070.u32); -+ -+ /* -+ * Access Enables (PCIE*_CFG001[MSAE,ME]) ME and MSAE should -+ * always be set. -+ * -+ * Interrupt Disable (PCIE*_CFG001[I_DIS]) System Error -+ * Message Enable (PCIE*_CFG001[SEE]) -+ */ -+ pciercx_cfg001.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG001(pcie_port)); -+ pciercx_cfg001.s.msae = 1; /* Memory space enable. */ -+ pciercx_cfg001.s.me = 1; /* Bus master enable. */ -+ pciercx_cfg001.s.i_dis = 1; /* INTx assertion disable. */ -+ pciercx_cfg001.s.see = 1; /* SERR# enable */ -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG001(pcie_port), -+ pciercx_cfg001.u32); -+ -+ /* Advanced Error Recovery Message Enables */ -+ /* (PCIE*_CFG066,PCIE*_CFG067,PCIE*_CFG069) */ -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG066(pcie_port), 0); -+ /* Use CVMX_PCIERCX_CFG067 hardware default */ -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG069(pcie_port), 0); -+ -+ /* Active State Power Management (PCIE*_CFG032[ASLPC]) */ -+ pciercx_cfg032.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port)); -+ pciercx_cfg032.s.aslpc = 0; /* Active state Link PM control. */ -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG032(pcie_port), -+ pciercx_cfg032.u32); -+ -+ /* Entrance Latencies (PCIE*_CFG451[L0EL,L1EL]) */ -+ -+ /* -+ * Link Width Mode (PCIERCn_CFG452[LME]) - Set during -+ * cvmx_pcie_rc_initialize_link() -+ * -+ * Primary Bus Number (PCIERCn_CFG006[PBNUM]) -+ * -+ * We set the primary bus number to 1 so IDT bridges are -+ * happy. They don't like zero. -+ */ -+ pciercx_cfg006.u32 = 0; -+ pciercx_cfg006.s.pbnum = 1; -+ pciercx_cfg006.s.sbnum = 1; -+ pciercx_cfg006.s.subbnum = 1; -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG006(pcie_port), -+ pciercx_cfg006.u32); -+ -+ /* -+ * Memory-mapped I/O BAR (PCIERCn_CFG008) -+ * Most applications should disable the memory-mapped I/O BAR by -+ * setting PCIERCn_CFG008[ML_ADDR] < PCIERCn_CFG008[MB_ADDR] -+ */ -+ pciercx_cfg008.u32 = 0; -+ pciercx_cfg008.s.mb_addr = 0x100; -+ pciercx_cfg008.s.ml_addr = 0; -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG008(pcie_port), -+ pciercx_cfg008.u32); -+ -+ /* -+ * Prefetchable BAR (PCIERCn_CFG009,PCIERCn_CFG010,PCIERCn_CFG011) -+ * Most applications should disable the prefetchable BAR by setting -+ * PCIERCn_CFG011[UMEM_LIMIT],PCIERCn_CFG009[LMEM_LIMIT] < -+ * PCIERCn_CFG010[UMEM_BASE],PCIERCn_CFG009[LMEM_BASE] -+ */ -+ pciercx_cfg009.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG009(pcie_port)); -+ pciercx_cfg010.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG010(pcie_port)); -+ pciercx_cfg011.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG011(pcie_port)); -+ pciercx_cfg009.s.lmem_base = 0x100; -+ pciercx_cfg009.s.lmem_limit = 0; -+ pciercx_cfg010.s.umem_base = 0x100; -+ pciercx_cfg011.s.umem_limit = 0; -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG009(pcie_port), -+ pciercx_cfg009.u32); -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG010(pcie_port), -+ pciercx_cfg010.u32); -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG011(pcie_port), -+ pciercx_cfg011.u32); -+ -+ /* -+ * System Error Interrupt Enables (PCIERCn_CFG035[SECEE,SEFEE,SENFEE]) -+ * PME Interrupt Enables (PCIERCn_CFG035[PMEIE]) -+ */ -+ pciercx_cfg035.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG035(pcie_port)); -+ /* System error on correctable error enable. */ -+ pciercx_cfg035.s.secee = 1; -+ /* System error on fatal error enable. */ -+ pciercx_cfg035.s.sefee = 1; -+ /* System error on non-fatal error enable. */ -+ pciercx_cfg035.s.senfee = 1; -+ /* PME interrupt enable. */ -+ pciercx_cfg035.s.pmeie = 1; -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG035(pcie_port), -+ pciercx_cfg035.u32); -+ -+ /* -+ * Advanced Error Recovery Interrupt Enables -+ * (PCIERCn_CFG075[CERE,NFERE,FERE]) -+ */ -+ pciercx_cfg075.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG075(pcie_port)); -+ /* Correctable error reporting enable. */ -+ pciercx_cfg075.s.cere = 1; -+ /* Non-fatal error reporting enable. */ -+ pciercx_cfg075.s.nfere = 1; -+ /* Fatal error reporting enable. */ -+ pciercx_cfg075.s.fere = 1; -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG075(pcie_port), -+ pciercx_cfg075.u32); -+ -+ /* HP Interrupt Enables (PCIERCn_CFG034[HPINT_EN], -+ * PCIERCn_CFG034[DLLS_EN,CCINT_EN]) -+ */ -+ pciercx_cfg034.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG034(pcie_port)); -+ /* Hot-plug interrupt enable. */ -+ pciercx_cfg034.s.hpint_en = 1; -+ /* Data Link Layer state changed enable */ -+ pciercx_cfg034.s.dlls_en = 1; -+ /* Command completed interrupt enable. */ -+ pciercx_cfg034.s.ccint_en = 1; -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG034(pcie_port), -+ pciercx_cfg034.u32); -+} -+ -+/** -+ * Initialize a host mode PCIe link. This function takes a PCIe -+ * port from reset to a link up state. Software can then begin -+ * configuring the rest of the link. -+ * -+ * @pcie_port: PCIe port to initialize -+ * -+ * Returns Zero on success -+ */ -+static int __cvmx_pcie_rc_initialize_link(int pcie_port) -+{ -+ uint64_t start_cycle; -+ union cvmx_pescx_ctl_status pescx_ctl_status; -+ union cvmx_pciercx_cfg452 pciercx_cfg452; -+ union cvmx_pciercx_cfg032 pciercx_cfg032; -+ union cvmx_pciercx_cfg448 pciercx_cfg448; -+ -+ /* Set the lane width */ -+ pciercx_cfg452.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG452(pcie_port)); -+ pescx_ctl_status.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS(pcie_port)); -+ if (pescx_ctl_status.s.qlm_cfg == 0) { -+ /* We're in 8 lane (56XX) or 4 lane (54XX) mode */ -+ pciercx_cfg452.s.lme = 0xf; -+ } else { -+ /* We're in 4 lane (56XX) or 2 lane (52XX) mode */ -+ pciercx_cfg452.s.lme = 0x7; -+ } -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG452(pcie_port), -+ pciercx_cfg452.u32); -+ -+ /* -+ * CN52XX pass 1.x has an errata where length mismatches on UR -+ * responses can cause bus errors on 64bit memory -+ * reads. Turning off length error checking fixes this. -+ */ -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) { -+ union cvmx_pciercx_cfg455 pciercx_cfg455; -+ pciercx_cfg455.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, -+ CVMX_PCIERCX_CFG455(pcie_port)); -+ pciercx_cfg455.s.m_cpl_len_err = 1; -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG455(pcie_port), -+ pciercx_cfg455.u32); -+ } -+ -+ /* Lane swap needs to be manually enabled for CN52XX */ -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX) && (pcie_port == 1)) { -+ pescx_ctl_status.s.lane_swp = 1; -+ cvmx_write_csr(CVMX_PESCX_CTL_STATUS(pcie_port), -+ pescx_ctl_status.u64); -+ } -+ -+ /* Bring up the link */ -+ pescx_ctl_status.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS(pcie_port)); -+ pescx_ctl_status.s.lnk_enb = 1; -+ cvmx_write_csr(CVMX_PESCX_CTL_STATUS(pcie_port), pescx_ctl_status.u64); -+ -+ /* -+ * CN52XX pass 1.0: Due to a bug in 2nd order CDR, it needs to -+ * be disabled. -+ */ -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0)) -+ __cvmx_helper_errata_qlm_disable_2nd_order_cdr(0); -+ -+ /* Wait for the link to come up */ -+ cvmx_dprintf("PCIe: Waiting for port %d link\n", pcie_port); -+ start_cycle = cvmx_get_cycle(); -+ do { -+ if (cvmx_get_cycle() - start_cycle > -+ 2 * cvmx_sysinfo_get()->cpu_clock_hz) { -+ cvmx_dprintf("PCIe: Port %d link timeout\n", -+ pcie_port); -+ return -1; -+ } -+ cvmx_wait(10000); -+ pciercx_cfg032.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, -+ CVMX_PCIERCX_CFG032(pcie_port)); -+ } while (pciercx_cfg032.s.dlla == 0); -+ -+ /* Display the link status */ -+ cvmx_dprintf("PCIe: Port %d link active, %d lanes\n", pcie_port, -+ pciercx_cfg032.s.nlw); -+ -+ /* -+ * Update the Replay Time Limit. Empirically, some PCIe -+ * devices take a little longer to respond than expected under -+ * load. As a workaround for this we configure the Replay Time -+ * Limit to the value expected for a 512 byte MPS instead of -+ * our actual 256 byte MPS. The numbers below are directly -+ * from the PCIe spec table 3-4. -+ */ -+ pciercx_cfg448.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG448(pcie_port)); -+ switch (pciercx_cfg032.s.nlw) { -+ case 1: /* 1 lane */ -+ pciercx_cfg448.s.rtl = 1677; -+ break; -+ case 2: /* 2 lanes */ -+ pciercx_cfg448.s.rtl = 867; -+ break; -+ case 4: /* 4 lanes */ -+ pciercx_cfg448.s.rtl = 462; -+ break; -+ case 8: /* 8 lanes */ -+ pciercx_cfg448.s.rtl = 258; -+ break; -+ } -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG448(pcie_port), -+ pciercx_cfg448.u32); -+ -+ return 0; -+} -+ -+/** -+ * Initialize a PCIe port for use in host(RC) mode. It doesn't -+ * enumerate the bus. -+ * -+ * @pcie_port: PCIe port to initialize -+ * -+ * Returns Zero on success -+ */ -+int cvmx_pcie_rc_initialize(int pcie_port) -+{ -+ int i; -+ union cvmx_ciu_soft_prst ciu_soft_prst; -+ union cvmx_pescx_bist_status pescx_bist_status; -+ union cvmx_pescx_bist_status2 pescx_bist_status2; -+ union cvmx_npei_ctl_status npei_ctl_status; -+ union cvmx_npei_mem_access_ctl npei_mem_access_ctl; -+ union cvmx_npei_mem_access_subidx mem_access_subid; -+ union cvmx_npei_dbg_data npei_dbg_data; -+ union cvmx_pescx_ctl_status2 pescx_ctl_status2; -+ -+ /* -+ * Make sure we aren't trying to setup a target mode interface -+ * in host mode. -+ */ -+ npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS); -+ if ((pcie_port == 0) && !npei_ctl_status.s.host_mode) { -+ cvmx_dprintf("PCIe: ERROR: cvmx_pcie_rc_initialize() called " -+ "on port0, but port0 is not in host mode\n"); -+ return -1; -+ } -+ -+ /* -+ * Make sure a CN52XX isn't trying to bring up port 1 when it -+ * is disabled. -+ */ -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) { -+ npei_dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA); -+ if ((pcie_port == 1) && npei_dbg_data.cn52xx.qlm0_link_width) { -+ cvmx_dprintf("PCIe: ERROR: cvmx_pcie_rc_initialize() " -+ "called on port1, but port1 is disabled\n"); -+ return -1; -+ } -+ } -+ -+ /* -+ * PCIe switch arbitration mode. '0' == fixed priority NPEI, -+ * PCIe0, then PCIe1. '1' == round robin. -+ */ -+ npei_ctl_status.s.arb = 1; -+ /* Allow up to 0x20 config retries */ -+ npei_ctl_status.s.cfg_rtry = 0x20; -+ /* -+ * CN52XX pass1.x has an errata where P0_NTAGS and P1_NTAGS -+ * don't reset. -+ */ -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) { -+ npei_ctl_status.s.p0_ntags = 0x20; -+ npei_ctl_status.s.p1_ntags = 0x20; -+ } -+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS, npei_ctl_status.u64); -+ -+ /* Bring the PCIe out of reset */ -+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_EBH5200) { -+ /* -+ * The EBH5200 board swapped the PCIe reset lines on -+ * the board. As a workaround for this bug, we bring -+ * both PCIe ports out of reset at the same time -+ * instead of on separate calls. So for port 0, we -+ * bring both out of reset and do nothing on port 1. -+ */ -+ if (pcie_port == 0) { -+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST); -+ /* -+ * After a chip reset the PCIe will also be in -+ * reset. If it isn't, most likely someone is -+ * trying to init it again without a proper -+ * PCIe reset. -+ */ -+ if (ciu_soft_prst.s.soft_prst == 0) { -+ /* Reset the ports */ -+ ciu_soft_prst.s.soft_prst = 1; -+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, -+ ciu_soft_prst.u64); -+ ciu_soft_prst.u64 = -+ cvmx_read_csr(CVMX_CIU_SOFT_PRST1); -+ ciu_soft_prst.s.soft_prst = 1; -+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, -+ ciu_soft_prst.u64); -+ /* Wait until pcie resets the ports. */ -+ udelay(2000); -+ } -+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1); -+ ciu_soft_prst.s.soft_prst = 0; -+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64); -+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST); -+ ciu_soft_prst.s.soft_prst = 0; -+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64); -+ } -+ } else { -+ /* -+ * The normal case: The PCIe ports are completely -+ * separate and can be brought out of reset -+ * independently. -+ */ -+ if (pcie_port) -+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1); -+ else -+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST); -+ /* -+ * After a chip reset the PCIe will also be in -+ * reset. If it isn't, most likely someone is trying -+ * to init it again without a proper PCIe reset. -+ */ -+ if (ciu_soft_prst.s.soft_prst == 0) { -+ /* Reset the port */ -+ ciu_soft_prst.s.soft_prst = 1; -+ if (pcie_port) -+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, -+ ciu_soft_prst.u64); -+ else -+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, -+ ciu_soft_prst.u64); -+ /* Wait until pcie resets the ports. */ -+ udelay(2000); -+ } -+ if (pcie_port) { -+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1); -+ ciu_soft_prst.s.soft_prst = 0; -+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64); -+ } else { -+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST); -+ ciu_soft_prst.s.soft_prst = 0; -+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64); -+ } -+ } -+ -+ /* -+ * Wait for PCIe reset to complete. Due to errata PCIE-700, we -+ * don't poll PESCX_CTL_STATUS2[PCIERST], but simply wait a -+ * fixed number of cycles. -+ */ -+ cvmx_wait(400000); -+ -+ /* PESCX_BIST_STATUS2[PCLK_RUN] was missing on pass 1 of CN56XX and -+ CN52XX, so we only probe it on newer chips */ -+ if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) -+ && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) { -+ /* Clear PCLK_RUN so we can check if the clock is running */ -+ pescx_ctl_status2.u64 = -+ cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port)); -+ pescx_ctl_status2.s.pclk_run = 1; -+ cvmx_write_csr(CVMX_PESCX_CTL_STATUS2(pcie_port), -+ pescx_ctl_status2.u64); -+ /* -+ * Now that we cleared PCLK_RUN, wait for it to be set -+ * again telling us the clock is running. -+ */ -+ if (CVMX_WAIT_FOR_FIELD64(CVMX_PESCX_CTL_STATUS2(pcie_port), -+ union cvmx_pescx_ctl_status2, -+ pclk_run, ==, 1, 10000)) { -+ cvmx_dprintf("PCIe: Port %d isn't clocked, skipping.\n", -+ pcie_port); -+ return -1; -+ } -+ } -+ -+ /* -+ * Check and make sure PCIe came out of reset. If it doesn't -+ * the board probably hasn't wired the clocks up and the -+ * interface should be skipped. -+ */ -+ pescx_ctl_status2.u64 = -+ cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port)); -+ if (pescx_ctl_status2.s.pcierst) { -+ cvmx_dprintf("PCIe: Port %d stuck in reset, skipping.\n", -+ pcie_port); -+ return -1; -+ } -+ -+ /* -+ * Check BIST2 status. If any bits are set skip this interface. This -+ * is an attempt to catch PCIE-813 on pass 1 parts. -+ */ -+ pescx_bist_status2.u64 = -+ cvmx_read_csr(CVMX_PESCX_BIST_STATUS2(pcie_port)); -+ if (pescx_bist_status2.u64) { -+ cvmx_dprintf("PCIe: Port %d BIST2 failed. Most likely this " -+ "port isn't hooked up, skipping.\n", -+ pcie_port); -+ return -1; -+ } -+ -+ /* Check BIST status */ -+ pescx_bist_status.u64 = -+ cvmx_read_csr(CVMX_PESCX_BIST_STATUS(pcie_port)); -+ if (pescx_bist_status.u64) -+ cvmx_dprintf("PCIe: BIST FAILED for port %d (0x%016llx)\n", -+ pcie_port, CAST64(pescx_bist_status.u64)); -+ -+ /* Initialize the config space CSRs */ -+ __cvmx_pcie_rc_initialize_config_space(pcie_port); -+ -+ /* Bring the link up */ -+ if (__cvmx_pcie_rc_initialize_link(pcie_port)) { -+ cvmx_dprintf -+ ("PCIe: ERROR: cvmx_pcie_rc_initialize_link() failed\n"); -+ return -1; -+ } -+ -+ /* Store merge control (NPEI_MEM_ACCESS_CTL[TIMER,MAX_WORD]) */ -+ npei_mem_access_ctl.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_MEM_ACCESS_CTL); -+ /* Allow 16 words to combine */ -+ npei_mem_access_ctl.s.max_word = 0; -+ /* Wait up to 127 cycles for more data */ -+ npei_mem_access_ctl.s.timer = 127; -+ cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_CTL, npei_mem_access_ctl.u64); -+ -+ /* Setup Mem access SubDIDs */ -+ mem_access_subid.u64 = 0; -+ /* Port the request is sent to. */ -+ mem_access_subid.s.port = pcie_port; -+ /* Due to an errata on pass 1 chips, no merging is allowed. */ -+ mem_access_subid.s.nmerge = 1; -+ /* Endian-swap for Reads. */ -+ mem_access_subid.s.esr = 1; -+ /* Endian-swap for Writes. */ -+ mem_access_subid.s.esw = 1; -+ /* No Snoop for Reads. */ -+ mem_access_subid.s.nsr = 1; -+ /* No Snoop for Writes. */ -+ mem_access_subid.s.nsw = 1; -+ /* Disable Relaxed Ordering for Reads. */ -+ mem_access_subid.s.ror = 0; -+ /* Disable Relaxed Ordering for Writes. */ -+ mem_access_subid.s.row = 0; -+ /* PCIe Adddress Bits <63:34>. */ -+ mem_access_subid.s.ba = 0; -+ -+ /* -+ * Setup mem access 12-15 for port 0, 16-19 for port 1, -+ * supplying 36 bits of address space. -+ */ -+ for (i = 12 + pcie_port * 4; i < 16 + pcie_port * 4; i++) { -+ cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(i), -+ mem_access_subid.u64); -+ /* Set each SUBID to extend the addressable range */ -+ mem_access_subid.s.ba += 1; -+ } -+ -+ /* -+ * Disable the peer to peer forwarding register. This must be -+ * setup by the OS after it enumerates the bus and assigns -+ * addresses to the PCIe busses. -+ */ -+ for (i = 0; i < 4; i++) { -+ cvmx_write_csr(CVMX_PESCX_P2P_BARX_START(i, pcie_port), -1); -+ cvmx_write_csr(CVMX_PESCX_P2P_BARX_END(i, pcie_port), -1); -+ } -+ -+ /* Set Octeon's BAR0 to decode 0-16KB. It overlaps with Bar2 */ -+ cvmx_write_csr(CVMX_PESCX_P2N_BAR0_START(pcie_port), 0); -+ -+ /* -+ * Disable Octeon's BAR1. It isn't needed in RC mode since -+ * BAR2 maps all of memory. BAR2 also maps 256MB-512MB into -+ * the 2nd 256MB of memory. -+ */ -+ cvmx_write_csr(CVMX_PESCX_P2N_BAR1_START(pcie_port), -1); -+ -+ /* -+ * Set Octeon's BAR2 to decode 0-2^39. Bar0 and Bar1 take -+ * precedence where they overlap. It also overlaps with the -+ * device addresses, so make sure the peer to peer forwarding -+ * is set right. -+ */ -+ cvmx_write_csr(CVMX_PESCX_P2N_BAR2_START(pcie_port), 0); -+ -+ /* -+ * Setup BAR2 attributes -+ * -+ * Relaxed Ordering (NPEI_CTL_PORTn[PTLP_RO,CTLP_RO, WAIT_COM]) -+ * - PTLP_RO,CTLP_RO should normally be set (except for debug). -+ * - WAIT_COM=0 will likely work for all applications. -+ * -+ * Load completion relaxed ordering (NPEI_CTL_PORTn[WAITL_COM]). -+ */ -+ if (pcie_port) { -+ union cvmx_npei_ctl_port1 npei_ctl_port; -+ npei_ctl_port.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_PORT1); -+ npei_ctl_port.s.bar2_enb = 1; -+ npei_ctl_port.s.bar2_esx = 1; -+ npei_ctl_port.s.bar2_cax = 0; -+ npei_ctl_port.s.ptlp_ro = 1; -+ npei_ctl_port.s.ctlp_ro = 1; -+ npei_ctl_port.s.wait_com = 0; -+ npei_ctl_port.s.waitl_com = 0; -+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_PORT1, npei_ctl_port.u64); -+ } else { -+ union cvmx_npei_ctl_port0 npei_ctl_port; -+ npei_ctl_port.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_PORT0); -+ npei_ctl_port.s.bar2_enb = 1; -+ npei_ctl_port.s.bar2_esx = 1; -+ npei_ctl_port.s.bar2_cax = 0; -+ npei_ctl_port.s.ptlp_ro = 1; -+ npei_ctl_port.s.ctlp_ro = 1; -+ npei_ctl_port.s.wait_com = 0; -+ npei_ctl_port.s.waitl_com = 0; -+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_PORT0, npei_ctl_port.u64); -+ } -+ return 0; -+} -+ -+/** -+ * Shutdown a PCIe port and put it in reset -+ * -+ * @pcie_port: PCIe port to shutdown -+ * -+ * Returns Zero on success -+ */ -+int cvmx_pcie_rc_shutdown(int pcie_port) -+{ -+ /* Wait for all pending operations to complete */ -+ if (CVMX_WAIT_FOR_FIELD64(CVMX_PESCX_CPL_LUT_VALID(pcie_port), -+ union cvmx_pescx_cpl_lut_valid, -+ tag, ==, 0, 2000)) -+ cvmx_dprintf("PCIe: Port %d shutdown timeout\n", pcie_port); -+ -+ /* Force reset */ -+ if (pcie_port) { -+ union cvmx_ciu_soft_prst ciu_soft_prst; -+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1); -+ ciu_soft_prst.s.soft_prst = 1; -+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64); -+ } else { -+ union cvmx_ciu_soft_prst ciu_soft_prst; -+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST); -+ ciu_soft_prst.s.soft_prst = 1; -+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64); -+ } -+ return 0; -+} -+ -+/** -+ * Build a PCIe config space request address for a device -+ * -+ * @pcie_port: PCIe port to access -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * -+ * Returns 64bit Octeon IO address -+ */ -+static inline uint64_t __cvmx_pcie_build_config_addr(int pcie_port, int bus, -+ int dev, int fn, int reg) -+{ -+ union cvmx_pcie_address pcie_addr; -+ union cvmx_pciercx_cfg006 pciercx_cfg006; -+ -+ pciercx_cfg006.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG006(pcie_port)); -+ if ((bus <= pciercx_cfg006.s.pbnum) && (dev != 0)) -+ return 0; -+ -+ pcie_addr.u64 = 0; -+ pcie_addr.config.upper = 2; -+ pcie_addr.config.io = 1; -+ pcie_addr.config.did = 3; -+ pcie_addr.config.subdid = 1; -+ pcie_addr.config.es = 1; -+ pcie_addr.config.port = pcie_port; -+ pcie_addr.config.ty = (bus > pciercx_cfg006.s.pbnum); -+ pcie_addr.config.bus = bus; -+ pcie_addr.config.dev = dev; -+ pcie_addr.config.func = fn; -+ pcie_addr.config.reg = reg; -+ return pcie_addr.u64; -+} -+ -+/** -+ * Read 8bits from a Device's config space -+ * -+ * @pcie_port: PCIe port the device is on -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * -+ * Returns Result of the read -+ */ -+uint8_t cvmx_pcie_config_read8(int pcie_port, int bus, int dev, -+ int fn, int reg) -+{ -+ uint64_t address = -+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg); -+ if (address) -+ return cvmx_read64_uint8(address); -+ else -+ return 0xff; -+} -+ -+/** -+ * Read 16bits from a Device's config space -+ * -+ * @pcie_port: PCIe port the device is on -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * -+ * Returns Result of the read -+ */ -+uint16_t cvmx_pcie_config_read16(int pcie_port, int bus, int dev, int fn, -+ int reg) -+{ -+ uint64_t address = -+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg); -+ if (address) -+ return le16_to_cpu(cvmx_read64_uint16(address)); -+ else -+ return 0xffff; -+} -+ -+/** -+ * Read 32bits from a Device's config space -+ * -+ * @pcie_port: PCIe port the device is on -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * -+ * Returns Result of the read -+ */ -+uint32_t cvmx_pcie_config_read32(int pcie_port, int bus, int dev, int fn, -+ int reg) -+{ -+ uint64_t address = -+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg); -+ if (address) -+ return le32_to_cpu(cvmx_read64_uint32(address)); -+ else -+ return 0xffffffff; -+} -+ -+/** -+ * Write 8bits to a Device's config space -+ * -+ * @pcie_port: PCIe port the device is on -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * @val: Value to write -+ */ -+void cvmx_pcie_config_write8(int pcie_port, int bus, int dev, int fn, -+ int reg, uint8_t val) -+{ -+ uint64_t address = -+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg); -+ if (address) -+ cvmx_write64_uint8(address, val); -+} -+ -+/** -+ * Write 16bits to a Device's config space -+ * -+ * @pcie_port: PCIe port the device is on -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * @val: Value to write -+ */ -+void cvmx_pcie_config_write16(int pcie_port, int bus, int dev, int fn, -+ int reg, uint16_t val) -+{ -+ uint64_t address = -+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg); -+ if (address) -+ cvmx_write64_uint16(address, cpu_to_le16(val)); -+} -+ -+/** -+ * Write 32bits to a Device's config space -+ * -+ * @pcie_port: PCIe port the device is on -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * @val: Value to write -+ */ -+void cvmx_pcie_config_write32(int pcie_port, int bus, int dev, int fn, -+ int reg, uint32_t val) -+{ -+ uint64_t address = -+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg); -+ if (address) -+ cvmx_write64_uint32(address, cpu_to_le32(val)); -+} -+ -+/** -+ * Read a PCIe config space register indirectly. This is used for -+ * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???. -+ * -+ * @pcie_port: PCIe port to read from -+ * @cfg_offset: Address to read -+ * -+ * Returns Value read -+ */ -+uint32_t cvmx_pcie_cfgx_read(int pcie_port, uint32_t cfg_offset) -+{ -+ union cvmx_pescx_cfg_rd pescx_cfg_rd; -+ pescx_cfg_rd.u64 = 0; -+ pescx_cfg_rd.s.addr = cfg_offset; -+ cvmx_write_csr(CVMX_PESCX_CFG_RD(pcie_port), pescx_cfg_rd.u64); -+ pescx_cfg_rd.u64 = cvmx_read_csr(CVMX_PESCX_CFG_RD(pcie_port)); -+ return pescx_cfg_rd.s.data; -+} -+ -+/** -+ * Write a PCIe config space register indirectly. This is used for -+ * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???. -+ * -+ * @pcie_port: PCIe port to write to -+ * @cfg_offset: Address to write -+ * @val: Value to write -+ */ -+void cvmx_pcie_cfgx_write(int pcie_port, uint32_t cfg_offset, uint32_t val) -+{ -+ union cvmx_pescx_cfg_wr pescx_cfg_wr; -+ pescx_cfg_wr.u64 = 0; -+ pescx_cfg_wr.s.addr = cfg_offset; -+ pescx_cfg_wr.s.data = val; -+ cvmx_write_csr(CVMX_PESCX_CFG_WR(pcie_port), pescx_cfg_wr.u64); -+} -+ -+/** -+ * Initialize a PCIe port for use in target(EP) mode. -+ * -+ * Returns Zero on success -+ */ -+int cvmx_pcie_ep_initialize(void) -+{ -+ int pcie_port = 0; -+ union cvmx_npei_ctl_status npei_ctl_status; -+ union cvmx_pciercx_cfg030 pciercx_cfg030; -+ union cvmx_npei_ctl_status2 npei_ctl_status2; -+ union cvmx_npei_mem_access_subidx mem_access_subid; -+ -+ npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS); -+ if (npei_ctl_status.s.host_mode) -+ return -1; -+ -+ /* Enable bus master and memory */ -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIEEP_CFG001, 0x6); -+ -+ /* -+ * Max Payload Size (PCIE*_CFG030[MPS]) -+ * Max Read Request Size (PCIE*_CFG030[MRRS]) -+ * Relaxed-order, no-snoop enables (PCIE*_CFG030[RO_EN,NS_EN] -+ * Error Message Enables (PCIE*_CFG030[CE_EN,NFE_EN,FE_EN,UR_EN]) -+ */ -+ pciercx_cfg030.u32 = -+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG030(pcie_port)); -+ /* Max payload size = 128 bytes (Limit of most PCs) */ -+ pciercx_cfg030.s.mps = 0; -+ /* -+ * Max read request size = 128 bytes for best Octeon DMA -+ * performance. -+ */ -+ pciercx_cfg030.s.mrrs = 0; -+ /* Enable relaxed ordering. */ -+ pciercx_cfg030.s.ro_en = 1; -+ /* Enable no snoop. */ -+ pciercx_cfg030.s.ns_en = 1; -+ /* Correctable error reporting enable. */ -+ pciercx_cfg030.s.ce_en = 1; -+ /* Non-fatal error reporting enable. */ -+ pciercx_cfg030.s.nfe_en = 1; -+ /* Fatal error reporting enable. */ -+ pciercx_cfg030.s.fe_en = 1; -+ /* Unsupported request reporting enable. */ -+ pciercx_cfg030.s.ur_en = 1; -+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG030(pcie_port), -+ pciercx_cfg030.u32); -+ -+ /* -+ * Max Payload Size (NPEI_CTL_STATUS2[MPS]) must match -+ * PCIE*_CFG030[MPS] -+ * -+ * Max Read Request Size (NPEI_CTL_STATUS2[MRRS]) must not -+ * exceed PCIE*_CFG030[MRRS] -+ */ -+ npei_ctl_status2.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS2); -+ /* Max payload size = 128 bytes (Limit of most PCs) */ -+ npei_ctl_status2.s.mps = 0; -+ /* Max read request size = 128 bytes for best Octeon DMA performance */ -+ npei_ctl_status2.s.mrrs = 0; -+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS2, npei_ctl_status2.u64); -+ -+ /* Setup Mem access SubDID 12 to access Host memory */ -+ mem_access_subid.u64 = 0; -+ /* Port the request is sent to. */ -+ mem_access_subid.s.port = pcie_port; -+ /* Merging is allowed in this window. */ -+ mem_access_subid.s.nmerge = 1; -+ /* Endian-swap for Reads. */ -+ mem_access_subid.s.esr = 0; -+ /* Endian-swap for Writes. */ -+ mem_access_subid.s.esw = 0; -+ /* No Snoop for Reads. */ -+ mem_access_subid.s.nsr = 1; -+ /* No Snoop for Writes. */ -+ mem_access_subid.s.nsw = 1; -+ /* Disable Relaxed Ordering for Reads. */ -+ mem_access_subid.s.ror = 0; -+ /* Disable Relaxed Ordering for Writes. */ -+ mem_access_subid.s.row = 0; -+ /* PCIe Adddress Bits <63:34>. */ -+ mem_access_subid.s.ba = 0; -+ cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(12), -+ mem_access_subid.u64); -+ return 0; -+} ---- /dev/null -+++ b/arch/mips/cavium-octeon/msi.c -@@ -0,0 +1,288 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2005-2007 Cavium Networks -+ */ -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/msi.h> -+#include <linux/spinlock.h> -+#include <linux/interrupt.h> -+ -+#include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-npi-defs.h> -+#include <asm/octeon/cvmx-pci-defs.h> -+#include <asm/octeon/cvmx-npei-defs.h> -+#include <asm/octeon/cvmx-pexp-defs.h> -+ -+#include "pci-common.h" -+ -+/* -+ * Each bit in msi_free_irq_bitmask represents a MSI interrupt that is -+ * in use. -+ */ -+static uint64_t msi_free_irq_bitmask; -+ -+/* -+ * Each bit in msi_multiple_irq_bitmask tells that the device using -+ * this bit in msi_free_irq_bitmask is also using the next bit. This -+ * is used so we can disable all of the MSI interrupts when a device -+ * uses multiple. -+ */ -+static uint64_t msi_multiple_irq_bitmask; -+ -+/* -+ * This lock controls updates to msi_free_irq_bitmask and -+ * msi_multiple_irq_bitmask. -+ */ -+static DEFINE_SPINLOCK(msi_free_irq_bitmask_lock); -+ -+ -+/** -+ * Called when a driver request MSI interrupts instead of the -+ * legacy INT A-D. This routine will allocate multiple interrupts -+ * for MSI devices that support them. A device can override this by -+ * programming the MSI control bits [6:4] before calling -+ * pci_enable_msi(). -+ * -+ * @param dev Device requesting MSI interrupts -+ * @param desc MSI descriptor -+ * -+ * Returns 0 on success. -+ */ -+int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) -+{ -+ struct msi_msg msg; -+ uint16_t control; -+ int configured_private_bits; -+ int request_private_bits; -+ int irq; -+ int irq_step; -+ uint64_t search_mask; -+ -+ /* -+ * Read the MSI config to figure out how many IRQs this device -+ * wants. Most devices only want 1, which will give -+ * configured_private_bits and request_private_bits equal 0. -+ */ -+ pci_read_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, -+ &control); -+ -+ /* -+ * If the number of private bits has been configured then use -+ * that value instead of the requested number. This gives the -+ * driver the chance to override the number of interrupts -+ * before calling pci_enable_msi(). -+ */ -+ configured_private_bits = (control & PCI_MSI_FLAGS_QSIZE) >> 4; -+ if (configured_private_bits == 0) { -+ /* Nothing is configured, so use the hardware requested size */ -+ request_private_bits = (control & PCI_MSI_FLAGS_QMASK) >> 1; -+ } else { -+ /* -+ * Use the number of configured bits, assuming the -+ * driver wanted to override the hardware request -+ * value. -+ */ -+ request_private_bits = configured_private_bits; -+ } -+ -+ /* -+ * The PCI 2.3 spec mandates that there are at most 32 -+ * interrupts. If this device asks for more, only give it one. -+ */ -+ if (request_private_bits > 5) -+ request_private_bits = 0; -+ -+try_only_one: -+ /* -+ * The IRQs have to be aligned on a power of two based on the -+ * number being requested. -+ */ -+ irq_step = 1 << request_private_bits; -+ -+ /* Mask with one bit for each IRQ */ -+ search_mask = (1 << irq_step) - 1; -+ -+ /* -+ * We're going to search msi_free_irq_bitmask_lock for zero -+ * bits. This represents an MSI interrupt number that isn't in -+ * use. -+ */ -+ spin_lock(&msi_free_irq_bitmask_lock); -+ for (irq = 0; irq < 64; irq += irq_step) { -+ if ((msi_free_irq_bitmask & (search_mask << irq)) == 0) { -+ msi_free_irq_bitmask |= search_mask << irq; -+ msi_multiple_irq_bitmask |= (search_mask >> 1) << irq; -+ break; -+ } -+ } -+ spin_unlock(&msi_free_irq_bitmask_lock); -+ -+ /* Make sure the search for available interrupts didn't fail */ -+ if (irq >= 64) { -+ if (request_private_bits) { -+ pr_err("arch_setup_msi_irq: Unable to find %d free " -+ "interrupts, trying just one", -+ 1 << request_private_bits); -+ request_private_bits = 0; -+ goto try_only_one; -+ } else -+ panic("arch_setup_msi_irq: Unable to find a free MSI " -+ "interrupt"); -+ } -+ -+ /* MSI interrupts start at logical IRQ OCTEON_IRQ_MSI_BIT0 */ -+ irq += OCTEON_IRQ_MSI_BIT0; -+ -+ switch (octeon_dma_bar_type) { -+ case OCTEON_DMA_BAR_TYPE_SMALL: -+ /* When not using big bar, Bar 0 is based at 128MB */ -+ msg.address_lo = -+ ((128ul << 20) + CVMX_PCI_MSI_RCV) & 0xffffffff; -+ msg.address_hi = ((128ul << 20) + CVMX_PCI_MSI_RCV) >> 32; -+ case OCTEON_DMA_BAR_TYPE_BIG: -+ /* When using big bar, Bar 0 is based at 0 */ -+ msg.address_lo = (0 + CVMX_PCI_MSI_RCV) & 0xffffffff; -+ msg.address_hi = (0 + CVMX_PCI_MSI_RCV) >> 32; -+ break; -+ case OCTEON_DMA_BAR_TYPE_PCIE: -+ /* When using PCIe, Bar 0 is based at 0 */ -+ /* FIXME CVMX_NPEI_MSI_RCV* other than 0? */ -+ msg.address_lo = (0 + CVMX_NPEI_PCIE_MSI_RCV) & 0xffffffff; -+ msg.address_hi = (0 + CVMX_NPEI_PCIE_MSI_RCV) >> 32; -+ break; -+ default: -+ panic("arch_setup_msi_irq: Invalid octeon_dma_bar_type\n"); -+ } -+ msg.data = irq - OCTEON_IRQ_MSI_BIT0; -+ -+ /* Update the number of IRQs the device has available to it */ -+ control &= ~PCI_MSI_FLAGS_QSIZE; -+ control |= request_private_bits << 4; -+ pci_write_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, -+ control); -+ -+ set_irq_msi(irq, desc); -+ write_msi_msg(irq, &msg); -+ return 0; -+} -+ -+ -+/** -+ * Called when a device no longer needs its MSI interrupts. All -+ * MSI interrupts for the device are freed. -+ * -+ * @irq: The devices first irq number. There may be multple in sequence. -+ */ -+void arch_teardown_msi_irq(unsigned int irq) -+{ -+ int number_irqs; -+ uint64_t bitmask; -+ -+ if ((irq < OCTEON_IRQ_MSI_BIT0) || (irq > OCTEON_IRQ_MSI_BIT63)) -+ panic("arch_teardown_msi_irq: Attempted to teardown illegal " -+ "MSI interrupt (%d)", irq); -+ irq -= OCTEON_IRQ_MSI_BIT0; -+ -+ /* -+ * Count the number of IRQs we need to free by looking at the -+ * msi_multiple_irq_bitmask. Each bit set means that the next -+ * IRQ is also owned by this device. -+ */ -+ number_irqs = 0; -+ while ((irq+number_irqs < 64) && -+ (msi_multiple_irq_bitmask & (1ull << (irq + number_irqs)))) -+ number_irqs++; -+ number_irqs++; -+ /* Mask with one bit for each IRQ */ -+ bitmask = (1 << number_irqs) - 1; -+ /* Shift the mask to the correct bit location */ -+ bitmask <<= irq; -+ if ((msi_free_irq_bitmask & bitmask) != bitmask) -+ panic("arch_teardown_msi_irq: Attempted to teardown MSI " -+ "interrupt (%d) not in use", irq); -+ -+ /* Checks are done, update the in use bitmask */ -+ spin_lock(&msi_free_irq_bitmask_lock); -+ msi_free_irq_bitmask &= ~bitmask; -+ msi_multiple_irq_bitmask &= ~bitmask; -+ spin_unlock(&msi_free_irq_bitmask_lock); -+} -+ -+ -+/** -+ * Called by the interrupt handling code when an MSI interrupt -+ * occurs. -+ * -+ * @param cpl -+ * @param dev_id -+ * -+ * @return -+ */ -+static irqreturn_t octeon_msi_interrupt(int cpl, void *dev_id) -+{ -+ uint64_t msi_bits; -+ int irq; -+ -+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_PCIE) -+ msi_bits = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_RCV0); -+ else -+ msi_bits = cvmx_read_csr(CVMX_NPI_NPI_MSI_RCV); -+ irq = fls64(msi_bits); -+ if (irq) { -+ irq += OCTEON_IRQ_MSI_BIT0 - 1; -+ if (irq_desc[irq].action) { -+ do_IRQ(irq); -+ return IRQ_HANDLED; -+ } else { -+ pr_err("Spurious MSI interrupt %d\n", irq); -+ if (octeon_has_feature(OCTEON_FEATURE_PCIE)) { -+ /* These chips have PCIe */ -+ cvmx_write_csr(CVMX_PEXP_NPEI_MSI_RCV0, -+ 1ull << (irq - -+ OCTEON_IRQ_MSI_BIT0)); -+ } else { -+ /* These chips have PCI */ -+ cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV, -+ 1ull << (irq - -+ OCTEON_IRQ_MSI_BIT0)); -+ } -+ } -+ } -+ return IRQ_NONE; -+} -+ -+ -+/** -+ * Initializes the MSI interrupt handling code -+ * -+ * @return -+ */ -+int octeon_msi_initialize(void) -+{ -+ int r; -+ if (octeon_has_feature(OCTEON_FEATURE_PCIE)) { -+ r = request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt, -+ IRQF_SHARED, -+ "MSI[0:63]", octeon_msi_interrupt); -+ } else if (octeon_is_pci_host()) { -+ r = request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt, -+ IRQF_SHARED, -+ "MSI[0:15]", octeon_msi_interrupt); -+ r += request_irq(OCTEON_IRQ_PCI_MSI1, octeon_msi_interrupt, -+ IRQF_SHARED, -+ "MSI[16:31]", octeon_msi_interrupt); -+ r += request_irq(OCTEON_IRQ_PCI_MSI2, octeon_msi_interrupt, -+ IRQF_SHARED, -+ "MSI[32:47]", octeon_msi_interrupt); -+ r += request_irq(OCTEON_IRQ_PCI_MSI3, octeon_msi_interrupt, -+ IRQF_SHARED, -+ "MSI[48:63]", octeon_msi_interrupt); -+ } -+ return 0; -+} -+ -+subsys_initcall(octeon_msi_initialize); ---- a/arch/mips/cavium-octeon/octeon-irq.c -+++ b/arch/mips/cavium-octeon/octeon-irq.c -@@ -10,6 +10,8 @@ - #include <linux/hardirq.h> - - #include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-pexp-defs.h> -+#include <asm/octeon/cvmx-npi-defs.h> - - DEFINE_RWLOCK(octeon_irq_ciu0_rwlock); - DEFINE_RWLOCK(octeon_irq_ciu1_rwlock); ---- /dev/null -+++ b/arch/mips/cavium-octeon/pci-common.c -@@ -0,0 +1,137 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2005-2007 Cavium Networks -+ */ -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/pci.h> -+#include <linux/interrupt.h> -+#include <linux/time.h> -+#include <linux/delay.h> -+#include "pci-common.h" -+ -+typeof(pcibios_map_irq) *octeon_pcibios_map_irq; -+enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; -+ -+/** -+ * Map a PCI device to the appropriate interrupt line -+ * -+ * @param dev The Linux PCI device structure for the device to map -+ * @param slot The slot number for this device on __BUS 0__. Linux -+ * enumerates through all the bridges and figures out the -+ * slot on Bus 0 where this device eventually hooks to. -+ * @param pin The PCI interrupt pin read from the device, then swizzled -+ * as it goes through each bridge. -+ * @return Interrupt number for the device -+ */ -+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -+{ -+ if (octeon_pcibios_map_irq) -+ return octeon_pcibios_map_irq(dev, slot, pin); -+ else -+ panic("octeon_pcibios_map_irq doesn't point to a " -+ "pcibios_map_irq() function"); -+} -+ -+ -+/** -+ * Called to perform platform specific PCI setup -+ * -+ * @param dev -+ * @return -+ */ -+int pcibios_plat_dev_init(struct pci_dev *dev) -+{ -+ uint16_t config; -+ uint32_t dconfig; -+ int pos; -+ /* -+ * Force the Cache line setting to 64 bytes. The standard -+ * Linux bus scan doesn't seem to set it. Octeon really has -+ * 128 byte lines, but Intel bridges get really upset if you -+ * try and set values above 64 bytes. Value is specified in -+ * 32bit words. -+ */ -+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 64 / 4); -+ /* Set latency timers for all devices */ -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 48); -+ -+ /* Enable reporting System errors and parity errors on all devices */ -+ /* Enable parity checking and error reporting */ -+ pci_read_config_word(dev, PCI_COMMAND, &config); -+ config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR; -+ pci_write_config_word(dev, PCI_COMMAND, config); -+ -+ if (dev->subordinate) { -+ /* Set latency timers on sub bridges */ -+ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 48); -+ /* More bridge error detection */ -+ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config); -+ config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR; -+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config); -+ } -+ -+ /* Enable the PCIe normal error reporting */ -+ pos = pci_find_capability(dev, PCI_CAP_ID_EXP); -+ if (pos) { -+ /* Update Device Control */ -+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config); -+ /* Correctable Error Reporting */ -+ config |= PCI_EXP_DEVCTL_CERE; -+ /* Non-Fatal Error Reporting */ -+ config |= PCI_EXP_DEVCTL_NFERE; -+ /* Fatal Error Reporting */ -+ config |= PCI_EXP_DEVCTL_FERE; -+ /* Unsupported Request */ -+ config |= PCI_EXP_DEVCTL_URRE; -+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config); -+ } -+ -+ /* Find the Advanced Error Reporting capability */ -+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); -+ if (pos) { -+ /* Clear Uncorrectable Error Status */ -+ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, -+ &dconfig); -+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, -+ dconfig); -+ /* Enable reporting of all uncorrectable errors */ -+ /* Uncorrectable Error Mask - turned on bits disable errors */ -+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0); -+ /* -+ * Leave severity at HW default. This only controls if -+ * errors are reported as uncorrectable or -+ * correctable, not if the error is reported. -+ */ -+ /* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */ -+ /* Clear Correctable Error Status */ -+ pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig); -+ pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig); -+ /* Enable reporting of all correctable errors */ -+ /* Correctable Error Mask - turned on bits disable errors */ -+ pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0); -+ /* Advanced Error Capabilities */ -+ pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig); -+ /* ECRC Generation Enable */ -+ if (config & PCI_ERR_CAP_ECRC_GENC) -+ config |= PCI_ERR_CAP_ECRC_GENE; -+ /* ECRC Check Enable */ -+ if (config & PCI_ERR_CAP_ECRC_CHKC) -+ config |= PCI_ERR_CAP_ECRC_CHKE; -+ pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig); -+ /* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */ -+ /* Report all errors to the root complex */ -+ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, -+ PCI_ERR_ROOT_CMD_COR_EN | -+ PCI_ERR_ROOT_CMD_NONFATAL_EN | -+ PCI_ERR_ROOT_CMD_FATAL_EN); -+ /* Clear the Root status register */ -+ pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig); -+ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig); -+ } -+ -+ return 0; -+} ---- /dev/null -+++ b/arch/mips/cavium-octeon/pci-common.h -@@ -0,0 +1,39 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2005-2007 Cavium Networks -+ */ -+#ifndef __OCTEON_PCI_COMMON_H__ -+#define __OCTEON_PCI_COMMON_H__ -+ -+#include <linux/pci.h> -+ -+/* Some PCI cards require delays when accessing config space. */ -+#define PCI_CONFIG_SPACE_DELAY 10000 -+ -+/* pcibios_map_irq() is defined inside pci-common.c. All it does is call the -+ Octeon specific version pointed to by this variable. This function needs to -+ change for PCI or PCIe based hosts */ -+extern typeof(pcibios_map_irq) *octeon_pcibios_map_irq; -+ -+/* The following defines are only used when octeon_dma_bar_type = -+ OCTEON_DMA_BAR_TYPE_BIG */ -+#define OCTEON_PCI_BAR1_HOLE_BITS 5 -+#define OCTEON_PCI_BAR1_HOLE_SIZE (1ul<<(OCTEON_PCI_BAR1_HOLE_BITS+3)) -+ -+enum octeon_dma_bar_type { -+ OCTEON_DMA_BAR_TYPE_INVALID, -+ OCTEON_DMA_BAR_TYPE_SMALL, -+ OCTEON_DMA_BAR_TYPE_BIG, -+ OCTEON_DMA_BAR_TYPE_PCIE -+}; -+ -+/** -+ * This is a variable to tell the DMA mapping system in dma-octeon.c -+ * how to map PCI DMA addresses. -+ */ -+extern enum octeon_dma_bar_type octeon_dma_bar_type; -+ -+#endif ---- /dev/null -+++ b/arch/mips/cavium-octeon/pci.c -@@ -0,0 +1,568 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2005-2007 Cavium Networks -+ */ -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/pci.h> -+#include <linux/interrupt.h> -+#include <linux/time.h> -+#include <linux/delay.h> -+ -+#include <asm/time.h> -+ -+#include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-npi-defs.h> -+#include <asm/octeon/cvmx-pci-defs.h> -+ -+#include "pci-common.h" -+ -+#define USE_OCTEON_INTERNAL_ARBITER -+ -+/* -+ * Octeon's PCI controller uses did=3, subdid=2 for PCI IO -+ * addresses. Use PCI endian swapping 1 so no address swapping is -+ * necessary. The Linux io routines will endian swap the data. -+ */ -+#define OCTEON_PCI_IOSPACE_BASE 0x80011a0400000000ull -+#define OCTEON_PCI_IOSPACE_SIZE (1ull<<32) -+ -+/* Octeon't PCI controller uses did=3, subdid=3 for PCI memory. */ -+#define OCTEON_PCI_MEMSPACE_OFFSET (0x00011b0000000000ull) -+ -+/** -+ * This is the bit decoding used for the Octeon PCI controller addresses -+ */ -+union octeon_pci_address { -+ uint64_t u64; -+ struct { -+ uint64_t upper:2; -+ uint64_t reserved:13; -+ uint64_t io:1; -+ uint64_t did:5; -+ uint64_t subdid:3; -+ uint64_t reserved2:4; -+ uint64_t endian_swap:2; -+ uint64_t reserved3:10; -+ uint64_t bus:8; -+ uint64_t dev:5; -+ uint64_t func:3; -+ uint64_t reg:8; -+ } s; -+}; -+ -+/** -+ * Return the mapping of PCI device number to IRQ line. Each -+ * character in the return string represents the interrupt -+ * line for the device at that position. Device 1 maps to the -+ * first character, etc. The characters A-D are used for PCI -+ * interrupts. -+ * -+ * Returns PCI interrupt mapping -+ */ -+const char *octeon_get_pci_interrupts(void) -+{ -+ /* -+ * Returning an empty string causes the interrupts to be -+ * routed based on the PCI specification. From the PCI spec: -+ * -+ * INTA# of Device Number 0 is connected to IRQW on the system -+ * board. (Device Number has no significance regarding being -+ * located on the system board or in a connector.) INTA# of -+ * Device Number 1 is connected to IRQX on the system -+ * board. INTA# of Device Number 2 is connected to IRQY on the -+ * system board. INTA# of Device Number 3 is connected to IRQZ -+ * on the system board. The table below describes how each -+ * agent's INTx# lines are connected to the system board -+ * interrupt lines. The following equation can be used to -+ * determine to which INTx# signal on the system board a given -+ * device's INTx# line(s) is connected. -+ * -+ * MB = (D + I) MOD 4 MB = System board Interrupt (IRQW = 0, -+ * IRQX = 1, IRQY = 2, and IRQZ = 3) D = Device Number I = -+ * Interrupt Number (INTA# = 0, INTB# = 1, INTC# = 2, and -+ * INTD# = 3) -+ */ -+ switch (octeon_bootinfo->board_type) { -+ case CVMX_BOARD_TYPE_NAO38: -+ /* This is really the NAC38 */ -+ return "AAAAADABAAAAAAAAAAAAAAAAAAAAAAAA"; -+ case CVMX_BOARD_TYPE_THUNDER: -+ return ""; -+ case CVMX_BOARD_TYPE_EBH3000: -+ return ""; -+ case CVMX_BOARD_TYPE_EBH3100: -+ case CVMX_BOARD_TYPE_CN3010_EVB_HS5: -+ case CVMX_BOARD_TYPE_CN3005_EVB_HS5: -+ return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; -+ case CVMX_BOARD_TYPE_BBGW_REF: -+ return "AABCD"; -+ default: -+ return ""; -+ } -+} -+ -+/** -+ * Map a PCI device to the appropriate interrupt line -+ * -+ * @dev: The Linux PCI device structure for the device to map -+ * @slot: The slot number for this device on __BUS 0__. Linux -+ * enumerates through all the bridges and figures out the -+ * slot on Bus 0 where this device eventually hooks to. -+ * @pin: The PCI interrupt pin read from the device, then swizzled -+ * as it goes through each bridge. -+ * Returns Interrupt number for the device -+ */ -+int __init octeon_pci_pcibios_map_irq(const struct pci_dev *dev, -+ u8 slot, u8 pin) -+{ -+ int irq_num; -+ const char *interrupts; -+ int dev_num; -+ -+ /* Get the board specific interrupt mapping */ -+ interrupts = octeon_get_pci_interrupts(); -+ -+ dev_num = dev->devfn >> 3; -+ if (dev_num < strlen(interrupts)) -+ irq_num = ((interrupts[dev_num] - 'A' + pin - 1) & 3) + -+ OCTEON_IRQ_PCI_INT0; -+ else -+ irq_num = ((slot + pin - 3) & 3) + OCTEON_IRQ_PCI_INT0; -+ return irq_num; -+} -+ -+ -+/** -+ * Read a value from configuration space -+ * -+ */ -+static int octeon_read_config(struct pci_bus *bus, unsigned int devfn, -+ int reg, int size, u32 *val) -+{ -+ union octeon_pci_address pci_addr; -+ -+ pci_addr.u64 = 0; -+ pci_addr.s.upper = 2; -+ pci_addr.s.io = 1; -+ pci_addr.s.did = 3; -+ pci_addr.s.subdid = 1; -+ pci_addr.s.endian_swap = 1; -+ pci_addr.s.bus = bus->number; -+ pci_addr.s.dev = devfn >> 3; -+ pci_addr.s.func = devfn & 0x7; -+ pci_addr.s.reg = reg; -+ -+#if PCI_CONFIG_SPACE_DELAY -+ udelay(PCI_CONFIG_SPACE_DELAY); -+#endif -+ switch (size) { -+ case 4: -+ *val = le32_to_cpu(cvmx_read64_uint32(pci_addr.u64)); -+ return PCIBIOS_SUCCESSFUL; -+ case 2: -+ *val = le16_to_cpu(cvmx_read64_uint16(pci_addr.u64)); -+ return PCIBIOS_SUCCESSFUL; -+ case 1: -+ *val = cvmx_read64_uint8(pci_addr.u64); -+ return PCIBIOS_SUCCESSFUL; -+ } -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+} -+ -+ -+/** -+ * Write a value to PCI configuration space -+ * -+ * @bus: -+ * @devfn: -+ * @reg: -+ * @size: -+ * @val: -+ * Returns -+ */ -+static int octeon_write_config(struct pci_bus *bus, unsigned int devfn, -+ int reg, int size, u32 val) -+{ -+ union octeon_pci_address pci_addr; -+ -+ pci_addr.u64 = 0; -+ pci_addr.s.upper = 2; -+ pci_addr.s.io = 1; -+ pci_addr.s.did = 3; -+ pci_addr.s.subdid = 1; -+ pci_addr.s.endian_swap = 1; -+ pci_addr.s.bus = bus->number; -+ pci_addr.s.dev = devfn >> 3; -+ pci_addr.s.func = devfn & 0x7; -+ pci_addr.s.reg = reg; -+ -+#if PCI_CONFIG_SPACE_DELAY -+ udelay(PCI_CONFIG_SPACE_DELAY); -+#endif -+ switch (size) { -+ case 4: -+ cvmx_write64_uint32(pci_addr.u64, cpu_to_le32(val)); -+ return PCIBIOS_SUCCESSFUL; -+ case 2: -+ cvmx_write64_uint16(pci_addr.u64, cpu_to_le16(val)); -+ return PCIBIOS_SUCCESSFUL; -+ case 1: -+ cvmx_write64_uint8(pci_addr.u64, val); -+ return PCIBIOS_SUCCESSFUL; -+ } -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+} -+ -+ -+static struct pci_ops octeon_pci_ops = { -+ octeon_read_config, -+ octeon_write_config, -+}; -+ -+static struct resource octeon_pci_mem_resource = { -+ .start = 0, -+ .end = 0, -+ .name = "Octeon PCI MEM", -+ .flags = IORESOURCE_MEM, -+}; -+ -+/* -+ * PCI ports must be above 16KB so the ISA bus filtering in the PCI-X to PCI -+ * bridge -+ */ -+static struct resource octeon_pci_io_resource = { -+ .start = 0x4000, -+ .end = OCTEON_PCI_IOSPACE_SIZE - 1, -+ .name = "Octeon PCI IO", -+ .flags = IORESOURCE_IO, -+}; -+ -+static struct pci_controller octeon_pci_controller = { -+ .pci_ops = &octeon_pci_ops, -+ .mem_resource = &octeon_pci_mem_resource, -+ .mem_offset = OCTEON_PCI_MEMSPACE_OFFSET, -+ .io_resource = &octeon_pci_io_resource, -+ .io_offset = 0, -+ .io_map_base = OCTEON_PCI_IOSPACE_BASE, -+}; -+ -+ -+/** -+ * Low level initialize the Octeon PCI controller -+ * -+ * Returns -+ */ -+static void octeon_pci_initialize(void) -+{ -+ union cvmx_pci_cfg01 cfg01; -+ union cvmx_npi_ctl_status ctl_status; -+ union cvmx_pci_ctl_status_2 ctl_status_2; -+ union cvmx_pci_cfg19 cfg19; -+ union cvmx_pci_cfg16 cfg16; -+ union cvmx_pci_cfg22 cfg22; -+ union cvmx_pci_cfg56 cfg56; -+ -+ /* Reset the PCI Bus */ -+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x1); -+ cvmx_read_csr(CVMX_CIU_SOFT_PRST); -+ -+ udelay(2000); /* Hold PCI reset for 2 ms */ -+ -+ ctl_status.u64 = 0; /* cvmx_read_csr(CVMX_NPI_CTL_STATUS); */ -+ ctl_status.s.max_word = 1; -+ ctl_status.s.timer = 1; -+ cvmx_write_csr(CVMX_NPI_CTL_STATUS, ctl_status.u64); -+ -+ /* Deassert PCI reset and advertize PCX Host Mode Device Capability -+ (64b) */ -+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x4); -+ cvmx_read_csr(CVMX_CIU_SOFT_PRST); -+ -+ udelay(2000); /* Wait 2 ms after deasserting PCI reset */ -+ -+ ctl_status_2.u32 = 0; -+ ctl_status_2.s.tsr_hwm = 1; /* Initializes to 0. Must be set -+ before any PCI reads. */ -+ ctl_status_2.s.bar2pres = 1; /* Enable BAR2 */ -+ ctl_status_2.s.bar2_enb = 1; -+ ctl_status_2.s.bar2_cax = 1; /* Don't use L2 */ -+ ctl_status_2.s.bar2_esx = 1; -+ ctl_status_2.s.pmo_amod = 1; /* Round robin priority */ -+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) { -+ /* BAR1 hole */ -+ ctl_status_2.s.bb1_hole = OCTEON_PCI_BAR1_HOLE_BITS; -+ ctl_status_2.s.bb1_siz = 1; /* BAR1 is 2GB */ -+ ctl_status_2.s.bb_ca = 1; /* Don't use L2 with big bars */ -+ ctl_status_2.s.bb_es = 1; /* Big bar in byte swap mode */ -+ ctl_status_2.s.bb1 = 1; /* BAR1 is big */ -+ ctl_status_2.s.bb0 = 1; /* BAR0 is big */ -+ } -+ -+ octeon_npi_write32(CVMX_NPI_PCI_CTL_STATUS_2, ctl_status_2.u32); -+ udelay(2000); /* Wait 2 ms before doing PCI reads */ -+ -+ ctl_status_2.u32 = octeon_npi_read32(CVMX_NPI_PCI_CTL_STATUS_2); -+ pr_notice("PCI Status: %s %s-bit\n", -+ ctl_status_2.s.ap_pcix ? "PCI-X" : "PCI", -+ ctl_status_2.s.ap_64ad ? "64" : "32"); -+ -+ if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) { -+ union cvmx_pci_cnt_reg cnt_reg_start; -+ union cvmx_pci_cnt_reg cnt_reg_end; -+ unsigned long cycles, pci_clock; -+ -+ cnt_reg_start.u64 = cvmx_read_csr(CVMX_NPI_PCI_CNT_REG); -+ cycles = read_c0_cvmcount(); -+ udelay(1000); -+ cnt_reg_end.u64 = cvmx_read_csr(CVMX_NPI_PCI_CNT_REG); -+ cycles = read_c0_cvmcount() - cycles; -+ pci_clock = (cnt_reg_end.s.pcicnt - cnt_reg_start.s.pcicnt) / -+ (cycles / (mips_hpt_frequency / 1000000)); -+ pr_notice("PCI Clock: %lu MHz\n", pci_clock); -+ } -+ -+ /* -+ * TDOMC must be set to one in PCI mode. TDOMC should be set to 4 -+ * in PCI-X mode to allow four oustanding splits. Otherwise, -+ * should not change from its reset value. Don't write PCI_CFG19 -+ * in PCI mode (0x82000001 reset value), write it to 0x82000004 -+ * after PCI-X mode is known. MRBCI,MDWE,MDRE -> must be zero. -+ * MRBCM -> must be one. -+ */ -+ if (ctl_status_2.s.ap_pcix) { -+ cfg19.u32 = 0; -+ /* -+ * Target Delayed/Split request outstanding maximum -+ * count. [1..31] and 0=32. NOTE: If the user -+ * programs these bits beyond the Designed Maximum -+ * outstanding count, then the designed maximum table -+ * depth will be used instead. No additional -+ * Deferred/Split transactions will be accepted if -+ * this outstanding maximum count is -+ * reached. Furthermore, no additional deferred/split -+ * transactions will be accepted if the I/O delay/ I/O -+ * Split Request outstanding maximum is reached. -+ */ -+ cfg19.s.tdomc = 4; -+ /* -+ * Master Deferred Read Request Outstanding Max Count -+ * (PCI only). CR4C[26:24] Max SAC cycles MAX DAC -+ * cycles 000 8 4 001 1 0 010 2 1 011 3 1 100 4 2 101 -+ * 5 2 110 6 3 111 7 3 For example, if these bits are -+ * programmed to 100, the core can support 2 DAC -+ * cycles, 4 SAC cycles or a combination of 1 DAC and -+ * 2 SAC cycles. NOTE: For the PCI-X maximum -+ * outstanding split transactions, refer to -+ * CRE0[22:20]. -+ */ -+ cfg19.s.mdrrmc = 2; -+ /* -+ * Master Request (Memory Read) Byte Count/Byte Enable -+ * select. 0 = Byte Enables valid. In PCI mode, a -+ * burst transaction cannot be performed using Memory -+ * Read command=4?h6. 1 = DWORD Byte Count valid -+ * (default). In PCI Mode, the memory read byte -+ * enables are automatically generated by the -+ * core. Note: N3 Master Request transaction sizes are -+ * always determined through the -+ * am_attr[<35:32>|<7:0>] field. -+ */ -+ cfg19.s.mrbcm = 1; -+ octeon_npi_write32(CVMX_NPI_PCI_CFG19, cfg19.u32); -+ } -+ -+ -+ cfg01.u32 = 0; -+ cfg01.s.msae = 1; /* Memory Space Access Enable */ -+ cfg01.s.me = 1; /* Master Enable */ -+ cfg01.s.pee = 1; /* PERR# Enable */ -+ cfg01.s.see = 1; /* System Error Enable */ -+ cfg01.s.fbbe = 1; /* Fast Back to Back Transaction Enable */ -+ -+ octeon_npi_write32(CVMX_NPI_PCI_CFG01, cfg01.u32); -+ -+#ifdef USE_OCTEON_INTERNAL_ARBITER -+ /* -+ * When OCTEON is a PCI host, most systems will use OCTEON's -+ * internal arbiter, so must enable it before any PCI/PCI-X -+ * traffic can occur. -+ */ -+ { -+ union cvmx_npi_pci_int_arb_cfg pci_int_arb_cfg; -+ -+ pci_int_arb_cfg.u64 = 0; -+ pci_int_arb_cfg.s.en = 1; /* Internal arbiter enable */ -+ cvmx_write_csr(CVMX_NPI_PCI_INT_ARB_CFG, pci_int_arb_cfg.u64); -+ } -+#endif /* USE_OCTEON_INTERNAL_ARBITER */ -+ -+ /* -+ * Preferrably written to 1 to set MLTD. [RDSATI,TRTAE, -+ * TWTAE,TMAE,DPPMR -> must be zero. TILT -> must not be set to -+ * 1..7. -+ */ -+ cfg16.u32 = 0; -+ cfg16.s.mltd = 1; /* Master Latency Timer Disable */ -+ octeon_npi_write32(CVMX_NPI_PCI_CFG16, cfg16.u32); -+ -+ /* -+ * Should be written to 0x4ff00. MTTV -> must be zero. -+ * FLUSH -> must be 1. MRV -> should be 0xFF. -+ */ -+ cfg22.u32 = 0; -+ /* Master Retry Value [1..255] and 0=infinite */ -+ cfg22.s.mrv = 0xff; -+ /* -+ * AM_DO_FLUSH_I control NOTE: This bit MUST BE ONE for proper -+ * N3K operation. -+ */ -+ cfg22.s.flush = 1; -+ octeon_npi_write32(CVMX_NPI_PCI_CFG22, cfg22.u32); -+ -+ /* -+ * MOST Indicates the maximum number of outstanding splits (in -1 -+ * notation) when OCTEON is in PCI-X mode. PCI-X performance is -+ * affected by the MOST selection. Should generally be written -+ * with one of 0x3be807, 0x2be807, 0x1be807, or 0x0be807, -+ * depending on the desired MOST of 3, 2, 1, or 0, respectively. -+ */ -+ cfg56.u32 = 0; -+ cfg56.s.pxcid = 7; /* RO - PCI-X Capability ID */ -+ cfg56.s.ncp = 0xe8; /* RO - Next Capability Pointer */ -+ cfg56.s.dpere = 1; /* Data Parity Error Recovery Enable */ -+ cfg56.s.roe = 1; /* Relaxed Ordering Enable */ -+ cfg56.s.mmbc = 1; /* Maximum Memory Byte Count -+ [0=512B,1=1024B,2=2048B,3=4096B] */ -+ cfg56.s.most = 3; /* Maximum outstanding Split transactions [0=1 -+ .. 7=32] */ -+ -+ octeon_npi_write32(CVMX_NPI_PCI_CFG56, cfg56.u32); -+ -+ /* -+ * Affects PCI performance when OCTEON services reads to its -+ * BAR1/BAR2. Refer to Section 10.6.1. The recommended values are -+ * 0x22, 0x33, and 0x33 for PCI_READ_CMD_6, PCI_READ_CMD_C, and -+ * PCI_READ_CMD_E, respectively. Unfortunately due to errata DDR-700, -+ * these values need to be changed so they won't possibly prefetch off -+ * of the end of memory if PCI is DMAing a buffer at the end of -+ * memory. Note that these values differ from their reset values. -+ */ -+ octeon_npi_write32(CVMX_NPI_PCI_READ_CMD_6, 0x21); -+ octeon_npi_write32(CVMX_NPI_PCI_READ_CMD_C, 0x31); -+ octeon_npi_write32(CVMX_NPI_PCI_READ_CMD_E, 0x31); -+} -+ -+ -+/** -+ * Initialize the Octeon PCI controller -+ * -+ * Returns -+ */ -+static int __init octeon_pci_setup(void) -+{ -+ union cvmx_npi_mem_access_subidx mem_access; -+ int index; -+ -+ /* Only these chips have PCI */ -+ if (octeon_has_feature(OCTEON_FEATURE_PCIE)) -+ return 0; -+ -+ /* Point pcibios_map_irq() to the PCI version of it */ -+ octeon_pcibios_map_irq = octeon_pci_pcibios_map_irq; -+ -+ /* Only use the big bars on chips that support it */ -+ if (OCTEON_IS_MODEL(OCTEON_CN31XX) || -+ OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2) || -+ OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)) -+ octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_SMALL; -+ else -+ octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_BIG; -+ -+ /* PCI I/O and PCI MEM values */ -+ set_io_port_base(OCTEON_PCI_IOSPACE_BASE); -+ ioport_resource.start = 0; -+ ioport_resource.end = OCTEON_PCI_IOSPACE_SIZE - 1; -+ if (!octeon_is_pci_host()) { -+ pr_notice("Not in host mode, PCI Controller not initialized\n"); -+ return 0; -+ } -+ -+ pr_notice("%s Octeon big bar support\n", -+ (octeon_dma_bar_type == -+ OCTEON_DMA_BAR_TYPE_BIG) ? "Enabling" : "Disabling"); -+ -+ octeon_pci_initialize(); -+ -+ mem_access.u64 = 0; -+ mem_access.s.esr = 1; /* Endian-Swap on read. */ -+ mem_access.s.esw = 1; /* Endian-Swap on write. */ -+ mem_access.s.nsr = 0; /* No-Snoop on read. */ -+ mem_access.s.nsw = 0; /* No-Snoop on write. */ -+ mem_access.s.ror = 0; /* Relax Read on read. */ -+ mem_access.s.row = 0; /* Relax Order on write. */ -+ mem_access.s.ba = 0; /* PCI Address bits [63:36]. */ -+ cvmx_write_csr(CVMX_NPI_MEM_ACCESS_SUBID3, mem_access.u64); -+ -+ /* -+ * Remap the Octeon BAR 2 above all 32 bit devices -+ * (0x8000000000ul). This is done here so it is remapped -+ * before the readl()'s below. We don't want BAR2 overlapping -+ * with BAR0/BAR1 during these reads. -+ */ -+ octeon_npi_write32(CVMX_NPI_PCI_CFG08, 0); -+ octeon_npi_write32(CVMX_NPI_PCI_CFG09, 0x80); -+ -+ /* Disable the BAR1 movable mappings */ -+ for (index = 0; index < 32; index++) -+ octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0); -+ -+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) { -+ /* Remap the Octeon BAR 0 to 0-2GB */ -+ octeon_npi_write32(CVMX_NPI_PCI_CFG04, 0); -+ octeon_npi_write32(CVMX_NPI_PCI_CFG05, 0); -+ -+ /* -+ * Remap the Octeon BAR 1 to map 2GB-4GB (minus the -+ * BAR 1 hole). -+ */ -+ octeon_npi_write32(CVMX_NPI_PCI_CFG06, 2ul << 30); -+ octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0); -+ -+ /* Devices go after BAR1 */ -+ octeon_pci_mem_resource.start = -+ OCTEON_PCI_MEMSPACE_OFFSET + (4ul << 30) - -+ (OCTEON_PCI_BAR1_HOLE_SIZE << 20); -+ octeon_pci_mem_resource.end = -+ octeon_pci_mem_resource.start + (1ul << 30); -+ } else { -+ /* Remap the Octeon BAR 0 to map 128MB-(128MB+4KB) */ -+ octeon_npi_write32(CVMX_NPI_PCI_CFG04, 128ul << 20); -+ octeon_npi_write32(CVMX_NPI_PCI_CFG05, 0); -+ -+ /* Remap the Octeon BAR 1 to map 0-128MB */ -+ octeon_npi_write32(CVMX_NPI_PCI_CFG06, 0); -+ octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0); -+ -+ /* Devices go after BAR0 */ -+ octeon_pci_mem_resource.start = -+ OCTEON_PCI_MEMSPACE_OFFSET + (128ul << 20) + -+ (4ul << 10); -+ octeon_pci_mem_resource.end = -+ octeon_pci_mem_resource.start + (1ul << 30); -+ } -+ -+ register_pci_controller(&octeon_pci_controller); -+ -+ /* -+ * Clear any errors that might be pending from before the bus -+ * was setup properly. -+ */ -+ cvmx_write_csr(CVMX_NPI_PCI_INT_SUM2, -1); -+ return 0; -+} -+ -+arch_initcall(octeon_pci_setup); ---- /dev/null -+++ b/arch/mips/cavium-octeon/pcie.c -@@ -0,0 +1,441 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2007, 2008 Cavium Networks -+ */ -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/pci.h> -+#include <linux/interrupt.h> -+#include <linux/time.h> -+#include <linux/delay.h> -+ -+#include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-pcie.h> -+#include <asm/octeon/cvmx-npei-defs.h> -+#include <asm/octeon/cvmx-pexp-defs.h> -+ -+#include "pci-common.h" -+ -+/** -+ * Map a PCI device to the appropriate interrupt line -+ * -+ * @param dev The Linux PCI device structure for the device to map -+ * @param slot The slot number for this device on __BUS 0__. Linux -+ * enumerates through all the bridges and figures out the -+ * slot on Bus 0 where this device eventually hooks to. -+ * @param pin The PCI interrupt pin read from the device, then swizzled -+ * as it goes through each bridge. -+ * @return Interrupt number for the device -+ */ -+int __init octeon_pcie_pcibios_map_irq(const struct pci_dev *dev, -+ u8 slot, u8 pin) -+{ -+ /* -+ * The EBH5600 board with the PCI to PCIe bridge mistakenly -+ * wires the first slot for both device id 2 and interrupt -+ * A. According to the PCI spec, device id 2 should be C. The -+ * following kludge attempts to fix this. -+ */ -+ if (strstr(octeon_board_type_string(), "EBH5600") && -+ dev->bus && dev->bus->parent) { -+ /* -+ * Iterate all the way up the device chain and find -+ * the root bus. -+ */ -+ while (dev->bus && dev->bus->parent) -+ dev = to_pci_dev(dev->bus->bridge); -+ /* If the root bus is number 0 and the PEX 8114 is the -+ * root, assume we are behind the miswired bus. We -+ * need to correct the swizzle level by two. Yuck. -+ */ -+ if ((dev->bus->number == 0) && -+ (dev->vendor == 0x10b5) && (dev->device == 0x8114)) { -+ /* -+ * The pin field is one based, not zero. We -+ * need to swizzle it by minus two. -+ */ -+ pin = ((pin - 3) & 3) + 1; -+ } -+ } -+ /* -+ * The -1 is because pin starts with one, not zero. It might -+ * be that this equation needs to include the slot number, but -+ * I don't have hardware to check that against. -+ */ -+ return pin - 1 + OCTEON_IRQ_PCI_INT0; -+} -+ -+/** -+ * Read a value from configuration space -+ * -+ * @param bus -+ * @param devfn -+ * @param reg -+ * @param size -+ * @param val -+ * @return -+ */ -+static inline int octeon_pcie_read_config(int pcie_port, struct pci_bus *bus, -+ unsigned int devfn, int reg, int size, -+ u32 *val) -+{ -+ union octeon_cvmemctl cvmmemctl; -+ union octeon_cvmemctl cvmmemctl_save; -+ int bus_number = bus->number; -+ -+ /* -+ * We need to force the bus number to be zero on the root -+ * bus. Linux numbers the 2nd root bus to start after all -+ * buses on root 0. -+ */ -+ if (bus->parent == NULL) -+ bus_number = 0; -+ -+ /* -+ * PCIe only has a single device connected to Octeon. It is -+ * always device ID 0. Don't bother doing reads for other -+ * device IDs on the first segment. -+ */ -+ if ((bus_number == 0) && (devfn >> 3 != 0)) -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+ -+ /* -+ * The following is a workaround for the CN57XX, CN56XX, -+ * CN55XX, and CN54XX errata with PCIe config reads from non -+ * existent devices. These chips will hang the PCIe link if a -+ * config read is performed that causes a UR response. -+ */ -+ if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1) || -+ OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_1)) { -+ /* -+ * For our EBH5600 board, port 0 has a bridge with two -+ * PCI-X slots. We need a new special checks to make -+ * sure we only probe valid stuff. The PCIe->PCI-X -+ * bridge only respondes to device ID 0, function -+ * 0-1 -+ */ -+ if ((bus_number == 0) && (devfn >= 2)) -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+ /* -+ * The PCI-X slots are device ID 2,3. Choose one of -+ * the below "if" blocks based on what is plugged into -+ * the board. -+ */ -+#if 1 -+ /* Use this option if you aren't using either slot */ -+ if (bus_number == 1) -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+#elif 0 -+ /* -+ * Use this option if you are using the first slot but -+ * not the second. -+ */ -+ if ((bus_number == 1) && (devfn >> 3 != 2)) -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+#elif 0 -+ /* -+ * Use this option if you are using the second slot -+ * but not the first. -+ */ -+ if ((bus_number == 1) && (devfn >> 3 != 3)) -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+#elif 0 -+ /* Use this opion if you are using both slots */ -+ if ((bus_number == 1) && -+ !((devfn == (2 << 3)) || (devfn == (3 << 3)))) -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+#endif -+ -+ /* -+ * The following #if gives a more complicated -+ * example. This is the required checks for running a -+ * Nitrox CN16XX-NHBX in the slot of the EBH5600. This -+ * card has a PLX PCIe bridge with four Nitrox PLX -+ * parts behind it. -+ */ -+#if 0 -+ /* PLX bridge with 4 ports */ -+ if ((bus_number == 3) && -+ !((devfn >> 3 >= 1) && (devfn >> 3 <= 4))) -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+ /* Nitrox behind PLX 1 */ -+ if ((bus_number == 4) && (devfn >> 3 != 0)) -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+ /* Nitrox behind PLX 2 */ -+ if ((bus_number == 5) && (devfn >> 3 != 0)) -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+ /* Nitrox behind PLX 3 */ -+ if ((bus_number == 6) && (devfn >> 3 != 0)) -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+ /* Nitrox behind PLX 4 */ -+ if ((bus_number == 7) && (devfn >> 3 != 0)) -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+#endif -+ /* -+ * Shorten the DID timeout so bus errors for PCIe -+ * config reads from non existent devices happen -+ * faster. This allows us to continue booting even if -+ * the above "if" checks are wrong. Once one of these -+ * errors happens, the PCIe port is dead. -+ */ -+ cvmmemctl_save.u64 = __read_64bit_c0_register($11, 7); -+ cvmmemctl.u64 = cvmmemctl_save.u64; -+ cvmmemctl.s.didtto = 2; -+ __write_64bit_c0_register($11, 7, cvmmemctl.u64); -+ } -+ -+ switch (size) { -+ case 4: -+ *val = cvmx_pcie_config_read32(pcie_port, bus_number, -+ devfn >> 3, devfn & 0x7, reg); -+ break; -+ case 2: -+ *val = cvmx_pcie_config_read16(pcie_port, bus_number, -+ devfn >> 3, devfn & 0x7, reg); -+ break; -+ case 1: -+ *val = cvmx_pcie_config_read8(pcie_port, bus_number, devfn >> 3, -+ devfn & 0x7, reg); -+ break; -+ default: -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+ } -+ -+ if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1) || -+ OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_1)) -+ __write_64bit_c0_register($11, 7, cvmmemctl_save.u64); -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int octeon_pcie0_read_config(struct pci_bus *bus, unsigned int devfn, -+ int reg, int size, u32 *val) -+{ -+ return octeon_pcie_read_config(0, bus, devfn, reg, size, val); -+} -+ -+static int octeon_pcie1_read_config(struct pci_bus *bus, unsigned int devfn, -+ int reg, int size, u32 *val) -+{ -+ return octeon_pcie_read_config(1, bus, devfn, reg, size, val); -+} -+ -+ -+ -+/** -+ * Write a value to PCI configuration space -+ * -+ * @param bus -+ * @param devfn -+ * @param reg -+ * @param size -+ * @param val -+ * @return -+ */ -+static inline int octeon_pcie_write_config(int pcie_port, struct pci_bus *bus, -+ unsigned int devfn, int reg, -+ int size, u32 val) -+{ -+ int bus_number = bus->number; -+ /* -+ * We need to force the bus number to be zero on the root -+ * bus. Linux numbers the 2nd root bus to start after all -+ * busses on root 0. -+ */ -+ if (bus->parent == NULL) -+ bus_number = 0; -+ -+ switch (size) { -+ case 4: -+ cvmx_pcie_config_write32(pcie_port, bus_number, devfn >> 3, -+ devfn & 0x7, reg, val); -+ return PCIBIOS_SUCCESSFUL; -+ case 2: -+ cvmx_pcie_config_write16(pcie_port, bus_number, devfn >> 3, -+ devfn & 0x7, reg, val); -+ return PCIBIOS_SUCCESSFUL; -+ case 1: -+ cvmx_pcie_config_write8(pcie_port, bus_number, devfn >> 3, -+ devfn & 0x7, reg, val); -+ return PCIBIOS_SUCCESSFUL; -+ } -+#if PCI_CONFIG_SPACE_DELAY -+ udelay(PCI_CONFIG_SPACE_DELAY); -+#endif -+ return PCIBIOS_FUNC_NOT_SUPPORTED; -+} -+ -+static int octeon_pcie0_write_config(struct pci_bus *bus, unsigned int devfn, -+ int reg, int size, u32 val) -+{ -+ return octeon_pcie_write_config(0, bus, devfn, reg, size, val); -+} -+ -+static int octeon_pcie1_write_config(struct pci_bus *bus, unsigned int devfn, -+ int reg, int size, u32 val) -+{ -+ return octeon_pcie_write_config(1, bus, devfn, reg, size, val); -+} -+ -+static struct pci_ops octeon_pcie0_ops = { -+ octeon_pcie0_read_config, -+ octeon_pcie0_write_config, -+}; -+ -+static struct resource octeon_pcie0_mem_resource = { -+ .name = "Octeon PCIe0 MEM", -+ .flags = IORESOURCE_MEM, -+}; -+ -+static struct resource octeon_pcie0_io_resource = { -+ .name = "Octeon PCIe0 IO", -+ .flags = IORESOURCE_IO, -+}; -+ -+static struct pci_controller octeon_pcie0_controller = { -+ .pci_ops = &octeon_pcie0_ops, -+ .mem_resource = &octeon_pcie0_mem_resource, -+ .io_resource = &octeon_pcie0_io_resource, -+}; -+ -+static struct pci_ops octeon_pcie1_ops = { -+ octeon_pcie1_read_config, -+ octeon_pcie1_write_config, -+}; -+ -+static struct resource octeon_pcie1_mem_resource = { -+ .name = "Octeon PCIe1 MEM", -+ .flags = IORESOURCE_MEM, -+}; -+ -+static struct resource octeon_pcie1_io_resource = { -+ .name = "Octeon PCIe1 IO", -+ .flags = IORESOURCE_IO, -+}; -+ -+static struct pci_controller octeon_pcie1_controller = { -+ .pci_ops = &octeon_pcie1_ops, -+ .mem_resource = &octeon_pcie1_mem_resource, -+ .io_resource = &octeon_pcie1_io_resource, -+}; -+ -+ -+/** -+ * Initialize the Octeon PCIe controllers -+ * -+ * @return -+ */ -+static int __init octeon_pcie_setup(void) -+{ -+ union cvmx_npei_ctl_status npei_ctl_status; -+ int result; -+ -+ /* These chips don't have PCIe */ -+ if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) -+ return 0; -+ -+ /* Point pcibios_map_irq() to the PCIe version of it */ -+ octeon_pcibios_map_irq = octeon_pcie_pcibios_map_irq; -+ -+ /* Use the PCIe based DMA mappings */ -+ octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_PCIE; -+ -+ /* -+ * PCIe I/O range. It is based on port 0 but includes up until -+ * port 1's end. -+ */ -+ set_io_port_base(CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(0))); -+ ioport_resource.start = 0; -+ ioport_resource.end = -+ cvmx_pcie_get_io_base_address(1) - -+ cvmx_pcie_get_io_base_address(0) + cvmx_pcie_get_io_size(1) - 1; -+ -+ npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS); -+ if (npei_ctl_status.s.host_mode) { -+ pr_notice("PCIe: Initializing port 0\n"); -+ result = cvmx_pcie_rc_initialize(0); -+ if (result == 0) { -+ /* Memory offsets are physical addresses */ -+ octeon_pcie0_controller.mem_offset = -+ cvmx_pcie_get_mem_base_address(0); -+ /* IO offsets are Mips virtual addresses */ -+ octeon_pcie0_controller.io_map_base = -+ CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address -+ (0)); -+ octeon_pcie0_controller.io_offset = 0; -+ /* -+ * To keep things similar to PCI, we start -+ * device addresses at the same place as PCI -+ * uisng big bar support. This normally -+ * translates to 4GB-256MB, which is the same -+ * as most x86 PCs. -+ */ -+ octeon_pcie0_controller.mem_resource->start = -+ cvmx_pcie_get_mem_base_address(0) + -+ (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20); -+ octeon_pcie0_controller.mem_resource->end = -+ cvmx_pcie_get_mem_base_address(0) + -+ cvmx_pcie_get_mem_size(0) - 1; -+ /* -+ * Ports must be above 16KB for the ISA bus -+ * filtering in the PCI-X to PCI bridge. -+ */ -+ octeon_pcie0_controller.io_resource->start = 4 << 10; -+ octeon_pcie0_controller.io_resource->end = -+ cvmx_pcie_get_io_size(0) - 1; -+ register_pci_controller(&octeon_pcie0_controller); -+ } -+ } else { -+ pr_notice("PCIe: Port 0 in endpoint mode, skipping.\n"); -+ } -+ -+ /* Skip the 2nd port on CN52XX if port 0 is in 4 lane mode */ -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) { -+ union cvmx_npei_dbg_data npei_dbg_data; -+ npei_dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA); -+ if (npei_dbg_data.cn52xx.qlm0_link_width) -+ return 0; -+ } -+ -+ pr_notice("PCIe: Initializing port 1\n"); -+ result = cvmx_pcie_rc_initialize(1); -+ if (result == 0) { -+ /* Memory offsets are physical addresses */ -+ octeon_pcie1_controller.mem_offset = -+ cvmx_pcie_get_mem_base_address(1); -+ /* IO offsets are Mips virtual addresses */ -+ octeon_pcie1_controller.io_map_base = -+ CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(1)); -+ octeon_pcie1_controller.io_offset = -+ cvmx_pcie_get_io_base_address(1) - -+ cvmx_pcie_get_io_base_address(0); -+ /* -+ * To keep things similar to PCI, we start device -+ * addresses at the same place as PCI uisng big bar -+ * support. This normally translates to 4GB-256MB, -+ * which is the same as most x86 PCs. -+ */ -+ octeon_pcie1_controller.mem_resource->start = -+ cvmx_pcie_get_mem_base_address(1) + (4ul << 30) - -+ (OCTEON_PCI_BAR1_HOLE_SIZE << 20); -+ octeon_pcie1_controller.mem_resource->end = -+ cvmx_pcie_get_mem_base_address(1) + -+ cvmx_pcie_get_mem_size(1) - 1; -+ /* -+ * Ports must be above 16KB for the ISA bus filtering -+ * in the PCI-X to PCI bridge. -+ */ -+ octeon_pcie1_controller.io_resource->start = -+ cvmx_pcie_get_io_base_address(1) - -+ cvmx_pcie_get_io_base_address(0); -+ octeon_pcie1_controller.io_resource->end = -+ octeon_pcie1_controller.io_resource->start + -+ cvmx_pcie_get_io_size(1) - 1; -+ register_pci_controller(&octeon_pcie1_controller); -+ } -+ return 0; -+} -+ -+arch_initcall(octeon_pcie_setup); ---- a/arch/mips/include/asm/octeon/cvmx-asm.h -+++ b/arch/mips/include/asm/octeon/cvmx-asm.h -@@ -119,7 +119,8 @@ - asm ("pop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input)) - #define CVMX_DPOP(result, input) \ - asm ("dpop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input)) -- -+#define CVMX_CLZ(result, input) \ -+ asm ("clz %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input)) - /* some new cop0-like stuff */ - #define CVMX_RDHWR(result, regstr) \ - asm volatile ("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d" (result)) ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-helper-errata.h -@@ -0,0 +1,92 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * @file -+ * -+ * Fixes and workaround for Octeon chip errata. This file -+ * contains functions called by cvmx-helper to workaround known -+ * chip errata. For the most part, code doesn't need to call -+ * these functions directly. -+ * -+ */ -+#ifndef __CVMX_HELPER_ERRATA_H__ -+#define __CVMX_HELPER_ERRATA_H__ -+ -+ -+#include "cvmx-wqe.h" -+ -+/** -+ * @INTERNAL -+ * Function to adjust internal IPD pointer alignments -+ * -+ * Returns 0 on success -+ * !0 on failure -+ */ -+extern int __cvmx_helper_errata_fix_ipd_ptr_alignment(void); -+ -+/** -+ * @INTERNAL -+ * Workaround ASX setup errata with CN38XX pass1 -+ * -+ * @interface: Interface to setup -+ * @port: Port to setup (0..3) -+ * @cpu_clock_hz: -+ * Chip frequency in Hertz -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_errata_asx_pass1(int interface, int port, -+ int cpu_clock_hz); -+ -+/** -+ * This function needs to be called on all Octeon chips with -+ * errata PKI-100. -+ * -+ * The Size field is 8 too large in WQE and next pointers -+ * -+ * The Size field generated by IPD is 8 larger than it should -+ * be. The Size field is <55:40> of both: -+ * - WORD3 in the work queue entry, and -+ * - the next buffer pointer (which precedes the packet data -+ * in each buffer). -+ * -+ * @work: Work queue entry to fix -+ * Returns Zero on success. Negative on failure -+ */ -+extern int cvmx_helper_fix_ipd_packet_chain(struct cvmx_wqe *work); -+ -+/** -+ * Due to errata G-720, the 2nd order CDR circuit on CN52XX pass -+ * 1 doesn't work properly. The following code disables 2nd order -+ * CDR for the specified QLM. -+ * -+ * @qlm: QLM to disable 2nd order CDR for. -+ */ -+extern void __cvmx_helper_errata_qlm_disable_2nd_order_cdr(int qlm); -+ -+#endif ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-helper-util.h -@@ -0,0 +1,266 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * Small helper utilities. -+ * -+ */ -+ -+#ifndef __CVMX_HELPER_UTIL_H__ -+#define __CVMX_HELPER_UTIL_H__ -+ -+#ifdef CVMX_ENABLE_HELPER_FUNCTIONS -+ -+/** -+ * Convert a interface mode into a human readable string -+ * -+ * @mode: Mode to convert -+ * -+ * Returns String -+ */ -+extern const char -+ *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t mode); -+ -+/** -+ * Debug routine to dump the packet structure to the console -+ * -+ * @work: Work queue entry containing the packet to dump -+ * Returns -+ */ -+extern int cvmx_helper_dump_packet(cvmx_wqe_t *work); -+ -+/** -+ * Setup Random Early Drop on a specific input queue -+ * -+ * @queue: Input queue to setup RED on (0-7) -+ * @pass_thresh: -+ * Packets will begin slowly dropping when there are less than -+ * this many packet buffers free in FPA 0. -+ * @drop_thresh: -+ * All incomming packets will be dropped when there are less -+ * than this many free packet buffers in FPA 0. -+ * Returns Zero on success. Negative on failure -+ */ -+extern int cvmx_helper_setup_red_queue(int queue, int pass_thresh, -+ int drop_thresh); -+ -+/** -+ * Setup Random Early Drop to automatically begin dropping packets. -+ * -+ * @pass_thresh: -+ * Packets will begin slowly dropping when there are less than -+ * this many packet buffers free in FPA 0. -+ * @drop_thresh: -+ * All incomming packets will be dropped when there are less -+ * than this many free packet buffers in FPA 0. -+ * Returns Zero on success. Negative on failure -+ */ -+extern int cvmx_helper_setup_red(int pass_thresh, int drop_thresh); -+ -+/** -+ * Get the version of the CVMX libraries. -+ * -+ * Returns Version string. Note this buffer is allocated statically -+ * and will be shared by all callers. -+ */ -+extern const char *cvmx_helper_get_version(void); -+ -+/** -+ * @INTERNAL -+ * Setup the common GMX settings that determine the number of -+ * ports. These setting apply to almost all configurations of all -+ * chips. -+ * -+ * @interface: Interface to configure -+ * @num_ports: Number of ports on the interface -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_setup_gmx(int interface, int num_ports); -+ -+/** -+ * Returns the IPD/PKO port number for a port on the given -+ * interface. -+ * -+ * @interface: Interface to use -+ * @port: Port on the interface -+ * -+ * Returns IPD/PKO port number -+ */ -+extern int cvmx_helper_get_ipd_port(int interface, int port); -+ -+/** -+ * Returns the IPD/PKO port number for the first port on the given -+ * interface. -+ * -+ * @interface: Interface to use -+ * -+ * Returns IPD/PKO port number -+ */ -+static inline int cvmx_helper_get_first_ipd_port(int interface) -+{ -+ return cvmx_helper_get_ipd_port(interface, 0); -+} -+ -+/** -+ * Returns the IPD/PKO port number for the last port on the given -+ * interface. -+ * -+ * @interface: Interface to use -+ * -+ * Returns IPD/PKO port number -+ */ -+static inline int cvmx_helper_get_last_ipd_port(int interface) -+{ -+ extern int cvmx_helper_ports_on_interface(int interface); -+ -+ return cvmx_helper_get_first_ipd_port(interface) + -+ cvmx_helper_ports_on_interface(interface) - 1; -+} -+ -+/** -+ * Free the packet buffers contained in a work queue entry. -+ * The work queue entry is not freed. -+ * -+ * @work: Work queue entry with packet to free -+ */ -+static inline void cvmx_helper_free_packet_data(cvmx_wqe_t *work) -+{ -+ uint64_t number_buffers; -+ cvmx_buf_ptr_t buffer_ptr; -+ cvmx_buf_ptr_t next_buffer_ptr; -+ uint64_t start_of_buffer; -+ -+ number_buffers = work->word2.s.bufs; -+ if (number_buffers == 0) -+ return; -+ buffer_ptr = work->packet_ptr; -+ -+ /* -+ * Since the number of buffers is not zero, we know this is -+ * not a dynamic short packet. We need to check if it is a -+ * packet received with IPD_CTL_STATUS[NO_WPTR]. If this is -+ * true, we need to free all buffers except for the first -+ * one. The caller doesn't expect their WQE pointer to be -+ * freed. -+ */ -+ start_of_buffer = ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7; -+ if (cvmx_ptr_to_phys(work) == start_of_buffer) { -+ next_buffer_ptr = -+ *(cvmx_buf_ptr_t *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8); -+ buffer_ptr = next_buffer_ptr; -+ number_buffers--; -+ } -+ -+ while (number_buffers--) { -+ /* -+ * Remember the back pointer is in cache lines, not -+ * 64bit words. -+ */ -+ start_of_buffer = -+ ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7; -+ /* -+ * Read pointer to next buffer before we free the -+ * current buffer. -+ */ -+ next_buffer_ptr = -+ *(cvmx_buf_ptr_t *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8); -+ cvmx_fpa_free(cvmx_phys_to_ptr(start_of_buffer), -+ buffer_ptr.s.pool, 0); -+ buffer_ptr = next_buffer_ptr; -+ } -+} -+ -+#endif /* CVMX_ENABLE_HELPER_FUNCTIONS */ -+ -+/** -+ * Returns the interface number for an IPD/PKO port number. -+ * -+ * @ipd_port: IPD/PKO port number -+ * -+ * Returns Interface number -+ */ -+extern int cvmx_helper_get_interface_num(int ipd_port); -+ -+/** -+ * Returns the interface index number for an IPD/PKO port -+ * number. -+ * -+ * @ipd_port: IPD/PKO port number -+ * -+ * Returns Interface index number -+ */ -+extern int cvmx_helper_get_interface_index_num(int ipd_port); -+ -+/** -+ * Initialize the internal QLM JTAG logic to allow programming -+ * of the JTAG chain by the cvmx_helper_qlm_jtag_*() functions. -+ * These functions should only be used at the direction of Cavium -+ * Networks. Programming incorrect values into the JTAG chain -+ * can cause chip damage. -+ */ -+extern void cvmx_helper_qlm_jtag_init(void); -+ -+/** -+ * Write up to 32bits into the QLM jtag chain. Bits are shifted -+ * into the MSB and out the LSB, so you should shift in the low -+ * order bits followed by the high order bits. The JTAG chain is -+ * 4 * 268 bits long, or 1072. -+ * -+ * @qlm: QLM to shift value into -+ * @bits: Number of bits to shift in (1-32). -+ * @data: Data to shift in. Bit 0 enters the chain first, followed by -+ * bit 1, etc. -+ * -+ * Returns The low order bits of the JTAG chain that shifted out of the -+ * circle. -+ */ -+extern uint32_t cvmx_helper_qlm_jtag_shift(int qlm, int bits, uint32_t data); -+ -+/** -+ * Shift long sequences of zeros into the QLM JTAG chain. It is -+ * common to need to shift more than 32 bits of zeros into the -+ * chain. This function is a convience wrapper around -+ * cvmx_helper_qlm_jtag_shift() to shift more than 32 bits of -+ * zeros at a time. -+ * -+ * @qlm: QLM to shift zeros into -+ * @bits: -+ */ -+extern void cvmx_helper_qlm_jtag_shift_zeros(int qlm, int bits); -+ -+/** -+ * Program the QLM JTAG chain into all lanes of the QLM. You must -+ * have already shifted in 268*4, or 1072 bits into the JTAG -+ * chain. Updating invalid values can possibly cause chip damage. -+ * -+ * @qlm: QLM to program -+ */ -+extern void cvmx_helper_qlm_jtag_update(int qlm); -+ -+#endif /* __CVMX_HELPER_H__ */ ---- a/arch/mips/include/asm/octeon/cvmx-packet.h -+++ b/arch/mips/include/asm/octeon/cvmx-packet.h -@@ -25,7 +25,8 @@ - * Contact Cavium Networks for more information - ***********************license end**************************************/ - --/* -+/** -+ * - * Packet buffer defines. - */ - -@@ -39,18 +40,23 @@ union cvmx_buf_ptr { - void *ptr; - uint64_t u64; - struct { -- /* if set, invert the "free" pick of the overall -+ /* -+ * If set, invert the "free" pick of the overall - * packet. HW always sets this bit to 0 on inbound -- * packet */ -+ * packet. -+ */ - uint64_t i:1; - -- /* Indicates the amount to back up to get to the -+ /* -+ * Indicates the amount to back up to get to the - * buffer start in cache lines. In most cases this is - * less than one complete cache line, so the value is -- * zero */ -+ * zero. -+ */ - uint64_t back:4; - /* The pool that the buffer came from / goes to */ - uint64_t pool:3; -+ - /* The size of the segment pointed to by addr (in bytes) */ - uint64_t size:16; - /* Pointer to the first byte of the data, NOT buffer */ ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-pcie.h -@@ -0,0 +1,284 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * @file -+ * -+ * Interface to PCIe as a host(RC) or target(EP) -+ * -+ */ -+ -+#ifndef __CVMX_PCIE_H__ -+#define __CVMX_PCIE_H__ -+ -+union cvmx_pcie_address { -+ uint64_t u64; -+ struct { -+ uint64_t upper:2; /* Normally 2 for XKPHYS */ -+ uint64_t reserved_49_61:13; /* Must be zero */ -+ uint64_t io:1; /* 1 for IO space access */ -+ uint64_t did:5; /* PCIe DID = 3 */ -+ uint64_t subdid:3; /* PCIe SubDID = 1 */ -+ uint64_t reserved_36_39:4; /* Must be zero */ -+ uint64_t es:2; /* Endian swap = 1 */ -+ uint64_t port:2; /* PCIe port 0,1 */ -+ uint64_t reserved_29_31:3; /* Must be zero */ -+ /* -+ * Selects the type of the configuration request (0 = type 0, -+ * 1 = type 1). -+ */ -+ uint64_t ty:1; -+ /* Target bus number sent in the ID in the request. */ -+ uint64_t bus:8; -+ /* -+ * Target device number sent in the ID in the -+ * request. Note that Dev must be zero for type 0 -+ * configuration requests. -+ */ -+ uint64_t dev:5; -+ /* Target function number sent in the ID in the request. */ -+ uint64_t func:3; -+ /* -+ * Selects a register in the configuration space of -+ * the target. -+ */ -+ uint64_t reg:12; -+ } config; -+ struct { -+ uint64_t upper:2; /* Normally 2 for XKPHYS */ -+ uint64_t reserved_49_61:13; /* Must be zero */ -+ uint64_t io:1; /* 1 for IO space access */ -+ uint64_t did:5; /* PCIe DID = 3 */ -+ uint64_t subdid:3; /* PCIe SubDID = 2 */ -+ uint64_t reserved_36_39:4; /* Must be zero */ -+ uint64_t es:2; /* Endian swap = 1 */ -+ uint64_t port:2; /* PCIe port 0,1 */ -+ uint64_t address:32; /* PCIe IO address */ -+ } io; -+ struct { -+ uint64_t upper:2; /* Normally 2 for XKPHYS */ -+ uint64_t reserved_49_61:13; /* Must be zero */ -+ uint64_t io:1; /* 1 for IO space access */ -+ uint64_t did:5; /* PCIe DID = 3 */ -+ uint64_t subdid:3; /* PCIe SubDID = 3-6 */ -+ uint64_t reserved_36_39:4; /* Must be zero */ -+ uint64_t address:36; /* PCIe Mem address */ -+ } mem; -+}; -+ -+/** -+ * Return the Core virtual base address for PCIe IO access. IOs are -+ * read/written as an offset from this address. -+ * -+ * @pcie_port: PCIe port the IO is for -+ * -+ * Returns 64bit Octeon IO base address for read/write -+ */ -+uint64_t cvmx_pcie_get_io_base_address(int pcie_port); -+ -+/** -+ * Size of the IO address region returned at address -+ * cvmx_pcie_get_io_base_address() -+ * -+ * @pcie_port: PCIe port the IO is for -+ * -+ * Returns Size of the IO window -+ */ -+uint64_t cvmx_pcie_get_io_size(int pcie_port); -+ -+/** -+ * Return the Core virtual base address for PCIe MEM access. Memory is -+ * read/written as an offset from this address. -+ * -+ * @pcie_port: PCIe port the IO is for -+ * -+ * Returns 64bit Octeon IO base address for read/write -+ */ -+uint64_t cvmx_pcie_get_mem_base_address(int pcie_port); -+ -+/** -+ * Size of the Mem address region returned at address -+ * cvmx_pcie_get_mem_base_address() -+ * -+ * @pcie_port: PCIe port the IO is for -+ * -+ * Returns Size of the Mem window -+ */ -+uint64_t cvmx_pcie_get_mem_size(int pcie_port); -+ -+/** -+ * Initialize a PCIe port for use in host(RC) mode. It doesn't -+ * enumerate the bus. -+ * -+ * @pcie_port: PCIe port to initialize -+ * -+ * Returns Zero on success -+ */ -+int cvmx_pcie_rc_initialize(int pcie_port); -+ -+/** -+ * Shutdown a PCIe port and put it in reset -+ * -+ * @pcie_port: PCIe port to shutdown -+ * -+ * Returns Zero on success -+ */ -+int cvmx_pcie_rc_shutdown(int pcie_port); -+ -+/** -+ * Read 8bits from a Device's config space -+ * -+ * @pcie_port: PCIe port the device is on -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * -+ * Returns Result of the read -+ */ -+uint8_t cvmx_pcie_config_read8(int pcie_port, int bus, int dev, int fn, -+ int reg); -+ -+/** -+ * Read 16bits from a Device's config space -+ * -+ * @pcie_port: PCIe port the device is on -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * -+ * Returns Result of the read -+ */ -+uint16_t cvmx_pcie_config_read16(int pcie_port, int bus, int dev, int fn, -+ int reg); -+ -+/** -+ * Read 32bits from a Device's config space -+ * -+ * @pcie_port: PCIe port the device is on -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * -+ * Returns Result of the read -+ */ -+uint32_t cvmx_pcie_config_read32(int pcie_port, int bus, int dev, int fn, -+ int reg); -+ -+/** -+ * Write 8bits to a Device's config space -+ * -+ * @pcie_port: PCIe port the device is on -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * @val: Value to write -+ */ -+void cvmx_pcie_config_write8(int pcie_port, int bus, int dev, int fn, int reg, -+ uint8_t val); -+ -+/** -+ * Write 16bits to a Device's config space -+ * -+ * @pcie_port: PCIe port the device is on -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * @val: Value to write -+ */ -+void cvmx_pcie_config_write16(int pcie_port, int bus, int dev, int fn, int reg, -+ uint16_t val); -+ -+/** -+ * Write 32bits to a Device's config space -+ * -+ * @pcie_port: PCIe port the device is on -+ * @bus: Sub bus -+ * @dev: Device ID -+ * @fn: Device sub function -+ * @reg: Register to access -+ * @val: Value to write -+ */ -+void cvmx_pcie_config_write32(int pcie_port, int bus, int dev, int fn, int reg, -+ uint32_t val); -+ -+/** -+ * Read a PCIe config space register indirectly. This is used for -+ * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???. -+ * -+ * @pcie_port: PCIe port to read from -+ * @cfg_offset: Address to read -+ * -+ * Returns Value read -+ */ -+uint32_t cvmx_pcie_cfgx_read(int pcie_port, uint32_t cfg_offset); -+ -+/** -+ * Write a PCIe config space register indirectly. This is used for -+ * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???. -+ * -+ * @pcie_port: PCIe port to write to -+ * @cfg_offset: Address to write -+ * @val: Value to write -+ */ -+void cvmx_pcie_cfgx_write(int pcie_port, uint32_t cfg_offset, uint32_t val); -+ -+/** -+ * Write a 32bit value to the Octeon NPEI register space -+ * -+ * @address: Address to write to -+ * @val: Value to write -+ */ -+static inline void cvmx_pcie_npei_write32(uint64_t address, uint32_t val) -+{ -+ cvmx_write64_uint32(address ^ 4, val); -+ cvmx_read64_uint32(address ^ 4); -+} -+ -+/** -+ * Read a 32bit value from the Octeon NPEI register space -+ * -+ * @address: Address to read -+ * Returns The result -+ */ -+static inline uint32_t cvmx_pcie_npei_read32(uint64_t address) -+{ -+ return cvmx_read64_uint32(address ^ 4); -+} -+ -+/** -+ * Initialize a PCIe port for use in target(EP) mode. -+ * -+ * Returns Zero on success -+ */ -+int cvmx_pcie_ep_initialize(void); -+ -+#endif ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-wqe.h -@@ -0,0 +1,422 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * This header file defines the work queue entry (wqe) data structure. -+ * Since this is a commonly used structure that depends on structures -+ * from several hardware blocks, those definitions have been placed -+ * in this file to create a single point of definition of the wqe -+ * format. -+ * -+ * Data structures are still named according to the block that they -+ * relate to. -+ * -+ */ -+ -+#ifndef __CVMX_WQE_H__ -+#define __CVMX_WQE_H__ -+ -+#include "cvmx-packet.h" -+ -+#define OCT_TAG_TYPE_STRING(x) ( \ -+ { \ -+ const char *r; \ -+ switch (x) { \ -+ case CVMX_POW_TAG_TYPE_ORDERED: \ -+ r = "ORDERED"; \ -+ break; \ -+ case CVMX_POW_TAG_TYPE_ATOMIC: \ -+ r = "ATOMIC"; \ -+ break; \ -+ case CVMX_POW_TAG_TYPE_NULL: \ -+ r = "NULL"; \ -+ break; \ -+ default: \ -+ r = "NULL_NULL"; \ -+ break; \ -+ } \ -+ r; \ -+ }) -+ -+/** -+ * HW decode / err_code in work queue entry -+ */ -+union cvmx_pip_wqe_word2{ -+ uint64_t u64; -+ -+ /* Use this struct if the hardware determines that the packet is IP */ -+ struct { -+ /* HW sets this to the number of buffers used by this packet */ -+ uint64_t bufs:8; -+ /* HW sets to the number of L2 bytes prior to the IP */ -+ uint64_t ip_offset:8; -+ /* Set to 1 if we found VLAN in the L2 */ -+ uint64_t vlan_valid:1; -+ uint64_t unassigned:2; -+ /* HW sets to the VLAN CFI flag (valid when vlan_valid) */ -+ uint64_t vlan_cfi:1; -+ /* HW sets to the VLAN_ID field (valid when vlan_valid) */ -+ uint64_t vlan_id:12; -+ -+ uint64_t unassigned2:12; -+ /* The packet needs to be decompressed */ -+ uint64_t dec_ipcomp:1; -+ /* The packet is either TCP or UDP */ -+ uint64_t tcp_or_udp:1; -+ /* The packet needs to be decrypted (ESP or AH) */ -+ uint64_t dec_ipsec:1; -+ /* The packet is IPv6 */ -+ uint64_t is_v6:1; -+ -+ /* -+ * rcv_error, not_IP, IP_exc, is_frag, L4_error, -+ * software, etc. -+ */ -+ -+ /* -+ * Reserved for software use, hardware will clear on -+ * packet creation. -+ */ -+ uint64_t software:1; -+ /* exceptional conditions below. */ -+ -+ /* -+ * The receive interface hardware detected an L4 error -+ * (only applies if !is_frag) (only applies if -+ * !rcv_error && !not_IP && !IP_exc && !is_frag) -+ * failure indicated in err_code below, decode: -+ * -+ * - 1 = Malformed L4 -+ * -+ * - 2 = L4 Checksum Error: the L4 checksum value is -+ * -+ * - 3 = UDP Length Error: The UDP length field would -+ * make the UDP data longer than what remains in -+ * the IP packet (as defined by the IP header -+ * length field). -+ * -+ * - 4 = Bad L4 Port: either the source or destination -+ * TCP/UDP port is 0. -+ * -+ * - 8 = TCP FIN Only: the packet is TCP and only the -+ * FIN flag set. -+ * -+ * - 9 = TCP No Flags: the packet is TCP and no flags -+ * are set. -+ * -+ * - 10 = TCP FIN RST: the packet is TCP and both FIN -+ * and RST are set. -+ * -+ * - 11 = TCP SYN URG: the packet is TCP and both SYN -+ * and URG are set. -+ * -+ * - 12 = TCP SYN RST: the packet is TCP and both SYN -+ * and RST are set. -+ * -+ * - 13 = TCP SYN FIN: the packet is TCP and both SYN -+ * and FIN are set. -+ * -+ */ -+ uint64_t L4_error:1; -+ /* Set if the packet is a fragment */ -+ uint64_t is_frag:1; -+ -+ /* -+ * The receive interface hardware detected an IP error -+ * / exception (only applies if !rcv_error && !not_IP) -+ * failure indicated in err_code below, decode: -+ * -+ * - 1 = Not IP: the IP version field is neither 4 nor -+ * 6. -+ * -+ * - 2 = IPv4 Header Checksum Error: the IPv4 header -+ * has a checksum violation. -+ * -+ * - 3 = IP Malformed Header: the packet is not long -+ * enough to contain the IP header. -+ * -+ * - 4 = IP Malformed: the packet is not long enough -+ * to contain the bytes indicated by the IP -+ * header. Pad is allowed. -+ * -+ * - 5 = IP TTL Hop: the IPv4 TTL field or the IPv6 -+ * Hop Count field are zero. -+ * -+ * - 6 = IP Options. -+ */ -+ uint64_t IP_exc:1; -+ /* -+ * Set if the hardware determined that the packet is a -+ * broadcast. -+ */ -+ uint64_t is_bcast:1; -+ /* -+ * Set if the hardware determined that the packet is a -+ * multi-cast. -+ */ -+ uint64_t is_mcast:1; -+ /* -+ * Set if the packet may not be IP (must be zero in -+ * this case). -+ */ -+ uint64_t not_IP:1; -+ /* -+ * The receive interface hardware detected a receive -+ * error (must be zero in this case) -+ * -+ * lower err_code = first-level descriptor of the work -+ * -+ * zero for packet submitted by hardware that isn't on -+ * the slow path. -+ */ -+ uint64_t rcv_error:1; -+ -+ /* Type is cvmx_pip_err_t */ -+ uint64_t err_code:8; -+ } s; -+ -+ /* Use this to get at the 16 vlan bits */ -+ struct { -+ uint64_t unused1:16; -+ uint64_t vlan:16; -+ uint64_t unused2:32; -+ } svlan; -+ -+ /* -+ * Use this struct if the hardware could not determine that -+ * the packet is ip. -+ */ -+ struct { -+ /* HW sets this to the number of buffers used by this packet. */ -+ uint64_t bufs:8; -+ uint64_t unused:8; -+ /* Set to 1 if we found VLAN in the L2. */ -+ uint64_t vlan_valid:1; -+ uint64_t unassigned:2; -+ /* HW sets to the VLAN CFI flag (valid when vlan_valid). */ -+ uint64_t vlan_cfi:1; -+ /* HW sets to the VLAN_ID field (valid when vlan_valid). */ -+ uint64_t vlan_id:12; -+ -+ uint64_t unassigned2:16; -+ /* -+ * Reserved for software use, hardware will clear on -+ * packet creation. -+ */ -+ uint64_t software:1; -+ uint64_t unassigned3:1; -+ /* Set if the hardware determined that the packet is rarp. */ -+ uint64_t is_rarp:1; -+ /* Set if the hardware determined that the packet is arp. */ -+ uint64_t is_arp:1; -+ /* -+ * Set if the hardware determined that the packet is a -+ * broadcast. -+ */ -+ uint64_t is_bcast:1; -+ /* -+ * Set if the hardware determined that the packet is a -+ * multi-cast. -+ */ -+ uint64_t is_mcast:1; -+ /* -+ * Set if the packet may not be IP (must be one in -+ * this case). -+ */ -+ uint64_t not_IP:1; -+ /* -+ * The receive interface hardware detected a receive -+ * error. Failure indicated in err_code below, decode: -+ * -+ * - 1 = partial error: a packet was partially -+ * received, but internal buffering / bandwidth -+ * was not adequate to receive the entire -+ * packet. -+ * -+ * - 2 = jabber error: the RGMII packet was too large -+ * and is truncated. -+ * -+ * - 3 = overrun error: the RGMII packet is longer -+ * than allowed and had an FCS error. -+ * -+ * - 4 = oversize error: the RGMII packet is longer -+ * than allowed. -+ * -+ * - 5 = alignment error: the RGMII packet is not an -+ * integer number of bytes and had an FCS error -+ * (100M and 10M only). -+ * -+ * - 6 = fragment error: the RGMII packet is shorter -+ * than allowed and had an FCS error. -+ * -+ * - 7 = GMX FCS error: the RGMII packet had an FCS -+ * error. -+ * -+ * - 8 = undersize error: the RGMII packet is shorter -+ * than allowed. -+ * -+ * - 9 = extend error: the RGMII packet had an extend -+ * error. -+ * -+ * - 10 = length mismatch error: the RGMII packet had -+ * a length that did not match the length field -+ * in the L2 HDR. -+ * -+ * - 11 = RGMII RX error/SPI4 DIP4 Error: the RGMII -+ * packet had one or more data reception errors -+ * (RXERR) or the SPI4 packet had one or more -+ * DIP4 errors. -+ * -+ * - 12 = RGMII skip error/SPI4 Abort Error: the RGMII -+ * packet was not large enough to cover the -+ * skipped bytes or the SPI4 packet was -+ * terminated with an About EOPS. -+ * -+ * - 13 = RGMII nibble error/SPI4 Port NXA Error: the -+ * RGMII packet had a studder error (data not -+ * repeated - 10/100M only) or the SPI4 packet -+ * was sent to an NXA. -+ * -+ * - 16 = FCS error: a SPI4.2 packet had an FCS error. -+ * -+ * - 17 = Skip error: a packet was not large enough to -+ * cover the skipped bytes. -+ * -+ * - 18 = L2 header malformed: the packet is not long -+ * enough to contain the L2 -+ */ -+ -+ /* -+ * lower err_code = first-level descriptor of the -+ * work. -+ * -+ * zero for packet submitted by hardware that isn't on -+ * the slow path. -+ */ -+ uint64_t rcv_error:1; -+ -+ /* Type is cvmx_pip_err_t (union, so can't use directly. */ -+ uint64_t err_code:8; -+ } snoip; -+ -+}; -+ -+/** -+ * Work queue entry format -+ * -+ * must be 8-byte aligned -+ */ -+struct cvmx_wqe { -+ -+ /***************************************************************** -+ * WORD 0 -+ * HW WRITE: the following 64 bits are filled by HW when a packet arrives -+ */ -+ -+ /** -+ * raw chksum result generated by the HW -+ */ -+ uint16_t hw_chksum; -+ /** -+ * Field unused by hardware - available for software -+ */ -+ uint8_t unused; -+ /** -+ * Next pointer used by hardware for list maintenance. -+ * May be written/read by HW before the work queue -+ * entry is scheduled to a PP -+ * (Only 36 bits used in Octeon 1) -+ */ -+ uint64_t next_ptr:40; -+ -+ /***************************************************************** -+ * WORD 1 -+ * HW WRITE: the following 64 bits are filled by HW when a packet arrives -+ */ -+ -+ /** -+ * HW sets to the total number of bytes in the packet -+ */ -+ uint64_t len:16; -+ /** -+ * HW sets this to input physical port -+ */ -+ uint64_t ipprt:6; -+ -+ /** -+ * HW sets this to what it thought the priority of the input packet was -+ */ -+ uint64_t qos:3; -+ -+ /** -+ * the group that the work queue entry will be scheduled to -+ */ -+ uint64_t grp:4; -+ /** -+ * the type of the tag (ORDERED, ATOMIC, NULL) -+ */ -+ uint64_t tag_type:3; -+ /** -+ * the synchronization/ordering tag -+ */ -+ uint64_t tag:32; -+ -+ /** -+ * WORD 2 HW WRITE: the following 64-bits are filled in by -+ * hardware when a packet arrives This indicates a variety of -+ * status and error conditions. -+ */ -+ union cvmx_pip_wqe_word2 word2; -+ -+ /** -+ * Pointer to the first segment of the packet. -+ */ -+ union cvmx_buf_ptr packet_ptr; -+ -+ /** -+ * HW WRITE: octeon will fill in a programmable amount from the -+ * packet, up to (at most, but perhaps less) the amount -+ * needed to fill the work queue entry to 128 bytes -+ * If the packet is recognized to be IP, the hardware starts (except that -+ * the IPv4 header is padded for appropriate alignment) writing here where -+ * the IP header starts. -+ * If the packet is not recognized to be IP, the hardware starts writing -+ * the beginning of the packet here. -+ */ -+ uint8_t packet_data[96]; -+ -+ /** -+ * If desired, SW can make the work Q entry any length. For the -+ * purposes of discussion here, Assume 128B always, as this is all that -+ * the hardware deals with. -+ * -+ */ -+ -+} CVMX_CACHE_LINE_ALIGNED; -+ -+#endif /* __CVMX_WQE_H__ */ ---- a/arch/mips/include/asm/octeon/cvmx.h -+++ b/arch/mips/include/asm/octeon/cvmx.h -@@ -376,6 +376,18 @@ static inline uint64_t cvmx_get_cycle(vo - } - - /** -+ * Wait for the specified number of cycle -+ * -+ */ -+static inline void cvmx_wait(uint64_t cycles) -+{ -+ uint64_t done = cvmx_get_cycle() + cycles; -+ -+ while (cvmx_get_cycle() < done) -+ ; /* Spin */ -+} -+ -+/** - * Reads a chip global cycle counter. This counts CPU cycles since - * chip reset. The counter is 64 bit. - * This register does not exist on CN38XX pass 1 silicion ---- a/arch/mips/include/asm/octeon/octeon.h -+++ b/arch/mips/include/asm/octeon/octeon.h -@@ -245,4 +245,6 @@ static inline uint32_t octeon_npi_read32 - return cvmx_read64_uint32(address ^ 4); - } - -+extern struct cvmx_bootinfo *octeon_bootinfo; -+ - #endif /* __ASM_OCTEON_OCTEON_H */ diff --git a/target/linux/octeon/patches-2.6.30/004-named_alloc_function.patch b/target/linux/octeon/patches-2.6.30/004-named_alloc_function.patch deleted file mode 100644 index a3135f0a8a..0000000000 --- a/target/linux/octeon/patches-2.6.30/004-named_alloc_function.patch +++ /dev/null @@ -1,223 +0,0 @@ -The MGMT ethernet driver uses these new functions. - -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - arch/mips/cavium-octeon/executive/cvmx-bootmem.c | 101 ++++++++++++++++++++++ - arch/mips/include/asm/octeon/cvmx-bootmem.h | 85 ++++++++++++++++++ - 2 files changed, 186 insertions(+), 0 deletions(-) - ---- a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c -+++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c -@@ -97,6 +97,32 @@ void *cvmx_bootmem_alloc(uint64_t size, - return cvmx_bootmem_alloc_range(size, alignment, 0, 0); - } - -+void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, -+ uint64_t max_addr, uint64_t align, -+ char *name) -+{ -+ int64_t addr; -+ -+ addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr, -+ align, name, 0); -+ if (addr >= 0) -+ return cvmx_phys_to_ptr(addr); -+ else -+ return NULL; -+} -+ -+void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address, -+ char *name) -+{ -+ return cvmx_bootmem_alloc_named_range(size, address, address + size, -+ 0, name); -+} -+ -+void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, char *name) -+{ -+ return cvmx_bootmem_alloc_named_range(size, 0, 0, alignment, name); -+} -+ - int cvmx_bootmem_free_named(char *name) - { - return cvmx_bootmem_phy_named_block_free(name, 0); -@@ -584,3 +610,78 @@ int cvmx_bootmem_phy_named_block_free(ch - cvmx_bootmem_unlock(); - return named_block_ptr != NULL; /* 0 on failure, 1 on success */ - } -+ -+int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr, -+ uint64_t max_addr, -+ uint64_t alignment, -+ char *name, -+ uint32_t flags) -+{ -+ int64_t addr_allocated; -+ struct cvmx_bootmem_named_block_desc *named_block_desc_ptr; -+ -+#ifdef DEBUG -+ cvmx_dprintf("cvmx_bootmem_phy_named_block_alloc: size: 0x%llx, min: " -+ "0x%llx, max: 0x%llx, align: 0x%llx, name: %s\n", -+ (unsigned long long)size, -+ (unsigned long long)min_addr, -+ (unsigned long long)max_addr, -+ (unsigned long long)alignment, -+ name); -+#endif -+ if (cvmx_bootmem_desc->major_version != 3) { -+ cvmx_dprintf("ERROR: Incompatible bootmem descriptor version: " -+ "%d.%d at addr: %p\n", -+ (int)cvmx_bootmem_desc->major_version, -+ (int)cvmx_bootmem_desc->minor_version, -+ cvmx_bootmem_desc); -+ return -1; -+ } -+ -+ /* -+ * Take lock here, as name lookup/block alloc/name add need to -+ * be atomic. -+ */ -+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING)) -+ cvmx_spinlock_lock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock)); -+ -+ /* Get pointer to first available named block descriptor */ -+ named_block_desc_ptr = -+ cvmx_bootmem_phy_named_block_find(NULL, -+ flags | CVMX_BOOTMEM_FLAG_NO_LOCKING); -+ -+ /* -+ * Check to see if name already in use, return error if name -+ * not available or no more room for blocks. -+ */ -+ if (cvmx_bootmem_phy_named_block_find(name, -+ flags | CVMX_BOOTMEM_FLAG_NO_LOCKING) || !named_block_desc_ptr) { -+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING)) -+ cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock)); -+ return -1; -+ } -+ -+ -+ /* -+ * Round size up to mult of minimum alignment bytes We need -+ * the actual size allocated to allow for blocks to be -+ * coallesced when they are freed. The alloc routine does the -+ * same rounding up on all allocations. -+ */ -+ size = __ALIGN_MASK(size, (CVMX_BOOTMEM_ALIGNMENT_SIZE - 1)); -+ -+ addr_allocated = cvmx_bootmem_phy_alloc(size, min_addr, max_addr, -+ alignment, -+ flags | CVMX_BOOTMEM_FLAG_NO_LOCKING); -+ if (addr_allocated >= 0) { -+ named_block_desc_ptr->base_addr = addr_allocated; -+ named_block_desc_ptr->size = size; -+ strncpy(named_block_desc_ptr->name, name, -+ cvmx_bootmem_desc->named_block_name_len); -+ named_block_desc_ptr->name[cvmx_bootmem_desc->named_block_name_len - 1] = 0; -+ } -+ -+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING)) -+ cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock)); -+ return addr_allocated; -+} ---- a/arch/mips/include/asm/octeon/cvmx-bootmem.h -+++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h -@@ -183,6 +183,64 @@ extern void *cvmx_bootmem_alloc_range(ui - * Returns 0 on failure, - * !0 on success - */ -+ -+ -+/** -+ * Allocate a block of memory from the free list that was passed -+ * to the application by the bootloader, and assign it a name in the -+ * global named block table. (part of the cvmx_bootmem_descriptor_t structure) -+ * Named blocks can later be freed. -+ * -+ * @size: Size in bytes of block to allocate -+ * @alignment: Alignment required - must be power of 2 -+ * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes -+ * -+ * Returns a pointer to block of memory, NULL on error -+ */ -+extern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, -+ char *name); -+ -+ -+ -+/** -+ * Allocate a block of memory from the free list that was passed -+ * to the application by the bootloader, and assign it a name in the -+ * global named block table. (part of the cvmx_bootmem_descriptor_t structure) -+ * Named blocks can later be freed. -+ * -+ * @size: Size in bytes of block to allocate -+ * @address: Physical address to allocate memory at. If this -+ * memory is not available, the allocation fails. -+ * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN -+ * bytes -+ * -+ * Returns a pointer to block of memory, NULL on error -+ */ -+extern void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address, -+ char *name); -+ -+ -+ -+/** -+ * Allocate a block of memory from a specific range of the free list -+ * that was passed to the application by the bootloader, and assign it -+ * a name in the global named block table. (part of the -+ * cvmx_bootmem_descriptor_t structure) Named blocks can later be -+ * freed. If request cannot be satisfied within the address range -+ * specified, NULL is returned -+ * -+ * @size: Size in bytes of block to allocate -+ * @min_addr: minimum address of range -+ * @max_addr: maximum address of range -+ * @align: Alignment of memory to be allocated. (must be a power of 2) -+ * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes -+ * -+ * Returns a pointer to block of memory, NULL on error -+ */ -+extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, -+ uint64_t max_addr, uint64_t align, -+ char *name); -+ - extern int cvmx_bootmem_free_named(char *name); - - /** -@@ -224,6 +282,33 @@ int64_t cvmx_bootmem_phy_alloc(uint64_t - uint32_t flags); - - /** -+ * Allocates a named block of physical memory from the free list, at -+ * (optional) requested address and alignment. -+ * -+ * @param size size of region to allocate. All requests are rounded -+ * up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE -+ * bytes size -+ * @param min_addr Minimum address that block can occupy. -+ * @param max_addr Specifies the maximum address_min (inclusive) that -+ * the allocation can use. -+ * @param alignment Requested alignment of the block. If this -+ * alignment cannot be met, the allocation fails. -+ * This must be a power of 2. (Note: Alignment of -+ * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and -+ * internally enforced. Requested alignments of less -+ * than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to -+ * CVMX_BOOTMEM_ALIGNMENT_SIZE.) -+ * @param name name to assign to named block -+ * @param flags Flags to control options for the allocation. -+ * -+ * @return physical address of block allocated, or -1 on failure -+ */ -+int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr, -+ uint64_t max_addr, -+ uint64_t alignment, -+ char *name, uint32_t flags); -+ -+/** - * Finds a named memory block by name. - * Also used for finding an unused entry in the named block table. - * diff --git a/target/linux/octeon/patches-2.6.30/005-register_defs_octeon_mgmt.patch b/target/linux/octeon/patches-2.6.30/005-register_defs_octeon_mgmt.patch deleted file mode 100644 index 5169f6cf65..0000000000 --- a/target/linux/octeon/patches-2.6.30/005-register_defs_octeon_mgmt.patch +++ /dev/null @@ -1,1642 +0,0 @@ -The MGMT ethernet driver uses the AGL, MIXX and SMIX blocks, so we add -definitions for them. - -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - arch/mips/include/asm/octeon/cvmx-agl-defs.h | 1194 +++++++++++++++++++++++++ - arch/mips/include/asm/octeon/cvmx-mixx-defs.h | 248 +++++ - arch/mips/include/asm/octeon/cvmx-smix-defs.h | 178 ++++ - 3 files changed, 1620 insertions(+), 0 deletions(-) - create mode 100644 arch/mips/include/asm/octeon/cvmx-agl-defs.h - create mode 100644 arch/mips/include/asm/octeon/cvmx-mixx-defs.h - create mode 100644 arch/mips/include/asm/octeon/cvmx-smix-defs.h - ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-agl-defs.h -@@ -0,0 +1,1194 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_AGL_DEFS_H__ -+#define __CVMX_AGL_DEFS_H__ -+ -+#define CVMX_AGL_GMX_BAD_REG \ -+ CVMX_ADD_IO_SEG(0x00011800E0000518ull) -+#define CVMX_AGL_GMX_BIST \ -+ CVMX_ADD_IO_SEG(0x00011800E0000400ull) -+#define CVMX_AGL_GMX_DRV_CTL \ -+ CVMX_ADD_IO_SEG(0x00011800E00007F0ull) -+#define CVMX_AGL_GMX_INF_MODE \ -+ CVMX_ADD_IO_SEG(0x00011800E00007F8ull) -+#define CVMX_AGL_GMX_PRTX_CFG(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000010ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_ADR_CAM0(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000180ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_ADR_CAM1(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000188ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_ADR_CAM2(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000190ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_ADR_CAM3(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000198ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_ADR_CAM4(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00001A0ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_ADR_CAM5(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00001A8ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_ADR_CAM_EN(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000108ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_ADR_CTL(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000100ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_DECISION(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000040ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_FRM_CHK(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000020ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_FRM_CTL(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000018ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_FRM_MAX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000030ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_FRM_MIN(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000028ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_IFG(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000058ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_INT_EN(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000008ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_INT_REG(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000000ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_JABBER(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000038ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_PAUSE_DROP_TIME(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000068ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_STATS_CTL(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000050ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_STATS_OCTS(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000088ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_STATS_OCTS_CTL(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000098ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_STATS_OCTS_DMAC(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00000A8ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_STATS_OCTS_DRP(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00000B8ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_STATS_PKTS(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000080ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00000C0ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_STATS_PKTS_CTL(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000090ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_STATS_PKTS_DMAC(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00000A0ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00000B0ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RXX_UDD_SKP(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000048ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_RX_BP_DROPX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000420ull + (((offset) & 1) * 8)) -+#define CVMX_AGL_GMX_RX_BP_OFFX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000460ull + (((offset) & 1) * 8)) -+#define CVMX_AGL_GMX_RX_BP_ONX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000440ull + (((offset) & 1) * 8)) -+#define CVMX_AGL_GMX_RX_PRT_INFO \ -+ CVMX_ADD_IO_SEG(0x00011800E00004E8ull) -+#define CVMX_AGL_GMX_RX_TX_STATUS \ -+ CVMX_ADD_IO_SEG(0x00011800E00007E8ull) -+#define CVMX_AGL_GMX_SMACX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000230ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_STAT_BP \ -+ CVMX_ADD_IO_SEG(0x00011800E0000520ull) -+#define CVMX_AGL_GMX_TXX_APPEND(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000218ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_CTL(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000270ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_MIN_PKT(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000240ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_PAUSE_PKT_INTERVAL(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000248ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_PAUSE_PKT_TIME(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000238ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_PAUSE_TOGO(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000258ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_PAUSE_ZERO(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000260ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_SOFT_PAUSE(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000250ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_STAT0(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000280ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_STAT1(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000288ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_STAT2(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000290ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_STAT3(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000298ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_STAT4(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00002A0ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_STAT5(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00002A8ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_STAT6(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00002B0ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_STAT7(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00002B8ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_STAT8(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00002C0ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_STAT9(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E00002C8ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_STATS_CTL(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000268ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TXX_THRESH(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800E0000210ull + (((offset) & 1) * 2048)) -+#define CVMX_AGL_GMX_TX_BP \ -+ CVMX_ADD_IO_SEG(0x00011800E00004D0ull) -+#define CVMX_AGL_GMX_TX_COL_ATTEMPT \ -+ CVMX_ADD_IO_SEG(0x00011800E0000498ull) -+#define CVMX_AGL_GMX_TX_IFG \ -+ CVMX_ADD_IO_SEG(0x00011800E0000488ull) -+#define CVMX_AGL_GMX_TX_INT_EN \ -+ CVMX_ADD_IO_SEG(0x00011800E0000508ull) -+#define CVMX_AGL_GMX_TX_INT_REG \ -+ CVMX_ADD_IO_SEG(0x00011800E0000500ull) -+#define CVMX_AGL_GMX_TX_JAM \ -+ CVMX_ADD_IO_SEG(0x00011800E0000490ull) -+#define CVMX_AGL_GMX_TX_LFSR \ -+ CVMX_ADD_IO_SEG(0x00011800E00004F8ull) -+#define CVMX_AGL_GMX_TX_OVR_BP \ -+ CVMX_ADD_IO_SEG(0x00011800E00004C8ull) -+#define CVMX_AGL_GMX_TX_PAUSE_PKT_DMAC \ -+ CVMX_ADD_IO_SEG(0x00011800E00004A0ull) -+#define CVMX_AGL_GMX_TX_PAUSE_PKT_TYPE \ -+ CVMX_ADD_IO_SEG(0x00011800E00004A8ull) -+ -+union cvmx_agl_gmx_bad_reg { -+ uint64_t u64; -+ struct cvmx_agl_gmx_bad_reg_s { -+ uint64_t reserved_38_63:26; -+ uint64_t txpsh1:1; -+ uint64_t txpop1:1; -+ uint64_t ovrflw1:1; -+ uint64_t txpsh:1; -+ uint64_t txpop:1; -+ uint64_t ovrflw:1; -+ uint64_t reserved_27_31:5; -+ uint64_t statovr:1; -+ uint64_t reserved_23_25:3; -+ uint64_t loststat:1; -+ uint64_t reserved_4_21:18; -+ uint64_t out_ovr:2; -+ uint64_t reserved_0_1:2; -+ } s; -+ struct cvmx_agl_gmx_bad_reg_s cn52xx; -+ struct cvmx_agl_gmx_bad_reg_s cn52xxp1; -+ struct cvmx_agl_gmx_bad_reg_cn56xx { -+ uint64_t reserved_35_63:29; -+ uint64_t txpsh:1; -+ uint64_t txpop:1; -+ uint64_t ovrflw:1; -+ uint64_t reserved_27_31:5; -+ uint64_t statovr:1; -+ uint64_t reserved_23_25:3; -+ uint64_t loststat:1; -+ uint64_t reserved_3_21:19; -+ uint64_t out_ovr:1; -+ uint64_t reserved_0_1:2; -+ } cn56xx; -+ struct cvmx_agl_gmx_bad_reg_cn56xx cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_bist { -+ uint64_t u64; -+ struct cvmx_agl_gmx_bist_s { -+ uint64_t reserved_10_63:54; -+ uint64_t status:10; -+ } s; -+ struct cvmx_agl_gmx_bist_s cn52xx; -+ struct cvmx_agl_gmx_bist_s cn52xxp1; -+ struct cvmx_agl_gmx_bist_s cn56xx; -+ struct cvmx_agl_gmx_bist_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_drv_ctl { -+ uint64_t u64; -+ struct cvmx_agl_gmx_drv_ctl_s { -+ uint64_t reserved_49_63:15; -+ uint64_t byp_en1:1; -+ uint64_t reserved_45_47:3; -+ uint64_t pctl1:5; -+ uint64_t reserved_37_39:3; -+ uint64_t nctl1:5; -+ uint64_t reserved_17_31:15; -+ uint64_t byp_en:1; -+ uint64_t reserved_13_15:3; -+ uint64_t pctl:5; -+ uint64_t reserved_5_7:3; -+ uint64_t nctl:5; -+ } s; -+ struct cvmx_agl_gmx_drv_ctl_s cn52xx; -+ struct cvmx_agl_gmx_drv_ctl_s cn52xxp1; -+ struct cvmx_agl_gmx_drv_ctl_cn56xx { -+ uint64_t reserved_17_63:47; -+ uint64_t byp_en:1; -+ uint64_t reserved_13_15:3; -+ uint64_t pctl:5; -+ uint64_t reserved_5_7:3; -+ uint64_t nctl:5; -+ } cn56xx; -+ struct cvmx_agl_gmx_drv_ctl_cn56xx cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_inf_mode { -+ uint64_t u64; -+ struct cvmx_agl_gmx_inf_mode_s { -+ uint64_t reserved_2_63:62; -+ uint64_t en:1; -+ uint64_t reserved_0_0:1; -+ } s; -+ struct cvmx_agl_gmx_inf_mode_s cn52xx; -+ struct cvmx_agl_gmx_inf_mode_s cn52xxp1; -+ struct cvmx_agl_gmx_inf_mode_s cn56xx; -+ struct cvmx_agl_gmx_inf_mode_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_prtx_cfg { -+ uint64_t u64; -+ struct cvmx_agl_gmx_prtx_cfg_s { -+ uint64_t reserved_6_63:58; -+ uint64_t tx_en:1; -+ uint64_t rx_en:1; -+ uint64_t slottime:1; -+ uint64_t duplex:1; -+ uint64_t speed:1; -+ uint64_t en:1; -+ } s; -+ struct cvmx_agl_gmx_prtx_cfg_s cn52xx; -+ struct cvmx_agl_gmx_prtx_cfg_s cn52xxp1; -+ struct cvmx_agl_gmx_prtx_cfg_s cn56xx; -+ struct cvmx_agl_gmx_prtx_cfg_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_adr_cam0 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_adr_cam0_s { -+ uint64_t adr:64; -+ } s; -+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xx; -+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xx; -+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_adr_cam1 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_adr_cam1_s { -+ uint64_t adr:64; -+ } s; -+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xx; -+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xx; -+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_adr_cam2 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_adr_cam2_s { -+ uint64_t adr:64; -+ } s; -+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xx; -+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xx; -+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_adr_cam3 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_adr_cam3_s { -+ uint64_t adr:64; -+ } s; -+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xx; -+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xx; -+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_adr_cam4 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_adr_cam4_s { -+ uint64_t adr:64; -+ } s; -+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xx; -+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xx; -+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_adr_cam5 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_adr_cam5_s { -+ uint64_t adr:64; -+ } s; -+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xx; -+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xx; -+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_adr_cam_en { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_adr_cam_en_s { -+ uint64_t reserved_8_63:56; -+ uint64_t en:8; -+ } s; -+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xx; -+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xx; -+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_adr_ctl { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_adr_ctl_s { -+ uint64_t reserved_4_63:60; -+ uint64_t cam_mode:1; -+ uint64_t mcst:2; -+ uint64_t bcst:1; -+ } s; -+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xx; -+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xx; -+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_decision { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_decision_s { -+ uint64_t reserved_5_63:59; -+ uint64_t cnt:5; -+ } s; -+ struct cvmx_agl_gmx_rxx_decision_s cn52xx; -+ struct cvmx_agl_gmx_rxx_decision_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_decision_s cn56xx; -+ struct cvmx_agl_gmx_rxx_decision_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_frm_chk { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_frm_chk_s { -+ uint64_t reserved_9_63:55; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t lenerr:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t maxerr:1; -+ uint64_t reserved_1_1:1; -+ uint64_t minerr:1; -+ } s; -+ struct cvmx_agl_gmx_rxx_frm_chk_s cn52xx; -+ struct cvmx_agl_gmx_rxx_frm_chk_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_frm_chk_s cn56xx; -+ struct cvmx_agl_gmx_rxx_frm_chk_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_frm_ctl { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_frm_ctl_s { -+ uint64_t reserved_10_63:54; -+ uint64_t pre_align:1; -+ uint64_t pad_len:1; -+ uint64_t vlan_len:1; -+ uint64_t pre_free:1; -+ uint64_t ctl_smac:1; -+ uint64_t ctl_mcst:1; -+ uint64_t ctl_bck:1; -+ uint64_t ctl_drp:1; -+ uint64_t pre_strp:1; -+ uint64_t pre_chk:1; -+ } s; -+ struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xx; -+ struct cvmx_agl_gmx_rxx_frm_ctl_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xx; -+ struct cvmx_agl_gmx_rxx_frm_ctl_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_frm_max { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_frm_max_s { -+ uint64_t reserved_16_63:48; -+ uint64_t len:16; -+ } s; -+ struct cvmx_agl_gmx_rxx_frm_max_s cn52xx; -+ struct cvmx_agl_gmx_rxx_frm_max_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_frm_max_s cn56xx; -+ struct cvmx_agl_gmx_rxx_frm_max_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_frm_min { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_frm_min_s { -+ uint64_t reserved_16_63:48; -+ uint64_t len:16; -+ } s; -+ struct cvmx_agl_gmx_rxx_frm_min_s cn52xx; -+ struct cvmx_agl_gmx_rxx_frm_min_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_frm_min_s cn56xx; -+ struct cvmx_agl_gmx_rxx_frm_min_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_ifg { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_ifg_s { -+ uint64_t reserved_4_63:60; -+ uint64_t ifg:4; -+ } s; -+ struct cvmx_agl_gmx_rxx_ifg_s cn52xx; -+ struct cvmx_agl_gmx_rxx_ifg_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_ifg_s cn56xx; -+ struct cvmx_agl_gmx_rxx_ifg_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_int_en { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_int_en_s { -+ uint64_t reserved_20_63:44; -+ uint64_t pause_drp:1; -+ uint64_t reserved_16_18:3; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t reserved_9_9:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t lenerr:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t maxerr:1; -+ uint64_t reserved_1_1:1; -+ uint64_t minerr:1; -+ } s; -+ struct cvmx_agl_gmx_rxx_int_en_s cn52xx; -+ struct cvmx_agl_gmx_rxx_int_en_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_int_en_s cn56xx; -+ struct cvmx_agl_gmx_rxx_int_en_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_int_reg { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_int_reg_s { -+ uint64_t reserved_20_63:44; -+ uint64_t pause_drp:1; -+ uint64_t reserved_16_18:3; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t reserved_9_9:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t lenerr:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t maxerr:1; -+ uint64_t reserved_1_1:1; -+ uint64_t minerr:1; -+ } s; -+ struct cvmx_agl_gmx_rxx_int_reg_s cn52xx; -+ struct cvmx_agl_gmx_rxx_int_reg_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_int_reg_s cn56xx; -+ struct cvmx_agl_gmx_rxx_int_reg_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_jabber { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_jabber_s { -+ uint64_t reserved_16_63:48; -+ uint64_t cnt:16; -+ } s; -+ struct cvmx_agl_gmx_rxx_jabber_s cn52xx; -+ struct cvmx_agl_gmx_rxx_jabber_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_jabber_s cn56xx; -+ struct cvmx_agl_gmx_rxx_jabber_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_pause_drop_time { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_pause_drop_time_s { -+ uint64_t reserved_16_63:48; -+ uint64_t status:16; -+ } s; -+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xx; -+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xx; -+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_stats_ctl { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_stats_ctl_s { -+ uint64_t reserved_1_63:63; -+ uint64_t rd_clr:1; -+ } s; -+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xx; -+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xx; -+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_stats_octs { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_stats_octs_s { -+ uint64_t reserved_48_63:16; -+ uint64_t cnt:48; -+ } s; -+ struct cvmx_agl_gmx_rxx_stats_octs_s cn52xx; -+ struct cvmx_agl_gmx_rxx_stats_octs_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_stats_octs_s cn56xx; -+ struct cvmx_agl_gmx_rxx_stats_octs_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_stats_octs_ctl { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s { -+ uint64_t reserved_48_63:16; -+ uint64_t cnt:48; -+ } s; -+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xx; -+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xx; -+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_stats_octs_dmac { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s { -+ uint64_t reserved_48_63:16; -+ uint64_t cnt:48; -+ } s; -+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xx; -+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xx; -+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_stats_octs_drp { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s { -+ uint64_t reserved_48_63:16; -+ uint64_t cnt:48; -+ } s; -+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xx; -+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xx; -+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_stats_pkts { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_stats_pkts_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xx; -+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xx; -+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_stats_pkts_bad { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xx; -+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xx; -+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_stats_pkts_ctl { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xx; -+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xx; -+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_stats_pkts_dmac { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xx; -+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xx; -+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_stats_pkts_drp { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xx; -+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xx; -+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rxx_udd_skp { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rxx_udd_skp_s { -+ uint64_t reserved_9_63:55; -+ uint64_t fcssel:1; -+ uint64_t reserved_7_7:1; -+ uint64_t len:7; -+ } s; -+ struct cvmx_agl_gmx_rxx_udd_skp_s cn52xx; -+ struct cvmx_agl_gmx_rxx_udd_skp_s cn52xxp1; -+ struct cvmx_agl_gmx_rxx_udd_skp_s cn56xx; -+ struct cvmx_agl_gmx_rxx_udd_skp_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rx_bp_dropx { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rx_bp_dropx_s { -+ uint64_t reserved_6_63:58; -+ uint64_t mark:6; -+ } s; -+ struct cvmx_agl_gmx_rx_bp_dropx_s cn52xx; -+ struct cvmx_agl_gmx_rx_bp_dropx_s cn52xxp1; -+ struct cvmx_agl_gmx_rx_bp_dropx_s cn56xx; -+ struct cvmx_agl_gmx_rx_bp_dropx_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rx_bp_offx { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rx_bp_offx_s { -+ uint64_t reserved_6_63:58; -+ uint64_t mark:6; -+ } s; -+ struct cvmx_agl_gmx_rx_bp_offx_s cn52xx; -+ struct cvmx_agl_gmx_rx_bp_offx_s cn52xxp1; -+ struct cvmx_agl_gmx_rx_bp_offx_s cn56xx; -+ struct cvmx_agl_gmx_rx_bp_offx_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rx_bp_onx { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rx_bp_onx_s { -+ uint64_t reserved_9_63:55; -+ uint64_t mark:9; -+ } s; -+ struct cvmx_agl_gmx_rx_bp_onx_s cn52xx; -+ struct cvmx_agl_gmx_rx_bp_onx_s cn52xxp1; -+ struct cvmx_agl_gmx_rx_bp_onx_s cn56xx; -+ struct cvmx_agl_gmx_rx_bp_onx_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rx_prt_info { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rx_prt_info_s { -+ uint64_t reserved_18_63:46; -+ uint64_t drop:2; -+ uint64_t reserved_2_15:14; -+ uint64_t commit:2; -+ } s; -+ struct cvmx_agl_gmx_rx_prt_info_s cn52xx; -+ struct cvmx_agl_gmx_rx_prt_info_s cn52xxp1; -+ struct cvmx_agl_gmx_rx_prt_info_cn56xx { -+ uint64_t reserved_17_63:47; -+ uint64_t drop:1; -+ uint64_t reserved_1_15:15; -+ uint64_t commit:1; -+ } cn56xx; -+ struct cvmx_agl_gmx_rx_prt_info_cn56xx cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_rx_tx_status { -+ uint64_t u64; -+ struct cvmx_agl_gmx_rx_tx_status_s { -+ uint64_t reserved_6_63:58; -+ uint64_t tx:2; -+ uint64_t reserved_2_3:2; -+ uint64_t rx:2; -+ } s; -+ struct cvmx_agl_gmx_rx_tx_status_s cn52xx; -+ struct cvmx_agl_gmx_rx_tx_status_s cn52xxp1; -+ struct cvmx_agl_gmx_rx_tx_status_cn56xx { -+ uint64_t reserved_5_63:59; -+ uint64_t tx:1; -+ uint64_t reserved_1_3:3; -+ uint64_t rx:1; -+ } cn56xx; -+ struct cvmx_agl_gmx_rx_tx_status_cn56xx cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_smacx { -+ uint64_t u64; -+ struct cvmx_agl_gmx_smacx_s { -+ uint64_t reserved_48_63:16; -+ uint64_t smac:48; -+ } s; -+ struct cvmx_agl_gmx_smacx_s cn52xx; -+ struct cvmx_agl_gmx_smacx_s cn52xxp1; -+ struct cvmx_agl_gmx_smacx_s cn56xx; -+ struct cvmx_agl_gmx_smacx_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_stat_bp { -+ uint64_t u64; -+ struct cvmx_agl_gmx_stat_bp_s { -+ uint64_t reserved_17_63:47; -+ uint64_t bp:1; -+ uint64_t cnt:16; -+ } s; -+ struct cvmx_agl_gmx_stat_bp_s cn52xx; -+ struct cvmx_agl_gmx_stat_bp_s cn52xxp1; -+ struct cvmx_agl_gmx_stat_bp_s cn56xx; -+ struct cvmx_agl_gmx_stat_bp_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_append { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_append_s { -+ uint64_t reserved_4_63:60; -+ uint64_t force_fcs:1; -+ uint64_t fcs:1; -+ uint64_t pad:1; -+ uint64_t preamble:1; -+ } s; -+ struct cvmx_agl_gmx_txx_append_s cn52xx; -+ struct cvmx_agl_gmx_txx_append_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_append_s cn56xx; -+ struct cvmx_agl_gmx_txx_append_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_ctl { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_ctl_s { -+ uint64_t reserved_2_63:62; -+ uint64_t xsdef_en:1; -+ uint64_t xscol_en:1; -+ } s; -+ struct cvmx_agl_gmx_txx_ctl_s cn52xx; -+ struct cvmx_agl_gmx_txx_ctl_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_ctl_s cn56xx; -+ struct cvmx_agl_gmx_txx_ctl_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_min_pkt { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_min_pkt_s { -+ uint64_t reserved_8_63:56; -+ uint64_t min_size:8; -+ } s; -+ struct cvmx_agl_gmx_txx_min_pkt_s cn52xx; -+ struct cvmx_agl_gmx_txx_min_pkt_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_min_pkt_s cn56xx; -+ struct cvmx_agl_gmx_txx_min_pkt_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_pause_pkt_interval { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s { -+ uint64_t reserved_16_63:48; -+ uint64_t interval:16; -+ } s; -+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xx; -+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xx; -+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_pause_pkt_time { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_pause_pkt_time_s { -+ uint64_t reserved_16_63:48; -+ uint64_t time:16; -+ } s; -+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xx; -+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xx; -+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_pause_togo { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_pause_togo_s { -+ uint64_t reserved_16_63:48; -+ uint64_t time:16; -+ } s; -+ struct cvmx_agl_gmx_txx_pause_togo_s cn52xx; -+ struct cvmx_agl_gmx_txx_pause_togo_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_pause_togo_s cn56xx; -+ struct cvmx_agl_gmx_txx_pause_togo_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_pause_zero { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_pause_zero_s { -+ uint64_t reserved_1_63:63; -+ uint64_t send:1; -+ } s; -+ struct cvmx_agl_gmx_txx_pause_zero_s cn52xx; -+ struct cvmx_agl_gmx_txx_pause_zero_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_pause_zero_s cn56xx; -+ struct cvmx_agl_gmx_txx_pause_zero_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_soft_pause { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_soft_pause_s { -+ uint64_t reserved_16_63:48; -+ uint64_t time:16; -+ } s; -+ struct cvmx_agl_gmx_txx_soft_pause_s cn52xx; -+ struct cvmx_agl_gmx_txx_soft_pause_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_soft_pause_s cn56xx; -+ struct cvmx_agl_gmx_txx_soft_pause_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_stat0 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_stat0_s { -+ uint64_t xsdef:32; -+ uint64_t xscol:32; -+ } s; -+ struct cvmx_agl_gmx_txx_stat0_s cn52xx; -+ struct cvmx_agl_gmx_txx_stat0_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_stat0_s cn56xx; -+ struct cvmx_agl_gmx_txx_stat0_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_stat1 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_stat1_s { -+ uint64_t scol:32; -+ uint64_t mcol:32; -+ } s; -+ struct cvmx_agl_gmx_txx_stat1_s cn52xx; -+ struct cvmx_agl_gmx_txx_stat1_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_stat1_s cn56xx; -+ struct cvmx_agl_gmx_txx_stat1_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_stat2 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_stat2_s { -+ uint64_t reserved_48_63:16; -+ uint64_t octs:48; -+ } s; -+ struct cvmx_agl_gmx_txx_stat2_s cn52xx; -+ struct cvmx_agl_gmx_txx_stat2_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_stat2_s cn56xx; -+ struct cvmx_agl_gmx_txx_stat2_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_stat3 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_stat3_s { -+ uint64_t reserved_32_63:32; -+ uint64_t pkts:32; -+ } s; -+ struct cvmx_agl_gmx_txx_stat3_s cn52xx; -+ struct cvmx_agl_gmx_txx_stat3_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_stat3_s cn56xx; -+ struct cvmx_agl_gmx_txx_stat3_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_stat4 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_stat4_s { -+ uint64_t hist1:32; -+ uint64_t hist0:32; -+ } s; -+ struct cvmx_agl_gmx_txx_stat4_s cn52xx; -+ struct cvmx_agl_gmx_txx_stat4_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_stat4_s cn56xx; -+ struct cvmx_agl_gmx_txx_stat4_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_stat5 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_stat5_s { -+ uint64_t hist3:32; -+ uint64_t hist2:32; -+ } s; -+ struct cvmx_agl_gmx_txx_stat5_s cn52xx; -+ struct cvmx_agl_gmx_txx_stat5_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_stat5_s cn56xx; -+ struct cvmx_agl_gmx_txx_stat5_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_stat6 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_stat6_s { -+ uint64_t hist5:32; -+ uint64_t hist4:32; -+ } s; -+ struct cvmx_agl_gmx_txx_stat6_s cn52xx; -+ struct cvmx_agl_gmx_txx_stat6_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_stat6_s cn56xx; -+ struct cvmx_agl_gmx_txx_stat6_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_stat7 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_stat7_s { -+ uint64_t hist7:32; -+ uint64_t hist6:32; -+ } s; -+ struct cvmx_agl_gmx_txx_stat7_s cn52xx; -+ struct cvmx_agl_gmx_txx_stat7_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_stat7_s cn56xx; -+ struct cvmx_agl_gmx_txx_stat7_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_stat8 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_stat8_s { -+ uint64_t mcst:32; -+ uint64_t bcst:32; -+ } s; -+ struct cvmx_agl_gmx_txx_stat8_s cn52xx; -+ struct cvmx_agl_gmx_txx_stat8_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_stat8_s cn56xx; -+ struct cvmx_agl_gmx_txx_stat8_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_stat9 { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_stat9_s { -+ uint64_t undflw:32; -+ uint64_t ctl:32; -+ } s; -+ struct cvmx_agl_gmx_txx_stat9_s cn52xx; -+ struct cvmx_agl_gmx_txx_stat9_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_stat9_s cn56xx; -+ struct cvmx_agl_gmx_txx_stat9_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_stats_ctl { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_stats_ctl_s { -+ uint64_t reserved_1_63:63; -+ uint64_t rd_clr:1; -+ } s; -+ struct cvmx_agl_gmx_txx_stats_ctl_s cn52xx; -+ struct cvmx_agl_gmx_txx_stats_ctl_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_stats_ctl_s cn56xx; -+ struct cvmx_agl_gmx_txx_stats_ctl_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_txx_thresh { -+ uint64_t u64; -+ struct cvmx_agl_gmx_txx_thresh_s { -+ uint64_t reserved_6_63:58; -+ uint64_t cnt:6; -+ } s; -+ struct cvmx_agl_gmx_txx_thresh_s cn52xx; -+ struct cvmx_agl_gmx_txx_thresh_s cn52xxp1; -+ struct cvmx_agl_gmx_txx_thresh_s cn56xx; -+ struct cvmx_agl_gmx_txx_thresh_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_tx_bp { -+ uint64_t u64; -+ struct cvmx_agl_gmx_tx_bp_s { -+ uint64_t reserved_2_63:62; -+ uint64_t bp:2; -+ } s; -+ struct cvmx_agl_gmx_tx_bp_s cn52xx; -+ struct cvmx_agl_gmx_tx_bp_s cn52xxp1; -+ struct cvmx_agl_gmx_tx_bp_cn56xx { -+ uint64_t reserved_1_63:63; -+ uint64_t bp:1; -+ } cn56xx; -+ struct cvmx_agl_gmx_tx_bp_cn56xx cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_tx_col_attempt { -+ uint64_t u64; -+ struct cvmx_agl_gmx_tx_col_attempt_s { -+ uint64_t reserved_5_63:59; -+ uint64_t limit:5; -+ } s; -+ struct cvmx_agl_gmx_tx_col_attempt_s cn52xx; -+ struct cvmx_agl_gmx_tx_col_attempt_s cn52xxp1; -+ struct cvmx_agl_gmx_tx_col_attempt_s cn56xx; -+ struct cvmx_agl_gmx_tx_col_attempt_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_tx_ifg { -+ uint64_t u64; -+ struct cvmx_agl_gmx_tx_ifg_s { -+ uint64_t reserved_8_63:56; -+ uint64_t ifg2:4; -+ uint64_t ifg1:4; -+ } s; -+ struct cvmx_agl_gmx_tx_ifg_s cn52xx; -+ struct cvmx_agl_gmx_tx_ifg_s cn52xxp1; -+ struct cvmx_agl_gmx_tx_ifg_s cn56xx; -+ struct cvmx_agl_gmx_tx_ifg_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_tx_int_en { -+ uint64_t u64; -+ struct cvmx_agl_gmx_tx_int_en_s { -+ uint64_t reserved_18_63:46; -+ uint64_t late_col:2; -+ uint64_t reserved_14_15:2; -+ uint64_t xsdef:2; -+ uint64_t reserved_10_11:2; -+ uint64_t xscol:2; -+ uint64_t reserved_4_7:4; -+ uint64_t undflw:2; -+ uint64_t reserved_1_1:1; -+ uint64_t pko_nxa:1; -+ } s; -+ struct cvmx_agl_gmx_tx_int_en_s cn52xx; -+ struct cvmx_agl_gmx_tx_int_en_s cn52xxp1; -+ struct cvmx_agl_gmx_tx_int_en_cn56xx { -+ uint64_t reserved_17_63:47; -+ uint64_t late_col:1; -+ uint64_t reserved_13_15:3; -+ uint64_t xsdef:1; -+ uint64_t reserved_9_11:3; -+ uint64_t xscol:1; -+ uint64_t reserved_3_7:5; -+ uint64_t undflw:1; -+ uint64_t reserved_1_1:1; -+ uint64_t pko_nxa:1; -+ } cn56xx; -+ struct cvmx_agl_gmx_tx_int_en_cn56xx cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_tx_int_reg { -+ uint64_t u64; -+ struct cvmx_agl_gmx_tx_int_reg_s { -+ uint64_t reserved_18_63:46; -+ uint64_t late_col:2; -+ uint64_t reserved_14_15:2; -+ uint64_t xsdef:2; -+ uint64_t reserved_10_11:2; -+ uint64_t xscol:2; -+ uint64_t reserved_4_7:4; -+ uint64_t undflw:2; -+ uint64_t reserved_1_1:1; -+ uint64_t pko_nxa:1; -+ } s; -+ struct cvmx_agl_gmx_tx_int_reg_s cn52xx; -+ struct cvmx_agl_gmx_tx_int_reg_s cn52xxp1; -+ struct cvmx_agl_gmx_tx_int_reg_cn56xx { -+ uint64_t reserved_17_63:47; -+ uint64_t late_col:1; -+ uint64_t reserved_13_15:3; -+ uint64_t xsdef:1; -+ uint64_t reserved_9_11:3; -+ uint64_t xscol:1; -+ uint64_t reserved_3_7:5; -+ uint64_t undflw:1; -+ uint64_t reserved_1_1:1; -+ uint64_t pko_nxa:1; -+ } cn56xx; -+ struct cvmx_agl_gmx_tx_int_reg_cn56xx cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_tx_jam { -+ uint64_t u64; -+ struct cvmx_agl_gmx_tx_jam_s { -+ uint64_t reserved_8_63:56; -+ uint64_t jam:8; -+ } s; -+ struct cvmx_agl_gmx_tx_jam_s cn52xx; -+ struct cvmx_agl_gmx_tx_jam_s cn52xxp1; -+ struct cvmx_agl_gmx_tx_jam_s cn56xx; -+ struct cvmx_agl_gmx_tx_jam_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_tx_lfsr { -+ uint64_t u64; -+ struct cvmx_agl_gmx_tx_lfsr_s { -+ uint64_t reserved_16_63:48; -+ uint64_t lfsr:16; -+ } s; -+ struct cvmx_agl_gmx_tx_lfsr_s cn52xx; -+ struct cvmx_agl_gmx_tx_lfsr_s cn52xxp1; -+ struct cvmx_agl_gmx_tx_lfsr_s cn56xx; -+ struct cvmx_agl_gmx_tx_lfsr_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_tx_ovr_bp { -+ uint64_t u64; -+ struct cvmx_agl_gmx_tx_ovr_bp_s { -+ uint64_t reserved_10_63:54; -+ uint64_t en:2; -+ uint64_t reserved_6_7:2; -+ uint64_t bp:2; -+ uint64_t reserved_2_3:2; -+ uint64_t ign_full:2; -+ } s; -+ struct cvmx_agl_gmx_tx_ovr_bp_s cn52xx; -+ struct cvmx_agl_gmx_tx_ovr_bp_s cn52xxp1; -+ struct cvmx_agl_gmx_tx_ovr_bp_cn56xx { -+ uint64_t reserved_9_63:55; -+ uint64_t en:1; -+ uint64_t reserved_5_7:3; -+ uint64_t bp:1; -+ uint64_t reserved_1_3:3; -+ uint64_t ign_full:1; -+ } cn56xx; -+ struct cvmx_agl_gmx_tx_ovr_bp_cn56xx cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_tx_pause_pkt_dmac { -+ uint64_t u64; -+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s { -+ uint64_t reserved_48_63:16; -+ uint64_t dmac:48; -+ } s; -+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xx; -+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xxp1; -+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xx; -+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xxp1; -+}; -+ -+union cvmx_agl_gmx_tx_pause_pkt_type { -+ uint64_t u64; -+ struct cvmx_agl_gmx_tx_pause_pkt_type_s { -+ uint64_t reserved_16_63:48; -+ uint64_t type:16; -+ } s; -+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xx; -+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xxp1; -+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xx; -+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h -@@ -0,0 +1,248 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_MIXX_DEFS_H__ -+#define __CVMX_MIXX_DEFS_H__ -+ -+#define CVMX_MIXX_BIST(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100078ull + (((offset) & 1) * 2048)) -+#define CVMX_MIXX_CTL(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100020ull + (((offset) & 1) * 2048)) -+#define CVMX_MIXX_INTENA(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100050ull + (((offset) & 1) * 2048)) -+#define CVMX_MIXX_IRCNT(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100030ull + (((offset) & 1) * 2048)) -+#define CVMX_MIXX_IRHWM(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100028ull + (((offset) & 1) * 2048)) -+#define CVMX_MIXX_IRING1(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100010ull + (((offset) & 1) * 2048)) -+#define CVMX_MIXX_IRING2(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100018ull + (((offset) & 1) * 2048)) -+#define CVMX_MIXX_ISR(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100048ull + (((offset) & 1) * 2048)) -+#define CVMX_MIXX_ORCNT(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100040ull + (((offset) & 1) * 2048)) -+#define CVMX_MIXX_ORHWM(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100038ull + (((offset) & 1) * 2048)) -+#define CVMX_MIXX_ORING1(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100000ull + (((offset) & 1) * 2048)) -+#define CVMX_MIXX_ORING2(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100008ull + (((offset) & 1) * 2048)) -+#define CVMX_MIXX_REMCNT(offset) \ -+ CVMX_ADD_IO_SEG(0x0001070000100058ull + (((offset) & 1) * 2048)) -+ -+union cvmx_mixx_bist { -+ uint64_t u64; -+ struct cvmx_mixx_bist_s { -+ uint64_t reserved_4_63:60; -+ uint64_t mrqdat:1; -+ uint64_t ipfdat:1; -+ uint64_t irfdat:1; -+ uint64_t orfdat:1; -+ } s; -+ struct cvmx_mixx_bist_s cn52xx; -+ struct cvmx_mixx_bist_s cn52xxp1; -+ struct cvmx_mixx_bist_s cn56xx; -+ struct cvmx_mixx_bist_s cn56xxp1; -+}; -+ -+union cvmx_mixx_ctl { -+ uint64_t u64; -+ struct cvmx_mixx_ctl_s { -+ uint64_t reserved_8_63:56; -+ uint64_t crc_strip:1; -+ uint64_t busy:1; -+ uint64_t en:1; -+ uint64_t reset:1; -+ uint64_t lendian:1; -+ uint64_t nbtarb:1; -+ uint64_t mrq_hwm:2; -+ } s; -+ struct cvmx_mixx_ctl_s cn52xx; -+ struct cvmx_mixx_ctl_s cn52xxp1; -+ struct cvmx_mixx_ctl_s cn56xx; -+ struct cvmx_mixx_ctl_s cn56xxp1; -+}; -+ -+union cvmx_mixx_intena { -+ uint64_t u64; -+ struct cvmx_mixx_intena_s { -+ uint64_t reserved_7_63:57; -+ uint64_t orunena:1; -+ uint64_t irunena:1; -+ uint64_t data_drpena:1; -+ uint64_t ithena:1; -+ uint64_t othena:1; -+ uint64_t ivfena:1; -+ uint64_t ovfena:1; -+ } s; -+ struct cvmx_mixx_intena_s cn52xx; -+ struct cvmx_mixx_intena_s cn52xxp1; -+ struct cvmx_mixx_intena_s cn56xx; -+ struct cvmx_mixx_intena_s cn56xxp1; -+}; -+ -+union cvmx_mixx_ircnt { -+ uint64_t u64; -+ struct cvmx_mixx_ircnt_s { -+ uint64_t reserved_20_63:44; -+ uint64_t ircnt:20; -+ } s; -+ struct cvmx_mixx_ircnt_s cn52xx; -+ struct cvmx_mixx_ircnt_s cn52xxp1; -+ struct cvmx_mixx_ircnt_s cn56xx; -+ struct cvmx_mixx_ircnt_s cn56xxp1; -+}; -+ -+union cvmx_mixx_irhwm { -+ uint64_t u64; -+ struct cvmx_mixx_irhwm_s { -+ uint64_t reserved_40_63:24; -+ uint64_t ibplwm:20; -+ uint64_t irhwm:20; -+ } s; -+ struct cvmx_mixx_irhwm_s cn52xx; -+ struct cvmx_mixx_irhwm_s cn52xxp1; -+ struct cvmx_mixx_irhwm_s cn56xx; -+ struct cvmx_mixx_irhwm_s cn56xxp1; -+}; -+ -+union cvmx_mixx_iring1 { -+ uint64_t u64; -+ struct cvmx_mixx_iring1_s { -+ uint64_t reserved_60_63:4; -+ uint64_t isize:20; -+ uint64_t reserved_36_39:4; -+ uint64_t ibase:33; -+ uint64_t reserved_0_2:3; -+ } s; -+ struct cvmx_mixx_iring1_s cn52xx; -+ struct cvmx_mixx_iring1_s cn52xxp1; -+ struct cvmx_mixx_iring1_s cn56xx; -+ struct cvmx_mixx_iring1_s cn56xxp1; -+}; -+ -+union cvmx_mixx_iring2 { -+ uint64_t u64; -+ struct cvmx_mixx_iring2_s { -+ uint64_t reserved_52_63:12; -+ uint64_t itlptr:20; -+ uint64_t reserved_20_31:12; -+ uint64_t idbell:20; -+ } s; -+ struct cvmx_mixx_iring2_s cn52xx; -+ struct cvmx_mixx_iring2_s cn52xxp1; -+ struct cvmx_mixx_iring2_s cn56xx; -+ struct cvmx_mixx_iring2_s cn56xxp1; -+}; -+ -+union cvmx_mixx_isr { -+ uint64_t u64; -+ struct cvmx_mixx_isr_s { -+ uint64_t reserved_7_63:57; -+ uint64_t orun:1; -+ uint64_t irun:1; -+ uint64_t data_drp:1; -+ uint64_t irthresh:1; -+ uint64_t orthresh:1; -+ uint64_t idblovf:1; -+ uint64_t odblovf:1; -+ } s; -+ struct cvmx_mixx_isr_s cn52xx; -+ struct cvmx_mixx_isr_s cn52xxp1; -+ struct cvmx_mixx_isr_s cn56xx; -+ struct cvmx_mixx_isr_s cn56xxp1; -+}; -+ -+union cvmx_mixx_orcnt { -+ uint64_t u64; -+ struct cvmx_mixx_orcnt_s { -+ uint64_t reserved_20_63:44; -+ uint64_t orcnt:20; -+ } s; -+ struct cvmx_mixx_orcnt_s cn52xx; -+ struct cvmx_mixx_orcnt_s cn52xxp1; -+ struct cvmx_mixx_orcnt_s cn56xx; -+ struct cvmx_mixx_orcnt_s cn56xxp1; -+}; -+ -+union cvmx_mixx_orhwm { -+ uint64_t u64; -+ struct cvmx_mixx_orhwm_s { -+ uint64_t reserved_20_63:44; -+ uint64_t orhwm:20; -+ } s; -+ struct cvmx_mixx_orhwm_s cn52xx; -+ struct cvmx_mixx_orhwm_s cn52xxp1; -+ struct cvmx_mixx_orhwm_s cn56xx; -+ struct cvmx_mixx_orhwm_s cn56xxp1; -+}; -+ -+union cvmx_mixx_oring1 { -+ uint64_t u64; -+ struct cvmx_mixx_oring1_s { -+ uint64_t reserved_60_63:4; -+ uint64_t osize:20; -+ uint64_t reserved_36_39:4; -+ uint64_t obase:33; -+ uint64_t reserved_0_2:3; -+ } s; -+ struct cvmx_mixx_oring1_s cn52xx; -+ struct cvmx_mixx_oring1_s cn52xxp1; -+ struct cvmx_mixx_oring1_s cn56xx; -+ struct cvmx_mixx_oring1_s cn56xxp1; -+}; -+ -+union cvmx_mixx_oring2 { -+ uint64_t u64; -+ struct cvmx_mixx_oring2_s { -+ uint64_t reserved_52_63:12; -+ uint64_t otlptr:20; -+ uint64_t reserved_20_31:12; -+ uint64_t odbell:20; -+ } s; -+ struct cvmx_mixx_oring2_s cn52xx; -+ struct cvmx_mixx_oring2_s cn52xxp1; -+ struct cvmx_mixx_oring2_s cn56xx; -+ struct cvmx_mixx_oring2_s cn56xxp1; -+}; -+ -+union cvmx_mixx_remcnt { -+ uint64_t u64; -+ struct cvmx_mixx_remcnt_s { -+ uint64_t reserved_52_63:12; -+ uint64_t iremcnt:20; -+ uint64_t reserved_20_31:12; -+ uint64_t oremcnt:20; -+ } s; -+ struct cvmx_mixx_remcnt_s cn52xx; -+ struct cvmx_mixx_remcnt_s cn52xxp1; -+ struct cvmx_mixx_remcnt_s cn56xx; -+ struct cvmx_mixx_remcnt_s cn56xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-smix-defs.h -@@ -0,0 +1,178 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_SMIX_DEFS_H__ -+#define __CVMX_SMIX_DEFS_H__ -+ -+#define CVMX_SMIX_CLK(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256)) -+#define CVMX_SMIX_CMD(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256)) -+#define CVMX_SMIX_EN(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256)) -+#define CVMX_SMIX_RD_DAT(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256)) -+#define CVMX_SMIX_WR_DAT(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256)) -+ -+union cvmx_smix_clk { -+ uint64_t u64; -+ struct cvmx_smix_clk_s { -+ uint64_t reserved_25_63:39; -+ uint64_t mode:1; -+ uint64_t reserved_21_23:3; -+ uint64_t sample_hi:5; -+ uint64_t sample_mode:1; -+ uint64_t reserved_14_14:1; -+ uint64_t clk_idle:1; -+ uint64_t preamble:1; -+ uint64_t sample:4; -+ uint64_t phase:8; -+ } s; -+ struct cvmx_smix_clk_cn30xx { -+ uint64_t reserved_21_63:43; -+ uint64_t sample_hi:5; -+ uint64_t reserved_14_15:2; -+ uint64_t clk_idle:1; -+ uint64_t preamble:1; -+ uint64_t sample:4; -+ uint64_t phase:8; -+ } cn30xx; -+ struct cvmx_smix_clk_cn30xx cn31xx; -+ struct cvmx_smix_clk_cn30xx cn38xx; -+ struct cvmx_smix_clk_cn30xx cn38xxp2; -+ struct cvmx_smix_clk_cn50xx { -+ uint64_t reserved_25_63:39; -+ uint64_t mode:1; -+ uint64_t reserved_21_23:3; -+ uint64_t sample_hi:5; -+ uint64_t reserved_14_15:2; -+ uint64_t clk_idle:1; -+ uint64_t preamble:1; -+ uint64_t sample:4; -+ uint64_t phase:8; -+ } cn50xx; -+ struct cvmx_smix_clk_s cn52xx; -+ struct cvmx_smix_clk_cn50xx cn52xxp1; -+ struct cvmx_smix_clk_s cn56xx; -+ struct cvmx_smix_clk_cn50xx cn56xxp1; -+ struct cvmx_smix_clk_cn30xx cn58xx; -+ struct cvmx_smix_clk_cn30xx cn58xxp1; -+}; -+ -+union cvmx_smix_cmd { -+ uint64_t u64; -+ struct cvmx_smix_cmd_s { -+ uint64_t reserved_18_63:46; -+ uint64_t phy_op:2; -+ uint64_t reserved_13_15:3; -+ uint64_t phy_adr:5; -+ uint64_t reserved_5_7:3; -+ uint64_t reg_adr:5; -+ } s; -+ struct cvmx_smix_cmd_cn30xx { -+ uint64_t reserved_17_63:47; -+ uint64_t phy_op:1; -+ uint64_t reserved_13_15:3; -+ uint64_t phy_adr:5; -+ uint64_t reserved_5_7:3; -+ uint64_t reg_adr:5; -+ } cn30xx; -+ struct cvmx_smix_cmd_cn30xx cn31xx; -+ struct cvmx_smix_cmd_cn30xx cn38xx; -+ struct cvmx_smix_cmd_cn30xx cn38xxp2; -+ struct cvmx_smix_cmd_s cn50xx; -+ struct cvmx_smix_cmd_s cn52xx; -+ struct cvmx_smix_cmd_s cn52xxp1; -+ struct cvmx_smix_cmd_s cn56xx; -+ struct cvmx_smix_cmd_s cn56xxp1; -+ struct cvmx_smix_cmd_cn30xx cn58xx; -+ struct cvmx_smix_cmd_cn30xx cn58xxp1; -+}; -+ -+union cvmx_smix_en { -+ uint64_t u64; -+ struct cvmx_smix_en_s { -+ uint64_t reserved_1_63:63; -+ uint64_t en:1; -+ } s; -+ struct cvmx_smix_en_s cn30xx; -+ struct cvmx_smix_en_s cn31xx; -+ struct cvmx_smix_en_s cn38xx; -+ struct cvmx_smix_en_s cn38xxp2; -+ struct cvmx_smix_en_s cn50xx; -+ struct cvmx_smix_en_s cn52xx; -+ struct cvmx_smix_en_s cn52xxp1; -+ struct cvmx_smix_en_s cn56xx; -+ struct cvmx_smix_en_s cn56xxp1; -+ struct cvmx_smix_en_s cn58xx; -+ struct cvmx_smix_en_s cn58xxp1; -+}; -+ -+union cvmx_smix_rd_dat { -+ uint64_t u64; -+ struct cvmx_smix_rd_dat_s { -+ uint64_t reserved_18_63:46; -+ uint64_t pending:1; -+ uint64_t val:1; -+ uint64_t dat:16; -+ } s; -+ struct cvmx_smix_rd_dat_s cn30xx; -+ struct cvmx_smix_rd_dat_s cn31xx; -+ struct cvmx_smix_rd_dat_s cn38xx; -+ struct cvmx_smix_rd_dat_s cn38xxp2; -+ struct cvmx_smix_rd_dat_s cn50xx; -+ struct cvmx_smix_rd_dat_s cn52xx; -+ struct cvmx_smix_rd_dat_s cn52xxp1; -+ struct cvmx_smix_rd_dat_s cn56xx; -+ struct cvmx_smix_rd_dat_s cn56xxp1; -+ struct cvmx_smix_rd_dat_s cn58xx; -+ struct cvmx_smix_rd_dat_s cn58xxp1; -+}; -+ -+union cvmx_smix_wr_dat { -+ uint64_t u64; -+ struct cvmx_smix_wr_dat_s { -+ uint64_t reserved_18_63:46; -+ uint64_t pending:1; -+ uint64_t val:1; -+ uint64_t dat:16; -+ } s; -+ struct cvmx_smix_wr_dat_s cn30xx; -+ struct cvmx_smix_wr_dat_s cn31xx; -+ struct cvmx_smix_wr_dat_s cn38xx; -+ struct cvmx_smix_wr_dat_s cn38xxp2; -+ struct cvmx_smix_wr_dat_s cn50xx; -+ struct cvmx_smix_wr_dat_s cn52xx; -+ struct cvmx_smix_wr_dat_s cn52xxp1; -+ struct cvmx_smix_wr_dat_s cn56xx; -+ struct cvmx_smix_wr_dat_s cn56xxp1; -+ struct cvmx_smix_wr_dat_s cn58xx; -+ struct cvmx_smix_wr_dat_s cn58xxp1; -+}; -+ -+#endif diff --git a/target/linux/octeon/patches-2.6.30/006-octeon_mgmt_driver.patch b/target/linux/octeon/patches-2.6.30/006-octeon_mgmt_driver.patch deleted file mode 100644 index 7ea094519e..0000000000 --- a/target/linux/octeon/patches-2.6.30/006-octeon_mgmt_driver.patch +++ /dev/null @@ -1,2022 +0,0 @@ -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - arch/mips/include/asm/octeon/cvmx-mdio.h | 577 +++++++++++++++++++++ - drivers/net/Kconfig | 8 + - drivers/net/Makefile | 1 + - drivers/net/octeon/Makefile | 11 + - drivers/net/octeon/cvmx-mgmt-port.c | 818 ++++++++++++++++++++++++++++++ - drivers/net/octeon/cvmx-mgmt-port.h | 168 ++++++ - drivers/net/octeon/octeon-mgmt-port.c | 389 ++++++++++++++ - 7 files changed, 1972 insertions(+), 0 deletions(-) - create mode 100644 arch/mips/include/asm/octeon/cvmx-mdio.h - create mode 100644 drivers/net/octeon/Makefile - create mode 100644 drivers/net/octeon/cvmx-mgmt-port.c - create mode 100644 drivers/net/octeon/cvmx-mgmt-port.h - create mode 100644 drivers/net/octeon/octeon-mgmt-port.c - ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-mdio.h -@@ -0,0 +1,577 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * Interface to the SMI/MDIO hardware, including support for both IEEE 802.3 -+ * clause 22 and clause 45 operations. -+ * -+ */ -+ -+#ifndef __CVMX_MIO_H__ -+#define __CVMX_MIO_H__ -+ -+#include "cvmx-smix-defs.h" -+ -+/** -+ * PHY register 0 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_CONTROL 0 -+union cvmx_mdio_phy_reg_control { -+ uint16_t u16; -+ struct { -+ uint16_t reset:1; -+ uint16_t loopback:1; -+ uint16_t speed_lsb:1; -+ uint16_t autoneg_enable:1; -+ uint16_t power_down:1; -+ uint16_t isolate:1; -+ uint16_t restart_autoneg:1; -+ uint16_t duplex:1; -+ uint16_t collision_test:1; -+ uint16_t speed_msb:1; -+ uint16_t unidirectional_enable:1; -+ uint16_t reserved_0_4:5; -+ } s; -+}; -+ -+/** -+ * PHY register 1 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_STATUS 1 -+union cvmx_mdio_phy_reg_status { -+ uint16_t u16; -+ struct { -+ uint16_t capable_100base_t4:1; -+ uint16_t capable_100base_x_full:1; -+ uint16_t capable_100base_x_half:1; -+ uint16_t capable_10_full:1; -+ uint16_t capable_10_half:1; -+ uint16_t capable_100base_t2_full:1; -+ uint16_t capable_100base_t2_half:1; -+ uint16_t capable_extended_status:1; -+ uint16_t capable_unidirectional:1; -+ uint16_t capable_mf_preamble_suppression:1; -+ uint16_t autoneg_complete:1; -+ uint16_t remote_fault:1; -+ uint16_t capable_autoneg:1; -+ uint16_t link_status:1; -+ uint16_t jabber_detect:1; -+ uint16_t capable_extended_registers:1; -+ -+ } s; -+}; -+ -+/** -+ * PHY register 2 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_ID1 2 -+union cvmx_mdio_phy_reg_id1 { -+ uint16_t u16; -+ struct { -+ uint16_t oui_bits_3_18; -+ } s; -+}; -+ -+/** -+ * PHY register 3 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_ID2 3 -+union cvmx_mdio_phy_reg_id2 { -+ uint16_t u16; -+ struct { -+ uint16_t oui_bits_19_24:6; -+ uint16_t model:6; -+ uint16_t revision:4; -+ } s; -+}; -+ -+/** -+ * PHY register 4 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_AUTONEG_ADVER 4 -+union cvmx_mdio_phy_reg_autoneg_adver { -+ uint16_t u16; -+ struct { -+ uint16_t next_page:1; -+ uint16_t reserved_14:1; -+ uint16_t remote_fault:1; -+ uint16_t reserved_12:1; -+ uint16_t asymmetric_pause:1; -+ uint16_t pause:1; -+ uint16_t advert_100base_t4:1; -+ uint16_t advert_100base_tx_full:1; -+ uint16_t advert_100base_tx_half:1; -+ uint16_t advert_10base_tx_full:1; -+ uint16_t advert_10base_tx_half:1; -+ uint16_t selector:5; -+ } s; -+}; -+ -+/** -+ * PHY register 5 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_LINK_PARTNER_ABILITY 5 -+union cvmx_mdio_phy_reg_link_partner_ability { -+ uint16_t u16; -+ struct { -+ uint16_t next_page:1; -+ uint16_t ack:1; -+ uint16_t remote_fault:1; -+ uint16_t reserved_12:1; -+ uint16_t asymmetric_pause:1; -+ uint16_t pause:1; -+ uint16_t advert_100base_t4:1; -+ uint16_t advert_100base_tx_full:1; -+ uint16_t advert_100base_tx_half:1; -+ uint16_t advert_10base_tx_full:1; -+ uint16_t advert_10base_tx_half:1; -+ uint16_t selector:5; -+ } s; -+}; -+ -+/** -+ * PHY register 6 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_AUTONEG_EXPANSION 6 -+union cvmx_mdio_phy_reg_autoneg_expansion { -+ uint16_t u16; -+ struct { -+ uint16_t reserved_5_15:11; -+ uint16_t parallel_detection_fault:1; -+ uint16_t link_partner_next_page_capable:1; -+ uint16_t local_next_page_capable:1; -+ uint16_t page_received:1; -+ uint16_t link_partner_autoneg_capable:1; -+ -+ } s; -+}; -+ -+/** -+ * PHY register 9 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_CONTROL_1000 9 -+union cvmx_mdio_phy_reg_control_1000 { -+ uint16_t u16; -+ struct { -+ uint16_t test_mode:3; -+ uint16_t manual_master_slave:1; -+ uint16_t master:1; -+ uint16_t port_type:1; -+ uint16_t advert_1000base_t_full:1; -+ uint16_t advert_1000base_t_half:1; -+ uint16_t reserved_0_7:8; -+ } s; -+}; -+ -+/** -+ * PHY register 10 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_STATUS_1000 10 -+union cvmx_mdio_phy_reg_status_1000 { -+ uint16_t u16; -+ struct { -+ uint16_t master_slave_fault:1; -+ uint16_t is_master:1; -+ uint16_t local_receiver_ok:1; -+ uint16_t remote_receiver_ok:1; -+ uint16_t remote_capable_1000base_t_full:1; -+ uint16_t remote_capable_1000base_t_half:1; -+ uint16_t reserved_8_9:2; -+ uint16_t idle_error_count:8; -+ } s; -+}; -+ -+/** -+ * PHY register 15 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_EXTENDED_STATUS 15 -+union cvmx_mdio_phy_reg_extended_status { -+ uint16_t u16; -+ struct { -+ uint16_t capable_1000base_x_full:1; -+ uint16_t capable_1000base_x_half:1; -+ uint16_t capable_1000base_t_full:1; -+ uint16_t capable_1000base_t_half:1; -+ uint16_t reserved_0_11:12; -+ } s; -+}; -+ -+/** -+ * PHY register 13 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_MMD_CONTROL 13 -+union cvmx_mdio_phy_reg_mmd_control { -+ uint16_t u16; -+ struct { -+ uint16_t function:2; -+ uint16_t reserved_5_13:9; -+ uint16_t devad:5; -+ } s; -+}; -+ -+/** -+ * PHY register 14 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA 14 -+union cvmx_mdio_phy_reg_mmd_address_data { -+ uint16_t u16; -+ struct { -+ uint16_t address_data:16; -+ } s; -+}; -+ -+/* Operating request encodings. */ -+#define MDIO_CLAUSE_22_WRITE 0 -+#define MDIO_CLAUSE_22_READ 1 -+ -+#define MDIO_CLAUSE_45_ADDRESS 0 -+#define MDIO_CLAUSE_45_WRITE 1 -+#define MDIO_CLAUSE_45_READ_INC 2 -+#define MDIO_CLAUSE_45_READ 3 -+ -+/* MMD identifiers, mostly for accessing devices withing XENPAK modules. */ -+#define CVMX_MMD_DEVICE_PMA_PMD 1 -+#define CVMX_MMD_DEVICE_WIS 2 -+#define CVMX_MMD_DEVICE_PCS 3 -+#define CVMX_MMD_DEVICE_PHY_XS 4 -+#define CVMX_MMD_DEVICE_DTS_XS 5 -+#define CVMX_MMD_DEVICE_TC 6 -+#define CVMX_MMD_DEVICE_CL22_EXT 29 -+#define CVMX_MMD_DEVICE_VENDOR_1 30 -+#define CVMX_MMD_DEVICE_VENDOR_2 31 -+ -+/** -+ * Perform an MII read. This function is used to read PHY -+ * registers controlling auto negotiation. -+ * -+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) -+ * support multiple busses. -+ * @phy_id: The MII phy id -+ * @location: Register location to read -+ * -+ * Returns Result from the read or -1 on failure -+ */ -+static inline int cvmx_mdio_read(int bus_id, int phy_id, int location) -+{ -+ union cvmx_smix_cmd smi_cmd; -+ union cvmx_smix_rd_dat smi_rd; -+ int timeout = 1000; -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = MDIO_CLAUSE_22_READ; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = location; -+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); -+ -+ do { -+ cvmx_wait(1000); -+ smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id)); -+ } while (smi_rd.s.pending && timeout--); -+ -+ if (smi_rd.s.val) -+ return smi_rd.s.dat; -+ else -+ return -1; -+} -+ -+/** -+ * Perform an MII write. This function is used to write PHY -+ * registers controlling auto negotiation. -+ * -+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) -+ * support multiple busses. -+ * @phy_id: The MII phy id -+ * @location: Register location to write -+ * @val: Value to write -+ * -+ * Returns -1 on error -+ * 0 on success -+ */ -+static inline int cvmx_mdio_write(int bus_id, int phy_id, int location, int val) -+{ -+ union cvmx_smix_cmd smi_cmd; -+ union cvmx_smix_wr_dat smi_wr; -+ int timeout = 1000; -+ -+ smi_wr.u64 = 0; -+ smi_wr.s.dat = val; -+ cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = MDIO_CLAUSE_22_WRITE; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = location; -+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); -+ -+ do { -+ cvmx_wait(1000); -+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); -+ } while (smi_wr.s.pending && --timeout); -+ if (timeout <= 0) -+ return -1; -+ -+ return 0; -+} -+ -+/** -+ * Perform an IEEE 802.3 clause 45 MII read using clause 22 operations. This -+ * function is used to read PHY registers controlling auto negotiation. -+ * -+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) -+ * support multiple busses. -+ * @phy_id: The MII phy id -+ * @device: MDIO Managable Device (MMD) id -+ * @location: Register location to read -+ * -+ * Returns Result from the read or -1 on failure -+ */ -+ -+static inline int cvmx_mdio_45_via_22_read(int bus_id, int phy_id, int device, -+ int location) -+{ -+ union cvmx_mdio_phy_reg_mmd_control mmd_control; -+ -+ /* -+ * a) To Register 13, write the Function field to 00 (address) -+ * and DEVAD field to the device address value for the -+ * desired MMD; -+ */ -+ mmd_control.u16 = 0; -+ mmd_control.s.function = MDIO_CLAUSE_45_ADDRESS; -+ mmd_control.s.devad = device; -+ cvmx_mdio_write(bus_id, phy_id, CVMX_MDIO_PHY_REG_MMD_CONTROL, -+ mmd_control.u16); -+ -+ /* -+ * b) To Register 14, write the desired address value to the -+ * MMD's address register; -+ */ -+ cvmx_mdio_write(bus_id, phy_id, CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA, -+ location); -+ -+ /* -+ * c) To Register 13, write the Function field to 01 (Data, no -+ * post increment) and DEVAD field to the same device -+ * address value for the desired MMD; -+ */ -+ mmd_control.u16 = 0; -+ mmd_control.s.function = MDIO_CLAUSE_45_READ; -+ mmd_control.s.devad = device; -+ cvmx_mdio_write(bus_id, phy_id, CVMX_MDIO_PHY_REG_MMD_CONTROL, -+ mmd_control.u16); -+ -+ /* -+ * d) From Register 14, read the content of the MMD's selected -+ * register. -+ */ -+ return cvmx_mdio_read(bus_id, phy_id, -+ CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA); -+} -+ -+/** -+ * Perform an IEEE 802.3 clause 45 MII write using clause 22 -+ * operations. This function is used to write PHY registers -+ * controlling auto negotiation. -+ * -+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) -+ * support multiple busses. -+ * @phy_id: The MII phy id -+ * @device: MDIO Managable Device (MMD) id -+ * @location: Register location to write -+ * @val: Value to write -+ * -+ * Returns -1 on error -+ * 0 on success -+ */ -+static inline int cvmx_mdio_45_via_22_write(int bus_id, int phy_id, int device, -+ int location, int val) -+{ -+ union cvmx_mdio_phy_reg_mmd_control mmd_control; -+ -+ /* -+ * a) To Register 13, write the Function field to 00 (address) -+ * and DEVAD field to the device address value for the -+ * desired MMD; -+ */ -+ mmd_control.u16 = 0; -+ mmd_control.s.function = MDIO_CLAUSE_45_ADDRESS; -+ mmd_control.s.devad = device; -+ cvmx_mdio_write(bus_id, phy_id, CVMX_MDIO_PHY_REG_MMD_CONTROL, -+ mmd_control.u16); -+ -+ /* -+ * b) To Register 14, write the desired address value to the -+ * MMD's address register; -+ */ -+ cvmx_mdio_write(bus_id, phy_id, CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA, -+ location); -+ -+ /* -+ * c) To Register 13, write the Function field to 01 (Data, no -+ * post increment) and DEVAD field to the same device -+ * address value for the desired MMD; -+ */ -+ mmd_control.u16 = 0; -+ mmd_control.s.function = MDIO_CLAUSE_45_READ; -+ mmd_control.s.devad = device; -+ cvmx_mdio_write(bus_id, phy_id, CVMX_MDIO_PHY_REG_MMD_CONTROL, -+ mmd_control.u16); -+ -+ /* -+ * d) To Register 14, write the content of the MMD's selected -+ * register. -+ */ -+ return cvmx_mdio_write(bus_id, phy_id, -+ CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA, val); -+ -+ return 0; -+} -+ -+/** -+ * Perform an IEEE 802.3 clause 45 MII read. This function is used to read PHY -+ * registers controlling auto negotiation. -+ * -+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) -+ * support multiple busses. -+ * @phy_id: The MII phy id -+ * @device: MDIO Managable Device (MMD) id -+ * @location: Register location to read -+ * -+ * Returns Result from the read or -1 on failure -+ */ -+ -+static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device, -+ int location) -+{ -+ union cvmx_smix_cmd smi_cmd; -+ union cvmx_smix_rd_dat smi_rd; -+ union cvmx_smix_wr_dat smi_wr; -+ int timeout = 1000; -+ -+ smi_wr.u64 = 0; -+ smi_wr.s.dat = location; -+ cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = device; -+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); -+ -+ do { -+ cvmx_wait(1000); -+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); -+ } while (smi_wr.s.pending && --timeout); -+ if (timeout <= 0) -+ return -1; -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = MDIO_CLAUSE_45_READ; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = device; -+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); -+ -+ do { -+ cvmx_wait(1000); -+ smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id)); -+ } while (smi_rd.s.pending && timeout--); -+ -+ if (0 == timeout) -+ cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d " -+ "device %2d register %2d TIME OUT\n", -+ bus_id, phy_id, device, location); -+ -+ if (smi_rd.s.val) -+ return smi_rd.s.dat; -+ else { -+ cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d " -+ "device %2d register %2d INVALID READ\n", -+ bus_id, phy_id, device, location); -+ return -1; -+ } -+} -+ -+/** -+ * Perform an IEEE 802.3 clause 45 MII write. This function is used to -+ * write PHY registers controlling auto negotiation. -+ * -+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) -+ * support multiple busses. -+ * @phy_id: The MII phy id -+ * @device: MDIO Managable Device (MMD) id -+ * @location: Register location to write -+ * @val: Value to write -+ * -+ * Returns -1 on error -+ * 0 on success -+ */ -+static inline int cvmx_mdio_45_write(int bus_id, int phy_id, int device, -+ int location, int val) -+{ -+ union cvmx_smix_cmd smi_cmd; -+ union cvmx_smix_wr_dat smi_wr; -+ int timeout = 1000; -+ -+ smi_wr.u64 = 0; -+ smi_wr.s.dat = location; -+ cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = device; -+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); -+ -+ do { -+ cvmx_wait(1000); -+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); -+ } while (smi_wr.s.pending && --timeout); -+ if (timeout <= 0) -+ return -1; -+ -+ smi_wr.u64 = 0; -+ smi_wr.s.dat = val; -+ cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = MDIO_CLAUSE_45_WRITE; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = device; -+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); -+ -+ do { -+ cvmx_wait(1000); -+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); -+ } while (smi_wr.s.pending && --timeout); -+ if (timeout <= 0) -+ return -1; -+ -+ return 0; -+} -+ -+#endif ---- a/drivers/net/Kconfig -+++ b/drivers/net/Kconfig -@@ -2035,6 +2035,14 @@ config ATL2 - To compile this driver as a module, choose M here. The module - will be called atl2. - -+config OCTEON_MGMT -+ tristate "OCTEON Management port ethernet driver (CN5XXX)" -+ depends on CPU_CAVIUM_OCTEON -+ default y -+ help -+ This option enables the ethernet driver for the management port on -+ CN52XX, CN57XX, CN56XX, CN55XX, and CN54XX chips. -+ - source "drivers/net/fs_enet/Kconfig" - - endif # NET_ETHERNET ---- a/drivers/net/Makefile -+++ b/drivers/net/Makefile -@@ -234,6 +234,7 @@ pasemi_mac_driver-objs := pasemi_mac.o p - obj-$(CONFIG_MLX4_CORE) += mlx4/ - obj-$(CONFIG_ENC28J60) += enc28j60.o - obj-$(CONFIG_ETHOC) += ethoc.o -+obj-$(CONFIG_OCTEON_MGMT) += octeon/ - - obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o - ---- /dev/null -+++ b/drivers/net/octeon/Makefile -@@ -0,0 +1,11 @@ -+# Makefile for the Cavium OCTEON Ethernet drivers. -+# -+# This file is subject to the terms and conditions of the GNU General Public -+# License. See the file "COPYING" in the main directory of this archive -+# for more details. -+# -+# Copyright (C) 2008 Cavium Networks -+ -+obj-$(CONFIG_OCTEON_MGMT) += octeon_mgmt.o -+ -+octeon_mgmt-objs := octeon-mgmt-port.o cvmx-mgmt-port.o -\ No newline at end of file ---- /dev/null -+++ b/drivers/net/octeon/cvmx-mgmt-port.c -@@ -0,0 +1,818 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * Support functions for managing the MII management port -+ * -+ */ -+ -+#include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-spinlock.h> -+#include <asm/octeon/cvmx-bootmem.h> -+#include <asm/octeon/cvmx-mdio.h> -+ -+#include <asm/octeon/cvmx-mixx-defs.h> -+#include <asm/octeon/cvmx-agl-defs.h> -+ -+#include "cvmx-mgmt-port.h" -+ -+#define CVMX_MGMT_PORT_NUM_PORTS 2 -+/* Number of TX ring buffer entries and buffers */ -+#define CVMX_MGMT_PORT_NUM_TX_BUFFERS 16 -+/* Number of RX ring buffer entries and buffers */ -+#define CVMX_MGMT_PORT_NUM_RX_BUFFERS 128 -+ -+#define CVMX_MGMT_PORT_TX_BUFFER_SIZE 12288 -+#define CVMX_MGMT_PORT_RX_BUFFER_SIZE 1536 -+ -+/** -+ * Format of the TX/RX ring buffer entries -+ */ -+union cvmx_mgmt_port_ring_entry { -+ uint64_t u64; -+ struct { -+ uint64_t reserved_62_63:2; -+ /* Length of the buffer/packet in bytes */ -+ uint64_t len:14; -+ /* The RX error code */ -+ uint64_t code:8; -+ /* Physical address of the buffer */ -+ uint64_t addr:40; -+ } s; -+}; -+ -+/** -+ * Per port state required for each mgmt port -+ */ -+struct cvmx_mgmt_port_state { -+ /* Used for exclusive access to this structure */ -+ cvmx_spinlock_t lock; -+ /* Where the next TX will write in the tx_ring and tx_buffers */ -+ int tx_write_index; -+ /* Where the next RX will be in the rx_ring and rx_buffers */ -+ int rx_read_index; -+ /* The SMI/MDIO PHY address */ -+ int phy_id; -+ /* Our MAC address */ -+ uint64_t mac; -+ union cvmx_mgmt_port_ring_entry tx_ring[CVMX_MGMT_PORT_NUM_TX_BUFFERS]; -+ union cvmx_mgmt_port_ring_entry rx_ring[CVMX_MGMT_PORT_NUM_RX_BUFFERS]; -+ char tx_buffers[CVMX_MGMT_PORT_NUM_TX_BUFFERS] -+ [CVMX_MGMT_PORT_TX_BUFFER_SIZE]; -+ char rx_buffers[CVMX_MGMT_PORT_NUM_RX_BUFFERS] -+ [CVMX_MGMT_PORT_RX_BUFFER_SIZE]; -+}; -+ -+/** -+ * Pointers to each mgmt port's state -+ */ -+struct cvmx_mgmt_port_state *cvmx_mgmt_port_state_ptr; -+ -+/** -+ * Return the number of management ports supported by this chip -+ * -+ * Returns Number of ports -+ */ -+int __cvmx_mgmt_port_num_ports(void) -+{ -+ if (OCTEON_IS_MODEL(OCTEON_CN56XX)) -+ return 1; -+ else if (OCTEON_IS_MODEL(OCTEON_CN52XX)) -+ return 2; -+ else -+ return 0; -+} -+ -+/** -+ * Called to initialize a management port for use. Multiple calls -+ * to this function accross applications is safe. -+ * -+ * @port: Port to initialize -+ * -+ * Returns CVMX_MGMT_PORT_SUCCESS or an error code -+ */ -+enum cvmx_mgmt_port_result cvmx_mgmt_port_initialize(int port) -+{ -+ char *alloc_name = "cvmx_mgmt_port"; -+ union cvmx_mixx_oring1 oring1; -+ union cvmx_mixx_ctl mix_ctl; -+ -+ if ((port < 0) || (port >= __cvmx_mgmt_port_num_ports())) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ cvmx_mgmt_port_state_ptr = -+ cvmx_bootmem_alloc_named(CVMX_MGMT_PORT_NUM_PORTS * -+ sizeof(struct cvmx_mgmt_port_state), 128, -+ alloc_name); -+ if (cvmx_mgmt_port_state_ptr) { -+ memset(cvmx_mgmt_port_state_ptr, 0, -+ CVMX_MGMT_PORT_NUM_PORTS * -+ sizeof(struct cvmx_mgmt_port_state)); -+ } else { -+ struct cvmx_bootmem_named_block_desc *block_desc = -+ cvmx_bootmem_find_named_block(alloc_name); -+ if (block_desc) -+ cvmx_mgmt_port_state_ptr = -+ cvmx_phys_to_ptr(block_desc->base_addr); -+ else { -+ cvmx_dprintf("ERROR: cvmx_mgmt_port_initialize: " -+ "Unable to get named block %s.\n", -+ alloc_name); -+ return CVMX_MGMT_PORT_NO_MEMORY; -+ } -+ } -+ -+ /* -+ * Reset the MIX block if the previous user had a different TX -+ * ring size. -+ */ -+ mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port)); -+ if (!mix_ctl.s.reset) { -+ oring1.u64 = cvmx_read_csr(CVMX_MIXX_ORING1(port)); -+ if (oring1.s.osize != CVMX_MGMT_PORT_NUM_TX_BUFFERS) { -+ mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port)); -+ mix_ctl.s.en = 0; -+ cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64); -+ do { -+ mix_ctl.u64 = -+ cvmx_read_csr(CVMX_MIXX_CTL(port)); -+ } while (mix_ctl.s.busy); -+ mix_ctl.s.reset = 1; -+ cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64); -+ cvmx_read_csr(CVMX_MIXX_CTL(port)); -+ memset(cvmx_mgmt_port_state_ptr + port, 0, -+ sizeof(struct cvmx_mgmt_port_state)); -+ } -+ } -+ -+ if (cvmx_mgmt_port_state_ptr[port].tx_ring[0].u64 == 0) { -+ struct cvmx_mgmt_port_state *state = -+ cvmx_mgmt_port_state_ptr + port; -+ int i; -+ union cvmx_mixx_bist mix_bist; -+ union cvmx_agl_gmx_bist agl_gmx_bist; -+ union cvmx_mixx_oring1 oring1; -+ union cvmx_mixx_iring1 iring1; -+ union cvmx_mixx_ctl mix_ctl; -+ -+ /* Make sure BIST passed */ -+ mix_bist.u64 = cvmx_read_csr(CVMX_MIXX_BIST(port)); -+ if (mix_bist.u64) -+ cvmx_dprintf("WARNING: cvmx_mgmt_port_initialize: " -+ "Managment port MIX failed BIST " -+ "(0x%016llx)\n", -+ (unsigned long long)mix_bist.u64); -+ -+ agl_gmx_bist.u64 = cvmx_read_csr(CVMX_AGL_GMX_BIST); -+ if (agl_gmx_bist.u64) -+ cvmx_dprintf("WARNING: cvmx_mgmt_port_initialize: " -+ "Managment port AGL failed BIST " -+ "(0x%016llx)\n", -+ (unsigned long long)agl_gmx_bist.u64); -+ -+ /* Clear all state information */ -+ memset(state, 0, sizeof(*state)); -+ -+ /* Take the control logic out of reset */ -+ mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port)); -+ mix_ctl.s.reset = 0; -+ cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64); -+ -+ /* Set the PHY address */ -+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) -+ state->phy_id = -1; -+ else -+ /* Will need to be change to match the board */ -+ state->phy_id = port; -+ -+ /* Create a default MAC address */ -+ state->mac = 0x000000dead000000ull; -+ state->mac += 0xffffff & CAST64(state); -+ -+ /* Setup the TX ring */ -+ for (i = 0; i < CVMX_MGMT_PORT_NUM_TX_BUFFERS; i++) { -+ state->tx_ring[i].s.len = CVMX_MGMT_PORT_TX_BUFFER_SIZE; -+ state->tx_ring[i].s.addr = -+ cvmx_ptr_to_phys(state->tx_buffers[i]); -+ } -+ -+ /* Tell the HW where the TX ring is */ -+ oring1.u64 = 0; -+ oring1.s.obase = cvmx_ptr_to_phys(state->tx_ring) >> 3; -+ oring1.s.osize = CVMX_MGMT_PORT_NUM_TX_BUFFERS; -+ CVMX_SYNCWS; -+ cvmx_write_csr(CVMX_MIXX_ORING1(port), oring1.u64); -+ -+ /* Setup the RX ring */ -+ for (i = 0; i < CVMX_MGMT_PORT_NUM_RX_BUFFERS; i++) { -+ /* This size is -8 due to an errata for CN56XX pass 1 */ -+ state->rx_ring[i].s.len = -+ CVMX_MGMT_PORT_RX_BUFFER_SIZE - 8; -+ state->rx_ring[i].s.addr = -+ cvmx_ptr_to_phys(state->rx_buffers[i]); -+ } -+ -+ /* Tell the HW where the RX ring is */ -+ iring1.u64 = 0; -+ iring1.s.ibase = cvmx_ptr_to_phys(state->rx_ring) >> 3; -+ iring1.s.isize = CVMX_MGMT_PORT_NUM_RX_BUFFERS; -+ CVMX_SYNCWS; -+ cvmx_write_csr(CVMX_MIXX_IRING1(port), iring1.u64); -+ cvmx_write_csr(CVMX_MIXX_IRING2(port), -+ CVMX_MGMT_PORT_NUM_RX_BUFFERS); -+ -+ /* Disable the external input/output */ -+ cvmx_mgmt_port_disable(port); -+ -+ /* Set the MAC address filtering up */ -+ cvmx_mgmt_port_set_mac(port, state->mac); -+ -+ /* -+ * Set the default max size to an MTU of 1500 with L2 -+ * and VLAN. -+ */ -+ cvmx_mgmt_port_set_max_packet_size(port, 1518); -+ -+ /* -+ * Enable the port HW. Packets are not allowed until -+ * cvmx_mgmt_port_enable() is called. -+ */ -+ mix_ctl.u64 = 0; -+ /* Strip the ending CRC */ -+ mix_ctl.s.crc_strip = 1; -+ /* Enable the port */ -+ mix_ctl.s.en = 1; -+ /* Arbitration mode */ -+ mix_ctl.s.nbtarb = 0; -+ /* MII CB-request FIFO programmable high watermark */ -+ mix_ctl.s.mrq_hwm = 1; -+ cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64); -+ -+ if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) -+ || OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) { -+ /* -+ * Force compensation values, as they are not -+ * determined properly by HW. -+ */ -+ union cvmx_agl_gmx_drv_ctl drv_ctl; -+ -+ drv_ctl.u64 = cvmx_read_csr(CVMX_AGL_GMX_DRV_CTL); -+ if (port) { -+ drv_ctl.s.byp_en1 = 1; -+ drv_ctl.s.nctl1 = 6; -+ drv_ctl.s.pctl1 = 6; -+ } else { -+ drv_ctl.s.byp_en = 1; -+ drv_ctl.s.nctl = 6; -+ drv_ctl.s.pctl = 6; -+ } -+ cvmx_write_csr(CVMX_AGL_GMX_DRV_CTL, drv_ctl.u64); -+ } -+ } -+ return CVMX_MGMT_PORT_SUCCESS; -+} -+ -+/** -+ * Shutdown a management port. This currently disables packet IO -+ * but leaves all hardware and buffers. Another application can then -+ * call initialize() without redoing the hardware setup. -+ * -+ * @port: Management port -+ * -+ * Returns CVMX_MGMT_PORT_SUCCESS or an error code -+ */ -+enum cvmx_mgmt_port_result cvmx_mgmt_port_shutdown(int port) -+{ -+ if ((port < 0) || (port >= __cvmx_mgmt_port_num_ports())) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ /* Stop packets from comming in */ -+ cvmx_mgmt_port_disable(port); -+ -+ /* -+ * We don't free any memory so the next intialize can reuse -+ * the HW setup. -+ */ -+ return CVMX_MGMT_PORT_SUCCESS; -+} -+ -+/** -+ * Enable packet IO on a management port -+ * -+ * @port: Management port -+ * -+ * Returns CVMX_MGMT_PORT_SUCCESS or an error code -+ */ -+enum cvmx_mgmt_port_result cvmx_mgmt_port_enable(int port) -+{ -+ struct cvmx_mgmt_port_state *state; -+ union cvmx_agl_gmx_prtx_cfg agl_gmx_prtx; -+ union cvmx_agl_gmx_inf_mode agl_gmx_inf_mode; -+ union cvmx_agl_gmx_rxx_frm_ctl rxx_frm_ctl; -+ -+ if ((port < 0) || (port >= __cvmx_mgmt_port_num_ports())) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ state = cvmx_mgmt_port_state_ptr + port; -+ -+ cvmx_spinlock_lock(&state->lock); -+ -+ rxx_frm_ctl.u64 = 0; -+ rxx_frm_ctl.s.pre_align = 1; -+ /* -+ * When set, disables the length check for non-min sized pkts -+ * with padding in the client data. -+ */ -+ rxx_frm_ctl.s.pad_len = 1; -+ /* When set, disables the length check for VLAN pkts */ -+ rxx_frm_ctl.s.vlan_len = 1; -+ /* When set, PREAMBLE checking is less strict */ -+ rxx_frm_ctl.s.pre_free = 1; -+ /* Control Pause Frames can match station SMAC */ -+ rxx_frm_ctl.s.ctl_smac = 0; -+ /* Control Pause Frames can match globally assign Multicast address */ -+ rxx_frm_ctl.s.ctl_mcst = 1; -+ /* Forward pause information to TX block */ -+ rxx_frm_ctl.s.ctl_bck = 1; -+ /* Drop Control Pause Frames */ -+ rxx_frm_ctl.s.ctl_drp = 1; -+ /* Strip off the preamble */ -+ rxx_frm_ctl.s.pre_strp = 1; -+ /* -+ * This port is configured to send PREAMBLE+SFD to begin every -+ * frame. GMX checks that the PREAMBLE is sent correctly. -+ */ -+ rxx_frm_ctl.s.pre_chk = 1; -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_CTL(port), rxx_frm_ctl.u64); -+ -+ /* Enable the AGL block */ -+ agl_gmx_inf_mode.u64 = 0; -+ agl_gmx_inf_mode.s.en = 1; -+ cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64); -+ -+ /* Configure the port duplex and enables */ -+ agl_gmx_prtx.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port)); -+ agl_gmx_prtx.s.tx_en = 1; -+ agl_gmx_prtx.s.rx_en = 1; -+ if (cvmx_mgmt_port_get_link(port) < 0) -+ agl_gmx_prtx.s.duplex = 0; -+ else -+ agl_gmx_prtx.s.duplex = 1; -+ agl_gmx_prtx.s.en = 1; -+ cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64); -+ -+ cvmx_spinlock_unlock(&state->lock); -+ return CVMX_MGMT_PORT_SUCCESS; -+} -+ -+/** -+ * Disable packet IO on a management port -+ * -+ * @port: Management port -+ * -+ * Returns CVMX_MGMT_PORT_SUCCESS or an error code -+ */ -+enum cvmx_mgmt_port_result cvmx_mgmt_port_disable(int port) -+{ -+ struct cvmx_mgmt_port_state *state; -+ union cvmx_agl_gmx_prtx_cfg agl_gmx_prtx; -+ -+ if ((port < 0) || (port >= __cvmx_mgmt_port_num_ports())) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ state = cvmx_mgmt_port_state_ptr + port; -+ -+ cvmx_spinlock_lock(&state->lock); -+ -+ agl_gmx_prtx.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port)); -+ agl_gmx_prtx.s.en = 0; -+ cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64); -+ -+ cvmx_spinlock_unlock(&state->lock); -+ return CVMX_MGMT_PORT_SUCCESS; -+} -+ -+/** -+ * Send a packet out the management port. The packet is copied so -+ * the input buffer isn't used after this call. -+ * -+ * @port: Management port -+ * @packet_len: Length of the packet to send. It does not include the final CRC -+ * @buffer: Packet data -+ * -+ * Returns CVMX_MGMT_PORT_SUCCESS or an error code -+ */ -+enum cvmx_mgmt_port_result cvmx_mgmt_port_send(int port, int packet_len, -+ void *buffer) -+{ -+ struct cvmx_mgmt_port_state *state; -+ union cvmx_mixx_oring2 mix_oring2; -+ -+ if ((port < 0) || (port >= __cvmx_mgmt_port_num_ports())) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ /* Max sure the packet size is valid */ -+ if ((packet_len < 1) || (packet_len > CVMX_MGMT_PORT_TX_BUFFER_SIZE)) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ if (buffer == NULL) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ state = cvmx_mgmt_port_state_ptr + port; -+ -+ cvmx_spinlock_lock(&state->lock); -+ -+ mix_oring2.u64 = cvmx_read_csr(CVMX_MIXX_ORING2(port)); -+ if (mix_oring2.s.odbell >= CVMX_MGMT_PORT_NUM_TX_BUFFERS - 1) { -+ /* No room for another packet */ -+ cvmx_spinlock_unlock(&state->lock); -+ return CVMX_MGMT_PORT_NO_MEMORY; -+ } else { -+ /* Copy the packet into the output buffer */ -+ memcpy(state->tx_buffers[state->tx_write_index], buffer, -+ packet_len); -+ /* Insert the source MAC */ -+ memcpy(state->tx_buffers[state->tx_write_index] + 6, -+ ((char *)&state->mac) + 2, 6); -+ /* Update the TX ring buffer entry size */ -+ state->tx_ring[state->tx_write_index].s.len = packet_len; -+ /* Increment our TX index */ -+ state->tx_write_index = -+ (state->tx_write_index + 1) % CVMX_MGMT_PORT_NUM_TX_BUFFERS; -+ /* Ring the doorbell, send ing the packet */ -+ CVMX_SYNCWS; -+ cvmx_write_csr(CVMX_MIXX_ORING2(port), 1); -+ if (cvmx_read_csr(CVMX_MIXX_ORCNT(port))) -+ cvmx_write_csr(CVMX_MIXX_ORCNT(port), -+ cvmx_read_csr(CVMX_MIXX_ORCNT(port))); -+ -+ cvmx_spinlock_unlock(&state->lock); -+ return CVMX_MGMT_PORT_SUCCESS; -+ } -+} -+ -+/** -+ * Receive a packet from the management port. -+ * -+ * @port: Management port -+ * @buffer_len: Size of the buffer to receive the packet into -+ * @buffer: Buffer to receive the packet into -+ * -+ * Returns The size of the packet, or a negative erorr code on failure. Zero -+ * means that no packets were available. -+ */ -+int cvmx_mgmt_port_receive(int port, int buffer_len, void *buffer) -+{ -+ union cvmx_mixx_ircnt mix_ircnt; -+ struct cvmx_mgmt_port_state *state; -+ int result; -+ -+ if ((port < 0) || (port >= __cvmx_mgmt_port_num_ports())) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ /* Max sure the buffer size is valid */ -+ if (buffer_len < 1) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ if (buffer == NULL) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ state = cvmx_mgmt_port_state_ptr + port; -+ -+ cvmx_spinlock_lock(&state->lock); -+ -+ /* Find out how many RX packets are pending */ -+ mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port)); -+ if (mix_ircnt.s.ircnt) { -+ void *source = state->rx_buffers[state->rx_read_index]; -+ uint64_t *zero_check = source; -+ /* -+ * CN56XX pass 1 has an errata where packets might -+ * start 8 bytes into the buffer instead of at their -+ * correct location. If the first 8 bytes is zero we -+ * assume this has happened. -+ */ -+ if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) -+ && (*zero_check == 0)) -+ source += 8; -+ /* Start off with zero bytes received */ -+ result = 0; -+ /* -+ * While the completion code signals more data, copy -+ * the buffers into the user's data. -+ */ -+ while (state->rx_ring[state->rx_read_index].s.code == 16) { -+ /* Only copy what will fit in the user's buffer */ -+ int length = state->rx_ring[state->rx_read_index].s.len; -+ if (length > buffer_len) -+ length = buffer_len; -+ memcpy(buffer, source, length); -+ /* -+ * Reduce the size of the buffer to the -+ * remaining space. If we run out we will -+ * signal an error when the code 15 buffer -+ * doesn't fit. -+ */ -+ buffer += length; -+ buffer_len -= length; -+ result += length; -+ /* -+ * Update this buffer for reuse in future -+ * receives. This size is -8 due to an errata -+ * for CN56XX pass 1. -+ */ -+ state->rx_ring[state->rx_read_index].s.code = 0; -+ state->rx_ring[state->rx_read_index].s.len = -+ CVMX_MGMT_PORT_RX_BUFFER_SIZE - 8; -+ state->rx_read_index = -+ (state->rx_read_index + -+ 1) % CVMX_MGMT_PORT_NUM_RX_BUFFERS; -+ /* -+ * Zero the beginning of the buffer for use by -+ * the errata check. -+ */ -+ *zero_check = 0; -+ CVMX_SYNCWS; -+ /* Increment the number of RX buffers */ -+ cvmx_write_csr(CVMX_MIXX_IRING2(port), 1); -+ source = state->rx_buffers[state->rx_read_index]; -+ zero_check = source; -+ } -+ -+ /* Check for the final good completion code */ -+ if (state->rx_ring[state->rx_read_index].s.code == 15) { -+ if (buffer_len >= -+ state->rx_ring[state->rx_read_index].s.len) { -+ int length = -+ state->rx_ring[state->rx_read_index].s.len; -+ memcpy(buffer, source, length); -+ result += length; -+ } else { -+ /* Not enough room for the packet */ -+ cvmx_dprintf("ERROR: cvmx_mgmt_port_receive: " -+ "Packet (%d) larger than " -+ "supplied buffer (%d)\n", -+ state->rx_ring[state->rx_read_index].s.len, -+ buffer_len); -+ result = CVMX_MGMT_PORT_NO_MEMORY; -+ } -+ } else { -+ union cvmx_agl_gmx_prtx_cfg agl_gmx_prtx; -+ cvmx_dprintf("ERROR: cvmx_mgmt_port_receive: Receive " -+ "error code %d. Packet dropped(Len %d)\n", -+ state->rx_ring[state->rx_read_index].s.code, -+ state->rx_ring[state->rx_read_index].s.len + -+ result); -+ result = -state->rx_ring[state->rx_read_index].s.code; -+ -+ /* Check to see if we need to change the duplex. */ -+ agl_gmx_prtx.u64 = -+ cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port)); -+ if (cvmx_mgmt_port_get_link(port) < 0) -+ agl_gmx_prtx.s.duplex = 0; -+ else -+ agl_gmx_prtx.s.duplex = 1; -+ cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), -+ agl_gmx_prtx.u64); -+ } -+ -+ /* -+ * Clean out the ring buffer entry. This size is -8 -+ * due to an errata for CN56XX pass 1. -+ */ -+ state->rx_ring[state->rx_read_index].s.code = 0; -+ state->rx_ring[state->rx_read_index].s.len = -+ CVMX_MGMT_PORT_RX_BUFFER_SIZE - 8; -+ state->rx_read_index = -+ (state->rx_read_index + 1) % CVMX_MGMT_PORT_NUM_RX_BUFFERS; -+ /* -+ * Zero the beginning of the buffer for use by the -+ * errata check. -+ */ -+ *zero_check = 0; -+ CVMX_SYNCWS; -+ /* Increment the number of RX buffers */ -+ cvmx_write_csr(CVMX_MIXX_IRING2(port), 1); -+ /* Decrement the pending RX count */ -+ cvmx_write_csr(CVMX_MIXX_IRCNT(port), 1); -+ } else { -+ /* No packets available */ -+ result = 0; -+ } -+ cvmx_spinlock_unlock(&state->lock); -+ return result; -+} -+ -+/** -+ * Get the management port link status: -+ * 100 = 100Mbps, full duplex -+ * 10 = 10Mbps, full duplex -+ * 0 = Link down -+ * -10 = 10Mpbs, half duplex -+ * -100 = 100Mbps, half duplex -+ * -+ * @port: Management port -+ * -+ * Returns -+ */ -+int cvmx_mgmt_port_get_link(int port) -+{ -+ struct cvmx_mgmt_port_state *state; -+ int phy_status; -+ int duplex; -+ -+ if ((port < 0) || (port >= __cvmx_mgmt_port_num_ports())) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ state = cvmx_mgmt_port_state_ptr + port; -+ -+ /* Assume 100Mbps if we don't know the PHY address */ -+ if (state->phy_id == -1) -+ return 100; -+ -+ /* Read the PHY state */ -+ phy_status = -+ cvmx_mdio_read(state->phy_id >> 8, state->phy_id & 0xff, 17); -+ -+ /* Only return a link if the PHY has finished auto negotiation -+ and set the resolved bit (bit 11) */ -+ if (!(phy_status & (1 << 11))) -+ return 0; -+ -+ /* Create multiple factor to represent duplex */ -+ if ((phy_status >> 13) & 1) -+ duplex = 1; -+ else -+ duplex = -1; -+ -+ /* Speed is encoded on bits 15-14 */ -+ switch ((phy_status >> 14) & 3) { -+ case 0: /* 10 Mbps */ -+ return 10 * duplex; -+ case 1: /* 100 Mbps */ -+ return 100 * duplex; -+ default: -+ return 0; -+ } -+} -+ -+/** -+ * Set the MAC address for a management port -+ * -+ * @port: Management port -+ * @mac: New MAC address. The lower 6 bytes are used. -+ * -+ * Returns CVMX_MGMT_PORT_SUCCESS or an error code -+ */ -+enum cvmx_mgmt_port_result cvmx_mgmt_port_set_mac(int port, uint64_t mac) -+{ -+ struct cvmx_mgmt_port_state *state; -+ union cvmx_agl_gmx_rxx_adr_ctl agl_gmx_rxx_adr_ctl; -+ -+ if ((port < 0) || (port >= __cvmx_mgmt_port_num_ports())) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ state = cvmx_mgmt_port_state_ptr + port; -+ -+ cvmx_spinlock_lock(&state->lock); -+ -+ agl_gmx_rxx_adr_ctl.u64 = 0; -+ /* Only accept matching MAC addresses */ -+ agl_gmx_rxx_adr_ctl.s.cam_mode = 1; -+ /* Drop multicast */ -+ agl_gmx_rxx_adr_ctl.s.mcst = 0; -+ /* Allow broadcast */ -+ agl_gmx_rxx_adr_ctl.s.bcst = 1; -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CTL(port), agl_gmx_rxx_adr_ctl.u64); -+ -+ /* Only using one of the CAMs */ -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM0(port), (mac >> 40) & 0xff); -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM1(port), (mac >> 32) & 0xff); -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM2(port), (mac >> 24) & 0xff); -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM3(port), (mac >> 16) & 0xff); -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM4(port), (mac >> 8) & 0xff); -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM5(port), (mac >> 0) & 0xff); -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM_EN(port), 1); -+ state->mac = mac; -+ -+ cvmx_spinlock_unlock(&state->lock); -+ return CVMX_MGMT_PORT_SUCCESS; -+} -+ -+/** -+ * Get the MAC address for a management port -+ * -+ * @port: Management port -+ * -+ * Returns MAC address -+ */ -+uint64_t cvmx_mgmt_port_get_mac(int port) -+{ -+ if ((port < 0) || (port >= __cvmx_mgmt_port_num_ports())) -+ return CVMX_MGMT_PORT_INVALID_PARAM; -+ -+ return cvmx_mgmt_port_state_ptr[port].mac; -+} -+ -+/** -+ * Set the multicast list. -+ * -+ * @port: Management port -+ * @flags: Interface flags -+ * -+ * Returns -+ */ -+void cvmx_mgmt_port_set_multicast_list(int port, int flags) -+{ -+ struct cvmx_mgmt_port_state *state; -+ union cvmx_agl_gmx_rxx_adr_ctl agl_gmx_rxx_adr_ctl; -+ -+ if ((port < 0) || (port >= __cvmx_mgmt_port_num_ports())) -+ return; -+ -+ state = cvmx_mgmt_port_state_ptr + port; -+ -+ cvmx_spinlock_lock(&state->lock); -+ -+ agl_gmx_rxx_adr_ctl.u64 = cvmx_read_csr(CVMX_AGL_GMX_RXX_ADR_CTL(port)); -+ -+ /* Allow broadcast MAC addresses */ -+ if (!agl_gmx_rxx_adr_ctl.s.bcst) -+ agl_gmx_rxx_adr_ctl.s.bcst = 1; -+ -+ if ((flags & CVMX_IFF_ALLMULTI) || (flags & CVMX_IFF_PROMISC)) -+ /* Force accept multicast packets */ -+ agl_gmx_rxx_adr_ctl.s.mcst = 2; -+ else -+ /* Force reject multicast packets */ -+ agl_gmx_rxx_adr_ctl.s.mcst = 1; -+ -+ if (flags & CVMX_IFF_PROMISC) -+ /* -+ * Reject matches if promisc. Since CAM is shut off, -+ * should accept everything. -+ */ -+ agl_gmx_rxx_adr_ctl.s.cam_mode = 0; -+ else -+ /* Filter packets based on the CAM */ -+ agl_gmx_rxx_adr_ctl.s.cam_mode = 1; -+ -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CTL(port), agl_gmx_rxx_adr_ctl.u64); -+ -+ if (flags & CVMX_IFF_PROMISC) -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM_EN(port), 0); -+ else -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM_EN(port), 1); -+ -+ cvmx_spinlock_unlock(&state->lock); -+} -+ -+/** -+ * Set the maximum packet allowed in. Size is specified -+ * including L2 but without FCS. A normal MTU would corespond -+ * to 1514 assuming the standard 14 byte L2 header. -+ * -+ * @port: Management port -+ * @size_without_fcs: -+ * Size in bytes without FCS -+ */ -+void cvmx_mgmt_port_set_max_packet_size(int port, int size_without_fcs) -+{ -+ struct cvmx_mgmt_port_state *state; -+ -+ if ((port < 0) || (port >= __cvmx_mgmt_port_num_ports())) -+ return; -+ -+ state = cvmx_mgmt_port_state_ptr + port; -+ -+ cvmx_spinlock_lock(&state->lock); -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_MAX(port), size_without_fcs); -+ cvmx_write_csr(CVMX_AGL_GMX_RXX_JABBER(port), -+ (size_without_fcs + 7) & 0xfff8); -+ cvmx_spinlock_unlock(&state->lock); -+} ---- /dev/null -+++ b/drivers/net/octeon/cvmx-mgmt-port.h -@@ -0,0 +1,168 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * Support functions for managing the MII management port -+ * -+ */ -+ -+#ifndef __CVMX_MGMT_PORT_H__ -+#define __CVMX_MGMT_PORT_H__ -+ -+enum cvmx_mgmt_port_result { -+ CVMX_MGMT_PORT_SUCCESS = 0, -+ CVMX_MGMT_PORT_NO_MEMORY = -1, -+ CVMX_MGMT_PORT_INVALID_PARAM = -2, -+}; -+ -+/* Enumeration of Net Device interface flags. */ -+enum cvmx_mgmt_port_netdevice_flags { -+ CVMX_IFF_PROMISC = 0x100, /* receive all packets */ -+ CVMX_IFF_ALLMULTI = 0x200, /* receive all multicast packets */ -+}; -+ -+/** -+ * Called to initialize a management port for use. Multiple calls -+ * to this function accross applications is safe. -+ * -+ * @port: Port to initialize -+ * -+ * Returns CVMX_MGMT_PORT_SUCCESS or an error code -+ */ -+extern enum cvmx_mgmt_port_result cvmx_mgmt_port_initialize(int port); -+ -+/** -+ * Shutdown a management port. This currently disables packet IO -+ * but leaves all hardware and buffers. Another application can then -+ * call initialize() without redoing the hardware setup. -+ * -+ * @port: Management port -+ * -+ * Returns CVMX_MGMT_PORT_SUCCESS or an error code -+ */ -+extern enum cvmx_mgmt_port_result cvmx_mgmt_port_shutdown(int port); -+ -+/** -+ * Enable packet IO on a management port -+ * -+ * @port: Management port -+ * -+ * Returns CVMX_MGMT_PORT_SUCCESS or an error code -+ */ -+extern enum cvmx_mgmt_port_result cvmx_mgmt_port_enable(int port); -+ -+/** -+ * Disable packet IO on a management port -+ * -+ * @port: Management port -+ * -+ * Returns CVMX_MGMT_PORT_SUCCESS or an error code -+ */ -+extern enum cvmx_mgmt_port_result cvmx_mgmt_port_disable(int port); -+ -+/** -+ * Send a packet out the management port. The packet is copied so -+ * the input buffer isn't used after this call. -+ * -+ * @port: Management port -+ * @packet_len: Length of the packet to send. It does not include the final CRC -+ * @buffer: Packet data -+ * -+ * Returns CVMX_MGMT_PORT_SUCCESS or an error code -+ */ -+extern enum cvmx_mgmt_port_result cvmx_mgmt_port_send(int port, int packet_len, -+ void *buffer); -+ -+/** -+ * Receive a packet from the management port. -+ * -+ * @port: Management port -+ * @buffer_len: Size of the buffer to receive the packet into -+ * @buffer: Buffer to receive the packet into -+ * -+ * Returns The size of the packet, or a negative erorr code on failure. Zero -+ * means that no packets were available. -+ */ -+extern int cvmx_mgmt_port_receive(int port, int buffer_len, void *buffer); -+ -+/** -+ * Get the management port link status: -+ * 100 = 100Mbps, full duplex -+ * 10 = 10Mbps, full duplex -+ * 0 = Link down -+ * -10 = 10Mpbs, half duplex -+ * -100 = 100Mbps, half duplex -+ * -+ * @port: Management port -+ * -+ * Returns -+ */ -+extern int cvmx_mgmt_port_get_link(int port); -+ -+/** -+ * Set the MAC address for a management port -+ * -+ * @port: Management port -+ * @mac: New MAC address. The lower 6 bytes are used. -+ * -+ * Returns CVMX_MGMT_PORT_SUCCESS or an error code -+ */ -+extern enum cvmx_mgmt_port_result cvmx_mgmt_port_set_mac(int port, -+ uint64_t mac); -+ -+/** -+ * Get the MAC address for a management port -+ * -+ * @port: Management port -+ * -+ * Returns MAC address -+ */ -+extern uint64_t cvmx_mgmt_port_get_mac(int port); -+ -+/** -+ * Set the multicast list. -+ * -+ * @port: Management port -+ * @flags: Interface flags -+ * -+ * Returns -+ */ -+extern void cvmx_mgmt_port_set_multicast_list(int port, int flags); -+ -+/** -+ * Set the maximum packet allowed in. Size is specified -+ * including L2 but without FCS. A normal MTU would corespond -+ * to 1514 assuming the standard 14 byte L2 header. -+ * -+ * @port: Management port -+ * @size_without_crc: -+ * Size in bytes without FCS -+ */ -+extern void cvmx_mgmt_port_set_max_packet_size(int port, int size_without_fcs); -+ -+#endif /* __CVMX_MGMT_PORT_H__ */ ---- /dev/null -+++ b/drivers/net/octeon/octeon-mgmt-port.c -@@ -0,0 +1,389 @@ -+/* -+ * Octeon Management Port Ethernet Driver -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2007, 2008 Cavium Networks -+ */ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/ip.h> -+#include <linux/string.h> -+#include <linux/delay.h> -+ -+#include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-mixx-defs.h> -+#include <asm/octeon/cvmx-agl-defs.h> -+ -+#include "cvmx-mgmt-port.h" -+ -+static struct net_device *global_dev[2] = { NULL, NULL }; -+ -+#define DEBUGPRINT(format, ...) do {if (printk_ratelimit()) \ -+ printk(format, ##__VA_ARGS__); \ -+ } while (0) -+ -+/** -+ * This is the definition of the Ethernet driver's private -+ * driver state stored in dev->priv. -+ */ -+struct device_private { -+ int port; -+ struct net_device_stats stats; /* Device statistics */ -+}; -+ -+ -+/** -+ * Packet transmit -+ * -+ * @param skb Packet to send -+ * @param dev Device info structure -+ * @return Always returns zero -+ */ -+static int packet_transmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ uint64_t flags; -+ struct device_private *priv = netdev_priv(dev); -+ enum cvmx_mgmt_port_result result; -+ local_irq_save(flags); -+ result = cvmx_mgmt_port_send(priv->port, skb->len, skb->data); -+ local_irq_restore(flags); -+ if (result == CVMX_MGMT_PORT_SUCCESS) { -+ priv->stats.tx_packets++; -+ priv->stats.tx_bytes += skb->len; -+ } else { -+ /* DEBUGPRINT("ERROR: cvmx_mgmt_port_send() failed with %d\n", -+ result); -+ */ -+ priv->stats.tx_dropped++; -+ } -+ dev_kfree_skb(skb); -+ return 0; -+} -+ -+ -+/** -+ * Interrupt handler. The interrupt occurs whenever the POW -+ * transitions from 0->1 packets in our group. -+ * -+ * @param cpl -+ * @param dev_id -+ * @param regs -+ * @return -+ */ -+static irqreturn_t do_interrupt(int cpl, void *dev_id) -+{ -+ uint64_t flags; -+ struct sk_buff *skb; -+ int result; -+ char packet[2048]; -+ struct net_device *dev = (struct net_device *) dev_id; -+ struct device_private *priv = netdev_priv(dev); -+ -+ do { -+ local_irq_save(flags); -+ result = cvmx_mgmt_port_receive(priv->port, sizeof(packet), -+ packet); -+ local_irq_restore(flags); -+ -+ /* Silently drop packets if we aren't up */ -+ if ((dev->flags & IFF_UP) == 0) -+ continue; -+ -+ if (result > 0) { -+ skb = dev_alloc_skb(result); -+ if (skb) { -+ memcpy(skb_put(skb, result), packet, result); -+ skb->protocol = eth_type_trans(skb, dev); -+ skb->dev = dev; -+ skb->ip_summed = CHECKSUM_NONE; -+ priv->stats.rx_bytes += skb->len; -+ priv->stats.rx_packets++; -+ netif_rx(skb); -+ } else { -+ DEBUGPRINT("%s: Failed to allocate skbuff, " -+ "packet dropped\n", -+ dev->name); -+ priv->stats.rx_dropped++; -+ } -+ } else if (result < 0) { -+ DEBUGPRINT("%s: Receive error code %d, packet " -+ "dropped\n", -+ dev->name, result); -+ priv->stats.rx_errors++; -+ } -+ } while (result != 0); -+ -+ /* Clear any pending interrupts */ -+ cvmx_write_csr(CVMX_MIXX_ISR(priv->port), -+ cvmx_read_csr(CVMX_MIXX_ISR(priv->port))); -+ cvmx_read_csr(CVMX_MIXX_ISR(priv->port)); -+ -+ return IRQ_HANDLED; -+} -+ -+ -+#ifdef CONFIG_NET_POLL_CONTROLLER -+/** -+ * This is called when the kernel needs to manually poll the -+ * device. For Octeon, this is simply calling the interrupt -+ * handler. We actually poll all the devices, not just the -+ * one supplied. -+ * -+ * @param dev Device to poll. Unused -+ */ -+static void device_poll_controller(struct net_device *dev) -+{ -+ do_interrupt(0, dev); -+} -+#endif -+ -+ -+/** -+ * Open a device for use. Device should be able to send and -+ * receive packets after this is called. -+ * -+ * @param dev Device to bring up -+ * @return Zero on success -+ */ -+static int device_open(struct net_device *dev) -+{ -+ /* Clear the statistics whenever the interface is brought up */ -+ struct device_private *priv = netdev_priv(dev); -+ memset(&priv->stats, 0, sizeof(priv->stats)); -+ cvmx_mgmt_port_enable(priv->port); -+ return 0; -+} -+ -+ -+/** -+ * Stop an ethernet device. No more packets should be -+ * received from this device. -+ * -+ * @param dev Device to bring down -+ * @return Zero on success -+ */ -+static int device_close(struct net_device *dev) -+{ -+ struct device_private *priv = netdev_priv(dev); -+ cvmx_mgmt_port_disable(priv->port); -+ return 0; -+} -+ -+ -+/** -+ * Get the low level ethernet statistics -+ * -+ * @param dev Device to get the statistics from -+ * @return Pointer to the statistics -+ */ -+static struct net_device_stats *device_get_stats(struct net_device *dev) -+{ -+ struct device_private *priv = netdev_priv(dev); -+ return &priv->stats; -+} -+ -+/** -+ * Set the multicast list. Currently unimplemented. -+ * -+ * @param dev Device to work on -+ */ -+static void ethernet_mgmt_port_set_multicast_list(struct net_device *dev) -+{ -+ struct device_private *priv = netdev_priv(dev); -+ int port = priv->port; -+ int num_ports; -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) -+ num_ports = 2; -+ else -+ num_ports = 1; -+ if (port < num_ports) -+ cvmx_mgmt_port_set_multicast_list(port, dev->flags); -+} -+ -+/** -+ * Set the hardware MAC address for a management port device -+ * -+ * @param dev Device to change the MAC address for -+ * @param addr Address structure to change it too. MAC address is addr + 2. -+ * @return Zero on success -+ */ -+static int ethernet_mgmt_port_set_mac_address(struct net_device *dev, -+ void *addr) -+{ -+ struct device_private *priv = netdev_priv(dev); -+ union cvmx_agl_gmx_prtx_cfg agl_gmx_cfg; -+ int port = priv->port; -+ int num_ports; -+ -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) -+ num_ports = 2; -+ else -+ num_ports = 1; -+ -+ memcpy(dev->dev_addr, addr + 2, 6); -+ -+ if (port < num_ports) { -+ int i; -+ uint8_t *ptr = addr; -+ uint64_t mac = 0; -+ for (i = 0; i < 6; i++) -+ mac = (mac<<8) | (uint64_t)(ptr[i+2]); -+ -+ agl_gmx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port)); -+ cvmx_mgmt_port_set_mac(port, mac); -+ ethernet_mgmt_port_set_multicast_list(dev); -+ cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_cfg.u64); -+ } -+ return 0; -+} -+ -+/** -+ * Per network device initialization -+ * -+ * @param dev Device to initialize -+ * @return Zero on success -+ */ -+static int device_init(struct net_device *dev) -+{ -+ struct device_private *priv = netdev_priv(dev); -+ uint64_t mac = cvmx_mgmt_port_get_mac(priv->port); -+ -+ dev->hard_start_xmit = packet_transmit; -+ dev->get_stats = device_get_stats; -+ dev->open = device_open; -+ dev->stop = device_close; -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ dev->poll_controller = device_poll_controller; -+#endif -+ dev->dev_addr[0] = (mac >> 40) & 0xff; -+ dev->dev_addr[1] = (mac >> 32) & 0xff; -+ dev->dev_addr[2] = (mac >> 24) & 0xff; -+ dev->dev_addr[3] = (mac >> 16) & 0xff; -+ dev->dev_addr[4] = (mac >> 8) & 0xff; -+ dev->dev_addr[5] = (mac >> 0) & 0xff; -+ return 0; -+} -+ -+ -+/** -+ * Module/ driver initialization. Creates the linux network -+ * devices. -+ * -+ * @return Zero on success -+ */ -+static int __init ethernet_mgmt_port_init(void) -+{ -+ struct net_device *dev; -+ struct device_private *priv; -+ union cvmx_mixx_irhwm mix_irhwm; -+ union cvmx_mixx_intena mix_intena; -+ int num_ports; -+ int port; -+ -+ if (!OCTEON_IS_MODEL(OCTEON_CN56XX) && !OCTEON_IS_MODEL(OCTEON_CN52XX)) -+ return 0; -+ -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) -+ num_ports = 2; -+ else -+ num_ports = 1; -+ -+ printk("Octeon management port ethernet driver\n"); -+ -+ for (port = 0; port < num_ports; port++) { -+ if (cvmx_mgmt_port_initialize(port) != CVMX_MGMT_PORT_SUCCESS) { -+ pr_err("ERROR: cvmx_mgmt_port_initialize(%d) " -+ "failed\n", port); -+ return -1; -+ } -+ -+ /* Setup is complete, create the virtual ethernet devices */ -+ dev = alloc_etherdev(sizeof(struct device_private)); -+ if (dev == NULL) { -+ pr_err("ERROR: Failed to allocate ethernet device\n"); -+ return -1; -+ } -+ -+ dev->init = device_init; -+ strcpy(dev->name, "mgmt%d"); -+ -+ /* Initialize the device private structure. */ -+ priv = netdev_priv(dev); -+ memset(priv, 0, sizeof(struct device_private)); -+ priv->port = port; -+ -+ if (register_netdev(dev) < 0) { -+ pr_err("ERROR: Failed to register ethernet device\n"); -+ kfree(dev); -+ return -1; -+ } -+ -+ /* Clear any pending interrupts */ -+ cvmx_write_csr(CVMX_MIXX_ISR(priv->port), -+ cvmx_read_csr(CVMX_MIXX_ISR(priv->port))); -+ -+ /* Register an IRQ hander for to receive interrupts */ -+ dev->irq = -+ (priv->port == 0) ? OCTEON_IRQ_MII0 : OCTEON_IRQ_MII1; -+ if (request_irq(dev->irq, do_interrupt, IRQF_SHARED, dev->name, -+ dev)) -+ pr_err("ethernet-mgmt: Failed to assign " -+ "interrupt %d\n", dev->irq); -+ -+ /* Interrupt every single RX packet */ -+ mix_irhwm.u64 = 0; -+ mix_irhwm.s.irhwm = 0; -+ cvmx_write_csr(CVMX_MIXX_IRHWM(priv->port), mix_irhwm.u64); -+ -+ /* Enable receive interrupts */ -+ mix_intena.u64 = 0; -+ mix_intena.s.ithena = 1; -+ cvmx_write_csr(CVMX_MIXX_INTENA(priv->port), mix_intena.u64); -+ -+ global_dev[priv->port] = dev; -+ -+ dev->set_mac_address = ethernet_mgmt_port_set_mac_address; -+ dev->set_multicast_list = ethernet_mgmt_port_set_multicast_list; -+ } -+ return 0; -+} -+ -+ -+/** -+ * Module / driver shutdown -+ * -+ * @return Zero on success -+ */ -+static void __exit ethernet_mgmt_port_cleanup(void) -+{ -+ int port; -+ for (port = 0; port < 2; port++) { -+ if (global_dev[port]) { -+ struct device_private *priv = -+ netdev_priv(global_dev[port]); -+ /* Disable interrupt */ -+ cvmx_write_csr(CVMX_MIXX_IRHWM(priv->port), 0); -+ cvmx_write_csr(CVMX_MIXX_INTENA(priv->port), 0); -+ cvmx_mgmt_port_shutdown(priv->port); -+ -+ /* Free the interrupt handler */ -+ free_irq(global_dev[port]->irq, global_dev[port]); -+ -+ /* Free the ethernet devices */ -+ unregister_netdev(global_dev[port]); -+ kfree(global_dev[port]); -+ global_dev[port] = NULL; -+ } -+ } -+} -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>"); -+MODULE_DESCRIPTION("Cavium Networks Octeon management port ethernet driver."); -+module_init(ethernet_mgmt_port_init); -+module_exit(ethernet_mgmt_port_cleanup); diff --git a/target/linux/octeon/patches-2.6.30/007-export_cvmx_sysinfo.patch b/target/linux/octeon/patches-2.6.30/007-export_cvmx_sysinfo.patch deleted file mode 100644 index 318916d15b..0000000000 --- a/target/linux/octeon/patches-2.6.30/007-export_cvmx_sysinfo.patch +++ /dev/null @@ -1,23 +0,0 @@ -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - arch/mips/cavium-octeon/executive/cvmx-sysinfo.c | 2 ++ - 1 files changed, 2 insertions(+), 0 deletions(-) - ---- a/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c -+++ b/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c -@@ -29,6 +29,7 @@ - * This module provides system/board/application information obtained - * by the bootloader. - */ -+#include <linux/module.h> - - #include <asm/octeon/cvmx.h> - #include <asm/octeon/cvmx-spinlock.h> -@@ -69,6 +70,7 @@ struct cvmx_sysinfo *cvmx_sysinfo_get(vo - { - return &(state.sysinfo); - } -+EXPORT_SYMBOL(cvmx_sysinfo_get); - - /** - * This function is used in non-simple executive environments (such as diff --git a/target/linux/octeon/patches-2.6.30/008-more_board_types_constraints.patch b/target/linux/octeon/patches-2.6.30/008-more_board_types_constraints.patch deleted file mode 100644 index bb375852ff..0000000000 --- a/target/linux/octeon/patches-2.6.30/008-more_board_types_constraints.patch +++ /dev/null @@ -1,37 +0,0 @@ -The bootloader now uses additional board type constants. The -octeon-ethernet driver needs some of the new values. - -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - arch/mips/include/asm/octeon/cvmx-bootinfo.h | 13 +++++++++++++ - 1 files changed, 13 insertions(+), 0 deletions(-) - ---- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h -+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h -@@ -157,6 +157,13 @@ enum cvmx_board_types_enum { - CVMX_BOARD_TYPE_NIC_XLE_4G = 21, - CVMX_BOARD_TYPE_EBT5600 = 22, - CVMX_BOARD_TYPE_EBH5201 = 23, -+ CVMX_BOARD_TYPE_EBT5200 = 24, -+ CVMX_BOARD_TYPE_CB5600 = 25, -+ CVMX_BOARD_TYPE_CB5601 = 26, -+ CVMX_BOARD_TYPE_CB5200 = 27, -+ /* Special 'generic' board type, supports many boards */ -+ CVMX_BOARD_TYPE_GENERIC = 28, -+ CVMX_BOARD_TYPE_EBH5610 = 29, - CVMX_BOARD_TYPE_MAX, - - /* -@@ -228,6 +235,12 @@ static inline const char *cvmx_board_typ - ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC_XLE_4G) - ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5600) - ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5201) -+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5200) -+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CB5600) -+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CB5601) -+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CB5200) -+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_GENERIC) -+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5610) - ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_MAX) - - /* Customer boards listed here */ diff --git a/target/linux/octeon/patches-2.6.30/009-more_chip_specific_feature_tests.patch b/target/linux/octeon/patches-2.6.30/009-more_chip_specific_feature_tests.patch deleted file mode 100644 index 63dc4f13de..0000000000 --- a/target/linux/octeon/patches-2.6.30/009-more_chip_specific_feature_tests.patch +++ /dev/null @@ -1,51 +0,0 @@ -The octeon-ethernet driver needs to check for additional chip specific -features, we add them to the octeon_has_feature() framework. - -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - arch/mips/include/asm/octeon/octeon-feature.h | 27 +++++++++++++++++++++++++ - 1 files changed, 27 insertions(+), 0 deletions(-) - ---- a/arch/mips/include/asm/octeon/octeon-feature.h -+++ b/arch/mips/include/asm/octeon/octeon-feature.h -@@ -57,6 +57,13 @@ enum octeon_feature { - OCTEON_FEATURE_RAID, - /* Octeon has a builtin USB */ - OCTEON_FEATURE_USB, -+ /* Octeon IPD can run without using work queue entries */ -+ OCTEON_FEATURE_NO_WPTR, -+ /* Octeon has DFA state machines */ -+ OCTEON_FEATURE_DFA, -+ /* Octeon MDIO block supports clause 45 transactions for 10 -+ * Gig support */ -+ OCTEON_FEATURE_MDIO_CLAUSE_45, - }; - - static inline int cvmx_fuse_read(int fuse); -@@ -112,6 +119,26 @@ static inline int octeon_has_feature(enu - case OCTEON_FEATURE_USB: - return !(OCTEON_IS_MODEL(OCTEON_CN38XX) - || OCTEON_IS_MODEL(OCTEON_CN58XX)); -+ case OCTEON_FEATURE_NO_WPTR: -+ return (OCTEON_IS_MODEL(OCTEON_CN56XX) -+ || OCTEON_IS_MODEL(OCTEON_CN52XX)) -+ && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) -+ && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X); -+ case OCTEON_FEATURE_DFA: -+ if (!OCTEON_IS_MODEL(OCTEON_CN38XX) -+ && !OCTEON_IS_MODEL(OCTEON_CN31XX) -+ && !OCTEON_IS_MODEL(OCTEON_CN58XX)) -+ return 0; -+ else if (OCTEON_IS_MODEL(OCTEON_CN3020)) -+ return 0; -+ else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)) -+ return 1; -+ else -+ return !cvmx_fuse_read(120); -+ case OCTEON_FEATURE_MDIO_CLAUSE_45: -+ return !(OCTEON_IS_MODEL(OCTEON_CN3XXX) -+ || OCTEON_IS_MODEL(OCTEON_CN58XX) -+ || OCTEON_IS_MODEL(OCTEON_CN50XX)); - } - return 0; - } diff --git a/target/linux/octeon/patches-2.6.30/010-export_erratum_function.patch b/target/linux/octeon/patches-2.6.30/010-export_erratum_function.patch deleted file mode 100644 index 83b09fbede..0000000000 --- a/target/linux/octeon/patches-2.6.30/010-export_erratum_function.patch +++ /dev/null @@ -1,21 +0,0 @@ -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - .../cavium-octeon/executive/cvmx-helper-errata.c | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) - ---- a/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c -+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c -@@ -33,6 +33,8 @@ - * these functions directly. - * - */ -+#include <linux/module.h> -+ - #include <asm/octeon/octeon.h> - - #include <asm/octeon/cvmx-helper-util.h> -@@ -377,3 +379,4 @@ void __cvmx_helper_errata_qlm_disable_2n - } - cvmx_helper_qlm_jtag_update(qlm); - } -+EXPORT_SYMBOL(__cvmx_helper_errata_qlm_disable_2nd_order_cdr); diff --git a/target/linux/octeon/patches-2.6.30/011-octeon_ethernet_driver.patch b/target/linux/octeon/patches-2.6.30/011-octeon_ethernet_driver.patch deleted file mode 100644 index dec15866b0..0000000000 --- a/target/linux/octeon/patches-2.6.30/011-octeon_ethernet_driver.patch +++ /dev/null @@ -1,26533 +0,0 @@ -The octeon-ethernet driver supports the sgmii, rgmii, spi, and xaui -ports present on the Cavium OCTEON family of SOCs. These SOCs are -multi-core mips64 processors with existing support over in arch/mips. - -The driver files can be categorized into three basic groups: - -1) Register definitions, these are named cvmx-*-defs.h - -2) Main driver code, these have names that don't start cvmx-. - -3) Interface specific functions and other utility code, names starting -with cvmx- - -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - drivers/staging/octeon/Kconfig | 12 + - drivers/staging/octeon/Makefile | 30 + - drivers/staging/octeon/cvmx-address.h | 274 +++ - drivers/staging/octeon/cvmx-asxx-defs.h | 475 +++++ - drivers/staging/octeon/cvmx-cmd-queue.c | 306 +++ - drivers/staging/octeon/cvmx-cmd-queue.h | 617 ++++++ - drivers/staging/octeon/cvmx-config.h | 169 ++ - drivers/staging/octeon/cvmx-dbg-defs.h | 72 + - drivers/staging/octeon/cvmx-fau.h | 597 ++++++ - drivers/staging/octeon/cvmx-fpa-defs.h | 403 ++++ - drivers/staging/octeon/cvmx-fpa.c | 183 ++ - drivers/staging/octeon/cvmx-fpa.h | 299 +++ - drivers/staging/octeon/cvmx-gmxx-defs.h | 2529 +++++++++++++++++++++++ - drivers/staging/octeon/cvmx-helper-board.c | 706 +++++++ - drivers/staging/octeon/cvmx-helper-board.h | 180 ++ - drivers/staging/octeon/cvmx-helper-fpa.c | 243 +++ - drivers/staging/octeon/cvmx-helper-fpa.h | 64 + - drivers/staging/octeon/cvmx-helper-loop.c | 85 + - drivers/staging/octeon/cvmx-helper-loop.h | 59 + - drivers/staging/octeon/cvmx-helper-npi.c | 113 + - drivers/staging/octeon/cvmx-helper-npi.h | 60 + - drivers/staging/octeon/cvmx-helper-rgmii.c | 525 +++++ - drivers/staging/octeon/cvmx-helper-rgmii.h | 110 + - drivers/staging/octeon/cvmx-helper-sgmii.c | 550 +++++ - drivers/staging/octeon/cvmx-helper-sgmii.h | 104 + - drivers/staging/octeon/cvmx-helper-spi.c | 195 ++ - drivers/staging/octeon/cvmx-helper-spi.h | 84 + - drivers/staging/octeon/cvmx-helper-util.c | 433 ++++ - drivers/staging/octeon/cvmx-helper-util.h | 215 ++ - drivers/staging/octeon/cvmx-helper-xaui.c | 348 ++++ - drivers/staging/octeon/cvmx-helper-xaui.h | 103 + - drivers/staging/octeon/cvmx-helper.c | 1058 ++++++++++ - drivers/staging/octeon/cvmx-helper.h | 227 ++ - drivers/staging/octeon/cvmx-interrupt-decodes.c | 371 ++++ - drivers/staging/octeon/cvmx-interrupt-rsl.c | 140 ++ - drivers/staging/octeon/cvmx-ipd.h | 338 +++ - drivers/staging/octeon/cvmx-mdio.h | 506 +++++ - drivers/staging/octeon/cvmx-packet.h | 65 + - drivers/staging/octeon/cvmx-pcsx-defs.h | 370 ++++ - drivers/staging/octeon/cvmx-pcsxx-defs.h | 316 +++ - drivers/staging/octeon/cvmx-pip-defs.h | 1267 ++++++++++++ - drivers/staging/octeon/cvmx-pip.h | 524 +++++ - drivers/staging/octeon/cvmx-pko-defs.h | 1133 ++++++++++ - drivers/staging/octeon/cvmx-pko.c | 506 +++++ - drivers/staging/octeon/cvmx-pko.h | 610 ++++++ - drivers/staging/octeon/cvmx-pow.h | 1982 ++++++++++++++++++ - drivers/staging/octeon/cvmx-scratch.h | 139 ++ - drivers/staging/octeon/cvmx-smix-defs.h | 178 ++ - drivers/staging/octeon/cvmx-spi.c | 667 ++++++ - drivers/staging/octeon/cvmx-spi.h | 269 +++ - drivers/staging/octeon/cvmx-spxx-defs.h | 347 ++++ - drivers/staging/octeon/cvmx-srxx-defs.h | 126 ++ - drivers/staging/octeon/cvmx-stxx-defs.h | 292 +++ - drivers/staging/octeon/cvmx-wqe.h | 397 ++++ - drivers/staging/octeon/ethernet-common.c | 328 +++ - drivers/staging/octeon/ethernet-common.h | 29 + - drivers/staging/octeon/ethernet-defines.h | 134 ++ - drivers/staging/octeon/ethernet-mdio.c | 231 +++ - drivers/staging/octeon/ethernet-mdio.h | 46 + - drivers/staging/octeon/ethernet-mem.c | 198 ++ - drivers/staging/octeon/ethernet-mem.h | 29 + - drivers/staging/octeon/ethernet-proc.c | 256 +++ - drivers/staging/octeon/ethernet-proc.h | 29 + - drivers/staging/octeon/ethernet-rgmii.c | 397 ++++ - drivers/staging/octeon/ethernet-rx.c | 505 +++++ - drivers/staging/octeon/ethernet-rx.h | 33 + - drivers/staging/octeon/ethernet-sgmii.c | 129 ++ - drivers/staging/octeon/ethernet-spi.c | 323 +++ - drivers/staging/octeon/ethernet-tx.c | 634 ++++++ - drivers/staging/octeon/ethernet-tx.h | 32 + - drivers/staging/octeon/ethernet-util.h | 81 + - drivers/staging/octeon/ethernet-xaui.c | 127 ++ - drivers/staging/octeon/ethernet.c | 507 +++++ - drivers/staging/octeon/octeon-ethernet.h | 127 ++ - 74 files changed, 26146 insertions(+), 0 deletions(-) - create mode 100644 drivers/staging/octeon/Kconfig - create mode 100644 drivers/staging/octeon/Makefile - create mode 100644 drivers/staging/octeon/cvmx-address.h - create mode 100644 drivers/staging/octeon/cvmx-asxx-defs.h - create mode 100644 drivers/staging/octeon/cvmx-cmd-queue.c - create mode 100644 drivers/staging/octeon/cvmx-cmd-queue.h - create mode 100644 drivers/staging/octeon/cvmx-config.h - create mode 100644 drivers/staging/octeon/cvmx-dbg-defs.h - create mode 100644 drivers/staging/octeon/cvmx-fau.h - create mode 100644 drivers/staging/octeon/cvmx-fpa-defs.h - create mode 100644 drivers/staging/octeon/cvmx-fpa.c - create mode 100644 drivers/staging/octeon/cvmx-fpa.h - create mode 100644 drivers/staging/octeon/cvmx-gmxx-defs.h - create mode 100644 drivers/staging/octeon/cvmx-helper-board.c - create mode 100644 drivers/staging/octeon/cvmx-helper-board.h - create mode 100644 drivers/staging/octeon/cvmx-helper-fpa.c - create mode 100644 drivers/staging/octeon/cvmx-helper-fpa.h - create mode 100644 drivers/staging/octeon/cvmx-helper-loop.c - create mode 100644 drivers/staging/octeon/cvmx-helper-loop.h - create mode 100644 drivers/staging/octeon/cvmx-helper-npi.c - create mode 100644 drivers/staging/octeon/cvmx-helper-npi.h - create mode 100644 drivers/staging/octeon/cvmx-helper-rgmii.c - create mode 100644 drivers/staging/octeon/cvmx-helper-rgmii.h - create mode 100644 drivers/staging/octeon/cvmx-helper-sgmii.c - create mode 100644 drivers/staging/octeon/cvmx-helper-sgmii.h - create mode 100644 drivers/staging/octeon/cvmx-helper-spi.c - create mode 100644 drivers/staging/octeon/cvmx-helper-spi.h - create mode 100644 drivers/staging/octeon/cvmx-helper-util.c - create mode 100644 drivers/staging/octeon/cvmx-helper-util.h - create mode 100644 drivers/staging/octeon/cvmx-helper-xaui.c - create mode 100644 drivers/staging/octeon/cvmx-helper-xaui.h - create mode 100644 drivers/staging/octeon/cvmx-helper.c - create mode 100644 drivers/staging/octeon/cvmx-helper.h - create mode 100644 drivers/staging/octeon/cvmx-interrupt-decodes.c - create mode 100644 drivers/staging/octeon/cvmx-interrupt-rsl.c - create mode 100644 drivers/staging/octeon/cvmx-ipd.h - create mode 100644 drivers/staging/octeon/cvmx-mdio.h - create mode 100644 drivers/staging/octeon/cvmx-packet.h - create mode 100644 drivers/staging/octeon/cvmx-pcsx-defs.h - create mode 100644 drivers/staging/octeon/cvmx-pcsxx-defs.h - create mode 100644 drivers/staging/octeon/cvmx-pip-defs.h - create mode 100644 drivers/staging/octeon/cvmx-pip.h - create mode 100644 drivers/staging/octeon/cvmx-pko-defs.h - create mode 100644 drivers/staging/octeon/cvmx-pko.c - create mode 100644 drivers/staging/octeon/cvmx-pko.h - create mode 100644 drivers/staging/octeon/cvmx-pow.h - create mode 100644 drivers/staging/octeon/cvmx-scratch.h - create mode 100644 drivers/staging/octeon/cvmx-smix-defs.h - create mode 100644 drivers/staging/octeon/cvmx-spi.c - create mode 100644 drivers/staging/octeon/cvmx-spi.h - create mode 100644 drivers/staging/octeon/cvmx-spxx-defs.h - create mode 100644 drivers/staging/octeon/cvmx-srxx-defs.h - create mode 100644 drivers/staging/octeon/cvmx-stxx-defs.h - create mode 100644 drivers/staging/octeon/cvmx-wqe.h - create mode 100644 drivers/staging/octeon/ethernet-common.c - create mode 100644 drivers/staging/octeon/ethernet-common.h - create mode 100644 drivers/staging/octeon/ethernet-defines.h - create mode 100644 drivers/staging/octeon/ethernet-mdio.c - create mode 100644 drivers/staging/octeon/ethernet-mdio.h - create mode 100644 drivers/staging/octeon/ethernet-mem.c - create mode 100644 drivers/staging/octeon/ethernet-mem.h - create mode 100644 drivers/staging/octeon/ethernet-proc.c - create mode 100644 drivers/staging/octeon/ethernet-proc.h - create mode 100644 drivers/staging/octeon/ethernet-rgmii.c - create mode 100644 drivers/staging/octeon/ethernet-rx.c - create mode 100644 drivers/staging/octeon/ethernet-rx.h - create mode 100644 drivers/staging/octeon/ethernet-sgmii.c - create mode 100644 drivers/staging/octeon/ethernet-spi.c - create mode 100644 drivers/staging/octeon/ethernet-tx.c - create mode 100644 drivers/staging/octeon/ethernet-tx.h - create mode 100644 drivers/staging/octeon/ethernet-util.h - create mode 100644 drivers/staging/octeon/ethernet-xaui.c - create mode 100644 drivers/staging/octeon/ethernet.c - create mode 100644 drivers/staging/octeon/octeon-ethernet.h - ---- /dev/null -+++ b/drivers/staging/octeon/Kconfig -@@ -0,0 +1,12 @@ -+config OCTEON_ETHERNET -+ tristate "Cavium Networks Octeon Ethernet support" -+ depends on CPU_CAVIUM_OCTEON -+ select MII -+ help -+ This driver supports the builtin ethernet ports on Cavium -+ Networks' products in the Octeon family. This driver supports the -+ CN3XXX and CN5XXX Octeon processors. -+ -+ To compile this driver as a module, choose M here. The module -+ will be called octeon-ethernet. -+ ---- /dev/null -+++ b/drivers/staging/octeon/Makefile -@@ -0,0 +1,30 @@ -+# This file is subject to the terms and conditions of the GNU General Public -+# License. See the file "COPYING" in the main directory of this archive -+# for more details. -+# -+# Copyright (C) 2005-2009 Cavium Networks -+# -+ -+# -+# Makefile for Cavium OCTEON on-board ethernet driver -+# -+ -+obj-${CONFIG_OCTEON_ETHERNET} := octeon-ethernet.o -+ -+octeon-ethernet-objs := ethernet.o -+octeon-ethernet-objs += ethernet-common.o -+octeon-ethernet-objs += ethernet-mdio.o -+octeon-ethernet-objs += ethernet-mem.o -+octeon-ethernet-objs += ethernet-proc.o -+octeon-ethernet-objs += ethernet-rgmii.o -+octeon-ethernet-objs += ethernet-rx.o -+octeon-ethernet-objs += ethernet-sgmii.o -+octeon-ethernet-objs += ethernet-spi.o -+octeon-ethernet-objs += ethernet-tx.o -+octeon-ethernet-objs += ethernet-xaui.o -+octeon-ethernet-objs += cvmx-pko.o cvmx-spi.o cvmx-cmd-queue.o \ -+ cvmx-helper-board.o cvmx-helper.o cvmx-helper-xaui.o \ -+ cvmx-helper-rgmii.o cvmx-helper-sgmii.o cvmx-helper-npi.o \ -+ cvmx-helper-loop.o cvmx-helper-spi.o cvmx-helper-util.o \ -+ cvmx-interrupt-decodes.o cvmx-interrupt-rsl.o -+ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-address.h -@@ -0,0 +1,274 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2009 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * Typedefs and defines for working with Octeon physical addresses. -+ * -+ */ -+#ifndef __CVMX_ADDRESS_H__ -+#define __CVMX_ADDRESS_H__ -+ -+#if 0 -+typedef enum { -+ CVMX_MIPS_SPACE_XKSEG = 3LL, -+ CVMX_MIPS_SPACE_XKPHYS = 2LL, -+ CVMX_MIPS_SPACE_XSSEG = 1LL, -+ CVMX_MIPS_SPACE_XUSEG = 0LL -+} cvmx_mips_space_t; -+#endif -+ -+typedef enum { -+ CVMX_MIPS_XKSEG_SPACE_KSEG0 = 0LL, -+ CVMX_MIPS_XKSEG_SPACE_KSEG1 = 1LL, -+ CVMX_MIPS_XKSEG_SPACE_SSEG = 2LL, -+ CVMX_MIPS_XKSEG_SPACE_KSEG3 = 3LL -+} cvmx_mips_xkseg_space_t; -+ -+/* decodes <14:13> of a kseg3 window address */ -+typedef enum { -+ CVMX_ADD_WIN_SCR = 0L, -+ /* see cvmx_add_win_dma_dec_t for further decode */ -+ CVMX_ADD_WIN_DMA = 1L, -+ CVMX_ADD_WIN_UNUSED = 2L, -+ CVMX_ADD_WIN_UNUSED2 = 3L -+} cvmx_add_win_dec_t; -+ -+/* decode within DMA space */ -+typedef enum { -+ /* -+ * Add store data to the write buffer entry, allocating it if -+ * necessary. -+ */ -+ CVMX_ADD_WIN_DMA_ADD = 0L, -+ /* send out the write buffer entry to DRAM */ -+ CVMX_ADD_WIN_DMA_SENDMEM = 1L, -+ /* store data must be normal DRAM memory space address in this case */ -+ /* send out the write buffer entry as an IOBDMA command */ -+ CVMX_ADD_WIN_DMA_SENDDMA = 2L, -+ /* see CVMX_ADD_WIN_DMA_SEND_DEC for data contents */ -+ /* send out the write buffer entry as an IO write */ -+ CVMX_ADD_WIN_DMA_SENDIO = 3L, -+ /* store data must be normal IO space address in this case */ -+ /* send out a single-tick command on the NCB bus */ -+ CVMX_ADD_WIN_DMA_SENDSINGLE = 4L, -+ /* no write buffer data needed/used */ -+} cvmx_add_win_dma_dec_t; -+ -+/* -+ * Physical Address Decode -+ * -+ * Octeon-I HW never interprets this X (<39:36> reserved -+ * for future expansion), software should set to 0. -+ * -+ * - 0x0 XXX0 0000 0000 to DRAM Cached -+ * - 0x0 XXX0 0FFF FFFF -+ * -+ * - 0x0 XXX0 1000 0000 to Boot Bus Uncached (Converted to 0x1 00X0 1000 0000 -+ * - 0x0 XXX0 1FFF FFFF + EJTAG to 0x1 00X0 1FFF FFFF) -+ * -+ * - 0x0 XXX0 2000 0000 to DRAM Cached -+ * - 0x0 XXXF FFFF FFFF -+ * -+ * - 0x1 00X0 0000 0000 to Boot Bus Uncached -+ * - 0x1 00XF FFFF FFFF -+ * -+ * - 0x1 01X0 0000 0000 to Other NCB Uncached -+ * - 0x1 FFXF FFFF FFFF devices -+ * -+ * Decode of all Octeon addresses -+ */ -+typedef union { -+ -+ uint64_t u64; -+ /* mapped or unmapped virtual address */ -+ struct { -+ uint64_t R:2; -+ uint64_t offset:62; -+ } sva; -+ -+ /* mapped USEG virtual addresses (typically) */ -+ struct { -+ uint64_t zeroes:33; -+ uint64_t offset:31; -+ } suseg; -+ -+ /* mapped or unmapped virtual address */ -+ struct { -+ uint64_t ones:33; -+ uint64_t sp:2; -+ uint64_t offset:29; -+ } sxkseg; -+ -+ /* -+ * physical address accessed through xkphys unmapped virtual -+ * address. -+ */ -+ struct { -+ uint64_t R:2; /* CVMX_MIPS_SPACE_XKPHYS in this case */ -+ uint64_t cca:3; /* ignored by octeon */ -+ uint64_t mbz:10; -+ uint64_t pa:49; /* physical address */ -+ } sxkphys; -+ -+ /* physical address */ -+ struct { -+ uint64_t mbz:15; -+ /* if set, the address is uncached and resides on MCB bus */ -+ uint64_t is_io:1; -+ /* -+ * the hardware ignores this field when is_io==0, else -+ * device ID. -+ */ -+ uint64_t did:8; -+ /* the hardware ignores <39:36> in Octeon I */ -+ uint64_t unaddr:4; -+ uint64_t offset:36; -+ } sphys; -+ -+ /* physical mem address */ -+ struct { -+ /* techically, <47:40> are dont-cares */ -+ uint64_t zeroes:24; -+ /* the hardware ignores <39:36> in Octeon I */ -+ uint64_t unaddr:4; -+ uint64_t offset:36; -+ } smem; -+ -+ /* physical IO address */ -+ struct { -+ uint64_t mem_region:2; -+ uint64_t mbz:13; -+ /* 1 in this case */ -+ uint64_t is_io:1; -+ /* -+ * The hardware ignores this field when is_io==0, else -+ * device ID. -+ */ -+ uint64_t did:8; -+ /* the hardware ignores <39:36> in Octeon I */ -+ uint64_t unaddr:4; -+ uint64_t offset:36; -+ } sio; -+ -+ /* -+ * Scratchpad virtual address - accessed through a window at -+ * the end of kseg3 -+ */ -+ struct { -+ uint64_t ones:49; -+ /* CVMX_ADD_WIN_SCR (0) in this case */ -+ cvmx_add_win_dec_t csrdec:2; -+ uint64_t addr:13; -+ } sscr; -+ -+ /* there should only be stores to IOBDMA space, no loads */ -+ /* -+ * IOBDMA virtual address - accessed through a window at the -+ * end of kseg3 -+ */ -+ struct { -+ uint64_t ones:49; -+ uint64_t csrdec:2; /* CVMX_ADD_WIN_DMA (1) in this case */ -+ uint64_t unused2:3; -+ uint64_t type:3; -+ uint64_t addr:7; -+ } sdma; -+ -+ struct { -+ uint64_t didspace:24; -+ uint64_t unused:40; -+ } sfilldidspace; -+ -+} cvmx_addr_t; -+ -+/* These macros for used by 32 bit applications */ -+ -+#define CVMX_MIPS32_SPACE_KSEG0 1l -+#define CVMX_ADD_SEG32(segment, add) \ -+ (((int32_t)segment << 31) | (int32_t)(add)) -+ -+/* -+ * Currently all IOs are performed using XKPHYS addressing. Linux uses -+ * the CvmMemCtl register to enable XKPHYS addressing to IO space from -+ * user mode. Future OSes may need to change the upper bits of IO -+ * addresses. The following define controls the upper two bits for all -+ * IO addresses generated by the simple executive library. -+ */ -+#define CVMX_IO_SEG CVMX_MIPS_SPACE_XKPHYS -+ -+/* These macros simplify the process of creating common IO addresses */ -+#define CVMX_ADD_SEG(segment, add) ((((uint64_t)segment) << 62) | (add)) -+#ifndef CVMX_ADD_IO_SEG -+#define CVMX_ADD_IO_SEG(add) CVMX_ADD_SEG(CVMX_IO_SEG, (add)) -+#endif -+#define CVMX_ADDR_DIDSPACE(did) (((CVMX_IO_SEG) << 22) | ((1ULL) << 8) | (did)) -+#define CVMX_ADDR_DID(did) (CVMX_ADDR_DIDSPACE(did) << 40) -+#define CVMX_FULL_DID(did, subdid) (((did) << 3) | (subdid)) -+ -+ /* from include/ncb_rsl_id.v */ -+#define CVMX_OCT_DID_MIS 0ULL /* misc stuff */ -+#define CVMX_OCT_DID_GMX0 1ULL -+#define CVMX_OCT_DID_GMX1 2ULL -+#define CVMX_OCT_DID_PCI 3ULL -+#define CVMX_OCT_DID_KEY 4ULL -+#define CVMX_OCT_DID_FPA 5ULL -+#define CVMX_OCT_DID_DFA 6ULL -+#define CVMX_OCT_DID_ZIP 7ULL -+#define CVMX_OCT_DID_RNG 8ULL -+#define CVMX_OCT_DID_IPD 9ULL -+#define CVMX_OCT_DID_PKT 10ULL -+#define CVMX_OCT_DID_TIM 11ULL -+#define CVMX_OCT_DID_TAG 12ULL -+ /* the rest are not on the IO bus */ -+#define CVMX_OCT_DID_L2C 16ULL -+#define CVMX_OCT_DID_LMC 17ULL -+#define CVMX_OCT_DID_SPX0 18ULL -+#define CVMX_OCT_DID_SPX1 19ULL -+#define CVMX_OCT_DID_PIP 20ULL -+#define CVMX_OCT_DID_ASX0 22ULL -+#define CVMX_OCT_DID_ASX1 23ULL -+#define CVMX_OCT_DID_IOB 30ULL -+ -+#define CVMX_OCT_DID_PKT_SEND CVMX_FULL_DID(CVMX_OCT_DID_PKT, 2ULL) -+#define CVMX_OCT_DID_TAG_SWTAG CVMX_FULL_DID(CVMX_OCT_DID_TAG, 0ULL) -+#define CVMX_OCT_DID_TAG_TAG1 CVMX_FULL_DID(CVMX_OCT_DID_TAG, 1ULL) -+#define CVMX_OCT_DID_TAG_TAG2 CVMX_FULL_DID(CVMX_OCT_DID_TAG, 2ULL) -+#define CVMX_OCT_DID_TAG_TAG3 CVMX_FULL_DID(CVMX_OCT_DID_TAG, 3ULL) -+#define CVMX_OCT_DID_TAG_NULL_RD CVMX_FULL_DID(CVMX_OCT_DID_TAG, 4ULL) -+#define CVMX_OCT_DID_TAG_CSR CVMX_FULL_DID(CVMX_OCT_DID_TAG, 7ULL) -+#define CVMX_OCT_DID_FAU_FAI CVMX_FULL_DID(CVMX_OCT_DID_IOB, 0ULL) -+#define CVMX_OCT_DID_TIM_CSR CVMX_FULL_DID(CVMX_OCT_DID_TIM, 0ULL) -+#define CVMX_OCT_DID_KEY_RW CVMX_FULL_DID(CVMX_OCT_DID_KEY, 0ULL) -+#define CVMX_OCT_DID_PCI_6 CVMX_FULL_DID(CVMX_OCT_DID_PCI, 6ULL) -+#define CVMX_OCT_DID_MIS_BOO CVMX_FULL_DID(CVMX_OCT_DID_MIS, 0ULL) -+#define CVMX_OCT_DID_PCI_RML CVMX_FULL_DID(CVMX_OCT_DID_PCI, 0ULL) -+#define CVMX_OCT_DID_IPD_CSR CVMX_FULL_DID(CVMX_OCT_DID_IPD, 7ULL) -+#define CVMX_OCT_DID_DFA_CSR CVMX_FULL_DID(CVMX_OCT_DID_DFA, 7ULL) -+#define CVMX_OCT_DID_MIS_CSR CVMX_FULL_DID(CVMX_OCT_DID_MIS, 7ULL) -+#define CVMX_OCT_DID_ZIP_CSR CVMX_FULL_DID(CVMX_OCT_DID_ZIP, 0ULL) -+ -+#endif /* __CVMX_ADDRESS_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-asxx-defs.h -@@ -0,0 +1,475 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_ASXX_DEFS_H__ -+#define __CVMX_ASXX_DEFS_H__ -+ -+#define CVMX_ASXX_GMII_RX_CLK_SET(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000180ull + (((block_id) & 0) * 0x8000000ull)) -+#define CVMX_ASXX_GMII_RX_DAT_SET(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000188ull + (((block_id) & 0) * 0x8000000ull)) -+#define CVMX_ASXX_INT_EN(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000018ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_INT_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000010ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_MII_RX_DAT_SET(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000190ull + (((block_id) & 0) * 0x8000000ull)) -+#define CVMX_ASXX_PRT_LOOP(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000040ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RLD_BYPASS(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000248ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RLD_BYPASS_SETTING(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000250ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RLD_COMP(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000220ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RLD_DATA_DRV(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000218ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RLD_FCRAM_MODE(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000210ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RLD_NCTL_STRONG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000230ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RLD_NCTL_WEAK(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000240ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RLD_PCTL_STRONG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000228ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RLD_PCTL_WEAK(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000238ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RLD_SETTING(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000258ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RX_CLK_SETX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000020ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RX_PRT_EN(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000000ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RX_WOL(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000100ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RX_WOL_MSK(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000108ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RX_WOL_POWOK(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000118ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_RX_WOL_SIG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000110ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_TX_CLK_SETX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000048ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_TX_COMP_BYP(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000068ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_TX_HI_WATERX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000080ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_ASXX_TX_PRT_EN(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000008ull + (((block_id) & 1) * 0x8000000ull)) -+ -+union cvmx_asxx_gmii_rx_clk_set { -+ uint64_t u64; -+ struct cvmx_asxx_gmii_rx_clk_set_s { -+ uint64_t reserved_5_63:59; -+ uint64_t setting:5; -+ } s; -+ struct cvmx_asxx_gmii_rx_clk_set_s cn30xx; -+ struct cvmx_asxx_gmii_rx_clk_set_s cn31xx; -+ struct cvmx_asxx_gmii_rx_clk_set_s cn50xx; -+}; -+ -+union cvmx_asxx_gmii_rx_dat_set { -+ uint64_t u64; -+ struct cvmx_asxx_gmii_rx_dat_set_s { -+ uint64_t reserved_5_63:59; -+ uint64_t setting:5; -+ } s; -+ struct cvmx_asxx_gmii_rx_dat_set_s cn30xx; -+ struct cvmx_asxx_gmii_rx_dat_set_s cn31xx; -+ struct cvmx_asxx_gmii_rx_dat_set_s cn50xx; -+}; -+ -+union cvmx_asxx_int_en { -+ uint64_t u64; -+ struct cvmx_asxx_int_en_s { -+ uint64_t reserved_12_63:52; -+ uint64_t txpsh:4; -+ uint64_t txpop:4; -+ uint64_t ovrflw:4; -+ } s; -+ struct cvmx_asxx_int_en_cn30xx { -+ uint64_t reserved_11_63:53; -+ uint64_t txpsh:3; -+ uint64_t reserved_7_7:1; -+ uint64_t txpop:3; -+ uint64_t reserved_3_3:1; -+ uint64_t ovrflw:3; -+ } cn30xx; -+ struct cvmx_asxx_int_en_cn30xx cn31xx; -+ struct cvmx_asxx_int_en_s cn38xx; -+ struct cvmx_asxx_int_en_s cn38xxp2; -+ struct cvmx_asxx_int_en_cn30xx cn50xx; -+ struct cvmx_asxx_int_en_s cn58xx; -+ struct cvmx_asxx_int_en_s cn58xxp1; -+}; -+ -+union cvmx_asxx_int_reg { -+ uint64_t u64; -+ struct cvmx_asxx_int_reg_s { -+ uint64_t reserved_12_63:52; -+ uint64_t txpsh:4; -+ uint64_t txpop:4; -+ uint64_t ovrflw:4; -+ } s; -+ struct cvmx_asxx_int_reg_cn30xx { -+ uint64_t reserved_11_63:53; -+ uint64_t txpsh:3; -+ uint64_t reserved_7_7:1; -+ uint64_t txpop:3; -+ uint64_t reserved_3_3:1; -+ uint64_t ovrflw:3; -+ } cn30xx; -+ struct cvmx_asxx_int_reg_cn30xx cn31xx; -+ struct cvmx_asxx_int_reg_s cn38xx; -+ struct cvmx_asxx_int_reg_s cn38xxp2; -+ struct cvmx_asxx_int_reg_cn30xx cn50xx; -+ struct cvmx_asxx_int_reg_s cn58xx; -+ struct cvmx_asxx_int_reg_s cn58xxp1; -+}; -+ -+union cvmx_asxx_mii_rx_dat_set { -+ uint64_t u64; -+ struct cvmx_asxx_mii_rx_dat_set_s { -+ uint64_t reserved_5_63:59; -+ uint64_t setting:5; -+ } s; -+ struct cvmx_asxx_mii_rx_dat_set_s cn30xx; -+ struct cvmx_asxx_mii_rx_dat_set_s cn50xx; -+}; -+ -+union cvmx_asxx_prt_loop { -+ uint64_t u64; -+ struct cvmx_asxx_prt_loop_s { -+ uint64_t reserved_8_63:56; -+ uint64_t ext_loop:4; -+ uint64_t int_loop:4; -+ } s; -+ struct cvmx_asxx_prt_loop_cn30xx { -+ uint64_t reserved_7_63:57; -+ uint64_t ext_loop:3; -+ uint64_t reserved_3_3:1; -+ uint64_t int_loop:3; -+ } cn30xx; -+ struct cvmx_asxx_prt_loop_cn30xx cn31xx; -+ struct cvmx_asxx_prt_loop_s cn38xx; -+ struct cvmx_asxx_prt_loop_s cn38xxp2; -+ struct cvmx_asxx_prt_loop_cn30xx cn50xx; -+ struct cvmx_asxx_prt_loop_s cn58xx; -+ struct cvmx_asxx_prt_loop_s cn58xxp1; -+}; -+ -+union cvmx_asxx_rld_bypass { -+ uint64_t u64; -+ struct cvmx_asxx_rld_bypass_s { -+ uint64_t reserved_1_63:63; -+ uint64_t bypass:1; -+ } s; -+ struct cvmx_asxx_rld_bypass_s cn38xx; -+ struct cvmx_asxx_rld_bypass_s cn38xxp2; -+ struct cvmx_asxx_rld_bypass_s cn58xx; -+ struct cvmx_asxx_rld_bypass_s cn58xxp1; -+}; -+ -+union cvmx_asxx_rld_bypass_setting { -+ uint64_t u64; -+ struct cvmx_asxx_rld_bypass_setting_s { -+ uint64_t reserved_5_63:59; -+ uint64_t setting:5; -+ } s; -+ struct cvmx_asxx_rld_bypass_setting_s cn38xx; -+ struct cvmx_asxx_rld_bypass_setting_s cn38xxp2; -+ struct cvmx_asxx_rld_bypass_setting_s cn58xx; -+ struct cvmx_asxx_rld_bypass_setting_s cn58xxp1; -+}; -+ -+union cvmx_asxx_rld_comp { -+ uint64_t u64; -+ struct cvmx_asxx_rld_comp_s { -+ uint64_t reserved_9_63:55; -+ uint64_t pctl:5; -+ uint64_t nctl:4; -+ } s; -+ struct cvmx_asxx_rld_comp_cn38xx { -+ uint64_t reserved_8_63:56; -+ uint64_t pctl:4; -+ uint64_t nctl:4; -+ } cn38xx; -+ struct cvmx_asxx_rld_comp_cn38xx cn38xxp2; -+ struct cvmx_asxx_rld_comp_s cn58xx; -+ struct cvmx_asxx_rld_comp_s cn58xxp1; -+}; -+ -+union cvmx_asxx_rld_data_drv { -+ uint64_t u64; -+ struct cvmx_asxx_rld_data_drv_s { -+ uint64_t reserved_8_63:56; -+ uint64_t pctl:4; -+ uint64_t nctl:4; -+ } s; -+ struct cvmx_asxx_rld_data_drv_s cn38xx; -+ struct cvmx_asxx_rld_data_drv_s cn38xxp2; -+ struct cvmx_asxx_rld_data_drv_s cn58xx; -+ struct cvmx_asxx_rld_data_drv_s cn58xxp1; -+}; -+ -+union cvmx_asxx_rld_fcram_mode { -+ uint64_t u64; -+ struct cvmx_asxx_rld_fcram_mode_s { -+ uint64_t reserved_1_63:63; -+ uint64_t mode:1; -+ } s; -+ struct cvmx_asxx_rld_fcram_mode_s cn38xx; -+ struct cvmx_asxx_rld_fcram_mode_s cn38xxp2; -+}; -+ -+union cvmx_asxx_rld_nctl_strong { -+ uint64_t u64; -+ struct cvmx_asxx_rld_nctl_strong_s { -+ uint64_t reserved_5_63:59; -+ uint64_t nctl:5; -+ } s; -+ struct cvmx_asxx_rld_nctl_strong_s cn38xx; -+ struct cvmx_asxx_rld_nctl_strong_s cn38xxp2; -+ struct cvmx_asxx_rld_nctl_strong_s cn58xx; -+ struct cvmx_asxx_rld_nctl_strong_s cn58xxp1; -+}; -+ -+union cvmx_asxx_rld_nctl_weak { -+ uint64_t u64; -+ struct cvmx_asxx_rld_nctl_weak_s { -+ uint64_t reserved_5_63:59; -+ uint64_t nctl:5; -+ } s; -+ struct cvmx_asxx_rld_nctl_weak_s cn38xx; -+ struct cvmx_asxx_rld_nctl_weak_s cn38xxp2; -+ struct cvmx_asxx_rld_nctl_weak_s cn58xx; -+ struct cvmx_asxx_rld_nctl_weak_s cn58xxp1; -+}; -+ -+union cvmx_asxx_rld_pctl_strong { -+ uint64_t u64; -+ struct cvmx_asxx_rld_pctl_strong_s { -+ uint64_t reserved_5_63:59; -+ uint64_t pctl:5; -+ } s; -+ struct cvmx_asxx_rld_pctl_strong_s cn38xx; -+ struct cvmx_asxx_rld_pctl_strong_s cn38xxp2; -+ struct cvmx_asxx_rld_pctl_strong_s cn58xx; -+ struct cvmx_asxx_rld_pctl_strong_s cn58xxp1; -+}; -+ -+union cvmx_asxx_rld_pctl_weak { -+ uint64_t u64; -+ struct cvmx_asxx_rld_pctl_weak_s { -+ uint64_t reserved_5_63:59; -+ uint64_t pctl:5; -+ } s; -+ struct cvmx_asxx_rld_pctl_weak_s cn38xx; -+ struct cvmx_asxx_rld_pctl_weak_s cn38xxp2; -+ struct cvmx_asxx_rld_pctl_weak_s cn58xx; -+ struct cvmx_asxx_rld_pctl_weak_s cn58xxp1; -+}; -+ -+union cvmx_asxx_rld_setting { -+ uint64_t u64; -+ struct cvmx_asxx_rld_setting_s { -+ uint64_t reserved_13_63:51; -+ uint64_t dfaset:5; -+ uint64_t dfalag:1; -+ uint64_t dfalead:1; -+ uint64_t dfalock:1; -+ uint64_t setting:5; -+ } s; -+ struct cvmx_asxx_rld_setting_cn38xx { -+ uint64_t reserved_5_63:59; -+ uint64_t setting:5; -+ } cn38xx; -+ struct cvmx_asxx_rld_setting_cn38xx cn38xxp2; -+ struct cvmx_asxx_rld_setting_s cn58xx; -+ struct cvmx_asxx_rld_setting_s cn58xxp1; -+}; -+ -+union cvmx_asxx_rx_clk_setx { -+ uint64_t u64; -+ struct cvmx_asxx_rx_clk_setx_s { -+ uint64_t reserved_5_63:59; -+ uint64_t setting:5; -+ } s; -+ struct cvmx_asxx_rx_clk_setx_s cn30xx; -+ struct cvmx_asxx_rx_clk_setx_s cn31xx; -+ struct cvmx_asxx_rx_clk_setx_s cn38xx; -+ struct cvmx_asxx_rx_clk_setx_s cn38xxp2; -+ struct cvmx_asxx_rx_clk_setx_s cn50xx; -+ struct cvmx_asxx_rx_clk_setx_s cn58xx; -+ struct cvmx_asxx_rx_clk_setx_s cn58xxp1; -+}; -+ -+union cvmx_asxx_rx_prt_en { -+ uint64_t u64; -+ struct cvmx_asxx_rx_prt_en_s { -+ uint64_t reserved_4_63:60; -+ uint64_t prt_en:4; -+ } s; -+ struct cvmx_asxx_rx_prt_en_cn30xx { -+ uint64_t reserved_3_63:61; -+ uint64_t prt_en:3; -+ } cn30xx; -+ struct cvmx_asxx_rx_prt_en_cn30xx cn31xx; -+ struct cvmx_asxx_rx_prt_en_s cn38xx; -+ struct cvmx_asxx_rx_prt_en_s cn38xxp2; -+ struct cvmx_asxx_rx_prt_en_cn30xx cn50xx; -+ struct cvmx_asxx_rx_prt_en_s cn58xx; -+ struct cvmx_asxx_rx_prt_en_s cn58xxp1; -+}; -+ -+union cvmx_asxx_rx_wol { -+ uint64_t u64; -+ struct cvmx_asxx_rx_wol_s { -+ uint64_t reserved_2_63:62; -+ uint64_t status:1; -+ uint64_t enable:1; -+ } s; -+ struct cvmx_asxx_rx_wol_s cn38xx; -+ struct cvmx_asxx_rx_wol_s cn38xxp2; -+}; -+ -+union cvmx_asxx_rx_wol_msk { -+ uint64_t u64; -+ struct cvmx_asxx_rx_wol_msk_s { -+ uint64_t msk:64; -+ } s; -+ struct cvmx_asxx_rx_wol_msk_s cn38xx; -+ struct cvmx_asxx_rx_wol_msk_s cn38xxp2; -+}; -+ -+union cvmx_asxx_rx_wol_powok { -+ uint64_t u64; -+ struct cvmx_asxx_rx_wol_powok_s { -+ uint64_t reserved_1_63:63; -+ uint64_t powerok:1; -+ } s; -+ struct cvmx_asxx_rx_wol_powok_s cn38xx; -+ struct cvmx_asxx_rx_wol_powok_s cn38xxp2; -+}; -+ -+union cvmx_asxx_rx_wol_sig { -+ uint64_t u64; -+ struct cvmx_asxx_rx_wol_sig_s { -+ uint64_t reserved_32_63:32; -+ uint64_t sig:32; -+ } s; -+ struct cvmx_asxx_rx_wol_sig_s cn38xx; -+ struct cvmx_asxx_rx_wol_sig_s cn38xxp2; -+}; -+ -+union cvmx_asxx_tx_clk_setx { -+ uint64_t u64; -+ struct cvmx_asxx_tx_clk_setx_s { -+ uint64_t reserved_5_63:59; -+ uint64_t setting:5; -+ } s; -+ struct cvmx_asxx_tx_clk_setx_s cn30xx; -+ struct cvmx_asxx_tx_clk_setx_s cn31xx; -+ struct cvmx_asxx_tx_clk_setx_s cn38xx; -+ struct cvmx_asxx_tx_clk_setx_s cn38xxp2; -+ struct cvmx_asxx_tx_clk_setx_s cn50xx; -+ struct cvmx_asxx_tx_clk_setx_s cn58xx; -+ struct cvmx_asxx_tx_clk_setx_s cn58xxp1; -+}; -+ -+union cvmx_asxx_tx_comp_byp { -+ uint64_t u64; -+ struct cvmx_asxx_tx_comp_byp_s { -+ uint64_t reserved_0_63:64; -+ } s; -+ struct cvmx_asxx_tx_comp_byp_cn30xx { -+ uint64_t reserved_9_63:55; -+ uint64_t bypass:1; -+ uint64_t pctl:4; -+ uint64_t nctl:4; -+ } cn30xx; -+ struct cvmx_asxx_tx_comp_byp_cn30xx cn31xx; -+ struct cvmx_asxx_tx_comp_byp_cn38xx { -+ uint64_t reserved_8_63:56; -+ uint64_t pctl:4; -+ uint64_t nctl:4; -+ } cn38xx; -+ struct cvmx_asxx_tx_comp_byp_cn38xx cn38xxp2; -+ struct cvmx_asxx_tx_comp_byp_cn50xx { -+ uint64_t reserved_17_63:47; -+ uint64_t bypass:1; -+ uint64_t reserved_13_15:3; -+ uint64_t pctl:5; -+ uint64_t reserved_5_7:3; -+ uint64_t nctl:5; -+ } cn50xx; -+ struct cvmx_asxx_tx_comp_byp_cn58xx { -+ uint64_t reserved_13_63:51; -+ uint64_t pctl:5; -+ uint64_t reserved_5_7:3; -+ uint64_t nctl:5; -+ } cn58xx; -+ struct cvmx_asxx_tx_comp_byp_cn58xx cn58xxp1; -+}; -+ -+union cvmx_asxx_tx_hi_waterx { -+ uint64_t u64; -+ struct cvmx_asxx_tx_hi_waterx_s { -+ uint64_t reserved_4_63:60; -+ uint64_t mark:4; -+ } s; -+ struct cvmx_asxx_tx_hi_waterx_cn30xx { -+ uint64_t reserved_3_63:61; -+ uint64_t mark:3; -+ } cn30xx; -+ struct cvmx_asxx_tx_hi_waterx_cn30xx cn31xx; -+ struct cvmx_asxx_tx_hi_waterx_s cn38xx; -+ struct cvmx_asxx_tx_hi_waterx_s cn38xxp2; -+ struct cvmx_asxx_tx_hi_waterx_cn30xx cn50xx; -+ struct cvmx_asxx_tx_hi_waterx_s cn58xx; -+ struct cvmx_asxx_tx_hi_waterx_s cn58xxp1; -+}; -+ -+union cvmx_asxx_tx_prt_en { -+ uint64_t u64; -+ struct cvmx_asxx_tx_prt_en_s { -+ uint64_t reserved_4_63:60; -+ uint64_t prt_en:4; -+ } s; -+ struct cvmx_asxx_tx_prt_en_cn30xx { -+ uint64_t reserved_3_63:61; -+ uint64_t prt_en:3; -+ } cn30xx; -+ struct cvmx_asxx_tx_prt_en_cn30xx cn31xx; -+ struct cvmx_asxx_tx_prt_en_s cn38xx; -+ struct cvmx_asxx_tx_prt_en_s cn38xxp2; -+ struct cvmx_asxx_tx_prt_en_cn30xx cn50xx; -+ struct cvmx_asxx_tx_prt_en_s cn58xx; -+ struct cvmx_asxx_tx_prt_en_s cn58xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-cmd-queue.c -@@ -0,0 +1,306 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * Support functions for managing command queues used for -+ * various hardware blocks. -+ */ -+ -+#include <linux/kernel.h> -+ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-config.h" -+#include "cvmx-fpa.h" -+#include "cvmx-cmd-queue.h" -+ -+#include <asm/octeon/cvmx-npei-defs.h> -+#include <asm/octeon/cvmx-pexp-defs.h> -+#include "cvmx-pko-defs.h" -+ -+/** -+ * This application uses this pointer to access the global queue -+ * state. It points to a bootmem named block. -+ */ -+__cvmx_cmd_queue_all_state_t *__cvmx_cmd_queue_state_ptr; -+ -+/** -+ * Initialize the Global queue state pointer. -+ * -+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code -+ */ -+static cvmx_cmd_queue_result_t __cvmx_cmd_queue_init_state_ptr(void) -+{ -+ char *alloc_name = "cvmx_cmd_queues"; -+#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32 -+ extern uint64_t octeon_reserve32_memory; -+#endif -+ -+ if (likely(__cvmx_cmd_queue_state_ptr)) -+ return CVMX_CMD_QUEUE_SUCCESS; -+ -+#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32 -+ if (octeon_reserve32_memory) -+ __cvmx_cmd_queue_state_ptr = -+ cvmx_bootmem_alloc_named_range(sizeof(*__cvmx_cmd_queue_state_ptr), -+ octeon_reserve32_memory, -+ octeon_reserve32_memory + -+ (CONFIG_CAVIUM_RESERVE32 << -+ 20) - 1, 128, alloc_name); -+ else -+#endif -+ __cvmx_cmd_queue_state_ptr = -+ cvmx_bootmem_alloc_named(sizeof(*__cvmx_cmd_queue_state_ptr), -+ 128, -+ alloc_name); -+ if (__cvmx_cmd_queue_state_ptr) -+ memset(__cvmx_cmd_queue_state_ptr, 0, -+ sizeof(*__cvmx_cmd_queue_state_ptr)); -+ else { -+ struct cvmx_bootmem_named_block_desc *block_desc = -+ cvmx_bootmem_find_named_block(alloc_name); -+ if (block_desc) -+ __cvmx_cmd_queue_state_ptr = -+ cvmx_phys_to_ptr(block_desc->base_addr); -+ else { -+ cvmx_dprintf -+ ("ERROR: cvmx_cmd_queue_initialize: Unable to get named block %s.\n", -+ alloc_name); -+ return CVMX_CMD_QUEUE_NO_MEMORY; -+ } -+ } -+ return CVMX_CMD_QUEUE_SUCCESS; -+} -+ -+/** -+ * Initialize a command queue for use. The initial FPA buffer is -+ * allocated and the hardware unit is configured to point to the -+ * new command queue. -+ * -+ * @queue_id: Hardware command queue to initialize. -+ * @max_depth: Maximum outstanding commands that can be queued. -+ * @fpa_pool: FPA pool the command queues should come from. -+ * @pool_size: Size of each buffer in the FPA pool (bytes) -+ * -+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code -+ */ -+cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id, -+ int max_depth, int fpa_pool, -+ int pool_size) -+{ -+ __cvmx_cmd_queue_state_t *qstate; -+ cvmx_cmd_queue_result_t result = __cvmx_cmd_queue_init_state_ptr(); -+ if (result != CVMX_CMD_QUEUE_SUCCESS) -+ return result; -+ -+ qstate = __cvmx_cmd_queue_get_state(queue_id); -+ if (qstate == NULL) -+ return CVMX_CMD_QUEUE_INVALID_PARAM; -+ -+ /* -+ * We artificially limit max_depth to 1<<20 words. It is an -+ * arbitrary limit. -+ */ -+ if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH) { -+ if ((max_depth < 0) || (max_depth > 1 << 20)) -+ return CVMX_CMD_QUEUE_INVALID_PARAM; -+ } else if (max_depth != 0) -+ return CVMX_CMD_QUEUE_INVALID_PARAM; -+ -+ if ((fpa_pool < 0) || (fpa_pool > 7)) -+ return CVMX_CMD_QUEUE_INVALID_PARAM; -+ if ((pool_size < 128) || (pool_size > 65536)) -+ return CVMX_CMD_QUEUE_INVALID_PARAM; -+ -+ /* See if someone else has already initialized the queue */ -+ if (qstate->base_ptr_div128) { -+ if (max_depth != (int)qstate->max_depth) { -+ cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: " -+ "Queue already initalized with different " -+ "max_depth (%d).\n", -+ (int)qstate->max_depth); -+ return CVMX_CMD_QUEUE_INVALID_PARAM; -+ } -+ if (fpa_pool != qstate->fpa_pool) { -+ cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: " -+ "Queue already initalized with different " -+ "FPA pool (%u).\n", -+ qstate->fpa_pool); -+ return CVMX_CMD_QUEUE_INVALID_PARAM; -+ } -+ if ((pool_size >> 3) - 1 != qstate->pool_size_m1) { -+ cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: " -+ "Queue already initalized with different " -+ "FPA pool size (%u).\n", -+ (qstate->pool_size_m1 + 1) << 3); -+ return CVMX_CMD_QUEUE_INVALID_PARAM; -+ } -+ CVMX_SYNCWS; -+ return CVMX_CMD_QUEUE_ALREADY_SETUP; -+ } else { -+ union cvmx_fpa_ctl_status status; -+ void *buffer; -+ -+ status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS); -+ if (!status.s.enb) { -+ cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: " -+ "FPA is not enabled.\n"); -+ return CVMX_CMD_QUEUE_NO_MEMORY; -+ } -+ buffer = cvmx_fpa_alloc(fpa_pool); -+ if (buffer == NULL) { -+ cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: " -+ "Unable to allocate initial buffer.\n"); -+ return CVMX_CMD_QUEUE_NO_MEMORY; -+ } -+ -+ memset(qstate, 0, sizeof(*qstate)); -+ qstate->max_depth = max_depth; -+ qstate->fpa_pool = fpa_pool; -+ qstate->pool_size_m1 = (pool_size >> 3) - 1; -+ qstate->base_ptr_div128 = cvmx_ptr_to_phys(buffer) / 128; -+ /* -+ * We zeroed the now serving field so we need to also -+ * zero the ticket. -+ */ -+ __cvmx_cmd_queue_state_ptr-> -+ ticket[__cvmx_cmd_queue_get_index(queue_id)] = 0; -+ CVMX_SYNCWS; -+ return CVMX_CMD_QUEUE_SUCCESS; -+ } -+} -+ -+/** -+ * Shutdown a queue a free it's command buffers to the FPA. The -+ * hardware connected to the queue must be stopped before this -+ * function is called. -+ * -+ * @queue_id: Queue to shutdown -+ * -+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code -+ */ -+cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id) -+{ -+ __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id); -+ if (qptr == NULL) { -+ cvmx_dprintf("ERROR: cvmx_cmd_queue_shutdown: Unable to " -+ "get queue information.\n"); -+ return CVMX_CMD_QUEUE_INVALID_PARAM; -+ } -+ -+ if (cvmx_cmd_queue_length(queue_id) > 0) { -+ cvmx_dprintf("ERROR: cvmx_cmd_queue_shutdown: Queue still " -+ "has data in it.\n"); -+ return CVMX_CMD_QUEUE_FULL; -+ } -+ -+ __cvmx_cmd_queue_lock(queue_id, qptr); -+ if (qptr->base_ptr_div128) { -+ cvmx_fpa_free(cvmx_phys_to_ptr -+ ((uint64_t) qptr->base_ptr_div128 << 7), -+ qptr->fpa_pool, 0); -+ qptr->base_ptr_div128 = 0; -+ } -+ __cvmx_cmd_queue_unlock(qptr); -+ -+ return CVMX_CMD_QUEUE_SUCCESS; -+} -+ -+/** -+ * Return the number of command words pending in the queue. This -+ * function may be relatively slow for some hardware units. -+ * -+ * @queue_id: Hardware command queue to query -+ * -+ * Returns Number of outstanding commands -+ */ -+int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id) -+{ -+ if (CVMX_ENABLE_PARAMETER_CHECKING) { -+ if (__cvmx_cmd_queue_get_state(queue_id) == NULL) -+ return CVMX_CMD_QUEUE_INVALID_PARAM; -+ } -+ -+ /* -+ * The cast is here so gcc with check that all values in the -+ * cvmx_cmd_queue_id_t enumeration are here. -+ */ -+ switch ((cvmx_cmd_queue_id_t) (queue_id & 0xff0000)) { -+ case CVMX_CMD_QUEUE_PKO_BASE: -+ /* -+ * FIXME: Need atomic lock on -+ * CVMX_PKO_REG_READ_IDX. Right now we are normally -+ * called with the queue lock, so that is a SLIGHT -+ * amount of protection. -+ */ -+ cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue_id & 0xffff); -+ if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) { -+ union cvmx_pko_mem_debug9 debug9; -+ debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9); -+ return debug9.cn38xx.doorbell; -+ } else { -+ union cvmx_pko_mem_debug8 debug8; -+ debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8); -+ return debug8.cn58xx.doorbell; -+ } -+ case CVMX_CMD_QUEUE_ZIP: -+ case CVMX_CMD_QUEUE_DFA: -+ case CVMX_CMD_QUEUE_RAID: -+ /* FIXME: Implement other lengths */ -+ return 0; -+ case CVMX_CMD_QUEUE_DMA_BASE: -+ { -+ union cvmx_npei_dmax_counts dmax_counts; -+ dmax_counts.u64 = -+ cvmx_read_csr(CVMX_PEXP_NPEI_DMAX_COUNTS -+ (queue_id & 0x7)); -+ return dmax_counts.s.dbell; -+ } -+ case CVMX_CMD_QUEUE_END: -+ return CVMX_CMD_QUEUE_INVALID_PARAM; -+ } -+ return CVMX_CMD_QUEUE_INVALID_PARAM; -+} -+ -+/** -+ * Return the command buffer to be written to. The purpose of this -+ * function is to allow CVMX routine access t othe low level buffer -+ * for initial hardware setup. User applications should not call this -+ * function directly. -+ * -+ * @queue_id: Command queue to query -+ * -+ * Returns Command buffer or NULL on failure -+ */ -+void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id) -+{ -+ __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id); -+ if (qptr && qptr->base_ptr_div128) -+ return cvmx_phys_to_ptr((uint64_t) qptr->base_ptr_div128 << 7); -+ else -+ return NULL; -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-cmd-queue.h -@@ -0,0 +1,617 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * -+ * Support functions for managing command queues used for -+ * various hardware blocks. -+ * -+ * The common command queue infrastructure abstracts out the -+ * software necessary for adding to Octeon's chained queue -+ * structures. These structures are used for commands to the -+ * PKO, ZIP, DFA, RAID, and DMA engine blocks. Although each -+ * hardware unit takes commands and CSRs of different types, -+ * they all use basic linked command buffers to store the -+ * pending request. In general, users of the CVMX API don't -+ * call cvmx-cmd-queue functions directly. Instead the hardware -+ * unit specific wrapper should be used. The wrappers perform -+ * unit specific validation and CSR writes to submit the -+ * commands. -+ * -+ * Even though most software will never directly interact with -+ * cvmx-cmd-queue, knowledge of its internal working can help -+ * in diagnosing performance problems and help with debugging. -+ * -+ * Command queue pointers are stored in a global named block -+ * called "cvmx_cmd_queues". Except for the PKO queues, each -+ * hardware queue is stored in its own cache line to reduce SMP -+ * contention on spin locks. The PKO queues are stored such that -+ * every 16th queue is next to each other in memory. This scheme -+ * allows for queues being in separate cache lines when there -+ * are low number of queues per port. With 16 queues per port, -+ * the first queue for each port is in the same cache area. The -+ * second queues for each port are in another area, etc. This -+ * allows software to implement very efficient lockless PKO with -+ * 16 queues per port using a minimum of cache lines per core. -+ * All queues for a given core will be isolated in the same -+ * cache area. -+ * -+ * In addition to the memory pointer layout, cvmx-cmd-queue -+ * provides an optimized fair ll/sc locking mechanism for the -+ * queues. The lock uses a "ticket / now serving" model to -+ * maintain fair order on contended locks. In addition, it uses -+ * predicted locking time to limit cache contention. When a core -+ * know it must wait in line for a lock, it spins on the -+ * internal cycle counter to completely eliminate any causes of -+ * bus traffic. -+ * -+ */ -+ -+#ifndef __CVMX_CMD_QUEUE_H__ -+#define __CVMX_CMD_QUEUE_H__ -+ -+#include <linux/prefetch.h> -+ -+#include "cvmx-fpa.h" -+/** -+ * By default we disable the max depth support. Most programs -+ * don't use it and it slows down the command queue processing -+ * significantly. -+ */ -+#ifndef CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH -+#define CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH 0 -+#endif -+ -+/** -+ * Enumeration representing all hardware blocks that use command -+ * queues. Each hardware block has up to 65536 sub identifiers for -+ * multiple command queues. Not all chips support all hardware -+ * units. -+ */ -+typedef enum { -+ CVMX_CMD_QUEUE_PKO_BASE = 0x00000, -+ -+#define CVMX_CMD_QUEUE_PKO(queue) \ -+ ((cvmx_cmd_queue_id_t)(CVMX_CMD_QUEUE_PKO_BASE + (0xffff&(queue)))) -+ -+ CVMX_CMD_QUEUE_ZIP = 0x10000, -+ CVMX_CMD_QUEUE_DFA = 0x20000, -+ CVMX_CMD_QUEUE_RAID = 0x30000, -+ CVMX_CMD_QUEUE_DMA_BASE = 0x40000, -+ -+#define CVMX_CMD_QUEUE_DMA(queue) \ -+ ((cvmx_cmd_queue_id_t)(CVMX_CMD_QUEUE_DMA_BASE + (0xffff&(queue)))) -+ -+ CVMX_CMD_QUEUE_END = 0x50000, -+} cvmx_cmd_queue_id_t; -+ -+/** -+ * Command write operations can fail if the comamnd queue needs -+ * a new buffer and the associated FPA pool is empty. It can also -+ * fail if the number of queued command words reaches the maximum -+ * set at initialization. -+ */ -+typedef enum { -+ CVMX_CMD_QUEUE_SUCCESS = 0, -+ CVMX_CMD_QUEUE_NO_MEMORY = -1, -+ CVMX_CMD_QUEUE_FULL = -2, -+ CVMX_CMD_QUEUE_INVALID_PARAM = -3, -+ CVMX_CMD_QUEUE_ALREADY_SETUP = -4, -+} cvmx_cmd_queue_result_t; -+ -+typedef struct { -+ /* You have lock when this is your ticket */ -+ uint8_t now_serving; -+ uint64_t unused1:24; -+ /* Maximum outstanding command words */ -+ uint32_t max_depth; -+ /* FPA pool buffers come from */ -+ uint64_t fpa_pool:3; -+ /* Top of command buffer pointer shifted 7 */ -+ uint64_t base_ptr_div128:29; -+ uint64_t unused2:6; -+ /* FPA buffer size in 64bit words minus 1 */ -+ uint64_t pool_size_m1:13; -+ /* Number of comamnds already used in buffer */ -+ uint64_t index:13; -+} __cvmx_cmd_queue_state_t; -+ -+/** -+ * This structure contains the global state of all comamnd queues. -+ * It is stored in a bootmem named block and shared by all -+ * applications running on Octeon. Tickets are stored in a differnet -+ * cahce line that queue information to reduce the contention on the -+ * ll/sc used to get a ticket. If this is not the case, the update -+ * of queue state causes the ll/sc to fail quite often. -+ */ -+typedef struct { -+ uint64_t ticket[(CVMX_CMD_QUEUE_END >> 16) * 256]; -+ __cvmx_cmd_queue_state_t state[(CVMX_CMD_QUEUE_END >> 16) * 256]; -+} __cvmx_cmd_queue_all_state_t; -+ -+/** -+ * Initialize a command queue for use. The initial FPA buffer is -+ * allocated and the hardware unit is configured to point to the -+ * new command queue. -+ * -+ * @queue_id: Hardware command queue to initialize. -+ * @max_depth: Maximum outstanding commands that can be queued. -+ * @fpa_pool: FPA pool the command queues should come from. -+ * @pool_size: Size of each buffer in the FPA pool (bytes) -+ * -+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code -+ */ -+cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id, -+ int max_depth, int fpa_pool, -+ int pool_size); -+ -+/** -+ * Shutdown a queue a free it's command buffers to the FPA. The -+ * hardware connected to the queue must be stopped before this -+ * function is called. -+ * -+ * @queue_id: Queue to shutdown -+ * -+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code -+ */ -+cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id); -+ -+/** -+ * Return the number of command words pending in the queue. This -+ * function may be relatively slow for some hardware units. -+ * -+ * @queue_id: Hardware command queue to query -+ * -+ * Returns Number of outstanding commands -+ */ -+int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id); -+ -+/** -+ * Return the command buffer to be written to. The purpose of this -+ * function is to allow CVMX routine access t othe low level buffer -+ * for initial hardware setup. User applications should not call this -+ * function directly. -+ * -+ * @queue_id: Command queue to query -+ * -+ * Returns Command buffer or NULL on failure -+ */ -+void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id); -+ -+/** -+ * Get the index into the state arrays for the supplied queue id. -+ * -+ * @queue_id: Queue ID to get an index for -+ * -+ * Returns Index into the state arrays -+ */ -+static inline int __cvmx_cmd_queue_get_index(cvmx_cmd_queue_id_t queue_id) -+{ -+ /* -+ * Warning: This code currently only works with devices that -+ * have 256 queues or less. Devices with more than 16 queues -+ * are layed out in memory to allow cores quick access to -+ * every 16th queue. This reduces cache thrashing when you are -+ * running 16 queues per port to support lockless operation. -+ */ -+ int unit = queue_id >> 16; -+ int q = (queue_id >> 4) & 0xf; -+ int core = queue_id & 0xf; -+ return unit * 256 + core * 16 + q; -+} -+ -+/** -+ * Lock the supplied queue so nobody else is updating it at the same -+ * time as us. -+ * -+ * @queue_id: Queue ID to lock -+ * @qptr: Pointer to the queue's global state -+ */ -+static inline void __cvmx_cmd_queue_lock(cvmx_cmd_queue_id_t queue_id, -+ __cvmx_cmd_queue_state_t *qptr) -+{ -+ extern __cvmx_cmd_queue_all_state_t -+ *__cvmx_cmd_queue_state_ptr; -+ int tmp; -+ int my_ticket; -+ prefetch(qptr); -+ asm volatile ( -+ ".set push\n" -+ ".set noreorder\n" -+ "1:\n" -+ /* Atomic add one to ticket_ptr */ -+ "ll %[my_ticket], %[ticket_ptr]\n" -+ /* and store the original value */ -+ "li %[ticket], 1\n" -+ /* in my_ticket */ -+ "baddu %[ticket], %[my_ticket]\n" -+ "sc %[ticket], %[ticket_ptr]\n" -+ "beqz %[ticket], 1b\n" -+ " nop\n" -+ /* Load the current now_serving ticket */ -+ "lbu %[ticket], %[now_serving]\n" -+ "2:\n" -+ /* Jump out if now_serving == my_ticket */ -+ "beq %[ticket], %[my_ticket], 4f\n" -+ /* Find out how many tickets are in front of me */ -+ " subu %[ticket], %[my_ticket], %[ticket]\n" -+ /* Use tickets in front of me minus one to delay */ -+ "subu %[ticket], 1\n" -+ /* Delay will be ((tickets in front)-1)*32 loops */ -+ "cins %[ticket], %[ticket], 5, 7\n" -+ "3:\n" -+ /* Loop here until our ticket might be up */ -+ "bnez %[ticket], 3b\n" -+ " subu %[ticket], 1\n" -+ /* Jump back up to check out ticket again */ -+ "b 2b\n" -+ /* Load the current now_serving ticket */ -+ " lbu %[ticket], %[now_serving]\n" -+ "4:\n" -+ ".set pop\n" : -+ [ticket_ptr] "=m"(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]), -+ [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp), -+ [my_ticket] "=r"(my_ticket) -+ ); -+} -+ -+/** -+ * Unlock the queue, flushing all writes. -+ * -+ * @qptr: Queue to unlock -+ */ -+static inline void __cvmx_cmd_queue_unlock(__cvmx_cmd_queue_state_t *qptr) -+{ -+ qptr->now_serving++; -+ CVMX_SYNCWS; -+} -+ -+/** -+ * Get the queue state structure for the given queue id -+ * -+ * @queue_id: Queue id to get -+ * -+ * Returns Queue structure or NULL on failure -+ */ -+static inline __cvmx_cmd_queue_state_t -+ *__cvmx_cmd_queue_get_state(cvmx_cmd_queue_id_t queue_id) -+{ -+ extern __cvmx_cmd_queue_all_state_t -+ *__cvmx_cmd_queue_state_ptr; -+ return &__cvmx_cmd_queue_state_ptr-> -+ state[__cvmx_cmd_queue_get_index(queue_id)]; -+} -+ -+/** -+ * Write an arbitrary number of command words to a command queue. -+ * This is a generic function; the fixed number of comamnd word -+ * functions yield higher performance. -+ * -+ * @queue_id: Hardware command queue to write to -+ * @use_locking: -+ * Use internal locking to ensure exclusive access for queue -+ * updates. If you don't use this locking you must ensure -+ * exclusivity some other way. Locking is strongly recommended. -+ * @cmd_count: Number of command words to write -+ * @cmds: Array of comamnds to write -+ * -+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code -+ */ -+static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write(cvmx_cmd_queue_id_t -+ queue_id, -+ int use_locking, -+ int cmd_count, -+ uint64_t *cmds) -+{ -+ __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id); -+ -+ /* Make sure nobody else is updating the same queue */ -+ if (likely(use_locking)) -+ __cvmx_cmd_queue_lock(queue_id, qptr); -+ -+ /* -+ * If a max queue length was specified then make sure we don't -+ * exceed it. If any part of the command would be below the -+ * limit we allow it. -+ */ -+ if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) { -+ if (unlikely -+ (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) { -+ if (likely(use_locking)) -+ __cvmx_cmd_queue_unlock(qptr); -+ return CVMX_CMD_QUEUE_FULL; -+ } -+ } -+ -+ /* -+ * Normally there is plenty of room in the current buffer for -+ * the command. -+ */ -+ if (likely(qptr->index + cmd_count < qptr->pool_size_m1)) { -+ uint64_t *ptr = -+ (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr-> -+ base_ptr_div128 << 7); -+ ptr += qptr->index; -+ qptr->index += cmd_count; -+ while (cmd_count--) -+ *ptr++ = *cmds++; -+ } else { -+ uint64_t *ptr; -+ int count; -+ /* -+ * We need a new comamnd buffer. Fail if there isn't -+ * one available. -+ */ -+ uint64_t *new_buffer = -+ (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool); -+ if (unlikely(new_buffer == NULL)) { -+ if (likely(use_locking)) -+ __cvmx_cmd_queue_unlock(qptr); -+ return CVMX_CMD_QUEUE_NO_MEMORY; -+ } -+ ptr = -+ (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr-> -+ base_ptr_div128 << 7); -+ /* -+ * Figure out how many command words will fit in this -+ * buffer. One location will be needed for the next -+ * buffer pointer. -+ */ -+ count = qptr->pool_size_m1 - qptr->index; -+ ptr += qptr->index; -+ cmd_count -= count; -+ while (count--) -+ *ptr++ = *cmds++; -+ *ptr = cvmx_ptr_to_phys(new_buffer); -+ /* -+ * The current buffer is full and has a link to the -+ * next buffer. Time to write the rest of the commands -+ * into the new buffer. -+ */ -+ qptr->base_ptr_div128 = *ptr >> 7; -+ qptr->index = cmd_count; -+ ptr = new_buffer; -+ while (cmd_count--) -+ *ptr++ = *cmds++; -+ } -+ -+ /* All updates are complete. Release the lock and return */ -+ if (likely(use_locking)) -+ __cvmx_cmd_queue_unlock(qptr); -+ return CVMX_CMD_QUEUE_SUCCESS; -+} -+ -+/** -+ * Simple function to write two command words to a command -+ * queue. -+ * -+ * @queue_id: Hardware command queue to write to -+ * @use_locking: -+ * Use internal locking to ensure exclusive access for queue -+ * updates. If you don't use this locking you must ensure -+ * exclusivity some other way. Locking is strongly recommended. -+ * @cmd1: Command -+ * @cmd2: Command -+ * -+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code -+ */ -+static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write2(cvmx_cmd_queue_id_t -+ queue_id, -+ int use_locking, -+ uint64_t cmd1, -+ uint64_t cmd2) -+{ -+ __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id); -+ -+ /* Make sure nobody else is updating the same queue */ -+ if (likely(use_locking)) -+ __cvmx_cmd_queue_lock(queue_id, qptr); -+ -+ /* -+ * If a max queue length was specified then make sure we don't -+ * exceed it. If any part of the command would be below the -+ * limit we allow it. -+ */ -+ if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) { -+ if (unlikely -+ (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) { -+ if (likely(use_locking)) -+ __cvmx_cmd_queue_unlock(qptr); -+ return CVMX_CMD_QUEUE_FULL; -+ } -+ } -+ -+ /* -+ * Normally there is plenty of room in the current buffer for -+ * the command. -+ */ -+ if (likely(qptr->index + 2 < qptr->pool_size_m1)) { -+ uint64_t *ptr = -+ (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr-> -+ base_ptr_div128 << 7); -+ ptr += qptr->index; -+ qptr->index += 2; -+ ptr[0] = cmd1; -+ ptr[1] = cmd2; -+ } else { -+ uint64_t *ptr; -+ /* -+ * Figure out how many command words will fit in this -+ * buffer. One location will be needed for the next -+ * buffer pointer. -+ */ -+ int count = qptr->pool_size_m1 - qptr->index; -+ /* -+ * We need a new comamnd buffer. Fail if there isn't -+ * one available. -+ */ -+ uint64_t *new_buffer = -+ (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool); -+ if (unlikely(new_buffer == NULL)) { -+ if (likely(use_locking)) -+ __cvmx_cmd_queue_unlock(qptr); -+ return CVMX_CMD_QUEUE_NO_MEMORY; -+ } -+ count--; -+ ptr = -+ (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr-> -+ base_ptr_div128 << 7); -+ ptr += qptr->index; -+ *ptr++ = cmd1; -+ if (likely(count)) -+ *ptr++ = cmd2; -+ *ptr = cvmx_ptr_to_phys(new_buffer); -+ /* -+ * The current buffer is full and has a link to the -+ * next buffer. Time to write the rest of the commands -+ * into the new buffer. -+ */ -+ qptr->base_ptr_div128 = *ptr >> 7; -+ qptr->index = 0; -+ if (unlikely(count == 0)) { -+ qptr->index = 1; -+ new_buffer[0] = cmd2; -+ } -+ } -+ -+ /* All updates are complete. Release the lock and return */ -+ if (likely(use_locking)) -+ __cvmx_cmd_queue_unlock(qptr); -+ return CVMX_CMD_QUEUE_SUCCESS; -+} -+ -+/** -+ * Simple function to write three command words to a command -+ * queue. -+ * -+ * @queue_id: Hardware command queue to write to -+ * @use_locking: -+ * Use internal locking to ensure exclusive access for queue -+ * updates. If you don't use this locking you must ensure -+ * exclusivity some other way. Locking is strongly recommended. -+ * @cmd1: Command -+ * @cmd2: Command -+ * @cmd3: Command -+ * -+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code -+ */ -+static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write3(cvmx_cmd_queue_id_t -+ queue_id, -+ int use_locking, -+ uint64_t cmd1, -+ uint64_t cmd2, -+ uint64_t cmd3) -+{ -+ __cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id); -+ -+ /* Make sure nobody else is updating the same queue */ -+ if (likely(use_locking)) -+ __cvmx_cmd_queue_lock(queue_id, qptr); -+ -+ /* -+ * If a max queue length was specified then make sure we don't -+ * exceed it. If any part of the command would be below the -+ * limit we allow it. -+ */ -+ if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) { -+ if (unlikely -+ (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) { -+ if (likely(use_locking)) -+ __cvmx_cmd_queue_unlock(qptr); -+ return CVMX_CMD_QUEUE_FULL; -+ } -+ } -+ -+ /* -+ * Normally there is plenty of room in the current buffer for -+ * the command. -+ */ -+ if (likely(qptr->index + 3 < qptr->pool_size_m1)) { -+ uint64_t *ptr = -+ (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr-> -+ base_ptr_div128 << 7); -+ ptr += qptr->index; -+ qptr->index += 3; -+ ptr[0] = cmd1; -+ ptr[1] = cmd2; -+ ptr[2] = cmd3; -+ } else { -+ uint64_t *ptr; -+ /* -+ * Figure out how many command words will fit in this -+ * buffer. One location will be needed for the next -+ * buffer pointer -+ */ -+ int count = qptr->pool_size_m1 - qptr->index; -+ /* -+ * We need a new comamnd buffer. Fail if there isn't -+ * one available -+ */ -+ uint64_t *new_buffer = -+ (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool); -+ if (unlikely(new_buffer == NULL)) { -+ if (likely(use_locking)) -+ __cvmx_cmd_queue_unlock(qptr); -+ return CVMX_CMD_QUEUE_NO_MEMORY; -+ } -+ count--; -+ ptr = -+ (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr-> -+ base_ptr_div128 << 7); -+ ptr += qptr->index; -+ *ptr++ = cmd1; -+ if (count) { -+ *ptr++ = cmd2; -+ if (count > 1) -+ *ptr++ = cmd3; -+ } -+ *ptr = cvmx_ptr_to_phys(new_buffer); -+ /* -+ * The current buffer is full and has a link to the -+ * next buffer. Time to write the rest of the commands -+ * into the new buffer. -+ */ -+ qptr->base_ptr_div128 = *ptr >> 7; -+ qptr->index = 0; -+ ptr = new_buffer; -+ if (count == 0) { -+ *ptr++ = cmd2; -+ qptr->index++; -+ } -+ if (count < 2) { -+ *ptr++ = cmd3; -+ qptr->index++; -+ } -+ } -+ -+ /* All updates are complete. Release the lock and return */ -+ if (likely(use_locking)) -+ __cvmx_cmd_queue_unlock(qptr); -+ return CVMX_CMD_QUEUE_SUCCESS; -+} -+ -+#endif /* __CVMX_CMD_QUEUE_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-config.h -@@ -0,0 +1,169 @@ -+#ifndef __CVMX_CONFIG_H__ -+#define __CVMX_CONFIG_H__ -+ -+/************************* Config Specific Defines ************************/ -+#define CVMX_LLM_NUM_PORTS 1 -+#define CVMX_NULL_POINTER_PROTECT 1 -+#define CVMX_ENABLE_DEBUG_PRINTS 1 -+/* PKO queues per port for interface 0 (ports 0-15) */ -+#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 1 -+/* PKO queues per port for interface 1 (ports 16-31) */ -+#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 1 -+/* Limit on the number of PKO ports enabled for interface 0 */ -+#define CVMX_PKO_MAX_PORTS_INTERFACE0 CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0 -+/* Limit on the number of PKO ports enabled for interface 1 */ -+#define CVMX_PKO_MAX_PORTS_INTERFACE1 CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1 -+/* PKO queues per port for PCI (ports 32-35) */ -+#define CVMX_PKO_QUEUES_PER_PORT_PCI 1 -+/* PKO queues per port for Loop devices (ports 36-39) */ -+#define CVMX_PKO_QUEUES_PER_PORT_LOOP 1 -+ -+/************************* FPA allocation *********************************/ -+/* Pool sizes in bytes, must be multiple of a cache line */ -+#define CVMX_FPA_POOL_0_SIZE (16 * CVMX_CACHE_LINE_SIZE) -+#define CVMX_FPA_POOL_1_SIZE (1 * CVMX_CACHE_LINE_SIZE) -+#define CVMX_FPA_POOL_2_SIZE (8 * CVMX_CACHE_LINE_SIZE) -+#define CVMX_FPA_POOL_3_SIZE (0 * CVMX_CACHE_LINE_SIZE) -+#define CVMX_FPA_POOL_4_SIZE (0 * CVMX_CACHE_LINE_SIZE) -+#define CVMX_FPA_POOL_5_SIZE (0 * CVMX_CACHE_LINE_SIZE) -+#define CVMX_FPA_POOL_6_SIZE (0 * CVMX_CACHE_LINE_SIZE) -+#define CVMX_FPA_POOL_7_SIZE (0 * CVMX_CACHE_LINE_SIZE) -+ -+/* Pools in use */ -+/* Packet buffers */ -+#define CVMX_FPA_PACKET_POOL (0) -+#define CVMX_FPA_PACKET_POOL_SIZE CVMX_FPA_POOL_0_SIZE -+/* Work queue entrys */ -+#define CVMX_FPA_WQE_POOL (1) -+#define CVMX_FPA_WQE_POOL_SIZE CVMX_FPA_POOL_1_SIZE -+/* PKO queue command buffers */ -+#define CVMX_FPA_OUTPUT_BUFFER_POOL (2) -+#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE CVMX_FPA_POOL_2_SIZE -+ -+/************************* FAU allocation ********************************/ -+/* The fetch and add registers are allocated here. They are arranged -+ * in order of descending size so that all alignment constraints are -+ * automatically met. The enums are linked so that the following enum -+ * continues allocating where the previous one left off, so the -+ * numbering within each enum always starts with zero. The macros -+ * take care of the address increment size, so the values entered -+ * always increase by 1. FAU registers are accessed with byte -+ * addresses. -+ */ -+ -+#define CVMX_FAU_REG_64_ADDR(x) ((x << 3) + CVMX_FAU_REG_64_START) -+typedef enum { -+ CVMX_FAU_REG_64_START = 0, -+ CVMX_FAU_REG_64_END = CVMX_FAU_REG_64_ADDR(0), -+} cvmx_fau_reg_64_t; -+ -+#define CVMX_FAU_REG_32_ADDR(x) ((x << 2) + CVMX_FAU_REG_32_START) -+typedef enum { -+ CVMX_FAU_REG_32_START = CVMX_FAU_REG_64_END, -+ CVMX_FAU_REG_32_END = CVMX_FAU_REG_32_ADDR(0), -+} cvmx_fau_reg_32_t; -+ -+#define CVMX_FAU_REG_16_ADDR(x) ((x << 1) + CVMX_FAU_REG_16_START) -+typedef enum { -+ CVMX_FAU_REG_16_START = CVMX_FAU_REG_32_END, -+ CVMX_FAU_REG_16_END = CVMX_FAU_REG_16_ADDR(0), -+} cvmx_fau_reg_16_t; -+ -+#define CVMX_FAU_REG_8_ADDR(x) ((x) + CVMX_FAU_REG_8_START) -+typedef enum { -+ CVMX_FAU_REG_8_START = CVMX_FAU_REG_16_END, -+ CVMX_FAU_REG_8_END = CVMX_FAU_REG_8_ADDR(0), -+} cvmx_fau_reg_8_t; -+ -+/* -+ * The name CVMX_FAU_REG_AVAIL_BASE is provided to indicate the first -+ * available FAU address that is not allocated in cvmx-config.h. This -+ * is 64 bit aligned. -+ */ -+#define CVMX_FAU_REG_AVAIL_BASE ((CVMX_FAU_REG_8_END + 0x7) & (~0x7ULL)) -+#define CVMX_FAU_REG_END (2048) -+ -+/********************** scratch memory allocation *************************/ -+/* Scratchpad memory allocation. Note that these are byte memory -+ * addresses. Some uses of scratchpad (IOBDMA for example) require -+ * the use of 8-byte aligned addresses, so proper alignment needs to -+ * be taken into account. -+ */ -+/* Generic scratch iobdma area */ -+#define CVMX_SCR_SCRATCH (0) -+/* First location available after cvmx-config.h allocated region. */ -+#define CVMX_SCR_REG_AVAIL_BASE (8) -+ -+/* -+ * CVMX_HELPER_FIRST_MBUFF_SKIP is the number of bytes to reserve -+ * before the beginning of the packet. If necessary, override the -+ * default here. See the IPD section of the hardware manual for MBUFF -+ * SKIP details. -+ */ -+#define CVMX_HELPER_FIRST_MBUFF_SKIP 184 -+ -+/* -+ * CVMX_HELPER_NOT_FIRST_MBUFF_SKIP is the number of bytes to reserve -+ * in each chained packet element. If necessary, override the default -+ * here. -+ */ -+#define CVMX_HELPER_NOT_FIRST_MBUFF_SKIP 0 -+ -+/* -+ * CVMX_HELPER_ENABLE_BACK_PRESSURE controls whether back pressure is -+ * enabled for all input ports. This controls if IPD sends -+ * backpressure to all ports if Octeon's FPA pools don't have enough -+ * packet or work queue entries. Even when this is off, it is still -+ * possible to get backpressure from individual hardware ports. When -+ * configuring backpressure, also check -+ * CVMX_HELPER_DISABLE_*_BACKPRESSURE below. If necessary, override -+ * the default here. -+ */ -+#define CVMX_HELPER_ENABLE_BACK_PRESSURE 1 -+ -+/* -+ * CVMX_HELPER_ENABLE_IPD controls if the IPD is enabled in the helper -+ * function. Once it is enabled the hardware starts accepting -+ * packets. You might want to skip the IPD enable if configuration -+ * changes are need from the default helper setup. If necessary, -+ * override the default here. -+ */ -+#define CVMX_HELPER_ENABLE_IPD 0 -+ -+/* -+ * CVMX_HELPER_INPUT_TAG_TYPE selects the type of tag that the IPD assigns -+ * to incoming packets. -+ */ -+#define CVMX_HELPER_INPUT_TAG_TYPE CVMX_POW_TAG_TYPE_ORDERED -+ -+#define CVMX_ENABLE_PARAMETER_CHECKING 0 -+ -+/* -+ * The following select which fields are used by the PIP to generate -+ * the tag on INPUT -+ * 0: don't include -+ * 1: include -+ */ -+#define CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP 0 -+#define CVMX_HELPER_INPUT_TAG_IPV6_DST_IP 0 -+#define CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT 0 -+#define CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT 0 -+#define CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER 0 -+#define CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP 0 -+#define CVMX_HELPER_INPUT_TAG_IPV4_DST_IP 0 -+#define CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT 0 -+#define CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT 0 -+#define CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL 0 -+#define CVMX_HELPER_INPUT_TAG_INPUT_PORT 1 -+ -+/* Select skip mode for input ports */ -+#define CVMX_HELPER_INPUT_PORT_SKIP_MODE CVMX_PIP_PORT_CFG_MODE_SKIPL2 -+ -+/* -+ * Force backpressure to be disabled. This overrides all other -+ * backpressure configuration. -+ */ -+#define CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE 0 -+ -+#endif /* __CVMX_CONFIG_H__ */ -+ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-dbg-defs.h -@@ -0,0 +1,72 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_DBG_DEFS_H__ -+#define __CVMX_DBG_DEFS_H__ -+ -+#define CVMX_DBG_DATA \ -+ CVMX_ADD_IO_SEG(0x00011F00000001E8ull) -+ -+union cvmx_dbg_data { -+ uint64_t u64; -+ struct cvmx_dbg_data_s { -+ uint64_t reserved_23_63:41; -+ uint64_t c_mul:5; -+ uint64_t dsel_ext:1; -+ uint64_t data:17; -+ } s; -+ struct cvmx_dbg_data_cn30xx { -+ uint64_t reserved_31_63:33; -+ uint64_t pll_mul:3; -+ uint64_t reserved_23_27:5; -+ uint64_t c_mul:5; -+ uint64_t dsel_ext:1; -+ uint64_t data:17; -+ } cn30xx; -+ struct cvmx_dbg_data_cn30xx cn31xx; -+ struct cvmx_dbg_data_cn38xx { -+ uint64_t reserved_29_63:35; -+ uint64_t d_mul:4; -+ uint64_t dclk_mul2:1; -+ uint64_t cclk_div2:1; -+ uint64_t c_mul:5; -+ uint64_t dsel_ext:1; -+ uint64_t data:17; -+ } cn38xx; -+ struct cvmx_dbg_data_cn38xx cn38xxp2; -+ struct cvmx_dbg_data_cn30xx cn50xx; -+ struct cvmx_dbg_data_cn58xx { -+ uint64_t reserved_29_63:35; -+ uint64_t rem:6; -+ uint64_t c_mul:5; -+ uint64_t dsel_ext:1; -+ uint64_t data:17; -+ } cn58xx; -+ struct cvmx_dbg_data_cn58xx cn58xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-fau.h -@@ -0,0 +1,597 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * Interface to the hardware Fetch and Add Unit. -+ */ -+ -+#ifndef __CVMX_FAU_H__ -+#define __CVMX_FAU_H__ -+ -+/* -+ * Octeon Fetch and Add Unit (FAU) -+ */ -+ -+#define CVMX_FAU_LOAD_IO_ADDRESS cvmx_build_io_address(0x1e, 0) -+#define CVMX_FAU_BITS_SCRADDR 63, 56 -+#define CVMX_FAU_BITS_LEN 55, 48 -+#define CVMX_FAU_BITS_INEVAL 35, 14 -+#define CVMX_FAU_BITS_TAGWAIT 13, 13 -+#define CVMX_FAU_BITS_NOADD 13, 13 -+#define CVMX_FAU_BITS_SIZE 12, 11 -+#define CVMX_FAU_BITS_REGISTER 10, 0 -+ -+typedef enum { -+ CVMX_FAU_OP_SIZE_8 = 0, -+ CVMX_FAU_OP_SIZE_16 = 1, -+ CVMX_FAU_OP_SIZE_32 = 2, -+ CVMX_FAU_OP_SIZE_64 = 3 -+} cvmx_fau_op_size_t; -+ -+/** -+ * Tagwait return definition. If a timeout occurs, the error -+ * bit will be set. Otherwise the value of the register before -+ * the update will be returned. -+ */ -+typedef struct { -+ uint64_t error:1; -+ int64_t value:63; -+} cvmx_fau_tagwait64_t; -+ -+/** -+ * Tagwait return definition. If a timeout occurs, the error -+ * bit will be set. Otherwise the value of the register before -+ * the update will be returned. -+ */ -+typedef struct { -+ uint64_t error:1; -+ int32_t value:31; -+} cvmx_fau_tagwait32_t; -+ -+/** -+ * Tagwait return definition. If a timeout occurs, the error -+ * bit will be set. Otherwise the value of the register before -+ * the update will be returned. -+ */ -+typedef struct { -+ uint64_t error:1; -+ int16_t value:15; -+} cvmx_fau_tagwait16_t; -+ -+/** -+ * Tagwait return definition. If a timeout occurs, the error -+ * bit will be set. Otherwise the value of the register before -+ * the update will be returned. -+ */ -+typedef struct { -+ uint64_t error:1; -+ int8_t value:7; -+} cvmx_fau_tagwait8_t; -+ -+/** -+ * Asynchronous tagwait return definition. If a timeout occurs, -+ * the error bit will be set. Otherwise the value of the -+ * register before the update will be returned. -+ */ -+typedef union { -+ uint64_t u64; -+ struct { -+ uint64_t invalid:1; -+ uint64_t data:63; /* unpredictable if invalid is set */ -+ } s; -+} cvmx_fau_async_tagwait_result_t; -+ -+/** -+ * Builds a store I/O address for writing to the FAU -+ * -+ * @noadd: 0 = Store value is atomically added to the current value -+ * 1 = Store value is atomically written over the current value -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 2 for 16 bit access. -+ * - Step by 4 for 32 bit access. -+ * - Step by 8 for 64 bit access. -+ * Returns Address to store for atomic update -+ */ -+static inline uint64_t __cvmx_fau_store_address(uint64_t noadd, uint64_t reg) -+{ -+ return CVMX_ADD_IO_SEG(CVMX_FAU_LOAD_IO_ADDRESS) | -+ cvmx_build_bits(CVMX_FAU_BITS_NOADD, noadd) | -+ cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg); -+} -+ -+/** -+ * Builds a I/O address for accessing the FAU -+ * -+ * @tagwait: Should the atomic add wait for the current tag switch -+ * operation to complete. -+ * - 0 = Don't wait -+ * - 1 = Wait for tag switch to complete -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 2 for 16 bit access. -+ * - Step by 4 for 32 bit access. -+ * - Step by 8 for 64 bit access. -+ * @value: Signed value to add. -+ * Note: When performing 32 and 64 bit access, only the low -+ * 22 bits are available. -+ * Returns Address to read from for atomic update -+ */ -+static inline uint64_t __cvmx_fau_atomic_address(uint64_t tagwait, uint64_t reg, -+ int64_t value) -+{ -+ return CVMX_ADD_IO_SEG(CVMX_FAU_LOAD_IO_ADDRESS) | -+ cvmx_build_bits(CVMX_FAU_BITS_INEVAL, value) | -+ cvmx_build_bits(CVMX_FAU_BITS_TAGWAIT, tagwait) | -+ cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg); -+} -+ -+/** -+ * Perform an atomic 64 bit add -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 8 for 64 bit access. -+ * @value: Signed value to add. -+ * Note: Only the low 22 bits are available. -+ * Returns Value of the register before the update -+ */ -+static inline int64_t cvmx_fau_fetch_and_add64(cvmx_fau_reg_64_t reg, -+ int64_t value) -+{ -+ return cvmx_read64_int64(__cvmx_fau_atomic_address(0, reg, value)); -+} -+ -+/** -+ * Perform an atomic 32 bit add -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 4 for 32 bit access. -+ * @value: Signed value to add. -+ * Note: Only the low 22 bits are available. -+ * Returns Value of the register before the update -+ */ -+static inline int32_t cvmx_fau_fetch_and_add32(cvmx_fau_reg_32_t reg, -+ int32_t value) -+{ -+ return cvmx_read64_int32(__cvmx_fau_atomic_address(0, reg, value)); -+} -+ -+/** -+ * Perform an atomic 16 bit add -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 2 for 16 bit access. -+ * @value: Signed value to add. -+ * Returns Value of the register before the update -+ */ -+static inline int16_t cvmx_fau_fetch_and_add16(cvmx_fau_reg_16_t reg, -+ int16_t value) -+{ -+ return cvmx_read64_int16(__cvmx_fau_atomic_address(0, reg, value)); -+} -+ -+/** -+ * Perform an atomic 8 bit add -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * @value: Signed value to add. -+ * Returns Value of the register before the update -+ */ -+static inline int8_t cvmx_fau_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value) -+{ -+ return cvmx_read64_int8(__cvmx_fau_atomic_address(0, reg, value)); -+} -+ -+/** -+ * Perform an atomic 64 bit add after the current tag switch -+ * completes -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 8 for 64 bit access. -+ * @value: Signed value to add. -+ * Note: Only the low 22 bits are available. -+ * Returns If a timeout occurs, the error bit will be set. Otherwise -+ * the value of the register before the update will be -+ * returned -+ */ -+static inline cvmx_fau_tagwait64_t -+cvmx_fau_tagwait_fetch_and_add64(cvmx_fau_reg_64_t reg, int64_t value) -+{ -+ union { -+ uint64_t i64; -+ cvmx_fau_tagwait64_t t; -+ } result; -+ result.i64 = -+ cvmx_read64_int64(__cvmx_fau_atomic_address(1, reg, value)); -+ return result.t; -+} -+ -+/** -+ * Perform an atomic 32 bit add after the current tag switch -+ * completes -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 4 for 32 bit access. -+ * @value: Signed value to add. -+ * Note: Only the low 22 bits are available. -+ * Returns If a timeout occurs, the error bit will be set. Otherwise -+ * the value of the register before the update will be -+ * returned -+ */ -+static inline cvmx_fau_tagwait32_t -+cvmx_fau_tagwait_fetch_and_add32(cvmx_fau_reg_32_t reg, int32_t value) -+{ -+ union { -+ uint64_t i32; -+ cvmx_fau_tagwait32_t t; -+ } result; -+ result.i32 = -+ cvmx_read64_int32(__cvmx_fau_atomic_address(1, reg, value)); -+ return result.t; -+} -+ -+/** -+ * Perform an atomic 16 bit add after the current tag switch -+ * completes -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 2 for 16 bit access. -+ * @value: Signed value to add. -+ * Returns If a timeout occurs, the error bit will be set. Otherwise -+ * the value of the register before the update will be -+ * returned -+ */ -+static inline cvmx_fau_tagwait16_t -+cvmx_fau_tagwait_fetch_and_add16(cvmx_fau_reg_16_t reg, int16_t value) -+{ -+ union { -+ uint64_t i16; -+ cvmx_fau_tagwait16_t t; -+ } result; -+ result.i16 = -+ cvmx_read64_int16(__cvmx_fau_atomic_address(1, reg, value)); -+ return result.t; -+} -+ -+/** -+ * Perform an atomic 8 bit add after the current tag switch -+ * completes -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * @value: Signed value to add. -+ * Returns If a timeout occurs, the error bit will be set. Otherwise -+ * the value of the register before the update will be -+ * returned -+ */ -+static inline cvmx_fau_tagwait8_t -+cvmx_fau_tagwait_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value) -+{ -+ union { -+ uint64_t i8; -+ cvmx_fau_tagwait8_t t; -+ } result; -+ result.i8 = cvmx_read64_int8(__cvmx_fau_atomic_address(1, reg, value)); -+ return result.t; -+} -+ -+/** -+ * Builds I/O data for async operations -+ * -+ * @scraddr: Scratch pad byte addres to write to. Must be 8 byte aligned -+ * @value: Signed value to add. -+ * Note: When performing 32 and 64 bit access, only the low -+ * 22 bits are available. -+ * @tagwait: Should the atomic add wait for the current tag switch -+ * operation to complete. -+ * - 0 = Don't wait -+ * - 1 = Wait for tag switch to complete -+ * @size: The size of the operation: -+ * - CVMX_FAU_OP_SIZE_8 (0) = 8 bits -+ * - CVMX_FAU_OP_SIZE_16 (1) = 16 bits -+ * - CVMX_FAU_OP_SIZE_32 (2) = 32 bits -+ * - CVMX_FAU_OP_SIZE_64 (3) = 64 bits -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 2 for 16 bit access. -+ * - Step by 4 for 32 bit access. -+ * - Step by 8 for 64 bit access. -+ * Returns Data to write using cvmx_send_single -+ */ -+static inline uint64_t __cvmx_fau_iobdma_data(uint64_t scraddr, int64_t value, -+ uint64_t tagwait, -+ cvmx_fau_op_size_t size, -+ uint64_t reg) -+{ -+ return CVMX_FAU_LOAD_IO_ADDRESS | -+ cvmx_build_bits(CVMX_FAU_BITS_SCRADDR, scraddr >> 3) | -+ cvmx_build_bits(CVMX_FAU_BITS_LEN, 1) | -+ cvmx_build_bits(CVMX_FAU_BITS_INEVAL, value) | -+ cvmx_build_bits(CVMX_FAU_BITS_TAGWAIT, tagwait) | -+ cvmx_build_bits(CVMX_FAU_BITS_SIZE, size) | -+ cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg); -+} -+ -+/** -+ * Perform an async atomic 64 bit add. The old value is -+ * placed in the scratch memory at byte address scraddr. -+ * -+ * @scraddr: Scratch memory byte address to put response in. -+ * Must be 8 byte aligned. -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 8 for 64 bit access. -+ * @value: Signed value to add. -+ * Note: Only the low 22 bits are available. -+ * Returns Placed in the scratch pad register -+ */ -+static inline void cvmx_fau_async_fetch_and_add64(uint64_t scraddr, -+ cvmx_fau_reg_64_t reg, -+ int64_t value) -+{ -+ cvmx_send_single(__cvmx_fau_iobdma_data -+ (scraddr, value, 0, CVMX_FAU_OP_SIZE_64, reg)); -+} -+ -+/** -+ * Perform an async atomic 32 bit add. The old value is -+ * placed in the scratch memory at byte address scraddr. -+ * -+ * @scraddr: Scratch memory byte address to put response in. -+ * Must be 8 byte aligned. -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 4 for 32 bit access. -+ * @value: Signed value to add. -+ * Note: Only the low 22 bits are available. -+ * Returns Placed in the scratch pad register -+ */ -+static inline void cvmx_fau_async_fetch_and_add32(uint64_t scraddr, -+ cvmx_fau_reg_32_t reg, -+ int32_t value) -+{ -+ cvmx_send_single(__cvmx_fau_iobdma_data -+ (scraddr, value, 0, CVMX_FAU_OP_SIZE_32, reg)); -+} -+ -+/** -+ * Perform an async atomic 16 bit add. The old value is -+ * placed in the scratch memory at byte address scraddr. -+ * -+ * @scraddr: Scratch memory byte address to put response in. -+ * Must be 8 byte aligned. -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 2 for 16 bit access. -+ * @value: Signed value to add. -+ * Returns Placed in the scratch pad register -+ */ -+static inline void cvmx_fau_async_fetch_and_add16(uint64_t scraddr, -+ cvmx_fau_reg_16_t reg, -+ int16_t value) -+{ -+ cvmx_send_single(__cvmx_fau_iobdma_data -+ (scraddr, value, 0, CVMX_FAU_OP_SIZE_16, reg)); -+} -+ -+/** -+ * Perform an async atomic 8 bit add. The old value is -+ * placed in the scratch memory at byte address scraddr. -+ * -+ * @scraddr: Scratch memory byte address to put response in. -+ * Must be 8 byte aligned. -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * @value: Signed value to add. -+ * Returns Placed in the scratch pad register -+ */ -+static inline void cvmx_fau_async_fetch_and_add8(uint64_t scraddr, -+ cvmx_fau_reg_8_t reg, -+ int8_t value) -+{ -+ cvmx_send_single(__cvmx_fau_iobdma_data -+ (scraddr, value, 0, CVMX_FAU_OP_SIZE_8, reg)); -+} -+ -+/** -+ * Perform an async atomic 64 bit add after the current tag -+ * switch completes. -+ * -+ * @scraddr: Scratch memory byte address to put response in. Must be -+ * 8 byte aligned. If a timeout occurs, the error bit (63) -+ * will be set. Otherwise the value of the register before -+ * the update will be returned -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 8 for 64 bit access. -+ * @value: Signed value to add. -+ * Note: Only the low 22 bits are available. -+ * Returns Placed in the scratch pad register -+ */ -+static inline void cvmx_fau_async_tagwait_fetch_and_add64(uint64_t scraddr, -+ cvmx_fau_reg_64_t reg, -+ int64_t value) -+{ -+ cvmx_send_single(__cvmx_fau_iobdma_data -+ (scraddr, value, 1, CVMX_FAU_OP_SIZE_64, reg)); -+} -+ -+/** -+ * Perform an async atomic 32 bit add after the current tag -+ * switch completes. -+ * -+ * @scraddr: Scratch memory byte address to put response in. Must be -+ * 8 byte aligned. If a timeout occurs, the error bit (63) -+ * will be set. Otherwise the value of the register before -+ * the update will be returned -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 4 for 32 bit access. -+ * @value: Signed value to add. -+ * Note: Only the low 22 bits are available. -+ * Returns Placed in the scratch pad register -+ */ -+static inline void cvmx_fau_async_tagwait_fetch_and_add32(uint64_t scraddr, -+ cvmx_fau_reg_32_t reg, -+ int32_t value) -+{ -+ cvmx_send_single(__cvmx_fau_iobdma_data -+ (scraddr, value, 1, CVMX_FAU_OP_SIZE_32, reg)); -+} -+ -+/** -+ * Perform an async atomic 16 bit add after the current tag -+ * switch completes. -+ * -+ * @scraddr: Scratch memory byte address to put response in. Must be -+ * 8 byte aligned. If a timeout occurs, the error bit (63) -+ * will be set. Otherwise the value of the register before -+ * the update will be returned -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 2 for 16 bit access. -+ * @value: Signed value to add. -+ * -+ * Returns Placed in the scratch pad register -+ */ -+static inline void cvmx_fau_async_tagwait_fetch_and_add16(uint64_t scraddr, -+ cvmx_fau_reg_16_t reg, -+ int16_t value) -+{ -+ cvmx_send_single(__cvmx_fau_iobdma_data -+ (scraddr, value, 1, CVMX_FAU_OP_SIZE_16, reg)); -+} -+ -+/** -+ * Perform an async atomic 8 bit add after the current tag -+ * switch completes. -+ * -+ * @scraddr: Scratch memory byte address to put response in. Must be -+ * 8 byte aligned. If a timeout occurs, the error bit (63) -+ * will be set. Otherwise the value of the register before -+ * the update will be returned -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * @value: Signed value to add. -+ * -+ * Returns Placed in the scratch pad register -+ */ -+static inline void cvmx_fau_async_tagwait_fetch_and_add8(uint64_t scraddr, -+ cvmx_fau_reg_8_t reg, -+ int8_t value) -+{ -+ cvmx_send_single(__cvmx_fau_iobdma_data -+ (scraddr, value, 1, CVMX_FAU_OP_SIZE_8, reg)); -+} -+ -+/** -+ * Perform an atomic 64 bit add -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 8 for 64 bit access. -+ * @value: Signed value to add. -+ */ -+static inline void cvmx_fau_atomic_add64(cvmx_fau_reg_64_t reg, int64_t value) -+{ -+ cvmx_write64_int64(__cvmx_fau_store_address(0, reg), value); -+} -+ -+/** -+ * Perform an atomic 32 bit add -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 4 for 32 bit access. -+ * @value: Signed value to add. -+ */ -+static inline void cvmx_fau_atomic_add32(cvmx_fau_reg_32_t reg, int32_t value) -+{ -+ cvmx_write64_int32(__cvmx_fau_store_address(0, reg), value); -+} -+ -+/** -+ * Perform an atomic 16 bit add -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 2 for 16 bit access. -+ * @value: Signed value to add. -+ */ -+static inline void cvmx_fau_atomic_add16(cvmx_fau_reg_16_t reg, int16_t value) -+{ -+ cvmx_write64_int16(__cvmx_fau_store_address(0, reg), value); -+} -+ -+/** -+ * Perform an atomic 8 bit add -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * @value: Signed value to add. -+ */ -+static inline void cvmx_fau_atomic_add8(cvmx_fau_reg_8_t reg, int8_t value) -+{ -+ cvmx_write64_int8(__cvmx_fau_store_address(0, reg), value); -+} -+ -+/** -+ * Perform an atomic 64 bit write -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 8 for 64 bit access. -+ * @value: Signed value to write. -+ */ -+static inline void cvmx_fau_atomic_write64(cvmx_fau_reg_64_t reg, int64_t value) -+{ -+ cvmx_write64_int64(__cvmx_fau_store_address(1, reg), value); -+} -+ -+/** -+ * Perform an atomic 32 bit write -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 4 for 32 bit access. -+ * @value: Signed value to write. -+ */ -+static inline void cvmx_fau_atomic_write32(cvmx_fau_reg_32_t reg, int32_t value) -+{ -+ cvmx_write64_int32(__cvmx_fau_store_address(1, reg), value); -+} -+ -+/** -+ * Perform an atomic 16 bit write -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * - Step by 2 for 16 bit access. -+ * @value: Signed value to write. -+ */ -+static inline void cvmx_fau_atomic_write16(cvmx_fau_reg_16_t reg, int16_t value) -+{ -+ cvmx_write64_int16(__cvmx_fau_store_address(1, reg), value); -+} -+ -+/** -+ * Perform an atomic 8 bit write -+ * -+ * @reg: FAU atomic register to access. 0 <= reg < 2048. -+ * @value: Signed value to write. -+ */ -+static inline void cvmx_fau_atomic_write8(cvmx_fau_reg_8_t reg, int8_t value) -+{ -+ cvmx_write64_int8(__cvmx_fau_store_address(1, reg), value); -+} -+ -+#endif /* __CVMX_FAU_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-fpa-defs.h -@@ -0,0 +1,403 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_FPA_DEFS_H__ -+#define __CVMX_FPA_DEFS_H__ -+ -+#define CVMX_FPA_BIST_STATUS \ -+ CVMX_ADD_IO_SEG(0x00011800280000E8ull) -+#define CVMX_FPA_CTL_STATUS \ -+ CVMX_ADD_IO_SEG(0x0001180028000050ull) -+#define CVMX_FPA_FPF0_MARKS \ -+ CVMX_ADD_IO_SEG(0x0001180028000000ull) -+#define CVMX_FPA_FPF0_SIZE \ -+ CVMX_ADD_IO_SEG(0x0001180028000058ull) -+#define CVMX_FPA_FPF1_MARKS \ -+ CVMX_ADD_IO_SEG(0x0001180028000008ull) -+#define CVMX_FPA_FPF2_MARKS \ -+ CVMX_ADD_IO_SEG(0x0001180028000010ull) -+#define CVMX_FPA_FPF3_MARKS \ -+ CVMX_ADD_IO_SEG(0x0001180028000018ull) -+#define CVMX_FPA_FPF4_MARKS \ -+ CVMX_ADD_IO_SEG(0x0001180028000020ull) -+#define CVMX_FPA_FPF5_MARKS \ -+ CVMX_ADD_IO_SEG(0x0001180028000028ull) -+#define CVMX_FPA_FPF6_MARKS \ -+ CVMX_ADD_IO_SEG(0x0001180028000030ull) -+#define CVMX_FPA_FPF7_MARKS \ -+ CVMX_ADD_IO_SEG(0x0001180028000038ull) -+#define CVMX_FPA_FPFX_MARKS(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180028000008ull + (((offset) & 7) * 8) - 8 * 1) -+#define CVMX_FPA_FPFX_SIZE(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180028000060ull + (((offset) & 7) * 8) - 8 * 1) -+#define CVMX_FPA_INT_ENB \ -+ CVMX_ADD_IO_SEG(0x0001180028000048ull) -+#define CVMX_FPA_INT_SUM \ -+ CVMX_ADD_IO_SEG(0x0001180028000040ull) -+#define CVMX_FPA_QUE0_PAGE_INDEX \ -+ CVMX_ADD_IO_SEG(0x00011800280000F0ull) -+#define CVMX_FPA_QUE1_PAGE_INDEX \ -+ CVMX_ADD_IO_SEG(0x00011800280000F8ull) -+#define CVMX_FPA_QUE2_PAGE_INDEX \ -+ CVMX_ADD_IO_SEG(0x0001180028000100ull) -+#define CVMX_FPA_QUE3_PAGE_INDEX \ -+ CVMX_ADD_IO_SEG(0x0001180028000108ull) -+#define CVMX_FPA_QUE4_PAGE_INDEX \ -+ CVMX_ADD_IO_SEG(0x0001180028000110ull) -+#define CVMX_FPA_QUE5_PAGE_INDEX \ -+ CVMX_ADD_IO_SEG(0x0001180028000118ull) -+#define CVMX_FPA_QUE6_PAGE_INDEX \ -+ CVMX_ADD_IO_SEG(0x0001180028000120ull) -+#define CVMX_FPA_QUE7_PAGE_INDEX \ -+ CVMX_ADD_IO_SEG(0x0001180028000128ull) -+#define CVMX_FPA_QUEX_AVAILABLE(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180028000098ull + (((offset) & 7) * 8)) -+#define CVMX_FPA_QUEX_PAGE_INDEX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800280000F0ull + (((offset) & 7) * 8)) -+#define CVMX_FPA_QUE_ACT \ -+ CVMX_ADD_IO_SEG(0x0001180028000138ull) -+#define CVMX_FPA_QUE_EXP \ -+ CVMX_ADD_IO_SEG(0x0001180028000130ull) -+#define CVMX_FPA_WART_CTL \ -+ CVMX_ADD_IO_SEG(0x00011800280000D8ull) -+#define CVMX_FPA_WART_STATUS \ -+ CVMX_ADD_IO_SEG(0x00011800280000E0ull) -+ -+union cvmx_fpa_bist_status { -+ uint64_t u64; -+ struct cvmx_fpa_bist_status_s { -+ uint64_t reserved_5_63:59; -+ uint64_t frd:1; -+ uint64_t fpf0:1; -+ uint64_t fpf1:1; -+ uint64_t ffr:1; -+ uint64_t fdr:1; -+ } s; -+ struct cvmx_fpa_bist_status_s cn30xx; -+ struct cvmx_fpa_bist_status_s cn31xx; -+ struct cvmx_fpa_bist_status_s cn38xx; -+ struct cvmx_fpa_bist_status_s cn38xxp2; -+ struct cvmx_fpa_bist_status_s cn50xx; -+ struct cvmx_fpa_bist_status_s cn52xx; -+ struct cvmx_fpa_bist_status_s cn52xxp1; -+ struct cvmx_fpa_bist_status_s cn56xx; -+ struct cvmx_fpa_bist_status_s cn56xxp1; -+ struct cvmx_fpa_bist_status_s cn58xx; -+ struct cvmx_fpa_bist_status_s cn58xxp1; -+}; -+ -+union cvmx_fpa_ctl_status { -+ uint64_t u64; -+ struct cvmx_fpa_ctl_status_s { -+ uint64_t reserved_18_63:46; -+ uint64_t reset:1; -+ uint64_t use_ldt:1; -+ uint64_t use_stt:1; -+ uint64_t enb:1; -+ uint64_t mem1_err:7; -+ uint64_t mem0_err:7; -+ } s; -+ struct cvmx_fpa_ctl_status_s cn30xx; -+ struct cvmx_fpa_ctl_status_s cn31xx; -+ struct cvmx_fpa_ctl_status_s cn38xx; -+ struct cvmx_fpa_ctl_status_s cn38xxp2; -+ struct cvmx_fpa_ctl_status_s cn50xx; -+ struct cvmx_fpa_ctl_status_s cn52xx; -+ struct cvmx_fpa_ctl_status_s cn52xxp1; -+ struct cvmx_fpa_ctl_status_s cn56xx; -+ struct cvmx_fpa_ctl_status_s cn56xxp1; -+ struct cvmx_fpa_ctl_status_s cn58xx; -+ struct cvmx_fpa_ctl_status_s cn58xxp1; -+}; -+ -+union cvmx_fpa_fpfx_marks { -+ uint64_t u64; -+ struct cvmx_fpa_fpfx_marks_s { -+ uint64_t reserved_22_63:42; -+ uint64_t fpf_wr:11; -+ uint64_t fpf_rd:11; -+ } s; -+ struct cvmx_fpa_fpfx_marks_s cn38xx; -+ struct cvmx_fpa_fpfx_marks_s cn38xxp2; -+ struct cvmx_fpa_fpfx_marks_s cn56xx; -+ struct cvmx_fpa_fpfx_marks_s cn56xxp1; -+ struct cvmx_fpa_fpfx_marks_s cn58xx; -+ struct cvmx_fpa_fpfx_marks_s cn58xxp1; -+}; -+ -+union cvmx_fpa_fpfx_size { -+ uint64_t u64; -+ struct cvmx_fpa_fpfx_size_s { -+ uint64_t reserved_11_63:53; -+ uint64_t fpf_siz:11; -+ } s; -+ struct cvmx_fpa_fpfx_size_s cn38xx; -+ struct cvmx_fpa_fpfx_size_s cn38xxp2; -+ struct cvmx_fpa_fpfx_size_s cn56xx; -+ struct cvmx_fpa_fpfx_size_s cn56xxp1; -+ struct cvmx_fpa_fpfx_size_s cn58xx; -+ struct cvmx_fpa_fpfx_size_s cn58xxp1; -+}; -+ -+union cvmx_fpa_fpf0_marks { -+ uint64_t u64; -+ struct cvmx_fpa_fpf0_marks_s { -+ uint64_t reserved_24_63:40; -+ uint64_t fpf_wr:12; -+ uint64_t fpf_rd:12; -+ } s; -+ struct cvmx_fpa_fpf0_marks_s cn38xx; -+ struct cvmx_fpa_fpf0_marks_s cn38xxp2; -+ struct cvmx_fpa_fpf0_marks_s cn56xx; -+ struct cvmx_fpa_fpf0_marks_s cn56xxp1; -+ struct cvmx_fpa_fpf0_marks_s cn58xx; -+ struct cvmx_fpa_fpf0_marks_s cn58xxp1; -+}; -+ -+union cvmx_fpa_fpf0_size { -+ uint64_t u64; -+ struct cvmx_fpa_fpf0_size_s { -+ uint64_t reserved_12_63:52; -+ uint64_t fpf_siz:12; -+ } s; -+ struct cvmx_fpa_fpf0_size_s cn38xx; -+ struct cvmx_fpa_fpf0_size_s cn38xxp2; -+ struct cvmx_fpa_fpf0_size_s cn56xx; -+ struct cvmx_fpa_fpf0_size_s cn56xxp1; -+ struct cvmx_fpa_fpf0_size_s cn58xx; -+ struct cvmx_fpa_fpf0_size_s cn58xxp1; -+}; -+ -+union cvmx_fpa_int_enb { -+ uint64_t u64; -+ struct cvmx_fpa_int_enb_s { -+ uint64_t reserved_28_63:36; -+ uint64_t q7_perr:1; -+ uint64_t q7_coff:1; -+ uint64_t q7_und:1; -+ uint64_t q6_perr:1; -+ uint64_t q6_coff:1; -+ uint64_t q6_und:1; -+ uint64_t q5_perr:1; -+ uint64_t q5_coff:1; -+ uint64_t q5_und:1; -+ uint64_t q4_perr:1; -+ uint64_t q4_coff:1; -+ uint64_t q4_und:1; -+ uint64_t q3_perr:1; -+ uint64_t q3_coff:1; -+ uint64_t q3_und:1; -+ uint64_t q2_perr:1; -+ uint64_t q2_coff:1; -+ uint64_t q2_und:1; -+ uint64_t q1_perr:1; -+ uint64_t q1_coff:1; -+ uint64_t q1_und:1; -+ uint64_t q0_perr:1; -+ uint64_t q0_coff:1; -+ uint64_t q0_und:1; -+ uint64_t fed1_dbe:1; -+ uint64_t fed1_sbe:1; -+ uint64_t fed0_dbe:1; -+ uint64_t fed0_sbe:1; -+ } s; -+ struct cvmx_fpa_int_enb_s cn30xx; -+ struct cvmx_fpa_int_enb_s cn31xx; -+ struct cvmx_fpa_int_enb_s cn38xx; -+ struct cvmx_fpa_int_enb_s cn38xxp2; -+ struct cvmx_fpa_int_enb_s cn50xx; -+ struct cvmx_fpa_int_enb_s cn52xx; -+ struct cvmx_fpa_int_enb_s cn52xxp1; -+ struct cvmx_fpa_int_enb_s cn56xx; -+ struct cvmx_fpa_int_enb_s cn56xxp1; -+ struct cvmx_fpa_int_enb_s cn58xx; -+ struct cvmx_fpa_int_enb_s cn58xxp1; -+}; -+ -+union cvmx_fpa_int_sum { -+ uint64_t u64; -+ struct cvmx_fpa_int_sum_s { -+ uint64_t reserved_28_63:36; -+ uint64_t q7_perr:1; -+ uint64_t q7_coff:1; -+ uint64_t q7_und:1; -+ uint64_t q6_perr:1; -+ uint64_t q6_coff:1; -+ uint64_t q6_und:1; -+ uint64_t q5_perr:1; -+ uint64_t q5_coff:1; -+ uint64_t q5_und:1; -+ uint64_t q4_perr:1; -+ uint64_t q4_coff:1; -+ uint64_t q4_und:1; -+ uint64_t q3_perr:1; -+ uint64_t q3_coff:1; -+ uint64_t q3_und:1; -+ uint64_t q2_perr:1; -+ uint64_t q2_coff:1; -+ uint64_t q2_und:1; -+ uint64_t q1_perr:1; -+ uint64_t q1_coff:1; -+ uint64_t q1_und:1; -+ uint64_t q0_perr:1; -+ uint64_t q0_coff:1; -+ uint64_t q0_und:1; -+ uint64_t fed1_dbe:1; -+ uint64_t fed1_sbe:1; -+ uint64_t fed0_dbe:1; -+ uint64_t fed0_sbe:1; -+ } s; -+ struct cvmx_fpa_int_sum_s cn30xx; -+ struct cvmx_fpa_int_sum_s cn31xx; -+ struct cvmx_fpa_int_sum_s cn38xx; -+ struct cvmx_fpa_int_sum_s cn38xxp2; -+ struct cvmx_fpa_int_sum_s cn50xx; -+ struct cvmx_fpa_int_sum_s cn52xx; -+ struct cvmx_fpa_int_sum_s cn52xxp1; -+ struct cvmx_fpa_int_sum_s cn56xx; -+ struct cvmx_fpa_int_sum_s cn56xxp1; -+ struct cvmx_fpa_int_sum_s cn58xx; -+ struct cvmx_fpa_int_sum_s cn58xxp1; -+}; -+ -+union cvmx_fpa_quex_available { -+ uint64_t u64; -+ struct cvmx_fpa_quex_available_s { -+ uint64_t reserved_29_63:35; -+ uint64_t que_siz:29; -+ } s; -+ struct cvmx_fpa_quex_available_s cn30xx; -+ struct cvmx_fpa_quex_available_s cn31xx; -+ struct cvmx_fpa_quex_available_s cn38xx; -+ struct cvmx_fpa_quex_available_s cn38xxp2; -+ struct cvmx_fpa_quex_available_s cn50xx; -+ struct cvmx_fpa_quex_available_s cn52xx; -+ struct cvmx_fpa_quex_available_s cn52xxp1; -+ struct cvmx_fpa_quex_available_s cn56xx; -+ struct cvmx_fpa_quex_available_s cn56xxp1; -+ struct cvmx_fpa_quex_available_s cn58xx; -+ struct cvmx_fpa_quex_available_s cn58xxp1; -+}; -+ -+union cvmx_fpa_quex_page_index { -+ uint64_t u64; -+ struct cvmx_fpa_quex_page_index_s { -+ uint64_t reserved_25_63:39; -+ uint64_t pg_num:25; -+ } s; -+ struct cvmx_fpa_quex_page_index_s cn30xx; -+ struct cvmx_fpa_quex_page_index_s cn31xx; -+ struct cvmx_fpa_quex_page_index_s cn38xx; -+ struct cvmx_fpa_quex_page_index_s cn38xxp2; -+ struct cvmx_fpa_quex_page_index_s cn50xx; -+ struct cvmx_fpa_quex_page_index_s cn52xx; -+ struct cvmx_fpa_quex_page_index_s cn52xxp1; -+ struct cvmx_fpa_quex_page_index_s cn56xx; -+ struct cvmx_fpa_quex_page_index_s cn56xxp1; -+ struct cvmx_fpa_quex_page_index_s cn58xx; -+ struct cvmx_fpa_quex_page_index_s cn58xxp1; -+}; -+ -+union cvmx_fpa_que_act { -+ uint64_t u64; -+ struct cvmx_fpa_que_act_s { -+ uint64_t reserved_29_63:35; -+ uint64_t act_que:3; -+ uint64_t act_indx:26; -+ } s; -+ struct cvmx_fpa_que_act_s cn30xx; -+ struct cvmx_fpa_que_act_s cn31xx; -+ struct cvmx_fpa_que_act_s cn38xx; -+ struct cvmx_fpa_que_act_s cn38xxp2; -+ struct cvmx_fpa_que_act_s cn50xx; -+ struct cvmx_fpa_que_act_s cn52xx; -+ struct cvmx_fpa_que_act_s cn52xxp1; -+ struct cvmx_fpa_que_act_s cn56xx; -+ struct cvmx_fpa_que_act_s cn56xxp1; -+ struct cvmx_fpa_que_act_s cn58xx; -+ struct cvmx_fpa_que_act_s cn58xxp1; -+}; -+ -+union cvmx_fpa_que_exp { -+ uint64_t u64; -+ struct cvmx_fpa_que_exp_s { -+ uint64_t reserved_29_63:35; -+ uint64_t exp_que:3; -+ uint64_t exp_indx:26; -+ } s; -+ struct cvmx_fpa_que_exp_s cn30xx; -+ struct cvmx_fpa_que_exp_s cn31xx; -+ struct cvmx_fpa_que_exp_s cn38xx; -+ struct cvmx_fpa_que_exp_s cn38xxp2; -+ struct cvmx_fpa_que_exp_s cn50xx; -+ struct cvmx_fpa_que_exp_s cn52xx; -+ struct cvmx_fpa_que_exp_s cn52xxp1; -+ struct cvmx_fpa_que_exp_s cn56xx; -+ struct cvmx_fpa_que_exp_s cn56xxp1; -+ struct cvmx_fpa_que_exp_s cn58xx; -+ struct cvmx_fpa_que_exp_s cn58xxp1; -+}; -+ -+union cvmx_fpa_wart_ctl { -+ uint64_t u64; -+ struct cvmx_fpa_wart_ctl_s { -+ uint64_t reserved_16_63:48; -+ uint64_t ctl:16; -+ } s; -+ struct cvmx_fpa_wart_ctl_s cn30xx; -+ struct cvmx_fpa_wart_ctl_s cn31xx; -+ struct cvmx_fpa_wart_ctl_s cn38xx; -+ struct cvmx_fpa_wart_ctl_s cn38xxp2; -+ struct cvmx_fpa_wart_ctl_s cn50xx; -+ struct cvmx_fpa_wart_ctl_s cn52xx; -+ struct cvmx_fpa_wart_ctl_s cn52xxp1; -+ struct cvmx_fpa_wart_ctl_s cn56xx; -+ struct cvmx_fpa_wart_ctl_s cn56xxp1; -+ struct cvmx_fpa_wart_ctl_s cn58xx; -+ struct cvmx_fpa_wart_ctl_s cn58xxp1; -+}; -+ -+union cvmx_fpa_wart_status { -+ uint64_t u64; -+ struct cvmx_fpa_wart_status_s { -+ uint64_t reserved_32_63:32; -+ uint64_t status:32; -+ } s; -+ struct cvmx_fpa_wart_status_s cn30xx; -+ struct cvmx_fpa_wart_status_s cn31xx; -+ struct cvmx_fpa_wart_status_s cn38xx; -+ struct cvmx_fpa_wart_status_s cn38xxp2; -+ struct cvmx_fpa_wart_status_s cn50xx; -+ struct cvmx_fpa_wart_status_s cn52xx; -+ struct cvmx_fpa_wart_status_s cn52xxp1; -+ struct cvmx_fpa_wart_status_s cn56xx; -+ struct cvmx_fpa_wart_status_s cn56xxp1; -+ struct cvmx_fpa_wart_status_s cn58xx; -+ struct cvmx_fpa_wart_status_s cn58xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-fpa.c -@@ -0,0 +1,183 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * @file -+ * -+ * Support library for the hardware Free Pool Allocator. -+ * -+ * -+ */ -+ -+#include "cvmx-config.h" -+#include "cvmx.h" -+#include "cvmx-fpa.h" -+#include "cvmx-ipd.h" -+ -+/** -+ * Current state of all the pools. Use access functions -+ * instead of using it directly. -+ */ -+CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS]; -+ -+/** -+ * Setup a FPA pool to control a new block of memory. The -+ * buffer pointer must be a physical address. -+ * -+ * @pool: Pool to initialize -+ * 0 <= pool < 8 -+ * @name: Constant character string to name this pool. -+ * String is not copied. -+ * @buffer: Pointer to the block of memory to use. This must be -+ * accessable by all processors and external hardware. -+ * @block_size: Size for each block controlled by the FPA -+ * @num_blocks: Number of blocks -+ * -+ * Returns 0 on Success, -+ * -1 on failure -+ */ -+int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer, -+ uint64_t block_size, uint64_t num_blocks) -+{ -+ char *ptr; -+ if (!buffer) { -+ cvmx_dprintf -+ ("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n"); -+ return -1; -+ } -+ if (pool >= CVMX_FPA_NUM_POOLS) { -+ cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n"); -+ return -1; -+ } -+ -+ if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) { -+ cvmx_dprintf -+ ("ERROR: cvmx_fpa_setup_pool: Block size too small.\n"); -+ return -1; -+ } -+ -+ if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT - 1)) != 0) { -+ cvmx_dprintf -+ ("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n"); -+ return -1; -+ } -+ -+ cvmx_fpa_pool_info[pool].name = name; -+ cvmx_fpa_pool_info[pool].size = block_size; -+ cvmx_fpa_pool_info[pool].starting_element_count = num_blocks; -+ cvmx_fpa_pool_info[pool].base = buffer; -+ -+ ptr = (char *)buffer; -+ while (num_blocks--) { -+ cvmx_fpa_free(ptr, pool, 0); -+ ptr += block_size; -+ } -+ return 0; -+} -+ -+/** -+ * Shutdown a Memory pool and validate that it had all of -+ * the buffers originally placed in it. -+ * -+ * @pool: Pool to shutdown -+ * Returns Zero on success -+ * - Positive is count of missing buffers -+ * - Negative is too many buffers or corrupted pointers -+ */ -+uint64_t cvmx_fpa_shutdown_pool(uint64_t pool) -+{ -+ uint64_t errors = 0; -+ uint64_t count = 0; -+ uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base); -+ uint64_t finish = -+ base + -+ cvmx_fpa_pool_info[pool].size * -+ cvmx_fpa_pool_info[pool].starting_element_count; -+ void *ptr; -+ uint64_t address; -+ -+ count = 0; -+ do { -+ ptr = cvmx_fpa_alloc(pool); -+ if (ptr) -+ address = cvmx_ptr_to_phys(ptr); -+ else -+ address = 0; -+ if (address) { -+ if ((address >= base) && (address < finish) && -+ (((address - -+ base) % cvmx_fpa_pool_info[pool].size) == 0)) { -+ count++; -+ } else { -+ cvmx_dprintf -+ ("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n", -+ (unsigned long long)address, -+ cvmx_fpa_pool_info[pool].name, (int)pool); -+ errors++; -+ } -+ } -+ } while (address); -+ -+#ifdef CVMX_ENABLE_PKO_FUNCTIONS -+ if (pool == 0) -+ cvmx_ipd_free_ptr(); -+#endif -+ -+ if (errors) { -+ cvmx_dprintf -+ ("ERROR: cvmx_fpa_shutdown_pool: Pool %s(%d) started at 0x%llx, ended at 0x%llx, with a step of 0x%llx\n", -+ cvmx_fpa_pool_info[pool].name, (int)pool, -+ (unsigned long long)base, (unsigned long long)finish, -+ (unsigned long long)cvmx_fpa_pool_info[pool].size); -+ return -errors; -+ } else -+ return 0; -+} -+ -+uint64_t cvmx_fpa_get_block_size(uint64_t pool) -+{ -+ switch (pool) { -+ case 0: -+ return CVMX_FPA_POOL_0_SIZE; -+ case 1: -+ return CVMX_FPA_POOL_1_SIZE; -+ case 2: -+ return CVMX_FPA_POOL_2_SIZE; -+ case 3: -+ return CVMX_FPA_POOL_3_SIZE; -+ case 4: -+ return CVMX_FPA_POOL_4_SIZE; -+ case 5: -+ return CVMX_FPA_POOL_5_SIZE; -+ case 6: -+ return CVMX_FPA_POOL_6_SIZE; -+ case 7: -+ return CVMX_FPA_POOL_7_SIZE; -+ default: -+ return 0; -+ } -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-fpa.h -@@ -0,0 +1,299 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * @file -+ * -+ * Interface to the hardware Free Pool Allocator. -+ * -+ * -+ */ -+ -+#ifndef __CVMX_FPA_H__ -+#define __CVMX_FPA_H__ -+ -+#include "cvmx-address.h" -+#include "cvmx-fpa-defs.h" -+ -+#define CVMX_FPA_NUM_POOLS 8 -+#define CVMX_FPA_MIN_BLOCK_SIZE 128 -+#define CVMX_FPA_ALIGNMENT 128 -+ -+/** -+ * Structure describing the data format used for stores to the FPA. -+ */ -+typedef union { -+ uint64_t u64; -+ struct { -+ /* -+ * the (64-bit word) location in scratchpad to write -+ * to (if len != 0) -+ */ -+ uint64_t scraddr:8; -+ /* the number of words in the response (0 => no response) */ -+ uint64_t len:8; -+ /* the ID of the device on the non-coherent bus */ -+ uint64_t did:8; -+ /* -+ * the address that will appear in the first tick on -+ * the NCB bus. -+ */ -+ uint64_t addr:40; -+ } s; -+} cvmx_fpa_iobdma_data_t; -+ -+/** -+ * Structure describing the current state of a FPA pool. -+ */ -+typedef struct { -+ /* Name it was created under */ -+ const char *name; -+ /* Size of each block */ -+ uint64_t size; -+ /* The base memory address of whole block */ -+ void *base; -+ /* The number of elements in the pool at creation */ -+ uint64_t starting_element_count; -+} cvmx_fpa_pool_info_t; -+ -+/** -+ * Current state of all the pools. Use access functions -+ * instead of using it directly. -+ */ -+extern cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS]; -+ -+/* CSR typedefs have been moved to cvmx-csr-*.h */ -+ -+/** -+ * Return the name of the pool -+ * -+ * @pool: Pool to get the name of -+ * Returns The name -+ */ -+static inline const char *cvmx_fpa_get_name(uint64_t pool) -+{ -+ return cvmx_fpa_pool_info[pool].name; -+} -+ -+/** -+ * Return the base of the pool -+ * -+ * @pool: Pool to get the base of -+ * Returns The base -+ */ -+static inline void *cvmx_fpa_get_base(uint64_t pool) -+{ -+ return cvmx_fpa_pool_info[pool].base; -+} -+ -+/** -+ * Check if a pointer belongs to an FPA pool. Return non-zero -+ * if the supplied pointer is inside the memory controlled by -+ * an FPA pool. -+ * -+ * @pool: Pool to check -+ * @ptr: Pointer to check -+ * Returns Non-zero if pointer is in the pool. Zero if not -+ */ -+static inline int cvmx_fpa_is_member(uint64_t pool, void *ptr) -+{ -+ return ((ptr >= cvmx_fpa_pool_info[pool].base) && -+ ((char *)ptr < -+ ((char *)(cvmx_fpa_pool_info[pool].base)) + -+ cvmx_fpa_pool_info[pool].size * -+ cvmx_fpa_pool_info[pool].starting_element_count)); -+} -+ -+/** -+ * Enable the FPA for use. Must be performed after any CSR -+ * configuration but before any other FPA functions. -+ */ -+static inline void cvmx_fpa_enable(void) -+{ -+ union cvmx_fpa_ctl_status status; -+ -+ status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS); -+ if (status.s.enb) { -+ cvmx_dprintf -+ ("Warning: Enabling FPA when FPA already enabled.\n"); -+ } -+ -+ /* -+ * Do runtime check as we allow pass1 compiled code to run on -+ * pass2 chips. -+ */ -+ if (cvmx_octeon_is_pass1()) { -+ union cvmx_fpa_fpfx_marks marks; -+ int i; -+ for (i = 1; i < 8; i++) { -+ marks.u64 = -+ cvmx_read_csr(CVMX_FPA_FPF1_MARKS + (i - 1) * 8ull); -+ marks.s.fpf_wr = 0xe0; -+ cvmx_write_csr(CVMX_FPA_FPF1_MARKS + (i - 1) * 8ull, -+ marks.u64); -+ } -+ -+ /* Enforce a 10 cycle delay between config and enable */ -+ cvmx_wait(10); -+ } -+ -+ /* FIXME: CVMX_FPA_CTL_STATUS read is unmodelled */ -+ status.u64 = 0; -+ status.s.enb = 1; -+ cvmx_write_csr(CVMX_FPA_CTL_STATUS, status.u64); -+} -+ -+/** -+ * Get a new block from the FPA -+ * -+ * @pool: Pool to get the block from -+ * Returns Pointer to the block or NULL on failure -+ */ -+static inline void *cvmx_fpa_alloc(uint64_t pool) -+{ -+ uint64_t address = -+ cvmx_read_csr(CVMX_ADDR_DID(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool))); -+ if (address) -+ return cvmx_phys_to_ptr(address); -+ else -+ return NULL; -+} -+ -+/** -+ * Asynchronously get a new block from the FPA -+ * -+ * @scr_addr: Local scratch address to put response in. This is a byte address, -+ * but must be 8 byte aligned. -+ * @pool: Pool to get the block from -+ */ -+static inline void cvmx_fpa_async_alloc(uint64_t scr_addr, uint64_t pool) -+{ -+ cvmx_fpa_iobdma_data_t data; -+ -+ /* -+ * Hardware only uses 64 bit alligned locations, so convert -+ * from byte address to 64-bit index -+ */ -+ data.s.scraddr = scr_addr >> 3; -+ data.s.len = 1; -+ data.s.did = CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool); -+ data.s.addr = 0; -+ cvmx_send_single(data.u64); -+} -+ -+/** -+ * Free a block allocated with a FPA pool. Does NOT provide memory -+ * ordering in cases where the memory block was modified by the core. -+ * -+ * @ptr: Block to free -+ * @pool: Pool to put it in -+ * @num_cache_lines: -+ * Cache lines to invalidate -+ */ -+static inline void cvmx_fpa_free_nosync(void *ptr, uint64_t pool, -+ uint64_t num_cache_lines) -+{ -+ cvmx_addr_t newptr; -+ newptr.u64 = cvmx_ptr_to_phys(ptr); -+ newptr.sfilldidspace.didspace = -+ CVMX_ADDR_DIDSPACE(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool)); -+ /* Prevent GCC from reordering around free */ -+ barrier(); -+ /* value written is number of cache lines not written back */ -+ cvmx_write_io(newptr.u64, num_cache_lines); -+} -+ -+/** -+ * Free a block allocated with a FPA pool. Provides required memory -+ * ordering in cases where memory block was modified by core. -+ * -+ * @ptr: Block to free -+ * @pool: Pool to put it in -+ * @num_cache_lines: -+ * Cache lines to invalidate -+ */ -+static inline void cvmx_fpa_free(void *ptr, uint64_t pool, -+ uint64_t num_cache_lines) -+{ -+ cvmx_addr_t newptr; -+ newptr.u64 = cvmx_ptr_to_phys(ptr); -+ newptr.sfilldidspace.didspace = -+ CVMX_ADDR_DIDSPACE(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool)); -+ /* -+ * Make sure that any previous writes to memory go out before -+ * we free this buffer. This also serves as a barrier to -+ * prevent GCC from reordering operations to after the -+ * free. -+ */ -+ CVMX_SYNCWS; -+ /* value written is number of cache lines not written back */ -+ cvmx_write_io(newptr.u64, num_cache_lines); -+} -+ -+/** -+ * Setup a FPA pool to control a new block of memory. -+ * This can only be called once per pool. Make sure proper -+ * locking enforces this. -+ * -+ * @pool: Pool to initialize -+ * 0 <= pool < 8 -+ * @name: Constant character string to name this pool. -+ * String is not copied. -+ * @buffer: Pointer to the block of memory to use. This must be -+ * accessable by all processors and external hardware. -+ * @block_size: Size for each block controlled by the FPA -+ * @num_blocks: Number of blocks -+ * -+ * Returns 0 on Success, -+ * -1 on failure -+ */ -+extern int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer, -+ uint64_t block_size, uint64_t num_blocks); -+ -+/** -+ * Shutdown a Memory pool and validate that it had all of -+ * the buffers originally placed in it. This should only be -+ * called by one processor after all hardware has finished -+ * using the pool. -+ * -+ * @pool: Pool to shutdown -+ * Returns Zero on success -+ * - Positive is count of missing buffers -+ * - Negative is too many buffers or corrupted pointers -+ */ -+extern uint64_t cvmx_fpa_shutdown_pool(uint64_t pool); -+ -+/** -+ * Get the size of blocks controlled by the pool -+ * This is resolved to a constant at compile time. -+ * -+ * @pool: Pool to access -+ * Returns Size of the block in bytes -+ */ -+uint64_t cvmx_fpa_get_block_size(uint64_t pool); -+ -+#endif /* __CVM_FPA_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-gmxx-defs.h -@@ -0,0 +1,2529 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_GMXX_DEFS_H__ -+#define __CVMX_GMXX_DEFS_H__ -+ -+#define CVMX_GMXX_BAD_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000518ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_BIST(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000400ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_CLK_EN(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080007F0ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_HG2_CONTROL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000550ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_INF_MODE(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080007F8ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_NXA_ADR(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000510ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_PRTX_CBFC_CTL(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000580ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_PRTX_CFG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000010ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_ADR_CAM0(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000180ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_ADR_CAM1(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000188ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_ADR_CAM2(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000190ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_ADR_CAM3(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000198ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_ADR_CAM4(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080001A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_ADR_CAM5(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080001A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_ADR_CAM_EN(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000108ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_ADR_CTL(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000100ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_DECISION(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000040ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_FRM_CHK(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000020ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_FRM_CTL(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000018ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_FRM_MAX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000030ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_FRM_MIN(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000028ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_IFG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000058ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_INT_EN(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000008ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_INT_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000000ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_JABBER(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000038ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_PAUSE_DROP_TIME(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000068ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_RX_INBND(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000060ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_STATS_CTL(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000050ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_STATS_OCTS(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000088ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_STATS_OCTS_CTL(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000098ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_STATS_OCTS_DMAC(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080000A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_STATS_OCTS_DRP(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080000B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_STATS_PKTS(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000080ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_STATS_PKTS_BAD(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080000C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_STATS_PKTS_CTL(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000090ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_STATS_PKTS_DMAC(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080000A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_STATS_PKTS_DRP(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080000B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RXX_UDD_SKP(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000048ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RX_BP_DROPX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000420ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RX_BP_OFFX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000460ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RX_BP_ONX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000440ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RX_HG2_STATUS(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000548ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RX_PASS_EN(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080005F8ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RX_PASS_MAPX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000600ull + (((offset) & 15) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RX_PRTS(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000410ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RX_PRT_INFO(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080004E8ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RX_TX_STATUS(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080007E8ull + (((block_id) & 0) * 0x8000000ull)) -+#define CVMX_GMXX_RX_XAUI_BAD_COL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000538ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_RX_XAUI_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000530ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_SMACX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000230ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_STAT_BP(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000520ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_APPEND(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000218ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_BURST(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000228ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_CBFC_XOFF(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080005A0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_CBFC_XON(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080005C0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_CLK(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000208ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_CTL(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000270ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_MIN_PKT(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000240ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000248ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_PAUSE_PKT_TIME(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000238ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_PAUSE_TOGO(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000258ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_PAUSE_ZERO(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000260ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_SGMII_CTL(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000300ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_SLOT(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000220ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_SOFT_PAUSE(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000250ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_STAT0(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000280ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_STAT1(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000288ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_STAT2(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000290ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_STAT3(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000298ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_STAT4(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080002A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_STAT5(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080002A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_STAT6(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080002B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_STAT7(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080002B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_STAT8(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080002C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_STAT9(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080002C8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_STATS_CTL(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000268ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TXX_THRESH(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000210ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_BP(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080004D0ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_CLK_MSKX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000780ull + (((offset) & 1) * 8) + (((block_id) & 0) * 0x0ull)) -+#define CVMX_GMXX_TX_COL_ATTEMPT(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000498ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_CORRUPT(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080004D8ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_HG2_REG1(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000558ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_HG2_REG2(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000560ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_IFG(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000488ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_INT_EN(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000508ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_INT_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000500ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_JAM(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000490ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_LFSR(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080004F8ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_OVR_BP(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080004C8ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_PAUSE_PKT_DMAC(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080004A0ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_PAUSE_PKT_TYPE(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080004A8ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_PRTS(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000480ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_SPI_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080004C0ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_SPI_DRAIN(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080004E0ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_SPI_MAX(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080004B0ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_SPI_ROUNDX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000680ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_SPI_THRESH(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800080004B8ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_TX_XAUI_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000528ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_GMXX_XAUI_EXT_LOOPBACK(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180008000540ull + (((block_id) & 1) * 0x8000000ull)) -+ -+union cvmx_gmxx_bad_reg { -+ uint64_t u64; -+ struct cvmx_gmxx_bad_reg_s { -+ uint64_t reserved_31_63:33; -+ uint64_t inb_nxa:4; -+ uint64_t statovr:1; -+ uint64_t loststat:4; -+ uint64_t reserved_18_21:4; -+ uint64_t out_ovr:16; -+ uint64_t ncb_ovr:1; -+ uint64_t out_col:1; -+ } s; -+ struct cvmx_gmxx_bad_reg_cn30xx { -+ uint64_t reserved_31_63:33; -+ uint64_t inb_nxa:4; -+ uint64_t statovr:1; -+ uint64_t reserved_25_25:1; -+ uint64_t loststat:3; -+ uint64_t reserved_5_21:17; -+ uint64_t out_ovr:3; -+ uint64_t reserved_0_1:2; -+ } cn30xx; -+ struct cvmx_gmxx_bad_reg_cn30xx cn31xx; -+ struct cvmx_gmxx_bad_reg_s cn38xx; -+ struct cvmx_gmxx_bad_reg_s cn38xxp2; -+ struct cvmx_gmxx_bad_reg_cn30xx cn50xx; -+ struct cvmx_gmxx_bad_reg_cn52xx { -+ uint64_t reserved_31_63:33; -+ uint64_t inb_nxa:4; -+ uint64_t statovr:1; -+ uint64_t loststat:4; -+ uint64_t reserved_6_21:16; -+ uint64_t out_ovr:4; -+ uint64_t reserved_0_1:2; -+ } cn52xx; -+ struct cvmx_gmxx_bad_reg_cn52xx cn52xxp1; -+ struct cvmx_gmxx_bad_reg_cn52xx cn56xx; -+ struct cvmx_gmxx_bad_reg_cn52xx cn56xxp1; -+ struct cvmx_gmxx_bad_reg_s cn58xx; -+ struct cvmx_gmxx_bad_reg_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_bist { -+ uint64_t u64; -+ struct cvmx_gmxx_bist_s { -+ uint64_t reserved_17_63:47; -+ uint64_t status:17; -+ } s; -+ struct cvmx_gmxx_bist_cn30xx { -+ uint64_t reserved_10_63:54; -+ uint64_t status:10; -+ } cn30xx; -+ struct cvmx_gmxx_bist_cn30xx cn31xx; -+ struct cvmx_gmxx_bist_cn30xx cn38xx; -+ struct cvmx_gmxx_bist_cn30xx cn38xxp2; -+ struct cvmx_gmxx_bist_cn50xx { -+ uint64_t reserved_12_63:52; -+ uint64_t status:12; -+ } cn50xx; -+ struct cvmx_gmxx_bist_cn52xx { -+ uint64_t reserved_16_63:48; -+ uint64_t status:16; -+ } cn52xx; -+ struct cvmx_gmxx_bist_cn52xx cn52xxp1; -+ struct cvmx_gmxx_bist_cn52xx cn56xx; -+ struct cvmx_gmxx_bist_cn52xx cn56xxp1; -+ struct cvmx_gmxx_bist_s cn58xx; -+ struct cvmx_gmxx_bist_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_clk_en { -+ uint64_t u64; -+ struct cvmx_gmxx_clk_en_s { -+ uint64_t reserved_1_63:63; -+ uint64_t clk_en:1; -+ } s; -+ struct cvmx_gmxx_clk_en_s cn52xx; -+ struct cvmx_gmxx_clk_en_s cn52xxp1; -+ struct cvmx_gmxx_clk_en_s cn56xx; -+ struct cvmx_gmxx_clk_en_s cn56xxp1; -+}; -+ -+union cvmx_gmxx_hg2_control { -+ uint64_t u64; -+ struct cvmx_gmxx_hg2_control_s { -+ uint64_t reserved_19_63:45; -+ uint64_t hg2tx_en:1; -+ uint64_t hg2rx_en:1; -+ uint64_t phys_en:1; -+ uint64_t logl_en:16; -+ } s; -+ struct cvmx_gmxx_hg2_control_s cn52xx; -+ struct cvmx_gmxx_hg2_control_s cn52xxp1; -+ struct cvmx_gmxx_hg2_control_s cn56xx; -+}; -+ -+union cvmx_gmxx_inf_mode { -+ uint64_t u64; -+ struct cvmx_gmxx_inf_mode_s { -+ uint64_t reserved_10_63:54; -+ uint64_t speed:2; -+ uint64_t reserved_6_7:2; -+ uint64_t mode:2; -+ uint64_t reserved_3_3:1; -+ uint64_t p0mii:1; -+ uint64_t en:1; -+ uint64_t type:1; -+ } s; -+ struct cvmx_gmxx_inf_mode_cn30xx { -+ uint64_t reserved_3_63:61; -+ uint64_t p0mii:1; -+ uint64_t en:1; -+ uint64_t type:1; -+ } cn30xx; -+ struct cvmx_gmxx_inf_mode_cn31xx { -+ uint64_t reserved_2_63:62; -+ uint64_t en:1; -+ uint64_t type:1; -+ } cn31xx; -+ struct cvmx_gmxx_inf_mode_cn31xx cn38xx; -+ struct cvmx_gmxx_inf_mode_cn31xx cn38xxp2; -+ struct cvmx_gmxx_inf_mode_cn30xx cn50xx; -+ struct cvmx_gmxx_inf_mode_cn52xx { -+ uint64_t reserved_10_63:54; -+ uint64_t speed:2; -+ uint64_t reserved_6_7:2; -+ uint64_t mode:2; -+ uint64_t reserved_2_3:2; -+ uint64_t en:1; -+ uint64_t type:1; -+ } cn52xx; -+ struct cvmx_gmxx_inf_mode_cn52xx cn52xxp1; -+ struct cvmx_gmxx_inf_mode_cn52xx cn56xx; -+ struct cvmx_gmxx_inf_mode_cn52xx cn56xxp1; -+ struct cvmx_gmxx_inf_mode_cn31xx cn58xx; -+ struct cvmx_gmxx_inf_mode_cn31xx cn58xxp1; -+}; -+ -+union cvmx_gmxx_nxa_adr { -+ uint64_t u64; -+ struct cvmx_gmxx_nxa_adr_s { -+ uint64_t reserved_6_63:58; -+ uint64_t prt:6; -+ } s; -+ struct cvmx_gmxx_nxa_adr_s cn30xx; -+ struct cvmx_gmxx_nxa_adr_s cn31xx; -+ struct cvmx_gmxx_nxa_adr_s cn38xx; -+ struct cvmx_gmxx_nxa_adr_s cn38xxp2; -+ struct cvmx_gmxx_nxa_adr_s cn50xx; -+ struct cvmx_gmxx_nxa_adr_s cn52xx; -+ struct cvmx_gmxx_nxa_adr_s cn52xxp1; -+ struct cvmx_gmxx_nxa_adr_s cn56xx; -+ struct cvmx_gmxx_nxa_adr_s cn56xxp1; -+ struct cvmx_gmxx_nxa_adr_s cn58xx; -+ struct cvmx_gmxx_nxa_adr_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_prtx_cbfc_ctl { -+ uint64_t u64; -+ struct cvmx_gmxx_prtx_cbfc_ctl_s { -+ uint64_t phys_en:16; -+ uint64_t logl_en:16; -+ uint64_t phys_bp:16; -+ uint64_t reserved_4_15:12; -+ uint64_t bck_en:1; -+ uint64_t drp_en:1; -+ uint64_t tx_en:1; -+ uint64_t rx_en:1; -+ } s; -+ struct cvmx_gmxx_prtx_cbfc_ctl_s cn52xx; -+ struct cvmx_gmxx_prtx_cbfc_ctl_s cn56xx; -+}; -+ -+union cvmx_gmxx_prtx_cfg { -+ uint64_t u64; -+ struct cvmx_gmxx_prtx_cfg_s { -+ uint64_t reserved_14_63:50; -+ uint64_t tx_idle:1; -+ uint64_t rx_idle:1; -+ uint64_t reserved_9_11:3; -+ uint64_t speed_msb:1; -+ uint64_t reserved_4_7:4; -+ uint64_t slottime:1; -+ uint64_t duplex:1; -+ uint64_t speed:1; -+ uint64_t en:1; -+ } s; -+ struct cvmx_gmxx_prtx_cfg_cn30xx { -+ uint64_t reserved_4_63:60; -+ uint64_t slottime:1; -+ uint64_t duplex:1; -+ uint64_t speed:1; -+ uint64_t en:1; -+ } cn30xx; -+ struct cvmx_gmxx_prtx_cfg_cn30xx cn31xx; -+ struct cvmx_gmxx_prtx_cfg_cn30xx cn38xx; -+ struct cvmx_gmxx_prtx_cfg_cn30xx cn38xxp2; -+ struct cvmx_gmxx_prtx_cfg_cn30xx cn50xx; -+ struct cvmx_gmxx_prtx_cfg_s cn52xx; -+ struct cvmx_gmxx_prtx_cfg_s cn52xxp1; -+ struct cvmx_gmxx_prtx_cfg_s cn56xx; -+ struct cvmx_gmxx_prtx_cfg_s cn56xxp1; -+ struct cvmx_gmxx_prtx_cfg_cn30xx cn58xx; -+ struct cvmx_gmxx_prtx_cfg_cn30xx cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_adr_cam0 { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_adr_cam0_s { -+ uint64_t adr:64; -+ } s; -+ struct cvmx_gmxx_rxx_adr_cam0_s cn30xx; -+ struct cvmx_gmxx_rxx_adr_cam0_s cn31xx; -+ struct cvmx_gmxx_rxx_adr_cam0_s cn38xx; -+ struct cvmx_gmxx_rxx_adr_cam0_s cn38xxp2; -+ struct cvmx_gmxx_rxx_adr_cam0_s cn50xx; -+ struct cvmx_gmxx_rxx_adr_cam0_s cn52xx; -+ struct cvmx_gmxx_rxx_adr_cam0_s cn52xxp1; -+ struct cvmx_gmxx_rxx_adr_cam0_s cn56xx; -+ struct cvmx_gmxx_rxx_adr_cam0_s cn56xxp1; -+ struct cvmx_gmxx_rxx_adr_cam0_s cn58xx; -+ struct cvmx_gmxx_rxx_adr_cam0_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_adr_cam1 { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_adr_cam1_s { -+ uint64_t adr:64; -+ } s; -+ struct cvmx_gmxx_rxx_adr_cam1_s cn30xx; -+ struct cvmx_gmxx_rxx_adr_cam1_s cn31xx; -+ struct cvmx_gmxx_rxx_adr_cam1_s cn38xx; -+ struct cvmx_gmxx_rxx_adr_cam1_s cn38xxp2; -+ struct cvmx_gmxx_rxx_adr_cam1_s cn50xx; -+ struct cvmx_gmxx_rxx_adr_cam1_s cn52xx; -+ struct cvmx_gmxx_rxx_adr_cam1_s cn52xxp1; -+ struct cvmx_gmxx_rxx_adr_cam1_s cn56xx; -+ struct cvmx_gmxx_rxx_adr_cam1_s cn56xxp1; -+ struct cvmx_gmxx_rxx_adr_cam1_s cn58xx; -+ struct cvmx_gmxx_rxx_adr_cam1_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_adr_cam2 { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_adr_cam2_s { -+ uint64_t adr:64; -+ } s; -+ struct cvmx_gmxx_rxx_adr_cam2_s cn30xx; -+ struct cvmx_gmxx_rxx_adr_cam2_s cn31xx; -+ struct cvmx_gmxx_rxx_adr_cam2_s cn38xx; -+ struct cvmx_gmxx_rxx_adr_cam2_s cn38xxp2; -+ struct cvmx_gmxx_rxx_adr_cam2_s cn50xx; -+ struct cvmx_gmxx_rxx_adr_cam2_s cn52xx; -+ struct cvmx_gmxx_rxx_adr_cam2_s cn52xxp1; -+ struct cvmx_gmxx_rxx_adr_cam2_s cn56xx; -+ struct cvmx_gmxx_rxx_adr_cam2_s cn56xxp1; -+ struct cvmx_gmxx_rxx_adr_cam2_s cn58xx; -+ struct cvmx_gmxx_rxx_adr_cam2_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_adr_cam3 { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_adr_cam3_s { -+ uint64_t adr:64; -+ } s; -+ struct cvmx_gmxx_rxx_adr_cam3_s cn30xx; -+ struct cvmx_gmxx_rxx_adr_cam3_s cn31xx; -+ struct cvmx_gmxx_rxx_adr_cam3_s cn38xx; -+ struct cvmx_gmxx_rxx_adr_cam3_s cn38xxp2; -+ struct cvmx_gmxx_rxx_adr_cam3_s cn50xx; -+ struct cvmx_gmxx_rxx_adr_cam3_s cn52xx; -+ struct cvmx_gmxx_rxx_adr_cam3_s cn52xxp1; -+ struct cvmx_gmxx_rxx_adr_cam3_s cn56xx; -+ struct cvmx_gmxx_rxx_adr_cam3_s cn56xxp1; -+ struct cvmx_gmxx_rxx_adr_cam3_s cn58xx; -+ struct cvmx_gmxx_rxx_adr_cam3_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_adr_cam4 { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_adr_cam4_s { -+ uint64_t adr:64; -+ } s; -+ struct cvmx_gmxx_rxx_adr_cam4_s cn30xx; -+ struct cvmx_gmxx_rxx_adr_cam4_s cn31xx; -+ struct cvmx_gmxx_rxx_adr_cam4_s cn38xx; -+ struct cvmx_gmxx_rxx_adr_cam4_s cn38xxp2; -+ struct cvmx_gmxx_rxx_adr_cam4_s cn50xx; -+ struct cvmx_gmxx_rxx_adr_cam4_s cn52xx; -+ struct cvmx_gmxx_rxx_adr_cam4_s cn52xxp1; -+ struct cvmx_gmxx_rxx_adr_cam4_s cn56xx; -+ struct cvmx_gmxx_rxx_adr_cam4_s cn56xxp1; -+ struct cvmx_gmxx_rxx_adr_cam4_s cn58xx; -+ struct cvmx_gmxx_rxx_adr_cam4_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_adr_cam5 { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_adr_cam5_s { -+ uint64_t adr:64; -+ } s; -+ struct cvmx_gmxx_rxx_adr_cam5_s cn30xx; -+ struct cvmx_gmxx_rxx_adr_cam5_s cn31xx; -+ struct cvmx_gmxx_rxx_adr_cam5_s cn38xx; -+ struct cvmx_gmxx_rxx_adr_cam5_s cn38xxp2; -+ struct cvmx_gmxx_rxx_adr_cam5_s cn50xx; -+ struct cvmx_gmxx_rxx_adr_cam5_s cn52xx; -+ struct cvmx_gmxx_rxx_adr_cam5_s cn52xxp1; -+ struct cvmx_gmxx_rxx_adr_cam5_s cn56xx; -+ struct cvmx_gmxx_rxx_adr_cam5_s cn56xxp1; -+ struct cvmx_gmxx_rxx_adr_cam5_s cn58xx; -+ struct cvmx_gmxx_rxx_adr_cam5_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_adr_cam_en { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_adr_cam_en_s { -+ uint64_t reserved_8_63:56; -+ uint64_t en:8; -+ } s; -+ struct cvmx_gmxx_rxx_adr_cam_en_s cn30xx; -+ struct cvmx_gmxx_rxx_adr_cam_en_s cn31xx; -+ struct cvmx_gmxx_rxx_adr_cam_en_s cn38xx; -+ struct cvmx_gmxx_rxx_adr_cam_en_s cn38xxp2; -+ struct cvmx_gmxx_rxx_adr_cam_en_s cn50xx; -+ struct cvmx_gmxx_rxx_adr_cam_en_s cn52xx; -+ struct cvmx_gmxx_rxx_adr_cam_en_s cn52xxp1; -+ struct cvmx_gmxx_rxx_adr_cam_en_s cn56xx; -+ struct cvmx_gmxx_rxx_adr_cam_en_s cn56xxp1; -+ struct cvmx_gmxx_rxx_adr_cam_en_s cn58xx; -+ struct cvmx_gmxx_rxx_adr_cam_en_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_adr_ctl { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_adr_ctl_s { -+ uint64_t reserved_4_63:60; -+ uint64_t cam_mode:1; -+ uint64_t mcst:2; -+ uint64_t bcst:1; -+ } s; -+ struct cvmx_gmxx_rxx_adr_ctl_s cn30xx; -+ struct cvmx_gmxx_rxx_adr_ctl_s cn31xx; -+ struct cvmx_gmxx_rxx_adr_ctl_s cn38xx; -+ struct cvmx_gmxx_rxx_adr_ctl_s cn38xxp2; -+ struct cvmx_gmxx_rxx_adr_ctl_s cn50xx; -+ struct cvmx_gmxx_rxx_adr_ctl_s cn52xx; -+ struct cvmx_gmxx_rxx_adr_ctl_s cn52xxp1; -+ struct cvmx_gmxx_rxx_adr_ctl_s cn56xx; -+ struct cvmx_gmxx_rxx_adr_ctl_s cn56xxp1; -+ struct cvmx_gmxx_rxx_adr_ctl_s cn58xx; -+ struct cvmx_gmxx_rxx_adr_ctl_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_decision { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_decision_s { -+ uint64_t reserved_5_63:59; -+ uint64_t cnt:5; -+ } s; -+ struct cvmx_gmxx_rxx_decision_s cn30xx; -+ struct cvmx_gmxx_rxx_decision_s cn31xx; -+ struct cvmx_gmxx_rxx_decision_s cn38xx; -+ struct cvmx_gmxx_rxx_decision_s cn38xxp2; -+ struct cvmx_gmxx_rxx_decision_s cn50xx; -+ struct cvmx_gmxx_rxx_decision_s cn52xx; -+ struct cvmx_gmxx_rxx_decision_s cn52xxp1; -+ struct cvmx_gmxx_rxx_decision_s cn56xx; -+ struct cvmx_gmxx_rxx_decision_s cn56xxp1; -+ struct cvmx_gmxx_rxx_decision_s cn58xx; -+ struct cvmx_gmxx_rxx_decision_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_frm_chk { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_frm_chk_s { -+ uint64_t reserved_10_63:54; -+ uint64_t niberr:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t lenerr:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t maxerr:1; -+ uint64_t carext:1; -+ uint64_t minerr:1; -+ } s; -+ struct cvmx_gmxx_rxx_frm_chk_s cn30xx; -+ struct cvmx_gmxx_rxx_frm_chk_s cn31xx; -+ struct cvmx_gmxx_rxx_frm_chk_s cn38xx; -+ struct cvmx_gmxx_rxx_frm_chk_s cn38xxp2; -+ struct cvmx_gmxx_rxx_frm_chk_cn50xx { -+ uint64_t reserved_10_63:54; -+ uint64_t niberr:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t reserved_6_6:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t reserved_2_2:1; -+ uint64_t carext:1; -+ uint64_t reserved_0_0:1; -+ } cn50xx; -+ struct cvmx_gmxx_rxx_frm_chk_cn52xx { -+ uint64_t reserved_9_63:55; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t reserved_5_6:2; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t reserved_2_2:1; -+ uint64_t carext:1; -+ uint64_t reserved_0_0:1; -+ } cn52xx; -+ struct cvmx_gmxx_rxx_frm_chk_cn52xx cn52xxp1; -+ struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xx; -+ struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xxp1; -+ struct cvmx_gmxx_rxx_frm_chk_s cn58xx; -+ struct cvmx_gmxx_rxx_frm_chk_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_frm_ctl { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_frm_ctl_s { -+ uint64_t reserved_11_63:53; -+ uint64_t null_dis:1; -+ uint64_t pre_align:1; -+ uint64_t pad_len:1; -+ uint64_t vlan_len:1; -+ uint64_t pre_free:1; -+ uint64_t ctl_smac:1; -+ uint64_t ctl_mcst:1; -+ uint64_t ctl_bck:1; -+ uint64_t ctl_drp:1; -+ uint64_t pre_strp:1; -+ uint64_t pre_chk:1; -+ } s; -+ struct cvmx_gmxx_rxx_frm_ctl_cn30xx { -+ uint64_t reserved_9_63:55; -+ uint64_t pad_len:1; -+ uint64_t vlan_len:1; -+ uint64_t pre_free:1; -+ uint64_t ctl_smac:1; -+ uint64_t ctl_mcst:1; -+ uint64_t ctl_bck:1; -+ uint64_t ctl_drp:1; -+ uint64_t pre_strp:1; -+ uint64_t pre_chk:1; -+ } cn30xx; -+ struct cvmx_gmxx_rxx_frm_ctl_cn31xx { -+ uint64_t reserved_8_63:56; -+ uint64_t vlan_len:1; -+ uint64_t pre_free:1; -+ uint64_t ctl_smac:1; -+ uint64_t ctl_mcst:1; -+ uint64_t ctl_bck:1; -+ uint64_t ctl_drp:1; -+ uint64_t pre_strp:1; -+ uint64_t pre_chk:1; -+ } cn31xx; -+ struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn38xx; -+ struct cvmx_gmxx_rxx_frm_ctl_cn31xx cn38xxp2; -+ struct cvmx_gmxx_rxx_frm_ctl_cn50xx { -+ uint64_t reserved_11_63:53; -+ uint64_t null_dis:1; -+ uint64_t pre_align:1; -+ uint64_t reserved_7_8:2; -+ uint64_t pre_free:1; -+ uint64_t ctl_smac:1; -+ uint64_t ctl_mcst:1; -+ uint64_t ctl_bck:1; -+ uint64_t ctl_drp:1; -+ uint64_t pre_strp:1; -+ uint64_t pre_chk:1; -+ } cn50xx; -+ struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xx; -+ struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xxp1; -+ struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn56xx; -+ struct cvmx_gmxx_rxx_frm_ctl_cn56xxp1 { -+ uint64_t reserved_10_63:54; -+ uint64_t pre_align:1; -+ uint64_t reserved_7_8:2; -+ uint64_t pre_free:1; -+ uint64_t ctl_smac:1; -+ uint64_t ctl_mcst:1; -+ uint64_t ctl_bck:1; -+ uint64_t ctl_drp:1; -+ uint64_t pre_strp:1; -+ uint64_t pre_chk:1; -+ } cn56xxp1; -+ struct cvmx_gmxx_rxx_frm_ctl_s cn58xx; -+ struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_frm_max { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_frm_max_s { -+ uint64_t reserved_16_63:48; -+ uint64_t len:16; -+ } s; -+ struct cvmx_gmxx_rxx_frm_max_s cn30xx; -+ struct cvmx_gmxx_rxx_frm_max_s cn31xx; -+ struct cvmx_gmxx_rxx_frm_max_s cn38xx; -+ struct cvmx_gmxx_rxx_frm_max_s cn38xxp2; -+ struct cvmx_gmxx_rxx_frm_max_s cn58xx; -+ struct cvmx_gmxx_rxx_frm_max_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_frm_min { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_frm_min_s { -+ uint64_t reserved_16_63:48; -+ uint64_t len:16; -+ } s; -+ struct cvmx_gmxx_rxx_frm_min_s cn30xx; -+ struct cvmx_gmxx_rxx_frm_min_s cn31xx; -+ struct cvmx_gmxx_rxx_frm_min_s cn38xx; -+ struct cvmx_gmxx_rxx_frm_min_s cn38xxp2; -+ struct cvmx_gmxx_rxx_frm_min_s cn58xx; -+ struct cvmx_gmxx_rxx_frm_min_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_ifg { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_ifg_s { -+ uint64_t reserved_4_63:60; -+ uint64_t ifg:4; -+ } s; -+ struct cvmx_gmxx_rxx_ifg_s cn30xx; -+ struct cvmx_gmxx_rxx_ifg_s cn31xx; -+ struct cvmx_gmxx_rxx_ifg_s cn38xx; -+ struct cvmx_gmxx_rxx_ifg_s cn38xxp2; -+ struct cvmx_gmxx_rxx_ifg_s cn50xx; -+ struct cvmx_gmxx_rxx_ifg_s cn52xx; -+ struct cvmx_gmxx_rxx_ifg_s cn52xxp1; -+ struct cvmx_gmxx_rxx_ifg_s cn56xx; -+ struct cvmx_gmxx_rxx_ifg_s cn56xxp1; -+ struct cvmx_gmxx_rxx_ifg_s cn58xx; -+ struct cvmx_gmxx_rxx_ifg_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_int_en { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_int_en_s { -+ uint64_t reserved_29_63:35; -+ uint64_t hg2cc:1; -+ uint64_t hg2fld:1; -+ uint64_t undat:1; -+ uint64_t uneop:1; -+ uint64_t unsop:1; -+ uint64_t bad_term:1; -+ uint64_t bad_seq:1; -+ uint64_t rem_fault:1; -+ uint64_t loc_fault:1; -+ uint64_t pause_drp:1; -+ uint64_t phy_dupx:1; -+ uint64_t phy_spd:1; -+ uint64_t phy_link:1; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t niberr:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t lenerr:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t maxerr:1; -+ uint64_t carext:1; -+ uint64_t minerr:1; -+ } s; -+ struct cvmx_gmxx_rxx_int_en_cn30xx { -+ uint64_t reserved_19_63:45; -+ uint64_t phy_dupx:1; -+ uint64_t phy_spd:1; -+ uint64_t phy_link:1; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t niberr:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t lenerr:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t maxerr:1; -+ uint64_t carext:1; -+ uint64_t minerr:1; -+ } cn30xx; -+ struct cvmx_gmxx_rxx_int_en_cn30xx cn31xx; -+ struct cvmx_gmxx_rxx_int_en_cn30xx cn38xx; -+ struct cvmx_gmxx_rxx_int_en_cn30xx cn38xxp2; -+ struct cvmx_gmxx_rxx_int_en_cn50xx { -+ uint64_t reserved_20_63:44; -+ uint64_t pause_drp:1; -+ uint64_t phy_dupx:1; -+ uint64_t phy_spd:1; -+ uint64_t phy_link:1; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t niberr:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t reserved_6_6:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t reserved_2_2:1; -+ uint64_t carext:1; -+ uint64_t reserved_0_0:1; -+ } cn50xx; -+ struct cvmx_gmxx_rxx_int_en_cn52xx { -+ uint64_t reserved_29_63:35; -+ uint64_t hg2cc:1; -+ uint64_t hg2fld:1; -+ uint64_t undat:1; -+ uint64_t uneop:1; -+ uint64_t unsop:1; -+ uint64_t bad_term:1; -+ uint64_t bad_seq:1; -+ uint64_t rem_fault:1; -+ uint64_t loc_fault:1; -+ uint64_t pause_drp:1; -+ uint64_t reserved_16_18:3; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t reserved_9_9:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t reserved_5_6:2; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t reserved_2_2:1; -+ uint64_t carext:1; -+ uint64_t reserved_0_0:1; -+ } cn52xx; -+ struct cvmx_gmxx_rxx_int_en_cn52xx cn52xxp1; -+ struct cvmx_gmxx_rxx_int_en_cn52xx cn56xx; -+ struct cvmx_gmxx_rxx_int_en_cn56xxp1 { -+ uint64_t reserved_27_63:37; -+ uint64_t undat:1; -+ uint64_t uneop:1; -+ uint64_t unsop:1; -+ uint64_t bad_term:1; -+ uint64_t bad_seq:1; -+ uint64_t rem_fault:1; -+ uint64_t loc_fault:1; -+ uint64_t pause_drp:1; -+ uint64_t reserved_16_18:3; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t reserved_9_9:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t reserved_5_6:2; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t reserved_2_2:1; -+ uint64_t carext:1; -+ uint64_t reserved_0_0:1; -+ } cn56xxp1; -+ struct cvmx_gmxx_rxx_int_en_cn58xx { -+ uint64_t reserved_20_63:44; -+ uint64_t pause_drp:1; -+ uint64_t phy_dupx:1; -+ uint64_t phy_spd:1; -+ uint64_t phy_link:1; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t niberr:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t lenerr:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t maxerr:1; -+ uint64_t carext:1; -+ uint64_t minerr:1; -+ } cn58xx; -+ struct cvmx_gmxx_rxx_int_en_cn58xx cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_int_reg { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_int_reg_s { -+ uint64_t reserved_29_63:35; -+ uint64_t hg2cc:1; -+ uint64_t hg2fld:1; -+ uint64_t undat:1; -+ uint64_t uneop:1; -+ uint64_t unsop:1; -+ uint64_t bad_term:1; -+ uint64_t bad_seq:1; -+ uint64_t rem_fault:1; -+ uint64_t loc_fault:1; -+ uint64_t pause_drp:1; -+ uint64_t phy_dupx:1; -+ uint64_t phy_spd:1; -+ uint64_t phy_link:1; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t niberr:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t lenerr:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t maxerr:1; -+ uint64_t carext:1; -+ uint64_t minerr:1; -+ } s; -+ struct cvmx_gmxx_rxx_int_reg_cn30xx { -+ uint64_t reserved_19_63:45; -+ uint64_t phy_dupx:1; -+ uint64_t phy_spd:1; -+ uint64_t phy_link:1; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t niberr:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t lenerr:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t maxerr:1; -+ uint64_t carext:1; -+ uint64_t minerr:1; -+ } cn30xx; -+ struct cvmx_gmxx_rxx_int_reg_cn30xx cn31xx; -+ struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xx; -+ struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xxp2; -+ struct cvmx_gmxx_rxx_int_reg_cn50xx { -+ uint64_t reserved_20_63:44; -+ uint64_t pause_drp:1; -+ uint64_t phy_dupx:1; -+ uint64_t phy_spd:1; -+ uint64_t phy_link:1; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t niberr:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t reserved_6_6:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t reserved_2_2:1; -+ uint64_t carext:1; -+ uint64_t reserved_0_0:1; -+ } cn50xx; -+ struct cvmx_gmxx_rxx_int_reg_cn52xx { -+ uint64_t reserved_29_63:35; -+ uint64_t hg2cc:1; -+ uint64_t hg2fld:1; -+ uint64_t undat:1; -+ uint64_t uneop:1; -+ uint64_t unsop:1; -+ uint64_t bad_term:1; -+ uint64_t bad_seq:1; -+ uint64_t rem_fault:1; -+ uint64_t loc_fault:1; -+ uint64_t pause_drp:1; -+ uint64_t reserved_16_18:3; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t reserved_9_9:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t reserved_5_6:2; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t reserved_2_2:1; -+ uint64_t carext:1; -+ uint64_t reserved_0_0:1; -+ } cn52xx; -+ struct cvmx_gmxx_rxx_int_reg_cn52xx cn52xxp1; -+ struct cvmx_gmxx_rxx_int_reg_cn52xx cn56xx; -+ struct cvmx_gmxx_rxx_int_reg_cn56xxp1 { -+ uint64_t reserved_27_63:37; -+ uint64_t undat:1; -+ uint64_t uneop:1; -+ uint64_t unsop:1; -+ uint64_t bad_term:1; -+ uint64_t bad_seq:1; -+ uint64_t rem_fault:1; -+ uint64_t loc_fault:1; -+ uint64_t pause_drp:1; -+ uint64_t reserved_16_18:3; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t reserved_9_9:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t reserved_5_6:2; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t reserved_2_2:1; -+ uint64_t carext:1; -+ uint64_t reserved_0_0:1; -+ } cn56xxp1; -+ struct cvmx_gmxx_rxx_int_reg_cn58xx { -+ uint64_t reserved_20_63:44; -+ uint64_t pause_drp:1; -+ uint64_t phy_dupx:1; -+ uint64_t phy_spd:1; -+ uint64_t phy_link:1; -+ uint64_t ifgerr:1; -+ uint64_t coldet:1; -+ uint64_t falerr:1; -+ uint64_t rsverr:1; -+ uint64_t pcterr:1; -+ uint64_t ovrerr:1; -+ uint64_t niberr:1; -+ uint64_t skperr:1; -+ uint64_t rcverr:1; -+ uint64_t lenerr:1; -+ uint64_t alnerr:1; -+ uint64_t fcserr:1; -+ uint64_t jabber:1; -+ uint64_t maxerr:1; -+ uint64_t carext:1; -+ uint64_t minerr:1; -+ } cn58xx; -+ struct cvmx_gmxx_rxx_int_reg_cn58xx cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_jabber { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_jabber_s { -+ uint64_t reserved_16_63:48; -+ uint64_t cnt:16; -+ } s; -+ struct cvmx_gmxx_rxx_jabber_s cn30xx; -+ struct cvmx_gmxx_rxx_jabber_s cn31xx; -+ struct cvmx_gmxx_rxx_jabber_s cn38xx; -+ struct cvmx_gmxx_rxx_jabber_s cn38xxp2; -+ struct cvmx_gmxx_rxx_jabber_s cn50xx; -+ struct cvmx_gmxx_rxx_jabber_s cn52xx; -+ struct cvmx_gmxx_rxx_jabber_s cn52xxp1; -+ struct cvmx_gmxx_rxx_jabber_s cn56xx; -+ struct cvmx_gmxx_rxx_jabber_s cn56xxp1; -+ struct cvmx_gmxx_rxx_jabber_s cn58xx; -+ struct cvmx_gmxx_rxx_jabber_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_pause_drop_time { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_pause_drop_time_s { -+ uint64_t reserved_16_63:48; -+ uint64_t status:16; -+ } s; -+ struct cvmx_gmxx_rxx_pause_drop_time_s cn50xx; -+ struct cvmx_gmxx_rxx_pause_drop_time_s cn52xx; -+ struct cvmx_gmxx_rxx_pause_drop_time_s cn52xxp1; -+ struct cvmx_gmxx_rxx_pause_drop_time_s cn56xx; -+ struct cvmx_gmxx_rxx_pause_drop_time_s cn56xxp1; -+ struct cvmx_gmxx_rxx_pause_drop_time_s cn58xx; -+ struct cvmx_gmxx_rxx_pause_drop_time_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_rx_inbnd { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_rx_inbnd_s { -+ uint64_t reserved_4_63:60; -+ uint64_t duplex:1; -+ uint64_t speed:2; -+ uint64_t status:1; -+ } s; -+ struct cvmx_gmxx_rxx_rx_inbnd_s cn30xx; -+ struct cvmx_gmxx_rxx_rx_inbnd_s cn31xx; -+ struct cvmx_gmxx_rxx_rx_inbnd_s cn38xx; -+ struct cvmx_gmxx_rxx_rx_inbnd_s cn38xxp2; -+ struct cvmx_gmxx_rxx_rx_inbnd_s cn50xx; -+ struct cvmx_gmxx_rxx_rx_inbnd_s cn58xx; -+ struct cvmx_gmxx_rxx_rx_inbnd_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_stats_ctl { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_stats_ctl_s { -+ uint64_t reserved_1_63:63; -+ uint64_t rd_clr:1; -+ } s; -+ struct cvmx_gmxx_rxx_stats_ctl_s cn30xx; -+ struct cvmx_gmxx_rxx_stats_ctl_s cn31xx; -+ struct cvmx_gmxx_rxx_stats_ctl_s cn38xx; -+ struct cvmx_gmxx_rxx_stats_ctl_s cn38xxp2; -+ struct cvmx_gmxx_rxx_stats_ctl_s cn50xx; -+ struct cvmx_gmxx_rxx_stats_ctl_s cn52xx; -+ struct cvmx_gmxx_rxx_stats_ctl_s cn52xxp1; -+ struct cvmx_gmxx_rxx_stats_ctl_s cn56xx; -+ struct cvmx_gmxx_rxx_stats_ctl_s cn56xxp1; -+ struct cvmx_gmxx_rxx_stats_ctl_s cn58xx; -+ struct cvmx_gmxx_rxx_stats_ctl_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_stats_octs { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_stats_octs_s { -+ uint64_t reserved_48_63:16; -+ uint64_t cnt:48; -+ } s; -+ struct cvmx_gmxx_rxx_stats_octs_s cn30xx; -+ struct cvmx_gmxx_rxx_stats_octs_s cn31xx; -+ struct cvmx_gmxx_rxx_stats_octs_s cn38xx; -+ struct cvmx_gmxx_rxx_stats_octs_s cn38xxp2; -+ struct cvmx_gmxx_rxx_stats_octs_s cn50xx; -+ struct cvmx_gmxx_rxx_stats_octs_s cn52xx; -+ struct cvmx_gmxx_rxx_stats_octs_s cn52xxp1; -+ struct cvmx_gmxx_rxx_stats_octs_s cn56xx; -+ struct cvmx_gmxx_rxx_stats_octs_s cn56xxp1; -+ struct cvmx_gmxx_rxx_stats_octs_s cn58xx; -+ struct cvmx_gmxx_rxx_stats_octs_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_stats_octs_ctl { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_stats_octs_ctl_s { -+ uint64_t reserved_48_63:16; -+ uint64_t cnt:48; -+ } s; -+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn30xx; -+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn31xx; -+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn38xx; -+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn38xxp2; -+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn50xx; -+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn52xx; -+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn52xxp1; -+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn56xx; -+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn56xxp1; -+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xx; -+ struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_stats_octs_dmac { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_stats_octs_dmac_s { -+ uint64_t reserved_48_63:16; -+ uint64_t cnt:48; -+ } s; -+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn30xx; -+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn31xx; -+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn38xx; -+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn38xxp2; -+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn50xx; -+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn52xx; -+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn52xxp1; -+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn56xx; -+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn56xxp1; -+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xx; -+ struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_stats_octs_drp { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_stats_octs_drp_s { -+ uint64_t reserved_48_63:16; -+ uint64_t cnt:48; -+ } s; -+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn30xx; -+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn31xx; -+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn38xx; -+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn38xxp2; -+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn50xx; -+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn52xx; -+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn52xxp1; -+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn56xx; -+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn56xxp1; -+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xx; -+ struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_stats_pkts { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_stats_pkts_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_gmxx_rxx_stats_pkts_s cn30xx; -+ struct cvmx_gmxx_rxx_stats_pkts_s cn31xx; -+ struct cvmx_gmxx_rxx_stats_pkts_s cn38xx; -+ struct cvmx_gmxx_rxx_stats_pkts_s cn38xxp2; -+ struct cvmx_gmxx_rxx_stats_pkts_s cn50xx; -+ struct cvmx_gmxx_rxx_stats_pkts_s cn52xx; -+ struct cvmx_gmxx_rxx_stats_pkts_s cn52xxp1; -+ struct cvmx_gmxx_rxx_stats_pkts_s cn56xx; -+ struct cvmx_gmxx_rxx_stats_pkts_s cn56xxp1; -+ struct cvmx_gmxx_rxx_stats_pkts_s cn58xx; -+ struct cvmx_gmxx_rxx_stats_pkts_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_stats_pkts_bad { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_stats_pkts_bad_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn30xx; -+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn31xx; -+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn38xx; -+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn38xxp2; -+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn50xx; -+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn52xx; -+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn52xxp1; -+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn56xx; -+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn56xxp1; -+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xx; -+ struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_stats_pkts_ctl { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn30xx; -+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn31xx; -+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn38xx; -+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn38xxp2; -+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn50xx; -+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn52xx; -+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn52xxp1; -+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn56xx; -+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn56xxp1; -+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xx; -+ struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_stats_pkts_dmac { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn30xx; -+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn31xx; -+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn38xx; -+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn38xxp2; -+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn50xx; -+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn52xx; -+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn52xxp1; -+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn56xx; -+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn56xxp1; -+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xx; -+ struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_stats_pkts_drp { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_stats_pkts_drp_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn30xx; -+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn31xx; -+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn38xx; -+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn38xxp2; -+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn50xx; -+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn52xx; -+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn52xxp1; -+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn56xx; -+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn56xxp1; -+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xx; -+ struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rxx_udd_skp { -+ uint64_t u64; -+ struct cvmx_gmxx_rxx_udd_skp_s { -+ uint64_t reserved_9_63:55; -+ uint64_t fcssel:1; -+ uint64_t reserved_7_7:1; -+ uint64_t len:7; -+ } s; -+ struct cvmx_gmxx_rxx_udd_skp_s cn30xx; -+ struct cvmx_gmxx_rxx_udd_skp_s cn31xx; -+ struct cvmx_gmxx_rxx_udd_skp_s cn38xx; -+ struct cvmx_gmxx_rxx_udd_skp_s cn38xxp2; -+ struct cvmx_gmxx_rxx_udd_skp_s cn50xx; -+ struct cvmx_gmxx_rxx_udd_skp_s cn52xx; -+ struct cvmx_gmxx_rxx_udd_skp_s cn52xxp1; -+ struct cvmx_gmxx_rxx_udd_skp_s cn56xx; -+ struct cvmx_gmxx_rxx_udd_skp_s cn56xxp1; -+ struct cvmx_gmxx_rxx_udd_skp_s cn58xx; -+ struct cvmx_gmxx_rxx_udd_skp_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rx_bp_dropx { -+ uint64_t u64; -+ struct cvmx_gmxx_rx_bp_dropx_s { -+ uint64_t reserved_6_63:58; -+ uint64_t mark:6; -+ } s; -+ struct cvmx_gmxx_rx_bp_dropx_s cn30xx; -+ struct cvmx_gmxx_rx_bp_dropx_s cn31xx; -+ struct cvmx_gmxx_rx_bp_dropx_s cn38xx; -+ struct cvmx_gmxx_rx_bp_dropx_s cn38xxp2; -+ struct cvmx_gmxx_rx_bp_dropx_s cn50xx; -+ struct cvmx_gmxx_rx_bp_dropx_s cn52xx; -+ struct cvmx_gmxx_rx_bp_dropx_s cn52xxp1; -+ struct cvmx_gmxx_rx_bp_dropx_s cn56xx; -+ struct cvmx_gmxx_rx_bp_dropx_s cn56xxp1; -+ struct cvmx_gmxx_rx_bp_dropx_s cn58xx; -+ struct cvmx_gmxx_rx_bp_dropx_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rx_bp_offx { -+ uint64_t u64; -+ struct cvmx_gmxx_rx_bp_offx_s { -+ uint64_t reserved_6_63:58; -+ uint64_t mark:6; -+ } s; -+ struct cvmx_gmxx_rx_bp_offx_s cn30xx; -+ struct cvmx_gmxx_rx_bp_offx_s cn31xx; -+ struct cvmx_gmxx_rx_bp_offx_s cn38xx; -+ struct cvmx_gmxx_rx_bp_offx_s cn38xxp2; -+ struct cvmx_gmxx_rx_bp_offx_s cn50xx; -+ struct cvmx_gmxx_rx_bp_offx_s cn52xx; -+ struct cvmx_gmxx_rx_bp_offx_s cn52xxp1; -+ struct cvmx_gmxx_rx_bp_offx_s cn56xx; -+ struct cvmx_gmxx_rx_bp_offx_s cn56xxp1; -+ struct cvmx_gmxx_rx_bp_offx_s cn58xx; -+ struct cvmx_gmxx_rx_bp_offx_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rx_bp_onx { -+ uint64_t u64; -+ struct cvmx_gmxx_rx_bp_onx_s { -+ uint64_t reserved_9_63:55; -+ uint64_t mark:9; -+ } s; -+ struct cvmx_gmxx_rx_bp_onx_s cn30xx; -+ struct cvmx_gmxx_rx_bp_onx_s cn31xx; -+ struct cvmx_gmxx_rx_bp_onx_s cn38xx; -+ struct cvmx_gmxx_rx_bp_onx_s cn38xxp2; -+ struct cvmx_gmxx_rx_bp_onx_s cn50xx; -+ struct cvmx_gmxx_rx_bp_onx_s cn52xx; -+ struct cvmx_gmxx_rx_bp_onx_s cn52xxp1; -+ struct cvmx_gmxx_rx_bp_onx_s cn56xx; -+ struct cvmx_gmxx_rx_bp_onx_s cn56xxp1; -+ struct cvmx_gmxx_rx_bp_onx_s cn58xx; -+ struct cvmx_gmxx_rx_bp_onx_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rx_hg2_status { -+ uint64_t u64; -+ struct cvmx_gmxx_rx_hg2_status_s { -+ uint64_t reserved_48_63:16; -+ uint64_t phtim2go:16; -+ uint64_t xof:16; -+ uint64_t lgtim2go:16; -+ } s; -+ struct cvmx_gmxx_rx_hg2_status_s cn52xx; -+ struct cvmx_gmxx_rx_hg2_status_s cn52xxp1; -+ struct cvmx_gmxx_rx_hg2_status_s cn56xx; -+}; -+ -+union cvmx_gmxx_rx_pass_en { -+ uint64_t u64; -+ struct cvmx_gmxx_rx_pass_en_s { -+ uint64_t reserved_16_63:48; -+ uint64_t en:16; -+ } s; -+ struct cvmx_gmxx_rx_pass_en_s cn38xx; -+ struct cvmx_gmxx_rx_pass_en_s cn38xxp2; -+ struct cvmx_gmxx_rx_pass_en_s cn58xx; -+ struct cvmx_gmxx_rx_pass_en_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rx_pass_mapx { -+ uint64_t u64; -+ struct cvmx_gmxx_rx_pass_mapx_s { -+ uint64_t reserved_4_63:60; -+ uint64_t dprt:4; -+ } s; -+ struct cvmx_gmxx_rx_pass_mapx_s cn38xx; -+ struct cvmx_gmxx_rx_pass_mapx_s cn38xxp2; -+ struct cvmx_gmxx_rx_pass_mapx_s cn58xx; -+ struct cvmx_gmxx_rx_pass_mapx_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rx_prt_info { -+ uint64_t u64; -+ struct cvmx_gmxx_rx_prt_info_s { -+ uint64_t reserved_32_63:32; -+ uint64_t drop:16; -+ uint64_t commit:16; -+ } s; -+ struct cvmx_gmxx_rx_prt_info_cn30xx { -+ uint64_t reserved_19_63:45; -+ uint64_t drop:3; -+ uint64_t reserved_3_15:13; -+ uint64_t commit:3; -+ } cn30xx; -+ struct cvmx_gmxx_rx_prt_info_cn30xx cn31xx; -+ struct cvmx_gmxx_rx_prt_info_s cn38xx; -+ struct cvmx_gmxx_rx_prt_info_cn30xx cn50xx; -+ struct cvmx_gmxx_rx_prt_info_cn52xx { -+ uint64_t reserved_20_63:44; -+ uint64_t drop:4; -+ uint64_t reserved_4_15:12; -+ uint64_t commit:4; -+ } cn52xx; -+ struct cvmx_gmxx_rx_prt_info_cn52xx cn52xxp1; -+ struct cvmx_gmxx_rx_prt_info_cn52xx cn56xx; -+ struct cvmx_gmxx_rx_prt_info_cn52xx cn56xxp1; -+ struct cvmx_gmxx_rx_prt_info_s cn58xx; -+ struct cvmx_gmxx_rx_prt_info_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rx_prts { -+ uint64_t u64; -+ struct cvmx_gmxx_rx_prts_s { -+ uint64_t reserved_3_63:61; -+ uint64_t prts:3; -+ } s; -+ struct cvmx_gmxx_rx_prts_s cn30xx; -+ struct cvmx_gmxx_rx_prts_s cn31xx; -+ struct cvmx_gmxx_rx_prts_s cn38xx; -+ struct cvmx_gmxx_rx_prts_s cn38xxp2; -+ struct cvmx_gmxx_rx_prts_s cn50xx; -+ struct cvmx_gmxx_rx_prts_s cn52xx; -+ struct cvmx_gmxx_rx_prts_s cn52xxp1; -+ struct cvmx_gmxx_rx_prts_s cn56xx; -+ struct cvmx_gmxx_rx_prts_s cn56xxp1; -+ struct cvmx_gmxx_rx_prts_s cn58xx; -+ struct cvmx_gmxx_rx_prts_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_rx_tx_status { -+ uint64_t u64; -+ struct cvmx_gmxx_rx_tx_status_s { -+ uint64_t reserved_7_63:57; -+ uint64_t tx:3; -+ uint64_t reserved_3_3:1; -+ uint64_t rx:3; -+ } s; -+ struct cvmx_gmxx_rx_tx_status_s cn30xx; -+ struct cvmx_gmxx_rx_tx_status_s cn31xx; -+ struct cvmx_gmxx_rx_tx_status_s cn50xx; -+}; -+ -+union cvmx_gmxx_rx_xaui_bad_col { -+ uint64_t u64; -+ struct cvmx_gmxx_rx_xaui_bad_col_s { -+ uint64_t reserved_40_63:24; -+ uint64_t val:1; -+ uint64_t state:3; -+ uint64_t lane_rxc:4; -+ uint64_t lane_rxd:32; -+ } s; -+ struct cvmx_gmxx_rx_xaui_bad_col_s cn52xx; -+ struct cvmx_gmxx_rx_xaui_bad_col_s cn52xxp1; -+ struct cvmx_gmxx_rx_xaui_bad_col_s cn56xx; -+ struct cvmx_gmxx_rx_xaui_bad_col_s cn56xxp1; -+}; -+ -+union cvmx_gmxx_rx_xaui_ctl { -+ uint64_t u64; -+ struct cvmx_gmxx_rx_xaui_ctl_s { -+ uint64_t reserved_2_63:62; -+ uint64_t status:2; -+ } s; -+ struct cvmx_gmxx_rx_xaui_ctl_s cn52xx; -+ struct cvmx_gmxx_rx_xaui_ctl_s cn52xxp1; -+ struct cvmx_gmxx_rx_xaui_ctl_s cn56xx; -+ struct cvmx_gmxx_rx_xaui_ctl_s cn56xxp1; -+}; -+ -+union cvmx_gmxx_smacx { -+ uint64_t u64; -+ struct cvmx_gmxx_smacx_s { -+ uint64_t reserved_48_63:16; -+ uint64_t smac:48; -+ } s; -+ struct cvmx_gmxx_smacx_s cn30xx; -+ struct cvmx_gmxx_smacx_s cn31xx; -+ struct cvmx_gmxx_smacx_s cn38xx; -+ struct cvmx_gmxx_smacx_s cn38xxp2; -+ struct cvmx_gmxx_smacx_s cn50xx; -+ struct cvmx_gmxx_smacx_s cn52xx; -+ struct cvmx_gmxx_smacx_s cn52xxp1; -+ struct cvmx_gmxx_smacx_s cn56xx; -+ struct cvmx_gmxx_smacx_s cn56xxp1; -+ struct cvmx_gmxx_smacx_s cn58xx; -+ struct cvmx_gmxx_smacx_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_stat_bp { -+ uint64_t u64; -+ struct cvmx_gmxx_stat_bp_s { -+ uint64_t reserved_17_63:47; -+ uint64_t bp:1; -+ uint64_t cnt:16; -+ } s; -+ struct cvmx_gmxx_stat_bp_s cn30xx; -+ struct cvmx_gmxx_stat_bp_s cn31xx; -+ struct cvmx_gmxx_stat_bp_s cn38xx; -+ struct cvmx_gmxx_stat_bp_s cn38xxp2; -+ struct cvmx_gmxx_stat_bp_s cn50xx; -+ struct cvmx_gmxx_stat_bp_s cn52xx; -+ struct cvmx_gmxx_stat_bp_s cn52xxp1; -+ struct cvmx_gmxx_stat_bp_s cn56xx; -+ struct cvmx_gmxx_stat_bp_s cn56xxp1; -+ struct cvmx_gmxx_stat_bp_s cn58xx; -+ struct cvmx_gmxx_stat_bp_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_append { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_append_s { -+ uint64_t reserved_4_63:60; -+ uint64_t force_fcs:1; -+ uint64_t fcs:1; -+ uint64_t pad:1; -+ uint64_t preamble:1; -+ } s; -+ struct cvmx_gmxx_txx_append_s cn30xx; -+ struct cvmx_gmxx_txx_append_s cn31xx; -+ struct cvmx_gmxx_txx_append_s cn38xx; -+ struct cvmx_gmxx_txx_append_s cn38xxp2; -+ struct cvmx_gmxx_txx_append_s cn50xx; -+ struct cvmx_gmxx_txx_append_s cn52xx; -+ struct cvmx_gmxx_txx_append_s cn52xxp1; -+ struct cvmx_gmxx_txx_append_s cn56xx; -+ struct cvmx_gmxx_txx_append_s cn56xxp1; -+ struct cvmx_gmxx_txx_append_s cn58xx; -+ struct cvmx_gmxx_txx_append_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_burst { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_burst_s { -+ uint64_t reserved_16_63:48; -+ uint64_t burst:16; -+ } s; -+ struct cvmx_gmxx_txx_burst_s cn30xx; -+ struct cvmx_gmxx_txx_burst_s cn31xx; -+ struct cvmx_gmxx_txx_burst_s cn38xx; -+ struct cvmx_gmxx_txx_burst_s cn38xxp2; -+ struct cvmx_gmxx_txx_burst_s cn50xx; -+ struct cvmx_gmxx_txx_burst_s cn52xx; -+ struct cvmx_gmxx_txx_burst_s cn52xxp1; -+ struct cvmx_gmxx_txx_burst_s cn56xx; -+ struct cvmx_gmxx_txx_burst_s cn56xxp1; -+ struct cvmx_gmxx_txx_burst_s cn58xx; -+ struct cvmx_gmxx_txx_burst_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_cbfc_xoff { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_cbfc_xoff_s { -+ uint64_t reserved_16_63:48; -+ uint64_t xoff:16; -+ } s; -+ struct cvmx_gmxx_txx_cbfc_xoff_s cn52xx; -+ struct cvmx_gmxx_txx_cbfc_xoff_s cn56xx; -+}; -+ -+union cvmx_gmxx_txx_cbfc_xon { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_cbfc_xon_s { -+ uint64_t reserved_16_63:48; -+ uint64_t xon:16; -+ } s; -+ struct cvmx_gmxx_txx_cbfc_xon_s cn52xx; -+ struct cvmx_gmxx_txx_cbfc_xon_s cn56xx; -+}; -+ -+union cvmx_gmxx_txx_clk { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_clk_s { -+ uint64_t reserved_6_63:58; -+ uint64_t clk_cnt:6; -+ } s; -+ struct cvmx_gmxx_txx_clk_s cn30xx; -+ struct cvmx_gmxx_txx_clk_s cn31xx; -+ struct cvmx_gmxx_txx_clk_s cn38xx; -+ struct cvmx_gmxx_txx_clk_s cn38xxp2; -+ struct cvmx_gmxx_txx_clk_s cn50xx; -+ struct cvmx_gmxx_txx_clk_s cn58xx; -+ struct cvmx_gmxx_txx_clk_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_ctl { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_ctl_s { -+ uint64_t reserved_2_63:62; -+ uint64_t xsdef_en:1; -+ uint64_t xscol_en:1; -+ } s; -+ struct cvmx_gmxx_txx_ctl_s cn30xx; -+ struct cvmx_gmxx_txx_ctl_s cn31xx; -+ struct cvmx_gmxx_txx_ctl_s cn38xx; -+ struct cvmx_gmxx_txx_ctl_s cn38xxp2; -+ struct cvmx_gmxx_txx_ctl_s cn50xx; -+ struct cvmx_gmxx_txx_ctl_s cn52xx; -+ struct cvmx_gmxx_txx_ctl_s cn52xxp1; -+ struct cvmx_gmxx_txx_ctl_s cn56xx; -+ struct cvmx_gmxx_txx_ctl_s cn56xxp1; -+ struct cvmx_gmxx_txx_ctl_s cn58xx; -+ struct cvmx_gmxx_txx_ctl_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_min_pkt { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_min_pkt_s { -+ uint64_t reserved_8_63:56; -+ uint64_t min_size:8; -+ } s; -+ struct cvmx_gmxx_txx_min_pkt_s cn30xx; -+ struct cvmx_gmxx_txx_min_pkt_s cn31xx; -+ struct cvmx_gmxx_txx_min_pkt_s cn38xx; -+ struct cvmx_gmxx_txx_min_pkt_s cn38xxp2; -+ struct cvmx_gmxx_txx_min_pkt_s cn50xx; -+ struct cvmx_gmxx_txx_min_pkt_s cn52xx; -+ struct cvmx_gmxx_txx_min_pkt_s cn52xxp1; -+ struct cvmx_gmxx_txx_min_pkt_s cn56xx; -+ struct cvmx_gmxx_txx_min_pkt_s cn56xxp1; -+ struct cvmx_gmxx_txx_min_pkt_s cn58xx; -+ struct cvmx_gmxx_txx_min_pkt_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_pause_pkt_interval { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_pause_pkt_interval_s { -+ uint64_t reserved_16_63:48; -+ uint64_t interval:16; -+ } s; -+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn30xx; -+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn31xx; -+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn38xx; -+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn38xxp2; -+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn50xx; -+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn52xx; -+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn52xxp1; -+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn56xx; -+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn56xxp1; -+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xx; -+ struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_pause_pkt_time { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_pause_pkt_time_s { -+ uint64_t reserved_16_63:48; -+ uint64_t time:16; -+ } s; -+ struct cvmx_gmxx_txx_pause_pkt_time_s cn30xx; -+ struct cvmx_gmxx_txx_pause_pkt_time_s cn31xx; -+ struct cvmx_gmxx_txx_pause_pkt_time_s cn38xx; -+ struct cvmx_gmxx_txx_pause_pkt_time_s cn38xxp2; -+ struct cvmx_gmxx_txx_pause_pkt_time_s cn50xx; -+ struct cvmx_gmxx_txx_pause_pkt_time_s cn52xx; -+ struct cvmx_gmxx_txx_pause_pkt_time_s cn52xxp1; -+ struct cvmx_gmxx_txx_pause_pkt_time_s cn56xx; -+ struct cvmx_gmxx_txx_pause_pkt_time_s cn56xxp1; -+ struct cvmx_gmxx_txx_pause_pkt_time_s cn58xx; -+ struct cvmx_gmxx_txx_pause_pkt_time_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_pause_togo { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_pause_togo_s { -+ uint64_t reserved_32_63:32; -+ uint64_t msg_time:16; -+ uint64_t time:16; -+ } s; -+ struct cvmx_gmxx_txx_pause_togo_cn30xx { -+ uint64_t reserved_16_63:48; -+ uint64_t time:16; -+ } cn30xx; -+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn31xx; -+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn38xx; -+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn38xxp2; -+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn50xx; -+ struct cvmx_gmxx_txx_pause_togo_s cn52xx; -+ struct cvmx_gmxx_txx_pause_togo_s cn52xxp1; -+ struct cvmx_gmxx_txx_pause_togo_s cn56xx; -+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn56xxp1; -+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xx; -+ struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_pause_zero { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_pause_zero_s { -+ uint64_t reserved_1_63:63; -+ uint64_t send:1; -+ } s; -+ struct cvmx_gmxx_txx_pause_zero_s cn30xx; -+ struct cvmx_gmxx_txx_pause_zero_s cn31xx; -+ struct cvmx_gmxx_txx_pause_zero_s cn38xx; -+ struct cvmx_gmxx_txx_pause_zero_s cn38xxp2; -+ struct cvmx_gmxx_txx_pause_zero_s cn50xx; -+ struct cvmx_gmxx_txx_pause_zero_s cn52xx; -+ struct cvmx_gmxx_txx_pause_zero_s cn52xxp1; -+ struct cvmx_gmxx_txx_pause_zero_s cn56xx; -+ struct cvmx_gmxx_txx_pause_zero_s cn56xxp1; -+ struct cvmx_gmxx_txx_pause_zero_s cn58xx; -+ struct cvmx_gmxx_txx_pause_zero_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_sgmii_ctl { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_sgmii_ctl_s { -+ uint64_t reserved_1_63:63; -+ uint64_t align:1; -+ } s; -+ struct cvmx_gmxx_txx_sgmii_ctl_s cn52xx; -+ struct cvmx_gmxx_txx_sgmii_ctl_s cn52xxp1; -+ struct cvmx_gmxx_txx_sgmii_ctl_s cn56xx; -+ struct cvmx_gmxx_txx_sgmii_ctl_s cn56xxp1; -+}; -+ -+union cvmx_gmxx_txx_slot { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_slot_s { -+ uint64_t reserved_10_63:54; -+ uint64_t slot:10; -+ } s; -+ struct cvmx_gmxx_txx_slot_s cn30xx; -+ struct cvmx_gmxx_txx_slot_s cn31xx; -+ struct cvmx_gmxx_txx_slot_s cn38xx; -+ struct cvmx_gmxx_txx_slot_s cn38xxp2; -+ struct cvmx_gmxx_txx_slot_s cn50xx; -+ struct cvmx_gmxx_txx_slot_s cn52xx; -+ struct cvmx_gmxx_txx_slot_s cn52xxp1; -+ struct cvmx_gmxx_txx_slot_s cn56xx; -+ struct cvmx_gmxx_txx_slot_s cn56xxp1; -+ struct cvmx_gmxx_txx_slot_s cn58xx; -+ struct cvmx_gmxx_txx_slot_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_soft_pause { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_soft_pause_s { -+ uint64_t reserved_16_63:48; -+ uint64_t time:16; -+ } s; -+ struct cvmx_gmxx_txx_soft_pause_s cn30xx; -+ struct cvmx_gmxx_txx_soft_pause_s cn31xx; -+ struct cvmx_gmxx_txx_soft_pause_s cn38xx; -+ struct cvmx_gmxx_txx_soft_pause_s cn38xxp2; -+ struct cvmx_gmxx_txx_soft_pause_s cn50xx; -+ struct cvmx_gmxx_txx_soft_pause_s cn52xx; -+ struct cvmx_gmxx_txx_soft_pause_s cn52xxp1; -+ struct cvmx_gmxx_txx_soft_pause_s cn56xx; -+ struct cvmx_gmxx_txx_soft_pause_s cn56xxp1; -+ struct cvmx_gmxx_txx_soft_pause_s cn58xx; -+ struct cvmx_gmxx_txx_soft_pause_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_stat0 { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_stat0_s { -+ uint64_t xsdef:32; -+ uint64_t xscol:32; -+ } s; -+ struct cvmx_gmxx_txx_stat0_s cn30xx; -+ struct cvmx_gmxx_txx_stat0_s cn31xx; -+ struct cvmx_gmxx_txx_stat0_s cn38xx; -+ struct cvmx_gmxx_txx_stat0_s cn38xxp2; -+ struct cvmx_gmxx_txx_stat0_s cn50xx; -+ struct cvmx_gmxx_txx_stat0_s cn52xx; -+ struct cvmx_gmxx_txx_stat0_s cn52xxp1; -+ struct cvmx_gmxx_txx_stat0_s cn56xx; -+ struct cvmx_gmxx_txx_stat0_s cn56xxp1; -+ struct cvmx_gmxx_txx_stat0_s cn58xx; -+ struct cvmx_gmxx_txx_stat0_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_stat1 { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_stat1_s { -+ uint64_t scol:32; -+ uint64_t mcol:32; -+ } s; -+ struct cvmx_gmxx_txx_stat1_s cn30xx; -+ struct cvmx_gmxx_txx_stat1_s cn31xx; -+ struct cvmx_gmxx_txx_stat1_s cn38xx; -+ struct cvmx_gmxx_txx_stat1_s cn38xxp2; -+ struct cvmx_gmxx_txx_stat1_s cn50xx; -+ struct cvmx_gmxx_txx_stat1_s cn52xx; -+ struct cvmx_gmxx_txx_stat1_s cn52xxp1; -+ struct cvmx_gmxx_txx_stat1_s cn56xx; -+ struct cvmx_gmxx_txx_stat1_s cn56xxp1; -+ struct cvmx_gmxx_txx_stat1_s cn58xx; -+ struct cvmx_gmxx_txx_stat1_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_stat2 { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_stat2_s { -+ uint64_t reserved_48_63:16; -+ uint64_t octs:48; -+ } s; -+ struct cvmx_gmxx_txx_stat2_s cn30xx; -+ struct cvmx_gmxx_txx_stat2_s cn31xx; -+ struct cvmx_gmxx_txx_stat2_s cn38xx; -+ struct cvmx_gmxx_txx_stat2_s cn38xxp2; -+ struct cvmx_gmxx_txx_stat2_s cn50xx; -+ struct cvmx_gmxx_txx_stat2_s cn52xx; -+ struct cvmx_gmxx_txx_stat2_s cn52xxp1; -+ struct cvmx_gmxx_txx_stat2_s cn56xx; -+ struct cvmx_gmxx_txx_stat2_s cn56xxp1; -+ struct cvmx_gmxx_txx_stat2_s cn58xx; -+ struct cvmx_gmxx_txx_stat2_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_stat3 { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_stat3_s { -+ uint64_t reserved_32_63:32; -+ uint64_t pkts:32; -+ } s; -+ struct cvmx_gmxx_txx_stat3_s cn30xx; -+ struct cvmx_gmxx_txx_stat3_s cn31xx; -+ struct cvmx_gmxx_txx_stat3_s cn38xx; -+ struct cvmx_gmxx_txx_stat3_s cn38xxp2; -+ struct cvmx_gmxx_txx_stat3_s cn50xx; -+ struct cvmx_gmxx_txx_stat3_s cn52xx; -+ struct cvmx_gmxx_txx_stat3_s cn52xxp1; -+ struct cvmx_gmxx_txx_stat3_s cn56xx; -+ struct cvmx_gmxx_txx_stat3_s cn56xxp1; -+ struct cvmx_gmxx_txx_stat3_s cn58xx; -+ struct cvmx_gmxx_txx_stat3_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_stat4 { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_stat4_s { -+ uint64_t hist1:32; -+ uint64_t hist0:32; -+ } s; -+ struct cvmx_gmxx_txx_stat4_s cn30xx; -+ struct cvmx_gmxx_txx_stat4_s cn31xx; -+ struct cvmx_gmxx_txx_stat4_s cn38xx; -+ struct cvmx_gmxx_txx_stat4_s cn38xxp2; -+ struct cvmx_gmxx_txx_stat4_s cn50xx; -+ struct cvmx_gmxx_txx_stat4_s cn52xx; -+ struct cvmx_gmxx_txx_stat4_s cn52xxp1; -+ struct cvmx_gmxx_txx_stat4_s cn56xx; -+ struct cvmx_gmxx_txx_stat4_s cn56xxp1; -+ struct cvmx_gmxx_txx_stat4_s cn58xx; -+ struct cvmx_gmxx_txx_stat4_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_stat5 { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_stat5_s { -+ uint64_t hist3:32; -+ uint64_t hist2:32; -+ } s; -+ struct cvmx_gmxx_txx_stat5_s cn30xx; -+ struct cvmx_gmxx_txx_stat5_s cn31xx; -+ struct cvmx_gmxx_txx_stat5_s cn38xx; -+ struct cvmx_gmxx_txx_stat5_s cn38xxp2; -+ struct cvmx_gmxx_txx_stat5_s cn50xx; -+ struct cvmx_gmxx_txx_stat5_s cn52xx; -+ struct cvmx_gmxx_txx_stat5_s cn52xxp1; -+ struct cvmx_gmxx_txx_stat5_s cn56xx; -+ struct cvmx_gmxx_txx_stat5_s cn56xxp1; -+ struct cvmx_gmxx_txx_stat5_s cn58xx; -+ struct cvmx_gmxx_txx_stat5_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_stat6 { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_stat6_s { -+ uint64_t hist5:32; -+ uint64_t hist4:32; -+ } s; -+ struct cvmx_gmxx_txx_stat6_s cn30xx; -+ struct cvmx_gmxx_txx_stat6_s cn31xx; -+ struct cvmx_gmxx_txx_stat6_s cn38xx; -+ struct cvmx_gmxx_txx_stat6_s cn38xxp2; -+ struct cvmx_gmxx_txx_stat6_s cn50xx; -+ struct cvmx_gmxx_txx_stat6_s cn52xx; -+ struct cvmx_gmxx_txx_stat6_s cn52xxp1; -+ struct cvmx_gmxx_txx_stat6_s cn56xx; -+ struct cvmx_gmxx_txx_stat6_s cn56xxp1; -+ struct cvmx_gmxx_txx_stat6_s cn58xx; -+ struct cvmx_gmxx_txx_stat6_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_stat7 { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_stat7_s { -+ uint64_t hist7:32; -+ uint64_t hist6:32; -+ } s; -+ struct cvmx_gmxx_txx_stat7_s cn30xx; -+ struct cvmx_gmxx_txx_stat7_s cn31xx; -+ struct cvmx_gmxx_txx_stat7_s cn38xx; -+ struct cvmx_gmxx_txx_stat7_s cn38xxp2; -+ struct cvmx_gmxx_txx_stat7_s cn50xx; -+ struct cvmx_gmxx_txx_stat7_s cn52xx; -+ struct cvmx_gmxx_txx_stat7_s cn52xxp1; -+ struct cvmx_gmxx_txx_stat7_s cn56xx; -+ struct cvmx_gmxx_txx_stat7_s cn56xxp1; -+ struct cvmx_gmxx_txx_stat7_s cn58xx; -+ struct cvmx_gmxx_txx_stat7_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_stat8 { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_stat8_s { -+ uint64_t mcst:32; -+ uint64_t bcst:32; -+ } s; -+ struct cvmx_gmxx_txx_stat8_s cn30xx; -+ struct cvmx_gmxx_txx_stat8_s cn31xx; -+ struct cvmx_gmxx_txx_stat8_s cn38xx; -+ struct cvmx_gmxx_txx_stat8_s cn38xxp2; -+ struct cvmx_gmxx_txx_stat8_s cn50xx; -+ struct cvmx_gmxx_txx_stat8_s cn52xx; -+ struct cvmx_gmxx_txx_stat8_s cn52xxp1; -+ struct cvmx_gmxx_txx_stat8_s cn56xx; -+ struct cvmx_gmxx_txx_stat8_s cn56xxp1; -+ struct cvmx_gmxx_txx_stat8_s cn58xx; -+ struct cvmx_gmxx_txx_stat8_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_stat9 { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_stat9_s { -+ uint64_t undflw:32; -+ uint64_t ctl:32; -+ } s; -+ struct cvmx_gmxx_txx_stat9_s cn30xx; -+ struct cvmx_gmxx_txx_stat9_s cn31xx; -+ struct cvmx_gmxx_txx_stat9_s cn38xx; -+ struct cvmx_gmxx_txx_stat9_s cn38xxp2; -+ struct cvmx_gmxx_txx_stat9_s cn50xx; -+ struct cvmx_gmxx_txx_stat9_s cn52xx; -+ struct cvmx_gmxx_txx_stat9_s cn52xxp1; -+ struct cvmx_gmxx_txx_stat9_s cn56xx; -+ struct cvmx_gmxx_txx_stat9_s cn56xxp1; -+ struct cvmx_gmxx_txx_stat9_s cn58xx; -+ struct cvmx_gmxx_txx_stat9_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_stats_ctl { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_stats_ctl_s { -+ uint64_t reserved_1_63:63; -+ uint64_t rd_clr:1; -+ } s; -+ struct cvmx_gmxx_txx_stats_ctl_s cn30xx; -+ struct cvmx_gmxx_txx_stats_ctl_s cn31xx; -+ struct cvmx_gmxx_txx_stats_ctl_s cn38xx; -+ struct cvmx_gmxx_txx_stats_ctl_s cn38xxp2; -+ struct cvmx_gmxx_txx_stats_ctl_s cn50xx; -+ struct cvmx_gmxx_txx_stats_ctl_s cn52xx; -+ struct cvmx_gmxx_txx_stats_ctl_s cn52xxp1; -+ struct cvmx_gmxx_txx_stats_ctl_s cn56xx; -+ struct cvmx_gmxx_txx_stats_ctl_s cn56xxp1; -+ struct cvmx_gmxx_txx_stats_ctl_s cn58xx; -+ struct cvmx_gmxx_txx_stats_ctl_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_txx_thresh { -+ uint64_t u64; -+ struct cvmx_gmxx_txx_thresh_s { -+ uint64_t reserved_9_63:55; -+ uint64_t cnt:9; -+ } s; -+ struct cvmx_gmxx_txx_thresh_cn30xx { -+ uint64_t reserved_7_63:57; -+ uint64_t cnt:7; -+ } cn30xx; -+ struct cvmx_gmxx_txx_thresh_cn30xx cn31xx; -+ struct cvmx_gmxx_txx_thresh_s cn38xx; -+ struct cvmx_gmxx_txx_thresh_s cn38xxp2; -+ struct cvmx_gmxx_txx_thresh_cn30xx cn50xx; -+ struct cvmx_gmxx_txx_thresh_s cn52xx; -+ struct cvmx_gmxx_txx_thresh_s cn52xxp1; -+ struct cvmx_gmxx_txx_thresh_s cn56xx; -+ struct cvmx_gmxx_txx_thresh_s cn56xxp1; -+ struct cvmx_gmxx_txx_thresh_s cn58xx; -+ struct cvmx_gmxx_txx_thresh_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_bp { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_bp_s { -+ uint64_t reserved_4_63:60; -+ uint64_t bp:4; -+ } s; -+ struct cvmx_gmxx_tx_bp_cn30xx { -+ uint64_t reserved_3_63:61; -+ uint64_t bp:3; -+ } cn30xx; -+ struct cvmx_gmxx_tx_bp_cn30xx cn31xx; -+ struct cvmx_gmxx_tx_bp_s cn38xx; -+ struct cvmx_gmxx_tx_bp_s cn38xxp2; -+ struct cvmx_gmxx_tx_bp_cn30xx cn50xx; -+ struct cvmx_gmxx_tx_bp_s cn52xx; -+ struct cvmx_gmxx_tx_bp_s cn52xxp1; -+ struct cvmx_gmxx_tx_bp_s cn56xx; -+ struct cvmx_gmxx_tx_bp_s cn56xxp1; -+ struct cvmx_gmxx_tx_bp_s cn58xx; -+ struct cvmx_gmxx_tx_bp_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_clk_mskx { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_clk_mskx_s { -+ uint64_t reserved_1_63:63; -+ uint64_t msk:1; -+ } s; -+ struct cvmx_gmxx_tx_clk_mskx_s cn30xx; -+ struct cvmx_gmxx_tx_clk_mskx_s cn50xx; -+}; -+ -+union cvmx_gmxx_tx_col_attempt { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_col_attempt_s { -+ uint64_t reserved_5_63:59; -+ uint64_t limit:5; -+ } s; -+ struct cvmx_gmxx_tx_col_attempt_s cn30xx; -+ struct cvmx_gmxx_tx_col_attempt_s cn31xx; -+ struct cvmx_gmxx_tx_col_attempt_s cn38xx; -+ struct cvmx_gmxx_tx_col_attempt_s cn38xxp2; -+ struct cvmx_gmxx_tx_col_attempt_s cn50xx; -+ struct cvmx_gmxx_tx_col_attempt_s cn52xx; -+ struct cvmx_gmxx_tx_col_attempt_s cn52xxp1; -+ struct cvmx_gmxx_tx_col_attempt_s cn56xx; -+ struct cvmx_gmxx_tx_col_attempt_s cn56xxp1; -+ struct cvmx_gmxx_tx_col_attempt_s cn58xx; -+ struct cvmx_gmxx_tx_col_attempt_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_corrupt { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_corrupt_s { -+ uint64_t reserved_4_63:60; -+ uint64_t corrupt:4; -+ } s; -+ struct cvmx_gmxx_tx_corrupt_cn30xx { -+ uint64_t reserved_3_63:61; -+ uint64_t corrupt:3; -+ } cn30xx; -+ struct cvmx_gmxx_tx_corrupt_cn30xx cn31xx; -+ struct cvmx_gmxx_tx_corrupt_s cn38xx; -+ struct cvmx_gmxx_tx_corrupt_s cn38xxp2; -+ struct cvmx_gmxx_tx_corrupt_cn30xx cn50xx; -+ struct cvmx_gmxx_tx_corrupt_s cn52xx; -+ struct cvmx_gmxx_tx_corrupt_s cn52xxp1; -+ struct cvmx_gmxx_tx_corrupt_s cn56xx; -+ struct cvmx_gmxx_tx_corrupt_s cn56xxp1; -+ struct cvmx_gmxx_tx_corrupt_s cn58xx; -+ struct cvmx_gmxx_tx_corrupt_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_hg2_reg1 { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_hg2_reg1_s { -+ uint64_t reserved_16_63:48; -+ uint64_t tx_xof:16; -+ } s; -+ struct cvmx_gmxx_tx_hg2_reg1_s cn52xx; -+ struct cvmx_gmxx_tx_hg2_reg1_s cn52xxp1; -+ struct cvmx_gmxx_tx_hg2_reg1_s cn56xx; -+}; -+ -+union cvmx_gmxx_tx_hg2_reg2 { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_hg2_reg2_s { -+ uint64_t reserved_16_63:48; -+ uint64_t tx_xon:16; -+ } s; -+ struct cvmx_gmxx_tx_hg2_reg2_s cn52xx; -+ struct cvmx_gmxx_tx_hg2_reg2_s cn52xxp1; -+ struct cvmx_gmxx_tx_hg2_reg2_s cn56xx; -+}; -+ -+union cvmx_gmxx_tx_ifg { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_ifg_s { -+ uint64_t reserved_8_63:56; -+ uint64_t ifg2:4; -+ uint64_t ifg1:4; -+ } s; -+ struct cvmx_gmxx_tx_ifg_s cn30xx; -+ struct cvmx_gmxx_tx_ifg_s cn31xx; -+ struct cvmx_gmxx_tx_ifg_s cn38xx; -+ struct cvmx_gmxx_tx_ifg_s cn38xxp2; -+ struct cvmx_gmxx_tx_ifg_s cn50xx; -+ struct cvmx_gmxx_tx_ifg_s cn52xx; -+ struct cvmx_gmxx_tx_ifg_s cn52xxp1; -+ struct cvmx_gmxx_tx_ifg_s cn56xx; -+ struct cvmx_gmxx_tx_ifg_s cn56xxp1; -+ struct cvmx_gmxx_tx_ifg_s cn58xx; -+ struct cvmx_gmxx_tx_ifg_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_int_en { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_int_en_s { -+ uint64_t reserved_20_63:44; -+ uint64_t late_col:4; -+ uint64_t xsdef:4; -+ uint64_t xscol:4; -+ uint64_t reserved_6_7:2; -+ uint64_t undflw:4; -+ uint64_t ncb_nxa:1; -+ uint64_t pko_nxa:1; -+ } s; -+ struct cvmx_gmxx_tx_int_en_cn30xx { -+ uint64_t reserved_19_63:45; -+ uint64_t late_col:3; -+ uint64_t reserved_15_15:1; -+ uint64_t xsdef:3; -+ uint64_t reserved_11_11:1; -+ uint64_t xscol:3; -+ uint64_t reserved_5_7:3; -+ uint64_t undflw:3; -+ uint64_t reserved_1_1:1; -+ uint64_t pko_nxa:1; -+ } cn30xx; -+ struct cvmx_gmxx_tx_int_en_cn31xx { -+ uint64_t reserved_15_63:49; -+ uint64_t xsdef:3; -+ uint64_t reserved_11_11:1; -+ uint64_t xscol:3; -+ uint64_t reserved_5_7:3; -+ uint64_t undflw:3; -+ uint64_t reserved_1_1:1; -+ uint64_t pko_nxa:1; -+ } cn31xx; -+ struct cvmx_gmxx_tx_int_en_s cn38xx; -+ struct cvmx_gmxx_tx_int_en_cn38xxp2 { -+ uint64_t reserved_16_63:48; -+ uint64_t xsdef:4; -+ uint64_t xscol:4; -+ uint64_t reserved_6_7:2; -+ uint64_t undflw:4; -+ uint64_t ncb_nxa:1; -+ uint64_t pko_nxa:1; -+ } cn38xxp2; -+ struct cvmx_gmxx_tx_int_en_cn30xx cn50xx; -+ struct cvmx_gmxx_tx_int_en_cn52xx { -+ uint64_t reserved_20_63:44; -+ uint64_t late_col:4; -+ uint64_t xsdef:4; -+ uint64_t xscol:4; -+ uint64_t reserved_6_7:2; -+ uint64_t undflw:4; -+ uint64_t reserved_1_1:1; -+ uint64_t pko_nxa:1; -+ } cn52xx; -+ struct cvmx_gmxx_tx_int_en_cn52xx cn52xxp1; -+ struct cvmx_gmxx_tx_int_en_cn52xx cn56xx; -+ struct cvmx_gmxx_tx_int_en_cn52xx cn56xxp1; -+ struct cvmx_gmxx_tx_int_en_s cn58xx; -+ struct cvmx_gmxx_tx_int_en_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_int_reg { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_int_reg_s { -+ uint64_t reserved_20_63:44; -+ uint64_t late_col:4; -+ uint64_t xsdef:4; -+ uint64_t xscol:4; -+ uint64_t reserved_6_7:2; -+ uint64_t undflw:4; -+ uint64_t ncb_nxa:1; -+ uint64_t pko_nxa:1; -+ } s; -+ struct cvmx_gmxx_tx_int_reg_cn30xx { -+ uint64_t reserved_19_63:45; -+ uint64_t late_col:3; -+ uint64_t reserved_15_15:1; -+ uint64_t xsdef:3; -+ uint64_t reserved_11_11:1; -+ uint64_t xscol:3; -+ uint64_t reserved_5_7:3; -+ uint64_t undflw:3; -+ uint64_t reserved_1_1:1; -+ uint64_t pko_nxa:1; -+ } cn30xx; -+ struct cvmx_gmxx_tx_int_reg_cn31xx { -+ uint64_t reserved_15_63:49; -+ uint64_t xsdef:3; -+ uint64_t reserved_11_11:1; -+ uint64_t xscol:3; -+ uint64_t reserved_5_7:3; -+ uint64_t undflw:3; -+ uint64_t reserved_1_1:1; -+ uint64_t pko_nxa:1; -+ } cn31xx; -+ struct cvmx_gmxx_tx_int_reg_s cn38xx; -+ struct cvmx_gmxx_tx_int_reg_cn38xxp2 { -+ uint64_t reserved_16_63:48; -+ uint64_t xsdef:4; -+ uint64_t xscol:4; -+ uint64_t reserved_6_7:2; -+ uint64_t undflw:4; -+ uint64_t ncb_nxa:1; -+ uint64_t pko_nxa:1; -+ } cn38xxp2; -+ struct cvmx_gmxx_tx_int_reg_cn30xx cn50xx; -+ struct cvmx_gmxx_tx_int_reg_cn52xx { -+ uint64_t reserved_20_63:44; -+ uint64_t late_col:4; -+ uint64_t xsdef:4; -+ uint64_t xscol:4; -+ uint64_t reserved_6_7:2; -+ uint64_t undflw:4; -+ uint64_t reserved_1_1:1; -+ uint64_t pko_nxa:1; -+ } cn52xx; -+ struct cvmx_gmxx_tx_int_reg_cn52xx cn52xxp1; -+ struct cvmx_gmxx_tx_int_reg_cn52xx cn56xx; -+ struct cvmx_gmxx_tx_int_reg_cn52xx cn56xxp1; -+ struct cvmx_gmxx_tx_int_reg_s cn58xx; -+ struct cvmx_gmxx_tx_int_reg_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_jam { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_jam_s { -+ uint64_t reserved_8_63:56; -+ uint64_t jam:8; -+ } s; -+ struct cvmx_gmxx_tx_jam_s cn30xx; -+ struct cvmx_gmxx_tx_jam_s cn31xx; -+ struct cvmx_gmxx_tx_jam_s cn38xx; -+ struct cvmx_gmxx_tx_jam_s cn38xxp2; -+ struct cvmx_gmxx_tx_jam_s cn50xx; -+ struct cvmx_gmxx_tx_jam_s cn52xx; -+ struct cvmx_gmxx_tx_jam_s cn52xxp1; -+ struct cvmx_gmxx_tx_jam_s cn56xx; -+ struct cvmx_gmxx_tx_jam_s cn56xxp1; -+ struct cvmx_gmxx_tx_jam_s cn58xx; -+ struct cvmx_gmxx_tx_jam_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_lfsr { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_lfsr_s { -+ uint64_t reserved_16_63:48; -+ uint64_t lfsr:16; -+ } s; -+ struct cvmx_gmxx_tx_lfsr_s cn30xx; -+ struct cvmx_gmxx_tx_lfsr_s cn31xx; -+ struct cvmx_gmxx_tx_lfsr_s cn38xx; -+ struct cvmx_gmxx_tx_lfsr_s cn38xxp2; -+ struct cvmx_gmxx_tx_lfsr_s cn50xx; -+ struct cvmx_gmxx_tx_lfsr_s cn52xx; -+ struct cvmx_gmxx_tx_lfsr_s cn52xxp1; -+ struct cvmx_gmxx_tx_lfsr_s cn56xx; -+ struct cvmx_gmxx_tx_lfsr_s cn56xxp1; -+ struct cvmx_gmxx_tx_lfsr_s cn58xx; -+ struct cvmx_gmxx_tx_lfsr_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_ovr_bp { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_ovr_bp_s { -+ uint64_t reserved_48_63:16; -+ uint64_t tx_prt_bp:16; -+ uint64_t reserved_12_31:20; -+ uint64_t en:4; -+ uint64_t bp:4; -+ uint64_t ign_full:4; -+ } s; -+ struct cvmx_gmxx_tx_ovr_bp_cn30xx { -+ uint64_t reserved_11_63:53; -+ uint64_t en:3; -+ uint64_t reserved_7_7:1; -+ uint64_t bp:3; -+ uint64_t reserved_3_3:1; -+ uint64_t ign_full:3; -+ } cn30xx; -+ struct cvmx_gmxx_tx_ovr_bp_cn30xx cn31xx; -+ struct cvmx_gmxx_tx_ovr_bp_cn38xx { -+ uint64_t reserved_12_63:52; -+ uint64_t en:4; -+ uint64_t bp:4; -+ uint64_t ign_full:4; -+ } cn38xx; -+ struct cvmx_gmxx_tx_ovr_bp_cn38xx cn38xxp2; -+ struct cvmx_gmxx_tx_ovr_bp_cn30xx cn50xx; -+ struct cvmx_gmxx_tx_ovr_bp_s cn52xx; -+ struct cvmx_gmxx_tx_ovr_bp_s cn52xxp1; -+ struct cvmx_gmxx_tx_ovr_bp_s cn56xx; -+ struct cvmx_gmxx_tx_ovr_bp_s cn56xxp1; -+ struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xx; -+ struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_pause_pkt_dmac { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_pause_pkt_dmac_s { -+ uint64_t reserved_48_63:16; -+ uint64_t dmac:48; -+ } s; -+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn30xx; -+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn31xx; -+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn38xx; -+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn38xxp2; -+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn50xx; -+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn52xx; -+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn52xxp1; -+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn56xx; -+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn56xxp1; -+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xx; -+ struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_pause_pkt_type { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_pause_pkt_type_s { -+ uint64_t reserved_16_63:48; -+ uint64_t type:16; -+ } s; -+ struct cvmx_gmxx_tx_pause_pkt_type_s cn30xx; -+ struct cvmx_gmxx_tx_pause_pkt_type_s cn31xx; -+ struct cvmx_gmxx_tx_pause_pkt_type_s cn38xx; -+ struct cvmx_gmxx_tx_pause_pkt_type_s cn38xxp2; -+ struct cvmx_gmxx_tx_pause_pkt_type_s cn50xx; -+ struct cvmx_gmxx_tx_pause_pkt_type_s cn52xx; -+ struct cvmx_gmxx_tx_pause_pkt_type_s cn52xxp1; -+ struct cvmx_gmxx_tx_pause_pkt_type_s cn56xx; -+ struct cvmx_gmxx_tx_pause_pkt_type_s cn56xxp1; -+ struct cvmx_gmxx_tx_pause_pkt_type_s cn58xx; -+ struct cvmx_gmxx_tx_pause_pkt_type_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_prts { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_prts_s { -+ uint64_t reserved_5_63:59; -+ uint64_t prts:5; -+ } s; -+ struct cvmx_gmxx_tx_prts_s cn30xx; -+ struct cvmx_gmxx_tx_prts_s cn31xx; -+ struct cvmx_gmxx_tx_prts_s cn38xx; -+ struct cvmx_gmxx_tx_prts_s cn38xxp2; -+ struct cvmx_gmxx_tx_prts_s cn50xx; -+ struct cvmx_gmxx_tx_prts_s cn52xx; -+ struct cvmx_gmxx_tx_prts_s cn52xxp1; -+ struct cvmx_gmxx_tx_prts_s cn56xx; -+ struct cvmx_gmxx_tx_prts_s cn56xxp1; -+ struct cvmx_gmxx_tx_prts_s cn58xx; -+ struct cvmx_gmxx_tx_prts_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_spi_ctl { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_spi_ctl_s { -+ uint64_t reserved_2_63:62; -+ uint64_t tpa_clr:1; -+ uint64_t cont_pkt:1; -+ } s; -+ struct cvmx_gmxx_tx_spi_ctl_s cn38xx; -+ struct cvmx_gmxx_tx_spi_ctl_s cn38xxp2; -+ struct cvmx_gmxx_tx_spi_ctl_s cn58xx; -+ struct cvmx_gmxx_tx_spi_ctl_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_spi_drain { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_spi_drain_s { -+ uint64_t reserved_16_63:48; -+ uint64_t drain:16; -+ } s; -+ struct cvmx_gmxx_tx_spi_drain_s cn38xx; -+ struct cvmx_gmxx_tx_spi_drain_s cn58xx; -+ struct cvmx_gmxx_tx_spi_drain_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_spi_max { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_spi_max_s { -+ uint64_t reserved_23_63:41; -+ uint64_t slice:7; -+ uint64_t max2:8; -+ uint64_t max1:8; -+ } s; -+ struct cvmx_gmxx_tx_spi_max_cn38xx { -+ uint64_t reserved_16_63:48; -+ uint64_t max2:8; -+ uint64_t max1:8; -+ } cn38xx; -+ struct cvmx_gmxx_tx_spi_max_cn38xx cn38xxp2; -+ struct cvmx_gmxx_tx_spi_max_s cn58xx; -+ struct cvmx_gmxx_tx_spi_max_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_spi_roundx { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_spi_roundx_s { -+ uint64_t reserved_16_63:48; -+ uint64_t round:16; -+ } s; -+ struct cvmx_gmxx_tx_spi_roundx_s cn58xx; -+ struct cvmx_gmxx_tx_spi_roundx_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_spi_thresh { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_spi_thresh_s { -+ uint64_t reserved_6_63:58; -+ uint64_t thresh:6; -+ } s; -+ struct cvmx_gmxx_tx_spi_thresh_s cn38xx; -+ struct cvmx_gmxx_tx_spi_thresh_s cn38xxp2; -+ struct cvmx_gmxx_tx_spi_thresh_s cn58xx; -+ struct cvmx_gmxx_tx_spi_thresh_s cn58xxp1; -+}; -+ -+union cvmx_gmxx_tx_xaui_ctl { -+ uint64_t u64; -+ struct cvmx_gmxx_tx_xaui_ctl_s { -+ uint64_t reserved_11_63:53; -+ uint64_t hg_pause_hgi:2; -+ uint64_t hg_en:1; -+ uint64_t reserved_7_7:1; -+ uint64_t ls_byp:1; -+ uint64_t ls:2; -+ uint64_t reserved_2_3:2; -+ uint64_t uni_en:1; -+ uint64_t dic_en:1; -+ } s; -+ struct cvmx_gmxx_tx_xaui_ctl_s cn52xx; -+ struct cvmx_gmxx_tx_xaui_ctl_s cn52xxp1; -+ struct cvmx_gmxx_tx_xaui_ctl_s cn56xx; -+ struct cvmx_gmxx_tx_xaui_ctl_s cn56xxp1; -+}; -+ -+union cvmx_gmxx_xaui_ext_loopback { -+ uint64_t u64; -+ struct cvmx_gmxx_xaui_ext_loopback_s { -+ uint64_t reserved_5_63:59; -+ uint64_t en:1; -+ uint64_t thresh:4; -+ } s; -+ struct cvmx_gmxx_xaui_ext_loopback_s cn52xx; -+ struct cvmx_gmxx_xaui_ext_loopback_s cn52xxp1; -+ struct cvmx_gmxx_xaui_ext_loopback_s cn56xx; -+ struct cvmx_gmxx_xaui_ext_loopback_s cn56xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-board.c -@@ -0,0 +1,706 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * -+ * Helper functions to abstract board specific data about -+ * network ports from the rest of the cvmx-helper files. -+ */ -+ -+#include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-bootinfo.h> -+ -+#include "cvmx-config.h" -+ -+#include "cvmx-mdio.h" -+ -+#include "cvmx-helper.h" -+#include "cvmx-helper-util.h" -+#include "cvmx-helper-board.h" -+ -+#include "cvmx-gmxx-defs.h" -+#include "cvmx-asxx-defs.h" -+ -+/** -+ * cvmx_override_board_link_get(int ipd_port) is a function -+ * pointer. It is meant to allow customization of the process of -+ * talking to a PHY to determine link speed. It is called every -+ * time a PHY must be polled for link status. Users should set -+ * this pointer to a function before calling any cvmx-helper -+ * operations. -+ */ -+cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port) = -+ NULL; -+ -+/** -+ * Return the MII PHY address associated with the given IPD -+ * port. A result of -1 means there isn't a MII capable PHY -+ * connected to this port. On chips supporting multiple MII -+ * busses the bus number is encoded in bits <15:8>. -+ * -+ * This function must be modified for every new Octeon board. -+ * Internally it uses switch statements based on the cvmx_sysinfo -+ * data to determine board types and revisions. It replies on the -+ * fact that every Octeon board receives a unique board type -+ * enumeration from the bootloader. -+ * -+ * @ipd_port: Octeon IPD port to get the MII address for. -+ * -+ * Returns MII PHY address and bus number or -1. -+ */ -+int cvmx_helper_board_get_mii_address(int ipd_port) -+{ -+ switch (cvmx_sysinfo_get()->board_type) { -+ case CVMX_BOARD_TYPE_SIM: -+ /* Simulator doesn't have MII */ -+ return -1; -+ case CVMX_BOARD_TYPE_EBT3000: -+ case CVMX_BOARD_TYPE_EBT5800: -+ case CVMX_BOARD_TYPE_THUNDER: -+ case CVMX_BOARD_TYPE_NICPRO2: -+ /* Interface 0 is SPI4, interface 1 is RGMII */ -+ if ((ipd_port >= 16) && (ipd_port < 20)) -+ return ipd_port - 16; -+ else -+ return -1; -+ case CVMX_BOARD_TYPE_KODAMA: -+ case CVMX_BOARD_TYPE_EBH3100: -+ case CVMX_BOARD_TYPE_HIKARI: -+ case CVMX_BOARD_TYPE_CN3010_EVB_HS5: -+ case CVMX_BOARD_TYPE_CN3005_EVB_HS5: -+ case CVMX_BOARD_TYPE_CN3020_EVB_HS5: -+ /* -+ * Port 0 is WAN connected to a PHY, Port 1 is GMII -+ * connected to a switch -+ */ -+ if (ipd_port == 0) -+ return 4; -+ else if (ipd_port == 1) -+ return 9; -+ else -+ return -1; -+ case CVMX_BOARD_TYPE_NAC38: -+ /* Board has 8 RGMII ports PHYs are 0-7 */ -+ if ((ipd_port >= 0) && (ipd_port < 4)) -+ return ipd_port; -+ else if ((ipd_port >= 16) && (ipd_port < 20)) -+ return ipd_port - 16 + 4; -+ else -+ return -1; -+ case CVMX_BOARD_TYPE_EBH3000: -+ /* Board has dual SPI4 and no PHYs */ -+ return -1; -+ case CVMX_BOARD_TYPE_EBH5200: -+ case CVMX_BOARD_TYPE_EBH5201: -+ case CVMX_BOARD_TYPE_EBT5200: -+ /* -+ * Board has 4 SGMII ports. The PHYs start right after the MII -+ * ports MII0 = 0, MII1 = 1, SGMII = 2-5. -+ */ -+ if ((ipd_port >= 0) && (ipd_port < 4)) -+ return ipd_port + 2; -+ else -+ return -1; -+ case CVMX_BOARD_TYPE_EBH5600: -+ case CVMX_BOARD_TYPE_EBH5601: -+ case CVMX_BOARD_TYPE_EBH5610: -+ /* -+ * Board has 8 SGMII ports. 4 connect out, two connect -+ * to a switch, and 2 loop to each other -+ */ -+ if ((ipd_port >= 0) && (ipd_port < 4)) -+ return ipd_port + 1; -+ else -+ return -1; -+ case CVMX_BOARD_TYPE_CUST_NB5: -+ if (ipd_port == 2) -+ return 4; -+ else -+ return -1; -+ case CVMX_BOARD_TYPE_NIC_XLE_4G: -+ /* Board has 4 SGMII ports. connected QLM3(interface 1) */ -+ if ((ipd_port >= 16) && (ipd_port < 20)) -+ return ipd_port - 16 + 1; -+ else -+ return -1; -+ case CVMX_BOARD_TYPE_BBGW_REF: -+ /* -+ * No PHYs are connected to Octeon, everything is -+ * through switch. -+ */ -+ return -1; -+ } -+ -+ /* Some unknown board. Somebody forgot to update this function... */ -+ cvmx_dprintf -+ ("cvmx_helper_board_get_mii_address: Unknown board type %d\n", -+ cvmx_sysinfo_get()->board_type); -+ return -1; -+} -+ -+/** -+ * This function is the board specific method of determining an -+ * ethernet ports link speed. Most Octeon boards have Marvell PHYs -+ * and are handled by the fall through case. This function must be -+ * updated for boards that don't have the normal Marvell PHYs. -+ * -+ * This function must be modified for every new Octeon board. -+ * Internally it uses switch statements based on the cvmx_sysinfo -+ * data to determine board types and revisions. It relies on the -+ * fact that every Octeon board receives a unique board type -+ * enumeration from the bootloader. -+ * -+ * @ipd_port: IPD input port associated with the port we want to get link -+ * status for. -+ * -+ * Returns The ports link status. If the link isn't fully resolved, this must -+ * return zero. -+ */ -+cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) -+{ -+ cvmx_helper_link_info_t result; -+ int phy_addr; -+ int is_broadcom_phy = 0; -+ -+ /* Give the user a chance to override the processing of this function */ -+ if (cvmx_override_board_link_get) -+ return cvmx_override_board_link_get(ipd_port); -+ -+ /* Unless we fix it later, all links are defaulted to down */ -+ result.u64 = 0; -+ -+ /* -+ * This switch statement should handle all ports that either don't use -+ * Marvell PHYS, or don't support in-band status. -+ */ -+ switch (cvmx_sysinfo_get()->board_type) { -+ case CVMX_BOARD_TYPE_SIM: -+ /* The simulator gives you a simulated 1Gbps full duplex link */ -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 1000; -+ return result; -+ case CVMX_BOARD_TYPE_EBH3100: -+ case CVMX_BOARD_TYPE_CN3010_EVB_HS5: -+ case CVMX_BOARD_TYPE_CN3005_EVB_HS5: -+ case CVMX_BOARD_TYPE_CN3020_EVB_HS5: -+ /* Port 1 on these boards is always Gigabit */ -+ if (ipd_port == 1) { -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 1000; -+ return result; -+ } -+ /* Fall through to the generic code below */ -+ break; -+ case CVMX_BOARD_TYPE_CUST_NB5: -+ /* Port 1 on these boards is always Gigabit */ -+ if (ipd_port == 1) { -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 1000; -+ return result; -+ } else /* The other port uses a broadcom PHY */ -+ is_broadcom_phy = 1; -+ break; -+ case CVMX_BOARD_TYPE_BBGW_REF: -+ /* Port 1 on these boards is always Gigabit */ -+ if (ipd_port == 2) { -+ /* Port 2 is not hooked up */ -+ result.u64 = 0; -+ return result; -+ } else { -+ /* Ports 0 and 1 connect to the switch */ -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 1000; -+ return result; -+ } -+ break; -+ } -+ -+ phy_addr = cvmx_helper_board_get_mii_address(ipd_port); -+ if (phy_addr != -1) { -+ if (is_broadcom_phy) { -+ /* -+ * Below we are going to read SMI/MDIO -+ * register 0x19 which works on Broadcom -+ * parts -+ */ -+ int phy_status = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ 0x19); -+ switch ((phy_status >> 8) & 0x7) { -+ case 0: -+ result.u64 = 0; -+ break; -+ case 1: -+ result.s.link_up = 1; -+ result.s.full_duplex = 0; -+ result.s.speed = 10; -+ break; -+ case 2: -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 10; -+ break; -+ case 3: -+ result.s.link_up = 1; -+ result.s.full_duplex = 0; -+ result.s.speed = 100; -+ break; -+ case 4: -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 100; -+ break; -+ case 5: -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 100; -+ break; -+ case 6: -+ result.s.link_up = 1; -+ result.s.full_duplex = 0; -+ result.s.speed = 1000; -+ break; -+ case 7: -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 1000; -+ break; -+ } -+ } else { -+ /* -+ * This code assumes we are using a Marvell -+ * Gigabit PHY. All the speed information can -+ * be read from register 17 in one -+ * go. Somebody using a different PHY will -+ * need to handle it above in the board -+ * specific area. -+ */ -+ int phy_status = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, 17); -+ -+ /* -+ * If the resolve bit 11 isn't set, see if -+ * autoneg is turned off (bit 12, reg 0). The -+ * resolve bit doesn't get set properly when -+ * autoneg is off, so force it. -+ */ -+ if ((phy_status & (1 << 11)) == 0) { -+ int auto_status = -+ cvmx_mdio_read(phy_addr >> 8, -+ phy_addr & 0xff, 0); -+ if ((auto_status & (1 << 12)) == 0) -+ phy_status |= 1 << 11; -+ } -+ -+ /* -+ * Only return a link if the PHY has finished -+ * auto negotiation and set the resolved bit -+ * (bit 11) -+ */ -+ if (phy_status & (1 << 11)) { -+ result.s.link_up = 1; -+ result.s.full_duplex = ((phy_status >> 13) & 1); -+ switch ((phy_status >> 14) & 3) { -+ case 0: /* 10 Mbps */ -+ result.s.speed = 10; -+ break; -+ case 1: /* 100 Mbps */ -+ result.s.speed = 100; -+ break; -+ case 2: /* 1 Gbps */ -+ result.s.speed = 1000; -+ break; -+ case 3: /* Illegal */ -+ result.u64 = 0; -+ break; -+ } -+ } -+ } -+ } else if (OCTEON_IS_MODEL(OCTEON_CN3XXX) -+ || OCTEON_IS_MODEL(OCTEON_CN58XX) -+ || OCTEON_IS_MODEL(OCTEON_CN50XX)) { -+ /* -+ * We don't have a PHY address, so attempt to use -+ * in-band status. It is really important that boards -+ * not supporting in-band status never get -+ * here. Reading broken in-band status tends to do bad -+ * things -+ */ -+ union cvmx_gmxx_rxx_rx_inbnd inband_status; -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ int index = cvmx_helper_get_interface_index_num(ipd_port); -+ inband_status.u64 = -+ cvmx_read_csr(CVMX_GMXX_RXX_RX_INBND(index, interface)); -+ -+ result.s.link_up = inband_status.s.status; -+ result.s.full_duplex = inband_status.s.duplex; -+ switch (inband_status.s.speed) { -+ case 0: /* 10 Mbps */ -+ result.s.speed = 10; -+ break; -+ case 1: /* 100 Mbps */ -+ result.s.speed = 100; -+ break; -+ case 2: /* 1 Gbps */ -+ result.s.speed = 1000; -+ break; -+ case 3: /* Illegal */ -+ result.u64 = 0; -+ break; -+ } -+ } else { -+ /* -+ * We don't have a PHY address and we don't have -+ * in-band status. There is no way to determine the -+ * link speed. Return down assuming this port isn't -+ * wired -+ */ -+ result.u64 = 0; -+ } -+ -+ /* If link is down, return all fields as zero. */ -+ if (!result.s.link_up) -+ result.u64 = 0; -+ -+ return result; -+} -+ -+/** -+ * This function as a board specific method of changing the PHY -+ * speed, duplex, and auto-negotiation. This programs the PHY and -+ * not Octeon. This can be used to force Octeon's links to -+ * specific settings. -+ * -+ * @phy_addr: The address of the PHY to program -+ * @enable_autoneg: -+ * Non zero if you want to enable auto-negotiation. -+ * @link_info: Link speed to program. If the speed is zero and auto-negotiation -+ * is enabled, all possible negotiation speeds are advertised. -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int cvmx_helper_board_link_set_phy(int phy_addr, -+ cvmx_helper_board_set_phy_link_flags_types_t -+ link_flags, -+ cvmx_helper_link_info_t link_info) -+{ -+ -+ /* Set the flow control settings based on link_flags */ -+ if ((link_flags & set_phy_link_flags_flow_control_mask) != -+ set_phy_link_flags_flow_control_dont_touch) { -+ cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver; -+ reg_autoneg_adver.u16 = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_AUTONEG_ADVER); -+ reg_autoneg_adver.s.asymmetric_pause = -+ (link_flags & set_phy_link_flags_flow_control_mask) == -+ set_phy_link_flags_flow_control_enable; -+ reg_autoneg_adver.s.pause = -+ (link_flags & set_phy_link_flags_flow_control_mask) == -+ set_phy_link_flags_flow_control_enable; -+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_AUTONEG_ADVER, -+ reg_autoneg_adver.u16); -+ } -+ -+ /* If speed isn't set and autoneg is on advertise all supported modes */ -+ if ((link_flags & set_phy_link_flags_autoneg) -+ && (link_info.s.speed == 0)) { -+ cvmx_mdio_phy_reg_control_t reg_control; -+ cvmx_mdio_phy_reg_status_t reg_status; -+ cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver; -+ cvmx_mdio_phy_reg_extended_status_t reg_extended_status; -+ cvmx_mdio_phy_reg_control_1000_t reg_control_1000; -+ -+ reg_status.u16 = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_STATUS); -+ reg_autoneg_adver.u16 = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_AUTONEG_ADVER); -+ reg_autoneg_adver.s.advert_100base_t4 = -+ reg_status.s.capable_100base_t4; -+ reg_autoneg_adver.s.advert_10base_tx_full = -+ reg_status.s.capable_10_full; -+ reg_autoneg_adver.s.advert_10base_tx_half = -+ reg_status.s.capable_10_half; -+ reg_autoneg_adver.s.advert_100base_tx_full = -+ reg_status.s.capable_100base_x_full; -+ reg_autoneg_adver.s.advert_100base_tx_half = -+ reg_status.s.capable_100base_x_half; -+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_AUTONEG_ADVER, -+ reg_autoneg_adver.u16); -+ if (reg_status.s.capable_extended_status) { -+ reg_extended_status.u16 = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_EXTENDED_STATUS); -+ reg_control_1000.u16 = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_CONTROL_1000); -+ reg_control_1000.s.advert_1000base_t_full = -+ reg_extended_status.s.capable_1000base_t_full; -+ reg_control_1000.s.advert_1000base_t_half = -+ reg_extended_status.s.capable_1000base_t_half; -+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_CONTROL_1000, -+ reg_control_1000.u16); -+ } -+ reg_control.u16 = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_CONTROL); -+ reg_control.s.autoneg_enable = 1; -+ reg_control.s.restart_autoneg = 1; -+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16); -+ } else if ((link_flags & set_phy_link_flags_autoneg)) { -+ cvmx_mdio_phy_reg_control_t reg_control; -+ cvmx_mdio_phy_reg_status_t reg_status; -+ cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver; -+ cvmx_mdio_phy_reg_extended_status_t reg_extended_status; -+ cvmx_mdio_phy_reg_control_1000_t reg_control_1000; -+ -+ reg_status.u16 = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_STATUS); -+ reg_autoneg_adver.u16 = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_AUTONEG_ADVER); -+ reg_autoneg_adver.s.advert_100base_t4 = 0; -+ reg_autoneg_adver.s.advert_10base_tx_full = 0; -+ reg_autoneg_adver.s.advert_10base_tx_half = 0; -+ reg_autoneg_adver.s.advert_100base_tx_full = 0; -+ reg_autoneg_adver.s.advert_100base_tx_half = 0; -+ if (reg_status.s.capable_extended_status) { -+ reg_extended_status.u16 = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_EXTENDED_STATUS); -+ reg_control_1000.u16 = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_CONTROL_1000); -+ reg_control_1000.s.advert_1000base_t_full = 0; -+ reg_control_1000.s.advert_1000base_t_half = 0; -+ } -+ switch (link_info.s.speed) { -+ case 10: -+ reg_autoneg_adver.s.advert_10base_tx_full = -+ link_info.s.full_duplex; -+ reg_autoneg_adver.s.advert_10base_tx_half = -+ !link_info.s.full_duplex; -+ break; -+ case 100: -+ reg_autoneg_adver.s.advert_100base_tx_full = -+ link_info.s.full_duplex; -+ reg_autoneg_adver.s.advert_100base_tx_half = -+ !link_info.s.full_duplex; -+ break; -+ case 1000: -+ reg_control_1000.s.advert_1000base_t_full = -+ link_info.s.full_duplex; -+ reg_control_1000.s.advert_1000base_t_half = -+ !link_info.s.full_duplex; -+ break; -+ } -+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_AUTONEG_ADVER, -+ reg_autoneg_adver.u16); -+ if (reg_status.s.capable_extended_status) -+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_CONTROL_1000, -+ reg_control_1000.u16); -+ reg_control.u16 = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_CONTROL); -+ reg_control.s.autoneg_enable = 1; -+ reg_control.s.restart_autoneg = 1; -+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16); -+ } else { -+ cvmx_mdio_phy_reg_control_t reg_control; -+ reg_control.u16 = -+ cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_CONTROL); -+ reg_control.s.autoneg_enable = 0; -+ reg_control.s.restart_autoneg = 1; -+ reg_control.s.duplex = link_info.s.full_duplex; -+ if (link_info.s.speed == 1000) { -+ reg_control.s.speed_msb = 1; -+ reg_control.s.speed_lsb = 0; -+ } else if (link_info.s.speed == 100) { -+ reg_control.s.speed_msb = 0; -+ reg_control.s.speed_lsb = 1; -+ } else if (link_info.s.speed == 10) { -+ reg_control.s.speed_msb = 0; -+ reg_control.s.speed_lsb = 0; -+ } -+ cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, -+ CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16); -+ } -+ return 0; -+} -+ -+/** -+ * This function is called by cvmx_helper_interface_probe() after it -+ * determines the number of ports Octeon can support on a specific -+ * interface. This function is the per board location to override -+ * this value. It is called with the number of ports Octeon might -+ * support and should return the number of actual ports on the -+ * board. -+ * -+ * This function must be modifed for every new Octeon board. -+ * Internally it uses switch statements based on the cvmx_sysinfo -+ * data to determine board types and revisions. It relys on the -+ * fact that every Octeon board receives a unique board type -+ * enumeration from the bootloader. -+ * -+ * @interface: Interface to probe -+ * @supported_ports: -+ * Number of ports Octeon supports. -+ * -+ * Returns Number of ports the actual board supports. Many times this will -+ * simple be "support_ports". -+ */ -+int __cvmx_helper_board_interface_probe(int interface, int supported_ports) -+{ -+ switch (cvmx_sysinfo_get()->board_type) { -+ case CVMX_BOARD_TYPE_CN3005_EVB_HS5: -+ if (interface == 0) -+ return 2; -+ break; -+ case CVMX_BOARD_TYPE_BBGW_REF: -+ if (interface == 0) -+ return 2; -+ break; -+ case CVMX_BOARD_TYPE_NIC_XLE_4G: -+ if (interface == 0) -+ return 0; -+ break; -+ /* The 2nd interface on the EBH5600 is connected to the Marvel switch, -+ which we don't support. Disable ports connected to it */ -+ case CVMX_BOARD_TYPE_EBH5600: -+ if (interface == 1) -+ return 0; -+ break; -+ } -+ return supported_ports; -+} -+ -+/** -+ * Enable packet input/output from the hardware. This function is -+ * called after by cvmx_helper_packet_hardware_enable() to -+ * perform board specific initialization. For most boards -+ * nothing is needed. -+ * -+ * @interface: Interface to enable -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_board_hardware_enable(int interface) -+{ -+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5) { -+ if (interface == 0) { -+ /* Different config for switch port */ -+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0); -+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0); -+ /* -+ * Boards with gigabit WAN ports need a -+ * different setting that is compatible with -+ * 100 Mbit settings -+ */ -+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), -+ 0xc); -+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), -+ 0xc); -+ } -+ } else if (cvmx_sysinfo_get()->board_type == -+ CVMX_BOARD_TYPE_CN3010_EVB_HS5) { -+ /* -+ * Broadcom PHYs require differnet ASX -+ * clocks. Unfortunately many boards don't define a -+ * new board Id and simply mangle the -+ * CN3010_EVB_HS5 -+ */ -+ if (interface == 0) { -+ /* -+ * Some boards use a hacked up bootloader that -+ * identifies them as CN3010_EVB_HS5 -+ * evaluation boards. This leads to all kinds -+ * of configuration problems. Detect one -+ * case, and print warning, while trying to do -+ * the right thing. -+ */ -+ int phy_addr = cvmx_helper_board_get_mii_address(0); -+ if (phy_addr != -1) { -+ int phy_identifier = -+ cvmx_mdio_read(phy_addr >> 8, -+ phy_addr & 0xff, 0x2); -+ /* Is it a Broadcom PHY? */ -+ if (phy_identifier == 0x0143) { -+ cvmx_dprintf("\n"); -+ cvmx_dprintf("ERROR:\n"); -+ cvmx_dprintf -+ ("ERROR: Board type is CVMX_BOARD_TYPE_CN3010_EVB_HS5, but Broadcom PHY found.\n"); -+ cvmx_dprintf -+ ("ERROR: The board type is mis-configured, and software malfunctions are likely.\n"); -+ cvmx_dprintf -+ ("ERROR: All boards require a unique board type to identify them.\n"); -+ cvmx_dprintf("ERROR:\n"); -+ cvmx_dprintf("\n"); -+ cvmx_wait(1000000000); -+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX -+ (0, interface), 5); -+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX -+ (0, interface), 5); -+ } -+ } -+ } -+ } -+ return 0; -+} -+ -+cvmx_helper_board_usb_clock_types_t __cvmx_helper_board_usb_get_clock_type(void) -+{ -+ switch (cvmx_sysinfo_get()->board_type) { -+ case CVMX_BOARD_TYPE_BBGW_REF: -+ return USB_CLOCK_TYPE_CRYSTAL_12; -+ } -+ return USB_CLOCK_TYPE_REF_48; -+} -+ -+int __cvmx_helper_board_usb_get_num_ports(int supported_ports) -+{ -+ switch (cvmx_sysinfo_get()->board_type) { -+ case CVMX_BOARD_TYPE_NIC_XLE_4G: -+ return 0; -+ } -+ -+ return supported_ports; -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-board.h -@@ -0,0 +1,180 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * Helper functions to abstract board specific data about -+ * network ports from the rest of the cvmx-helper files. -+ * -+ */ -+#ifndef __CVMX_HELPER_BOARD_H__ -+#define __CVMX_HELPER_BOARD_H__ -+ -+#include "cvmx-helper.h" -+ -+typedef enum { -+ USB_CLOCK_TYPE_REF_12, -+ USB_CLOCK_TYPE_REF_24, -+ USB_CLOCK_TYPE_REF_48, -+ USB_CLOCK_TYPE_CRYSTAL_12, -+} cvmx_helper_board_usb_clock_types_t; -+ -+typedef enum { -+ set_phy_link_flags_autoneg = 0x1, -+ set_phy_link_flags_flow_control_dont_touch = 0x0 << 1, -+ set_phy_link_flags_flow_control_enable = 0x1 << 1, -+ set_phy_link_flags_flow_control_disable = 0x2 << 1, -+ set_phy_link_flags_flow_control_mask = 0x3 << 1, /* Mask for 2 bit wide flow control field */ -+} cvmx_helper_board_set_phy_link_flags_types_t; -+ -+/** -+ * cvmx_override_board_link_get(int ipd_port) is a function -+ * pointer. It is meant to allow customization of the process of -+ * talking to a PHY to determine link speed. It is called every -+ * time a PHY must be polled for link status. Users should set -+ * this pointer to a function before calling any cvmx-helper -+ * operations. -+ */ -+extern cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port); -+ -+/** -+ * Return the MII PHY address associated with the given IPD -+ * port. A result of -1 means there isn't a MII capable PHY -+ * connected to this port. On chips supporting multiple MII -+ * busses the bus number is encoded in bits <15:8>. -+ * -+ * This function must be modifed for every new Octeon board. -+ * Internally it uses switch statements based on the cvmx_sysinfo -+ * data to determine board types and revisions. It relys on the -+ * fact that every Octeon board receives a unique board type -+ * enumeration from the bootloader. -+ * -+ * @ipd_port: Octeon IPD port to get the MII address for. -+ * -+ * Returns MII PHY address and bus number or -1. -+ */ -+extern int cvmx_helper_board_get_mii_address(int ipd_port); -+ -+/** -+ * This function as a board specific method of changing the PHY -+ * speed, duplex, and autonegotiation. This programs the PHY and -+ * not Octeon. This can be used to force Octeon's links to -+ * specific settings. -+ * -+ * @phy_addr: The address of the PHY to program -+ * @link_flags: -+ * Flags to control autonegotiation. Bit 0 is autonegotiation -+ * enable/disable to maintain backware compatability. -+ * @link_info: Link speed to program. If the speed is zero and autonegotiation -+ * is enabled, all possible negotiation speeds are advertised. -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int cvmx_helper_board_link_set_phy(int phy_addr, -+ cvmx_helper_board_set_phy_link_flags_types_t -+ link_flags, -+ cvmx_helper_link_info_t link_info); -+ -+/** -+ * This function is the board specific method of determining an -+ * ethernet ports link speed. Most Octeon boards have Marvell PHYs -+ * and are handled by the fall through case. This function must be -+ * updated for boards that don't have the normal Marvell PHYs. -+ * -+ * This function must be modifed for every new Octeon board. -+ * Internally it uses switch statements based on the cvmx_sysinfo -+ * data to determine board types and revisions. It relys on the -+ * fact that every Octeon board receives a unique board type -+ * enumeration from the bootloader. -+ * -+ * @ipd_port: IPD input port associated with the port we want to get link -+ * status for. -+ * -+ * Returns The ports link status. If the link isn't fully resolved, this must -+ * return zero. -+ */ -+extern cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port); -+ -+/** -+ * This function is called by cvmx_helper_interface_probe() after it -+ * determines the number of ports Octeon can support on a specific -+ * interface. This function is the per board location to override -+ * this value. It is called with the number of ports Octeon might -+ * support and should return the number of actual ports on the -+ * board. -+ * -+ * This function must be modifed for every new Octeon board. -+ * Internally it uses switch statements based on the cvmx_sysinfo -+ * data to determine board types and revisions. It relys on the -+ * fact that every Octeon board receives a unique board type -+ * enumeration from the bootloader. -+ * -+ * @interface: Interface to probe -+ * @supported_ports: -+ * Number of ports Octeon supports. -+ * -+ * Returns Number of ports the actual board supports. Many times this will -+ * simple be "support_ports". -+ */ -+extern int __cvmx_helper_board_interface_probe(int interface, -+ int supported_ports); -+ -+/** -+ * Enable packet input/output from the hardware. This function is -+ * called after by cvmx_helper_packet_hardware_enable() to -+ * perform board specific initialization. For most boards -+ * nothing is needed. -+ * -+ * @interface: Interface to enable -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_board_hardware_enable(int interface); -+ -+/** -+ * Gets the clock type used for the USB block based on board type. -+ * Used by the USB code for auto configuration of clock type. -+ * -+ * Returns USB clock type enumeration -+ */ -+cvmx_helper_board_usb_clock_types_t -+__cvmx_helper_board_usb_get_clock_type(void); -+ -+/** -+ * Adjusts the number of available USB ports on Octeon based on board -+ * specifics. -+ * -+ * @supported_ports: expected number of ports based on chip type; -+ * -+ * -+ * Returns number of available usb ports, based on board specifics. -+ * Return value is supported_ports if function does not -+ * override. -+ */ -+int __cvmx_helper_board_usb_get_num_ports(int supported_ports); -+ -+#endif /* __CVMX_HELPER_BOARD_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-fpa.c -@@ -0,0 +1,243 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * @file -+ * -+ * Helper functions for FPA setup. -+ * -+ */ -+#include "executive-config.h" -+#include "cvmx-config.h" -+#include "cvmx.h" -+#include "cvmx-bootmem.h" -+#include "cvmx-fpa.h" -+#include "cvmx-helper-fpa.h" -+ -+/** -+ * Allocate memory for and initialize a single FPA pool. -+ * -+ * @pool: Pool to initialize -+ * @buffer_size: Size of buffers to allocate in bytes -+ * @buffers: Number of buffers to put in the pool. Zero is allowed -+ * @name: String name of the pool for debugging purposes -+ * Returns Zero on success, non-zero on failure -+ */ -+static int __cvmx_helper_initialize_fpa_pool(int pool, uint64_t buffer_size, -+ uint64_t buffers, const char *name) -+{ -+ uint64_t current_num; -+ void *memory; -+ uint64_t align = CVMX_CACHE_LINE_SIZE; -+ -+ /* -+ * Align the allocation so that power of 2 size buffers are -+ * naturally aligned. -+ */ -+ while (align < buffer_size) -+ align = align << 1; -+ -+ if (buffers == 0) -+ return 0; -+ -+ current_num = cvmx_read_csr(CVMX_FPA_QUEX_AVAILABLE(pool)); -+ if (current_num) { -+ cvmx_dprintf("Fpa pool %d(%s) already has %llu buffers. " -+ "Skipping setup.\n", -+ pool, name, (unsigned long long)current_num); -+ return 0; -+ } -+ -+ memory = cvmx_bootmem_alloc(buffer_size * buffers, align); -+ if (memory == NULL) { -+ cvmx_dprintf("Out of memory initializing fpa pool %d(%s).\n", -+ pool, name); -+ return -1; -+ } -+ cvmx_fpa_setup_pool(pool, name, memory, buffer_size, buffers); -+ return 0; -+} -+ -+/** -+ * Allocate memory and initialize the FPA pools using memory -+ * from cvmx-bootmem. Specifying zero for the number of -+ * buffers will cause that FPA pool to not be setup. This is -+ * useful if you aren't using some of the hardware and want -+ * to save memory. Use cvmx_helper_initialize_fpa instead of -+ * this function directly. -+ * -+ * @pip_pool: Should always be CVMX_FPA_PACKET_POOL -+ * @pip_size: Should always be CVMX_FPA_PACKET_POOL_SIZE -+ * @pip_buffers: -+ * Number of packet buffers. -+ * @wqe_pool: Should always be CVMX_FPA_WQE_POOL -+ * @wqe_size: Should always be CVMX_FPA_WQE_POOL_SIZE -+ * @wqe_entries: -+ * Number of work queue entries -+ * @pko_pool: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL -+ * @pko_size: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE -+ * @pko_buffers: -+ * PKO Command buffers. You should at minimum have two per -+ * each PKO queue. -+ * @tim_pool: Should always be CVMX_FPA_TIMER_POOL -+ * @tim_size: Should always be CVMX_FPA_TIMER_POOL_SIZE -+ * @tim_buffers: -+ * TIM ring buffer command queues. At least two per timer bucket -+ * is recommened. -+ * @dfa_pool: Should always be CVMX_FPA_DFA_POOL -+ * @dfa_size: Should always be CVMX_FPA_DFA_POOL_SIZE -+ * @dfa_buffers: -+ * DFA command buffer. A relatively small (32 for example) -+ * number should work. -+ * Returns Zero on success, non-zero if out of memory -+ */ -+static int __cvmx_helper_initialize_fpa(int pip_pool, int pip_size, -+ int pip_buffers, int wqe_pool, -+ int wqe_size, int wqe_entries, -+ int pko_pool, int pko_size, -+ int pko_buffers, int tim_pool, -+ int tim_size, int tim_buffers, -+ int dfa_pool, int dfa_size, -+ int dfa_buffers) -+{ -+ int status; -+ -+ cvmx_fpa_enable(); -+ -+ if ((pip_buffers > 0) && (pip_buffers <= 64)) -+ cvmx_dprintf -+ ("Warning: %d packet buffers may not be enough for hardware" -+ " prefetch. 65 or more is recommended.\n", pip_buffers); -+ -+ if (pip_pool >= 0) { -+ status = -+ __cvmx_helper_initialize_fpa_pool(pip_pool, pip_size, -+ pip_buffers, -+ "Packet Buffers"); -+ if (status) -+ return status; -+ } -+ -+ if (wqe_pool >= 0) { -+ status = -+ __cvmx_helper_initialize_fpa_pool(wqe_pool, wqe_size, -+ wqe_entries, -+ "Work Queue Entries"); -+ if (status) -+ return status; -+ } -+ -+ if (pko_pool >= 0) { -+ status = -+ __cvmx_helper_initialize_fpa_pool(pko_pool, pko_size, -+ pko_buffers, -+ "PKO Command Buffers"); -+ if (status) -+ return status; -+ } -+ -+ if (tim_pool >= 0) { -+ status = -+ __cvmx_helper_initialize_fpa_pool(tim_pool, tim_size, -+ tim_buffers, -+ "TIM Command Buffers"); -+ if (status) -+ return status; -+ } -+ -+ if (dfa_pool >= 0) { -+ status = -+ __cvmx_helper_initialize_fpa_pool(dfa_pool, dfa_size, -+ dfa_buffers, -+ "DFA Command Buffers"); -+ if (status) -+ return status; -+ } -+ -+ return 0; -+} -+ -+/** -+ * Allocate memory and initialize the FPA pools using memory -+ * from cvmx-bootmem. Sizes of each element in the pools is -+ * controlled by the cvmx-config.h header file. Specifying -+ * zero for any parameter will cause that FPA pool to not be -+ * setup. This is useful if you aren't using some of the -+ * hardware and want to save memory. -+ * -+ * @packet_buffers: -+ * Number of packet buffers to allocate -+ * @work_queue_entries: -+ * Number of work queue entries -+ * @pko_buffers: -+ * PKO Command buffers. You should at minimum have two per -+ * each PKO queue. -+ * @tim_buffers: -+ * TIM ring buffer command queues. At least two per timer bucket -+ * is recommened. -+ * @dfa_buffers: -+ * DFA command buffer. A relatively small (32 for example) -+ * number should work. -+ * Returns Zero on success, non-zero if out of memory -+ */ -+int cvmx_helper_initialize_fpa(int packet_buffers, int work_queue_entries, -+ int pko_buffers, int tim_buffers, -+ int dfa_buffers) -+{ -+#ifndef CVMX_FPA_PACKET_POOL -+#define CVMX_FPA_PACKET_POOL -1 -+#define CVMX_FPA_PACKET_POOL_SIZE 0 -+#endif -+#ifndef CVMX_FPA_WQE_POOL -+#define CVMX_FPA_WQE_POOL -1 -+#define CVMX_FPA_WQE_POOL_SIZE 0 -+#endif -+#ifndef CVMX_FPA_OUTPUT_BUFFER_POOL -+#define CVMX_FPA_OUTPUT_BUFFER_POOL -1 -+#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE 0 -+#endif -+#ifndef CVMX_FPA_TIMER_POOL -+#define CVMX_FPA_TIMER_POOL -1 -+#define CVMX_FPA_TIMER_POOL_SIZE 0 -+#endif -+#ifndef CVMX_FPA_DFA_POOL -+#define CVMX_FPA_DFA_POOL -1 -+#define CVMX_FPA_DFA_POOL_SIZE 0 -+#endif -+ return __cvmx_helper_initialize_fpa(CVMX_FPA_PACKET_POOL, -+ CVMX_FPA_PACKET_POOL_SIZE, -+ packet_buffers, CVMX_FPA_WQE_POOL, -+ CVMX_FPA_WQE_POOL_SIZE, -+ work_queue_entries, -+ CVMX_FPA_OUTPUT_BUFFER_POOL, -+ CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, -+ pko_buffers, CVMX_FPA_TIMER_POOL, -+ CVMX_FPA_TIMER_POOL_SIZE, -+ tim_buffers, CVMX_FPA_DFA_POOL, -+ CVMX_FPA_DFA_POOL_SIZE, -+ dfa_buffers); -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-fpa.h -@@ -0,0 +1,64 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * @file -+ * -+ * Helper functions for FPA setup. -+ * -+ */ -+#ifndef __CVMX_HELPER_H_FPA__ -+#define __CVMX_HELPER_H_FPA__ -+ -+/** -+ * Allocate memory and initialize the FPA pools using memory -+ * from cvmx-bootmem. Sizes of each element in the pools is -+ * controlled by the cvmx-config.h header file. Specifying -+ * zero for any parameter will cause that FPA pool to not be -+ * setup. This is useful if you aren't using some of the -+ * hardware and want to save memory. -+ * -+ * @packet_buffers: -+ * Number of packet buffers to allocate -+ * @work_queue_entries: -+ * Number of work queue entries -+ * @pko_buffers: -+ * PKO Command buffers. You should at minimum have two per -+ * each PKO queue. -+ * @tim_buffers: -+ * TIM ring buffer command queues. At least two per timer bucket -+ * is recommened. -+ * @dfa_buffers: -+ * DFA command buffer. A relatively small (32 for example) -+ * number should work. -+ * Returns Zero on success, non-zero if out of memory -+ */ -+extern int cvmx_helper_initialize_fpa(int packet_buffers, -+ int work_queue_entries, int pko_buffers, -+ int tim_buffers, int dfa_buffers); -+ -+#endif /* __CVMX_HELPER_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-loop.c -@@ -0,0 +1,85 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * Functions for LOOP initialization, configuration, -+ * and monitoring. -+ */ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-config.h" -+ -+#include "cvmx-helper.h" -+#include "cvmx-pip-defs.h" -+ -+/** -+ * Probe a LOOP interface and determine the number of ports -+ * connected to it. The LOOP interface should still be down -+ * after this call. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Number of ports on the interface. Zero to disable. -+ */ -+int __cvmx_helper_loop_probe(int interface) -+{ -+ union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs; -+ int num_ports = 4; -+ int port; -+ -+ /* We need to disable length checking so packet < 64 bytes and jumbo -+ frames don't get errors */ -+ for (port = 0; port < num_ports; port++) { -+ union cvmx_pip_prt_cfgx port_cfg; -+ int ipd_port = cvmx_helper_get_ipd_port(interface, port); -+ port_cfg.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port)); -+ port_cfg.s.maxerr_en = 0; -+ port_cfg.s.minerr_en = 0; -+ cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_cfg.u64); -+ } -+ -+ /* Disable FCS stripping for loopback ports */ -+ ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS); -+ ipd_sub_port_fcs.s.port_bit2 = 0; -+ cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64); -+ return num_ports; -+} -+ -+/** -+ * Bringup and enable a LOOP interface. After this call packet -+ * I/O should be fully functional. This is called with IPD -+ * enabled but PKO disabled. -+ * -+ * @interface: Interface to bring up -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_loop_enable(int interface) -+{ -+ /* Do nothing. */ -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-loop.h -@@ -0,0 +1,59 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as published by -+ * the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, -+ * but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT. -+ * See the GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * @file -+ * -+ * Functions for LOOP initialization, configuration, -+ * and monitoring. -+ * -+ */ -+#ifndef __CVMX_HELPER_LOOP_H__ -+#define __CVMX_HELPER_LOOP_H__ -+ -+/** -+ * Probe a LOOP interface and determine the number of ports -+ * connected to it. The LOOP interface should still be down after -+ * this call. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Number of ports on the interface. Zero to disable. -+ */ -+extern int __cvmx_helper_loop_probe(int interface); -+ -+/** -+ * Bringup and enable a LOOP interface. After this call packet -+ * I/O should be fully functional. This is called with IPD -+ * enabled but PKO disabled. -+ * -+ * @interface: Interface to bring up -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_loop_enable(int interface); -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-npi.c -@@ -0,0 +1,113 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * Functions for NPI initialization, configuration, -+ * and monitoring. -+ */ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-config.h" -+ -+#include "cvmx-helper.h" -+ -+#include "cvmx-pip-defs.h" -+ -+/** -+ * Probe a NPI interface and determine the number of ports -+ * connected to it. The NPI interface should still be down -+ * after this call. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Number of ports on the interface. Zero to disable. -+ */ -+int __cvmx_helper_npi_probe(int interface) -+{ -+#if CVMX_PKO_QUEUES_PER_PORT_PCI > 0 -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) -+ return 4; -+ else if (OCTEON_IS_MODEL(OCTEON_CN56XX) -+ && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)) -+ /* The packet engines didn't exist before pass 2 */ -+ return 4; -+ else if (OCTEON_IS_MODEL(OCTEON_CN52XX) -+ && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) -+ /* The packet engines didn't exist before pass 2 */ -+ return 4; -+#if 0 -+ /* -+ * Technically CN30XX, CN31XX, and CN50XX contain packet -+ * engines, but nobody ever uses them. Since this is the case, -+ * we disable them here. -+ */ -+ else if (OCTEON_IS_MODEL(OCTEON_CN31XX) -+ || OCTEON_IS_MODEL(OCTEON_CN50XX)) -+ return 2; -+ else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) -+ return 1; -+#endif -+#endif -+ return 0; -+} -+ -+/** -+ * Bringup and enable a NPI interface. After this call packet -+ * I/O should be fully functional. This is called with IPD -+ * enabled but PKO disabled. -+ * -+ * @interface: Interface to bring up -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_npi_enable(int interface) -+{ -+ /* -+ * On CN50XX, CN52XX, and CN56XX we need to disable length -+ * checking so packet < 64 bytes and jumbo frames don't get -+ * errors. -+ */ -+ if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) && -+ !OCTEON_IS_MODEL(OCTEON_CN58XX)) { -+ int num_ports = cvmx_helper_ports_on_interface(interface); -+ int port; -+ for (port = 0; port < num_ports; port++) { -+ union cvmx_pip_prt_cfgx port_cfg; -+ int ipd_port = -+ cvmx_helper_get_ipd_port(interface, port); -+ port_cfg.u64 = -+ cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port)); -+ port_cfg.s.maxerr_en = 0; -+ port_cfg.s.minerr_en = 0; -+ cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), -+ port_cfg.u64); -+ } -+ } -+ -+ /* Enables are controlled by the remote host, so nothing to do here */ -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-npi.h -@@ -0,0 +1,60 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * @file -+ * -+ * Functions for NPI initialization, configuration, -+ * and monitoring. -+ * -+ */ -+#ifndef __CVMX_HELPER_NPI_H__ -+#define __CVMX_HELPER_NPI_H__ -+ -+/** -+ * Probe a NPI interface and determine the number of ports -+ * connected to it. The NPI interface should still be down after -+ * this call. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Number of ports on the interface. Zero to disable. -+ */ -+extern int __cvmx_helper_npi_probe(int interface); -+ -+/** -+ * Bringup and enable a NPI interface. After this call packet -+ * I/O should be fully functional. This is called with IPD -+ * enabled but PKO disabled. -+ * -+ * @interface: Interface to bring up -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_npi_enable(int interface); -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-rgmii.c -@@ -0,0 +1,525 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * Functions for RGMII/GMII/MII initialization, configuration, -+ * and monitoring. -+ */ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-config.h" -+ -+ -+#include "cvmx-mdio.h" -+#include "cvmx-pko.h" -+#include "cvmx-helper.h" -+#include "cvmx-helper-board.h" -+ -+#include <asm/octeon/cvmx-npi-defs.h> -+#include "cvmx-gmxx-defs.h" -+#include "cvmx-asxx-defs.h" -+#include "cvmx-dbg-defs.h" -+ -+void __cvmx_interrupt_gmxx_enable(int interface); -+void __cvmx_interrupt_asxx_enable(int block); -+ -+/** -+ * Probe RGMII ports and determine the number present -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Number of RGMII/GMII/MII ports (0-4). -+ */ -+int __cvmx_helper_rgmii_probe(int interface) -+{ -+ int num_ports = 0; -+ union cvmx_gmxx_inf_mode mode; -+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); -+ -+ if (mode.s.type) { -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) -+ || OCTEON_IS_MODEL(OCTEON_CN58XX)) { -+ cvmx_dprintf("ERROR: RGMII initialize called in " -+ "SPI interface\n"); -+ } else if (OCTEON_IS_MODEL(OCTEON_CN31XX) -+ || OCTEON_IS_MODEL(OCTEON_CN30XX) -+ || OCTEON_IS_MODEL(OCTEON_CN50XX)) { -+ /* -+ * On these chips "type" says we're in -+ * GMII/MII mode. This limits us to 2 ports -+ */ -+ num_ports = 2; -+ } else { -+ cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n", -+ __func__); -+ } -+ } else { -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) -+ || OCTEON_IS_MODEL(OCTEON_CN58XX)) { -+ num_ports = 4; -+ } else if (OCTEON_IS_MODEL(OCTEON_CN31XX) -+ || OCTEON_IS_MODEL(OCTEON_CN30XX) -+ || OCTEON_IS_MODEL(OCTEON_CN50XX)) { -+ num_ports = 3; -+ } else { -+ cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n", -+ __func__); -+ } -+ } -+ return num_ports; -+} -+ -+/** -+ * Put an RGMII interface in loopback mode. Internal packets sent -+ * out will be received back again on the same port. Externally -+ * received packets will echo back out. -+ * -+ * @port: IPD port number to loop. -+ */ -+void cvmx_helper_rgmii_internal_loopback(int port) -+{ -+ int interface = (port >> 4) & 1; -+ int index = port & 0xf; -+ uint64_t tmp; -+ -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ gmx_cfg.u64 = 0; -+ gmx_cfg.s.duplex = 1; -+ gmx_cfg.s.slottime = 1; -+ gmx_cfg.s.speed = 1; -+ cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1); -+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200); -+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000); -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); -+ tmp = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface)); -+ cvmx_write_csr(CVMX_ASXX_PRT_LOOP(interface), (1 << index) | tmp); -+ tmp = cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(interface)); -+ cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface), (1 << index) | tmp); -+ tmp = cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)); -+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), (1 << index) | tmp); -+ gmx_cfg.s.en = 1; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); -+} -+ -+/** -+ * Workaround ASX setup errata with CN38XX pass1 -+ * -+ * @interface: Interface to setup -+ * @port: Port to setup (0..3) -+ * @cpu_clock_hz: -+ * Chip frequency in Hertz -+ * -+ * Returns Zero on success, negative on failure -+ */ -+static int __cvmx_helper_errata_asx_pass1(int interface, int port, -+ int cpu_clock_hz) -+{ -+ /* Set hi water mark as per errata GMX-4 */ -+ if (cpu_clock_hz >= 325000000 && cpu_clock_hz < 375000000) -+ cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 12); -+ else if (cpu_clock_hz >= 375000000 && cpu_clock_hz < 437000000) -+ cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 11); -+ else if (cpu_clock_hz >= 437000000 && cpu_clock_hz < 550000000) -+ cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 10); -+ else if (cpu_clock_hz >= 550000000 && cpu_clock_hz < 687000000) -+ cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 9); -+ else -+ cvmx_dprintf("Illegal clock frequency (%d). " -+ "CVMX_ASXX_TX_HI_WATERX not set\n", cpu_clock_hz); -+ return 0; -+} -+ -+/** -+ * Configure all of the ASX, GMX, and PKO regsiters required -+ * to get RGMII to function on the supplied interface. -+ * -+ * @interface: PKO Interface to configure (0 or 1) -+ * -+ * Returns Zero on success -+ */ -+int __cvmx_helper_rgmii_enable(int interface) -+{ -+ int num_ports = cvmx_helper_ports_on_interface(interface); -+ int port; -+ struct cvmx_sysinfo *sys_info_ptr = cvmx_sysinfo_get(); -+ union cvmx_gmxx_inf_mode mode; -+ union cvmx_asxx_tx_prt_en asx_tx; -+ union cvmx_asxx_rx_prt_en asx_rx; -+ -+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); -+ -+ if (mode.s.en == 0) -+ return -1; -+ if ((OCTEON_IS_MODEL(OCTEON_CN38XX) || -+ OCTEON_IS_MODEL(OCTEON_CN58XX)) && mode.s.type == 1) -+ /* Ignore SPI interfaces */ -+ return -1; -+ -+ /* Configure the ASX registers needed to use the RGMII ports */ -+ asx_tx.u64 = 0; -+ asx_tx.s.prt_en = cvmx_build_mask(num_ports); -+ cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface), asx_tx.u64); -+ -+ asx_rx.u64 = 0; -+ asx_rx.s.prt_en = cvmx_build_mask(num_ports); -+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), asx_rx.u64); -+ -+ /* Configure the GMX registers needed to use the RGMII ports */ -+ for (port = 0; port < num_ports; port++) { -+ /* Setting of CVMX_GMXX_TXX_THRESH has been moved to -+ __cvmx_helper_setup_gmx() */ -+ -+ if (cvmx_octeon_is_pass1()) -+ __cvmx_helper_errata_asx_pass1(interface, port, -+ sys_info_ptr-> -+ cpu_clock_hz); -+ else { -+ /* -+ * Configure more flexible RGMII preamble -+ * checking. Pass 1 doesn't support this -+ * feature. -+ */ -+ union cvmx_gmxx_rxx_frm_ctl frm_ctl; -+ frm_ctl.u64 = -+ cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL -+ (port, interface)); -+ /* New field, so must be compile time */ -+ frm_ctl.s.pre_free = 1; -+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(port, interface), -+ frm_ctl.u64); -+ } -+ -+ /* -+ * Each pause frame transmitted will ask for about 10M -+ * bit times before resume. If buffer space comes -+ * available before that time has expired, an XON -+ * pause frame (0 time) will be transmitted to restart -+ * the flow. -+ */ -+ cvmx_write_csr(CVMX_GMXX_TXX_PAUSE_PKT_TIME(port, interface), -+ 20000); -+ cvmx_write_csr(CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL -+ (port, interface), 19000); -+ -+ if (OCTEON_IS_MODEL(OCTEON_CN50XX)) { -+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, interface), -+ 16); -+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, interface), -+ 16); -+ } else { -+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, interface), -+ 24); -+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, interface), -+ 24); -+ } -+ } -+ -+ __cvmx_helper_setup_gmx(interface, num_ports); -+ -+ /* enable the ports now */ -+ for (port = 0; port < num_ports; port++) { -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port -+ (interface, port)); -+ gmx_cfg.u64 = -+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(port, interface)); -+ gmx_cfg.s.en = 1; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(port, interface), -+ gmx_cfg.u64); -+ } -+ __cvmx_interrupt_asxx_enable(interface); -+ __cvmx_interrupt_gmxx_enable(interface); -+ -+ return 0; -+} -+ -+/** -+ * Return the link state of an IPD/PKO port as returned by -+ * auto negotiation. The result of this function may not match -+ * Octeon's link config if auto negotiation has changed since -+ * the last call to cvmx_helper_link_set(). -+ * -+ * @ipd_port: IPD/PKO port to query -+ * -+ * Returns Link state -+ */ -+cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port) -+{ -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ int index = cvmx_helper_get_interface_index_num(ipd_port); -+ union cvmx_asxx_prt_loop asxx_prt_loop; -+ -+ asxx_prt_loop.u64 = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface)); -+ if (asxx_prt_loop.s.int_loop & (1 << index)) { -+ /* Force 1Gbps full duplex on internal loopback */ -+ cvmx_helper_link_info_t result; -+ result.u64 = 0; -+ result.s.full_duplex = 1; -+ result.s.link_up = 1; -+ result.s.speed = 1000; -+ return result; -+ } else -+ return __cvmx_helper_board_link_get(ipd_port); -+} -+ -+/** -+ * Configure an IPD/PKO port for the specified link state. This -+ * function does not influence auto negotiation at the PHY level. -+ * The passed link state must always match the link state returned -+ * by cvmx_helper_link_get(). It is normally best to use -+ * cvmx_helper_link_autoconf() instead. -+ * -+ * @ipd_port: IPD/PKO port to configure -+ * @link_info: The new link state -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_rgmii_link_set(int ipd_port, -+ cvmx_helper_link_info_t link_info) -+{ -+ int result = 0; -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ int index = cvmx_helper_get_interface_index_num(ipd_port); -+ union cvmx_gmxx_prtx_cfg original_gmx_cfg; -+ union cvmx_gmxx_prtx_cfg new_gmx_cfg; -+ union cvmx_pko_mem_queue_qos pko_mem_queue_qos; -+ union cvmx_pko_mem_queue_qos pko_mem_queue_qos_save[16]; -+ union cvmx_gmxx_tx_ovr_bp gmx_tx_ovr_bp; -+ union cvmx_gmxx_tx_ovr_bp gmx_tx_ovr_bp_save; -+ int i; -+ -+ /* Ignore speed sets in the simulator */ -+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) -+ return 0; -+ -+ /* Read the current settings so we know the current enable state */ -+ original_gmx_cfg.u64 = -+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ new_gmx_cfg = original_gmx_cfg; -+ -+ /* Disable the lowest level RX */ -+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), -+ cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)) & -+ ~(1 << index)); -+ -+ /* Disable all queues so that TX should become idle */ -+ for (i = 0; i < cvmx_pko_get_num_queues(ipd_port); i++) { -+ int queue = cvmx_pko_get_base_queue(ipd_port) + i; -+ cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue); -+ pko_mem_queue_qos.u64 = cvmx_read_csr(CVMX_PKO_MEM_QUEUE_QOS); -+ pko_mem_queue_qos.s.pid = ipd_port; -+ pko_mem_queue_qos.s.qid = queue; -+ pko_mem_queue_qos_save[i] = pko_mem_queue_qos; -+ pko_mem_queue_qos.s.qos_mask = 0; -+ cvmx_write_csr(CVMX_PKO_MEM_QUEUE_QOS, pko_mem_queue_qos.u64); -+ } -+ -+ /* Disable backpressure */ -+ gmx_tx_ovr_bp.u64 = cvmx_read_csr(CVMX_GMXX_TX_OVR_BP(interface)); -+ gmx_tx_ovr_bp_save = gmx_tx_ovr_bp; -+ gmx_tx_ovr_bp.s.bp &= ~(1 << index); -+ gmx_tx_ovr_bp.s.en |= 1 << index; -+ cvmx_write_csr(CVMX_GMXX_TX_OVR_BP(interface), gmx_tx_ovr_bp.u64); -+ cvmx_read_csr(CVMX_GMXX_TX_OVR_BP(interface)); -+ -+ /* -+ * Poll the GMX state machine waiting for it to become -+ * idle. Preferably we should only change speed when it is -+ * idle. If it doesn't become idle we will still do the speed -+ * change, but there is a slight chance that GMX will -+ * lockup. -+ */ -+ cvmx_write_csr(CVMX_NPI_DBG_SELECT, -+ interface * 0x800 + index * 0x100 + 0x880); -+ CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data, data & 7, -+ ==, 0, 10000); -+ CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data, data & 0xf, -+ ==, 0, 10000); -+ -+ /* Disable the port before we make any changes */ -+ new_gmx_cfg.s.en = 0; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64); -+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ -+ /* Set full/half duplex */ -+ if (cvmx_octeon_is_pass1()) -+ /* Half duplex is broken for 38XX Pass 1 */ -+ new_gmx_cfg.s.duplex = 1; -+ else if (!link_info.s.link_up) -+ /* Force full duplex on down links */ -+ new_gmx_cfg.s.duplex = 1; -+ else -+ new_gmx_cfg.s.duplex = link_info.s.full_duplex; -+ -+ /* Set the link speed. Anything unknown is set to 1Gbps */ -+ if (link_info.s.speed == 10) { -+ new_gmx_cfg.s.slottime = 0; -+ new_gmx_cfg.s.speed = 0; -+ } else if (link_info.s.speed == 100) { -+ new_gmx_cfg.s.slottime = 0; -+ new_gmx_cfg.s.speed = 0; -+ } else { -+ new_gmx_cfg.s.slottime = 1; -+ new_gmx_cfg.s.speed = 1; -+ } -+ -+ /* Adjust the clocks */ -+ if (link_info.s.speed == 10) { -+ cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 50); -+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x40); -+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0); -+ } else if (link_info.s.speed == 100) { -+ cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 5); -+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x40); -+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0); -+ } else { -+ cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1); -+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200); -+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000); -+ } -+ -+ if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) { -+ if ((link_info.s.speed == 10) || (link_info.s.speed == 100)) { -+ union cvmx_gmxx_inf_mode mode; -+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); -+ -+ /* -+ * Port .en .type .p0mii Configuration -+ * ---- --- ----- ------ ----------------------------------------- -+ * X 0 X X All links are disabled. -+ * 0 1 X 0 Port 0 is RGMII -+ * 0 1 X 1 Port 0 is MII -+ * 1 1 0 X Ports 1 and 2 are configured as RGMII ports. -+ * 1 1 1 X Port 1: GMII/MII; Port 2: disabled. GMII or -+ * MII port is selected by GMX_PRT1_CFG[SPEED]. -+ */ -+ -+ /* In MII mode, CLK_CNT = 1. */ -+ if (((index == 0) && (mode.s.p0mii == 1)) -+ || ((index != 0) && (mode.s.type == 1))) { -+ cvmx_write_csr(CVMX_GMXX_TXX_CLK -+ (index, interface), 1); -+ } -+ } -+ } -+ -+ /* Do a read to make sure all setup stuff is complete */ -+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ -+ /* Save the new GMX setting without enabling the port */ -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64); -+ -+ /* Enable the lowest level RX */ -+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), -+ cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)) | (1 << -+ index)); -+ -+ /* Re-enable the TX path */ -+ for (i = 0; i < cvmx_pko_get_num_queues(ipd_port); i++) { -+ int queue = cvmx_pko_get_base_queue(ipd_port) + i; -+ cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue); -+ cvmx_write_csr(CVMX_PKO_MEM_QUEUE_QOS, -+ pko_mem_queue_qos_save[i].u64); -+ } -+ -+ /* Restore backpressure */ -+ cvmx_write_csr(CVMX_GMXX_TX_OVR_BP(interface), gmx_tx_ovr_bp_save.u64); -+ -+ /* Restore the GMX enable state. Port config is complete */ -+ new_gmx_cfg.s.en = original_gmx_cfg.s.en; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64); -+ -+ return result; -+} -+ -+/** -+ * Configure a port for internal and/or external loopback. Internal loopback -+ * causes packets sent by the port to be received by Octeon. External loopback -+ * causes packets received from the wire to sent out again. -+ * -+ * @ipd_port: IPD/PKO port to loopback. -+ * @enable_internal: -+ * Non zero if you want internal loopback -+ * @enable_external: -+ * Non zero if you want external loopback -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+int __cvmx_helper_rgmii_configure_loopback(int ipd_port, int enable_internal, -+ int enable_external) -+{ -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ int index = cvmx_helper_get_interface_index_num(ipd_port); -+ int original_enable; -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ union cvmx_asxx_prt_loop asxx_prt_loop; -+ -+ /* Read the current enable state and save it */ -+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ original_enable = gmx_cfg.s.en; -+ /* Force port to be disabled */ -+ gmx_cfg.s.en = 0; -+ if (enable_internal) { -+ /* Force speed if we're doing internal loopback */ -+ gmx_cfg.s.duplex = 1; -+ gmx_cfg.s.slottime = 1; -+ gmx_cfg.s.speed = 1; -+ cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1); -+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200); -+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000); -+ } -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); -+ -+ /* Set the loopback bits */ -+ asxx_prt_loop.u64 = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface)); -+ if (enable_internal) -+ asxx_prt_loop.s.int_loop |= 1 << index; -+ else -+ asxx_prt_loop.s.int_loop &= ~(1 << index); -+ if (enable_external) -+ asxx_prt_loop.s.ext_loop |= 1 << index; -+ else -+ asxx_prt_loop.s.ext_loop &= ~(1 << index); -+ cvmx_write_csr(CVMX_ASXX_PRT_LOOP(interface), asxx_prt_loop.u64); -+ -+ /* Force enables in internal loopback */ -+ if (enable_internal) { -+ uint64_t tmp; -+ tmp = cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(interface)); -+ cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface), -+ (1 << index) | tmp); -+ tmp = cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)); -+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), -+ (1 << index) | tmp); -+ original_enable = 1; -+ } -+ -+ /* Restore the enable state */ -+ gmx_cfg.s.en = original_enable; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-rgmii.h -@@ -0,0 +1,110 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * @file -+ * -+ * Functions for RGMII/GMII/MII initialization, configuration, -+ * and monitoring. -+ * -+ */ -+#ifndef __CVMX_HELPER_RGMII_H__ -+#define __CVMX_HELPER_RGMII_H__ -+ -+/** -+ * Probe RGMII ports and determine the number present -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Number of RGMII/GMII/MII ports (0-4). -+ */ -+extern int __cvmx_helper_rgmii_probe(int interface); -+ -+/** -+ * Put an RGMII interface in loopback mode. Internal packets sent -+ * out will be received back again on the same port. Externally -+ * received packets will echo back out. -+ * -+ * @port: IPD port number to loop. -+ */ -+extern void cvmx_helper_rgmii_internal_loopback(int port); -+ -+/** -+ * Configure all of the ASX, GMX, and PKO regsiters required -+ * to get RGMII to function on the supplied interface. -+ * -+ * @interface: PKO Interface to configure (0 or 1) -+ * -+ * Returns Zero on success -+ */ -+extern int __cvmx_helper_rgmii_enable(int interface); -+ -+/** -+ * Return the link state of an IPD/PKO port as returned by -+ * auto negotiation. The result of this function may not match -+ * Octeon's link config if auto negotiation has changed since -+ * the last call to cvmx_helper_link_set(). -+ * -+ * @ipd_port: IPD/PKO port to query -+ * -+ * Returns Link state -+ */ -+extern cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port); -+ -+/** -+ * Configure an IPD/PKO port for the specified link state. This -+ * function does not influence auto negotiation at the PHY level. -+ * The passed link state must always match the link state returned -+ * by cvmx_helper_link_get(). It is normally best to use -+ * cvmx_helper_link_autoconf() instead. -+ * -+ * @ipd_port: IPD/PKO port to configure -+ * @link_info: The new link state -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_rgmii_link_set(int ipd_port, -+ cvmx_helper_link_info_t link_info); -+ -+/** -+ * Configure a port for internal and/or external loopback. Internal loopback -+ * causes packets sent by the port to be received by Octeon. External loopback -+ * causes packets received from the wire to sent out again. -+ * -+ * @ipd_port: IPD/PKO port to loopback. -+ * @enable_internal: -+ * Non zero if you want internal loopback -+ * @enable_external: -+ * Non zero if you want external loopback -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+extern int __cvmx_helper_rgmii_configure_loopback(int ipd_port, -+ int enable_internal, -+ int enable_external); -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-sgmii.c -@@ -0,0 +1,550 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * Functions for SGMII initialization, configuration, -+ * and monitoring. -+ */ -+ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-config.h" -+ -+#include "cvmx-mdio.h" -+#include "cvmx-helper.h" -+#include "cvmx-helper-board.h" -+ -+#include "cvmx-gmxx-defs.h" -+#include "cvmx-pcsx-defs.h" -+ -+void __cvmx_interrupt_gmxx_enable(int interface); -+void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block); -+void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index); -+ -+/** -+ * Perform initialization required only once for an SGMII port. -+ * -+ * @interface: Interface to init -+ * @index: Index of prot on the interface -+ * -+ * Returns Zero on success, negative on failure -+ */ -+static int __cvmx_helper_sgmii_hardware_init_one_time(int interface, int index) -+{ -+ const uint64_t clock_mhz = cvmx_sysinfo_get()->cpu_clock_hz / 1000000; -+ union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg; -+ union cvmx_pcsx_linkx_timer_count_reg pcsx_linkx_timer_count_reg; -+ union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg; -+ -+ /* Disable GMX */ -+ gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ gmxx_prtx_cfg.s.en = 0; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64); -+ -+ /* -+ * Write PCS*_LINK*_TIMER_COUNT_REG[COUNT] with the -+ * appropriate value. 1000BASE-X specifies a 10ms -+ * interval. SGMII specifies a 1.6ms interval. -+ */ -+ pcs_misc_ctl_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface)); -+ pcsx_linkx_timer_count_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface)); -+ if (pcs_misc_ctl_reg.s.mode) { -+ /* 1000BASE-X */ -+ pcsx_linkx_timer_count_reg.s.count = -+ (10000ull * clock_mhz) >> 10; -+ } else { -+ /* SGMII */ -+ pcsx_linkx_timer_count_reg.s.count = -+ (1600ull * clock_mhz) >> 10; -+ } -+ cvmx_write_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface), -+ pcsx_linkx_timer_count_reg.u64); -+ -+ /* -+ * Write the advertisement register to be used as the -+ * tx_Config_Reg<D15:D0> of the autonegotiation. In -+ * 1000BASE-X mode, tx_Config_Reg<D15:D0> is PCS*_AN*_ADV_REG. -+ * In SGMII PHY mode, tx_Config_Reg<D15:D0> is -+ * PCS*_SGM*_AN_ADV_REG. In SGMII MAC mode, -+ * tx_Config_Reg<D15:D0> is the fixed value 0x4001, so this -+ * step can be skipped. -+ */ -+ if (pcs_misc_ctl_reg.s.mode) { -+ /* 1000BASE-X */ -+ union cvmx_pcsx_anx_adv_reg pcsx_anx_adv_reg; -+ pcsx_anx_adv_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_ANX_ADV_REG(index, interface)); -+ pcsx_anx_adv_reg.s.rem_flt = 0; -+ pcsx_anx_adv_reg.s.pause = 3; -+ pcsx_anx_adv_reg.s.hfd = 1; -+ pcsx_anx_adv_reg.s.fd = 1; -+ cvmx_write_csr(CVMX_PCSX_ANX_ADV_REG(index, interface), -+ pcsx_anx_adv_reg.u64); -+ } else { -+ union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg; -+ pcsx_miscx_ctl_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface)); -+ if (pcsx_miscx_ctl_reg.s.mac_phy) { -+ /* PHY Mode */ -+ union cvmx_pcsx_sgmx_an_adv_reg pcsx_sgmx_an_adv_reg; -+ pcsx_sgmx_an_adv_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_SGMX_AN_ADV_REG -+ (index, interface)); -+ pcsx_sgmx_an_adv_reg.s.link = 1; -+ pcsx_sgmx_an_adv_reg.s.dup = 1; -+ pcsx_sgmx_an_adv_reg.s.speed = 2; -+ cvmx_write_csr(CVMX_PCSX_SGMX_AN_ADV_REG -+ (index, interface), -+ pcsx_sgmx_an_adv_reg.u64); -+ } else { -+ /* MAC Mode - Nothing to do */ -+ } -+ } -+ return 0; -+} -+ -+/** -+ * Initialize the SERTES link for the first time or after a loss -+ * of link. -+ * -+ * @interface: Interface to init -+ * @index: Index of prot on the interface -+ * -+ * Returns Zero on success, negative on failure -+ */ -+static int __cvmx_helper_sgmii_hardware_init_link(int interface, int index) -+{ -+ union cvmx_pcsx_mrx_control_reg control_reg; -+ -+ /* -+ * Take PCS through a reset sequence. -+ * PCS*_MR*_CONTROL_REG[PWR_DN] should be cleared to zero. -+ * Write PCS*_MR*_CONTROL_REG[RESET]=1 (while not changing the -+ * value of the other PCS*_MR*_CONTROL_REG bits). Read -+ * PCS*_MR*_CONTROL_REG[RESET] until it changes value to -+ * zero. -+ */ -+ control_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface)); -+ if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) { -+ control_reg.s.reset = 1; -+ cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface), -+ control_reg.u64); -+ if (CVMX_WAIT_FOR_FIELD64 -+ (CVMX_PCSX_MRX_CONTROL_REG(index, interface), -+ union cvmx_pcsx_mrx_control_reg, reset, ==, 0, 10000)) { -+ cvmx_dprintf("SGMII%d: Timeout waiting for port %d " -+ "to finish reset\n", -+ interface, index); -+ return -1; -+ } -+ } -+ -+ /* -+ * Write PCS*_MR*_CONTROL_REG[RST_AN]=1 to ensure a fresh -+ * sgmii negotiation starts. -+ */ -+ control_reg.s.rst_an = 1; -+ control_reg.s.an_en = 1; -+ control_reg.s.pwr_dn = 0; -+ cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface), -+ control_reg.u64); -+ -+ /* -+ * Wait for PCS*_MR*_STATUS_REG[AN_CPT] to be set, indicating -+ * that sgmii autonegotiation is complete. In MAC mode this -+ * isn't an ethernet link, but a link between Octeon and the -+ * PHY. -+ */ -+ if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) && -+ CVMX_WAIT_FOR_FIELD64(CVMX_PCSX_MRX_STATUS_REG(index, interface), -+ union cvmx_pcsx_mrx_status_reg, an_cpt, ==, 1, -+ 10000)) { -+ /* cvmx_dprintf("SGMII%d: Port %d link timeout\n", interface, index); */ -+ return -1; -+ } -+ return 0; -+} -+ -+/** -+ * Configure an SGMII link to the specified speed after the SERTES -+ * link is up. -+ * -+ * @interface: Interface to init -+ * @index: Index of prot on the interface -+ * @link_info: Link state to configure -+ * -+ * Returns Zero on success, negative on failure -+ */ -+static int __cvmx_helper_sgmii_hardware_init_link_speed(int interface, -+ int index, -+ cvmx_helper_link_info_t -+ link_info) -+{ -+ int is_enabled; -+ union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg; -+ union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg; -+ -+ /* Disable GMX before we make any changes. Remember the enable state */ -+ gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ is_enabled = gmxx_prtx_cfg.s.en; -+ gmxx_prtx_cfg.s.en = 0; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64); -+ -+ /* Wait for GMX to be idle */ -+ if (CVMX_WAIT_FOR_FIELD64 -+ (CVMX_GMXX_PRTX_CFG(index, interface), union cvmx_gmxx_prtx_cfg, -+ rx_idle, ==, 1, 10000) -+ || CVMX_WAIT_FOR_FIELD64(CVMX_GMXX_PRTX_CFG(index, interface), -+ union cvmx_gmxx_prtx_cfg, tx_idle, ==, 1, -+ 10000)) { -+ cvmx_dprintf -+ ("SGMII%d: Timeout waiting for port %d to be idle\n", -+ interface, index); -+ return -1; -+ } -+ -+ /* Read GMX CFG again to make sure the disable completed */ -+ gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ -+ /* -+ * Get the misc control for PCS. We will need to set the -+ * duplication amount. -+ */ -+ pcsx_miscx_ctl_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface)); -+ -+ /* -+ * Use GMXENO to force the link down if the status we get says -+ * it should be down. -+ */ -+ pcsx_miscx_ctl_reg.s.gmxeno = !link_info.s.link_up; -+ -+ /* Only change the duplex setting if the link is up */ -+ if (link_info.s.link_up) -+ gmxx_prtx_cfg.s.duplex = link_info.s.full_duplex; -+ -+ /* Do speed based setting for GMX */ -+ switch (link_info.s.speed) { -+ case 10: -+ gmxx_prtx_cfg.s.speed = 0; -+ gmxx_prtx_cfg.s.speed_msb = 1; -+ gmxx_prtx_cfg.s.slottime = 0; -+ /* Setting from GMX-603 */ -+ pcsx_miscx_ctl_reg.s.samp_pt = 25; -+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 64); -+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0); -+ break; -+ case 100: -+ gmxx_prtx_cfg.s.speed = 0; -+ gmxx_prtx_cfg.s.speed_msb = 0; -+ gmxx_prtx_cfg.s.slottime = 0; -+ pcsx_miscx_ctl_reg.s.samp_pt = 0x5; -+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 64); -+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0); -+ break; -+ case 1000: -+ gmxx_prtx_cfg.s.speed = 1; -+ gmxx_prtx_cfg.s.speed_msb = 0; -+ gmxx_prtx_cfg.s.slottime = 1; -+ pcsx_miscx_ctl_reg.s.samp_pt = 1; -+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 512); -+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 8192); -+ break; -+ default: -+ break; -+ } -+ -+ /* Write the new misc control for PCS */ -+ cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface), -+ pcsx_miscx_ctl_reg.u64); -+ -+ /* Write the new GMX settings with the port still disabled */ -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64); -+ -+ /* Read GMX CFG again to make sure the config completed */ -+ gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ -+ /* Restore the enabled / disabled state */ -+ gmxx_prtx_cfg.s.en = is_enabled; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64); -+ -+ return 0; -+} -+ -+/** -+ * Bring up the SGMII interface to be ready for packet I/O but -+ * leave I/O disabled using the GMX override. This function -+ * follows the bringup documented in 10.6.3 of the manual. -+ * -+ * @interface: Interface to bringup -+ * @num_ports: Number of ports on the interface -+ * -+ * Returns Zero on success, negative on failure -+ */ -+static int __cvmx_helper_sgmii_hardware_init(int interface, int num_ports) -+{ -+ int index; -+ -+ __cvmx_helper_setup_gmx(interface, num_ports); -+ -+ for (index = 0; index < num_ports; index++) { -+ int ipd_port = cvmx_helper_get_ipd_port(interface, index); -+ __cvmx_helper_sgmii_hardware_init_one_time(interface, index); -+ __cvmx_helper_sgmii_link_set(ipd_port, -+ __cvmx_helper_sgmii_link_get -+ (ipd_port)); -+ -+ } -+ -+ return 0; -+} -+ -+/** -+ * Probe a SGMII interface and determine the number of ports -+ * connected to it. The SGMII interface should still be down after -+ * this call. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Number of ports on the interface. Zero to disable. -+ */ -+int __cvmx_helper_sgmii_probe(int interface) -+{ -+ union cvmx_gmxx_inf_mode mode; -+ -+ /* -+ * Due to errata GMX-700 on CN56XXp1.x and CN52XXp1.x, the -+ * interface needs to be enabled before IPD otherwise per port -+ * backpressure may not work properly -+ */ -+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); -+ mode.s.en = 1; -+ cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64); -+ return 4; -+} -+ -+/** -+ * Bringup and enable a SGMII interface. After this call packet -+ * I/O should be fully functional. This is called with IPD -+ * enabled but PKO disabled. -+ * -+ * @interface: Interface to bring up -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_sgmii_enable(int interface) -+{ -+ int num_ports = cvmx_helper_ports_on_interface(interface); -+ int index; -+ -+ __cvmx_helper_sgmii_hardware_init(interface, num_ports); -+ -+ for (index = 0; index < num_ports; index++) { -+ union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg; -+ gmxx_prtx_cfg.u64 = -+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ gmxx_prtx_cfg.s.en = 1; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), -+ gmxx_prtx_cfg.u64); -+ __cvmx_interrupt_pcsx_intx_en_reg_enable(index, interface); -+ } -+ __cvmx_interrupt_pcsxx_int_en_reg_enable(interface); -+ __cvmx_interrupt_gmxx_enable(interface); -+ return 0; -+} -+ -+/** -+ * Return the link state of an IPD/PKO port as returned by -+ * auto negotiation. The result of this function may not match -+ * Octeon's link config if auto negotiation has changed since -+ * the last call to cvmx_helper_link_set(). -+ * -+ * @ipd_port: IPD/PKO port to query -+ * -+ * Returns Link state -+ */ -+cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port) -+{ -+ cvmx_helper_link_info_t result; -+ union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg; -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ int index = cvmx_helper_get_interface_index_num(ipd_port); -+ union cvmx_pcsx_mrx_control_reg pcsx_mrx_control_reg; -+ -+ result.u64 = 0; -+ -+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) { -+ /* The simulator gives you a simulated 1Gbps full duplex link */ -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 1000; -+ return result; -+ } -+ -+ pcsx_mrx_control_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface)); -+ if (pcsx_mrx_control_reg.s.loopbck1) { -+ /* Force 1Gbps full duplex link for internal loopback */ -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 1000; -+ return result; -+ } -+ -+ pcs_misc_ctl_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface)); -+ if (pcs_misc_ctl_reg.s.mode) { -+ /* 1000BASE-X */ -+ /* FIXME */ -+ } else { -+ union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg; -+ pcsx_miscx_ctl_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface)); -+ if (pcsx_miscx_ctl_reg.s.mac_phy) { -+ /* PHY Mode */ -+ union cvmx_pcsx_mrx_status_reg pcsx_mrx_status_reg; -+ union cvmx_pcsx_anx_results_reg pcsx_anx_results_reg; -+ -+ /* -+ * Don't bother continuing if the SERTES low -+ * level link is down -+ */ -+ pcsx_mrx_status_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_MRX_STATUS_REG -+ (index, interface)); -+ if (pcsx_mrx_status_reg.s.lnk_st == 0) { -+ if (__cvmx_helper_sgmii_hardware_init_link -+ (interface, index) != 0) -+ return result; -+ } -+ -+ /* Read the autoneg results */ -+ pcsx_anx_results_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_ANX_RESULTS_REG -+ (index, interface)); -+ if (pcsx_anx_results_reg.s.an_cpt) { -+ /* -+ * Auto negotiation is complete. Set -+ * status accordingly. -+ */ -+ result.s.full_duplex = -+ pcsx_anx_results_reg.s.dup; -+ result.s.link_up = -+ pcsx_anx_results_reg.s.link_ok; -+ switch (pcsx_anx_results_reg.s.spd) { -+ case 0: -+ result.s.speed = 10; -+ break; -+ case 1: -+ result.s.speed = 100; -+ break; -+ case 2: -+ result.s.speed = 1000; -+ break; -+ default: -+ result.s.speed = 0; -+ result.s.link_up = 0; -+ break; -+ } -+ } else { -+ /* -+ * Auto negotiation isn't -+ * complete. Return link down. -+ */ -+ result.s.speed = 0; -+ result.s.link_up = 0; -+ } -+ } else { /* MAC Mode */ -+ -+ result = __cvmx_helper_board_link_get(ipd_port); -+ } -+ } -+ return result; -+} -+ -+/** -+ * Configure an IPD/PKO port for the specified link state. This -+ * function does not influence auto negotiation at the PHY level. -+ * The passed link state must always match the link state returned -+ * by cvmx_helper_link_get(). It is normally best to use -+ * cvmx_helper_link_autoconf() instead. -+ * -+ * @ipd_port: IPD/PKO port to configure -+ * @link_info: The new link state -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_sgmii_link_set(int ipd_port, -+ cvmx_helper_link_info_t link_info) -+{ -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ int index = cvmx_helper_get_interface_index_num(ipd_port); -+ __cvmx_helper_sgmii_hardware_init_link(interface, index); -+ return __cvmx_helper_sgmii_hardware_init_link_speed(interface, index, -+ link_info); -+} -+ -+/** -+ * Configure a port for internal and/or external loopback. Internal -+ * loopback causes packets sent by the port to be received by -+ * Octeon. External loopback causes packets received from the wire to -+ * sent out again. -+ * -+ * @ipd_port: IPD/PKO port to loopback. -+ * @enable_internal: -+ * Non zero if you want internal loopback -+ * @enable_external: -+ * Non zero if you want external loopback -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+int __cvmx_helper_sgmii_configure_loopback(int ipd_port, int enable_internal, -+ int enable_external) -+{ -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ int index = cvmx_helper_get_interface_index_num(ipd_port); -+ union cvmx_pcsx_mrx_control_reg pcsx_mrx_control_reg; -+ union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg; -+ -+ pcsx_mrx_control_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface)); -+ pcsx_mrx_control_reg.s.loopbck1 = enable_internal; -+ cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface), -+ pcsx_mrx_control_reg.u64); -+ -+ pcsx_miscx_ctl_reg.u64 = -+ cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface)); -+ pcsx_miscx_ctl_reg.s.loopbck2 = enable_external; -+ cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface), -+ pcsx_miscx_ctl_reg.u64); -+ -+ __cvmx_helper_sgmii_hardware_init_link(interface, index); -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-sgmii.h -@@ -0,0 +1,104 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * @file -+ * -+ * Functions for SGMII initialization, configuration, -+ * and monitoring. -+ * -+ */ -+#ifndef __CVMX_HELPER_SGMII_H__ -+#define __CVMX_HELPER_SGMII_H__ -+ -+/** -+ * Probe a SGMII interface and determine the number of ports -+ * connected to it. The SGMII interface should still be down after -+ * this call. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Number of ports on the interface. Zero to disable. -+ */ -+extern int __cvmx_helper_sgmii_probe(int interface); -+ -+/** -+ * Bringup and enable a SGMII interface. After this call packet -+ * I/O should be fully functional. This is called with IPD -+ * enabled but PKO disabled. -+ * -+ * @interface: Interface to bring up -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_sgmii_enable(int interface); -+ -+/** -+ * Return the link state of an IPD/PKO port as returned by -+ * auto negotiation. The result of this function may not match -+ * Octeon's link config if auto negotiation has changed since -+ * the last call to cvmx_helper_link_set(). -+ * -+ * @ipd_port: IPD/PKO port to query -+ * -+ * Returns Link state -+ */ -+extern cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port); -+ -+/** -+ * Configure an IPD/PKO port for the specified link state. This -+ * function does not influence auto negotiation at the PHY level. -+ * The passed link state must always match the link state returned -+ * by cvmx_helper_link_get(). It is normally best to use -+ * cvmx_helper_link_autoconf() instead. -+ * -+ * @ipd_port: IPD/PKO port to configure -+ * @link_info: The new link state -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_sgmii_link_set(int ipd_port, -+ cvmx_helper_link_info_t link_info); -+ -+/** -+ * Configure a port for internal and/or external loopback. Internal loopback -+ * causes packets sent by the port to be received by Octeon. External loopback -+ * causes packets received from the wire to sent out again. -+ * -+ * @ipd_port: IPD/PKO port to loopback. -+ * @enable_internal: -+ * Non zero if you want internal loopback -+ * @enable_external: -+ * Non zero if you want external loopback -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+extern int __cvmx_helper_sgmii_configure_loopback(int ipd_port, -+ int enable_internal, -+ int enable_external); -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-spi.c -@@ -0,0 +1,195 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+void __cvmx_interrupt_gmxx_enable(int interface); -+void __cvmx_interrupt_spxx_int_msk_enable(int index); -+void __cvmx_interrupt_stxx_int_msk_enable(int index); -+ -+/* -+ * Functions for SPI initialization, configuration, -+ * and monitoring. -+ */ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-config.h" -+#include "cvmx-spi.h" -+#include "cvmx-helper.h" -+ -+#include "cvmx-pip-defs.h" -+#include "cvmx-pko-defs.h" -+ -+/* -+ * CVMX_HELPER_SPI_TIMEOUT is used to determine how long the SPI -+ * initialization routines wait for SPI training. You can override the -+ * value using executive-config.h if necessary. -+ */ -+#ifndef CVMX_HELPER_SPI_TIMEOUT -+#define CVMX_HELPER_SPI_TIMEOUT 10 -+#endif -+ -+/** -+ * Probe a SPI interface and determine the number of ports -+ * connected to it. The SPI interface should still be down after -+ * this call. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Number of ports on the interface. Zero to disable. -+ */ -+int __cvmx_helper_spi_probe(int interface) -+{ -+ int num_ports = 0; -+ -+ if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) && -+ cvmx_spi4000_is_present(interface)) { -+ num_ports = 10; -+ } else { -+ union cvmx_pko_reg_crc_enable enable; -+ num_ports = 16; -+ /* -+ * Unlike the SPI4000, most SPI devices don't -+ * automatically put on the L2 CRC. For everything -+ * except for the SPI4000 have PKO append the L2 CRC -+ * to the packet. -+ */ -+ enable.u64 = cvmx_read_csr(CVMX_PKO_REG_CRC_ENABLE); -+ enable.s.enable |= 0xffff << (interface * 16); -+ cvmx_write_csr(CVMX_PKO_REG_CRC_ENABLE, enable.u64); -+ } -+ __cvmx_helper_setup_gmx(interface, num_ports); -+ return num_ports; -+} -+ -+/** -+ * Bringup and enable a SPI interface. After this call packet I/O -+ * should be fully functional. This is called with IPD enabled but -+ * PKO disabled. -+ * -+ * @interface: Interface to bring up -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_spi_enable(int interface) -+{ -+ /* -+ * Normally the ethernet L2 CRC is checked and stripped in the -+ * GMX block. When you are using SPI, this isn' the case and -+ * IPD needs to check the L2 CRC. -+ */ -+ int num_ports = cvmx_helper_ports_on_interface(interface); -+ int ipd_port; -+ for (ipd_port = interface * 16; ipd_port < interface * 16 + num_ports; -+ ipd_port++) { -+ union cvmx_pip_prt_cfgx port_config; -+ port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port)); -+ port_config.s.crc_en = 1; -+ cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_config.u64); -+ } -+ -+ if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) { -+ cvmx_spi_start_interface(interface, CVMX_SPI_MODE_DUPLEX, -+ CVMX_HELPER_SPI_TIMEOUT, num_ports); -+ if (cvmx_spi4000_is_present(interface)) -+ cvmx_spi4000_initialize(interface); -+ } -+ __cvmx_interrupt_spxx_int_msk_enable(interface); -+ __cvmx_interrupt_stxx_int_msk_enable(interface); -+ __cvmx_interrupt_gmxx_enable(interface); -+ return 0; -+} -+ -+/** -+ * Return the link state of an IPD/PKO port as returned by -+ * auto negotiation. The result of this function may not match -+ * Octeon's link config if auto negotiation has changed since -+ * the last call to cvmx_helper_link_set(). -+ * -+ * @ipd_port: IPD/PKO port to query -+ * -+ * Returns Link state -+ */ -+cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port) -+{ -+ cvmx_helper_link_info_t result; -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ int index = cvmx_helper_get_interface_index_num(ipd_port); -+ result.u64 = 0; -+ -+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) { -+ /* The simulator gives you a simulated full duplex link */ -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 10000; -+ } else if (cvmx_spi4000_is_present(interface)) { -+ union cvmx_gmxx_rxx_rx_inbnd inband = -+ cvmx_spi4000_check_speed(interface, index); -+ result.s.link_up = inband.s.status; -+ result.s.full_duplex = inband.s.duplex; -+ switch (inband.s.speed) { -+ case 0: /* 10 Mbps */ -+ result.s.speed = 10; -+ break; -+ case 1: /* 100 Mbps */ -+ result.s.speed = 100; -+ break; -+ case 2: /* 1 Gbps */ -+ result.s.speed = 1000; -+ break; -+ case 3: /* Illegal */ -+ result.s.speed = 0; -+ result.s.link_up = 0; -+ break; -+ } -+ } else { -+ /* For generic SPI we can't determine the link, just return some -+ sane results */ -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 10000; -+ } -+ return result; -+} -+ -+/** -+ * Configure an IPD/PKO port for the specified link state. This -+ * function does not influence auto negotiation at the PHY level. -+ * The passed link state must always match the link state returned -+ * by cvmx_helper_link_get(). It is normally best to use -+ * cvmx_helper_link_autoconf() instead. -+ * -+ * @ipd_port: IPD/PKO port to configure -+ * @link_info: The new link state -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_spi_link_set(int ipd_port, cvmx_helper_link_info_t link_info) -+{ -+ /* Nothing to do. If we have a SPI4000 then the setup was already performed -+ by cvmx_spi4000_check_speed(). If not then there isn't any link -+ info */ -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-spi.h -@@ -0,0 +1,84 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * Functions for SPI initialization, configuration, -+ * and monitoring. -+ */ -+#ifndef __CVMX_HELPER_SPI_H__ -+#define __CVMX_HELPER_SPI_H__ -+ -+/** -+ * Probe a SPI interface and determine the number of ports -+ * connected to it. The SPI interface should still be down after -+ * this call. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Number of ports on the interface. Zero to disable. -+ */ -+extern int __cvmx_helper_spi_probe(int interface); -+ -+/** -+ * Bringup and enable a SPI interface. After this call packet I/O -+ * should be fully functional. This is called with IPD enabled but -+ * PKO disabled. -+ * -+ * @interface: Interface to bring up -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_spi_enable(int interface); -+ -+/** -+ * Return the link state of an IPD/PKO port as returned by -+ * auto negotiation. The result of this function may not match -+ * Octeon's link config if auto negotiation has changed since -+ * the last call to cvmx_helper_link_set(). -+ * -+ * @ipd_port: IPD/PKO port to query -+ * -+ * Returns Link state -+ */ -+extern cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port); -+ -+/** -+ * Configure an IPD/PKO port for the specified link state. This -+ * function does not influence auto negotiation at the PHY level. -+ * The passed link state must always match the link state returned -+ * by cvmx_helper_link_get(). It is normally best to use -+ * cvmx_helper_link_autoconf() instead. -+ * -+ * @ipd_port: IPD/PKO port to configure -+ * @link_info: The new link state -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_spi_link_set(int ipd_port, -+ cvmx_helper_link_info_t link_info); -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-util.c -@@ -0,0 +1,433 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * Small helper utilities. -+ */ -+#include <linux/kernel.h> -+ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-config.h" -+ -+#include "cvmx-fpa.h" -+#include "cvmx-pip.h" -+#include "cvmx-pko.h" -+#include "cvmx-ipd.h" -+#include "cvmx-spi.h" -+ -+#include "cvmx-helper.h" -+#include "cvmx-helper-util.h" -+ -+#include <asm/octeon/cvmx-ipd-defs.h> -+ -+/** -+ * Convert a interface mode into a human readable string -+ * -+ * @mode: Mode to convert -+ * -+ * Returns String -+ */ -+const char *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t -+ mode) -+{ -+ switch (mode) { -+ case CVMX_HELPER_INTERFACE_MODE_DISABLED: -+ return "DISABLED"; -+ case CVMX_HELPER_INTERFACE_MODE_RGMII: -+ return "RGMII"; -+ case CVMX_HELPER_INTERFACE_MODE_GMII: -+ return "GMII"; -+ case CVMX_HELPER_INTERFACE_MODE_SPI: -+ return "SPI"; -+ case CVMX_HELPER_INTERFACE_MODE_PCIE: -+ return "PCIE"; -+ case CVMX_HELPER_INTERFACE_MODE_XAUI: -+ return "XAUI"; -+ case CVMX_HELPER_INTERFACE_MODE_SGMII: -+ return "SGMII"; -+ case CVMX_HELPER_INTERFACE_MODE_PICMG: -+ return "PICMG"; -+ case CVMX_HELPER_INTERFACE_MODE_NPI: -+ return "NPI"; -+ case CVMX_HELPER_INTERFACE_MODE_LOOP: -+ return "LOOP"; -+ } -+ return "UNKNOWN"; -+} -+ -+/** -+ * Debug routine to dump the packet structure to the console -+ * -+ * @work: Work queue entry containing the packet to dump -+ * Returns -+ */ -+int cvmx_helper_dump_packet(cvmx_wqe_t *work) -+{ -+ uint64_t count; -+ uint64_t remaining_bytes; -+ union cvmx_buf_ptr buffer_ptr; -+ uint64_t start_of_buffer; -+ uint8_t *data_address; -+ uint8_t *end_of_data; -+ -+ cvmx_dprintf("Packet Length: %u\n", work->len); -+ cvmx_dprintf(" Input Port: %u\n", work->ipprt); -+ cvmx_dprintf(" QoS: %u\n", work->qos); -+ cvmx_dprintf(" Buffers: %u\n", work->word2.s.bufs); -+ -+ if (work->word2.s.bufs == 0) { -+ union cvmx_ipd_wqe_fpa_queue wqe_pool; -+ wqe_pool.u64 = cvmx_read_csr(CVMX_IPD_WQE_FPA_QUEUE); -+ buffer_ptr.u64 = 0; -+ buffer_ptr.s.pool = wqe_pool.s.wqe_pool; -+ buffer_ptr.s.size = 128; -+ buffer_ptr.s.addr = cvmx_ptr_to_phys(work->packet_data); -+ if (likely(!work->word2.s.not_IP)) { -+ union cvmx_pip_ip_offset pip_ip_offset; -+ pip_ip_offset.u64 = cvmx_read_csr(CVMX_PIP_IP_OFFSET); -+ buffer_ptr.s.addr += -+ (pip_ip_offset.s.offset << 3) - -+ work->word2.s.ip_offset; -+ buffer_ptr.s.addr += (work->word2.s.is_v6 ^ 1) << 2; -+ } else { -+ /* -+ * WARNING: This code assumes that the packet -+ * is not RAW. If it was, we would use -+ * PIP_GBL_CFG[RAW_SHF] instead of -+ * PIP_GBL_CFG[NIP_SHF]. -+ */ -+ union cvmx_pip_gbl_cfg pip_gbl_cfg; -+ pip_gbl_cfg.u64 = cvmx_read_csr(CVMX_PIP_GBL_CFG); -+ buffer_ptr.s.addr += pip_gbl_cfg.s.nip_shf; -+ } -+ } else -+ buffer_ptr = work->packet_ptr; -+ remaining_bytes = work->len; -+ -+ while (remaining_bytes) { -+ start_of_buffer = -+ ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7; -+ cvmx_dprintf(" Buffer Start:%llx\n", -+ (unsigned long long)start_of_buffer); -+ cvmx_dprintf(" Buffer I : %u\n", buffer_ptr.s.i); -+ cvmx_dprintf(" Buffer Back: %u\n", buffer_ptr.s.back); -+ cvmx_dprintf(" Buffer Pool: %u\n", buffer_ptr.s.pool); -+ cvmx_dprintf(" Buffer Data: %llx\n", -+ (unsigned long long)buffer_ptr.s.addr); -+ cvmx_dprintf(" Buffer Size: %u\n", buffer_ptr.s.size); -+ -+ cvmx_dprintf("\t\t"); -+ data_address = (uint8_t *) cvmx_phys_to_ptr(buffer_ptr.s.addr); -+ end_of_data = data_address + buffer_ptr.s.size; -+ count = 0; -+ while (data_address < end_of_data) { -+ if (remaining_bytes == 0) -+ break; -+ else -+ remaining_bytes--; -+ cvmx_dprintf("%02x", (unsigned int)*data_address); -+ data_address++; -+ if (remaining_bytes && (count == 7)) { -+ cvmx_dprintf("\n\t\t"); -+ count = 0; -+ } else -+ count++; -+ } -+ cvmx_dprintf("\n"); -+ -+ if (remaining_bytes) -+ buffer_ptr = *(union cvmx_buf_ptr *) -+ cvmx_phys_to_ptr(buffer_ptr.s.addr - 8); -+ } -+ return 0; -+} -+ -+/** -+ * Setup Random Early Drop on a specific input queue -+ * -+ * @queue: Input queue to setup RED on (0-7) -+ * @pass_thresh: -+ * Packets will begin slowly dropping when there are less than -+ * this many packet buffers free in FPA 0. -+ * @drop_thresh: -+ * All incomming packets will be dropped when there are less -+ * than this many free packet buffers in FPA 0. -+ * Returns Zero on success. Negative on failure -+ */ -+int cvmx_helper_setup_red_queue(int queue, int pass_thresh, int drop_thresh) -+{ -+ union cvmx_ipd_qosx_red_marks red_marks; -+ union cvmx_ipd_red_quex_param red_param; -+ -+ /* Set RED to begin dropping packets when there are pass_thresh buffers -+ left. It will linearly drop more packets until reaching drop_thresh -+ buffers */ -+ red_marks.u64 = 0; -+ red_marks.s.drop = drop_thresh; -+ red_marks.s.pass = pass_thresh; -+ cvmx_write_csr(CVMX_IPD_QOSX_RED_MARKS(queue), red_marks.u64); -+ -+ /* Use the actual queue 0 counter, not the average */ -+ red_param.u64 = 0; -+ red_param.s.prb_con = -+ (255ul << 24) / (red_marks.s.pass - red_marks.s.drop); -+ red_param.s.avg_con = 1; -+ red_param.s.new_con = 255; -+ red_param.s.use_pcnt = 1; -+ cvmx_write_csr(CVMX_IPD_RED_QUEX_PARAM(queue), red_param.u64); -+ return 0; -+} -+ -+/** -+ * Setup Random Early Drop to automatically begin dropping packets. -+ * -+ * @pass_thresh: -+ * Packets will begin slowly dropping when there are less than -+ * this many packet buffers free in FPA 0. -+ * @drop_thresh: -+ * All incomming packets will be dropped when there are less -+ * than this many free packet buffers in FPA 0. -+ * Returns Zero on success. Negative on failure -+ */ -+int cvmx_helper_setup_red(int pass_thresh, int drop_thresh) -+{ -+ union cvmx_ipd_portx_bp_page_cnt page_cnt; -+ union cvmx_ipd_bp_prt_red_end ipd_bp_prt_red_end; -+ union cvmx_ipd_red_port_enable red_port_enable; -+ int queue; -+ int interface; -+ int port; -+ -+ /* Disable backpressure based on queued buffers. It needs SW support */ -+ page_cnt.u64 = 0; -+ page_cnt.s.bp_enb = 0; -+ page_cnt.s.page_cnt = 100; -+ for (interface = 0; interface < 2; interface++) { -+ for (port = cvmx_helper_get_first_ipd_port(interface); -+ port < cvmx_helper_get_last_ipd_port(interface); port++) -+ cvmx_write_csr(CVMX_IPD_PORTX_BP_PAGE_CNT(port), -+ page_cnt.u64); -+ } -+ -+ for (queue = 0; queue < 8; queue++) -+ cvmx_helper_setup_red_queue(queue, pass_thresh, drop_thresh); -+ -+ /* Shutoff the dropping based on the per port page count. SW isn't -+ decrementing it right now */ -+ ipd_bp_prt_red_end.u64 = 0; -+ ipd_bp_prt_red_end.s.prt_enb = 0; -+ cvmx_write_csr(CVMX_IPD_BP_PRT_RED_END, ipd_bp_prt_red_end.u64); -+ -+ red_port_enable.u64 = 0; -+ red_port_enable.s.prt_enb = 0xfffffffffull; -+ red_port_enable.s.avg_dly = 10000; -+ red_port_enable.s.prb_dly = 10000; -+ cvmx_write_csr(CVMX_IPD_RED_PORT_ENABLE, red_port_enable.u64); -+ -+ return 0; -+} -+ -+/** -+ * Setup the common GMX settings that determine the number of -+ * ports. These setting apply to almost all configurations of all -+ * chips. -+ * -+ * @interface: Interface to configure -+ * @num_ports: Number of ports on the interface -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_setup_gmx(int interface, int num_ports) -+{ -+ union cvmx_gmxx_tx_prts gmx_tx_prts; -+ union cvmx_gmxx_rx_prts gmx_rx_prts; -+ union cvmx_pko_reg_gmx_port_mode pko_mode; -+ union cvmx_gmxx_txx_thresh gmx_tx_thresh; -+ int index; -+ -+ /* Tell GMX the number of TX ports on this interface */ -+ gmx_tx_prts.u64 = cvmx_read_csr(CVMX_GMXX_TX_PRTS(interface)); -+ gmx_tx_prts.s.prts = num_ports; -+ cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), gmx_tx_prts.u64); -+ -+ /* Tell GMX the number of RX ports on this interface. This only -+ ** applies to *GMII and XAUI ports */ -+ if (cvmx_helper_interface_get_mode(interface) == -+ CVMX_HELPER_INTERFACE_MODE_RGMII -+ || cvmx_helper_interface_get_mode(interface) == -+ CVMX_HELPER_INTERFACE_MODE_SGMII -+ || cvmx_helper_interface_get_mode(interface) == -+ CVMX_HELPER_INTERFACE_MODE_GMII -+ || cvmx_helper_interface_get_mode(interface) == -+ CVMX_HELPER_INTERFACE_MODE_XAUI) { -+ if (num_ports > 4) { -+ cvmx_dprintf("__cvmx_helper_setup_gmx: Illegal " -+ "num_ports\n"); -+ return -1; -+ } -+ -+ gmx_rx_prts.u64 = cvmx_read_csr(CVMX_GMXX_RX_PRTS(interface)); -+ gmx_rx_prts.s.prts = num_ports; -+ cvmx_write_csr(CVMX_GMXX_RX_PRTS(interface), gmx_rx_prts.u64); -+ } -+ -+ /* Skip setting CVMX_PKO_REG_GMX_PORT_MODE on 30XX, 31XX, and 50XX */ -+ if (!OCTEON_IS_MODEL(OCTEON_CN30XX) && !OCTEON_IS_MODEL(OCTEON_CN31XX) -+ && !OCTEON_IS_MODEL(OCTEON_CN50XX)) { -+ /* Tell PKO the number of ports on this interface */ -+ pko_mode.u64 = cvmx_read_csr(CVMX_PKO_REG_GMX_PORT_MODE); -+ if (interface == 0) { -+ if (num_ports == 1) -+ pko_mode.s.mode0 = 4; -+ else if (num_ports == 2) -+ pko_mode.s.mode0 = 3; -+ else if (num_ports <= 4) -+ pko_mode.s.mode0 = 2; -+ else if (num_ports <= 8) -+ pko_mode.s.mode0 = 1; -+ else -+ pko_mode.s.mode0 = 0; -+ } else { -+ if (num_ports == 1) -+ pko_mode.s.mode1 = 4; -+ else if (num_ports == 2) -+ pko_mode.s.mode1 = 3; -+ else if (num_ports <= 4) -+ pko_mode.s.mode1 = 2; -+ else if (num_ports <= 8) -+ pko_mode.s.mode1 = 1; -+ else -+ pko_mode.s.mode1 = 0; -+ } -+ cvmx_write_csr(CVMX_PKO_REG_GMX_PORT_MODE, pko_mode.u64); -+ } -+ -+ /* -+ * Set GMX to buffer as much data as possible before starting -+ * transmit. This reduces the chances that we have a TX under -+ * run due to memory contention. Any packet that fits entirely -+ * in the GMX FIFO can never have an under run regardless of -+ * memory load. -+ */ -+ gmx_tx_thresh.u64 = cvmx_read_csr(CVMX_GMXX_TXX_THRESH(0, interface)); -+ if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN31XX) -+ || OCTEON_IS_MODEL(OCTEON_CN50XX)) { -+ /* These chips have a fixed max threshold of 0x40 */ -+ gmx_tx_thresh.s.cnt = 0x40; -+ } else { -+ /* Choose the max value for the number of ports */ -+ if (num_ports <= 1) -+ gmx_tx_thresh.s.cnt = 0x100 / 1; -+ else if (num_ports == 2) -+ gmx_tx_thresh.s.cnt = 0x100 / 2; -+ else -+ gmx_tx_thresh.s.cnt = 0x100 / 4; -+ } -+ /* -+ * SPI and XAUI can have lots of ports but the GMX hardware -+ * only ever has a max of 4. -+ */ -+ if (num_ports > 4) -+ num_ports = 4; -+ for (index = 0; index < num_ports; index++) -+ cvmx_write_csr(CVMX_GMXX_TXX_THRESH(index, interface), -+ gmx_tx_thresh.u64); -+ -+ return 0; -+} -+ -+/** -+ * Returns the IPD/PKO port number for a port on teh given -+ * interface. -+ * -+ * @interface: Interface to use -+ * @port: Port on the interface -+ * -+ * Returns IPD/PKO port number -+ */ -+int cvmx_helper_get_ipd_port(int interface, int port) -+{ -+ switch (interface) { -+ case 0: -+ return port; -+ case 1: -+ return port + 16; -+ case 2: -+ return port + 32; -+ case 3: -+ return port + 36; -+ } -+ return -1; -+} -+ -+/** -+ * Returns the interface number for an IPD/PKO port number. -+ * -+ * @ipd_port: IPD/PKO port number -+ * -+ * Returns Interface number -+ */ -+int cvmx_helper_get_interface_num(int ipd_port) -+{ -+ if (ipd_port < 16) -+ return 0; -+ else if (ipd_port < 32) -+ return 1; -+ else if (ipd_port < 36) -+ return 2; -+ else if (ipd_port < 40) -+ return 3; -+ else -+ cvmx_dprintf("cvmx_helper_get_interface_num: Illegal IPD " -+ "port number\n"); -+ -+ return -1; -+} -+ -+/** -+ * Returns the interface index number for an IPD/PKO port -+ * number. -+ * -+ * @ipd_port: IPD/PKO port number -+ * -+ * Returns Interface index number -+ */ -+int cvmx_helper_get_interface_index_num(int ipd_port) -+{ -+ if (ipd_port < 32) -+ return ipd_port & 15; -+ else if (ipd_port < 36) -+ return ipd_port & 3; -+ else if (ipd_port < 40) -+ return ipd_port & 3; -+ else -+ cvmx_dprintf("cvmx_helper_get_interface_index_num: " -+ "Illegal IPD port number\n"); -+ -+ return -1; -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-util.h -@@ -0,0 +1,215 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * -+ * Small helper utilities. -+ * -+ */ -+ -+#ifndef __CVMX_HELPER_UTIL_H__ -+#define __CVMX_HELPER_UTIL_H__ -+ -+/** -+ * Convert a interface mode into a human readable string -+ * -+ * @mode: Mode to convert -+ * -+ * Returns String -+ */ -+extern const char -+ *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t mode); -+ -+/** -+ * Debug routine to dump the packet structure to the console -+ * -+ * @work: Work queue entry containing the packet to dump -+ * Returns -+ */ -+extern int cvmx_helper_dump_packet(cvmx_wqe_t *work); -+ -+/** -+ * Setup Random Early Drop on a specific input queue -+ * -+ * @queue: Input queue to setup RED on (0-7) -+ * @pass_thresh: -+ * Packets will begin slowly dropping when there are less than -+ * this many packet buffers free in FPA 0. -+ * @drop_thresh: -+ * All incomming packets will be dropped when there are less -+ * than this many free packet buffers in FPA 0. -+ * Returns Zero on success. Negative on failure -+ */ -+extern int cvmx_helper_setup_red_queue(int queue, int pass_thresh, -+ int drop_thresh); -+ -+/** -+ * Setup Random Early Drop to automatically begin dropping packets. -+ * -+ * @pass_thresh: -+ * Packets will begin slowly dropping when there are less than -+ * this many packet buffers free in FPA 0. -+ * @drop_thresh: -+ * All incomming packets will be dropped when there are less -+ * than this many free packet buffers in FPA 0. -+ * Returns Zero on success. Negative on failure -+ */ -+extern int cvmx_helper_setup_red(int pass_thresh, int drop_thresh); -+ -+/** -+ * Get the version of the CVMX libraries. -+ * -+ * Returns Version string. Note this buffer is allocated statically -+ * and will be shared by all callers. -+ */ -+extern const char *cvmx_helper_get_version(void); -+ -+/** -+ * Setup the common GMX settings that determine the number of -+ * ports. These setting apply to almost all configurations of all -+ * chips. -+ * -+ * @interface: Interface to configure -+ * @num_ports: Number of ports on the interface -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_setup_gmx(int interface, int num_ports); -+ -+/** -+ * Returns the IPD/PKO port number for a port on the given -+ * interface. -+ * -+ * @interface: Interface to use -+ * @port: Port on the interface -+ * -+ * Returns IPD/PKO port number -+ */ -+extern int cvmx_helper_get_ipd_port(int interface, int port); -+ -+/** -+ * Returns the IPD/PKO port number for the first port on the given -+ * interface. -+ * -+ * @interface: Interface to use -+ * -+ * Returns IPD/PKO port number -+ */ -+static inline int cvmx_helper_get_first_ipd_port(int interface) -+{ -+ return cvmx_helper_get_ipd_port(interface, 0); -+} -+ -+/** -+ * Returns the IPD/PKO port number for the last port on the given -+ * interface. -+ * -+ * @interface: Interface to use -+ * -+ * Returns IPD/PKO port number -+ */ -+static inline int cvmx_helper_get_last_ipd_port(int interface) -+{ -+ extern int cvmx_helper_ports_on_interface(int interface); -+ -+ return cvmx_helper_get_first_ipd_port(interface) + -+ cvmx_helper_ports_on_interface(interface) - 1; -+} -+ -+/** -+ * Free the packet buffers contained in a work queue entry. -+ * The work queue entry is not freed. -+ * -+ * @work: Work queue entry with packet to free -+ */ -+static inline void cvmx_helper_free_packet_data(cvmx_wqe_t *work) -+{ -+ uint64_t number_buffers; -+ union cvmx_buf_ptr buffer_ptr; -+ union cvmx_buf_ptr next_buffer_ptr; -+ uint64_t start_of_buffer; -+ -+ number_buffers = work->word2.s.bufs; -+ if (number_buffers == 0) -+ return; -+ buffer_ptr = work->packet_ptr; -+ -+ /* -+ * Since the number of buffers is not zero, we know this is -+ * not a dynamic short packet. We need to check if it is a -+ * packet received with IPD_CTL_STATUS[NO_WPTR]. If this is -+ * true, we need to free all buffers except for the first -+ * one. The caller doesn't expect their WQE pointer to be -+ * freed -+ */ -+ start_of_buffer = ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7; -+ if (cvmx_ptr_to_phys(work) == start_of_buffer) { -+ next_buffer_ptr = -+ *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8); -+ buffer_ptr = next_buffer_ptr; -+ number_buffers--; -+ } -+ -+ while (number_buffers--) { -+ /* -+ * Remember the back pointer is in cache lines, not -+ * 64bit words -+ */ -+ start_of_buffer = -+ ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7; -+ /* -+ * Read pointer to next buffer before we free the -+ * current buffer. -+ */ -+ next_buffer_ptr = -+ *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8); -+ cvmx_fpa_free(cvmx_phys_to_ptr(start_of_buffer), -+ buffer_ptr.s.pool, 0); -+ buffer_ptr = next_buffer_ptr; -+ } -+} -+ -+/** -+ * Returns the interface number for an IPD/PKO port number. -+ * -+ * @ipd_port: IPD/PKO port number -+ * -+ * Returns Interface number -+ */ -+extern int cvmx_helper_get_interface_num(int ipd_port); -+ -+/** -+ * Returns the interface index number for an IPD/PKO port -+ * number. -+ * -+ * @ipd_port: IPD/PKO port number -+ * -+ * Returns Interface index number -+ */ -+extern int cvmx_helper_get_interface_index_num(int ipd_port); -+ -+#endif /* __CVMX_HELPER_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-xaui.c -@@ -0,0 +1,348 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * Functions for XAUI initialization, configuration, -+ * and monitoring. -+ * -+ */ -+ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-config.h" -+ -+#include "cvmx-helper.h" -+ -+#include "cvmx-pko-defs.h" -+#include "cvmx-gmxx-defs.h" -+#include "cvmx-pcsxx-defs.h" -+ -+void __cvmx_interrupt_gmxx_enable(int interface); -+void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block); -+void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index); -+/** -+ * Probe a XAUI interface and determine the number of ports -+ * connected to it. The XAUI interface should still be down -+ * after this call. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Number of ports on the interface. Zero to disable. -+ */ -+int __cvmx_helper_xaui_probe(int interface) -+{ -+ int i; -+ union cvmx_gmxx_hg2_control gmx_hg2_control; -+ union cvmx_gmxx_inf_mode mode; -+ -+ /* -+ * Due to errata GMX-700 on CN56XXp1.x and CN52XXp1.x, the -+ * interface needs to be enabled before IPD otherwise per port -+ * backpressure may not work properly. -+ */ -+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); -+ mode.s.en = 1; -+ cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64); -+ -+ __cvmx_helper_setup_gmx(interface, 1); -+ -+ /* -+ * Setup PKO to support 16 ports for HiGig2 virtual -+ * ports. We're pointing all of the PKO packet ports for this -+ * interface to the XAUI. This allows us to use HiGig2 -+ * backpressure per port. -+ */ -+ for (i = 0; i < 16; i++) { -+ union cvmx_pko_mem_port_ptrs pko_mem_port_ptrs; -+ pko_mem_port_ptrs.u64 = 0; -+ /* -+ * We set each PKO port to have equal priority in a -+ * round robin fashion. -+ */ -+ pko_mem_port_ptrs.s.static_p = 0; -+ pko_mem_port_ptrs.s.qos_mask = 0xff; -+ /* All PKO ports map to the same XAUI hardware port */ -+ pko_mem_port_ptrs.s.eid = interface * 4; -+ pko_mem_port_ptrs.s.pid = interface * 16 + i; -+ cvmx_write_csr(CVMX_PKO_MEM_PORT_PTRS, pko_mem_port_ptrs.u64); -+ } -+ -+ /* If HiGig2 is enabled return 16 ports, otherwise return 1 port */ -+ gmx_hg2_control.u64 = cvmx_read_csr(CVMX_GMXX_HG2_CONTROL(interface)); -+ if (gmx_hg2_control.s.hg2tx_en) -+ return 16; -+ else -+ return 1; -+} -+ -+/** -+ * Bringup and enable a XAUI interface. After this call packet -+ * I/O should be fully functional. This is called with IPD -+ * enabled but PKO disabled. -+ * -+ * @interface: Interface to bring up -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_xaui_enable(int interface) -+{ -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ union cvmx_pcsxx_control1_reg xauiCtl; -+ union cvmx_pcsxx_misc_ctl_reg xauiMiscCtl; -+ union cvmx_gmxx_tx_xaui_ctl gmxXauiTxCtl; -+ union cvmx_gmxx_rxx_int_en gmx_rx_int_en; -+ union cvmx_gmxx_tx_int_en gmx_tx_int_en; -+ union cvmx_pcsxx_int_en_reg pcsx_int_en_reg; -+ -+ /* (1) Interface has already been enabled. */ -+ -+ /* (2) Disable GMX. */ -+ xauiMiscCtl.u64 = cvmx_read_csr(CVMX_PCSXX_MISC_CTL_REG(interface)); -+ xauiMiscCtl.s.gmxeno = 1; -+ cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64); -+ -+ /* (3) Disable GMX and PCSX interrupts. */ -+ gmx_rx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_EN(0, interface)); -+ cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0); -+ gmx_tx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_TX_INT_EN(interface)); -+ cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0); -+ pcsx_int_en_reg.u64 = cvmx_read_csr(CVMX_PCSXX_INT_EN_REG(interface)); -+ cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0); -+ -+ /* (4) Bring up the PCSX and GMX reconciliation layer. */ -+ /* (4)a Set polarity and lane swapping. */ -+ /* (4)b */ -+ gmxXauiTxCtl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface)); -+ /* Enable better IFG packing and improves performance */ -+ gmxXauiTxCtl.s.dic_en = 1; -+ gmxXauiTxCtl.s.uni_en = 0; -+ cvmx_write_csr(CVMX_GMXX_TX_XAUI_CTL(interface), gmxXauiTxCtl.u64); -+ -+ /* (4)c Aply reset sequence */ -+ xauiCtl.u64 = cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface)); -+ xauiCtl.s.lo_pwr = 0; -+ xauiCtl.s.reset = 1; -+ cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface), xauiCtl.u64); -+ -+ /* Wait for PCS to come out of reset */ -+ if (CVMX_WAIT_FOR_FIELD64 -+ (CVMX_PCSXX_CONTROL1_REG(interface), union cvmx_pcsxx_control1_reg, -+ reset, ==, 0, 10000)) -+ return -1; -+ /* Wait for PCS to be aligned */ -+ if (CVMX_WAIT_FOR_FIELD64 -+ (CVMX_PCSXX_10GBX_STATUS_REG(interface), -+ union cvmx_pcsxx_10gbx_status_reg, alignd, ==, 1, 10000)) -+ return -1; -+ /* Wait for RX to be ready */ -+ if (CVMX_WAIT_FOR_FIELD64 -+ (CVMX_GMXX_RX_XAUI_CTL(interface), union cvmx_gmxx_rx_xaui_ctl, -+ status, ==, 0, 10000)) -+ return -1; -+ -+ /* (6) Configure GMX */ -+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface)); -+ gmx_cfg.s.en = 0; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64); -+ -+ /* Wait for GMX RX to be idle */ -+ if (CVMX_WAIT_FOR_FIELD64 -+ (CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg, -+ rx_idle, ==, 1, 10000)) -+ return -1; -+ /* Wait for GMX TX to be idle */ -+ if (CVMX_WAIT_FOR_FIELD64 -+ (CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg, -+ tx_idle, ==, 1, 10000)) -+ return -1; -+ -+ /* GMX configure */ -+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface)); -+ gmx_cfg.s.speed = 1; -+ gmx_cfg.s.speed_msb = 0; -+ gmx_cfg.s.slottime = 1; -+ cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), 1); -+ cvmx_write_csr(CVMX_GMXX_TXX_SLOT(0, interface), 512); -+ cvmx_write_csr(CVMX_GMXX_TXX_BURST(0, interface), 8192); -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64); -+ -+ /* (7) Clear out any error state */ -+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(0, interface), -+ cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(0, interface))); -+ cvmx_write_csr(CVMX_GMXX_TX_INT_REG(interface), -+ cvmx_read_csr(CVMX_GMXX_TX_INT_REG(interface))); -+ cvmx_write_csr(CVMX_PCSXX_INT_REG(interface), -+ cvmx_read_csr(CVMX_PCSXX_INT_REG(interface))); -+ -+ /* Wait for receive link */ -+ if (CVMX_WAIT_FOR_FIELD64 -+ (CVMX_PCSXX_STATUS1_REG(interface), union cvmx_pcsxx_status1_reg, -+ rcv_lnk, ==, 1, 10000)) -+ return -1; -+ if (CVMX_WAIT_FOR_FIELD64 -+ (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg, -+ xmtflt, ==, 0, 10000)) -+ return -1; -+ if (CVMX_WAIT_FOR_FIELD64 -+ (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg, -+ rcvflt, ==, 0, 10000)) -+ return -1; -+ -+ cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), gmx_rx_int_en.u64); -+ cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64); -+ cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), pcsx_int_en_reg.u64); -+ -+ cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port(interface, 0)); -+ -+ /* (8) Enable packet reception */ -+ xauiMiscCtl.s.gmxeno = 0; -+ cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64); -+ -+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface)); -+ gmx_cfg.s.en = 1; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64); -+ -+ __cvmx_interrupt_pcsx_intx_en_reg_enable(0, interface); -+ __cvmx_interrupt_pcsx_intx_en_reg_enable(1, interface); -+ __cvmx_interrupt_pcsx_intx_en_reg_enable(2, interface); -+ __cvmx_interrupt_pcsx_intx_en_reg_enable(3, interface); -+ __cvmx_interrupt_pcsxx_int_en_reg_enable(interface); -+ __cvmx_interrupt_gmxx_enable(interface); -+ -+ return 0; -+} -+ -+/** -+ * Return the link state of an IPD/PKO port as returned by -+ * auto negotiation. The result of this function may not match -+ * Octeon's link config if auto negotiation has changed since -+ * the last call to cvmx_helper_link_set(). -+ * -+ * @ipd_port: IPD/PKO port to query -+ * -+ * Returns Link state -+ */ -+cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port) -+{ -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ union cvmx_gmxx_tx_xaui_ctl gmxx_tx_xaui_ctl; -+ union cvmx_gmxx_rx_xaui_ctl gmxx_rx_xaui_ctl; -+ union cvmx_pcsxx_status1_reg pcsxx_status1_reg; -+ cvmx_helper_link_info_t result; -+ -+ gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface)); -+ gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface)); -+ pcsxx_status1_reg.u64 = -+ cvmx_read_csr(CVMX_PCSXX_STATUS1_REG(interface)); -+ result.u64 = 0; -+ -+ /* Only return a link if both RX and TX are happy */ -+ if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0) && -+ (pcsxx_status1_reg.s.rcv_lnk == 1)) { -+ result.s.link_up = 1; -+ result.s.full_duplex = 1; -+ result.s.speed = 10000; -+ } else { -+ /* Disable GMX and PCSX interrupts. */ -+ cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0); -+ cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0); -+ cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0); -+ } -+ return result; -+} -+ -+/** -+ * Configure an IPD/PKO port for the specified link state. This -+ * function does not influence auto negotiation at the PHY level. -+ * The passed link state must always match the link state returned -+ * by cvmx_helper_link_get(). It is normally best to use -+ * cvmx_helper_link_autoconf() instead. -+ * -+ * @ipd_port: IPD/PKO port to configure -+ * @link_info: The new link state -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int __cvmx_helper_xaui_link_set(int ipd_port, cvmx_helper_link_info_t link_info) -+{ -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ union cvmx_gmxx_tx_xaui_ctl gmxx_tx_xaui_ctl; -+ union cvmx_gmxx_rx_xaui_ctl gmxx_rx_xaui_ctl; -+ -+ gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface)); -+ gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface)); -+ -+ /* If the link shouldn't be up, then just return */ -+ if (!link_info.s.link_up) -+ return 0; -+ -+ /* Do nothing if both RX and TX are happy */ -+ if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0)) -+ return 0; -+ -+ /* Bring the link up */ -+ return __cvmx_helper_xaui_enable(interface); -+} -+ -+/** -+ * Configure a port for internal and/or external loopback. Internal loopback -+ * causes packets sent by the port to be received by Octeon. External loopback -+ * causes packets received from the wire to sent out again. -+ * -+ * @ipd_port: IPD/PKO port to loopback. -+ * @enable_internal: -+ * Non zero if you want internal loopback -+ * @enable_external: -+ * Non zero if you want external loopback -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+extern int __cvmx_helper_xaui_configure_loopback(int ipd_port, -+ int enable_internal, -+ int enable_external) -+{ -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ union cvmx_pcsxx_control1_reg pcsxx_control1_reg; -+ union cvmx_gmxx_xaui_ext_loopback gmxx_xaui_ext_loopback; -+ -+ /* Set the internal loop */ -+ pcsxx_control1_reg.u64 = -+ cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface)); -+ pcsxx_control1_reg.s.loopbck1 = enable_internal; -+ cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface), -+ pcsxx_control1_reg.u64); -+ -+ /* Set the external loop */ -+ gmxx_xaui_ext_loopback.u64 = -+ cvmx_read_csr(CVMX_GMXX_XAUI_EXT_LOOPBACK(interface)); -+ gmxx_xaui_ext_loopback.s.en = enable_external; -+ cvmx_write_csr(CVMX_GMXX_XAUI_EXT_LOOPBACK(interface), -+ gmxx_xaui_ext_loopback.u64); -+ -+ /* Take the link through a reset */ -+ return __cvmx_helper_xaui_enable(interface); -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper-xaui.h -@@ -0,0 +1,103 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * @file -+ * -+ * Functions for XAUI initialization, configuration, -+ * and monitoring. -+ * -+ */ -+#ifndef __CVMX_HELPER_XAUI_H__ -+#define __CVMX_HELPER_XAUI_H__ -+ -+/** -+ * Probe a XAUI interface and determine the number of ports -+ * connected to it. The XAUI interface should still be down -+ * after this call. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Number of ports on the interface. Zero to disable. -+ */ -+extern int __cvmx_helper_xaui_probe(int interface); -+ -+/** -+ * Bringup and enable a XAUI interface. After this call packet -+ * I/O should be fully functional. This is called with IPD -+ * enabled but PKO disabled. -+ * -+ * @interface: Interface to bring up -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_xaui_enable(int interface); -+ -+/** -+ * Return the link state of an IPD/PKO port as returned by -+ * auto negotiation. The result of this function may not match -+ * Octeon's link config if auto negotiation has changed since -+ * the last call to cvmx_helper_link_set(). -+ * -+ * @ipd_port: IPD/PKO port to query -+ * -+ * Returns Link state -+ */ -+extern cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port); -+ -+/** -+ * Configure an IPD/PKO port for the specified link state. This -+ * function does not influence auto negotiation at the PHY level. -+ * The passed link state must always match the link state returned -+ * by cvmx_helper_link_get(). It is normally best to use -+ * cvmx_helper_link_autoconf() instead. -+ * -+ * @ipd_port: IPD/PKO port to configure -+ * @link_info: The new link state -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int __cvmx_helper_xaui_link_set(int ipd_port, -+ cvmx_helper_link_info_t link_info); -+ -+/** -+ * Configure a port for internal and/or external loopback. Internal loopback -+ * causes packets sent by the port to be received by Octeon. External loopback -+ * causes packets received from the wire to sent out again. -+ * -+ * @ipd_port: IPD/PKO port to loopback. -+ * @enable_internal: -+ * Non zero if you want internal loopback -+ * @enable_external: -+ * Non zero if you want external loopback -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+extern int __cvmx_helper_xaui_configure_loopback(int ipd_port, -+ int enable_internal, -+ int enable_external); -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper.c -@@ -0,0 +1,1058 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * -+ * Helper functions for common, but complicated tasks. -+ * -+ */ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-config.h" -+ -+#include "cvmx-fpa.h" -+#include "cvmx-pip.h" -+#include "cvmx-pko.h" -+#include "cvmx-ipd.h" -+#include "cvmx-spi.h" -+#include "cvmx-helper.h" -+#include "cvmx-helper-board.h" -+ -+#include "cvmx-pip-defs.h" -+#include "cvmx-smix-defs.h" -+#include "cvmx-asxx-defs.h" -+ -+/** -+ * cvmx_override_pko_queue_priority(int ipd_port, uint64_t -+ * priorities[16]) is a function pointer. It is meant to allow -+ * customization of the PKO queue priorities based on the port -+ * number. Users should set this pointer to a function before -+ * calling any cvmx-helper operations. -+ */ -+void (*cvmx_override_pko_queue_priority) (int pko_port, -+ uint64_t priorities[16]); -+ -+/** -+ * cvmx_override_ipd_port_setup(int ipd_port) is a function -+ * pointer. It is meant to allow customization of the IPD port -+ * setup before packet input/output comes online. It is called -+ * after cvmx-helper does the default IPD configuration, but -+ * before IPD is enabled. Users should set this pointer to a -+ * function before calling any cvmx-helper operations. -+ */ -+void (*cvmx_override_ipd_port_setup) (int ipd_port); -+ -+/* Port count per interface */ -+static int interface_port_count[4] = { 0, 0, 0, 0 }; -+ -+/* Port last configured link info index by IPD/PKO port */ -+static cvmx_helper_link_info_t -+ port_link_info[CVMX_PIP_NUM_INPUT_PORTS]; -+ -+/** -+ * Return the number of interfaces the chip has. Each interface -+ * may have multiple ports. Most chips support two interfaces, -+ * but the CNX0XX and CNX1XX are exceptions. These only support -+ * one interface. -+ * -+ * Returns Number of interfaces on chip -+ */ -+int cvmx_helper_get_number_of_interfaces(void) -+{ -+ if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) -+ return 4; -+ else -+ return 3; -+} -+ -+/** -+ * Return the number of ports on an interface. Depending on the -+ * chip and configuration, this can be 1-16. A value of 0 -+ * specifies that the interface doesn't exist or isn't usable. -+ * -+ * @interface: Interface to get the port count for -+ * -+ * Returns Number of ports on interface. Can be Zero. -+ */ -+int cvmx_helper_ports_on_interface(int interface) -+{ -+ return interface_port_count[interface]; -+} -+ -+/** -+ * 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. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Mode of the interface. Unknown or unsupported interfaces return -+ * DISABLED. -+ */ -+cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface) -+{ -+ union cvmx_gmxx_inf_mode mode; -+ if (interface == 2) -+ return CVMX_HELPER_INTERFACE_MODE_NPI; -+ -+ if (interface == 3) { -+ if (OCTEON_IS_MODEL(OCTEON_CN56XX) -+ || OCTEON_IS_MODEL(OCTEON_CN52XX)) -+ return CVMX_HELPER_INTERFACE_MODE_LOOP; -+ else -+ return CVMX_HELPER_INTERFACE_MODE_DISABLED; -+ } -+ -+ if (interface == 0 -+ && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5 -+ && cvmx_sysinfo_get()->board_rev_major == 1) { -+ /* -+ * Lie about interface type of CN3005 board. This -+ * board has a switch on port 1 like the other -+ * evaluation boards, but it is connected over RGMII -+ * instead of GMII. Report GMII mode so that the -+ * speed is forced to 1 Gbit full duplex. Other than -+ * some initial configuration (which does not use the -+ * output of this function) there is no difference in -+ * setup between GMII and RGMII modes. -+ */ -+ return CVMX_HELPER_INTERFACE_MODE_GMII; -+ } -+ -+ /* Interface 1 is always disabled on CN31XX and CN30XX */ -+ if ((interface == 1) -+ && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX) -+ || OCTEON_IS_MODEL(OCTEON_CN50XX) -+ || OCTEON_IS_MODEL(OCTEON_CN52XX))) -+ return CVMX_HELPER_INTERFACE_MODE_DISABLED; -+ -+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); -+ -+ if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) { -+ switch (mode.cn56xx.mode) { -+ case 0: -+ return CVMX_HELPER_INTERFACE_MODE_DISABLED; -+ case 1: -+ return CVMX_HELPER_INTERFACE_MODE_XAUI; -+ case 2: -+ return CVMX_HELPER_INTERFACE_MODE_SGMII; -+ case 3: -+ return CVMX_HELPER_INTERFACE_MODE_PICMG; -+ default: -+ return CVMX_HELPER_INTERFACE_MODE_DISABLED; -+ } -+ } else { -+ if (!mode.s.en) -+ return CVMX_HELPER_INTERFACE_MODE_DISABLED; -+ -+ if (mode.s.type) { -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) -+ || OCTEON_IS_MODEL(OCTEON_CN58XX)) -+ return CVMX_HELPER_INTERFACE_MODE_SPI; -+ else -+ return CVMX_HELPER_INTERFACE_MODE_GMII; -+ } else -+ return CVMX_HELPER_INTERFACE_MODE_RGMII; -+ } -+} -+ -+/** -+ * Configure the IPD/PIP tagging and QoS options for a specific -+ * port. This function determines the POW work queue entry -+ * contents for a port. The setup performed here is controlled by -+ * the defines in executive-config.h. -+ * -+ * @ipd_port: Port to configure. This follows the IPD numbering, not the -+ * per interface numbering -+ * -+ * Returns Zero on success, negative on failure -+ */ -+static int __cvmx_helper_port_setup_ipd(int ipd_port) -+{ -+ union cvmx_pip_prt_cfgx port_config; -+ union cvmx_pip_prt_tagx tag_config; -+ -+ port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port)); -+ tag_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port)); -+ -+ /* Have each port go to a different POW queue */ -+ port_config.s.qos = ipd_port & 0x7; -+ -+ /* Process the headers and place the IP header in the work queue */ -+ port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE; -+ -+ tag_config.s.ip6_src_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP; -+ tag_config.s.ip6_dst_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_IP; -+ tag_config.s.ip6_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT; -+ tag_config.s.ip6_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT; -+ tag_config.s.ip6_nxth_flag = CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER; -+ tag_config.s.ip4_src_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP; -+ tag_config.s.ip4_dst_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_IP; -+ tag_config.s.ip4_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT; -+ tag_config.s.ip4_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT; -+ tag_config.s.ip4_pctl_flag = CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL; -+ tag_config.s.inc_prt_flag = CVMX_HELPER_INPUT_TAG_INPUT_PORT; -+ tag_config.s.tcp6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE; -+ tag_config.s.tcp4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE; -+ tag_config.s.ip6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE; -+ tag_config.s.ip4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE; -+ tag_config.s.non_tag_type = CVMX_HELPER_INPUT_TAG_TYPE; -+ /* Put all packets in group 0. Other groups can be used by the app */ -+ tag_config.s.grp = 0; -+ -+ cvmx_pip_config_port(ipd_port, port_config, tag_config); -+ -+ /* Give the user a chance to override our setting for each port */ -+ if (cvmx_override_ipd_port_setup) -+ cvmx_override_ipd_port_setup(ipd_port); -+ -+ return 0; -+} -+ -+/** -+ * This function probes an interface to determine the actual -+ * number of hardware ports connected to it. It doesn't setup the -+ * ports or enable them. The main goal here is to set the global -+ * interface_port_count[interface] correctly. Hardware setup of the -+ * ports will be performed later. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int cvmx_helper_interface_probe(int interface) -+{ -+ /* At this stage in the game we don't want packets to be moving yet. -+ The following probe calls should perform hardware setup -+ needed to determine port counts. Receive must still be disabled */ -+ switch (cvmx_helper_interface_get_mode(interface)) { -+ /* These types don't support ports to IPD/PKO */ -+ case CVMX_HELPER_INTERFACE_MODE_DISABLED: -+ case CVMX_HELPER_INTERFACE_MODE_PCIE: -+ interface_port_count[interface] = 0; -+ break; -+ /* XAUI is a single high speed port */ -+ case CVMX_HELPER_INTERFACE_MODE_XAUI: -+ interface_port_count[interface] = -+ __cvmx_helper_xaui_probe(interface); -+ break; -+ /* -+ * RGMII/GMII/MII are all treated about the same. Most -+ * functions refer to these ports as RGMII. -+ */ -+ case CVMX_HELPER_INTERFACE_MODE_RGMII: -+ case CVMX_HELPER_INTERFACE_MODE_GMII: -+ interface_port_count[interface] = -+ __cvmx_helper_rgmii_probe(interface); -+ break; -+ /* -+ * SPI4 can have 1-16 ports depending on the device at -+ * the other end. -+ */ -+ case CVMX_HELPER_INTERFACE_MODE_SPI: -+ interface_port_count[interface] = -+ __cvmx_helper_spi_probe(interface); -+ break; -+ /* -+ * SGMII can have 1-4 ports depending on how many are -+ * hooked up. -+ */ -+ case CVMX_HELPER_INTERFACE_MODE_SGMII: -+ case CVMX_HELPER_INTERFACE_MODE_PICMG: -+ interface_port_count[interface] = -+ __cvmx_helper_sgmii_probe(interface); -+ break; -+ /* PCI target Network Packet Interface */ -+ case CVMX_HELPER_INTERFACE_MODE_NPI: -+ interface_port_count[interface] = -+ __cvmx_helper_npi_probe(interface); -+ break; -+ /* -+ * Special loopback only ports. These are not the same -+ * as other ports in loopback mode. -+ */ -+ case CVMX_HELPER_INTERFACE_MODE_LOOP: -+ interface_port_count[interface] = -+ __cvmx_helper_loop_probe(interface); -+ break; -+ } -+ -+ interface_port_count[interface] = -+ __cvmx_helper_board_interface_probe(interface, -+ interface_port_count -+ [interface]); -+ -+ /* Make sure all global variables propagate to other cores */ -+ CVMX_SYNCWS; -+ -+ return 0; -+} -+ -+/** -+ * Setup the IPD/PIP for the ports on an interface. Packet -+ * classification and tagging are set for every port on the -+ * interface. The number of ports on the interface must already -+ * have been probed. -+ * -+ * @interface: Interface to setup IPD/PIP for -+ * -+ * Returns Zero on success, negative on failure -+ */ -+static int __cvmx_helper_interface_setup_ipd(int interface) -+{ -+ int ipd_port = cvmx_helper_get_ipd_port(interface, 0); -+ int num_ports = interface_port_count[interface]; -+ -+ while (num_ports--) { -+ __cvmx_helper_port_setup_ipd(ipd_port); -+ ipd_port++; -+ } -+ return 0; -+} -+ -+/** -+ * Setup global setting for IPD/PIP not related to a specific -+ * interface or port. This must be called before IPD is enabled. -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+static int __cvmx_helper_global_setup_ipd(void) -+{ -+ /* Setup the global packet input options */ -+ cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE / 8, -+ CVMX_HELPER_FIRST_MBUFF_SKIP / 8, -+ CVMX_HELPER_NOT_FIRST_MBUFF_SKIP / 8, -+ /* The +8 is to account for the next ptr */ -+ (CVMX_HELPER_FIRST_MBUFF_SKIP + 8) / 128, -+ /* The +8 is to account for the next ptr */ -+ (CVMX_HELPER_NOT_FIRST_MBUFF_SKIP + 8) / 128, -+ CVMX_FPA_WQE_POOL, -+ CVMX_IPD_OPC_MODE_STT, -+ CVMX_HELPER_ENABLE_BACK_PRESSURE); -+ return 0; -+} -+ -+/** -+ * Setup the PKO for the ports on an interface. The number of -+ * queues per port and the priority of each PKO output queue -+ * is set here. PKO must be disabled when this function is called. -+ * -+ * @interface: Interface to setup PKO for -+ * -+ * Returns Zero on success, negative on failure -+ */ -+static int __cvmx_helper_interface_setup_pko(int interface) -+{ -+ /* -+ * Each packet output queue has an associated priority. The -+ * higher the priority, the more often it can send a packet. A -+ * priority of 8 means it can send in all 8 rounds of -+ * contention. We're going to make each queue one less than -+ * the last. The vector of priorities has been extended to -+ * support CN5xxx CPUs, where up to 16 queues can be -+ * associated to a port. To keep backward compatibility we -+ * don't change the initial 8 priorities and replicate them in -+ * the second half. With per-core PKO queues (PKO lockless -+ * operation) all queues have the same priority. -+ */ -+ uint64_t priorities[16] = -+ { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 }; -+ -+ /* -+ * Setup the IPD/PIP and PKO for the ports discovered -+ * above. Here packet classification, tagging and output -+ * priorities are set. -+ */ -+ int ipd_port = cvmx_helper_get_ipd_port(interface, 0); -+ int num_ports = interface_port_count[interface]; -+ while (num_ports--) { -+ /* -+ * Give the user a chance to override the per queue -+ * priorities. -+ */ -+ if (cvmx_override_pko_queue_priority) -+ cvmx_override_pko_queue_priority(ipd_port, priorities); -+ -+ cvmx_pko_config_port(ipd_port, -+ cvmx_pko_get_base_queue_per_core(ipd_port, -+ 0), -+ cvmx_pko_get_num_queues(ipd_port), -+ priorities); -+ ipd_port++; -+ } -+ return 0; -+} -+ -+/** -+ * Setup global setting for PKO not related to a specific -+ * interface or port. This must be called before PKO is enabled. -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+static int __cvmx_helper_global_setup_pko(void) -+{ -+ /* -+ * Disable tagwait FAU timeout. This needs to be done before -+ * anyone might start packet output using tags. -+ */ -+ union cvmx_iob_fau_timeout fau_to; -+ fau_to.u64 = 0; -+ fau_to.s.tout_val = 0xfff; -+ fau_to.s.tout_enb = 0; -+ cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64); -+ return 0; -+} -+ -+/** -+ * Setup global backpressure setting. -+ * -+ * Returns Zero on success, negative on failure -+ */ -+static int __cvmx_helper_global_setup_backpressure(void) -+{ -+#if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE -+ /* Disable backpressure if configured to do so */ -+ /* Disable backpressure (pause frame) generation */ -+ int num_interfaces = cvmx_helper_get_number_of_interfaces(); -+ int interface; -+ for (interface = 0; interface < num_interfaces; interface++) { -+ switch (cvmx_helper_interface_get_mode(interface)) { -+ case CVMX_HELPER_INTERFACE_MODE_DISABLED: -+ case CVMX_HELPER_INTERFACE_MODE_PCIE: -+ case CVMX_HELPER_INTERFACE_MODE_NPI: -+ case CVMX_HELPER_INTERFACE_MODE_LOOP: -+ case CVMX_HELPER_INTERFACE_MODE_XAUI: -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_RGMII: -+ case CVMX_HELPER_INTERFACE_MODE_GMII: -+ case CVMX_HELPER_INTERFACE_MODE_SPI: -+ case CVMX_HELPER_INTERFACE_MODE_SGMII: -+ case CVMX_HELPER_INTERFACE_MODE_PICMG: -+ cvmx_gmx_set_backpressure_override(interface, 0xf); -+ break; -+ } -+ } -+#endif -+ -+ return 0; -+} -+ -+/** -+ * Enable packet input/output from the hardware. This function is -+ * called after all internal setup is complete and IPD is enabled. -+ * After this function completes, packets will be accepted from the -+ * hardware ports. PKO should still be disabled to make sure packets -+ * aren't sent out partially setup hardware. -+ * -+ * @interface: Interface to enable -+ * -+ * Returns Zero on success, negative on failure -+ */ -+static int __cvmx_helper_packet_hardware_enable(int interface) -+{ -+ int result = 0; -+ switch (cvmx_helper_interface_get_mode(interface)) { -+ /* These types don't support ports to IPD/PKO */ -+ case CVMX_HELPER_INTERFACE_MODE_DISABLED: -+ case CVMX_HELPER_INTERFACE_MODE_PCIE: -+ /* Nothing to do */ -+ break; -+ /* XAUI is a single high speed port */ -+ case CVMX_HELPER_INTERFACE_MODE_XAUI: -+ result = __cvmx_helper_xaui_enable(interface); -+ break; -+ /* -+ * RGMII/GMII/MII are all treated about the same. Most -+ * functions refer to these ports as RGMII -+ */ -+ case CVMX_HELPER_INTERFACE_MODE_RGMII: -+ case CVMX_HELPER_INTERFACE_MODE_GMII: -+ result = __cvmx_helper_rgmii_enable(interface); -+ break; -+ /* -+ * SPI4 can have 1-16 ports depending on the device at -+ * the other end -+ */ -+ case CVMX_HELPER_INTERFACE_MODE_SPI: -+ result = __cvmx_helper_spi_enable(interface); -+ break; -+ /* -+ * SGMII can have 1-4 ports depending on how many are -+ * hooked up -+ */ -+ case CVMX_HELPER_INTERFACE_MODE_SGMII: -+ case CVMX_HELPER_INTERFACE_MODE_PICMG: -+ result = __cvmx_helper_sgmii_enable(interface); -+ break; -+ /* PCI target Network Packet Interface */ -+ case CVMX_HELPER_INTERFACE_MODE_NPI: -+ result = __cvmx_helper_npi_enable(interface); -+ break; -+ /* -+ * Special loopback only ports. These are not the same -+ * as other ports in loopback mode -+ */ -+ case CVMX_HELPER_INTERFACE_MODE_LOOP: -+ result = __cvmx_helper_loop_enable(interface); -+ break; -+ } -+ result |= __cvmx_helper_board_hardware_enable(interface); -+ return result; -+} -+ -+/** -+ * Function to adjust internal IPD pointer alignments -+ * -+ * Returns 0 on success -+ * !0 on failure -+ */ -+int __cvmx_helper_errata_fix_ipd_ptr_alignment(void) -+{ -+#define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \ -+ (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_FIRST_MBUFF_SKIP) -+#define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \ -+ (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_NOT_FIRST_MBUFF_SKIP) -+#define FIX_IPD_OUTPORT 0 -+ /* Ports 0-15 are interface 0, 16-31 are interface 1 */ -+#define INTERFACE(port) (port >> 4) -+#define INDEX(port) (port & 0xf) -+ uint64_t *p64; -+ cvmx_pko_command_word0_t pko_command; -+ union cvmx_buf_ptr g_buffer, pkt_buffer; -+ cvmx_wqe_t *work; -+ int size, num_segs = 0, wqe_pcnt, pkt_pcnt; -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ int retry_cnt; -+ int retry_loop_cnt; -+ int mtu; -+ int i; -+ cvmx_helper_link_info_t link_info; -+ -+ /* Save values for restore at end */ -+ uint64_t prtx_cfg = -+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG -+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT))); -+ uint64_t tx_ptr_en = -+ cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT))); -+ uint64_t rx_ptr_en = -+ cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT))); -+ uint64_t rxx_jabber = -+ cvmx_read_csr(CVMX_GMXX_RXX_JABBER -+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT))); -+ uint64_t frame_max = -+ cvmx_read_csr(CVMX_GMXX_RXX_FRM_MAX -+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT))); -+ -+ /* Configure port to gig FDX as required for loopback mode */ -+ cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT); -+ -+ /* -+ * Disable reception on all ports so if traffic is present it -+ * will not interfere. -+ */ -+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 0); -+ -+ cvmx_wait(100000000ull); -+ -+ for (retry_loop_cnt = 0; retry_loop_cnt < 10; retry_loop_cnt++) { -+ retry_cnt = 100000; -+ wqe_pcnt = cvmx_read_csr(CVMX_IPD_PTR_COUNT); -+ pkt_pcnt = (wqe_pcnt >> 7) & 0x7f; -+ wqe_pcnt &= 0x7f; -+ -+ num_segs = (2 + pkt_pcnt - wqe_pcnt) & 3; -+ -+ if (num_segs == 0) -+ goto fix_ipd_exit; -+ -+ num_segs += 1; -+ -+ size = -+ FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES + -+ ((num_segs - 1) * FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES) - -+ (FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES / 2); -+ -+ cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), -+ 1 << INDEX(FIX_IPD_OUTPORT)); -+ CVMX_SYNC; -+ -+ g_buffer.u64 = 0; -+ g_buffer.s.addr = -+ cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_WQE_POOL)); -+ if (g_buffer.s.addr == 0) { -+ cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT " -+ "buffer allocation failure.\n"); -+ goto fix_ipd_exit; -+ } -+ -+ g_buffer.s.pool = CVMX_FPA_WQE_POOL; -+ g_buffer.s.size = num_segs; -+ -+ pkt_buffer.u64 = 0; -+ pkt_buffer.s.addr = -+ cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL)); -+ if (pkt_buffer.s.addr == 0) { -+ cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT " -+ "buffer allocation failure.\n"); -+ goto fix_ipd_exit; -+ } -+ pkt_buffer.s.i = 1; -+ pkt_buffer.s.pool = CVMX_FPA_PACKET_POOL; -+ pkt_buffer.s.size = FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES; -+ -+ p64 = (uint64_t *) cvmx_phys_to_ptr(pkt_buffer.s.addr); -+ p64[0] = 0xffffffffffff0000ull; -+ p64[1] = 0x08004510ull; -+ p64[2] = ((uint64_t) (size - 14) << 48) | 0x5ae740004000ull; -+ p64[3] = 0x3a5fc0a81073c0a8ull; -+ -+ for (i = 0; i < num_segs; i++) { -+ if (i > 0) -+ pkt_buffer.s.size = -+ FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES; -+ -+ if (i == (num_segs - 1)) -+ pkt_buffer.s.i = 0; -+ -+ *(uint64_t *) cvmx_phys_to_ptr(g_buffer.s.addr + -+ 8 * i) = pkt_buffer.u64; -+ } -+ -+ /* Build the PKO command */ -+ pko_command.u64 = 0; -+ pko_command.s.segs = num_segs; -+ pko_command.s.total_bytes = size; -+ pko_command.s.dontfree = 0; -+ pko_command.s.gather = 1; -+ -+ gmx_cfg.u64 = -+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG -+ (INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT))); -+ gmx_cfg.s.en = 1; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG -+ (INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT)), gmx_cfg.u64); -+ cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), -+ 1 << INDEX(FIX_IPD_OUTPORT)); -+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), -+ 1 << INDEX(FIX_IPD_OUTPORT)); -+ -+ mtu = -+ cvmx_read_csr(CVMX_GMXX_RXX_JABBER -+ (INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT))); -+ cvmx_write_csr(CVMX_GMXX_RXX_JABBER -+ (INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4); -+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX -+ (INDEX(FIX_IPD_OUTPORT), -+ INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4); -+ -+ cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT, -+ cvmx_pko_get_base_queue -+ (FIX_IPD_OUTPORT), -+ CVMX_PKO_LOCK_CMD_QUEUE); -+ cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT, -+ cvmx_pko_get_base_queue -+ (FIX_IPD_OUTPORT), pko_command, -+ g_buffer, CVMX_PKO_LOCK_CMD_QUEUE); -+ -+ CVMX_SYNC; -+ -+ do { -+ work = cvmx_pow_work_request_sync(CVMX_POW_WAIT); -+ retry_cnt--; -+ } while ((work == NULL) && (retry_cnt > 0)); -+ -+ if (!retry_cnt) -+ cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT " -+ "get_work() timeout occured.\n"); -+ -+ /* Free packet */ -+ if (work) -+ cvmx_helper_free_packet_data(work); -+ } -+ -+fix_ipd_exit: -+ -+ /* Return CSR configs to saved values */ -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG -+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)), -+ prtx_cfg); -+ cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), -+ tx_ptr_en); -+ cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), -+ rx_ptr_en); -+ cvmx_write_csr(CVMX_GMXX_RXX_JABBER -+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)), -+ rxx_jabber); -+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX -+ (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)), -+ frame_max); -+ cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0); -+ /* Set link to down so autonegotiation will set it up again */ -+ link_info.u64 = 0; -+ cvmx_helper_link_set(FIX_IPD_OUTPORT, link_info); -+ -+ /* -+ * Bring the link back up as autonegotiation is not done in -+ * user applications. -+ */ -+ cvmx_helper_link_autoconf(FIX_IPD_OUTPORT); -+ -+ CVMX_SYNC; -+ if (num_segs) -+ cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n"); -+ -+ return !!num_segs; -+ -+} -+ -+/** -+ * Called after all internal packet IO paths are setup. This -+ * function enables IPD/PIP and begins packet input and output. -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int cvmx_helper_ipd_and_packet_input_enable(void) -+{ -+ int num_interfaces; -+ int interface; -+ -+ /* Enable IPD */ -+ cvmx_ipd_enable(); -+ -+ /* -+ * Time to enable hardware ports packet input and output. Note -+ * that at this point IPD/PIP must be fully functional and PKO -+ * must be disabled -+ */ -+ num_interfaces = cvmx_helper_get_number_of_interfaces(); -+ for (interface = 0; interface < num_interfaces; interface++) { -+ if (cvmx_helper_ports_on_interface(interface) > 0) -+ __cvmx_helper_packet_hardware_enable(interface); -+ } -+ -+ /* Finally enable PKO now that the entire path is up and running */ -+ cvmx_pko_enable(); -+ -+ if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1) -+ || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1)) -+ && (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM)) -+ __cvmx_helper_errata_fix_ipd_ptr_alignment(); -+ return 0; -+} -+ -+/** -+ * Initialize the PIP, IPD, and PKO hardware to support -+ * simple priority based queues for the ethernet ports. Each -+ * port is configured with a number of priority queues based -+ * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower -+ * priority than the previous. -+ * -+ * Returns Zero on success, non-zero on failure -+ */ -+int cvmx_helper_initialize_packet_io_global(void) -+{ -+ int result = 0; -+ int interface; -+ union cvmx_l2c_cfg l2c_cfg; -+ union cvmx_smix_en smix_en; -+ const int num_interfaces = cvmx_helper_get_number_of_interfaces(); -+ -+ /* -+ * CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to -+ * be disabled. -+ */ -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0)) -+ __cvmx_helper_errata_qlm_disable_2nd_order_cdr(1); -+ -+ /* -+ * Tell L2 to give the IOB statically higher priority compared -+ * to the cores. This avoids conditions where IO blocks might -+ * be starved under very high L2 loads. -+ */ -+ l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG); -+ l2c_cfg.s.lrf_arb_mode = 0; -+ l2c_cfg.s.rfb_arb_mode = 0; -+ cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64); -+ -+ /* Make sure SMI/MDIO is enabled so we can query PHYs */ -+ smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0)); -+ if (!smix_en.s.en) { -+ smix_en.s.en = 1; -+ cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64); -+ } -+ -+ /* Newer chips actually have two SMI/MDIO interfaces */ -+ if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) && -+ !OCTEON_IS_MODEL(OCTEON_CN58XX) && -+ !OCTEON_IS_MODEL(OCTEON_CN50XX)) { -+ smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1)); -+ if (!smix_en.s.en) { -+ smix_en.s.en = 1; -+ cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64); -+ } -+ } -+ -+ cvmx_pko_initialize_global(); -+ for (interface = 0; interface < num_interfaces; interface++) { -+ result |= cvmx_helper_interface_probe(interface); -+ if (cvmx_helper_ports_on_interface(interface) > 0) -+ cvmx_dprintf("Interface %d has %d ports (%s)\n", -+ interface, -+ cvmx_helper_ports_on_interface(interface), -+ cvmx_helper_interface_mode_to_string -+ (cvmx_helper_interface_get_mode -+ (interface))); -+ result |= __cvmx_helper_interface_setup_ipd(interface); -+ result |= __cvmx_helper_interface_setup_pko(interface); -+ } -+ -+ result |= __cvmx_helper_global_setup_ipd(); -+ result |= __cvmx_helper_global_setup_pko(); -+ -+ /* Enable any flow control and backpressure */ -+ result |= __cvmx_helper_global_setup_backpressure(); -+ -+#if CVMX_HELPER_ENABLE_IPD -+ result |= cvmx_helper_ipd_and_packet_input_enable(); -+#endif -+ return result; -+} -+ -+/** -+ * Does core local initialization for packet io -+ * -+ * Returns Zero on success, non-zero on failure -+ */ -+int cvmx_helper_initialize_packet_io_local(void) -+{ -+ return cvmx_pko_initialize_local(); -+} -+ -+/** -+ * Auto configure an IPD/PKO port link state and speed. This -+ * function basically does the equivalent of: -+ * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port)); -+ * -+ * @ipd_port: IPD/PKO port to auto configure -+ * -+ * Returns Link state after configure -+ */ -+cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port) -+{ -+ cvmx_helper_link_info_t link_info; -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ int index = cvmx_helper_get_interface_index_num(ipd_port); -+ -+ if (index >= cvmx_helper_ports_on_interface(interface)) { -+ link_info.u64 = 0; -+ return link_info; -+ } -+ -+ link_info = cvmx_helper_link_get(ipd_port); -+ if (link_info.u64 == port_link_info[ipd_port].u64) -+ return link_info; -+ -+ /* If we fail to set the link speed, port_link_info will not change */ -+ cvmx_helper_link_set(ipd_port, link_info); -+ -+ /* -+ * port_link_info should be the current value, which will be -+ * different than expect if cvmx_helper_link_set() failed. -+ */ -+ return port_link_info[ipd_port]; -+} -+ -+/** -+ * Return the link state of an IPD/PKO port as returned by -+ * auto negotiation. The result of this function may not match -+ * Octeon's link config if auto negotiation has changed since -+ * the last call to cvmx_helper_link_set(). -+ * -+ * @ipd_port: IPD/PKO port to query -+ * -+ * Returns Link state -+ */ -+cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port) -+{ -+ cvmx_helper_link_info_t result; -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ int index = cvmx_helper_get_interface_index_num(ipd_port); -+ -+ /* The default result will be a down link unless the code below -+ changes it */ -+ result.u64 = 0; -+ -+ if (index >= cvmx_helper_ports_on_interface(interface)) -+ return result; -+ -+ switch (cvmx_helper_interface_get_mode(interface)) { -+ case CVMX_HELPER_INTERFACE_MODE_DISABLED: -+ case CVMX_HELPER_INTERFACE_MODE_PCIE: -+ /* Network links are not supported */ -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_XAUI: -+ result = __cvmx_helper_xaui_link_get(ipd_port); -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_GMII: -+ if (index == 0) -+ result = __cvmx_helper_rgmii_link_get(ipd_port); -+ else { -+ result.s.full_duplex = 1; -+ result.s.link_up = 1; -+ result.s.speed = 1000; -+ } -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_RGMII: -+ result = __cvmx_helper_rgmii_link_get(ipd_port); -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_SPI: -+ result = __cvmx_helper_spi_link_get(ipd_port); -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_SGMII: -+ case CVMX_HELPER_INTERFACE_MODE_PICMG: -+ result = __cvmx_helper_sgmii_link_get(ipd_port); -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_NPI: -+ case CVMX_HELPER_INTERFACE_MODE_LOOP: -+ /* Network links are not supported */ -+ break; -+ } -+ return result; -+} -+ -+/** -+ * Configure an IPD/PKO port for the specified link state. This -+ * function does not influence auto negotiation at the PHY level. -+ * The passed link state must always match the link state returned -+ * by cvmx_helper_link_get(). It is normally best to use -+ * cvmx_helper_link_autoconf() instead. -+ * -+ * @ipd_port: IPD/PKO port to configure -+ * @link_info: The new link state -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info) -+{ -+ int result = -1; -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ int index = cvmx_helper_get_interface_index_num(ipd_port); -+ -+ if (index >= cvmx_helper_ports_on_interface(interface)) -+ return -1; -+ -+ switch (cvmx_helper_interface_get_mode(interface)) { -+ case CVMX_HELPER_INTERFACE_MODE_DISABLED: -+ case CVMX_HELPER_INTERFACE_MODE_PCIE: -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_XAUI: -+ result = __cvmx_helper_xaui_link_set(ipd_port, link_info); -+ break; -+ /* -+ * RGMII/GMII/MII are all treated about the same. Most -+ * functions refer to these ports as RGMII. -+ */ -+ case CVMX_HELPER_INTERFACE_MODE_RGMII: -+ case CVMX_HELPER_INTERFACE_MODE_GMII: -+ result = __cvmx_helper_rgmii_link_set(ipd_port, link_info); -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_SPI: -+ result = __cvmx_helper_spi_link_set(ipd_port, link_info); -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_SGMII: -+ case CVMX_HELPER_INTERFACE_MODE_PICMG: -+ result = __cvmx_helper_sgmii_link_set(ipd_port, link_info); -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_NPI: -+ case CVMX_HELPER_INTERFACE_MODE_LOOP: -+ break; -+ } -+ /* Set the port_link_info here so that the link status is updated -+ no matter how cvmx_helper_link_set is called. We don't change -+ the value if link_set failed */ -+ if (result == 0) -+ port_link_info[ipd_port].u64 = link_info.u64; -+ return result; -+} -+ -+/** -+ * Configure a port for internal and/or external loopback. Internal loopback -+ * causes packets sent by the port to be received by Octeon. External loopback -+ * causes packets received from the wire to sent out again. -+ * -+ * @ipd_port: IPD/PKO port to loopback. -+ * @enable_internal: -+ * Non zero if you want internal loopback -+ * @enable_external: -+ * Non zero if you want external loopback -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+int cvmx_helper_configure_loopback(int ipd_port, int enable_internal, -+ int enable_external) -+{ -+ int result = -1; -+ int interface = cvmx_helper_get_interface_num(ipd_port); -+ int index = cvmx_helper_get_interface_index_num(ipd_port); -+ -+ if (index >= cvmx_helper_ports_on_interface(interface)) -+ return -1; -+ -+ switch (cvmx_helper_interface_get_mode(interface)) { -+ case CVMX_HELPER_INTERFACE_MODE_DISABLED: -+ case CVMX_HELPER_INTERFACE_MODE_PCIE: -+ case CVMX_HELPER_INTERFACE_MODE_SPI: -+ case CVMX_HELPER_INTERFACE_MODE_NPI: -+ case CVMX_HELPER_INTERFACE_MODE_LOOP: -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_XAUI: -+ result = -+ __cvmx_helper_xaui_configure_loopback(ipd_port, -+ enable_internal, -+ enable_external); -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_RGMII: -+ case CVMX_HELPER_INTERFACE_MODE_GMII: -+ result = -+ __cvmx_helper_rgmii_configure_loopback(ipd_port, -+ enable_internal, -+ enable_external); -+ break; -+ case CVMX_HELPER_INTERFACE_MODE_SGMII: -+ case CVMX_HELPER_INTERFACE_MODE_PICMG: -+ result = -+ __cvmx_helper_sgmii_configure_loopback(ipd_port, -+ enable_internal, -+ enable_external); -+ break; -+ } -+ return result; -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-helper.h -@@ -0,0 +1,227 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * -+ * Helper functions for common, but complicated tasks. -+ * -+ */ -+ -+#ifndef __CVMX_HELPER_H__ -+#define __CVMX_HELPER_H__ -+ -+#include "cvmx-config.h" -+#include "cvmx-fpa.h" -+#include "cvmx-wqe.h" -+ -+typedef enum { -+ CVMX_HELPER_INTERFACE_MODE_DISABLED, -+ CVMX_HELPER_INTERFACE_MODE_RGMII, -+ CVMX_HELPER_INTERFACE_MODE_GMII, -+ CVMX_HELPER_INTERFACE_MODE_SPI, -+ CVMX_HELPER_INTERFACE_MODE_PCIE, -+ CVMX_HELPER_INTERFACE_MODE_XAUI, -+ CVMX_HELPER_INTERFACE_MODE_SGMII, -+ CVMX_HELPER_INTERFACE_MODE_PICMG, -+ CVMX_HELPER_INTERFACE_MODE_NPI, -+ CVMX_HELPER_INTERFACE_MODE_LOOP, -+} cvmx_helper_interface_mode_t; -+ -+typedef union { -+ uint64_t u64; -+ struct { -+ uint64_t reserved_20_63:44; -+ uint64_t link_up:1; /**< Is the physical link up? */ -+ uint64_t full_duplex:1; /**< 1 if the link is full duplex */ -+ uint64_t speed:18; /**< Speed of the link in Mbps */ -+ } s; -+} cvmx_helper_link_info_t; -+ -+#include "cvmx-helper-fpa.h" -+ -+#include <asm/octeon/cvmx-helper-errata.h> -+#include "cvmx-helper-loop.h" -+#include "cvmx-helper-npi.h" -+#include "cvmx-helper-rgmii.h" -+#include "cvmx-helper-sgmii.h" -+#include "cvmx-helper-spi.h" -+#include "cvmx-helper-util.h" -+#include "cvmx-helper-xaui.h" -+ -+/** -+ * cvmx_override_pko_queue_priority(int ipd_port, uint64_t -+ * priorities[16]) is a function pointer. It is meant to allow -+ * customization of the PKO queue priorities based on the port -+ * number. Users should set this pointer to a function before -+ * calling any cvmx-helper operations. -+ */ -+extern void (*cvmx_override_pko_queue_priority) (int pko_port, -+ uint64_t priorities[16]); -+ -+/** -+ * cvmx_override_ipd_port_setup(int ipd_port) is a function -+ * pointer. It is meant to allow customization of the IPD port -+ * setup before packet input/output comes online. It is called -+ * after cvmx-helper does the default IPD configuration, but -+ * before IPD is enabled. Users should set this pointer to a -+ * function before calling any cvmx-helper operations. -+ */ -+extern void (*cvmx_override_ipd_port_setup) (int ipd_port); -+ -+/** -+ * This function enables the IPD and also enables the packet interfaces. -+ * The packet interfaces (RGMII and SPI) must be enabled after the -+ * IPD. This should be called by the user program after any additional -+ * IPD configuration changes are made if CVMX_HELPER_ENABLE_IPD -+ * is not set in the executive-config.h file. -+ * -+ * Returns 0 on success -+ * -1 on failure -+ */ -+extern int cvmx_helper_ipd_and_packet_input_enable(void); -+ -+/** -+ * Initialize the PIP, IPD, and PKO hardware to support -+ * simple priority based queues for the ethernet ports. Each -+ * port is configured with a number of priority queues based -+ * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower -+ * priority than the previous. -+ * -+ * Returns Zero on success, non-zero on failure -+ */ -+extern int cvmx_helper_initialize_packet_io_global(void); -+ -+/** -+ * Does core local initialization for packet io -+ * -+ * Returns Zero on success, non-zero on failure -+ */ -+extern int cvmx_helper_initialize_packet_io_local(void); -+ -+/** -+ * Returns the number of ports on the given interface. -+ * The interface must be initialized before the port count -+ * can be returned. -+ * -+ * @interface: Which interface to return port count for. -+ * -+ * Returns Port count for interface -+ * -1 for uninitialized interface -+ */ -+extern int cvmx_helper_ports_on_interface(int interface); -+ -+/** -+ * Return the number of interfaces the chip has. Each interface -+ * may have multiple ports. Most chips support two interfaces, -+ * but the CNX0XX and CNX1XX are exceptions. These only support -+ * one interface. -+ * -+ * Returns Number of interfaces on chip -+ */ -+extern int cvmx_helper_get_number_of_interfaces(void); -+ -+/** -+ * 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. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Mode of the interface. Unknown or unsupported interfaces return -+ * DISABLED. -+ */ -+extern cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int -+ interface); -+ -+/** -+ * Auto configure an IPD/PKO port link state and speed. This -+ * function basically does the equivalent of: -+ * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port)); -+ * -+ * @ipd_port: IPD/PKO port to auto configure -+ * -+ * Returns Link state after configure -+ */ -+extern cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port); -+ -+/** -+ * Return the link state of an IPD/PKO port as returned by -+ * auto negotiation. The result of this function may not match -+ * Octeon's link config if auto negotiation has changed since -+ * the last call to cvmx_helper_link_set(). -+ * -+ * @ipd_port: IPD/PKO port to query -+ * -+ * Returns Link state -+ */ -+extern cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port); -+ -+/** -+ * Configure an IPD/PKO port for the specified link state. This -+ * function does not influence auto negotiation at the PHY level. -+ * The passed link state must always match the link state returned -+ * by cvmx_helper_link_get(). It is normally best to use -+ * cvmx_helper_link_autoconf() instead. -+ * -+ * @ipd_port: IPD/PKO port to configure -+ * @link_info: The new link state -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int cvmx_helper_link_set(int ipd_port, -+ cvmx_helper_link_info_t link_info); -+ -+/** -+ * This function probes an interface to determine the actual -+ * number of hardware ports connected to it. It doesn't setup the -+ * ports or enable them. The main goal here is to set the global -+ * interface_port_count[interface] correctly. Hardware setup of the -+ * ports will be performed later. -+ * -+ * @interface: Interface to probe -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int cvmx_helper_interface_probe(int interface); -+ -+/** -+ * Configure a port for internal and/or external loopback. Internal loopback -+ * causes packets sent by the port to be received by Octeon. External loopback -+ * causes packets received from the wire to sent out again. -+ * -+ * @ipd_port: IPD/PKO port to loopback. -+ * @enable_internal: -+ * Non zero if you want internal loopback -+ * @enable_external: -+ * Non zero if you want external loopback -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+extern int cvmx_helper_configure_loopback(int ipd_port, int enable_internal, -+ int enable_external); -+ -+#endif /* __CVMX_HELPER_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-interrupt-decodes.c -@@ -0,0 +1,371 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2009 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * -+ * Automatically generated functions useful for enabling -+ * and decoding RSL_INT_BLOCKS interrupts. -+ * -+ */ -+ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-gmxx-defs.h" -+#include "cvmx-pcsx-defs.h" -+#include "cvmx-pcsxx-defs.h" -+#include "cvmx-spxx-defs.h" -+#include "cvmx-stxx-defs.h" -+ -+#ifndef PRINT_ERROR -+#define PRINT_ERROR(format, ...) -+#endif -+ -+ -+/** -+ * __cvmx_interrupt_gmxx_rxx_int_en_enable enables all interrupt bits in cvmx_gmxx_rxx_int_en_t -+ */ -+void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block) -+{ -+ union cvmx_gmxx_rxx_int_en gmx_rx_int_en; -+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, block), -+ cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, block))); -+ gmx_rx_int_en.u64 = 0; -+ if (OCTEON_IS_MODEL(OCTEON_CN56XX)) { -+ /* Skipping gmx_rx_int_en.s.reserved_29_63 */ -+ gmx_rx_int_en.s.hg2cc = 1; -+ gmx_rx_int_en.s.hg2fld = 1; -+ gmx_rx_int_en.s.undat = 1; -+ gmx_rx_int_en.s.uneop = 1; -+ gmx_rx_int_en.s.unsop = 1; -+ gmx_rx_int_en.s.bad_term = 1; -+ gmx_rx_int_en.s.bad_seq = 1; -+ gmx_rx_int_en.s.rem_fault = 1; -+ gmx_rx_int_en.s.loc_fault = 1; -+ gmx_rx_int_en.s.pause_drp = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_16_18 */ -+ /*gmx_rx_int_en.s.ifgerr = 1; */ -+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ -+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ -+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ -+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ -+ gmx_rx_int_en.s.ovrerr = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_9_9 */ -+ gmx_rx_int_en.s.skperr = 1; -+ gmx_rx_int_en.s.rcverr = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_5_6 */ -+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */ -+ gmx_rx_int_en.s.jabber = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_2_2 */ -+ gmx_rx_int_en.s.carext = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_0_0 */ -+ } -+ if (OCTEON_IS_MODEL(OCTEON_CN30XX)) { -+ /* Skipping gmx_rx_int_en.s.reserved_19_63 */ -+ /*gmx_rx_int_en.s.phy_dupx = 1; */ -+ /*gmx_rx_int_en.s.phy_spd = 1; */ -+ /*gmx_rx_int_en.s.phy_link = 1; */ -+ /*gmx_rx_int_en.s.ifgerr = 1; */ -+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ -+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ -+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ -+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ -+ gmx_rx_int_en.s.ovrerr = 1; -+ gmx_rx_int_en.s.niberr = 1; -+ gmx_rx_int_en.s.skperr = 1; -+ gmx_rx_int_en.s.rcverr = 1; -+ /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */ -+ gmx_rx_int_en.s.alnerr = 1; -+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */ -+ gmx_rx_int_en.s.jabber = 1; -+ gmx_rx_int_en.s.maxerr = 1; -+ gmx_rx_int_en.s.carext = 1; -+ gmx_rx_int_en.s.minerr = 1; -+ } -+ if (OCTEON_IS_MODEL(OCTEON_CN50XX)) { -+ /* Skipping gmx_rx_int_en.s.reserved_20_63 */ -+ gmx_rx_int_en.s.pause_drp = 1; -+ /*gmx_rx_int_en.s.phy_dupx = 1; */ -+ /*gmx_rx_int_en.s.phy_spd = 1; */ -+ /*gmx_rx_int_en.s.phy_link = 1; */ -+ /*gmx_rx_int_en.s.ifgerr = 1; */ -+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ -+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ -+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ -+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ -+ gmx_rx_int_en.s.ovrerr = 1; -+ gmx_rx_int_en.s.niberr = 1; -+ gmx_rx_int_en.s.skperr = 1; -+ gmx_rx_int_en.s.rcverr = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_6_6 */ -+ gmx_rx_int_en.s.alnerr = 1; -+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */ -+ gmx_rx_int_en.s.jabber = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_2_2 */ -+ gmx_rx_int_en.s.carext = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_0_0 */ -+ } -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)) { -+ /* Skipping gmx_rx_int_en.s.reserved_19_63 */ -+ /*gmx_rx_int_en.s.phy_dupx = 1; */ -+ /*gmx_rx_int_en.s.phy_spd = 1; */ -+ /*gmx_rx_int_en.s.phy_link = 1; */ -+ /*gmx_rx_int_en.s.ifgerr = 1; */ -+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ -+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ -+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ -+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ -+ gmx_rx_int_en.s.ovrerr = 1; -+ gmx_rx_int_en.s.niberr = 1; -+ gmx_rx_int_en.s.skperr = 1; -+ gmx_rx_int_en.s.rcverr = 1; -+ /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */ -+ gmx_rx_int_en.s.alnerr = 1; -+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */ -+ gmx_rx_int_en.s.jabber = 1; -+ gmx_rx_int_en.s.maxerr = 1; -+ gmx_rx_int_en.s.carext = 1; -+ gmx_rx_int_en.s.minerr = 1; -+ } -+ if (OCTEON_IS_MODEL(OCTEON_CN31XX)) { -+ /* Skipping gmx_rx_int_en.s.reserved_19_63 */ -+ /*gmx_rx_int_en.s.phy_dupx = 1; */ -+ /*gmx_rx_int_en.s.phy_spd = 1; */ -+ /*gmx_rx_int_en.s.phy_link = 1; */ -+ /*gmx_rx_int_en.s.ifgerr = 1; */ -+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ -+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ -+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ -+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ -+ gmx_rx_int_en.s.ovrerr = 1; -+ gmx_rx_int_en.s.niberr = 1; -+ gmx_rx_int_en.s.skperr = 1; -+ gmx_rx_int_en.s.rcverr = 1; -+ /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */ -+ gmx_rx_int_en.s.alnerr = 1; -+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */ -+ gmx_rx_int_en.s.jabber = 1; -+ gmx_rx_int_en.s.maxerr = 1; -+ gmx_rx_int_en.s.carext = 1; -+ gmx_rx_int_en.s.minerr = 1; -+ } -+ if (OCTEON_IS_MODEL(OCTEON_CN58XX)) { -+ /* Skipping gmx_rx_int_en.s.reserved_20_63 */ -+ gmx_rx_int_en.s.pause_drp = 1; -+ /*gmx_rx_int_en.s.phy_dupx = 1; */ -+ /*gmx_rx_int_en.s.phy_spd = 1; */ -+ /*gmx_rx_int_en.s.phy_link = 1; */ -+ /*gmx_rx_int_en.s.ifgerr = 1; */ -+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ -+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ -+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ -+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ -+ gmx_rx_int_en.s.ovrerr = 1; -+ gmx_rx_int_en.s.niberr = 1; -+ gmx_rx_int_en.s.skperr = 1; -+ gmx_rx_int_en.s.rcverr = 1; -+ /*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */ -+ gmx_rx_int_en.s.alnerr = 1; -+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */ -+ gmx_rx_int_en.s.jabber = 1; -+ gmx_rx_int_en.s.maxerr = 1; -+ gmx_rx_int_en.s.carext = 1; -+ gmx_rx_int_en.s.minerr = 1; -+ } -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) { -+ /* Skipping gmx_rx_int_en.s.reserved_29_63 */ -+ gmx_rx_int_en.s.hg2cc = 1; -+ gmx_rx_int_en.s.hg2fld = 1; -+ gmx_rx_int_en.s.undat = 1; -+ gmx_rx_int_en.s.uneop = 1; -+ gmx_rx_int_en.s.unsop = 1; -+ gmx_rx_int_en.s.bad_term = 1; -+ gmx_rx_int_en.s.bad_seq = 0; -+ gmx_rx_int_en.s.rem_fault = 1; -+ gmx_rx_int_en.s.loc_fault = 0; -+ gmx_rx_int_en.s.pause_drp = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_16_18 */ -+ /*gmx_rx_int_en.s.ifgerr = 1; */ -+ /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ -+ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ -+ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ -+ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ -+ gmx_rx_int_en.s.ovrerr = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_9_9 */ -+ gmx_rx_int_en.s.skperr = 1; -+ gmx_rx_int_en.s.rcverr = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_5_6 */ -+ /*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */ -+ gmx_rx_int_en.s.jabber = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_2_2 */ -+ gmx_rx_int_en.s.carext = 1; -+ /* Skipping gmx_rx_int_en.s.reserved_0_0 */ -+ } -+ cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, block), gmx_rx_int_en.u64); -+} -+/** -+ * __cvmx_interrupt_pcsx_intx_en_reg_enable enables all interrupt bits in cvmx_pcsx_intx_en_reg_t -+ */ -+void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block) -+{ -+ union cvmx_pcsx_intx_en_reg pcs_int_en_reg; -+ cvmx_write_csr(CVMX_PCSX_INTX_REG(index, block), -+ cvmx_read_csr(CVMX_PCSX_INTX_REG(index, block))); -+ pcs_int_en_reg.u64 = 0; -+ if (OCTEON_IS_MODEL(OCTEON_CN56XX)) { -+ /* Skipping pcs_int_en_reg.s.reserved_12_63 */ -+ /*pcs_int_en_reg.s.dup = 1; // This happens during normal operation */ -+ pcs_int_en_reg.s.sync_bad_en = 1; -+ pcs_int_en_reg.s.an_bad_en = 1; -+ pcs_int_en_reg.s.rxlock_en = 1; -+ pcs_int_en_reg.s.rxbad_en = 1; -+ /*pcs_int_en_reg.s.rxerr_en = 1; // This happens during normal operation */ -+ pcs_int_en_reg.s.txbad_en = 1; -+ pcs_int_en_reg.s.txfifo_en = 1; -+ pcs_int_en_reg.s.txfifu_en = 1; -+ pcs_int_en_reg.s.an_err_en = 1; -+ /*pcs_int_en_reg.s.xmit_en = 1; // This happens during normal operation */ -+ /*pcs_int_en_reg.s.lnkspd_en = 1; // This happens during normal operation */ -+ } -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) { -+ /* Skipping pcs_int_en_reg.s.reserved_12_63 */ -+ /*pcs_int_en_reg.s.dup = 1; // This happens during normal operation */ -+ pcs_int_en_reg.s.sync_bad_en = 1; -+ pcs_int_en_reg.s.an_bad_en = 1; -+ pcs_int_en_reg.s.rxlock_en = 1; -+ pcs_int_en_reg.s.rxbad_en = 1; -+ /*pcs_int_en_reg.s.rxerr_en = 1; // This happens during normal operation */ -+ pcs_int_en_reg.s.txbad_en = 1; -+ pcs_int_en_reg.s.txfifo_en = 1; -+ pcs_int_en_reg.s.txfifu_en = 1; -+ pcs_int_en_reg.s.an_err_en = 1; -+ /*pcs_int_en_reg.s.xmit_en = 1; // This happens during normal operation */ -+ /*pcs_int_en_reg.s.lnkspd_en = 1; // This happens during normal operation */ -+ } -+ cvmx_write_csr(CVMX_PCSX_INTX_EN_REG(index, block), pcs_int_en_reg.u64); -+} -+/** -+ * __cvmx_interrupt_pcsxx_int_en_reg_enable enables all interrupt bits in cvmx_pcsxx_int_en_reg_t -+ */ -+void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index) -+{ -+ union cvmx_pcsxx_int_en_reg pcsx_int_en_reg; -+ cvmx_write_csr(CVMX_PCSXX_INT_REG(index), -+ cvmx_read_csr(CVMX_PCSXX_INT_REG(index))); -+ pcsx_int_en_reg.u64 = 0; -+ if (OCTEON_IS_MODEL(OCTEON_CN56XX)) { -+ /* Skipping pcsx_int_en_reg.s.reserved_6_63 */ -+ pcsx_int_en_reg.s.algnlos_en = 1; -+ pcsx_int_en_reg.s.synlos_en = 1; -+ pcsx_int_en_reg.s.bitlckls_en = 1; -+ pcsx_int_en_reg.s.rxsynbad_en = 1; -+ pcsx_int_en_reg.s.rxbad_en = 1; -+ pcsx_int_en_reg.s.txflt_en = 1; -+ } -+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) { -+ /* Skipping pcsx_int_en_reg.s.reserved_6_63 */ -+ pcsx_int_en_reg.s.algnlos_en = 1; -+ pcsx_int_en_reg.s.synlos_en = 1; -+ pcsx_int_en_reg.s.bitlckls_en = 0; /* Happens if XAUI module is not installed */ -+ pcsx_int_en_reg.s.rxsynbad_en = 1; -+ pcsx_int_en_reg.s.rxbad_en = 1; -+ pcsx_int_en_reg.s.txflt_en = 1; -+ } -+ cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(index), pcsx_int_en_reg.u64); -+} -+ -+/** -+ * __cvmx_interrupt_spxx_int_msk_enable enables all interrupt bits in cvmx_spxx_int_msk_t -+ */ -+void __cvmx_interrupt_spxx_int_msk_enable(int index) -+{ -+ union cvmx_spxx_int_msk spx_int_msk; -+ cvmx_write_csr(CVMX_SPXX_INT_REG(index), -+ cvmx_read_csr(CVMX_SPXX_INT_REG(index))); -+ spx_int_msk.u64 = 0; -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)) { -+ /* Skipping spx_int_msk.s.reserved_12_63 */ -+ spx_int_msk.s.calerr = 1; -+ spx_int_msk.s.syncerr = 1; -+ spx_int_msk.s.diperr = 1; -+ spx_int_msk.s.tpaovr = 1; -+ spx_int_msk.s.rsverr = 1; -+ spx_int_msk.s.drwnng = 1; -+ spx_int_msk.s.clserr = 1; -+ spx_int_msk.s.spiovr = 1; -+ /* Skipping spx_int_msk.s.reserved_2_3 */ -+ spx_int_msk.s.abnorm = 1; -+ spx_int_msk.s.prtnxa = 1; -+ } -+ if (OCTEON_IS_MODEL(OCTEON_CN58XX)) { -+ /* Skipping spx_int_msk.s.reserved_12_63 */ -+ spx_int_msk.s.calerr = 1; -+ spx_int_msk.s.syncerr = 1; -+ spx_int_msk.s.diperr = 1; -+ spx_int_msk.s.tpaovr = 1; -+ spx_int_msk.s.rsverr = 1; -+ spx_int_msk.s.drwnng = 1; -+ spx_int_msk.s.clserr = 1; -+ spx_int_msk.s.spiovr = 1; -+ /* Skipping spx_int_msk.s.reserved_2_3 */ -+ spx_int_msk.s.abnorm = 1; -+ spx_int_msk.s.prtnxa = 1; -+ } -+ cvmx_write_csr(CVMX_SPXX_INT_MSK(index), spx_int_msk.u64); -+} -+/** -+ * __cvmx_interrupt_stxx_int_msk_enable enables all interrupt bits in cvmx_stxx_int_msk_t -+ */ -+void __cvmx_interrupt_stxx_int_msk_enable(int index) -+{ -+ union cvmx_stxx_int_msk stx_int_msk; -+ cvmx_write_csr(CVMX_STXX_INT_REG(index), -+ cvmx_read_csr(CVMX_STXX_INT_REG(index))); -+ stx_int_msk.u64 = 0; -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)) { -+ /* Skipping stx_int_msk.s.reserved_8_63 */ -+ stx_int_msk.s.frmerr = 1; -+ stx_int_msk.s.unxfrm = 1; -+ stx_int_msk.s.nosync = 1; -+ stx_int_msk.s.diperr = 1; -+ stx_int_msk.s.datovr = 1; -+ stx_int_msk.s.ovrbst = 1; -+ stx_int_msk.s.calpar1 = 1; -+ stx_int_msk.s.calpar0 = 1; -+ } -+ if (OCTEON_IS_MODEL(OCTEON_CN58XX)) { -+ /* Skipping stx_int_msk.s.reserved_8_63 */ -+ stx_int_msk.s.frmerr = 1; -+ stx_int_msk.s.unxfrm = 1; -+ stx_int_msk.s.nosync = 1; -+ stx_int_msk.s.diperr = 1; -+ stx_int_msk.s.datovr = 1; -+ stx_int_msk.s.ovrbst = 1; -+ stx_int_msk.s.calpar1 = 1; -+ stx_int_msk.s.calpar0 = 1; -+ } -+ cvmx_write_csr(CVMX_STXX_INT_MSK(index), stx_int_msk.u64); -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-interrupt-rsl.c -@@ -0,0 +1,140 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * Utility functions to decode Octeon's RSL_INT_BLOCKS -+ * interrupts into error messages. -+ */ -+ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-asxx-defs.h" -+#include "cvmx-gmxx-defs.h" -+ -+#ifndef PRINT_ERROR -+#define PRINT_ERROR(format, ...) -+#endif -+ -+void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block); -+ -+/** -+ * Enable ASX error interrupts that exist on CN3XXX, CN50XX, and -+ * CN58XX. -+ * -+ * @block: Interface to enable 0-1 -+ */ -+void __cvmx_interrupt_asxx_enable(int block) -+{ -+ int mask; -+ union cvmx_asxx_int_en csr; -+ /* -+ * CN38XX and CN58XX have two interfaces with 4 ports per -+ * interface. All other chips have a max of 3 ports on -+ * interface 0 -+ */ -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) -+ mask = 0xf; /* Set enables for 4 ports */ -+ else -+ mask = 0x7; /* Set enables for 3 ports */ -+ -+ /* Enable interface interrupts */ -+ csr.u64 = cvmx_read_csr(CVMX_ASXX_INT_EN(block)); -+ csr.s.txpsh = mask; -+ csr.s.txpop = mask; -+ csr.s.ovrflw = mask; -+ cvmx_write_csr(CVMX_ASXX_INT_EN(block), csr.u64); -+} -+/** -+ * Enable GMX error reporting for the supplied interface -+ * -+ * @interface: Interface to enable -+ */ -+void __cvmx_interrupt_gmxx_enable(int interface) -+{ -+ union cvmx_gmxx_inf_mode mode; -+ union cvmx_gmxx_tx_int_en gmx_tx_int_en; -+ int num_ports; -+ int index; -+ -+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); -+ -+ if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) { -+ if (mode.s.en) { -+ switch (mode.cn56xx.mode) { -+ case 1: /* XAUI */ -+ num_ports = 1; -+ break; -+ case 2: /* SGMII */ -+ case 3: /* PICMG */ -+ num_ports = 4; -+ break; -+ default: /* Disabled */ -+ num_ports = 0; -+ break; -+ } -+ } else -+ num_ports = 0; -+ } else { -+ if (mode.s.en) { -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) -+ || OCTEON_IS_MODEL(OCTEON_CN58XX)) { -+ /* -+ * SPI on CN38XX and CN58XX report all -+ * errors through port 0. RGMII needs -+ * to check all 4 ports -+ */ -+ if (mode.s.type) -+ num_ports = 1; -+ else -+ num_ports = 4; -+ } else { -+ /* -+ * CN30XX, CN31XX, and CN50XX have two -+ * or three ports. GMII and MII has 2, -+ * RGMII has three -+ */ -+ if (mode.s.type) -+ num_ports = 2; -+ else -+ num_ports = 3; -+ } -+ } else -+ num_ports = 0; -+ } -+ -+ gmx_tx_int_en.u64 = 0; -+ if (num_ports) { -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) -+ || OCTEON_IS_MODEL(OCTEON_CN58XX)) -+ gmx_tx_int_en.s.ncb_nxa = 1; -+ gmx_tx_int_en.s.pko_nxa = 1; -+ } -+ gmx_tx_int_en.s.undflw = (1 << num_ports) - 1; -+ cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64); -+ for (index = 0; index < num_ports; index++) -+ __cvmx_interrupt_gmxx_rxx_int_en_enable(index, interface); -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-ipd.h -@@ -0,0 +1,338 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * Interface to the hardware Input Packet Data unit. -+ */ -+ -+#ifndef __CVMX_IPD_H__ -+#define __CVMX_IPD_H__ -+ -+#include <asm/octeon/octeon-feature.h> -+ -+#include <asm/octeon/cvmx-ipd-defs.h> -+ -+enum cvmx_ipd_mode { -+ CVMX_IPD_OPC_MODE_STT = 0LL, /* All blocks DRAM, not cached in L2 */ -+ CVMX_IPD_OPC_MODE_STF = 1LL, /* All bloccks into L2 */ -+ CVMX_IPD_OPC_MODE_STF1_STT = 2LL, /* 1st block L2, rest DRAM */ -+ CVMX_IPD_OPC_MODE_STF2_STT = 3LL /* 1st, 2nd blocks L2, rest DRAM */ -+}; -+ -+#ifndef CVMX_ENABLE_LEN_M8_FIX -+#define CVMX_ENABLE_LEN_M8_FIX 0 -+#endif -+ -+/* CSR typedefs have been moved to cvmx-csr-*.h */ -+typedef union cvmx_ipd_1st_mbuff_skip cvmx_ipd_mbuff_first_skip_t; -+typedef union cvmx_ipd_1st_next_ptr_back cvmx_ipd_first_next_ptr_back_t; -+ -+typedef cvmx_ipd_mbuff_first_skip_t cvmx_ipd_mbuff_not_first_skip_t; -+typedef cvmx_ipd_first_next_ptr_back_t cvmx_ipd_second_next_ptr_back_t; -+ -+/** -+ * Configure IPD -+ * -+ * @mbuff_size: Packets buffer size in 8 byte words -+ * @first_mbuff_skip: -+ * Number of 8 byte words to skip in the first buffer -+ * @not_first_mbuff_skip: -+ * Number of 8 byte words to skip in each following buffer -+ * @first_back: Must be same as first_mbuff_skip / 128 -+ * @second_back: -+ * Must be same as not_first_mbuff_skip / 128 -+ * @wqe_fpa_pool: -+ * FPA pool to get work entries from -+ * @cache_mode: -+ * @back_pres_enable_flag: -+ * Enable or disable port back pressure -+ */ -+static inline void cvmx_ipd_config(uint64_t mbuff_size, -+ uint64_t first_mbuff_skip, -+ uint64_t not_first_mbuff_skip, -+ uint64_t first_back, -+ uint64_t second_back, -+ uint64_t wqe_fpa_pool, -+ enum cvmx_ipd_mode cache_mode, -+ uint64_t back_pres_enable_flag) -+{ -+ cvmx_ipd_mbuff_first_skip_t first_skip; -+ cvmx_ipd_mbuff_not_first_skip_t not_first_skip; -+ union cvmx_ipd_packet_mbuff_size size; -+ cvmx_ipd_first_next_ptr_back_t first_back_struct; -+ cvmx_ipd_second_next_ptr_back_t second_back_struct; -+ union cvmx_ipd_wqe_fpa_queue wqe_pool; -+ union cvmx_ipd_ctl_status ipd_ctl_reg; -+ -+ first_skip.u64 = 0; -+ first_skip.s.skip_sz = first_mbuff_skip; -+ cvmx_write_csr(CVMX_IPD_1ST_MBUFF_SKIP, first_skip.u64); -+ -+ not_first_skip.u64 = 0; -+ not_first_skip.s.skip_sz = not_first_mbuff_skip; -+ cvmx_write_csr(CVMX_IPD_NOT_1ST_MBUFF_SKIP, not_first_skip.u64); -+ -+ size.u64 = 0; -+ size.s.mb_size = mbuff_size; -+ cvmx_write_csr(CVMX_IPD_PACKET_MBUFF_SIZE, size.u64); -+ -+ first_back_struct.u64 = 0; -+ first_back_struct.s.back = first_back; -+ cvmx_write_csr(CVMX_IPD_1st_NEXT_PTR_BACK, first_back_struct.u64); -+ -+ second_back_struct.u64 = 0; -+ second_back_struct.s.back = second_back; -+ cvmx_write_csr(CVMX_IPD_2nd_NEXT_PTR_BACK, second_back_struct.u64); -+ -+ wqe_pool.u64 = 0; -+ wqe_pool.s.wqe_pool = wqe_fpa_pool; -+ cvmx_write_csr(CVMX_IPD_WQE_FPA_QUEUE, wqe_pool.u64); -+ -+ ipd_ctl_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS); -+ ipd_ctl_reg.s.opc_mode = cache_mode; -+ ipd_ctl_reg.s.pbp_en = back_pres_enable_flag; -+ cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_reg.u64); -+ -+ /* Note: the example RED code that used to be here has been moved to -+ cvmx_helper_setup_red */ -+} -+ -+/** -+ * Enable IPD -+ */ -+static inline void cvmx_ipd_enable(void) -+{ -+ union cvmx_ipd_ctl_status ipd_reg; -+ ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS); -+ if (ipd_reg.s.ipd_en) { -+ cvmx_dprintf -+ ("Warning: Enabling IPD when IPD already enabled.\n"); -+ } -+ ipd_reg.s.ipd_en = 1; -+#if CVMX_ENABLE_LEN_M8_FIX -+ if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) -+ ipd_reg.s.len_m8 = TRUE; -+#endif -+ cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64); -+} -+ -+/** -+ * Disable IPD -+ */ -+static inline void cvmx_ipd_disable(void) -+{ -+ union cvmx_ipd_ctl_status ipd_reg; -+ ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS); -+ ipd_reg.s.ipd_en = 0; -+ cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64); -+} -+ -+/** -+ * Supportive function for cvmx_fpa_shutdown_pool. -+ */ -+static inline void cvmx_ipd_free_ptr(void) -+{ -+ /* Only CN38XXp{1,2} cannot read pointer out of the IPD */ -+ if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1) -+ && !OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) { -+ int no_wptr = 0; -+ union cvmx_ipd_ptr_count ipd_ptr_count; -+ ipd_ptr_count.u64 = cvmx_read_csr(CVMX_IPD_PTR_COUNT); -+ -+ /* Handle Work Queue Entry in cn56xx and cn52xx */ -+ if (octeon_has_feature(OCTEON_FEATURE_NO_WPTR)) { -+ union cvmx_ipd_ctl_status ipd_ctl_status; -+ ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS); -+ if (ipd_ctl_status.s.no_wptr) -+ no_wptr = 1; -+ } -+ -+ /* Free the prefetched WQE */ -+ if (ipd_ptr_count.s.wqev_cnt) { -+ union cvmx_ipd_wqe_ptr_valid ipd_wqe_ptr_valid; -+ ipd_wqe_ptr_valid.u64 = -+ cvmx_read_csr(CVMX_IPD_WQE_PTR_VALID); -+ if (no_wptr) -+ cvmx_fpa_free(cvmx_phys_to_ptr -+ ((uint64_t) ipd_wqe_ptr_valid.s. -+ ptr << 7), CVMX_FPA_PACKET_POOL, -+ 0); -+ else -+ cvmx_fpa_free(cvmx_phys_to_ptr -+ ((uint64_t) ipd_wqe_ptr_valid.s. -+ ptr << 7), CVMX_FPA_WQE_POOL, 0); -+ } -+ -+ /* Free all WQE in the fifo */ -+ if (ipd_ptr_count.s.wqe_pcnt) { -+ int i; -+ union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl; -+ ipd_pwp_ptr_fifo_ctl.u64 = -+ cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL); -+ for (i = 0; i < ipd_ptr_count.s.wqe_pcnt; i++) { -+ ipd_pwp_ptr_fifo_ctl.s.cena = 0; -+ ipd_pwp_ptr_fifo_ctl.s.raddr = -+ ipd_pwp_ptr_fifo_ctl.s.max_cnts + -+ (ipd_pwp_ptr_fifo_ctl.s.wraddr + -+ i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts; -+ cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, -+ ipd_pwp_ptr_fifo_ctl.u64); -+ ipd_pwp_ptr_fifo_ctl.u64 = -+ cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL); -+ if (no_wptr) -+ cvmx_fpa_free(cvmx_phys_to_ptr -+ ((uint64_t) -+ ipd_pwp_ptr_fifo_ctl.s. -+ ptr << 7), -+ CVMX_FPA_PACKET_POOL, 0); -+ else -+ cvmx_fpa_free(cvmx_phys_to_ptr -+ ((uint64_t) -+ ipd_pwp_ptr_fifo_ctl.s. -+ ptr << 7), -+ CVMX_FPA_WQE_POOL, 0); -+ } -+ ipd_pwp_ptr_fifo_ctl.s.cena = 1; -+ cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, -+ ipd_pwp_ptr_fifo_ctl.u64); -+ } -+ -+ /* Free the prefetched packet */ -+ if (ipd_ptr_count.s.pktv_cnt) { -+ union cvmx_ipd_pkt_ptr_valid ipd_pkt_ptr_valid; -+ ipd_pkt_ptr_valid.u64 = -+ cvmx_read_csr(CVMX_IPD_PKT_PTR_VALID); -+ cvmx_fpa_free(cvmx_phys_to_ptr -+ (ipd_pkt_ptr_valid.s.ptr << 7), -+ CVMX_FPA_PACKET_POOL, 0); -+ } -+ -+ /* Free the per port prefetched packets */ -+ if (1) { -+ int i; -+ union cvmx_ipd_prc_port_ptr_fifo_ctl -+ ipd_prc_port_ptr_fifo_ctl; -+ ipd_prc_port_ptr_fifo_ctl.u64 = -+ cvmx_read_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL); -+ -+ for (i = 0; i < ipd_prc_port_ptr_fifo_ctl.s.max_pkt; -+ i++) { -+ ipd_prc_port_ptr_fifo_ctl.s.cena = 0; -+ ipd_prc_port_ptr_fifo_ctl.s.raddr = -+ i % ipd_prc_port_ptr_fifo_ctl.s.max_pkt; -+ cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL, -+ ipd_prc_port_ptr_fifo_ctl.u64); -+ ipd_prc_port_ptr_fifo_ctl.u64 = -+ cvmx_read_csr -+ (CVMX_IPD_PRC_PORT_PTR_FIFO_CTL); -+ cvmx_fpa_free(cvmx_phys_to_ptr -+ ((uint64_t) -+ ipd_prc_port_ptr_fifo_ctl.s. -+ ptr << 7), CVMX_FPA_PACKET_POOL, -+ 0); -+ } -+ ipd_prc_port_ptr_fifo_ctl.s.cena = 1; -+ cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL, -+ ipd_prc_port_ptr_fifo_ctl.u64); -+ } -+ -+ /* Free all packets in the holding fifo */ -+ if (ipd_ptr_count.s.pfif_cnt) { -+ int i; -+ union cvmx_ipd_prc_hold_ptr_fifo_ctl -+ ipd_prc_hold_ptr_fifo_ctl; -+ -+ ipd_prc_hold_ptr_fifo_ctl.u64 = -+ cvmx_read_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL); -+ -+ for (i = 0; i < ipd_ptr_count.s.pfif_cnt; i++) { -+ ipd_prc_hold_ptr_fifo_ctl.s.cena = 0; -+ ipd_prc_hold_ptr_fifo_ctl.s.raddr = -+ (ipd_prc_hold_ptr_fifo_ctl.s.praddr + -+ i) % ipd_prc_hold_ptr_fifo_ctl.s.max_pkt; -+ cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL, -+ ipd_prc_hold_ptr_fifo_ctl.u64); -+ ipd_prc_hold_ptr_fifo_ctl.u64 = -+ cvmx_read_csr -+ (CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL); -+ cvmx_fpa_free(cvmx_phys_to_ptr -+ ((uint64_t) -+ ipd_prc_hold_ptr_fifo_ctl.s. -+ ptr << 7), CVMX_FPA_PACKET_POOL, -+ 0); -+ } -+ ipd_prc_hold_ptr_fifo_ctl.s.cena = 1; -+ cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL, -+ ipd_prc_hold_ptr_fifo_ctl.u64); -+ } -+ -+ /* Free all packets in the fifo */ -+ if (ipd_ptr_count.s.pkt_pcnt) { -+ int i; -+ union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl; -+ ipd_pwp_ptr_fifo_ctl.u64 = -+ cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL); -+ -+ for (i = 0; i < ipd_ptr_count.s.pkt_pcnt; i++) { -+ ipd_pwp_ptr_fifo_ctl.s.cena = 0; -+ ipd_pwp_ptr_fifo_ctl.s.raddr = -+ (ipd_pwp_ptr_fifo_ctl.s.praddr + -+ i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts; -+ cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, -+ ipd_pwp_ptr_fifo_ctl.u64); -+ ipd_pwp_ptr_fifo_ctl.u64 = -+ cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL); -+ cvmx_fpa_free(cvmx_phys_to_ptr -+ ((uint64_t) ipd_pwp_ptr_fifo_ctl. -+ s.ptr << 7), -+ CVMX_FPA_PACKET_POOL, 0); -+ } -+ ipd_pwp_ptr_fifo_ctl.s.cena = 1; -+ cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, -+ ipd_pwp_ptr_fifo_ctl.u64); -+ } -+ -+ /* Reset the IPD to get all buffers out of it */ -+ { -+ union cvmx_ipd_ctl_status ipd_ctl_status; -+ ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS); -+ ipd_ctl_status.s.reset = 1; -+ cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_status.u64); -+ } -+ -+ /* Reset the PIP */ -+ { -+ union cvmx_pip_sft_rst pip_sft_rst; -+ pip_sft_rst.u64 = cvmx_read_csr(CVMX_PIP_SFT_RST); -+ pip_sft_rst.s.rst = 1; -+ cvmx_write_csr(CVMX_PIP_SFT_RST, pip_sft_rst.u64); -+ } -+ } -+} -+ -+#endif /* __CVMX_IPD_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-mdio.h -@@ -0,0 +1,506 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * -+ * Interface to the SMI/MDIO hardware, including support for both IEEE 802.3 -+ * clause 22 and clause 45 operations. -+ * -+ */ -+ -+#ifndef __CVMX_MIO_H__ -+#define __CVMX_MIO_H__ -+ -+#include "cvmx-smix-defs.h" -+ -+/** -+ * PHY register 0 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_CONTROL 0 -+typedef union { -+ uint16_t u16; -+ struct { -+ uint16_t reset:1; -+ uint16_t loopback:1; -+ uint16_t speed_lsb:1; -+ uint16_t autoneg_enable:1; -+ uint16_t power_down:1; -+ uint16_t isolate:1; -+ uint16_t restart_autoneg:1; -+ uint16_t duplex:1; -+ uint16_t collision_test:1; -+ uint16_t speed_msb:1; -+ uint16_t unidirectional_enable:1; -+ uint16_t reserved_0_4:5; -+ } s; -+} cvmx_mdio_phy_reg_control_t; -+ -+/** -+ * PHY register 1 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_STATUS 1 -+typedef union { -+ uint16_t u16; -+ struct { -+ uint16_t capable_100base_t4:1; -+ uint16_t capable_100base_x_full:1; -+ uint16_t capable_100base_x_half:1; -+ uint16_t capable_10_full:1; -+ uint16_t capable_10_half:1; -+ uint16_t capable_100base_t2_full:1; -+ uint16_t capable_100base_t2_half:1; -+ uint16_t capable_extended_status:1; -+ uint16_t capable_unidirectional:1; -+ uint16_t capable_mf_preamble_suppression:1; -+ uint16_t autoneg_complete:1; -+ uint16_t remote_fault:1; -+ uint16_t capable_autoneg:1; -+ uint16_t link_status:1; -+ uint16_t jabber_detect:1; -+ uint16_t capable_extended_registers:1; -+ -+ } s; -+} cvmx_mdio_phy_reg_status_t; -+ -+/** -+ * PHY register 2 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_ID1 2 -+typedef union { -+ uint16_t u16; -+ struct { -+ uint16_t oui_bits_3_18; -+ } s; -+} cvmx_mdio_phy_reg_id1_t; -+ -+/** -+ * PHY register 3 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_ID2 3 -+typedef union { -+ uint16_t u16; -+ struct { -+ uint16_t oui_bits_19_24:6; -+ uint16_t model:6; -+ uint16_t revision:4; -+ } s; -+} cvmx_mdio_phy_reg_id2_t; -+ -+/** -+ * PHY register 4 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_AUTONEG_ADVER 4 -+typedef union { -+ uint16_t u16; -+ struct { -+ uint16_t next_page:1; -+ uint16_t reserved_14:1; -+ uint16_t remote_fault:1; -+ uint16_t reserved_12:1; -+ uint16_t asymmetric_pause:1; -+ uint16_t pause:1; -+ uint16_t advert_100base_t4:1; -+ uint16_t advert_100base_tx_full:1; -+ uint16_t advert_100base_tx_half:1; -+ uint16_t advert_10base_tx_full:1; -+ uint16_t advert_10base_tx_half:1; -+ uint16_t selector:5; -+ } s; -+} cvmx_mdio_phy_reg_autoneg_adver_t; -+ -+/** -+ * PHY register 5 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_LINK_PARTNER_ABILITY 5 -+typedef union { -+ uint16_t u16; -+ struct { -+ uint16_t next_page:1; -+ uint16_t ack:1; -+ uint16_t remote_fault:1; -+ uint16_t reserved_12:1; -+ uint16_t asymmetric_pause:1; -+ uint16_t pause:1; -+ uint16_t advert_100base_t4:1; -+ uint16_t advert_100base_tx_full:1; -+ uint16_t advert_100base_tx_half:1; -+ uint16_t advert_10base_tx_full:1; -+ uint16_t advert_10base_tx_half:1; -+ uint16_t selector:5; -+ } s; -+} cvmx_mdio_phy_reg_link_partner_ability_t; -+ -+/** -+ * PHY register 6 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_AUTONEG_EXPANSION 6 -+typedef union { -+ uint16_t u16; -+ struct { -+ uint16_t reserved_5_15:11; -+ uint16_t parallel_detection_fault:1; -+ uint16_t link_partner_next_page_capable:1; -+ uint16_t local_next_page_capable:1; -+ uint16_t page_received:1; -+ uint16_t link_partner_autoneg_capable:1; -+ -+ } s; -+} cvmx_mdio_phy_reg_autoneg_expansion_t; -+ -+/** -+ * PHY register 9 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_CONTROL_1000 9 -+typedef union { -+ uint16_t u16; -+ struct { -+ uint16_t test_mode:3; -+ uint16_t manual_master_slave:1; -+ uint16_t master:1; -+ uint16_t port_type:1; -+ uint16_t advert_1000base_t_full:1; -+ uint16_t advert_1000base_t_half:1; -+ uint16_t reserved_0_7:8; -+ } s; -+} cvmx_mdio_phy_reg_control_1000_t; -+ -+/** -+ * PHY register 10 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_STATUS_1000 10 -+typedef union { -+ uint16_t u16; -+ struct { -+ uint16_t master_slave_fault:1; -+ uint16_t is_master:1; -+ uint16_t local_receiver_ok:1; -+ uint16_t remote_receiver_ok:1; -+ uint16_t remote_capable_1000base_t_full:1; -+ uint16_t remote_capable_1000base_t_half:1; -+ uint16_t reserved_8_9:2; -+ uint16_t idle_error_count:8; -+ } s; -+} cvmx_mdio_phy_reg_status_1000_t; -+ -+/** -+ * PHY register 15 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_EXTENDED_STATUS 15 -+typedef union { -+ uint16_t u16; -+ struct { -+ uint16_t capable_1000base_x_full:1; -+ uint16_t capable_1000base_x_half:1; -+ uint16_t capable_1000base_t_full:1; -+ uint16_t capable_1000base_t_half:1; -+ uint16_t reserved_0_11:12; -+ } s; -+} cvmx_mdio_phy_reg_extended_status_t; -+ -+/** -+ * PHY register 13 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_MMD_CONTROL 13 -+typedef union { -+ uint16_t u16; -+ struct { -+ uint16_t function:2; -+ uint16_t reserved_5_13:9; -+ uint16_t devad:5; -+ } s; -+} cvmx_mdio_phy_reg_mmd_control_t; -+ -+/** -+ * PHY register 14 from the 802.3 spec -+ */ -+#define CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA 14 -+typedef union { -+ uint16_t u16; -+ struct { -+ uint16_t address_data:16; -+ } s; -+} cvmx_mdio_phy_reg_mmd_address_data_t; -+ -+/* Operating request encodings. */ -+#define MDIO_CLAUSE_22_WRITE 0 -+#define MDIO_CLAUSE_22_READ 1 -+ -+#define MDIO_CLAUSE_45_ADDRESS 0 -+#define MDIO_CLAUSE_45_WRITE 1 -+#define MDIO_CLAUSE_45_READ_INC 2 -+#define MDIO_CLAUSE_45_READ 3 -+ -+/* MMD identifiers, mostly for accessing devices withing XENPAK modules. */ -+#define CVMX_MMD_DEVICE_PMA_PMD 1 -+#define CVMX_MMD_DEVICE_WIS 2 -+#define CVMX_MMD_DEVICE_PCS 3 -+#define CVMX_MMD_DEVICE_PHY_XS 4 -+#define CVMX_MMD_DEVICE_DTS_XS 5 -+#define CVMX_MMD_DEVICE_TC 6 -+#define CVMX_MMD_DEVICE_CL22_EXT 29 -+#define CVMX_MMD_DEVICE_VENDOR_1 30 -+#define CVMX_MMD_DEVICE_VENDOR_2 31 -+ -+/* Helper function to put MDIO interface into clause 45 mode */ -+static inline void __cvmx_mdio_set_clause45_mode(int bus_id) -+{ -+ union cvmx_smix_clk smi_clk; -+ /* Put bus into clause 45 mode */ -+ smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id)); -+ smi_clk.s.mode = 1; -+ smi_clk.s.preamble = 1; -+ cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64); -+} -+ -+/* Helper function to put MDIO interface into clause 22 mode */ -+static inline void __cvmx_mdio_set_clause22_mode(int bus_id) -+{ -+ union cvmx_smix_clk smi_clk; -+ /* Put bus into clause 22 mode */ -+ smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id)); -+ smi_clk.s.mode = 0; -+ cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64); -+} -+ -+/** -+ * Perform an MII read. This function is used to read PHY -+ * registers controlling auto negotiation. -+ * -+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) -+ * support multiple busses. -+ * @phy_id: The MII phy id -+ * @location: Register location to read -+ * -+ * Returns Result from the read or -1 on failure -+ */ -+static inline int cvmx_mdio_read(int bus_id, int phy_id, int location) -+{ -+ union cvmx_smix_cmd smi_cmd; -+ union cvmx_smix_rd_dat smi_rd; -+ int timeout = 1000; -+ -+ if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45)) -+ __cvmx_mdio_set_clause22_mode(bus_id); -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = MDIO_CLAUSE_22_READ; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = location; -+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); -+ -+ do { -+ cvmx_wait(1000); -+ smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id)); -+ } while (smi_rd.s.pending && timeout--); -+ -+ if (smi_rd.s.val) -+ return smi_rd.s.dat; -+ else -+ return -1; -+} -+ -+/** -+ * Perform an MII write. This function is used to write PHY -+ * registers controlling auto negotiation. -+ * -+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) -+ * support multiple busses. -+ * @phy_id: The MII phy id -+ * @location: Register location to write -+ * @val: Value to write -+ * -+ * Returns -1 on error -+ * 0 on success -+ */ -+static inline int cvmx_mdio_write(int bus_id, int phy_id, int location, int val) -+{ -+ union cvmx_smix_cmd smi_cmd; -+ union cvmx_smix_wr_dat smi_wr; -+ int timeout = 1000; -+ -+ if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45)) -+ __cvmx_mdio_set_clause22_mode(bus_id); -+ -+ smi_wr.u64 = 0; -+ smi_wr.s.dat = val; -+ cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = MDIO_CLAUSE_22_WRITE; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = location; -+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); -+ -+ do { -+ cvmx_wait(1000); -+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); -+ } while (smi_wr.s.pending && --timeout); -+ if (timeout <= 0) -+ return -1; -+ -+ return 0; -+} -+ -+/** -+ * Perform an IEEE 802.3 clause 45 MII read. This function is used to -+ * read PHY registers controlling auto negotiation. -+ * -+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) -+ * support multiple busses. -+ * @phy_id: The MII phy id -+ * @device: MDIO Managable Device (MMD) id -+ * @location: Register location to read -+ * -+ * Returns Result from the read or -1 on failure -+ */ -+ -+static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device, -+ int location) -+{ -+ union cvmx_smix_cmd smi_cmd; -+ union cvmx_smix_rd_dat smi_rd; -+ union cvmx_smix_wr_dat smi_wr; -+ int timeout = 1000; -+ -+ if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45)) -+ return -1; -+ -+ __cvmx_mdio_set_clause45_mode(bus_id); -+ -+ smi_wr.u64 = 0; -+ smi_wr.s.dat = location; -+ cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = device; -+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); -+ -+ do { -+ cvmx_wait(1000); -+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); -+ } while (smi_wr.s.pending && --timeout); -+ if (timeout <= 0) { -+ cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d " -+ "device %2d register %2d TIME OUT(address)\n", -+ bus_id, phy_id, device, location); -+ return -1; -+ } -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = MDIO_CLAUSE_45_READ; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = device; -+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); -+ -+ do { -+ cvmx_wait(1000); -+ smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id)); -+ } while (smi_rd.s.pending && timeout--); -+ -+ if (timeout <= 0) { -+ cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d " -+ "device %2d register %2d TIME OUT(data)\n", -+ bus_id, phy_id, device, location); -+ return -1; -+ } -+ -+ if (smi_rd.s.val) -+ return smi_rd.s.dat; -+ else { -+ cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d " -+ "device %2d register %2d INVALID READ\n", -+ bus_id, phy_id, device, location); -+ return -1; -+ } -+} -+ -+/** -+ * Perform an IEEE 802.3 clause 45 MII write. This function is used to -+ * write PHY registers controlling auto negotiation. -+ * -+ * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) -+ * support multiple busses. -+ * @phy_id: The MII phy id -+ * @device: MDIO Managable Device (MMD) id -+ * @location: Register location to write -+ * @val: Value to write -+ * -+ * Returns -1 on error -+ * 0 on success -+ */ -+static inline int cvmx_mdio_45_write(int bus_id, int phy_id, int device, -+ int location, int val) -+{ -+ union cvmx_smix_cmd smi_cmd; -+ union cvmx_smix_wr_dat smi_wr; -+ int timeout = 1000; -+ -+ if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45)) -+ return -1; -+ -+ __cvmx_mdio_set_clause45_mode(bus_id); -+ -+ smi_wr.u64 = 0; -+ smi_wr.s.dat = location; -+ cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = device; -+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); -+ -+ do { -+ cvmx_wait(1000); -+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); -+ } while (smi_wr.s.pending && --timeout); -+ if (timeout <= 0) -+ return -1; -+ -+ smi_wr.u64 = 0; -+ smi_wr.s.dat = val; -+ cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = MDIO_CLAUSE_45_WRITE; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = device; -+ cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); -+ -+ do { -+ cvmx_wait(1000); -+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); -+ } while (smi_wr.s.pending && --timeout); -+ if (timeout <= 0) -+ return -1; -+ -+ return 0; -+} -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-packet.h -@@ -0,0 +1,65 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * Packet buffer defines. -+ */ -+ -+#ifndef __CVMX_PACKET_H__ -+#define __CVMX_PACKET_H__ -+ -+/** -+ * This structure defines a buffer pointer on Octeon -+ */ -+union cvmx_buf_ptr { -+ void *ptr; -+ uint64_t u64; -+ struct { -+ /* -+ * if set, invert the "free" pick of the overall -+ * packet. HW always sets this bit to 0 on inbound -+ * packet -+ */ -+ uint64_t i:1; -+ /* -+ * Indicates the amount to back up to get to the -+ * buffer start in cache lines. In most cases this is -+ * less than one complete cache line, so the value is -+ * zero. -+ */ -+ uint64_t back:4; -+ /* The pool that the buffer came from / goes to */ -+ uint64_t pool:3; -+ /* The size of the segment pointed to by addr (in bytes) */ -+ uint64_t size:16; -+ /* Pointer to the first byte of the data, NOT buffer */ -+ uint64_t addr:40; -+ } s; -+}; -+ -+#endif /* __CVMX_PACKET_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-pcsx-defs.h -@@ -0,0 +1,370 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_PCSX_DEFS_H__ -+#define __CVMX_PCSX_DEFS_H__ -+ -+#define CVMX_PCSX_ANX_ADV_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001010ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_ANX_EXT_ST_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001028ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_ANX_LP_ABIL_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001018ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_ANX_RESULTS_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001020ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_INTX_EN_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001088ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_INTX_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001080ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_LINKX_TIMER_COUNT_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001040ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_LOG_ANLX_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001090ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_MISCX_CTL_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001078ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_MRX_CONTROL_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001000ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_MRX_STATUS_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001008ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_RXX_STATES_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001058ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_RXX_SYNC_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001050ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_SGMX_AN_ADV_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001068ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_SGMX_LP_ADV_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001070ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_TXX_STATES_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001060ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSX_TX_RXX_POLARITY_REG(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0001048ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull)) -+ -+union cvmx_pcsx_anx_adv_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_anx_adv_reg_s { -+ uint64_t reserved_16_63:48; -+ uint64_t np:1; -+ uint64_t reserved_14_14:1; -+ uint64_t rem_flt:2; -+ uint64_t reserved_9_11:3; -+ uint64_t pause:2; -+ uint64_t hfd:1; -+ uint64_t fd:1; -+ uint64_t reserved_0_4:5; -+ } s; -+ struct cvmx_pcsx_anx_adv_reg_s cn52xx; -+ struct cvmx_pcsx_anx_adv_reg_s cn52xxp1; -+ struct cvmx_pcsx_anx_adv_reg_s cn56xx; -+ struct cvmx_pcsx_anx_adv_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_anx_ext_st_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_anx_ext_st_reg_s { -+ uint64_t reserved_16_63:48; -+ uint64_t thou_xfd:1; -+ uint64_t thou_xhd:1; -+ uint64_t thou_tfd:1; -+ uint64_t thou_thd:1; -+ uint64_t reserved_0_11:12; -+ } s; -+ struct cvmx_pcsx_anx_ext_st_reg_s cn52xx; -+ struct cvmx_pcsx_anx_ext_st_reg_s cn52xxp1; -+ struct cvmx_pcsx_anx_ext_st_reg_s cn56xx; -+ struct cvmx_pcsx_anx_ext_st_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_anx_lp_abil_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_anx_lp_abil_reg_s { -+ uint64_t reserved_16_63:48; -+ uint64_t np:1; -+ uint64_t ack:1; -+ uint64_t rem_flt:2; -+ uint64_t reserved_9_11:3; -+ uint64_t pause:2; -+ uint64_t hfd:1; -+ uint64_t fd:1; -+ uint64_t reserved_0_4:5; -+ } s; -+ struct cvmx_pcsx_anx_lp_abil_reg_s cn52xx; -+ struct cvmx_pcsx_anx_lp_abil_reg_s cn52xxp1; -+ struct cvmx_pcsx_anx_lp_abil_reg_s cn56xx; -+ struct cvmx_pcsx_anx_lp_abil_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_anx_results_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_anx_results_reg_s { -+ uint64_t reserved_7_63:57; -+ uint64_t pause:2; -+ uint64_t spd:2; -+ uint64_t an_cpt:1; -+ uint64_t dup:1; -+ uint64_t link_ok:1; -+ } s; -+ struct cvmx_pcsx_anx_results_reg_s cn52xx; -+ struct cvmx_pcsx_anx_results_reg_s cn52xxp1; -+ struct cvmx_pcsx_anx_results_reg_s cn56xx; -+ struct cvmx_pcsx_anx_results_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_intx_en_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_intx_en_reg_s { -+ uint64_t reserved_12_63:52; -+ uint64_t dup:1; -+ uint64_t sync_bad_en:1; -+ uint64_t an_bad_en:1; -+ uint64_t rxlock_en:1; -+ uint64_t rxbad_en:1; -+ uint64_t rxerr_en:1; -+ uint64_t txbad_en:1; -+ uint64_t txfifo_en:1; -+ uint64_t txfifu_en:1; -+ uint64_t an_err_en:1; -+ uint64_t xmit_en:1; -+ uint64_t lnkspd_en:1; -+ } s; -+ struct cvmx_pcsx_intx_en_reg_s cn52xx; -+ struct cvmx_pcsx_intx_en_reg_s cn52xxp1; -+ struct cvmx_pcsx_intx_en_reg_s cn56xx; -+ struct cvmx_pcsx_intx_en_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_intx_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_intx_reg_s { -+ uint64_t reserved_12_63:52; -+ uint64_t dup:1; -+ uint64_t sync_bad:1; -+ uint64_t an_bad:1; -+ uint64_t rxlock:1; -+ uint64_t rxbad:1; -+ uint64_t rxerr:1; -+ uint64_t txbad:1; -+ uint64_t txfifo:1; -+ uint64_t txfifu:1; -+ uint64_t an_err:1; -+ uint64_t xmit:1; -+ uint64_t lnkspd:1; -+ } s; -+ struct cvmx_pcsx_intx_reg_s cn52xx; -+ struct cvmx_pcsx_intx_reg_s cn52xxp1; -+ struct cvmx_pcsx_intx_reg_s cn56xx; -+ struct cvmx_pcsx_intx_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_linkx_timer_count_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_linkx_timer_count_reg_s { -+ uint64_t reserved_16_63:48; -+ uint64_t count:16; -+ } s; -+ struct cvmx_pcsx_linkx_timer_count_reg_s cn52xx; -+ struct cvmx_pcsx_linkx_timer_count_reg_s cn52xxp1; -+ struct cvmx_pcsx_linkx_timer_count_reg_s cn56xx; -+ struct cvmx_pcsx_linkx_timer_count_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_log_anlx_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_log_anlx_reg_s { -+ uint64_t reserved_4_63:60; -+ uint64_t lafifovfl:1; -+ uint64_t la_en:1; -+ uint64_t pkt_sz:2; -+ } s; -+ struct cvmx_pcsx_log_anlx_reg_s cn52xx; -+ struct cvmx_pcsx_log_anlx_reg_s cn52xxp1; -+ struct cvmx_pcsx_log_anlx_reg_s cn56xx; -+ struct cvmx_pcsx_log_anlx_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_miscx_ctl_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_miscx_ctl_reg_s { -+ uint64_t reserved_13_63:51; -+ uint64_t sgmii:1; -+ uint64_t gmxeno:1; -+ uint64_t loopbck2:1; -+ uint64_t mac_phy:1; -+ uint64_t mode:1; -+ uint64_t an_ovrd:1; -+ uint64_t samp_pt:7; -+ } s; -+ struct cvmx_pcsx_miscx_ctl_reg_s cn52xx; -+ struct cvmx_pcsx_miscx_ctl_reg_s cn52xxp1; -+ struct cvmx_pcsx_miscx_ctl_reg_s cn56xx; -+ struct cvmx_pcsx_miscx_ctl_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_mrx_control_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_mrx_control_reg_s { -+ uint64_t reserved_16_63:48; -+ uint64_t reset:1; -+ uint64_t loopbck1:1; -+ uint64_t spdlsb:1; -+ uint64_t an_en:1; -+ uint64_t pwr_dn:1; -+ uint64_t reserved_10_10:1; -+ uint64_t rst_an:1; -+ uint64_t dup:1; -+ uint64_t coltst:1; -+ uint64_t spdmsb:1; -+ uint64_t uni:1; -+ uint64_t reserved_0_4:5; -+ } s; -+ struct cvmx_pcsx_mrx_control_reg_s cn52xx; -+ struct cvmx_pcsx_mrx_control_reg_s cn52xxp1; -+ struct cvmx_pcsx_mrx_control_reg_s cn56xx; -+ struct cvmx_pcsx_mrx_control_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_mrx_status_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_mrx_status_reg_s { -+ uint64_t reserved_16_63:48; -+ uint64_t hun_t4:1; -+ uint64_t hun_xfd:1; -+ uint64_t hun_xhd:1; -+ uint64_t ten_fd:1; -+ uint64_t ten_hd:1; -+ uint64_t hun_t2fd:1; -+ uint64_t hun_t2hd:1; -+ uint64_t ext_st:1; -+ uint64_t reserved_7_7:1; -+ uint64_t prb_sup:1; -+ uint64_t an_cpt:1; -+ uint64_t rm_flt:1; -+ uint64_t an_abil:1; -+ uint64_t lnk_st:1; -+ uint64_t reserved_1_1:1; -+ uint64_t extnd:1; -+ } s; -+ struct cvmx_pcsx_mrx_status_reg_s cn52xx; -+ struct cvmx_pcsx_mrx_status_reg_s cn52xxp1; -+ struct cvmx_pcsx_mrx_status_reg_s cn56xx; -+ struct cvmx_pcsx_mrx_status_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_rxx_states_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_rxx_states_reg_s { -+ uint64_t reserved_16_63:48; -+ uint64_t rx_bad:1; -+ uint64_t rx_st:5; -+ uint64_t sync_bad:1; -+ uint64_t sync:4; -+ uint64_t an_bad:1; -+ uint64_t an_st:4; -+ } s; -+ struct cvmx_pcsx_rxx_states_reg_s cn52xx; -+ struct cvmx_pcsx_rxx_states_reg_s cn52xxp1; -+ struct cvmx_pcsx_rxx_states_reg_s cn56xx; -+ struct cvmx_pcsx_rxx_states_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_rxx_sync_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_rxx_sync_reg_s { -+ uint64_t reserved_2_63:62; -+ uint64_t sync:1; -+ uint64_t bit_lock:1; -+ } s; -+ struct cvmx_pcsx_rxx_sync_reg_s cn52xx; -+ struct cvmx_pcsx_rxx_sync_reg_s cn52xxp1; -+ struct cvmx_pcsx_rxx_sync_reg_s cn56xx; -+ struct cvmx_pcsx_rxx_sync_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_sgmx_an_adv_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_sgmx_an_adv_reg_s { -+ uint64_t reserved_16_63:48; -+ uint64_t link:1; -+ uint64_t ack:1; -+ uint64_t reserved_13_13:1; -+ uint64_t dup:1; -+ uint64_t speed:2; -+ uint64_t reserved_1_9:9; -+ uint64_t one:1; -+ } s; -+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xx; -+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xxp1; -+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xx; -+ struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_sgmx_lp_adv_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_sgmx_lp_adv_reg_s { -+ uint64_t reserved_16_63:48; -+ uint64_t link:1; -+ uint64_t reserved_13_14:2; -+ uint64_t dup:1; -+ uint64_t speed:2; -+ uint64_t reserved_1_9:9; -+ uint64_t one:1; -+ } s; -+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xx; -+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xxp1; -+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xx; -+ struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_txx_states_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_txx_states_reg_s { -+ uint64_t reserved_7_63:57; -+ uint64_t xmit:2; -+ uint64_t tx_bad:1; -+ uint64_t ord_st:4; -+ } s; -+ struct cvmx_pcsx_txx_states_reg_s cn52xx; -+ struct cvmx_pcsx_txx_states_reg_s cn52xxp1; -+ struct cvmx_pcsx_txx_states_reg_s cn56xx; -+ struct cvmx_pcsx_txx_states_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsx_tx_rxx_polarity_reg { -+ uint64_t u64; -+ struct cvmx_pcsx_tx_rxx_polarity_reg_s { -+ uint64_t reserved_4_63:60; -+ uint64_t rxovrd:1; -+ uint64_t autorxpl:1; -+ uint64_t rxplrt:1; -+ uint64_t txplrt:1; -+ } s; -+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xx; -+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xxp1; -+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xx; -+ struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-pcsxx-defs.h -@@ -0,0 +1,316 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_PCSXX_DEFS_H__ -+#define __CVMX_PCSXX_DEFS_H__ -+ -+#define CVMX_PCSXX_10GBX_STATUS_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000828ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_BIST_STATUS_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000870ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_BIT_LOCK_STATUS_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000850ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_CONTROL1_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000800ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_CONTROL2_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000818ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_INT_EN_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000860ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_INT_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000858ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_LOG_ANL_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000868ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_MISC_CTL_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000848ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_RX_SYNC_STATES_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000838ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_SPD_ABIL_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000810ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_STATUS1_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000808ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_STATUS2_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000820ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_TX_RX_POLARITY_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000840ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_PCSXX_TX_RX_STATES_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800B0000830ull + (((block_id) & 1) * 0x8000000ull)) -+ -+union cvmx_pcsxx_10gbx_status_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_10gbx_status_reg_s { -+ uint64_t reserved_13_63:51; -+ uint64_t alignd:1; -+ uint64_t pattst:1; -+ uint64_t reserved_4_10:7; -+ uint64_t l3sync:1; -+ uint64_t l2sync:1; -+ uint64_t l1sync:1; -+ uint64_t l0sync:1; -+ } s; -+ struct cvmx_pcsxx_10gbx_status_reg_s cn52xx; -+ struct cvmx_pcsxx_10gbx_status_reg_s cn52xxp1; -+ struct cvmx_pcsxx_10gbx_status_reg_s cn56xx; -+ struct cvmx_pcsxx_10gbx_status_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_bist_status_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_bist_status_reg_s { -+ uint64_t reserved_1_63:63; -+ uint64_t bist_status:1; -+ } s; -+ struct cvmx_pcsxx_bist_status_reg_s cn52xx; -+ struct cvmx_pcsxx_bist_status_reg_s cn52xxp1; -+ struct cvmx_pcsxx_bist_status_reg_s cn56xx; -+ struct cvmx_pcsxx_bist_status_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_bit_lock_status_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_bit_lock_status_reg_s { -+ uint64_t reserved_4_63:60; -+ uint64_t bitlck3:1; -+ uint64_t bitlck2:1; -+ uint64_t bitlck1:1; -+ uint64_t bitlck0:1; -+ } s; -+ struct cvmx_pcsxx_bit_lock_status_reg_s cn52xx; -+ struct cvmx_pcsxx_bit_lock_status_reg_s cn52xxp1; -+ struct cvmx_pcsxx_bit_lock_status_reg_s cn56xx; -+ struct cvmx_pcsxx_bit_lock_status_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_control1_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_control1_reg_s { -+ uint64_t reserved_16_63:48; -+ uint64_t reset:1; -+ uint64_t loopbck1:1; -+ uint64_t spdsel1:1; -+ uint64_t reserved_12_12:1; -+ uint64_t lo_pwr:1; -+ uint64_t reserved_7_10:4; -+ uint64_t spdsel0:1; -+ uint64_t spd:4; -+ uint64_t reserved_0_1:2; -+ } s; -+ struct cvmx_pcsxx_control1_reg_s cn52xx; -+ struct cvmx_pcsxx_control1_reg_s cn52xxp1; -+ struct cvmx_pcsxx_control1_reg_s cn56xx; -+ struct cvmx_pcsxx_control1_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_control2_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_control2_reg_s { -+ uint64_t reserved_2_63:62; -+ uint64_t type:2; -+ } s; -+ struct cvmx_pcsxx_control2_reg_s cn52xx; -+ struct cvmx_pcsxx_control2_reg_s cn52xxp1; -+ struct cvmx_pcsxx_control2_reg_s cn56xx; -+ struct cvmx_pcsxx_control2_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_int_en_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_int_en_reg_s { -+ uint64_t reserved_6_63:58; -+ uint64_t algnlos_en:1; -+ uint64_t synlos_en:1; -+ uint64_t bitlckls_en:1; -+ uint64_t rxsynbad_en:1; -+ uint64_t rxbad_en:1; -+ uint64_t txflt_en:1; -+ } s; -+ struct cvmx_pcsxx_int_en_reg_s cn52xx; -+ struct cvmx_pcsxx_int_en_reg_s cn52xxp1; -+ struct cvmx_pcsxx_int_en_reg_s cn56xx; -+ struct cvmx_pcsxx_int_en_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_int_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_int_reg_s { -+ uint64_t reserved_6_63:58; -+ uint64_t algnlos:1; -+ uint64_t synlos:1; -+ uint64_t bitlckls:1; -+ uint64_t rxsynbad:1; -+ uint64_t rxbad:1; -+ uint64_t txflt:1; -+ } s; -+ struct cvmx_pcsxx_int_reg_s cn52xx; -+ struct cvmx_pcsxx_int_reg_s cn52xxp1; -+ struct cvmx_pcsxx_int_reg_s cn56xx; -+ struct cvmx_pcsxx_int_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_log_anl_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_log_anl_reg_s { -+ uint64_t reserved_7_63:57; -+ uint64_t enc_mode:1; -+ uint64_t drop_ln:2; -+ uint64_t lafifovfl:1; -+ uint64_t la_en:1; -+ uint64_t pkt_sz:2; -+ } s; -+ struct cvmx_pcsxx_log_anl_reg_s cn52xx; -+ struct cvmx_pcsxx_log_anl_reg_s cn52xxp1; -+ struct cvmx_pcsxx_log_anl_reg_s cn56xx; -+ struct cvmx_pcsxx_log_anl_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_misc_ctl_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_misc_ctl_reg_s { -+ uint64_t reserved_4_63:60; -+ uint64_t tx_swap:1; -+ uint64_t rx_swap:1; -+ uint64_t xaui:1; -+ uint64_t gmxeno:1; -+ } s; -+ struct cvmx_pcsxx_misc_ctl_reg_s cn52xx; -+ struct cvmx_pcsxx_misc_ctl_reg_s cn52xxp1; -+ struct cvmx_pcsxx_misc_ctl_reg_s cn56xx; -+ struct cvmx_pcsxx_misc_ctl_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_rx_sync_states_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_rx_sync_states_reg_s { -+ uint64_t reserved_16_63:48; -+ uint64_t sync3st:4; -+ uint64_t sync2st:4; -+ uint64_t sync1st:4; -+ uint64_t sync0st:4; -+ } s; -+ struct cvmx_pcsxx_rx_sync_states_reg_s cn52xx; -+ struct cvmx_pcsxx_rx_sync_states_reg_s cn52xxp1; -+ struct cvmx_pcsxx_rx_sync_states_reg_s cn56xx; -+ struct cvmx_pcsxx_rx_sync_states_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_spd_abil_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_spd_abil_reg_s { -+ uint64_t reserved_2_63:62; -+ uint64_t tenpasst:1; -+ uint64_t tengb:1; -+ } s; -+ struct cvmx_pcsxx_spd_abil_reg_s cn52xx; -+ struct cvmx_pcsxx_spd_abil_reg_s cn52xxp1; -+ struct cvmx_pcsxx_spd_abil_reg_s cn56xx; -+ struct cvmx_pcsxx_spd_abil_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_status1_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_status1_reg_s { -+ uint64_t reserved_8_63:56; -+ uint64_t flt:1; -+ uint64_t reserved_3_6:4; -+ uint64_t rcv_lnk:1; -+ uint64_t lpable:1; -+ uint64_t reserved_0_0:1; -+ } s; -+ struct cvmx_pcsxx_status1_reg_s cn52xx; -+ struct cvmx_pcsxx_status1_reg_s cn52xxp1; -+ struct cvmx_pcsxx_status1_reg_s cn56xx; -+ struct cvmx_pcsxx_status1_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_status2_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_status2_reg_s { -+ uint64_t reserved_16_63:48; -+ uint64_t dev:2; -+ uint64_t reserved_12_13:2; -+ uint64_t xmtflt:1; -+ uint64_t rcvflt:1; -+ uint64_t reserved_3_9:7; -+ uint64_t tengb_w:1; -+ uint64_t tengb_x:1; -+ uint64_t tengb_r:1; -+ } s; -+ struct cvmx_pcsxx_status2_reg_s cn52xx; -+ struct cvmx_pcsxx_status2_reg_s cn52xxp1; -+ struct cvmx_pcsxx_status2_reg_s cn56xx; -+ struct cvmx_pcsxx_status2_reg_s cn56xxp1; -+}; -+ -+union cvmx_pcsxx_tx_rx_polarity_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_tx_rx_polarity_reg_s { -+ uint64_t reserved_10_63:54; -+ uint64_t xor_rxplrt:4; -+ uint64_t xor_txplrt:4; -+ uint64_t rxplrt:1; -+ uint64_t txplrt:1; -+ } s; -+ struct cvmx_pcsxx_tx_rx_polarity_reg_s cn52xx; -+ struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 { -+ uint64_t reserved_2_63:62; -+ uint64_t rxplrt:1; -+ uint64_t txplrt:1; -+ } cn52xxp1; -+ struct cvmx_pcsxx_tx_rx_polarity_reg_s cn56xx; -+ struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 cn56xxp1; -+}; -+ -+union cvmx_pcsxx_tx_rx_states_reg { -+ uint64_t u64; -+ struct cvmx_pcsxx_tx_rx_states_reg_s { -+ uint64_t reserved_14_63:50; -+ uint64_t term_err:1; -+ uint64_t syn3bad:1; -+ uint64_t syn2bad:1; -+ uint64_t syn1bad:1; -+ uint64_t syn0bad:1; -+ uint64_t rxbad:1; -+ uint64_t algn_st:3; -+ uint64_t rx_st:2; -+ uint64_t tx_st:3; -+ } s; -+ struct cvmx_pcsxx_tx_rx_states_reg_s cn52xx; -+ struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 { -+ uint64_t reserved_13_63:51; -+ uint64_t syn3bad:1; -+ uint64_t syn2bad:1; -+ uint64_t syn1bad:1; -+ uint64_t syn0bad:1; -+ uint64_t rxbad:1; -+ uint64_t algn_st:3; -+ uint64_t rx_st:2; -+ uint64_t tx_st:3; -+ } cn52xxp1; -+ struct cvmx_pcsxx_tx_rx_states_reg_s cn56xx; -+ struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 cn56xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-pip-defs.h -@@ -0,0 +1,1267 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_PIP_DEFS_H__ -+#define __CVMX_PIP_DEFS_H__ -+ -+/* -+ * Enumeration representing the amount of packet processing -+ * and validation performed by the input hardware. -+ */ -+enum cvmx_pip_port_parse_mode { -+ /* -+ * Packet input doesn't perform any processing of the input -+ * packet. -+ */ -+ CVMX_PIP_PORT_CFG_MODE_NONE = 0ull, -+ /* -+ * Full packet processing is performed with pointer starting -+ * at the L2 (ethernet MAC) header. -+ */ -+ CVMX_PIP_PORT_CFG_MODE_SKIPL2 = 1ull, -+ /* -+ * Input packets are assumed to be IP. Results from non IP -+ * packets is undefined. Pointers reference the beginning of -+ * the IP header. -+ */ -+ CVMX_PIP_PORT_CFG_MODE_SKIPIP = 2ull -+}; -+ -+#define CVMX_PIP_BCK_PRS \ -+ CVMX_ADD_IO_SEG(0x00011800A0000038ull) -+#define CVMX_PIP_BIST_STATUS \ -+ CVMX_ADD_IO_SEG(0x00011800A0000000ull) -+#define CVMX_PIP_CRC_CTLX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000040ull + (((offset) & 1) * 8)) -+#define CVMX_PIP_CRC_IVX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000050ull + (((offset) & 1) * 8)) -+#define CVMX_PIP_DEC_IPSECX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000080ull + (((offset) & 3) * 8)) -+#define CVMX_PIP_DSA_SRC_GRP \ -+ CVMX_ADD_IO_SEG(0x00011800A0000190ull) -+#define CVMX_PIP_DSA_VID_GRP \ -+ CVMX_ADD_IO_SEG(0x00011800A0000198ull) -+#define CVMX_PIP_FRM_LEN_CHKX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000180ull + (((offset) & 1) * 8)) -+#define CVMX_PIP_GBL_CFG \ -+ CVMX_ADD_IO_SEG(0x00011800A0000028ull) -+#define CVMX_PIP_GBL_CTL \ -+ CVMX_ADD_IO_SEG(0x00011800A0000020ull) -+#define CVMX_PIP_HG_PRI_QOS \ -+ CVMX_ADD_IO_SEG(0x00011800A00001A0ull) -+#define CVMX_PIP_INT_EN \ -+ CVMX_ADD_IO_SEG(0x00011800A0000010ull) -+#define CVMX_PIP_INT_REG \ -+ CVMX_ADD_IO_SEG(0x00011800A0000008ull) -+#define CVMX_PIP_IP_OFFSET \ -+ CVMX_ADD_IO_SEG(0x00011800A0000060ull) -+#define CVMX_PIP_PRT_CFGX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000200ull + (((offset) & 63) * 8)) -+#define CVMX_PIP_PRT_TAGX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000400ull + (((offset) & 63) * 8)) -+#define CVMX_PIP_QOS_DIFFX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000600ull + (((offset) & 63) * 8)) -+#define CVMX_PIP_QOS_VLANX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A00000C0ull + (((offset) & 7) * 8)) -+#define CVMX_PIP_QOS_WATCHX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000100ull + (((offset) & 7) * 8)) -+#define CVMX_PIP_RAW_WORD \ -+ CVMX_ADD_IO_SEG(0x00011800A00000B0ull) -+#define CVMX_PIP_SFT_RST \ -+ CVMX_ADD_IO_SEG(0x00011800A0000030ull) -+#define CVMX_PIP_STAT0_PRTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000800ull + (((offset) & 63) * 80)) -+#define CVMX_PIP_STAT1_PRTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000808ull + (((offset) & 63) * 80)) -+#define CVMX_PIP_STAT2_PRTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000810ull + (((offset) & 63) * 80)) -+#define CVMX_PIP_STAT3_PRTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000818ull + (((offset) & 63) * 80)) -+#define CVMX_PIP_STAT4_PRTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000820ull + (((offset) & 63) * 80)) -+#define CVMX_PIP_STAT5_PRTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000828ull + (((offset) & 63) * 80)) -+#define CVMX_PIP_STAT6_PRTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000830ull + (((offset) & 63) * 80)) -+#define CVMX_PIP_STAT7_PRTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000838ull + (((offset) & 63) * 80)) -+#define CVMX_PIP_STAT8_PRTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000840ull + (((offset) & 63) * 80)) -+#define CVMX_PIP_STAT9_PRTX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0000848ull + (((offset) & 63) * 80)) -+#define CVMX_PIP_STAT_CTL \ -+ CVMX_ADD_IO_SEG(0x00011800A0000018ull) -+#define CVMX_PIP_STAT_INB_ERRSX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0001A10ull + (((offset) & 63) * 32)) -+#define CVMX_PIP_STAT_INB_OCTSX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0001A08ull + (((offset) & 63) * 32)) -+#define CVMX_PIP_STAT_INB_PKTSX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0001A00ull + (((offset) & 63) * 32)) -+#define CVMX_PIP_TAG_INCX(offset) \ -+ CVMX_ADD_IO_SEG(0x00011800A0001800ull + (((offset) & 63) * 8)) -+#define CVMX_PIP_TAG_MASK \ -+ CVMX_ADD_IO_SEG(0x00011800A0000070ull) -+#define CVMX_PIP_TAG_SECRET \ -+ CVMX_ADD_IO_SEG(0x00011800A0000068ull) -+#define CVMX_PIP_TODO_ENTRY \ -+ CVMX_ADD_IO_SEG(0x00011800A0000078ull) -+ -+union cvmx_pip_bck_prs { -+ uint64_t u64; -+ struct cvmx_pip_bck_prs_s { -+ uint64_t bckprs:1; -+ uint64_t reserved_13_62:50; -+ uint64_t hiwater:5; -+ uint64_t reserved_5_7:3; -+ uint64_t lowater:5; -+ } s; -+ struct cvmx_pip_bck_prs_s cn38xx; -+ struct cvmx_pip_bck_prs_s cn38xxp2; -+ struct cvmx_pip_bck_prs_s cn56xx; -+ struct cvmx_pip_bck_prs_s cn56xxp1; -+ struct cvmx_pip_bck_prs_s cn58xx; -+ struct cvmx_pip_bck_prs_s cn58xxp1; -+}; -+ -+union cvmx_pip_bist_status { -+ uint64_t u64; -+ struct cvmx_pip_bist_status_s { -+ uint64_t reserved_18_63:46; -+ uint64_t bist:18; -+ } s; -+ struct cvmx_pip_bist_status_s cn30xx; -+ struct cvmx_pip_bist_status_s cn31xx; -+ struct cvmx_pip_bist_status_s cn38xx; -+ struct cvmx_pip_bist_status_s cn38xxp2; -+ struct cvmx_pip_bist_status_cn50xx { -+ uint64_t reserved_17_63:47; -+ uint64_t bist:17; -+ } cn50xx; -+ struct cvmx_pip_bist_status_s cn52xx; -+ struct cvmx_pip_bist_status_s cn52xxp1; -+ struct cvmx_pip_bist_status_s cn56xx; -+ struct cvmx_pip_bist_status_s cn56xxp1; -+ struct cvmx_pip_bist_status_s cn58xx; -+ struct cvmx_pip_bist_status_s cn58xxp1; -+}; -+ -+union cvmx_pip_crc_ctlx { -+ uint64_t u64; -+ struct cvmx_pip_crc_ctlx_s { -+ uint64_t reserved_2_63:62; -+ uint64_t invres:1; -+ uint64_t reflect:1; -+ } s; -+ struct cvmx_pip_crc_ctlx_s cn38xx; -+ struct cvmx_pip_crc_ctlx_s cn38xxp2; -+ struct cvmx_pip_crc_ctlx_s cn58xx; -+ struct cvmx_pip_crc_ctlx_s cn58xxp1; -+}; -+ -+union cvmx_pip_crc_ivx { -+ uint64_t u64; -+ struct cvmx_pip_crc_ivx_s { -+ uint64_t reserved_32_63:32; -+ uint64_t iv:32; -+ } s; -+ struct cvmx_pip_crc_ivx_s cn38xx; -+ struct cvmx_pip_crc_ivx_s cn38xxp2; -+ struct cvmx_pip_crc_ivx_s cn58xx; -+ struct cvmx_pip_crc_ivx_s cn58xxp1; -+}; -+ -+union cvmx_pip_dec_ipsecx { -+ uint64_t u64; -+ struct cvmx_pip_dec_ipsecx_s { -+ uint64_t reserved_18_63:46; -+ uint64_t tcp:1; -+ uint64_t udp:1; -+ uint64_t dprt:16; -+ } s; -+ struct cvmx_pip_dec_ipsecx_s cn30xx; -+ struct cvmx_pip_dec_ipsecx_s cn31xx; -+ struct cvmx_pip_dec_ipsecx_s cn38xx; -+ struct cvmx_pip_dec_ipsecx_s cn38xxp2; -+ struct cvmx_pip_dec_ipsecx_s cn50xx; -+ struct cvmx_pip_dec_ipsecx_s cn52xx; -+ struct cvmx_pip_dec_ipsecx_s cn52xxp1; -+ struct cvmx_pip_dec_ipsecx_s cn56xx; -+ struct cvmx_pip_dec_ipsecx_s cn56xxp1; -+ struct cvmx_pip_dec_ipsecx_s cn58xx; -+ struct cvmx_pip_dec_ipsecx_s cn58xxp1; -+}; -+ -+union cvmx_pip_dsa_src_grp { -+ uint64_t u64; -+ struct cvmx_pip_dsa_src_grp_s { -+ uint64_t map15:4; -+ uint64_t map14:4; -+ uint64_t map13:4; -+ uint64_t map12:4; -+ uint64_t map11:4; -+ uint64_t map10:4; -+ uint64_t map9:4; -+ uint64_t map8:4; -+ uint64_t map7:4; -+ uint64_t map6:4; -+ uint64_t map5:4; -+ uint64_t map4:4; -+ uint64_t map3:4; -+ uint64_t map2:4; -+ uint64_t map1:4; -+ uint64_t map0:4; -+ } s; -+ struct cvmx_pip_dsa_src_grp_s cn52xx; -+ struct cvmx_pip_dsa_src_grp_s cn52xxp1; -+ struct cvmx_pip_dsa_src_grp_s cn56xx; -+}; -+ -+union cvmx_pip_dsa_vid_grp { -+ uint64_t u64; -+ struct cvmx_pip_dsa_vid_grp_s { -+ uint64_t map15:4; -+ uint64_t map14:4; -+ uint64_t map13:4; -+ uint64_t map12:4; -+ uint64_t map11:4; -+ uint64_t map10:4; -+ uint64_t map9:4; -+ uint64_t map8:4; -+ uint64_t map7:4; -+ uint64_t map6:4; -+ uint64_t map5:4; -+ uint64_t map4:4; -+ uint64_t map3:4; -+ uint64_t map2:4; -+ uint64_t map1:4; -+ uint64_t map0:4; -+ } s; -+ struct cvmx_pip_dsa_vid_grp_s cn52xx; -+ struct cvmx_pip_dsa_vid_grp_s cn52xxp1; -+ struct cvmx_pip_dsa_vid_grp_s cn56xx; -+}; -+ -+union cvmx_pip_frm_len_chkx { -+ uint64_t u64; -+ struct cvmx_pip_frm_len_chkx_s { -+ uint64_t reserved_32_63:32; -+ uint64_t maxlen:16; -+ uint64_t minlen:16; -+ } s; -+ struct cvmx_pip_frm_len_chkx_s cn50xx; -+ struct cvmx_pip_frm_len_chkx_s cn52xx; -+ struct cvmx_pip_frm_len_chkx_s cn52xxp1; -+ struct cvmx_pip_frm_len_chkx_s cn56xx; -+ struct cvmx_pip_frm_len_chkx_s cn56xxp1; -+}; -+ -+union cvmx_pip_gbl_cfg { -+ uint64_t u64; -+ struct cvmx_pip_gbl_cfg_s { -+ uint64_t reserved_19_63:45; -+ uint64_t tag_syn:1; -+ uint64_t ip6_udp:1; -+ uint64_t max_l2:1; -+ uint64_t reserved_11_15:5; -+ uint64_t raw_shf:3; -+ uint64_t reserved_3_7:5; -+ uint64_t nip_shf:3; -+ } s; -+ struct cvmx_pip_gbl_cfg_s cn30xx; -+ struct cvmx_pip_gbl_cfg_s cn31xx; -+ struct cvmx_pip_gbl_cfg_s cn38xx; -+ struct cvmx_pip_gbl_cfg_s cn38xxp2; -+ struct cvmx_pip_gbl_cfg_s cn50xx; -+ struct cvmx_pip_gbl_cfg_s cn52xx; -+ struct cvmx_pip_gbl_cfg_s cn52xxp1; -+ struct cvmx_pip_gbl_cfg_s cn56xx; -+ struct cvmx_pip_gbl_cfg_s cn56xxp1; -+ struct cvmx_pip_gbl_cfg_s cn58xx; -+ struct cvmx_pip_gbl_cfg_s cn58xxp1; -+}; -+ -+union cvmx_pip_gbl_ctl { -+ uint64_t u64; -+ struct cvmx_pip_gbl_ctl_s { -+ uint64_t reserved_27_63:37; -+ uint64_t dsa_grp_tvid:1; -+ uint64_t dsa_grp_scmd:1; -+ uint64_t dsa_grp_sid:1; -+ uint64_t reserved_21_23:3; -+ uint64_t ring_en:1; -+ uint64_t reserved_17_19:3; -+ uint64_t ignrs:1; -+ uint64_t vs_wqe:1; -+ uint64_t vs_qos:1; -+ uint64_t l2_mal:1; -+ uint64_t tcp_flag:1; -+ uint64_t l4_len:1; -+ uint64_t l4_chk:1; -+ uint64_t l4_prt:1; -+ uint64_t l4_mal:1; -+ uint64_t reserved_6_7:2; -+ uint64_t ip6_eext:2; -+ uint64_t ip4_opts:1; -+ uint64_t ip_hop:1; -+ uint64_t ip_mal:1; -+ uint64_t ip_chk:1; -+ } s; -+ struct cvmx_pip_gbl_ctl_cn30xx { -+ uint64_t reserved_17_63:47; -+ uint64_t ignrs:1; -+ uint64_t vs_wqe:1; -+ uint64_t vs_qos:1; -+ uint64_t l2_mal:1; -+ uint64_t tcp_flag:1; -+ uint64_t l4_len:1; -+ uint64_t l4_chk:1; -+ uint64_t l4_prt:1; -+ uint64_t l4_mal:1; -+ uint64_t reserved_6_7:2; -+ uint64_t ip6_eext:2; -+ uint64_t ip4_opts:1; -+ uint64_t ip_hop:1; -+ uint64_t ip_mal:1; -+ uint64_t ip_chk:1; -+ } cn30xx; -+ struct cvmx_pip_gbl_ctl_cn30xx cn31xx; -+ struct cvmx_pip_gbl_ctl_cn30xx cn38xx; -+ struct cvmx_pip_gbl_ctl_cn30xx cn38xxp2; -+ struct cvmx_pip_gbl_ctl_cn30xx cn50xx; -+ struct cvmx_pip_gbl_ctl_s cn52xx; -+ struct cvmx_pip_gbl_ctl_s cn52xxp1; -+ struct cvmx_pip_gbl_ctl_s cn56xx; -+ struct cvmx_pip_gbl_ctl_cn56xxp1 { -+ uint64_t reserved_21_63:43; -+ uint64_t ring_en:1; -+ uint64_t reserved_17_19:3; -+ uint64_t ignrs:1; -+ uint64_t vs_wqe:1; -+ uint64_t vs_qos:1; -+ uint64_t l2_mal:1; -+ uint64_t tcp_flag:1; -+ uint64_t l4_len:1; -+ uint64_t l4_chk:1; -+ uint64_t l4_prt:1; -+ uint64_t l4_mal:1; -+ uint64_t reserved_6_7:2; -+ uint64_t ip6_eext:2; -+ uint64_t ip4_opts:1; -+ uint64_t ip_hop:1; -+ uint64_t ip_mal:1; -+ uint64_t ip_chk:1; -+ } cn56xxp1; -+ struct cvmx_pip_gbl_ctl_cn30xx cn58xx; -+ struct cvmx_pip_gbl_ctl_cn30xx cn58xxp1; -+}; -+ -+union cvmx_pip_hg_pri_qos { -+ uint64_t u64; -+ struct cvmx_pip_hg_pri_qos_s { -+ uint64_t reserved_11_63:53; -+ uint64_t qos:3; -+ uint64_t reserved_6_7:2; -+ uint64_t pri:6; -+ } s; -+ struct cvmx_pip_hg_pri_qos_s cn52xx; -+ struct cvmx_pip_hg_pri_qos_s cn52xxp1; -+ struct cvmx_pip_hg_pri_qos_s cn56xx; -+}; -+ -+union cvmx_pip_int_en { -+ uint64_t u64; -+ struct cvmx_pip_int_en_s { -+ uint64_t reserved_13_63:51; -+ uint64_t punyerr:1; -+ uint64_t lenerr:1; -+ uint64_t maxerr:1; -+ uint64_t minerr:1; -+ uint64_t beperr:1; -+ uint64_t feperr:1; -+ uint64_t todoovr:1; -+ uint64_t skprunt:1; -+ uint64_t badtag:1; -+ uint64_t prtnxa:1; -+ uint64_t bckprs:1; -+ uint64_t crcerr:1; -+ uint64_t pktdrp:1; -+ } s; -+ struct cvmx_pip_int_en_cn30xx { -+ uint64_t reserved_9_63:55; -+ uint64_t beperr:1; -+ uint64_t feperr:1; -+ uint64_t todoovr:1; -+ uint64_t skprunt:1; -+ uint64_t badtag:1; -+ uint64_t prtnxa:1; -+ uint64_t bckprs:1; -+ uint64_t crcerr:1; -+ uint64_t pktdrp:1; -+ } cn30xx; -+ struct cvmx_pip_int_en_cn30xx cn31xx; -+ struct cvmx_pip_int_en_cn30xx cn38xx; -+ struct cvmx_pip_int_en_cn30xx cn38xxp2; -+ struct cvmx_pip_int_en_cn50xx { -+ uint64_t reserved_12_63:52; -+ uint64_t lenerr:1; -+ uint64_t maxerr:1; -+ uint64_t minerr:1; -+ uint64_t beperr:1; -+ uint64_t feperr:1; -+ uint64_t todoovr:1; -+ uint64_t skprunt:1; -+ uint64_t badtag:1; -+ uint64_t prtnxa:1; -+ uint64_t bckprs:1; -+ uint64_t reserved_1_1:1; -+ uint64_t pktdrp:1; -+ } cn50xx; -+ struct cvmx_pip_int_en_cn52xx { -+ uint64_t reserved_13_63:51; -+ uint64_t punyerr:1; -+ uint64_t lenerr:1; -+ uint64_t maxerr:1; -+ uint64_t minerr:1; -+ uint64_t beperr:1; -+ uint64_t feperr:1; -+ uint64_t todoovr:1; -+ uint64_t skprunt:1; -+ uint64_t badtag:1; -+ uint64_t prtnxa:1; -+ uint64_t bckprs:1; -+ uint64_t reserved_1_1:1; -+ uint64_t pktdrp:1; -+ } cn52xx; -+ struct cvmx_pip_int_en_cn52xx cn52xxp1; -+ struct cvmx_pip_int_en_s cn56xx; -+ struct cvmx_pip_int_en_cn56xxp1 { -+ uint64_t reserved_12_63:52; -+ uint64_t lenerr:1; -+ uint64_t maxerr:1; -+ uint64_t minerr:1; -+ uint64_t beperr:1; -+ uint64_t feperr:1; -+ uint64_t todoovr:1; -+ uint64_t skprunt:1; -+ uint64_t badtag:1; -+ uint64_t prtnxa:1; -+ uint64_t bckprs:1; -+ uint64_t crcerr:1; -+ uint64_t pktdrp:1; -+ } cn56xxp1; -+ struct cvmx_pip_int_en_cn58xx { -+ uint64_t reserved_13_63:51; -+ uint64_t punyerr:1; -+ uint64_t reserved_9_11:3; -+ uint64_t beperr:1; -+ uint64_t feperr:1; -+ uint64_t todoovr:1; -+ uint64_t skprunt:1; -+ uint64_t badtag:1; -+ uint64_t prtnxa:1; -+ uint64_t bckprs:1; -+ uint64_t crcerr:1; -+ uint64_t pktdrp:1; -+ } cn58xx; -+ struct cvmx_pip_int_en_cn30xx cn58xxp1; -+}; -+ -+union cvmx_pip_int_reg { -+ uint64_t u64; -+ struct cvmx_pip_int_reg_s { -+ uint64_t reserved_13_63:51; -+ uint64_t punyerr:1; -+ uint64_t lenerr:1; -+ uint64_t maxerr:1; -+ uint64_t minerr:1; -+ uint64_t beperr:1; -+ uint64_t feperr:1; -+ uint64_t todoovr:1; -+ uint64_t skprunt:1; -+ uint64_t badtag:1; -+ uint64_t prtnxa:1; -+ uint64_t bckprs:1; -+ uint64_t crcerr:1; -+ uint64_t pktdrp:1; -+ } s; -+ struct cvmx_pip_int_reg_cn30xx { -+ uint64_t reserved_9_63:55; -+ uint64_t beperr:1; -+ uint64_t feperr:1; -+ uint64_t todoovr:1; -+ uint64_t skprunt:1; -+ uint64_t badtag:1; -+ uint64_t prtnxa:1; -+ uint64_t bckprs:1; -+ uint64_t crcerr:1; -+ uint64_t pktdrp:1; -+ } cn30xx; -+ struct cvmx_pip_int_reg_cn30xx cn31xx; -+ struct cvmx_pip_int_reg_cn30xx cn38xx; -+ struct cvmx_pip_int_reg_cn30xx cn38xxp2; -+ struct cvmx_pip_int_reg_cn50xx { -+ uint64_t reserved_12_63:52; -+ uint64_t lenerr:1; -+ uint64_t maxerr:1; -+ uint64_t minerr:1; -+ uint64_t beperr:1; -+ uint64_t feperr:1; -+ uint64_t todoovr:1; -+ uint64_t skprunt:1; -+ uint64_t badtag:1; -+ uint64_t prtnxa:1; -+ uint64_t bckprs:1; -+ uint64_t reserved_1_1:1; -+ uint64_t pktdrp:1; -+ } cn50xx; -+ struct cvmx_pip_int_reg_cn52xx { -+ uint64_t reserved_13_63:51; -+ uint64_t punyerr:1; -+ uint64_t lenerr:1; -+ uint64_t maxerr:1; -+ uint64_t minerr:1; -+ uint64_t beperr:1; -+ uint64_t feperr:1; -+ uint64_t todoovr:1; -+ uint64_t skprunt:1; -+ uint64_t badtag:1; -+ uint64_t prtnxa:1; -+ uint64_t bckprs:1; -+ uint64_t reserved_1_1:1; -+ uint64_t pktdrp:1; -+ } cn52xx; -+ struct cvmx_pip_int_reg_cn52xx cn52xxp1; -+ struct cvmx_pip_int_reg_s cn56xx; -+ struct cvmx_pip_int_reg_cn56xxp1 { -+ uint64_t reserved_12_63:52; -+ uint64_t lenerr:1; -+ uint64_t maxerr:1; -+ uint64_t minerr:1; -+ uint64_t beperr:1; -+ uint64_t feperr:1; -+ uint64_t todoovr:1; -+ uint64_t skprunt:1; -+ uint64_t badtag:1; -+ uint64_t prtnxa:1; -+ uint64_t bckprs:1; -+ uint64_t crcerr:1; -+ uint64_t pktdrp:1; -+ } cn56xxp1; -+ struct cvmx_pip_int_reg_cn58xx { -+ uint64_t reserved_13_63:51; -+ uint64_t punyerr:1; -+ uint64_t reserved_9_11:3; -+ uint64_t beperr:1; -+ uint64_t feperr:1; -+ uint64_t todoovr:1; -+ uint64_t skprunt:1; -+ uint64_t badtag:1; -+ uint64_t prtnxa:1; -+ uint64_t bckprs:1; -+ uint64_t crcerr:1; -+ uint64_t pktdrp:1; -+ } cn58xx; -+ struct cvmx_pip_int_reg_cn30xx cn58xxp1; -+}; -+ -+union cvmx_pip_ip_offset { -+ uint64_t u64; -+ struct cvmx_pip_ip_offset_s { -+ uint64_t reserved_3_63:61; -+ uint64_t offset:3; -+ } s; -+ struct cvmx_pip_ip_offset_s cn30xx; -+ struct cvmx_pip_ip_offset_s cn31xx; -+ struct cvmx_pip_ip_offset_s cn38xx; -+ struct cvmx_pip_ip_offset_s cn38xxp2; -+ struct cvmx_pip_ip_offset_s cn50xx; -+ struct cvmx_pip_ip_offset_s cn52xx; -+ struct cvmx_pip_ip_offset_s cn52xxp1; -+ struct cvmx_pip_ip_offset_s cn56xx; -+ struct cvmx_pip_ip_offset_s cn56xxp1; -+ struct cvmx_pip_ip_offset_s cn58xx; -+ struct cvmx_pip_ip_offset_s cn58xxp1; -+}; -+ -+union cvmx_pip_prt_cfgx { -+ uint64_t u64; -+ struct cvmx_pip_prt_cfgx_s { -+ uint64_t reserved_53_63:11; -+ uint64_t pad_len:1; -+ uint64_t vlan_len:1; -+ uint64_t lenerr_en:1; -+ uint64_t maxerr_en:1; -+ uint64_t minerr_en:1; -+ uint64_t grp_wat_47:4; -+ uint64_t qos_wat_47:4; -+ uint64_t reserved_37_39:3; -+ uint64_t rawdrp:1; -+ uint64_t tag_inc:2; -+ uint64_t dyn_rs:1; -+ uint64_t inst_hdr:1; -+ uint64_t grp_wat:4; -+ uint64_t hg_qos:1; -+ uint64_t qos:3; -+ uint64_t qos_wat:4; -+ uint64_t qos_vsel:1; -+ uint64_t qos_vod:1; -+ uint64_t qos_diff:1; -+ uint64_t qos_vlan:1; -+ uint64_t reserved_13_15:3; -+ uint64_t crc_en:1; -+ uint64_t higig_en:1; -+ uint64_t dsa_en:1; -+ uint64_t mode:2; -+ uint64_t reserved_7_7:1; -+ uint64_t skip:7; -+ } s; -+ struct cvmx_pip_prt_cfgx_cn30xx { -+ uint64_t reserved_37_63:27; -+ uint64_t rawdrp:1; -+ uint64_t tag_inc:2; -+ uint64_t dyn_rs:1; -+ uint64_t inst_hdr:1; -+ uint64_t grp_wat:4; -+ uint64_t reserved_27_27:1; -+ uint64_t qos:3; -+ uint64_t qos_wat:4; -+ uint64_t reserved_18_19:2; -+ uint64_t qos_diff:1; -+ uint64_t qos_vlan:1; -+ uint64_t reserved_10_15:6; -+ uint64_t mode:2; -+ uint64_t reserved_7_7:1; -+ uint64_t skip:7; -+ } cn30xx; -+ struct cvmx_pip_prt_cfgx_cn30xx cn31xx; -+ struct cvmx_pip_prt_cfgx_cn38xx { -+ uint64_t reserved_37_63:27; -+ uint64_t rawdrp:1; -+ uint64_t tag_inc:2; -+ uint64_t dyn_rs:1; -+ uint64_t inst_hdr:1; -+ uint64_t grp_wat:4; -+ uint64_t reserved_27_27:1; -+ uint64_t qos:3; -+ uint64_t qos_wat:4; -+ uint64_t reserved_18_19:2; -+ uint64_t qos_diff:1; -+ uint64_t qos_vlan:1; -+ uint64_t reserved_13_15:3; -+ uint64_t crc_en:1; -+ uint64_t reserved_10_11:2; -+ uint64_t mode:2; -+ uint64_t reserved_7_7:1; -+ uint64_t skip:7; -+ } cn38xx; -+ struct cvmx_pip_prt_cfgx_cn38xx cn38xxp2; -+ struct cvmx_pip_prt_cfgx_cn50xx { -+ uint64_t reserved_53_63:11; -+ uint64_t pad_len:1; -+ uint64_t vlan_len:1; -+ uint64_t lenerr_en:1; -+ uint64_t maxerr_en:1; -+ uint64_t minerr_en:1; -+ uint64_t grp_wat_47:4; -+ uint64_t qos_wat_47:4; -+ uint64_t reserved_37_39:3; -+ uint64_t rawdrp:1; -+ uint64_t tag_inc:2; -+ uint64_t dyn_rs:1; -+ uint64_t inst_hdr:1; -+ uint64_t grp_wat:4; -+ uint64_t reserved_27_27:1; -+ uint64_t qos:3; -+ uint64_t qos_wat:4; -+ uint64_t reserved_19_19:1; -+ uint64_t qos_vod:1; -+ uint64_t qos_diff:1; -+ uint64_t qos_vlan:1; -+ uint64_t reserved_13_15:3; -+ uint64_t crc_en:1; -+ uint64_t reserved_10_11:2; -+ uint64_t mode:2; -+ uint64_t reserved_7_7:1; -+ uint64_t skip:7; -+ } cn50xx; -+ struct cvmx_pip_prt_cfgx_s cn52xx; -+ struct cvmx_pip_prt_cfgx_s cn52xxp1; -+ struct cvmx_pip_prt_cfgx_s cn56xx; -+ struct cvmx_pip_prt_cfgx_cn50xx cn56xxp1; -+ struct cvmx_pip_prt_cfgx_cn58xx { -+ uint64_t reserved_37_63:27; -+ uint64_t rawdrp:1; -+ uint64_t tag_inc:2; -+ uint64_t dyn_rs:1; -+ uint64_t inst_hdr:1; -+ uint64_t grp_wat:4; -+ uint64_t reserved_27_27:1; -+ uint64_t qos:3; -+ uint64_t qos_wat:4; -+ uint64_t reserved_19_19:1; -+ uint64_t qos_vod:1; -+ uint64_t qos_diff:1; -+ uint64_t qos_vlan:1; -+ uint64_t reserved_13_15:3; -+ uint64_t crc_en:1; -+ uint64_t reserved_10_11:2; -+ uint64_t mode:2; -+ uint64_t reserved_7_7:1; -+ uint64_t skip:7; -+ } cn58xx; -+ struct cvmx_pip_prt_cfgx_cn58xx cn58xxp1; -+}; -+ -+union cvmx_pip_prt_tagx { -+ uint64_t u64; -+ struct cvmx_pip_prt_tagx_s { -+ uint64_t reserved_40_63:24; -+ uint64_t grptagbase:4; -+ uint64_t grptagmask:4; -+ uint64_t grptag:1; -+ uint64_t grptag_mskip:1; -+ uint64_t tag_mode:2; -+ uint64_t inc_vs:2; -+ uint64_t inc_vlan:1; -+ uint64_t inc_prt_flag:1; -+ uint64_t ip6_dprt_flag:1; -+ uint64_t ip4_dprt_flag:1; -+ uint64_t ip6_sprt_flag:1; -+ uint64_t ip4_sprt_flag:1; -+ uint64_t ip6_nxth_flag:1; -+ uint64_t ip4_pctl_flag:1; -+ uint64_t ip6_dst_flag:1; -+ uint64_t ip4_dst_flag:1; -+ uint64_t ip6_src_flag:1; -+ uint64_t ip4_src_flag:1; -+ uint64_t tcp6_tag_type:2; -+ uint64_t tcp4_tag_type:2; -+ uint64_t ip6_tag_type:2; -+ uint64_t ip4_tag_type:2; -+ uint64_t non_tag_type:2; -+ uint64_t grp:4; -+ } s; -+ struct cvmx_pip_prt_tagx_cn30xx { -+ uint64_t reserved_40_63:24; -+ uint64_t grptagbase:4; -+ uint64_t grptagmask:4; -+ uint64_t grptag:1; -+ uint64_t reserved_30_30:1; -+ uint64_t tag_mode:2; -+ uint64_t inc_vs:2; -+ uint64_t inc_vlan:1; -+ uint64_t inc_prt_flag:1; -+ uint64_t ip6_dprt_flag:1; -+ uint64_t ip4_dprt_flag:1; -+ uint64_t ip6_sprt_flag:1; -+ uint64_t ip4_sprt_flag:1; -+ uint64_t ip6_nxth_flag:1; -+ uint64_t ip4_pctl_flag:1; -+ uint64_t ip6_dst_flag:1; -+ uint64_t ip4_dst_flag:1; -+ uint64_t ip6_src_flag:1; -+ uint64_t ip4_src_flag:1; -+ uint64_t tcp6_tag_type:2; -+ uint64_t tcp4_tag_type:2; -+ uint64_t ip6_tag_type:2; -+ uint64_t ip4_tag_type:2; -+ uint64_t non_tag_type:2; -+ uint64_t grp:4; -+ } cn30xx; -+ struct cvmx_pip_prt_tagx_cn30xx cn31xx; -+ struct cvmx_pip_prt_tagx_cn30xx cn38xx; -+ struct cvmx_pip_prt_tagx_cn30xx cn38xxp2; -+ struct cvmx_pip_prt_tagx_s cn50xx; -+ struct cvmx_pip_prt_tagx_s cn52xx; -+ struct cvmx_pip_prt_tagx_s cn52xxp1; -+ struct cvmx_pip_prt_tagx_s cn56xx; -+ struct cvmx_pip_prt_tagx_s cn56xxp1; -+ struct cvmx_pip_prt_tagx_cn30xx cn58xx; -+ struct cvmx_pip_prt_tagx_cn30xx cn58xxp1; -+}; -+ -+union cvmx_pip_qos_diffx { -+ uint64_t u64; -+ struct cvmx_pip_qos_diffx_s { -+ uint64_t reserved_3_63:61; -+ uint64_t qos:3; -+ } s; -+ struct cvmx_pip_qos_diffx_s cn30xx; -+ struct cvmx_pip_qos_diffx_s cn31xx; -+ struct cvmx_pip_qos_diffx_s cn38xx; -+ struct cvmx_pip_qos_diffx_s cn38xxp2; -+ struct cvmx_pip_qos_diffx_s cn50xx; -+ struct cvmx_pip_qos_diffx_s cn52xx; -+ struct cvmx_pip_qos_diffx_s cn52xxp1; -+ struct cvmx_pip_qos_diffx_s cn56xx; -+ struct cvmx_pip_qos_diffx_s cn56xxp1; -+ struct cvmx_pip_qos_diffx_s cn58xx; -+ struct cvmx_pip_qos_diffx_s cn58xxp1; -+}; -+ -+union cvmx_pip_qos_vlanx { -+ uint64_t u64; -+ struct cvmx_pip_qos_vlanx_s { -+ uint64_t reserved_7_63:57; -+ uint64_t qos1:3; -+ uint64_t reserved_3_3:1; -+ uint64_t qos:3; -+ } s; -+ struct cvmx_pip_qos_vlanx_cn30xx { -+ uint64_t reserved_3_63:61; -+ uint64_t qos:3; -+ } cn30xx; -+ struct cvmx_pip_qos_vlanx_cn30xx cn31xx; -+ struct cvmx_pip_qos_vlanx_cn30xx cn38xx; -+ struct cvmx_pip_qos_vlanx_cn30xx cn38xxp2; -+ struct cvmx_pip_qos_vlanx_cn30xx cn50xx; -+ struct cvmx_pip_qos_vlanx_s cn52xx; -+ struct cvmx_pip_qos_vlanx_s cn52xxp1; -+ struct cvmx_pip_qos_vlanx_s cn56xx; -+ struct cvmx_pip_qos_vlanx_cn30xx cn56xxp1; -+ struct cvmx_pip_qos_vlanx_cn30xx cn58xx; -+ struct cvmx_pip_qos_vlanx_cn30xx cn58xxp1; -+}; -+ -+union cvmx_pip_qos_watchx { -+ uint64_t u64; -+ struct cvmx_pip_qos_watchx_s { -+ uint64_t reserved_48_63:16; -+ uint64_t mask:16; -+ uint64_t reserved_28_31:4; -+ uint64_t grp:4; -+ uint64_t reserved_23_23:1; -+ uint64_t qos:3; -+ uint64_t reserved_19_19:1; -+ uint64_t match_type:3; -+ uint64_t match_value:16; -+ } s; -+ struct cvmx_pip_qos_watchx_cn30xx { -+ uint64_t reserved_48_63:16; -+ uint64_t mask:16; -+ uint64_t reserved_28_31:4; -+ uint64_t grp:4; -+ uint64_t reserved_23_23:1; -+ uint64_t qos:3; -+ uint64_t reserved_18_19:2; -+ uint64_t match_type:2; -+ uint64_t match_value:16; -+ } cn30xx; -+ struct cvmx_pip_qos_watchx_cn30xx cn31xx; -+ struct cvmx_pip_qos_watchx_cn30xx cn38xx; -+ struct cvmx_pip_qos_watchx_cn30xx cn38xxp2; -+ struct cvmx_pip_qos_watchx_s cn50xx; -+ struct cvmx_pip_qos_watchx_s cn52xx; -+ struct cvmx_pip_qos_watchx_s cn52xxp1; -+ struct cvmx_pip_qos_watchx_s cn56xx; -+ struct cvmx_pip_qos_watchx_s cn56xxp1; -+ struct cvmx_pip_qos_watchx_cn30xx cn58xx; -+ struct cvmx_pip_qos_watchx_cn30xx cn58xxp1; -+}; -+ -+union cvmx_pip_raw_word { -+ uint64_t u64; -+ struct cvmx_pip_raw_word_s { -+ uint64_t reserved_56_63:8; -+ uint64_t word:56; -+ } s; -+ struct cvmx_pip_raw_word_s cn30xx; -+ struct cvmx_pip_raw_word_s cn31xx; -+ struct cvmx_pip_raw_word_s cn38xx; -+ struct cvmx_pip_raw_word_s cn38xxp2; -+ struct cvmx_pip_raw_word_s cn50xx; -+ struct cvmx_pip_raw_word_s cn52xx; -+ struct cvmx_pip_raw_word_s cn52xxp1; -+ struct cvmx_pip_raw_word_s cn56xx; -+ struct cvmx_pip_raw_word_s cn56xxp1; -+ struct cvmx_pip_raw_word_s cn58xx; -+ struct cvmx_pip_raw_word_s cn58xxp1; -+}; -+ -+union cvmx_pip_sft_rst { -+ uint64_t u64; -+ struct cvmx_pip_sft_rst_s { -+ uint64_t reserved_1_63:63; -+ uint64_t rst:1; -+ } s; -+ struct cvmx_pip_sft_rst_s cn30xx; -+ struct cvmx_pip_sft_rst_s cn31xx; -+ struct cvmx_pip_sft_rst_s cn38xx; -+ struct cvmx_pip_sft_rst_s cn50xx; -+ struct cvmx_pip_sft_rst_s cn52xx; -+ struct cvmx_pip_sft_rst_s cn52xxp1; -+ struct cvmx_pip_sft_rst_s cn56xx; -+ struct cvmx_pip_sft_rst_s cn56xxp1; -+ struct cvmx_pip_sft_rst_s cn58xx; -+ struct cvmx_pip_sft_rst_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat0_prtx { -+ uint64_t u64; -+ struct cvmx_pip_stat0_prtx_s { -+ uint64_t drp_pkts:32; -+ uint64_t drp_octs:32; -+ } s; -+ struct cvmx_pip_stat0_prtx_s cn30xx; -+ struct cvmx_pip_stat0_prtx_s cn31xx; -+ struct cvmx_pip_stat0_prtx_s cn38xx; -+ struct cvmx_pip_stat0_prtx_s cn38xxp2; -+ struct cvmx_pip_stat0_prtx_s cn50xx; -+ struct cvmx_pip_stat0_prtx_s cn52xx; -+ struct cvmx_pip_stat0_prtx_s cn52xxp1; -+ struct cvmx_pip_stat0_prtx_s cn56xx; -+ struct cvmx_pip_stat0_prtx_s cn56xxp1; -+ struct cvmx_pip_stat0_prtx_s cn58xx; -+ struct cvmx_pip_stat0_prtx_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat1_prtx { -+ uint64_t u64; -+ struct cvmx_pip_stat1_prtx_s { -+ uint64_t reserved_48_63:16; -+ uint64_t octs:48; -+ } s; -+ struct cvmx_pip_stat1_prtx_s cn30xx; -+ struct cvmx_pip_stat1_prtx_s cn31xx; -+ struct cvmx_pip_stat1_prtx_s cn38xx; -+ struct cvmx_pip_stat1_prtx_s cn38xxp2; -+ struct cvmx_pip_stat1_prtx_s cn50xx; -+ struct cvmx_pip_stat1_prtx_s cn52xx; -+ struct cvmx_pip_stat1_prtx_s cn52xxp1; -+ struct cvmx_pip_stat1_prtx_s cn56xx; -+ struct cvmx_pip_stat1_prtx_s cn56xxp1; -+ struct cvmx_pip_stat1_prtx_s cn58xx; -+ struct cvmx_pip_stat1_prtx_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat2_prtx { -+ uint64_t u64; -+ struct cvmx_pip_stat2_prtx_s { -+ uint64_t pkts:32; -+ uint64_t raw:32; -+ } s; -+ struct cvmx_pip_stat2_prtx_s cn30xx; -+ struct cvmx_pip_stat2_prtx_s cn31xx; -+ struct cvmx_pip_stat2_prtx_s cn38xx; -+ struct cvmx_pip_stat2_prtx_s cn38xxp2; -+ struct cvmx_pip_stat2_prtx_s cn50xx; -+ struct cvmx_pip_stat2_prtx_s cn52xx; -+ struct cvmx_pip_stat2_prtx_s cn52xxp1; -+ struct cvmx_pip_stat2_prtx_s cn56xx; -+ struct cvmx_pip_stat2_prtx_s cn56xxp1; -+ struct cvmx_pip_stat2_prtx_s cn58xx; -+ struct cvmx_pip_stat2_prtx_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat3_prtx { -+ uint64_t u64; -+ struct cvmx_pip_stat3_prtx_s { -+ uint64_t bcst:32; -+ uint64_t mcst:32; -+ } s; -+ struct cvmx_pip_stat3_prtx_s cn30xx; -+ struct cvmx_pip_stat3_prtx_s cn31xx; -+ struct cvmx_pip_stat3_prtx_s cn38xx; -+ struct cvmx_pip_stat3_prtx_s cn38xxp2; -+ struct cvmx_pip_stat3_prtx_s cn50xx; -+ struct cvmx_pip_stat3_prtx_s cn52xx; -+ struct cvmx_pip_stat3_prtx_s cn52xxp1; -+ struct cvmx_pip_stat3_prtx_s cn56xx; -+ struct cvmx_pip_stat3_prtx_s cn56xxp1; -+ struct cvmx_pip_stat3_prtx_s cn58xx; -+ struct cvmx_pip_stat3_prtx_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat4_prtx { -+ uint64_t u64; -+ struct cvmx_pip_stat4_prtx_s { -+ uint64_t h65to127:32; -+ uint64_t h64:32; -+ } s; -+ struct cvmx_pip_stat4_prtx_s cn30xx; -+ struct cvmx_pip_stat4_prtx_s cn31xx; -+ struct cvmx_pip_stat4_prtx_s cn38xx; -+ struct cvmx_pip_stat4_prtx_s cn38xxp2; -+ struct cvmx_pip_stat4_prtx_s cn50xx; -+ struct cvmx_pip_stat4_prtx_s cn52xx; -+ struct cvmx_pip_stat4_prtx_s cn52xxp1; -+ struct cvmx_pip_stat4_prtx_s cn56xx; -+ struct cvmx_pip_stat4_prtx_s cn56xxp1; -+ struct cvmx_pip_stat4_prtx_s cn58xx; -+ struct cvmx_pip_stat4_prtx_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat5_prtx { -+ uint64_t u64; -+ struct cvmx_pip_stat5_prtx_s { -+ uint64_t h256to511:32; -+ uint64_t h128to255:32; -+ } s; -+ struct cvmx_pip_stat5_prtx_s cn30xx; -+ struct cvmx_pip_stat5_prtx_s cn31xx; -+ struct cvmx_pip_stat5_prtx_s cn38xx; -+ struct cvmx_pip_stat5_prtx_s cn38xxp2; -+ struct cvmx_pip_stat5_prtx_s cn50xx; -+ struct cvmx_pip_stat5_prtx_s cn52xx; -+ struct cvmx_pip_stat5_prtx_s cn52xxp1; -+ struct cvmx_pip_stat5_prtx_s cn56xx; -+ struct cvmx_pip_stat5_prtx_s cn56xxp1; -+ struct cvmx_pip_stat5_prtx_s cn58xx; -+ struct cvmx_pip_stat5_prtx_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat6_prtx { -+ uint64_t u64; -+ struct cvmx_pip_stat6_prtx_s { -+ uint64_t h1024to1518:32; -+ uint64_t h512to1023:32; -+ } s; -+ struct cvmx_pip_stat6_prtx_s cn30xx; -+ struct cvmx_pip_stat6_prtx_s cn31xx; -+ struct cvmx_pip_stat6_prtx_s cn38xx; -+ struct cvmx_pip_stat6_prtx_s cn38xxp2; -+ struct cvmx_pip_stat6_prtx_s cn50xx; -+ struct cvmx_pip_stat6_prtx_s cn52xx; -+ struct cvmx_pip_stat6_prtx_s cn52xxp1; -+ struct cvmx_pip_stat6_prtx_s cn56xx; -+ struct cvmx_pip_stat6_prtx_s cn56xxp1; -+ struct cvmx_pip_stat6_prtx_s cn58xx; -+ struct cvmx_pip_stat6_prtx_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat7_prtx { -+ uint64_t u64; -+ struct cvmx_pip_stat7_prtx_s { -+ uint64_t fcs:32; -+ uint64_t h1519:32; -+ } s; -+ struct cvmx_pip_stat7_prtx_s cn30xx; -+ struct cvmx_pip_stat7_prtx_s cn31xx; -+ struct cvmx_pip_stat7_prtx_s cn38xx; -+ struct cvmx_pip_stat7_prtx_s cn38xxp2; -+ struct cvmx_pip_stat7_prtx_s cn50xx; -+ struct cvmx_pip_stat7_prtx_s cn52xx; -+ struct cvmx_pip_stat7_prtx_s cn52xxp1; -+ struct cvmx_pip_stat7_prtx_s cn56xx; -+ struct cvmx_pip_stat7_prtx_s cn56xxp1; -+ struct cvmx_pip_stat7_prtx_s cn58xx; -+ struct cvmx_pip_stat7_prtx_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat8_prtx { -+ uint64_t u64; -+ struct cvmx_pip_stat8_prtx_s { -+ uint64_t frag:32; -+ uint64_t undersz:32; -+ } s; -+ struct cvmx_pip_stat8_prtx_s cn30xx; -+ struct cvmx_pip_stat8_prtx_s cn31xx; -+ struct cvmx_pip_stat8_prtx_s cn38xx; -+ struct cvmx_pip_stat8_prtx_s cn38xxp2; -+ struct cvmx_pip_stat8_prtx_s cn50xx; -+ struct cvmx_pip_stat8_prtx_s cn52xx; -+ struct cvmx_pip_stat8_prtx_s cn52xxp1; -+ struct cvmx_pip_stat8_prtx_s cn56xx; -+ struct cvmx_pip_stat8_prtx_s cn56xxp1; -+ struct cvmx_pip_stat8_prtx_s cn58xx; -+ struct cvmx_pip_stat8_prtx_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat9_prtx { -+ uint64_t u64; -+ struct cvmx_pip_stat9_prtx_s { -+ uint64_t jabber:32; -+ uint64_t oversz:32; -+ } s; -+ struct cvmx_pip_stat9_prtx_s cn30xx; -+ struct cvmx_pip_stat9_prtx_s cn31xx; -+ struct cvmx_pip_stat9_prtx_s cn38xx; -+ struct cvmx_pip_stat9_prtx_s cn38xxp2; -+ struct cvmx_pip_stat9_prtx_s cn50xx; -+ struct cvmx_pip_stat9_prtx_s cn52xx; -+ struct cvmx_pip_stat9_prtx_s cn52xxp1; -+ struct cvmx_pip_stat9_prtx_s cn56xx; -+ struct cvmx_pip_stat9_prtx_s cn56xxp1; -+ struct cvmx_pip_stat9_prtx_s cn58xx; -+ struct cvmx_pip_stat9_prtx_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat_ctl { -+ uint64_t u64; -+ struct cvmx_pip_stat_ctl_s { -+ uint64_t reserved_1_63:63; -+ uint64_t rdclr:1; -+ } s; -+ struct cvmx_pip_stat_ctl_s cn30xx; -+ struct cvmx_pip_stat_ctl_s cn31xx; -+ struct cvmx_pip_stat_ctl_s cn38xx; -+ struct cvmx_pip_stat_ctl_s cn38xxp2; -+ struct cvmx_pip_stat_ctl_s cn50xx; -+ struct cvmx_pip_stat_ctl_s cn52xx; -+ struct cvmx_pip_stat_ctl_s cn52xxp1; -+ struct cvmx_pip_stat_ctl_s cn56xx; -+ struct cvmx_pip_stat_ctl_s cn56xxp1; -+ struct cvmx_pip_stat_ctl_s cn58xx; -+ struct cvmx_pip_stat_ctl_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat_inb_errsx { -+ uint64_t u64; -+ struct cvmx_pip_stat_inb_errsx_s { -+ uint64_t reserved_16_63:48; -+ uint64_t errs:16; -+ } s; -+ struct cvmx_pip_stat_inb_errsx_s cn30xx; -+ struct cvmx_pip_stat_inb_errsx_s cn31xx; -+ struct cvmx_pip_stat_inb_errsx_s cn38xx; -+ struct cvmx_pip_stat_inb_errsx_s cn38xxp2; -+ struct cvmx_pip_stat_inb_errsx_s cn50xx; -+ struct cvmx_pip_stat_inb_errsx_s cn52xx; -+ struct cvmx_pip_stat_inb_errsx_s cn52xxp1; -+ struct cvmx_pip_stat_inb_errsx_s cn56xx; -+ struct cvmx_pip_stat_inb_errsx_s cn56xxp1; -+ struct cvmx_pip_stat_inb_errsx_s cn58xx; -+ struct cvmx_pip_stat_inb_errsx_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat_inb_octsx { -+ uint64_t u64; -+ struct cvmx_pip_stat_inb_octsx_s { -+ uint64_t reserved_48_63:16; -+ uint64_t octs:48; -+ } s; -+ struct cvmx_pip_stat_inb_octsx_s cn30xx; -+ struct cvmx_pip_stat_inb_octsx_s cn31xx; -+ struct cvmx_pip_stat_inb_octsx_s cn38xx; -+ struct cvmx_pip_stat_inb_octsx_s cn38xxp2; -+ struct cvmx_pip_stat_inb_octsx_s cn50xx; -+ struct cvmx_pip_stat_inb_octsx_s cn52xx; -+ struct cvmx_pip_stat_inb_octsx_s cn52xxp1; -+ struct cvmx_pip_stat_inb_octsx_s cn56xx; -+ struct cvmx_pip_stat_inb_octsx_s cn56xxp1; -+ struct cvmx_pip_stat_inb_octsx_s cn58xx; -+ struct cvmx_pip_stat_inb_octsx_s cn58xxp1; -+}; -+ -+union cvmx_pip_stat_inb_pktsx { -+ uint64_t u64; -+ struct cvmx_pip_stat_inb_pktsx_s { -+ uint64_t reserved_32_63:32; -+ uint64_t pkts:32; -+ } s; -+ struct cvmx_pip_stat_inb_pktsx_s cn30xx; -+ struct cvmx_pip_stat_inb_pktsx_s cn31xx; -+ struct cvmx_pip_stat_inb_pktsx_s cn38xx; -+ struct cvmx_pip_stat_inb_pktsx_s cn38xxp2; -+ struct cvmx_pip_stat_inb_pktsx_s cn50xx; -+ struct cvmx_pip_stat_inb_pktsx_s cn52xx; -+ struct cvmx_pip_stat_inb_pktsx_s cn52xxp1; -+ struct cvmx_pip_stat_inb_pktsx_s cn56xx; -+ struct cvmx_pip_stat_inb_pktsx_s cn56xxp1; -+ struct cvmx_pip_stat_inb_pktsx_s cn58xx; -+ struct cvmx_pip_stat_inb_pktsx_s cn58xxp1; -+}; -+ -+union cvmx_pip_tag_incx { -+ uint64_t u64; -+ struct cvmx_pip_tag_incx_s { -+ uint64_t reserved_8_63:56; -+ uint64_t en:8; -+ } s; -+ struct cvmx_pip_tag_incx_s cn30xx; -+ struct cvmx_pip_tag_incx_s cn31xx; -+ struct cvmx_pip_tag_incx_s cn38xx; -+ struct cvmx_pip_tag_incx_s cn38xxp2; -+ struct cvmx_pip_tag_incx_s cn50xx; -+ struct cvmx_pip_tag_incx_s cn52xx; -+ struct cvmx_pip_tag_incx_s cn52xxp1; -+ struct cvmx_pip_tag_incx_s cn56xx; -+ struct cvmx_pip_tag_incx_s cn56xxp1; -+ struct cvmx_pip_tag_incx_s cn58xx; -+ struct cvmx_pip_tag_incx_s cn58xxp1; -+}; -+ -+union cvmx_pip_tag_mask { -+ uint64_t u64; -+ struct cvmx_pip_tag_mask_s { -+ uint64_t reserved_16_63:48; -+ uint64_t mask:16; -+ } s; -+ struct cvmx_pip_tag_mask_s cn30xx; -+ struct cvmx_pip_tag_mask_s cn31xx; -+ struct cvmx_pip_tag_mask_s cn38xx; -+ struct cvmx_pip_tag_mask_s cn38xxp2; -+ struct cvmx_pip_tag_mask_s cn50xx; -+ struct cvmx_pip_tag_mask_s cn52xx; -+ struct cvmx_pip_tag_mask_s cn52xxp1; -+ struct cvmx_pip_tag_mask_s cn56xx; -+ struct cvmx_pip_tag_mask_s cn56xxp1; -+ struct cvmx_pip_tag_mask_s cn58xx; -+ struct cvmx_pip_tag_mask_s cn58xxp1; -+}; -+ -+union cvmx_pip_tag_secret { -+ uint64_t u64; -+ struct cvmx_pip_tag_secret_s { -+ uint64_t reserved_32_63:32; -+ uint64_t dst:16; -+ uint64_t src:16; -+ } s; -+ struct cvmx_pip_tag_secret_s cn30xx; -+ struct cvmx_pip_tag_secret_s cn31xx; -+ struct cvmx_pip_tag_secret_s cn38xx; -+ struct cvmx_pip_tag_secret_s cn38xxp2; -+ struct cvmx_pip_tag_secret_s cn50xx; -+ struct cvmx_pip_tag_secret_s cn52xx; -+ struct cvmx_pip_tag_secret_s cn52xxp1; -+ struct cvmx_pip_tag_secret_s cn56xx; -+ struct cvmx_pip_tag_secret_s cn56xxp1; -+ struct cvmx_pip_tag_secret_s cn58xx; -+ struct cvmx_pip_tag_secret_s cn58xxp1; -+}; -+ -+union cvmx_pip_todo_entry { -+ uint64_t u64; -+ struct cvmx_pip_todo_entry_s { -+ uint64_t val:1; -+ uint64_t reserved_62_62:1; -+ uint64_t entry:62; -+ } s; -+ struct cvmx_pip_todo_entry_s cn30xx; -+ struct cvmx_pip_todo_entry_s cn31xx; -+ struct cvmx_pip_todo_entry_s cn38xx; -+ struct cvmx_pip_todo_entry_s cn38xxp2; -+ struct cvmx_pip_todo_entry_s cn50xx; -+ struct cvmx_pip_todo_entry_s cn52xx; -+ struct cvmx_pip_todo_entry_s cn52xxp1; -+ struct cvmx_pip_todo_entry_s cn56xx; -+ struct cvmx_pip_todo_entry_s cn56xxp1; -+ struct cvmx_pip_todo_entry_s cn58xx; -+ struct cvmx_pip_todo_entry_s cn58xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-pip.h -@@ -0,0 +1,524 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * Interface to the hardware Packet Input Processing unit. -+ * -+ */ -+ -+#ifndef __CVMX_PIP_H__ -+#define __CVMX_PIP_H__ -+ -+#include "cvmx-wqe.h" -+#include "cvmx-fpa.h" -+#include "cvmx-pip-defs.h" -+ -+#define CVMX_PIP_NUM_INPUT_PORTS 40 -+#define CVMX_PIP_NUM_WATCHERS 4 -+ -+/* -+ * Encodes the different error and exception codes -+ */ -+typedef enum { -+ CVMX_PIP_L4_NO_ERR = 0ull, -+ /* -+ * 1 = TCP (UDP) packet not long enough to cover TCP (UDP) -+ * header -+ */ -+ CVMX_PIP_L4_MAL_ERR = 1ull, -+ /* 2 = TCP/UDP checksum failure */ -+ CVMX_PIP_CHK_ERR = 2ull, -+ /* -+ * 3 = TCP/UDP length check (TCP/UDP length does not match IP -+ * length). -+ */ -+ CVMX_PIP_L4_LENGTH_ERR = 3ull, -+ /* 4 = illegal TCP/UDP port (either source or dest port is zero) */ -+ CVMX_PIP_BAD_PRT_ERR = 4ull, -+ /* 8 = TCP flags = FIN only */ -+ CVMX_PIP_TCP_FLG8_ERR = 8ull, -+ /* 9 = TCP flags = 0 */ -+ CVMX_PIP_TCP_FLG9_ERR = 9ull, -+ /* 10 = TCP flags = FIN+RST+* */ -+ CVMX_PIP_TCP_FLG10_ERR = 10ull, -+ /* 11 = TCP flags = SYN+URG+* */ -+ CVMX_PIP_TCP_FLG11_ERR = 11ull, -+ /* 12 = TCP flags = SYN+RST+* */ -+ CVMX_PIP_TCP_FLG12_ERR = 12ull, -+ /* 13 = TCP flags = SYN+FIN+* */ -+ CVMX_PIP_TCP_FLG13_ERR = 13ull -+} cvmx_pip_l4_err_t; -+ -+typedef enum { -+ -+ CVMX_PIP_IP_NO_ERR = 0ull, -+ /* 1 = not IPv4 or IPv6 */ -+ CVMX_PIP_NOT_IP = 1ull, -+ /* 2 = IPv4 header checksum violation */ -+ CVMX_PIP_IPV4_HDR_CHK = 2ull, -+ /* 3 = malformed (packet not long enough to cover IP hdr) */ -+ CVMX_PIP_IP_MAL_HDR = 3ull, -+ /* 4 = malformed (packet not long enough to cover len in IP hdr) */ -+ CVMX_PIP_IP_MAL_PKT = 4ull, -+ /* 5 = TTL / hop count equal zero */ -+ CVMX_PIP_TTL_HOP = 5ull, -+ /* 6 = IPv4 options / IPv6 early extension headers */ -+ CVMX_PIP_OPTS = 6ull -+} cvmx_pip_ip_exc_t; -+ -+/** -+ * NOTES -+ * late collision (data received before collision) -+ * late collisions cannot be detected by the receiver -+ * they would appear as JAM bits which would appear as bad FCS -+ * or carrier extend error which is CVMX_PIP_EXTEND_ERR -+ */ -+typedef enum { -+ /* No error */ -+ CVMX_PIP_RX_NO_ERR = 0ull, -+ /* RGM+SPI 1 = partially received packet (buffering/bandwidth -+ * not adequate) */ -+ CVMX_PIP_PARTIAL_ERR = 1ull, -+ /* RGM+SPI 2 = receive packet too large and truncated */ -+ CVMX_PIP_JABBER_ERR = 2ull, -+ /* -+ * RGM 3 = max frame error (pkt len > max frame len) (with FCS -+ * error) -+ */ -+ CVMX_PIP_OVER_FCS_ERR = 3ull, -+ /* RGM+SPI 4 = max frame error (pkt len > max frame len) */ -+ CVMX_PIP_OVER_ERR = 4ull, -+ /* -+ * RGM 5 = nibble error (data not byte multiple - 100M and 10M -+ * only) -+ */ -+ CVMX_PIP_ALIGN_ERR = 5ull, -+ /* -+ * RGM 6 = min frame error (pkt len < min frame len) (with FCS -+ * error) -+ */ -+ CVMX_PIP_UNDER_FCS_ERR = 6ull, -+ /* RGM 7 = FCS error */ -+ CVMX_PIP_GMX_FCS_ERR = 7ull, -+ /* RGM+SPI 8 = min frame error (pkt len < min frame len) */ -+ CVMX_PIP_UNDER_ERR = 8ull, -+ /* RGM 9 = Frame carrier extend error */ -+ CVMX_PIP_EXTEND_ERR = 9ull, -+ /* -+ * RGM 10 = length mismatch (len did not match len in L2 -+ * length/type) -+ */ -+ CVMX_PIP_LENGTH_ERR = 10ull, -+ /* RGM 11 = Frame error (some or all data bits marked err) */ -+ CVMX_PIP_DAT_ERR = 11ull, -+ /* SPI 11 = DIP4 error */ -+ CVMX_PIP_DIP_ERR = 11ull, -+ /* -+ * RGM 12 = packet was not large enough to pass the skipper - -+ * no inspection could occur. -+ */ -+ CVMX_PIP_SKIP_ERR = 12ull, -+ /* -+ * RGM 13 = studder error (data not repeated - 100M and 10M -+ * only) -+ */ -+ CVMX_PIP_NIBBLE_ERR = 13ull, -+ /* RGM+SPI 16 = FCS error */ -+ CVMX_PIP_PIP_FCS = 16L, -+ /* -+ * RGM+SPI+PCI 17 = packet was not large enough to pass the -+ * skipper - no inspection could occur. -+ */ -+ CVMX_PIP_PIP_SKIP_ERR = 17L, -+ /* -+ * RGM+SPI+PCI 18 = malformed l2 (packet not long enough to -+ * cover L2 hdr). -+ */ -+ CVMX_PIP_PIP_L2_MAL_HDR = 18L -+ /* -+ * NOTES: xx = late collision (data received before collision) -+ * late collisions cannot be detected by the receiver -+ * they would appear as JAM bits which would appear as -+ * bad FCS or carrier extend error which is -+ * CVMX_PIP_EXTEND_ERR -+ */ -+} cvmx_pip_rcv_err_t; -+ -+/** -+ * This defines the err_code field errors in the work Q entry -+ */ -+typedef union { -+ cvmx_pip_l4_err_t l4_err; -+ cvmx_pip_ip_exc_t ip_exc; -+ cvmx_pip_rcv_err_t rcv_err; -+} cvmx_pip_err_t; -+ -+/** -+ * Status statistics for a port -+ */ -+typedef struct { -+ /* Inbound octets marked to be dropped by the IPD */ -+ uint32_t dropped_octets; -+ /* Inbound packets marked to be dropped by the IPD */ -+ uint32_t dropped_packets; -+ /* RAW PCI Packets received by PIP per port */ -+ uint32_t pci_raw_packets; -+ /* Number of octets processed by PIP */ -+ uint32_t octets; -+ /* Number of packets processed by PIP */ -+ uint32_t packets; -+ /* -+ * Number of indentified L2 multicast packets. Does not -+ * include broadcast packets. Only includes packets whose -+ * parse mode is SKIP_TO_L2 -+ */ -+ uint32_t multicast_packets; -+ /* -+ * Number of indentified L2 broadcast packets. Does not -+ * include multicast packets. Only includes packets whose -+ * parse mode is SKIP_TO_L2 -+ */ -+ uint32_t broadcast_packets; -+ /* Number of 64B packets */ -+ uint32_t len_64_packets; -+ /* Number of 65-127B packets */ -+ uint32_t len_65_127_packets; -+ /* Number of 128-255B packets */ -+ uint32_t len_128_255_packets; -+ /* Number of 256-511B packets */ -+ uint32_t len_256_511_packets; -+ /* Number of 512-1023B packets */ -+ uint32_t len_512_1023_packets; -+ /* Number of 1024-1518B packets */ -+ uint32_t len_1024_1518_packets; -+ /* Number of 1519-max packets */ -+ uint32_t len_1519_max_packets; -+ /* Number of packets with FCS or Align opcode errors */ -+ uint32_t fcs_align_err_packets; -+ /* Number of packets with length < min */ -+ uint32_t runt_packets; -+ /* Number of packets with length < min and FCS error */ -+ uint32_t runt_crc_packets; -+ /* Number of packets with length > max */ -+ uint32_t oversize_packets; -+ /* Number of packets with length > max and FCS error */ -+ uint32_t oversize_crc_packets; -+ /* Number of packets without GMX/SPX/PCI errors received by PIP */ -+ uint32_t inb_packets; -+ /* -+ * Total number of octets from all packets received by PIP, -+ * including CRC -+ */ -+ uint64_t inb_octets; -+ /* Number of packets with GMX/SPX/PCI errors received by PIP */ -+ uint16_t inb_errors; -+} cvmx_pip_port_status_t; -+ -+/** -+ * Definition of the PIP custom header that can be prepended -+ * to a packet by external hardware. -+ */ -+typedef union { -+ uint64_t u64; -+ struct { -+ /* -+ * Documented as R - Set if the Packet is RAWFULL. If -+ * set, this header must be the full 8 bytes. -+ */ -+ uint64_t rawfull:1; -+ /* Must be zero */ -+ uint64_t reserved0:5; -+ /* PIP parse mode for this packet */ -+ uint64_t parse_mode:2; -+ /* Must be zero */ -+ uint64_t reserved1:1; -+ /* -+ * Skip amount, including this header, to the -+ * beginning of the packet -+ */ -+ uint64_t skip_len:7; -+ /* Must be zero */ -+ uint64_t reserved2:6; -+ /* POW input queue for this packet */ -+ uint64_t qos:3; -+ /* POW input group for this packet */ -+ uint64_t grp:4; -+ /* -+ * Flag to store this packet in the work queue entry, -+ * if possible -+ */ -+ uint64_t rs:1; -+ /* POW input tag type */ -+ uint64_t tag_type:2; -+ /* POW input tag */ -+ uint64_t tag:32; -+ } s; -+} cvmx_pip_pkt_inst_hdr_t; -+ -+/* CSR typedefs have been moved to cvmx-csr-*.h */ -+ -+/** -+ * Configure an ethernet input port -+ * -+ * @port_num: Port number to configure -+ * @port_cfg: Port hardware configuration -+ * @port_tag_cfg: -+ * Port POW tagging configuration -+ */ -+static inline void cvmx_pip_config_port(uint64_t port_num, -+ union cvmx_pip_prt_cfgx port_cfg, -+ union cvmx_pip_prt_tagx port_tag_cfg) -+{ -+ cvmx_write_csr(CVMX_PIP_PRT_CFGX(port_num), port_cfg.u64); -+ cvmx_write_csr(CVMX_PIP_PRT_TAGX(port_num), port_tag_cfg.u64); -+} -+#if 0 -+/** -+ * @deprecated This function is a thin wrapper around the Pass1 version -+ * of the CVMX_PIP_QOS_WATCHX CSR; Pass2 has added a field for -+ * setting the group that is incompatible with this function, -+ * the preferred upgrade path is to use the CSR directly. -+ * -+ * Configure the global QoS packet watchers. Each watcher is -+ * capable of matching a field in a packet to determine the -+ * QoS queue for scheduling. -+ * -+ * @watcher: Watcher number to configure (0 - 3). -+ * @match_type: Watcher match type -+ * @match_value: -+ * Value the watcher will match against -+ * @qos: QoS queue for packets matching this watcher -+ */ -+static inline void cvmx_pip_config_watcher(uint64_t watcher, -+ cvmx_pip_qos_watch_types match_type, -+ uint64_t match_value, uint64_t qos) -+{ -+ cvmx_pip_port_watcher_cfg_t watcher_config; -+ -+ watcher_config.u64 = 0; -+ watcher_config.s.match_type = match_type; -+ watcher_config.s.match_value = match_value; -+ watcher_config.s.qos = qos; -+ -+ cvmx_write_csr(CVMX_PIP_QOS_WATCHX(watcher), watcher_config.u64); -+} -+#endif -+/** -+ * Configure the VLAN priority to QoS queue mapping. -+ * -+ * @vlan_priority: -+ * VLAN priority (0-7) -+ * @qos: QoS queue for packets matching this watcher -+ */ -+static inline void cvmx_pip_config_vlan_qos(uint64_t vlan_priority, -+ uint64_t qos) -+{ -+ union cvmx_pip_qos_vlanx pip_qos_vlanx; -+ pip_qos_vlanx.u64 = 0; -+ pip_qos_vlanx.s.qos = qos; -+ cvmx_write_csr(CVMX_PIP_QOS_VLANX(vlan_priority), pip_qos_vlanx.u64); -+} -+ -+/** -+ * Configure the Diffserv to QoS queue mapping. -+ * -+ * @diffserv: Diffserv field value (0-63) -+ * @qos: QoS queue for packets matching this watcher -+ */ -+static inline void cvmx_pip_config_diffserv_qos(uint64_t diffserv, uint64_t qos) -+{ -+ union cvmx_pip_qos_diffx pip_qos_diffx; -+ pip_qos_diffx.u64 = 0; -+ pip_qos_diffx.s.qos = qos; -+ cvmx_write_csr(CVMX_PIP_QOS_DIFFX(diffserv), pip_qos_diffx.u64); -+} -+ -+/** -+ * Get the status counters for a port. -+ * -+ * @port_num: Port number to get statistics for. -+ * @clear: Set to 1 to clear the counters after they are read -+ * @status: Where to put the results. -+ */ -+static inline void cvmx_pip_get_port_status(uint64_t port_num, uint64_t clear, -+ cvmx_pip_port_status_t *status) -+{ -+ union cvmx_pip_stat_ctl pip_stat_ctl; -+ union cvmx_pip_stat0_prtx stat0; -+ union cvmx_pip_stat1_prtx stat1; -+ union cvmx_pip_stat2_prtx stat2; -+ union cvmx_pip_stat3_prtx stat3; -+ union cvmx_pip_stat4_prtx stat4; -+ union cvmx_pip_stat5_prtx stat5; -+ union cvmx_pip_stat6_prtx stat6; -+ union cvmx_pip_stat7_prtx stat7; -+ union cvmx_pip_stat8_prtx stat8; -+ union cvmx_pip_stat9_prtx stat9; -+ union cvmx_pip_stat_inb_pktsx pip_stat_inb_pktsx; -+ union cvmx_pip_stat_inb_octsx pip_stat_inb_octsx; -+ union cvmx_pip_stat_inb_errsx pip_stat_inb_errsx; -+ -+ pip_stat_ctl.u64 = 0; -+ pip_stat_ctl.s.rdclr = clear; -+ cvmx_write_csr(CVMX_PIP_STAT_CTL, pip_stat_ctl.u64); -+ -+ stat0.u64 = cvmx_read_csr(CVMX_PIP_STAT0_PRTX(port_num)); -+ stat1.u64 = cvmx_read_csr(CVMX_PIP_STAT1_PRTX(port_num)); -+ stat2.u64 = cvmx_read_csr(CVMX_PIP_STAT2_PRTX(port_num)); -+ stat3.u64 = cvmx_read_csr(CVMX_PIP_STAT3_PRTX(port_num)); -+ stat4.u64 = cvmx_read_csr(CVMX_PIP_STAT4_PRTX(port_num)); -+ stat5.u64 = cvmx_read_csr(CVMX_PIP_STAT5_PRTX(port_num)); -+ stat6.u64 = cvmx_read_csr(CVMX_PIP_STAT6_PRTX(port_num)); -+ stat7.u64 = cvmx_read_csr(CVMX_PIP_STAT7_PRTX(port_num)); -+ stat8.u64 = cvmx_read_csr(CVMX_PIP_STAT8_PRTX(port_num)); -+ stat9.u64 = cvmx_read_csr(CVMX_PIP_STAT9_PRTX(port_num)); -+ pip_stat_inb_pktsx.u64 = -+ cvmx_read_csr(CVMX_PIP_STAT_INB_PKTSX(port_num)); -+ pip_stat_inb_octsx.u64 = -+ cvmx_read_csr(CVMX_PIP_STAT_INB_OCTSX(port_num)); -+ pip_stat_inb_errsx.u64 = -+ cvmx_read_csr(CVMX_PIP_STAT_INB_ERRSX(port_num)); -+ -+ status->dropped_octets = stat0.s.drp_octs; -+ status->dropped_packets = stat0.s.drp_pkts; -+ status->octets = stat1.s.octs; -+ status->pci_raw_packets = stat2.s.raw; -+ status->packets = stat2.s.pkts; -+ status->multicast_packets = stat3.s.mcst; -+ status->broadcast_packets = stat3.s.bcst; -+ status->len_64_packets = stat4.s.h64; -+ status->len_65_127_packets = stat4.s.h65to127; -+ status->len_128_255_packets = stat5.s.h128to255; -+ status->len_256_511_packets = stat5.s.h256to511; -+ status->len_512_1023_packets = stat6.s.h512to1023; -+ status->len_1024_1518_packets = stat6.s.h1024to1518; -+ status->len_1519_max_packets = stat7.s.h1519; -+ status->fcs_align_err_packets = stat7.s.fcs; -+ status->runt_packets = stat8.s.undersz; -+ status->runt_crc_packets = stat8.s.frag; -+ status->oversize_packets = stat9.s.oversz; -+ status->oversize_crc_packets = stat9.s.jabber; -+ status->inb_packets = pip_stat_inb_pktsx.s.pkts; -+ status->inb_octets = pip_stat_inb_octsx.s.octs; -+ status->inb_errors = pip_stat_inb_errsx.s.errs; -+ -+ if (cvmx_octeon_is_pass1()) { -+ /* -+ * Kludge to fix Octeon Pass 1 errata - Drop counts -+ * don't work. -+ */ -+ if (status->inb_packets > status->packets) -+ status->dropped_packets = -+ status->inb_packets - status->packets; -+ else -+ status->dropped_packets = 0; -+ if (status->inb_octets - status->inb_packets * 4 > -+ status->octets) -+ status->dropped_octets = -+ status->inb_octets - status->inb_packets * 4 - -+ status->octets; -+ else -+ status->dropped_octets = 0; -+ } -+} -+ -+/** -+ * Configure the hardware CRC engine -+ * -+ * @interface: Interface to configure (0 or 1) -+ * @invert_result: -+ * Invert the result of the CRC -+ * @reflect: Reflect -+ * @initialization_vector: -+ * CRC initialization vector -+ */ -+static inline void cvmx_pip_config_crc(uint64_t interface, -+ uint64_t invert_result, uint64_t reflect, -+ uint32_t initialization_vector) -+{ -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) { -+ union cvmx_pip_crc_ctlx config; -+ union cvmx_pip_crc_ivx pip_crc_ivx; -+ -+ config.u64 = 0; -+ config.s.invres = invert_result; -+ config.s.reflect = reflect; -+ cvmx_write_csr(CVMX_PIP_CRC_CTLX(interface), config.u64); -+ -+ pip_crc_ivx.u64 = 0; -+ pip_crc_ivx.s.iv = initialization_vector; -+ cvmx_write_csr(CVMX_PIP_CRC_IVX(interface), pip_crc_ivx.u64); -+ } -+} -+ -+/** -+ * Clear all bits in a tag mask. This should be called on -+ * startup before any calls to cvmx_pip_tag_mask_set. Each bit -+ * set in the final mask represent a byte used in the packet for -+ * tag generation. -+ * -+ * @mask_index: Which tag mask to clear (0..3) -+ */ -+static inline void cvmx_pip_tag_mask_clear(uint64_t mask_index) -+{ -+ uint64_t index; -+ union cvmx_pip_tag_incx pip_tag_incx; -+ pip_tag_incx.u64 = 0; -+ pip_tag_incx.s.en = 0; -+ for (index = mask_index * 16; index < (mask_index + 1) * 16; index++) -+ cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64); -+} -+ -+/** -+ * Sets a range of bits in the tag mask. The tag mask is used -+ * when the cvmx_pip_port_tag_cfg_t tag_mode is non zero. -+ * There are four separate masks that can be configured. -+ * -+ * @mask_index: Which tag mask to modify (0..3) -+ * @offset: Offset into the bitmask to set bits at. Use the GCC macro -+ * offsetof() to determine the offsets into packet headers. -+ * For example, offsetof(ethhdr, protocol) returns the offset -+ * of the ethernet protocol field. The bitmask selects which -+ * bytes to include the the tag, with bit offset X selecting -+ * byte at offset X from the beginning of the packet data. -+ * @len: Number of bytes to include. Usually this is the sizeof() -+ * the field. -+ */ -+static inline void cvmx_pip_tag_mask_set(uint64_t mask_index, uint64_t offset, -+ uint64_t len) -+{ -+ while (len--) { -+ union cvmx_pip_tag_incx pip_tag_incx; -+ uint64_t index = mask_index * 16 + offset / 8; -+ pip_tag_incx.u64 = cvmx_read_csr(CVMX_PIP_TAG_INCX(index)); -+ pip_tag_incx.s.en |= 0x80 >> (offset & 0x7); -+ cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64); -+ offset++; -+ } -+} -+ -+#endif /* __CVMX_PIP_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-pko-defs.h -@@ -0,0 +1,1133 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_PKO_DEFS_H__ -+#define __CVMX_PKO_DEFS_H__ -+ -+#define CVMX_PKO_MEM_COUNT0 \ -+ CVMX_ADD_IO_SEG(0x0001180050001080ull) -+#define CVMX_PKO_MEM_COUNT1 \ -+ CVMX_ADD_IO_SEG(0x0001180050001088ull) -+#define CVMX_PKO_MEM_DEBUG0 \ -+ CVMX_ADD_IO_SEG(0x0001180050001100ull) -+#define CVMX_PKO_MEM_DEBUG1 \ -+ CVMX_ADD_IO_SEG(0x0001180050001108ull) -+#define CVMX_PKO_MEM_DEBUG10 \ -+ CVMX_ADD_IO_SEG(0x0001180050001150ull) -+#define CVMX_PKO_MEM_DEBUG11 \ -+ CVMX_ADD_IO_SEG(0x0001180050001158ull) -+#define CVMX_PKO_MEM_DEBUG12 \ -+ CVMX_ADD_IO_SEG(0x0001180050001160ull) -+#define CVMX_PKO_MEM_DEBUG13 \ -+ CVMX_ADD_IO_SEG(0x0001180050001168ull) -+#define CVMX_PKO_MEM_DEBUG14 \ -+ CVMX_ADD_IO_SEG(0x0001180050001170ull) -+#define CVMX_PKO_MEM_DEBUG2 \ -+ CVMX_ADD_IO_SEG(0x0001180050001110ull) -+#define CVMX_PKO_MEM_DEBUG3 \ -+ CVMX_ADD_IO_SEG(0x0001180050001118ull) -+#define CVMX_PKO_MEM_DEBUG4 \ -+ CVMX_ADD_IO_SEG(0x0001180050001120ull) -+#define CVMX_PKO_MEM_DEBUG5 \ -+ CVMX_ADD_IO_SEG(0x0001180050001128ull) -+#define CVMX_PKO_MEM_DEBUG6 \ -+ CVMX_ADD_IO_SEG(0x0001180050001130ull) -+#define CVMX_PKO_MEM_DEBUG7 \ -+ CVMX_ADD_IO_SEG(0x0001180050001138ull) -+#define CVMX_PKO_MEM_DEBUG8 \ -+ CVMX_ADD_IO_SEG(0x0001180050001140ull) -+#define CVMX_PKO_MEM_DEBUG9 \ -+ CVMX_ADD_IO_SEG(0x0001180050001148ull) -+#define CVMX_PKO_MEM_PORT_PTRS \ -+ CVMX_ADD_IO_SEG(0x0001180050001010ull) -+#define CVMX_PKO_MEM_PORT_QOS \ -+ CVMX_ADD_IO_SEG(0x0001180050001018ull) -+#define CVMX_PKO_MEM_PORT_RATE0 \ -+ CVMX_ADD_IO_SEG(0x0001180050001020ull) -+#define CVMX_PKO_MEM_PORT_RATE1 \ -+ CVMX_ADD_IO_SEG(0x0001180050001028ull) -+#define CVMX_PKO_MEM_QUEUE_PTRS \ -+ CVMX_ADD_IO_SEG(0x0001180050001000ull) -+#define CVMX_PKO_MEM_QUEUE_QOS \ -+ CVMX_ADD_IO_SEG(0x0001180050001008ull) -+#define CVMX_PKO_REG_BIST_RESULT \ -+ CVMX_ADD_IO_SEG(0x0001180050000080ull) -+#define CVMX_PKO_REG_CMD_BUF \ -+ CVMX_ADD_IO_SEG(0x0001180050000010ull) -+#define CVMX_PKO_REG_CRC_CTLX(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180050000028ull + (((offset) & 1) * 8)) -+#define CVMX_PKO_REG_CRC_ENABLE \ -+ CVMX_ADD_IO_SEG(0x0001180050000020ull) -+#define CVMX_PKO_REG_CRC_IVX(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180050000038ull + (((offset) & 1) * 8)) -+#define CVMX_PKO_REG_DEBUG0 \ -+ CVMX_ADD_IO_SEG(0x0001180050000098ull) -+#define CVMX_PKO_REG_DEBUG1 \ -+ CVMX_ADD_IO_SEG(0x00011800500000A0ull) -+#define CVMX_PKO_REG_DEBUG2 \ -+ CVMX_ADD_IO_SEG(0x00011800500000A8ull) -+#define CVMX_PKO_REG_DEBUG3 \ -+ CVMX_ADD_IO_SEG(0x00011800500000B0ull) -+#define CVMX_PKO_REG_ENGINE_INFLIGHT \ -+ CVMX_ADD_IO_SEG(0x0001180050000050ull) -+#define CVMX_PKO_REG_ENGINE_THRESH \ -+ CVMX_ADD_IO_SEG(0x0001180050000058ull) -+#define CVMX_PKO_REG_ERROR \ -+ CVMX_ADD_IO_SEG(0x0001180050000088ull) -+#define CVMX_PKO_REG_FLAGS \ -+ CVMX_ADD_IO_SEG(0x0001180050000000ull) -+#define CVMX_PKO_REG_GMX_PORT_MODE \ -+ CVMX_ADD_IO_SEG(0x0001180050000018ull) -+#define CVMX_PKO_REG_INT_MASK \ -+ CVMX_ADD_IO_SEG(0x0001180050000090ull) -+#define CVMX_PKO_REG_QUEUE_MODE \ -+ CVMX_ADD_IO_SEG(0x0001180050000048ull) -+#define CVMX_PKO_REG_QUEUE_PTRS1 \ -+ CVMX_ADD_IO_SEG(0x0001180050000100ull) -+#define CVMX_PKO_REG_READ_IDX \ -+ CVMX_ADD_IO_SEG(0x0001180050000008ull) -+ -+union cvmx_pko_mem_count0 { -+ uint64_t u64; -+ struct cvmx_pko_mem_count0_s { -+ uint64_t reserved_32_63:32; -+ uint64_t count:32; -+ } s; -+ struct cvmx_pko_mem_count0_s cn30xx; -+ struct cvmx_pko_mem_count0_s cn31xx; -+ struct cvmx_pko_mem_count0_s cn38xx; -+ struct cvmx_pko_mem_count0_s cn38xxp2; -+ struct cvmx_pko_mem_count0_s cn50xx; -+ struct cvmx_pko_mem_count0_s cn52xx; -+ struct cvmx_pko_mem_count0_s cn52xxp1; -+ struct cvmx_pko_mem_count0_s cn56xx; -+ struct cvmx_pko_mem_count0_s cn56xxp1; -+ struct cvmx_pko_mem_count0_s cn58xx; -+ struct cvmx_pko_mem_count0_s cn58xxp1; -+}; -+ -+union cvmx_pko_mem_count1 { -+ uint64_t u64; -+ struct cvmx_pko_mem_count1_s { -+ uint64_t reserved_48_63:16; -+ uint64_t count:48; -+ } s; -+ struct cvmx_pko_mem_count1_s cn30xx; -+ struct cvmx_pko_mem_count1_s cn31xx; -+ struct cvmx_pko_mem_count1_s cn38xx; -+ struct cvmx_pko_mem_count1_s cn38xxp2; -+ struct cvmx_pko_mem_count1_s cn50xx; -+ struct cvmx_pko_mem_count1_s cn52xx; -+ struct cvmx_pko_mem_count1_s cn52xxp1; -+ struct cvmx_pko_mem_count1_s cn56xx; -+ struct cvmx_pko_mem_count1_s cn56xxp1; -+ struct cvmx_pko_mem_count1_s cn58xx; -+ struct cvmx_pko_mem_count1_s cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug0 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug0_s { -+ uint64_t fau:28; -+ uint64_t cmd:14; -+ uint64_t segs:6; -+ uint64_t size:16; -+ } s; -+ struct cvmx_pko_mem_debug0_s cn30xx; -+ struct cvmx_pko_mem_debug0_s cn31xx; -+ struct cvmx_pko_mem_debug0_s cn38xx; -+ struct cvmx_pko_mem_debug0_s cn38xxp2; -+ struct cvmx_pko_mem_debug0_s cn50xx; -+ struct cvmx_pko_mem_debug0_s cn52xx; -+ struct cvmx_pko_mem_debug0_s cn52xxp1; -+ struct cvmx_pko_mem_debug0_s cn56xx; -+ struct cvmx_pko_mem_debug0_s cn56xxp1; -+ struct cvmx_pko_mem_debug0_s cn58xx; -+ struct cvmx_pko_mem_debug0_s cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug1 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug1_s { -+ uint64_t i:1; -+ uint64_t back:4; -+ uint64_t pool:3; -+ uint64_t size:16; -+ uint64_t ptr:40; -+ } s; -+ struct cvmx_pko_mem_debug1_s cn30xx; -+ struct cvmx_pko_mem_debug1_s cn31xx; -+ struct cvmx_pko_mem_debug1_s cn38xx; -+ struct cvmx_pko_mem_debug1_s cn38xxp2; -+ struct cvmx_pko_mem_debug1_s cn50xx; -+ struct cvmx_pko_mem_debug1_s cn52xx; -+ struct cvmx_pko_mem_debug1_s cn52xxp1; -+ struct cvmx_pko_mem_debug1_s cn56xx; -+ struct cvmx_pko_mem_debug1_s cn56xxp1; -+ struct cvmx_pko_mem_debug1_s cn58xx; -+ struct cvmx_pko_mem_debug1_s cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug10 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug10_s { -+ uint64_t reserved_0_63:64; -+ } s; -+ struct cvmx_pko_mem_debug10_cn30xx { -+ uint64_t fau:28; -+ uint64_t cmd:14; -+ uint64_t segs:6; -+ uint64_t size:16; -+ } cn30xx; -+ struct cvmx_pko_mem_debug10_cn30xx cn31xx; -+ struct cvmx_pko_mem_debug10_cn30xx cn38xx; -+ struct cvmx_pko_mem_debug10_cn30xx cn38xxp2; -+ struct cvmx_pko_mem_debug10_cn50xx { -+ uint64_t reserved_49_63:15; -+ uint64_t ptrs1:17; -+ uint64_t reserved_17_31:15; -+ uint64_t ptrs2:17; -+ } cn50xx; -+ struct cvmx_pko_mem_debug10_cn50xx cn52xx; -+ struct cvmx_pko_mem_debug10_cn50xx cn52xxp1; -+ struct cvmx_pko_mem_debug10_cn50xx cn56xx; -+ struct cvmx_pko_mem_debug10_cn50xx cn56xxp1; -+ struct cvmx_pko_mem_debug10_cn50xx cn58xx; -+ struct cvmx_pko_mem_debug10_cn50xx cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug11 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug11_s { -+ uint64_t i:1; -+ uint64_t back:4; -+ uint64_t pool:3; -+ uint64_t size:16; -+ uint64_t reserved_0_39:40; -+ } s; -+ struct cvmx_pko_mem_debug11_cn30xx { -+ uint64_t i:1; -+ uint64_t back:4; -+ uint64_t pool:3; -+ uint64_t size:16; -+ uint64_t ptr:40; -+ } cn30xx; -+ struct cvmx_pko_mem_debug11_cn30xx cn31xx; -+ struct cvmx_pko_mem_debug11_cn30xx cn38xx; -+ struct cvmx_pko_mem_debug11_cn30xx cn38xxp2; -+ struct cvmx_pko_mem_debug11_cn50xx { -+ uint64_t reserved_23_63:41; -+ uint64_t maj:1; -+ uint64_t uid:3; -+ uint64_t sop:1; -+ uint64_t len:1; -+ uint64_t chk:1; -+ uint64_t cnt:13; -+ uint64_t mod:3; -+ } cn50xx; -+ struct cvmx_pko_mem_debug11_cn50xx cn52xx; -+ struct cvmx_pko_mem_debug11_cn50xx cn52xxp1; -+ struct cvmx_pko_mem_debug11_cn50xx cn56xx; -+ struct cvmx_pko_mem_debug11_cn50xx cn56xxp1; -+ struct cvmx_pko_mem_debug11_cn50xx cn58xx; -+ struct cvmx_pko_mem_debug11_cn50xx cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug12 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug12_s { -+ uint64_t reserved_0_63:64; -+ } s; -+ struct cvmx_pko_mem_debug12_cn30xx { -+ uint64_t data:64; -+ } cn30xx; -+ struct cvmx_pko_mem_debug12_cn30xx cn31xx; -+ struct cvmx_pko_mem_debug12_cn30xx cn38xx; -+ struct cvmx_pko_mem_debug12_cn30xx cn38xxp2; -+ struct cvmx_pko_mem_debug12_cn50xx { -+ uint64_t fau:28; -+ uint64_t cmd:14; -+ uint64_t segs:6; -+ uint64_t size:16; -+ } cn50xx; -+ struct cvmx_pko_mem_debug12_cn50xx cn52xx; -+ struct cvmx_pko_mem_debug12_cn50xx cn52xxp1; -+ struct cvmx_pko_mem_debug12_cn50xx cn56xx; -+ struct cvmx_pko_mem_debug12_cn50xx cn56xxp1; -+ struct cvmx_pko_mem_debug12_cn50xx cn58xx; -+ struct cvmx_pko_mem_debug12_cn50xx cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug13 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug13_s { -+ uint64_t i:1; -+ uint64_t back:4; -+ uint64_t pool:3; -+ uint64_t reserved_0_55:56; -+ } s; -+ struct cvmx_pko_mem_debug13_cn30xx { -+ uint64_t reserved_51_63:13; -+ uint64_t widx:17; -+ uint64_t ridx2:17; -+ uint64_t widx2:17; -+ } cn30xx; -+ struct cvmx_pko_mem_debug13_cn30xx cn31xx; -+ struct cvmx_pko_mem_debug13_cn30xx cn38xx; -+ struct cvmx_pko_mem_debug13_cn30xx cn38xxp2; -+ struct cvmx_pko_mem_debug13_cn50xx { -+ uint64_t i:1; -+ uint64_t back:4; -+ uint64_t pool:3; -+ uint64_t size:16; -+ uint64_t ptr:40; -+ } cn50xx; -+ struct cvmx_pko_mem_debug13_cn50xx cn52xx; -+ struct cvmx_pko_mem_debug13_cn50xx cn52xxp1; -+ struct cvmx_pko_mem_debug13_cn50xx cn56xx; -+ struct cvmx_pko_mem_debug13_cn50xx cn56xxp1; -+ struct cvmx_pko_mem_debug13_cn50xx cn58xx; -+ struct cvmx_pko_mem_debug13_cn50xx cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug14 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug14_s { -+ uint64_t reserved_0_63:64; -+ } s; -+ struct cvmx_pko_mem_debug14_cn30xx { -+ uint64_t reserved_17_63:47; -+ uint64_t ridx:17; -+ } cn30xx; -+ struct cvmx_pko_mem_debug14_cn30xx cn31xx; -+ struct cvmx_pko_mem_debug14_cn30xx cn38xx; -+ struct cvmx_pko_mem_debug14_cn30xx cn38xxp2; -+ struct cvmx_pko_mem_debug14_cn52xx { -+ uint64_t data:64; -+ } cn52xx; -+ struct cvmx_pko_mem_debug14_cn52xx cn52xxp1; -+ struct cvmx_pko_mem_debug14_cn52xx cn56xx; -+ struct cvmx_pko_mem_debug14_cn52xx cn56xxp1; -+}; -+ -+union cvmx_pko_mem_debug2 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug2_s { -+ uint64_t i:1; -+ uint64_t back:4; -+ uint64_t pool:3; -+ uint64_t size:16; -+ uint64_t ptr:40; -+ } s; -+ struct cvmx_pko_mem_debug2_s cn30xx; -+ struct cvmx_pko_mem_debug2_s cn31xx; -+ struct cvmx_pko_mem_debug2_s cn38xx; -+ struct cvmx_pko_mem_debug2_s cn38xxp2; -+ struct cvmx_pko_mem_debug2_s cn50xx; -+ struct cvmx_pko_mem_debug2_s cn52xx; -+ struct cvmx_pko_mem_debug2_s cn52xxp1; -+ struct cvmx_pko_mem_debug2_s cn56xx; -+ struct cvmx_pko_mem_debug2_s cn56xxp1; -+ struct cvmx_pko_mem_debug2_s cn58xx; -+ struct cvmx_pko_mem_debug2_s cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug3 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug3_s { -+ uint64_t reserved_0_63:64; -+ } s; -+ struct cvmx_pko_mem_debug3_cn30xx { -+ uint64_t i:1; -+ uint64_t back:4; -+ uint64_t pool:3; -+ uint64_t size:16; -+ uint64_t ptr:40; -+ } cn30xx; -+ struct cvmx_pko_mem_debug3_cn30xx cn31xx; -+ struct cvmx_pko_mem_debug3_cn30xx cn38xx; -+ struct cvmx_pko_mem_debug3_cn30xx cn38xxp2; -+ struct cvmx_pko_mem_debug3_cn50xx { -+ uint64_t data:64; -+ } cn50xx; -+ struct cvmx_pko_mem_debug3_cn50xx cn52xx; -+ struct cvmx_pko_mem_debug3_cn50xx cn52xxp1; -+ struct cvmx_pko_mem_debug3_cn50xx cn56xx; -+ struct cvmx_pko_mem_debug3_cn50xx cn56xxp1; -+ struct cvmx_pko_mem_debug3_cn50xx cn58xx; -+ struct cvmx_pko_mem_debug3_cn50xx cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug4 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug4_s { -+ uint64_t reserved_0_63:64; -+ } s; -+ struct cvmx_pko_mem_debug4_cn30xx { -+ uint64_t data:64; -+ } cn30xx; -+ struct cvmx_pko_mem_debug4_cn30xx cn31xx; -+ struct cvmx_pko_mem_debug4_cn30xx cn38xx; -+ struct cvmx_pko_mem_debug4_cn30xx cn38xxp2; -+ struct cvmx_pko_mem_debug4_cn50xx { -+ uint64_t cmnd_segs:3; -+ uint64_t cmnd_siz:16; -+ uint64_t cmnd_off:6; -+ uint64_t uid:3; -+ uint64_t dread_sop:1; -+ uint64_t init_dwrite:1; -+ uint64_t chk_once:1; -+ uint64_t chk_mode:1; -+ uint64_t active:1; -+ uint64_t static_p:1; -+ uint64_t qos:3; -+ uint64_t qcb_ridx:5; -+ uint64_t qid_off_max:4; -+ uint64_t qid_off:4; -+ uint64_t qid_base:8; -+ uint64_t wait:1; -+ uint64_t minor:2; -+ uint64_t major:3; -+ } cn50xx; -+ struct cvmx_pko_mem_debug4_cn52xx { -+ uint64_t curr_siz:8; -+ uint64_t curr_off:16; -+ uint64_t cmnd_segs:6; -+ uint64_t cmnd_siz:16; -+ uint64_t cmnd_off:6; -+ uint64_t uid:2; -+ uint64_t dread_sop:1; -+ uint64_t init_dwrite:1; -+ uint64_t chk_once:1; -+ uint64_t chk_mode:1; -+ uint64_t wait:1; -+ uint64_t minor:2; -+ uint64_t major:3; -+ } cn52xx; -+ struct cvmx_pko_mem_debug4_cn52xx cn52xxp1; -+ struct cvmx_pko_mem_debug4_cn52xx cn56xx; -+ struct cvmx_pko_mem_debug4_cn52xx cn56xxp1; -+ struct cvmx_pko_mem_debug4_cn50xx cn58xx; -+ struct cvmx_pko_mem_debug4_cn50xx cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug5 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug5_s { -+ uint64_t reserved_0_63:64; -+ } s; -+ struct cvmx_pko_mem_debug5_cn30xx { -+ uint64_t dwri_mod:1; -+ uint64_t dwri_sop:1; -+ uint64_t dwri_len:1; -+ uint64_t dwri_cnt:13; -+ uint64_t cmnd_siz:16; -+ uint64_t uid:1; -+ uint64_t xfer_wor:1; -+ uint64_t xfer_dwr:1; -+ uint64_t cbuf_fre:1; -+ uint64_t reserved_27_27:1; -+ uint64_t chk_mode:1; -+ uint64_t active:1; -+ uint64_t qos:3; -+ uint64_t qcb_ridx:5; -+ uint64_t qid_off:3; -+ uint64_t qid_base:7; -+ uint64_t wait:1; -+ uint64_t minor:2; -+ uint64_t major:4; -+ } cn30xx; -+ struct cvmx_pko_mem_debug5_cn30xx cn31xx; -+ struct cvmx_pko_mem_debug5_cn30xx cn38xx; -+ struct cvmx_pko_mem_debug5_cn30xx cn38xxp2; -+ struct cvmx_pko_mem_debug5_cn50xx { -+ uint64_t curr_ptr:29; -+ uint64_t curr_siz:16; -+ uint64_t curr_off:16; -+ uint64_t cmnd_segs:3; -+ } cn50xx; -+ struct cvmx_pko_mem_debug5_cn52xx { -+ uint64_t reserved_54_63:10; -+ uint64_t nxt_inflt:6; -+ uint64_t curr_ptr:40; -+ uint64_t curr_siz:8; -+ } cn52xx; -+ struct cvmx_pko_mem_debug5_cn52xx cn52xxp1; -+ struct cvmx_pko_mem_debug5_cn52xx cn56xx; -+ struct cvmx_pko_mem_debug5_cn52xx cn56xxp1; -+ struct cvmx_pko_mem_debug5_cn50xx cn58xx; -+ struct cvmx_pko_mem_debug5_cn50xx cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug6 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug6_s { -+ uint64_t reserved_37_63:27; -+ uint64_t qid_offres:4; -+ uint64_t qid_offths:4; -+ uint64_t preempter:1; -+ uint64_t preemptee:1; -+ uint64_t preempted:1; -+ uint64_t active:1; -+ uint64_t statc:1; -+ uint64_t qos:3; -+ uint64_t qcb_ridx:5; -+ uint64_t qid_offmax:4; -+ uint64_t reserved_0_11:12; -+ } s; -+ struct cvmx_pko_mem_debug6_cn30xx { -+ uint64_t reserved_11_63:53; -+ uint64_t qid_offm:3; -+ uint64_t static_p:1; -+ uint64_t work_min:3; -+ uint64_t dwri_chk:1; -+ uint64_t dwri_uid:1; -+ uint64_t dwri_mod:2; -+ } cn30xx; -+ struct cvmx_pko_mem_debug6_cn30xx cn31xx; -+ struct cvmx_pko_mem_debug6_cn30xx cn38xx; -+ struct cvmx_pko_mem_debug6_cn30xx cn38xxp2; -+ struct cvmx_pko_mem_debug6_cn50xx { -+ uint64_t reserved_11_63:53; -+ uint64_t curr_ptr:11; -+ } cn50xx; -+ struct cvmx_pko_mem_debug6_cn52xx { -+ uint64_t reserved_37_63:27; -+ uint64_t qid_offres:4; -+ uint64_t qid_offths:4; -+ uint64_t preempter:1; -+ uint64_t preemptee:1; -+ uint64_t preempted:1; -+ uint64_t active:1; -+ uint64_t statc:1; -+ uint64_t qos:3; -+ uint64_t qcb_ridx:5; -+ uint64_t qid_offmax:4; -+ uint64_t qid_off:4; -+ uint64_t qid_base:8; -+ } cn52xx; -+ struct cvmx_pko_mem_debug6_cn52xx cn52xxp1; -+ struct cvmx_pko_mem_debug6_cn52xx cn56xx; -+ struct cvmx_pko_mem_debug6_cn52xx cn56xxp1; -+ struct cvmx_pko_mem_debug6_cn50xx cn58xx; -+ struct cvmx_pko_mem_debug6_cn50xx cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug7 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug7_s { -+ uint64_t qos:5; -+ uint64_t tail:1; -+ uint64_t reserved_0_57:58; -+ } s; -+ struct cvmx_pko_mem_debug7_cn30xx { -+ uint64_t reserved_58_63:6; -+ uint64_t dwb:9; -+ uint64_t start:33; -+ uint64_t size:16; -+ } cn30xx; -+ struct cvmx_pko_mem_debug7_cn30xx cn31xx; -+ struct cvmx_pko_mem_debug7_cn30xx cn38xx; -+ struct cvmx_pko_mem_debug7_cn30xx cn38xxp2; -+ struct cvmx_pko_mem_debug7_cn50xx { -+ uint64_t qos:5; -+ uint64_t tail:1; -+ uint64_t buf_siz:13; -+ uint64_t buf_ptr:33; -+ uint64_t qcb_widx:6; -+ uint64_t qcb_ridx:6; -+ } cn50xx; -+ struct cvmx_pko_mem_debug7_cn50xx cn52xx; -+ struct cvmx_pko_mem_debug7_cn50xx cn52xxp1; -+ struct cvmx_pko_mem_debug7_cn50xx cn56xx; -+ struct cvmx_pko_mem_debug7_cn50xx cn56xxp1; -+ struct cvmx_pko_mem_debug7_cn50xx cn58xx; -+ struct cvmx_pko_mem_debug7_cn50xx cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug8 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug8_s { -+ uint64_t reserved_59_63:5; -+ uint64_t tail:1; -+ uint64_t buf_siz:13; -+ uint64_t reserved_0_44:45; -+ } s; -+ struct cvmx_pko_mem_debug8_cn30xx { -+ uint64_t qos:5; -+ uint64_t tail:1; -+ uint64_t buf_siz:13; -+ uint64_t buf_ptr:33; -+ uint64_t qcb_widx:6; -+ uint64_t qcb_ridx:6; -+ } cn30xx; -+ struct cvmx_pko_mem_debug8_cn30xx cn31xx; -+ struct cvmx_pko_mem_debug8_cn30xx cn38xx; -+ struct cvmx_pko_mem_debug8_cn30xx cn38xxp2; -+ struct cvmx_pko_mem_debug8_cn50xx { -+ uint64_t reserved_28_63:36; -+ uint64_t doorbell:20; -+ uint64_t reserved_6_7:2; -+ uint64_t static_p:1; -+ uint64_t s_tail:1; -+ uint64_t static_q:1; -+ uint64_t qos:3; -+ } cn50xx; -+ struct cvmx_pko_mem_debug8_cn52xx { -+ uint64_t reserved_29_63:35; -+ uint64_t preempter:1; -+ uint64_t doorbell:20; -+ uint64_t reserved_7_7:1; -+ uint64_t preemptee:1; -+ uint64_t static_p:1; -+ uint64_t s_tail:1; -+ uint64_t static_q:1; -+ uint64_t qos:3; -+ } cn52xx; -+ struct cvmx_pko_mem_debug8_cn52xx cn52xxp1; -+ struct cvmx_pko_mem_debug8_cn52xx cn56xx; -+ struct cvmx_pko_mem_debug8_cn52xx cn56xxp1; -+ struct cvmx_pko_mem_debug8_cn50xx cn58xx; -+ struct cvmx_pko_mem_debug8_cn50xx cn58xxp1; -+}; -+ -+union cvmx_pko_mem_debug9 { -+ uint64_t u64; -+ struct cvmx_pko_mem_debug9_s { -+ uint64_t reserved_49_63:15; -+ uint64_t ptrs0:17; -+ uint64_t reserved_0_31:32; -+ } s; -+ struct cvmx_pko_mem_debug9_cn30xx { -+ uint64_t reserved_28_63:36; -+ uint64_t doorbell:20; -+ uint64_t reserved_5_7:3; -+ uint64_t s_tail:1; -+ uint64_t static_q:1; -+ uint64_t qos:3; -+ } cn30xx; -+ struct cvmx_pko_mem_debug9_cn30xx cn31xx; -+ struct cvmx_pko_mem_debug9_cn38xx { -+ uint64_t reserved_28_63:36; -+ uint64_t doorbell:20; -+ uint64_t reserved_6_7:2; -+ uint64_t static_p:1; -+ uint64_t s_tail:1; -+ uint64_t static_q:1; -+ uint64_t qos:3; -+ } cn38xx; -+ struct cvmx_pko_mem_debug9_cn38xx cn38xxp2; -+ struct cvmx_pko_mem_debug9_cn50xx { -+ uint64_t reserved_49_63:15; -+ uint64_t ptrs0:17; -+ uint64_t reserved_17_31:15; -+ uint64_t ptrs3:17; -+ } cn50xx; -+ struct cvmx_pko_mem_debug9_cn50xx cn52xx; -+ struct cvmx_pko_mem_debug9_cn50xx cn52xxp1; -+ struct cvmx_pko_mem_debug9_cn50xx cn56xx; -+ struct cvmx_pko_mem_debug9_cn50xx cn56xxp1; -+ struct cvmx_pko_mem_debug9_cn50xx cn58xx; -+ struct cvmx_pko_mem_debug9_cn50xx cn58xxp1; -+}; -+ -+union cvmx_pko_mem_port_ptrs { -+ uint64_t u64; -+ struct cvmx_pko_mem_port_ptrs_s { -+ uint64_t reserved_62_63:2; -+ uint64_t static_p:1; -+ uint64_t qos_mask:8; -+ uint64_t reserved_16_52:37; -+ uint64_t bp_port:6; -+ uint64_t eid:4; -+ uint64_t pid:6; -+ } s; -+ struct cvmx_pko_mem_port_ptrs_s cn52xx; -+ struct cvmx_pko_mem_port_ptrs_s cn52xxp1; -+ struct cvmx_pko_mem_port_ptrs_s cn56xx; -+ struct cvmx_pko_mem_port_ptrs_s cn56xxp1; -+}; -+ -+union cvmx_pko_mem_port_qos { -+ uint64_t u64; -+ struct cvmx_pko_mem_port_qos_s { -+ uint64_t reserved_61_63:3; -+ uint64_t qos_mask:8; -+ uint64_t reserved_10_52:43; -+ uint64_t eid:4; -+ uint64_t pid:6; -+ } s; -+ struct cvmx_pko_mem_port_qos_s cn52xx; -+ struct cvmx_pko_mem_port_qos_s cn52xxp1; -+ struct cvmx_pko_mem_port_qos_s cn56xx; -+ struct cvmx_pko_mem_port_qos_s cn56xxp1; -+}; -+ -+union cvmx_pko_mem_port_rate0 { -+ uint64_t u64; -+ struct cvmx_pko_mem_port_rate0_s { -+ uint64_t reserved_51_63:13; -+ uint64_t rate_word:19; -+ uint64_t rate_pkt:24; -+ uint64_t reserved_6_7:2; -+ uint64_t pid:6; -+ } s; -+ struct cvmx_pko_mem_port_rate0_s cn52xx; -+ struct cvmx_pko_mem_port_rate0_s cn52xxp1; -+ struct cvmx_pko_mem_port_rate0_s cn56xx; -+ struct cvmx_pko_mem_port_rate0_s cn56xxp1; -+}; -+ -+union cvmx_pko_mem_port_rate1 { -+ uint64_t u64; -+ struct cvmx_pko_mem_port_rate1_s { -+ uint64_t reserved_32_63:32; -+ uint64_t rate_lim:24; -+ uint64_t reserved_6_7:2; -+ uint64_t pid:6; -+ } s; -+ struct cvmx_pko_mem_port_rate1_s cn52xx; -+ struct cvmx_pko_mem_port_rate1_s cn52xxp1; -+ struct cvmx_pko_mem_port_rate1_s cn56xx; -+ struct cvmx_pko_mem_port_rate1_s cn56xxp1; -+}; -+ -+union cvmx_pko_mem_queue_ptrs { -+ uint64_t u64; -+ struct cvmx_pko_mem_queue_ptrs_s { -+ uint64_t s_tail:1; -+ uint64_t static_p:1; -+ uint64_t static_q:1; -+ uint64_t qos_mask:8; -+ uint64_t buf_ptr:36; -+ uint64_t tail:1; -+ uint64_t index:3; -+ uint64_t port:6; -+ uint64_t queue:7; -+ } s; -+ struct cvmx_pko_mem_queue_ptrs_s cn30xx; -+ struct cvmx_pko_mem_queue_ptrs_s cn31xx; -+ struct cvmx_pko_mem_queue_ptrs_s cn38xx; -+ struct cvmx_pko_mem_queue_ptrs_s cn38xxp2; -+ struct cvmx_pko_mem_queue_ptrs_s cn50xx; -+ struct cvmx_pko_mem_queue_ptrs_s cn52xx; -+ struct cvmx_pko_mem_queue_ptrs_s cn52xxp1; -+ struct cvmx_pko_mem_queue_ptrs_s cn56xx; -+ struct cvmx_pko_mem_queue_ptrs_s cn56xxp1; -+ struct cvmx_pko_mem_queue_ptrs_s cn58xx; -+ struct cvmx_pko_mem_queue_ptrs_s cn58xxp1; -+}; -+ -+union cvmx_pko_mem_queue_qos { -+ uint64_t u64; -+ struct cvmx_pko_mem_queue_qos_s { -+ uint64_t reserved_61_63:3; -+ uint64_t qos_mask:8; -+ uint64_t reserved_13_52:40; -+ uint64_t pid:6; -+ uint64_t qid:7; -+ } s; -+ struct cvmx_pko_mem_queue_qos_s cn30xx; -+ struct cvmx_pko_mem_queue_qos_s cn31xx; -+ struct cvmx_pko_mem_queue_qos_s cn38xx; -+ struct cvmx_pko_mem_queue_qos_s cn38xxp2; -+ struct cvmx_pko_mem_queue_qos_s cn50xx; -+ struct cvmx_pko_mem_queue_qos_s cn52xx; -+ struct cvmx_pko_mem_queue_qos_s cn52xxp1; -+ struct cvmx_pko_mem_queue_qos_s cn56xx; -+ struct cvmx_pko_mem_queue_qos_s cn56xxp1; -+ struct cvmx_pko_mem_queue_qos_s cn58xx; -+ struct cvmx_pko_mem_queue_qos_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_bist_result { -+ uint64_t u64; -+ struct cvmx_pko_reg_bist_result_s { -+ uint64_t reserved_0_63:64; -+ } s; -+ struct cvmx_pko_reg_bist_result_cn30xx { -+ uint64_t reserved_27_63:37; -+ uint64_t psb2:5; -+ uint64_t count:1; -+ uint64_t rif:1; -+ uint64_t wif:1; -+ uint64_t ncb:1; -+ uint64_t out:1; -+ uint64_t crc:1; -+ uint64_t chk:1; -+ uint64_t qsb:2; -+ uint64_t qcb:2; -+ uint64_t pdb:4; -+ uint64_t psb:7; -+ } cn30xx; -+ struct cvmx_pko_reg_bist_result_cn30xx cn31xx; -+ struct cvmx_pko_reg_bist_result_cn30xx cn38xx; -+ struct cvmx_pko_reg_bist_result_cn30xx cn38xxp2; -+ struct cvmx_pko_reg_bist_result_cn50xx { -+ uint64_t reserved_33_63:31; -+ uint64_t csr:1; -+ uint64_t iob:1; -+ uint64_t out_crc:1; -+ uint64_t out_ctl:3; -+ uint64_t out_sta:1; -+ uint64_t out_wif:1; -+ uint64_t prt_chk:3; -+ uint64_t prt_nxt:1; -+ uint64_t prt_psb:6; -+ uint64_t ncb_inb:2; -+ uint64_t prt_qcb:2; -+ uint64_t prt_qsb:3; -+ uint64_t dat_dat:4; -+ uint64_t dat_ptr:4; -+ } cn50xx; -+ struct cvmx_pko_reg_bist_result_cn52xx { -+ uint64_t reserved_35_63:29; -+ uint64_t csr:1; -+ uint64_t iob:1; -+ uint64_t out_dat:1; -+ uint64_t out_ctl:3; -+ uint64_t out_sta:1; -+ uint64_t out_wif:1; -+ uint64_t prt_chk:3; -+ uint64_t prt_nxt:1; -+ uint64_t prt_psb:8; -+ uint64_t ncb_inb:2; -+ uint64_t prt_qcb:2; -+ uint64_t prt_qsb:3; -+ uint64_t prt_ctl:2; -+ uint64_t dat_dat:2; -+ uint64_t dat_ptr:4; -+ } cn52xx; -+ struct cvmx_pko_reg_bist_result_cn52xx cn52xxp1; -+ struct cvmx_pko_reg_bist_result_cn52xx cn56xx; -+ struct cvmx_pko_reg_bist_result_cn52xx cn56xxp1; -+ struct cvmx_pko_reg_bist_result_cn50xx cn58xx; -+ struct cvmx_pko_reg_bist_result_cn50xx cn58xxp1; -+}; -+ -+union cvmx_pko_reg_cmd_buf { -+ uint64_t u64; -+ struct cvmx_pko_reg_cmd_buf_s { -+ uint64_t reserved_23_63:41; -+ uint64_t pool:3; -+ uint64_t reserved_13_19:7; -+ uint64_t size:13; -+ } s; -+ struct cvmx_pko_reg_cmd_buf_s cn30xx; -+ struct cvmx_pko_reg_cmd_buf_s cn31xx; -+ struct cvmx_pko_reg_cmd_buf_s cn38xx; -+ struct cvmx_pko_reg_cmd_buf_s cn38xxp2; -+ struct cvmx_pko_reg_cmd_buf_s cn50xx; -+ struct cvmx_pko_reg_cmd_buf_s cn52xx; -+ struct cvmx_pko_reg_cmd_buf_s cn52xxp1; -+ struct cvmx_pko_reg_cmd_buf_s cn56xx; -+ struct cvmx_pko_reg_cmd_buf_s cn56xxp1; -+ struct cvmx_pko_reg_cmd_buf_s cn58xx; -+ struct cvmx_pko_reg_cmd_buf_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_crc_ctlx { -+ uint64_t u64; -+ struct cvmx_pko_reg_crc_ctlx_s { -+ uint64_t reserved_2_63:62; -+ uint64_t invres:1; -+ uint64_t refin:1; -+ } s; -+ struct cvmx_pko_reg_crc_ctlx_s cn38xx; -+ struct cvmx_pko_reg_crc_ctlx_s cn38xxp2; -+ struct cvmx_pko_reg_crc_ctlx_s cn58xx; -+ struct cvmx_pko_reg_crc_ctlx_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_crc_enable { -+ uint64_t u64; -+ struct cvmx_pko_reg_crc_enable_s { -+ uint64_t reserved_32_63:32; -+ uint64_t enable:32; -+ } s; -+ struct cvmx_pko_reg_crc_enable_s cn38xx; -+ struct cvmx_pko_reg_crc_enable_s cn38xxp2; -+ struct cvmx_pko_reg_crc_enable_s cn58xx; -+ struct cvmx_pko_reg_crc_enable_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_crc_ivx { -+ uint64_t u64; -+ struct cvmx_pko_reg_crc_ivx_s { -+ uint64_t reserved_32_63:32; -+ uint64_t iv:32; -+ } s; -+ struct cvmx_pko_reg_crc_ivx_s cn38xx; -+ struct cvmx_pko_reg_crc_ivx_s cn38xxp2; -+ struct cvmx_pko_reg_crc_ivx_s cn58xx; -+ struct cvmx_pko_reg_crc_ivx_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_debug0 { -+ uint64_t u64; -+ struct cvmx_pko_reg_debug0_s { -+ uint64_t asserts:64; -+ } s; -+ struct cvmx_pko_reg_debug0_cn30xx { -+ uint64_t reserved_17_63:47; -+ uint64_t asserts:17; -+ } cn30xx; -+ struct cvmx_pko_reg_debug0_cn30xx cn31xx; -+ struct cvmx_pko_reg_debug0_cn30xx cn38xx; -+ struct cvmx_pko_reg_debug0_cn30xx cn38xxp2; -+ struct cvmx_pko_reg_debug0_s cn50xx; -+ struct cvmx_pko_reg_debug0_s cn52xx; -+ struct cvmx_pko_reg_debug0_s cn52xxp1; -+ struct cvmx_pko_reg_debug0_s cn56xx; -+ struct cvmx_pko_reg_debug0_s cn56xxp1; -+ struct cvmx_pko_reg_debug0_s cn58xx; -+ struct cvmx_pko_reg_debug0_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_debug1 { -+ uint64_t u64; -+ struct cvmx_pko_reg_debug1_s { -+ uint64_t asserts:64; -+ } s; -+ struct cvmx_pko_reg_debug1_s cn50xx; -+ struct cvmx_pko_reg_debug1_s cn52xx; -+ struct cvmx_pko_reg_debug1_s cn52xxp1; -+ struct cvmx_pko_reg_debug1_s cn56xx; -+ struct cvmx_pko_reg_debug1_s cn56xxp1; -+ struct cvmx_pko_reg_debug1_s cn58xx; -+ struct cvmx_pko_reg_debug1_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_debug2 { -+ uint64_t u64; -+ struct cvmx_pko_reg_debug2_s { -+ uint64_t asserts:64; -+ } s; -+ struct cvmx_pko_reg_debug2_s cn50xx; -+ struct cvmx_pko_reg_debug2_s cn52xx; -+ struct cvmx_pko_reg_debug2_s cn52xxp1; -+ struct cvmx_pko_reg_debug2_s cn56xx; -+ struct cvmx_pko_reg_debug2_s cn56xxp1; -+ struct cvmx_pko_reg_debug2_s cn58xx; -+ struct cvmx_pko_reg_debug2_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_debug3 { -+ uint64_t u64; -+ struct cvmx_pko_reg_debug3_s { -+ uint64_t asserts:64; -+ } s; -+ struct cvmx_pko_reg_debug3_s cn50xx; -+ struct cvmx_pko_reg_debug3_s cn52xx; -+ struct cvmx_pko_reg_debug3_s cn52xxp1; -+ struct cvmx_pko_reg_debug3_s cn56xx; -+ struct cvmx_pko_reg_debug3_s cn56xxp1; -+ struct cvmx_pko_reg_debug3_s cn58xx; -+ struct cvmx_pko_reg_debug3_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_engine_inflight { -+ uint64_t u64; -+ struct cvmx_pko_reg_engine_inflight_s { -+ uint64_t reserved_40_63:24; -+ uint64_t engine9:4; -+ uint64_t engine8:4; -+ uint64_t engine7:4; -+ uint64_t engine6:4; -+ uint64_t engine5:4; -+ uint64_t engine4:4; -+ uint64_t engine3:4; -+ uint64_t engine2:4; -+ uint64_t engine1:4; -+ uint64_t engine0:4; -+ } s; -+ struct cvmx_pko_reg_engine_inflight_s cn52xx; -+ struct cvmx_pko_reg_engine_inflight_s cn52xxp1; -+ struct cvmx_pko_reg_engine_inflight_s cn56xx; -+ struct cvmx_pko_reg_engine_inflight_s cn56xxp1; -+}; -+ -+union cvmx_pko_reg_engine_thresh { -+ uint64_t u64; -+ struct cvmx_pko_reg_engine_thresh_s { -+ uint64_t reserved_10_63:54; -+ uint64_t mask:10; -+ } s; -+ struct cvmx_pko_reg_engine_thresh_s cn52xx; -+ struct cvmx_pko_reg_engine_thresh_s cn52xxp1; -+ struct cvmx_pko_reg_engine_thresh_s cn56xx; -+ struct cvmx_pko_reg_engine_thresh_s cn56xxp1; -+}; -+ -+union cvmx_pko_reg_error { -+ uint64_t u64; -+ struct cvmx_pko_reg_error_s { -+ uint64_t reserved_3_63:61; -+ uint64_t currzero:1; -+ uint64_t doorbell:1; -+ uint64_t parity:1; -+ } s; -+ struct cvmx_pko_reg_error_cn30xx { -+ uint64_t reserved_2_63:62; -+ uint64_t doorbell:1; -+ uint64_t parity:1; -+ } cn30xx; -+ struct cvmx_pko_reg_error_cn30xx cn31xx; -+ struct cvmx_pko_reg_error_cn30xx cn38xx; -+ struct cvmx_pko_reg_error_cn30xx cn38xxp2; -+ struct cvmx_pko_reg_error_s cn50xx; -+ struct cvmx_pko_reg_error_s cn52xx; -+ struct cvmx_pko_reg_error_s cn52xxp1; -+ struct cvmx_pko_reg_error_s cn56xx; -+ struct cvmx_pko_reg_error_s cn56xxp1; -+ struct cvmx_pko_reg_error_s cn58xx; -+ struct cvmx_pko_reg_error_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_flags { -+ uint64_t u64; -+ struct cvmx_pko_reg_flags_s { -+ uint64_t reserved_4_63:60; -+ uint64_t reset:1; -+ uint64_t store_be:1; -+ uint64_t ena_dwb:1; -+ uint64_t ena_pko:1; -+ } s; -+ struct cvmx_pko_reg_flags_s cn30xx; -+ struct cvmx_pko_reg_flags_s cn31xx; -+ struct cvmx_pko_reg_flags_s cn38xx; -+ struct cvmx_pko_reg_flags_s cn38xxp2; -+ struct cvmx_pko_reg_flags_s cn50xx; -+ struct cvmx_pko_reg_flags_s cn52xx; -+ struct cvmx_pko_reg_flags_s cn52xxp1; -+ struct cvmx_pko_reg_flags_s cn56xx; -+ struct cvmx_pko_reg_flags_s cn56xxp1; -+ struct cvmx_pko_reg_flags_s cn58xx; -+ struct cvmx_pko_reg_flags_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_gmx_port_mode { -+ uint64_t u64; -+ struct cvmx_pko_reg_gmx_port_mode_s { -+ uint64_t reserved_6_63:58; -+ uint64_t mode1:3; -+ uint64_t mode0:3; -+ } s; -+ struct cvmx_pko_reg_gmx_port_mode_s cn30xx; -+ struct cvmx_pko_reg_gmx_port_mode_s cn31xx; -+ struct cvmx_pko_reg_gmx_port_mode_s cn38xx; -+ struct cvmx_pko_reg_gmx_port_mode_s cn38xxp2; -+ struct cvmx_pko_reg_gmx_port_mode_s cn50xx; -+ struct cvmx_pko_reg_gmx_port_mode_s cn52xx; -+ struct cvmx_pko_reg_gmx_port_mode_s cn52xxp1; -+ struct cvmx_pko_reg_gmx_port_mode_s cn56xx; -+ struct cvmx_pko_reg_gmx_port_mode_s cn56xxp1; -+ struct cvmx_pko_reg_gmx_port_mode_s cn58xx; -+ struct cvmx_pko_reg_gmx_port_mode_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_int_mask { -+ uint64_t u64; -+ struct cvmx_pko_reg_int_mask_s { -+ uint64_t reserved_3_63:61; -+ uint64_t currzero:1; -+ uint64_t doorbell:1; -+ uint64_t parity:1; -+ } s; -+ struct cvmx_pko_reg_int_mask_cn30xx { -+ uint64_t reserved_2_63:62; -+ uint64_t doorbell:1; -+ uint64_t parity:1; -+ } cn30xx; -+ struct cvmx_pko_reg_int_mask_cn30xx cn31xx; -+ struct cvmx_pko_reg_int_mask_cn30xx cn38xx; -+ struct cvmx_pko_reg_int_mask_cn30xx cn38xxp2; -+ struct cvmx_pko_reg_int_mask_s cn50xx; -+ struct cvmx_pko_reg_int_mask_s cn52xx; -+ struct cvmx_pko_reg_int_mask_s cn52xxp1; -+ struct cvmx_pko_reg_int_mask_s cn56xx; -+ struct cvmx_pko_reg_int_mask_s cn56xxp1; -+ struct cvmx_pko_reg_int_mask_s cn58xx; -+ struct cvmx_pko_reg_int_mask_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_queue_mode { -+ uint64_t u64; -+ struct cvmx_pko_reg_queue_mode_s { -+ uint64_t reserved_2_63:62; -+ uint64_t mode:2; -+ } s; -+ struct cvmx_pko_reg_queue_mode_s cn30xx; -+ struct cvmx_pko_reg_queue_mode_s cn31xx; -+ struct cvmx_pko_reg_queue_mode_s cn38xx; -+ struct cvmx_pko_reg_queue_mode_s cn38xxp2; -+ struct cvmx_pko_reg_queue_mode_s cn50xx; -+ struct cvmx_pko_reg_queue_mode_s cn52xx; -+ struct cvmx_pko_reg_queue_mode_s cn52xxp1; -+ struct cvmx_pko_reg_queue_mode_s cn56xx; -+ struct cvmx_pko_reg_queue_mode_s cn56xxp1; -+ struct cvmx_pko_reg_queue_mode_s cn58xx; -+ struct cvmx_pko_reg_queue_mode_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_queue_ptrs1 { -+ uint64_t u64; -+ struct cvmx_pko_reg_queue_ptrs1_s { -+ uint64_t reserved_2_63:62; -+ uint64_t idx3:1; -+ uint64_t qid7:1; -+ } s; -+ struct cvmx_pko_reg_queue_ptrs1_s cn50xx; -+ struct cvmx_pko_reg_queue_ptrs1_s cn52xx; -+ struct cvmx_pko_reg_queue_ptrs1_s cn52xxp1; -+ struct cvmx_pko_reg_queue_ptrs1_s cn56xx; -+ struct cvmx_pko_reg_queue_ptrs1_s cn56xxp1; -+ struct cvmx_pko_reg_queue_ptrs1_s cn58xx; -+ struct cvmx_pko_reg_queue_ptrs1_s cn58xxp1; -+}; -+ -+union cvmx_pko_reg_read_idx { -+ uint64_t u64; -+ struct cvmx_pko_reg_read_idx_s { -+ uint64_t reserved_16_63:48; -+ uint64_t inc:8; -+ uint64_t index:8; -+ } s; -+ struct cvmx_pko_reg_read_idx_s cn30xx; -+ struct cvmx_pko_reg_read_idx_s cn31xx; -+ struct cvmx_pko_reg_read_idx_s cn38xx; -+ struct cvmx_pko_reg_read_idx_s cn38xxp2; -+ struct cvmx_pko_reg_read_idx_s cn50xx; -+ struct cvmx_pko_reg_read_idx_s cn52xx; -+ struct cvmx_pko_reg_read_idx_s cn52xxp1; -+ struct cvmx_pko_reg_read_idx_s cn56xx; -+ struct cvmx_pko_reg_read_idx_s cn56xxp1; -+ struct cvmx_pko_reg_read_idx_s cn58xx; -+ struct cvmx_pko_reg_read_idx_s cn58xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-pko.c -@@ -0,0 +1,506 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * Support library for the hardware Packet Output unit. -+ */ -+ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-config.h" -+#include "cvmx-pko.h" -+#include "cvmx-helper.h" -+ -+/** -+ * Internal state of packet output -+ */ -+ -+/** -+ * Call before any other calls to initialize the packet -+ * output system. This does chip global config, and should only be -+ * done by one core. -+ */ -+ -+void cvmx_pko_initialize_global(void) -+{ -+ int i; -+ uint64_t priority = 8; -+ union cvmx_pko_reg_cmd_buf config; -+ -+ /* -+ * Set the size of the PKO command buffers to an odd number of -+ * 64bit words. This allows the normal two word send to stay -+ * aligned and never span a comamnd word buffer. -+ */ -+ config.u64 = 0; -+ config.s.pool = CVMX_FPA_OUTPUT_BUFFER_POOL; -+ config.s.size = CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE / 8 - 1; -+ -+ cvmx_write_csr(CVMX_PKO_REG_CMD_BUF, config.u64); -+ -+ for (i = 0; i < CVMX_PKO_MAX_OUTPUT_QUEUES; i++) -+ cvmx_pko_config_port(CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID, i, 1, -+ &priority); -+ -+ /* -+ * If we aren't using all of the queues optimize PKO's -+ * internal memory. -+ */ -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX) -+ || OCTEON_IS_MODEL(OCTEON_CN56XX) -+ || OCTEON_IS_MODEL(OCTEON_CN52XX)) { -+ int num_interfaces = cvmx_helper_get_number_of_interfaces(); -+ int last_port = -+ cvmx_helper_get_last_ipd_port(num_interfaces - 1); -+ int max_queues = -+ cvmx_pko_get_base_queue(last_port) + -+ cvmx_pko_get_num_queues(last_port); -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX)) { -+ if (max_queues <= 32) -+ cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 2); -+ else if (max_queues <= 64) -+ cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 1); -+ } else { -+ if (max_queues <= 64) -+ cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 2); -+ else if (max_queues <= 128) -+ cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 1); -+ } -+ } -+} -+ -+/** -+ * This function does per-core initialization required by the PKO routines. -+ * This must be called on all cores that will do packet output, and must -+ * be called after the FPA has been initialized and filled with pages. -+ * -+ * Returns 0 on success -+ * !0 on failure -+ */ -+int cvmx_pko_initialize_local(void) -+{ -+ /* Nothing to do */ -+ return 0; -+} -+ -+/** -+ * Enables the packet output hardware. It must already be -+ * configured. -+ */ -+void cvmx_pko_enable(void) -+{ -+ union cvmx_pko_reg_flags flags; -+ -+ flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS); -+ if (flags.s.ena_pko) -+ cvmx_dprintf -+ ("Warning: Enabling PKO when PKO already enabled.\n"); -+ -+ flags.s.ena_dwb = 1; -+ flags.s.ena_pko = 1; -+ /* -+ * always enable big endian for 3-word command. Does nothing -+ * for 2-word. -+ */ -+ flags.s.store_be = 1; -+ cvmx_write_csr(CVMX_PKO_REG_FLAGS, flags.u64); -+} -+ -+/** -+ * Disables the packet output. Does not affect any configuration. -+ */ -+void cvmx_pko_disable(void) -+{ -+ union cvmx_pko_reg_flags pko_reg_flags; -+ pko_reg_flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS); -+ pko_reg_flags.s.ena_pko = 0; -+ cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64); -+} -+ -+ -+/** -+ * Reset the packet output. -+ */ -+static void __cvmx_pko_reset(void) -+{ -+ union cvmx_pko_reg_flags pko_reg_flags; -+ pko_reg_flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS); -+ pko_reg_flags.s.reset = 1; -+ cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64); -+} -+ -+/** -+ * Shutdown and free resources required by packet output. -+ */ -+void cvmx_pko_shutdown(void) -+{ -+ union cvmx_pko_mem_queue_ptrs config; -+ int queue; -+ -+ cvmx_pko_disable(); -+ -+ for (queue = 0; queue < CVMX_PKO_MAX_OUTPUT_QUEUES; queue++) { -+ config.u64 = 0; -+ config.s.tail = 1; -+ config.s.index = 0; -+ config.s.port = CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID; -+ config.s.queue = queue & 0x7f; -+ config.s.qos_mask = 0; -+ config.s.buf_ptr = 0; -+ if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) { -+ union cvmx_pko_reg_queue_ptrs1 config1; -+ config1.u64 = 0; -+ config1.s.qid7 = queue >> 7; -+ cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64); -+ } -+ cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64); -+ cvmx_cmd_queue_shutdown(CVMX_CMD_QUEUE_PKO(queue)); -+ } -+ __cvmx_pko_reset(); -+} -+ -+/** -+ * Configure a output port and the associated queues for use. -+ * -+ * @port: Port to configure. -+ * @base_queue: First queue number to associate with this port. -+ * @num_queues: Number of queues to associate with this port -+ * @priority: Array of priority levels for each queue. Values are -+ * allowed to be 0-8. A value of 8 get 8 times the traffic -+ * of a value of 1. A value of 0 indicates that no rounds -+ * will be participated in. These priorities can be changed -+ * on the fly while the pko is enabled. A priority of 9 -+ * indicates that static priority should be used. If static -+ * priority is used all queues with static priority must be -+ * contiguous starting at the base_queue, and lower numbered -+ * queues have higher priority than higher numbered queues. -+ * There must be num_queues elements in the array. -+ */ -+cvmx_pko_status_t cvmx_pko_config_port(uint64_t port, uint64_t base_queue, -+ uint64_t num_queues, -+ const uint64_t priority[]) -+{ -+ cvmx_pko_status_t result_code; -+ uint64_t queue; -+ union cvmx_pko_mem_queue_ptrs config; -+ union cvmx_pko_reg_queue_ptrs1 config1; -+ int static_priority_base = -1; -+ int static_priority_end = -1; -+ -+ if ((port >= CVMX_PKO_NUM_OUTPUT_PORTS) -+ && (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID)) { -+ cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid port %llu\n", -+ (unsigned long long)port); -+ return CVMX_PKO_INVALID_PORT; -+ } -+ -+ if (base_queue + num_queues > CVMX_PKO_MAX_OUTPUT_QUEUES) { -+ cvmx_dprintf -+ ("ERROR: cvmx_pko_config_port: Invalid queue range %llu\n", -+ (unsigned long long)(base_queue + num_queues)); -+ return CVMX_PKO_INVALID_QUEUE; -+ } -+ -+ if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) { -+ /* -+ * Validate the static queue priority setup and set -+ * static_priority_base and static_priority_end -+ * accordingly. -+ */ -+ for (queue = 0; queue < num_queues; queue++) { -+ /* Find first queue of static priority */ -+ if (static_priority_base == -1 -+ && priority[queue] == -+ CVMX_PKO_QUEUE_STATIC_PRIORITY) -+ static_priority_base = queue; -+ /* Find last queue of static priority */ -+ if (static_priority_base != -1 -+ && static_priority_end == -1 -+ && priority[queue] != CVMX_PKO_QUEUE_STATIC_PRIORITY -+ && queue) -+ static_priority_end = queue - 1; -+ else if (static_priority_base != -1 -+ && static_priority_end == -1 -+ && queue == num_queues - 1) -+ /* all queues are static priority */ -+ static_priority_end = queue; -+ /* -+ * Check to make sure all static priority -+ * queues are contiguous. Also catches some -+ * cases of static priorites not starting at -+ * queue 0. -+ */ -+ if (static_priority_end != -1 -+ && (int)queue > static_priority_end -+ && priority[queue] == -+ CVMX_PKO_QUEUE_STATIC_PRIORITY) { -+ cvmx_dprintf("ERROR: cvmx_pko_config_port: " -+ "Static priority queues aren't " -+ "contiguous or don't start at " -+ "base queue. q: %d, eq: %d\n", -+ (int)queue, static_priority_end); -+ return CVMX_PKO_INVALID_PRIORITY; -+ } -+ } -+ if (static_priority_base > 0) { -+ cvmx_dprintf("ERROR: cvmx_pko_config_port: Static " -+ "priority queues don't start at base " -+ "queue. sq: %d\n", -+ static_priority_base); -+ return CVMX_PKO_INVALID_PRIORITY; -+ } -+#if 0 -+ cvmx_dprintf("Port %d: Static priority queue base: %d, " -+ "end: %d\n", port, -+ static_priority_base, static_priority_end); -+#endif -+ } -+ /* -+ * At this point, static_priority_base and static_priority_end -+ * are either both -1, or are valid start/end queue -+ * numbers. -+ */ -+ -+ result_code = CVMX_PKO_SUCCESS; -+ -+#ifdef PKO_DEBUG -+ cvmx_dprintf("num queues: %d (%lld,%lld)\n", num_queues, -+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE0, -+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE1); -+#endif -+ -+ for (queue = 0; queue < num_queues; queue++) { -+ uint64_t *buf_ptr = NULL; -+ -+ config1.u64 = 0; -+ config1.s.idx3 = queue >> 3; -+ config1.s.qid7 = (base_queue + queue) >> 7; -+ -+ config.u64 = 0; -+ config.s.tail = queue == (num_queues - 1); -+ config.s.index = queue; -+ config.s.port = port; -+ config.s.queue = base_queue + queue; -+ -+ if (!cvmx_octeon_is_pass1()) { -+ config.s.static_p = static_priority_base >= 0; -+ config.s.static_q = (int)queue <= static_priority_end; -+ config.s.s_tail = (int)queue == static_priority_end; -+ } -+ /* -+ * Convert the priority into an enable bit field. Try -+ * to space the bits out evenly so the packet don't -+ * get grouped up -+ */ -+ switch ((int)priority[queue]) { -+ case 0: -+ config.s.qos_mask = 0x00; -+ break; -+ case 1: -+ config.s.qos_mask = 0x01; -+ break; -+ case 2: -+ config.s.qos_mask = 0x11; -+ break; -+ case 3: -+ config.s.qos_mask = 0x49; -+ break; -+ case 4: -+ config.s.qos_mask = 0x55; -+ break; -+ case 5: -+ config.s.qos_mask = 0x57; -+ break; -+ case 6: -+ config.s.qos_mask = 0x77; -+ break; -+ case 7: -+ config.s.qos_mask = 0x7f; -+ break; -+ case 8: -+ config.s.qos_mask = 0xff; -+ break; -+ case CVMX_PKO_QUEUE_STATIC_PRIORITY: -+ /* Pass 1 will fall through to the error case */ -+ if (!cvmx_octeon_is_pass1()) { -+ config.s.qos_mask = 0xff; -+ break; -+ } -+ default: -+ cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid " -+ "priority %llu\n", -+ (unsigned long long)priority[queue]); -+ config.s.qos_mask = 0xff; -+ result_code = CVMX_PKO_INVALID_PRIORITY; -+ break; -+ } -+ -+ if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) { -+ cvmx_cmd_queue_result_t cmd_res = -+ cvmx_cmd_queue_initialize(CVMX_CMD_QUEUE_PKO -+ (base_queue + queue), -+ CVMX_PKO_MAX_QUEUE_DEPTH, -+ CVMX_FPA_OUTPUT_BUFFER_POOL, -+ CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE -+ - -+ CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST -+ * 8); -+ if (cmd_res != CVMX_CMD_QUEUE_SUCCESS) { -+ switch (cmd_res) { -+ case CVMX_CMD_QUEUE_NO_MEMORY: -+ cvmx_dprintf("ERROR: " -+ "cvmx_pko_config_port: " -+ "Unable to allocate " -+ "output buffer.\n"); -+ return CVMX_PKO_NO_MEMORY; -+ case CVMX_CMD_QUEUE_ALREADY_SETUP: -+ cvmx_dprintf -+ ("ERROR: cvmx_pko_config_port: Port already setup.\n"); -+ return CVMX_PKO_PORT_ALREADY_SETUP; -+ case CVMX_CMD_QUEUE_INVALID_PARAM: -+ default: -+ cvmx_dprintf -+ ("ERROR: cvmx_pko_config_port: Command queue initialization failed.\n"); -+ return CVMX_PKO_CMD_QUEUE_INIT_ERROR; -+ } -+ } -+ -+ buf_ptr = -+ (uint64_t *) -+ cvmx_cmd_queue_buffer(CVMX_CMD_QUEUE_PKO -+ (base_queue + queue)); -+ config.s.buf_ptr = cvmx_ptr_to_phys(buf_ptr); -+ } else -+ config.s.buf_ptr = 0; -+ -+ CVMX_SYNCWS; -+ -+ if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) -+ cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64); -+ cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64); -+ } -+ -+ return result_code; -+} -+ -+#ifdef PKO_DEBUG -+/** -+ * Show map of ports -> queues for different cores. -+ */ -+void cvmx_pko_show_queue_map() -+{ -+ int core, port; -+ int pko_output_ports = 36; -+ -+ cvmx_dprintf("port"); -+ for (port = 0; port < pko_output_ports; port++) -+ cvmx_dprintf("%3d ", port); -+ cvmx_dprintf("\n"); -+ -+ for (core = 0; core < CVMX_MAX_CORES; core++) { -+ cvmx_dprintf("\n%2d: ", core); -+ for (port = 0; port < pko_output_ports; port++) { -+ cvmx_dprintf("%3d ", -+ cvmx_pko_get_base_queue_per_core(port, -+ core)); -+ } -+ } -+ cvmx_dprintf("\n"); -+} -+#endif -+ -+/** -+ * Rate limit a PKO port to a max packets/sec. This function is only -+ * supported on CN51XX and higher, excluding CN58XX. -+ * -+ * @port: Port to rate limit -+ * @packets_s: Maximum packet/sec -+ * @burst: Maximum number of packets to burst in a row before rate -+ * limiting cuts in. -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst) -+{ -+ union cvmx_pko_mem_port_rate0 pko_mem_port_rate0; -+ union cvmx_pko_mem_port_rate1 pko_mem_port_rate1; -+ -+ pko_mem_port_rate0.u64 = 0; -+ pko_mem_port_rate0.s.pid = port; -+ pko_mem_port_rate0.s.rate_pkt = -+ cvmx_sysinfo_get()->cpu_clock_hz / packets_s / 16; -+ /* No cost per word since we are limited by packets/sec, not bits/sec */ -+ pko_mem_port_rate0.s.rate_word = 0; -+ -+ pko_mem_port_rate1.u64 = 0; -+ pko_mem_port_rate1.s.pid = port; -+ pko_mem_port_rate1.s.rate_lim = -+ ((uint64_t) pko_mem_port_rate0.s.rate_pkt * burst) >> 8; -+ -+ cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE0, pko_mem_port_rate0.u64); -+ cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE1, pko_mem_port_rate1.u64); -+ return 0; -+} -+ -+/** -+ * Rate limit a PKO port to a max bits/sec. This function is only -+ * supported on CN51XX and higher, excluding CN58XX. -+ * -+ * @port: Port to rate limit -+ * @bits_s: PKO rate limit in bits/sec -+ * @burst: Maximum number of bits to burst before rate -+ * limiting cuts in. -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst) -+{ -+ union cvmx_pko_mem_port_rate0 pko_mem_port_rate0; -+ union cvmx_pko_mem_port_rate1 pko_mem_port_rate1; -+ uint64_t clock_rate = cvmx_sysinfo_get()->cpu_clock_hz; -+ uint64_t tokens_per_bit = clock_rate * 16 / bits_s; -+ -+ pko_mem_port_rate0.u64 = 0; -+ pko_mem_port_rate0.s.pid = port; -+ /* -+ * Each packet has a 12 bytes of interframe gap, an 8 byte -+ * preamble, and a 4 byte CRC. These are not included in the -+ * per word count. Multiply by 8 to covert to bits and divide -+ * by 256 for limit granularity. -+ */ -+ pko_mem_port_rate0.s.rate_pkt = (12 + 8 + 4) * 8 * tokens_per_bit / 256; -+ /* Each 8 byte word has 64bits */ -+ pko_mem_port_rate0.s.rate_word = 64 * tokens_per_bit; -+ -+ pko_mem_port_rate1.u64 = 0; -+ pko_mem_port_rate1.s.pid = port; -+ pko_mem_port_rate1.s.rate_lim = tokens_per_bit * burst / 256; -+ -+ cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE0, pko_mem_port_rate0.u64); -+ cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE1, pko_mem_port_rate1.u64); -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-pko.h -@@ -0,0 +1,610 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * Interface to the hardware Packet Output unit. -+ * -+ * Starting with SDK 1.7.0, the PKO output functions now support -+ * two types of locking. CVMX_PKO_LOCK_ATOMIC_TAG continues to -+ * function similarly to previous SDKs by using POW atomic tags -+ * to preserve ordering and exclusivity. As a new option, you -+ * can now pass CVMX_PKO_LOCK_CMD_QUEUE which uses a ll/sc -+ * memory based locking instead. This locking has the advantage -+ * of not affecting the tag state but doesn't preserve packet -+ * ordering. CVMX_PKO_LOCK_CMD_QUEUE is appropriate in most -+ * generic code while CVMX_PKO_LOCK_CMD_QUEUE should be used -+ * with hand tuned fast path code. -+ * -+ * Some of other SDK differences visible to the command command -+ * queuing: -+ * - PKO indexes are no longer stored in the FAU. A large -+ * percentage of the FAU register block used to be tied up -+ * maintaining PKO queue pointers. These are now stored in a -+ * global named block. -+ * - The PKO <b>use_locking</b> parameter can now have a global -+ * effect. Since all application use the same named block, -+ * queue locking correctly applies across all operating -+ * systems when using CVMX_PKO_LOCK_CMD_QUEUE. -+ * - PKO 3 word commands are now supported. Use -+ * cvmx_pko_send_packet_finish3(). -+ * -+ */ -+ -+#ifndef __CVMX_PKO_H__ -+#define __CVMX_PKO_H__ -+ -+#include "cvmx-fpa.h" -+#include "cvmx-pow.h" -+#include "cvmx-cmd-queue.h" -+#include "cvmx-pko-defs.h" -+ -+/* Adjust the command buffer size by 1 word so that in the case of using only -+ * two word PKO commands no command words stradle buffers. The useful values -+ * for this are 0 and 1. */ -+#define CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST (1) -+ -+#define CVMX_PKO_MAX_OUTPUT_QUEUES_STATIC 256 -+#define CVMX_PKO_MAX_OUTPUT_QUEUES ((OCTEON_IS_MODEL(OCTEON_CN31XX) || \ -+ OCTEON_IS_MODEL(OCTEON_CN3010) || OCTEON_IS_MODEL(OCTEON_CN3005) || \ -+ OCTEON_IS_MODEL(OCTEON_CN50XX)) ? 32 : \ -+ (OCTEON_IS_MODEL(OCTEON_CN58XX) || \ -+ OCTEON_IS_MODEL(OCTEON_CN56XX)) ? 256 : 128) -+#define CVMX_PKO_NUM_OUTPUT_PORTS 40 -+/* use this for queues that are not used */ -+#define CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID 63 -+#define CVMX_PKO_QUEUE_STATIC_PRIORITY 9 -+#define CVMX_PKO_ILLEGAL_QUEUE 0xFFFF -+#define CVMX_PKO_MAX_QUEUE_DEPTH 0 -+ -+typedef enum { -+ CVMX_PKO_SUCCESS, -+ CVMX_PKO_INVALID_PORT, -+ CVMX_PKO_INVALID_QUEUE, -+ CVMX_PKO_INVALID_PRIORITY, -+ CVMX_PKO_NO_MEMORY, -+ CVMX_PKO_PORT_ALREADY_SETUP, -+ CVMX_PKO_CMD_QUEUE_INIT_ERROR -+} cvmx_pko_status_t; -+ -+/** -+ * This enumeration represents the differnet locking modes supported by PKO. -+ */ -+typedef enum { -+ /* -+ * PKO doesn't do any locking. It is the responsibility of the -+ * application to make sure that no other core is accessing -+ * the same queue at the smae time -+ */ -+ CVMX_PKO_LOCK_NONE = 0, -+ /* -+ * PKO performs an atomic tagswitch to insure exclusive access -+ * to the output queue. This will maintain packet ordering on -+ * output. -+ */ -+ CVMX_PKO_LOCK_ATOMIC_TAG = 1, -+ /* -+ * PKO uses the common command queue locks to insure exclusive -+ * access to the output queue. This is a memory based -+ * ll/sc. This is the most portable locking mechanism. -+ */ -+ CVMX_PKO_LOCK_CMD_QUEUE = 2, -+} cvmx_pko_lock_t; -+ -+typedef struct { -+ uint32_t packets; -+ uint64_t octets; -+ uint64_t doorbell; -+} cvmx_pko_port_status_t; -+ -+/** -+ * This structure defines the address to use on a packet enqueue -+ */ -+typedef union { -+ uint64_t u64; -+ struct { -+ /* Must CVMX_IO_SEG */ -+ uint64_t mem_space:2; -+ /* Must be zero */ -+ uint64_t reserved:13; -+ /* Must be one */ -+ uint64_t is_io:1; -+ /* The ID of the device on the non-coherent bus */ -+ uint64_t did:8; -+ /* Must be zero */ -+ uint64_t reserved2:4; -+ /* Must be zero */ -+ uint64_t reserved3:18; -+ /* -+ * The hardware likes to have the output port in -+ * addition to the output queue, -+ */ -+ uint64_t port:6; -+ /* -+ * The output queue to send the packet to (0-127 are -+ * legal) -+ */ -+ uint64_t queue:9; -+ /* Must be zero */ -+ uint64_t reserved4:3; -+ } s; -+} cvmx_pko_doorbell_address_t; -+ -+/** -+ * Structure of the first packet output command word. -+ */ -+typedef union { -+ uint64_t u64; -+ struct { -+ /* -+ * The size of the reg1 operation - could be 8, 16, -+ * 32, or 64 bits. -+ */ -+ uint64_t size1:2; -+ /* -+ * The size of the reg0 operation - could be 8, 16, -+ * 32, or 64 bits. -+ */ -+ uint64_t size0:2; -+ /* -+ * If set, subtract 1, if clear, subtract packet -+ * size. -+ */ -+ uint64_t subone1:1; -+ /* -+ * The register, subtract will be done if reg1 is -+ * non-zero. -+ */ -+ uint64_t reg1:11; -+ /* If set, subtract 1, if clear, subtract packet size */ -+ uint64_t subone0:1; -+ /* The register, subtract will be done if reg0 is non-zero */ -+ uint64_t reg0:11; -+ /* -+ * When set, interpret segment pointer and segment -+ * bytes in little endian order. -+ */ -+ uint64_t le:1; -+ /* -+ * When set, packet data not allocated in L2 cache by -+ * PKO. -+ */ -+ uint64_t n2:1; -+ /* -+ * If set and rsp is set, word3 contains a pointer to -+ * a work queue entry. -+ */ -+ uint64_t wqp:1; -+ /* If set, the hardware will send a response when done */ -+ uint64_t rsp:1; -+ /* -+ * If set, the supplied pkt_ptr is really a pointer to -+ * a list of pkt_ptr's. -+ */ -+ uint64_t gather:1; -+ /* -+ * If ipoffp1 is non zero, (ipoffp1-1) is the number -+ * of bytes to IP header, and the hardware will -+ * calculate and insert the UDP/TCP checksum. -+ */ -+ uint64_t ipoffp1:7; -+ /* -+ * If set, ignore the I bit (force to zero) from all -+ * pointer structures. -+ */ -+ uint64_t ignore_i:1; -+ /* -+ * If clear, the hardware will attempt to free the -+ * buffers containing the packet. -+ */ -+ uint64_t dontfree:1; -+ /* -+ * The total number of segs in the packet, if gather -+ * set, also gather list length. -+ */ -+ uint64_t segs:6; -+ /* Including L2, but no trailing CRC */ -+ uint64_t total_bytes:16; -+ } s; -+} cvmx_pko_command_word0_t; -+ -+/* CSR typedefs have been moved to cvmx-csr-*.h */ -+ -+/** -+ * Definition of internal state for Packet output processing -+ */ -+typedef struct { -+ /* ptr to start of buffer, offset kept in FAU reg */ -+ uint64_t *start_ptr; -+} cvmx_pko_state_elem_t; -+ -+/** -+ * Call before any other calls to initialize the packet -+ * output system. -+ */ -+extern void cvmx_pko_initialize_global(void); -+extern int cvmx_pko_initialize_local(void); -+ -+/** -+ * Enables the packet output hardware. It must already be -+ * configured. -+ */ -+extern void cvmx_pko_enable(void); -+ -+/** -+ * Disables the packet output. Does not affect any configuration. -+ */ -+extern void cvmx_pko_disable(void); -+ -+/** -+ * Shutdown and free resources required by packet output. -+ */ -+ -+extern void cvmx_pko_shutdown(void); -+ -+/** -+ * Configure a output port and the associated queues for use. -+ * -+ * @port: Port to configure. -+ * @base_queue: First queue number to associate with this port. -+ * @num_queues: Number of queues t oassociate with this port -+ * @priority: Array of priority levels for each queue. Values are -+ * allowed to be 1-8. A value of 8 get 8 times the traffic -+ * of a value of 1. There must be num_queues elements in the -+ * array. -+ */ -+extern cvmx_pko_status_t cvmx_pko_config_port(uint64_t port, -+ uint64_t base_queue, -+ uint64_t num_queues, -+ const uint64_t priority[]); -+ -+/** -+ * Ring the packet output doorbell. This tells the packet -+ * output hardware that "len" command words have been added -+ * to its pending list. This command includes the required -+ * CVMX_SYNCWS before the doorbell ring. -+ * -+ * @port: Port the packet is for -+ * @queue: Queue the packet is for -+ * @len: Length of the command in 64 bit words -+ */ -+static inline void cvmx_pko_doorbell(uint64_t port, uint64_t queue, -+ uint64_t len) -+{ -+ cvmx_pko_doorbell_address_t ptr; -+ -+ ptr.u64 = 0; -+ ptr.s.mem_space = CVMX_IO_SEG; -+ ptr.s.did = CVMX_OCT_DID_PKT_SEND; -+ ptr.s.is_io = 1; -+ ptr.s.port = port; -+ ptr.s.queue = queue; -+ /* -+ * Need to make sure output queue data is in DRAM before -+ * doorbell write. -+ */ -+ CVMX_SYNCWS; -+ cvmx_write_io(ptr.u64, len); -+} -+ -+/** -+ * Prepare to send a packet. This may initiate a tag switch to -+ * get exclusive access to the output queue structure, and -+ * performs other prep work for the packet send operation. -+ * -+ * cvmx_pko_send_packet_finish() MUST be called after this function is called, -+ * and must be called with the same port/queue/use_locking arguments. -+ * -+ * The use_locking parameter allows the caller to use three -+ * possible locking modes. -+ * - CVMX_PKO_LOCK_NONE -+ * - PKO doesn't do any locking. It is the responsibility -+ * of the application to make sure that no other core -+ * is accessing the same queue at the smae time. -+ * - CVMX_PKO_LOCK_ATOMIC_TAG -+ * - PKO performs an atomic tagswitch to insure exclusive -+ * access to the output queue. This will maintain -+ * packet ordering on output. -+ * - CVMX_PKO_LOCK_CMD_QUEUE -+ * - PKO uses the common command queue locks to insure -+ * exclusive access to the output queue. This is a -+ * memory based ll/sc. This is the most portable -+ * locking mechanism. -+ * -+ * NOTE: If atomic locking is used, the POW entry CANNOT be -+ * descheduled, as it does not contain a valid WQE pointer. -+ * -+ * @port: Port to send it on -+ * @queue: Queue to use -+ * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or -+ * CVMX_PKO_LOCK_CMD_QUEUE -+ */ -+ -+static inline void cvmx_pko_send_packet_prepare(uint64_t port, uint64_t queue, -+ cvmx_pko_lock_t use_locking) -+{ -+ if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG) { -+ /* -+ * Must do a full switch here to handle all cases. We -+ * use a fake WQE pointer, as the POW does not access -+ * this memory. The WQE pointer and group are only -+ * used if this work is descheduled, which is not -+ * supported by the -+ * cvmx_pko_send_packet_prepare/cvmx_pko_send_packet_finish -+ * combination. Note that this is a special case in -+ * which these fake values can be used - this is not a -+ * general technique. -+ */ -+ uint32_t tag = -+ CVMX_TAG_SW_BITS_INTERNAL << CVMX_TAG_SW_SHIFT | -+ CVMX_TAG_SUBGROUP_PKO << CVMX_TAG_SUBGROUP_SHIFT | -+ (CVMX_TAG_SUBGROUP_MASK & queue); -+ cvmx_pow_tag_sw_full((cvmx_wqe_t *) cvmx_phys_to_ptr(0x80), tag, -+ CVMX_POW_TAG_TYPE_ATOMIC, 0); -+ } -+} -+ -+/** -+ * Complete packet output. cvmx_pko_send_packet_prepare() must be -+ * called exactly once before this, and the same parameters must be -+ * passed to both cvmx_pko_send_packet_prepare() and -+ * cvmx_pko_send_packet_finish(). -+ * -+ * @port: Port to send it on -+ * @queue: Queue to use -+ * @pko_command: -+ * PKO HW command word -+ * @packet: Packet to send -+ * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or -+ * CVMX_PKO_LOCK_CMD_QUEUE -+ * -+ * Returns returns CVMX_PKO_SUCCESS on success, or error code on -+ * failure of output -+ */ -+static inline cvmx_pko_status_t cvmx_pko_send_packet_finish( -+ uint64_t port, -+ uint64_t queue, -+ cvmx_pko_command_word0_t pko_command, -+ union cvmx_buf_ptr packet, -+ cvmx_pko_lock_t use_locking) -+{ -+ cvmx_cmd_queue_result_t result; -+ if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG) -+ cvmx_pow_tag_sw_wait(); -+ result = cvmx_cmd_queue_write2(CVMX_CMD_QUEUE_PKO(queue), -+ (use_locking == CVMX_PKO_LOCK_CMD_QUEUE), -+ pko_command.u64, packet.u64); -+ if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) { -+ cvmx_pko_doorbell(port, queue, 2); -+ return CVMX_PKO_SUCCESS; -+ } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY) -+ || (result == CVMX_CMD_QUEUE_FULL)) { -+ return CVMX_PKO_NO_MEMORY; -+ } else { -+ return CVMX_PKO_INVALID_QUEUE; -+ } -+} -+ -+/** -+ * Complete packet output. cvmx_pko_send_packet_prepare() must be -+ * called exactly once before this, and the same parameters must be -+ * passed to both cvmx_pko_send_packet_prepare() and -+ * cvmx_pko_send_packet_finish(). -+ * -+ * @port: Port to send it on -+ * @queue: Queue to use -+ * @pko_command: -+ * PKO HW command word -+ * @packet: Packet to send -+ * @addr: Plysical address of a work queue entry or physical address -+ * to zero on complete. -+ * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or -+ * CVMX_PKO_LOCK_CMD_QUEUE -+ * -+ * Returns returns CVMX_PKO_SUCCESS on success, or error code on -+ * failure of output -+ */ -+static inline cvmx_pko_status_t cvmx_pko_send_packet_finish3( -+ uint64_t port, -+ uint64_t queue, -+ cvmx_pko_command_word0_t pko_command, -+ union cvmx_buf_ptr packet, -+ uint64_t addr, -+ cvmx_pko_lock_t use_locking) -+{ -+ cvmx_cmd_queue_result_t result; -+ if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG) -+ cvmx_pow_tag_sw_wait(); -+ result = cvmx_cmd_queue_write3(CVMX_CMD_QUEUE_PKO(queue), -+ (use_locking == CVMX_PKO_LOCK_CMD_QUEUE), -+ pko_command.u64, packet.u64, addr); -+ if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) { -+ cvmx_pko_doorbell(port, queue, 3); -+ return CVMX_PKO_SUCCESS; -+ } else if ((result == CVMX_CMD_QUEUE_NO_MEMORY) -+ || (result == CVMX_CMD_QUEUE_FULL)) { -+ return CVMX_PKO_NO_MEMORY; -+ } else { -+ return CVMX_PKO_INVALID_QUEUE; -+ } -+} -+ -+/** -+ * Return the pko output queue associated with a port and a specific core. -+ * In normal mode (PKO lockless operation is disabled), the value returned -+ * is the base queue. -+ * -+ * @port: Port number -+ * @core: Core to get queue for -+ * -+ * Returns Core-specific output queue -+ */ -+static inline int cvmx_pko_get_base_queue_per_core(int port, int core) -+{ -+#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0 -+#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0 16 -+#endif -+#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1 -+#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1 16 -+#endif -+ -+ if (port < CVMX_PKO_MAX_PORTS_INTERFACE0) -+ return port * CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + core; -+ else if (port >= 16 && port < 16 + CVMX_PKO_MAX_PORTS_INTERFACE1) -+ return CVMX_PKO_MAX_PORTS_INTERFACE0 * -+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + (port - -+ 16) * -+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + core; -+ else if ((port >= 32) && (port < 36)) -+ return CVMX_PKO_MAX_PORTS_INTERFACE0 * -+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + -+ CVMX_PKO_MAX_PORTS_INTERFACE1 * -+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + (port - -+ 32) * -+ CVMX_PKO_QUEUES_PER_PORT_PCI; -+ else if ((port >= 36) && (port < 40)) -+ return CVMX_PKO_MAX_PORTS_INTERFACE0 * -+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + -+ CVMX_PKO_MAX_PORTS_INTERFACE1 * -+ CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + -+ 4 * CVMX_PKO_QUEUES_PER_PORT_PCI + (port - -+ 36) * -+ CVMX_PKO_QUEUES_PER_PORT_LOOP; -+ else -+ /* Given the limit on the number of ports we can map to -+ * CVMX_MAX_OUTPUT_QUEUES_STATIC queues (currently 256, -+ * divided among all cores), the remaining unmapped ports -+ * are assigned an illegal queue number */ -+ return CVMX_PKO_ILLEGAL_QUEUE; -+} -+ -+/** -+ * For a given port number, return the base pko output queue -+ * for the port. -+ * -+ * @port: Port number -+ * Returns Base output queue -+ */ -+static inline int cvmx_pko_get_base_queue(int port) -+{ -+ return cvmx_pko_get_base_queue_per_core(port, 0); -+} -+ -+/** -+ * For a given port number, return the number of pko output queues. -+ * -+ * @port: Port number -+ * Returns Number of output queues -+ */ -+static inline int cvmx_pko_get_num_queues(int port) -+{ -+ if (port < 16) -+ return CVMX_PKO_QUEUES_PER_PORT_INTERFACE0; -+ else if (port < 32) -+ return CVMX_PKO_QUEUES_PER_PORT_INTERFACE1; -+ else if (port < 36) -+ return CVMX_PKO_QUEUES_PER_PORT_PCI; -+ else if (port < 40) -+ return CVMX_PKO_QUEUES_PER_PORT_LOOP; -+ else -+ return 0; -+} -+ -+/** -+ * Get the status counters for a port. -+ * -+ * @port_num: Port number to get statistics for. -+ * @clear: Set to 1 to clear the counters after they are read -+ * @status: Where to put the results. -+ */ -+static inline void cvmx_pko_get_port_status(uint64_t port_num, uint64_t clear, -+ cvmx_pko_port_status_t *status) -+{ -+ union cvmx_pko_reg_read_idx pko_reg_read_idx; -+ union cvmx_pko_mem_count0 pko_mem_count0; -+ union cvmx_pko_mem_count1 pko_mem_count1; -+ -+ pko_reg_read_idx.u64 = 0; -+ pko_reg_read_idx.s.index = port_num; -+ cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64); -+ -+ pko_mem_count0.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT0); -+ status->packets = pko_mem_count0.s.count; -+ if (clear) { -+ pko_mem_count0.s.count = port_num; -+ cvmx_write_csr(CVMX_PKO_MEM_COUNT0, pko_mem_count0.u64); -+ } -+ -+ pko_mem_count1.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT1); -+ status->octets = pko_mem_count1.s.count; -+ if (clear) { -+ pko_mem_count1.s.count = port_num; -+ cvmx_write_csr(CVMX_PKO_MEM_COUNT1, pko_mem_count1.u64); -+ } -+ -+ if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) { -+ union cvmx_pko_mem_debug9 debug9; -+ pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num); -+ cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64); -+ debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9); -+ status->doorbell = debug9.cn38xx.doorbell; -+ } else { -+ union cvmx_pko_mem_debug8 debug8; -+ pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num); -+ cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64); -+ debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8); -+ status->doorbell = debug8.cn58xx.doorbell; -+ } -+} -+ -+/** -+ * Rate limit a PKO port to a max packets/sec. This function is only -+ * supported on CN57XX, CN56XX, CN55XX, and CN54XX. -+ * -+ * @port: Port to rate limit -+ * @packets_s: Maximum packet/sec -+ * @burst: Maximum number of packets to burst in a row before rate -+ * limiting cuts in. -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst); -+ -+/** -+ * Rate limit a PKO port to a max bits/sec. This function is only -+ * supported on CN57XX, CN56XX, CN55XX, and CN54XX. -+ * -+ * @port: Port to rate limit -+ * @bits_s: PKO rate limit in bits/sec -+ * @burst: Maximum number of bits to burst before rate -+ * limiting cuts in. -+ * -+ * Returns Zero on success, negative on failure -+ */ -+extern int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst); -+ -+#endif /* __CVMX_PKO_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-pow.h -@@ -0,0 +1,1982 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * Interface to the hardware Packet Order / Work unit. -+ * -+ * New, starting with SDK 1.7.0, cvmx-pow supports a number of -+ * extended consistency checks. The define -+ * CVMX_ENABLE_POW_CHECKS controls the runtime insertion of POW -+ * internal state checks to find common programming errors. If -+ * CVMX_ENABLE_POW_CHECKS is not defined, checks are by default -+ * enabled. For example, cvmx-pow will check for the following -+ * program errors or POW state inconsistency. -+ * - Requesting a POW operation with an active tag switch in -+ * progress. -+ * - Waiting for a tag switch to complete for an excessively -+ * long period. This is normally a sign of an error in locking -+ * causing deadlock. -+ * - Illegal tag switches from NULL_NULL. -+ * - Illegal tag switches from NULL. -+ * - Illegal deschedule request. -+ * - WQE pointer not matching the one attached to the core by -+ * the POW. -+ * -+ */ -+ -+#ifndef __CVMX_POW_H__ -+#define __CVMX_POW_H__ -+ -+#include <asm/octeon/cvmx-pow-defs.h> -+ -+#include "cvmx-scratch.h" -+#include "cvmx-wqe.h" -+ -+/* Default to having all POW constancy checks turned on */ -+#ifndef CVMX_ENABLE_POW_CHECKS -+#define CVMX_ENABLE_POW_CHECKS 1 -+#endif -+ -+enum cvmx_pow_tag_type { -+ /* Tag ordering is maintained */ -+ CVMX_POW_TAG_TYPE_ORDERED = 0L, -+ /* Tag ordering is maintained, and at most one PP has the tag */ -+ CVMX_POW_TAG_TYPE_ATOMIC = 1L, -+ /* -+ * The work queue entry from the order - NEVER tag switch from -+ * NULL to NULL -+ */ -+ CVMX_POW_TAG_TYPE_NULL = 2L, -+ /* A tag switch to NULL, and there is no space reserved in POW -+ * - NEVER tag switch to NULL_NULL -+ * - NEVER tag switch from NULL_NULL -+ * - NULL_NULL is entered at the beginning of time and on a deschedule. -+ * - NULL_NULL can be exited by a new work request. A NULL_SWITCH -+ * load can also switch the state to NULL -+ */ -+ CVMX_POW_TAG_TYPE_NULL_NULL = 3L -+}; -+ -+/** -+ * Wait flag values for pow functions. -+ */ -+typedef enum { -+ CVMX_POW_WAIT = 1, -+ CVMX_POW_NO_WAIT = 0, -+} cvmx_pow_wait_t; -+ -+/** -+ * POW tag operations. These are used in the data stored to the POW. -+ */ -+typedef enum { -+ /* -+ * switch the tag (only) for this PP -+ * - the previous tag should be non-NULL in this case -+ * - tag switch response required -+ * - fields used: op, type, tag -+ */ -+ CVMX_POW_TAG_OP_SWTAG = 0L, -+ /* -+ * switch the tag for this PP, with full information -+ * - this should be used when the previous tag is NULL -+ * - tag switch response required -+ * - fields used: address, op, grp, type, tag -+ */ -+ CVMX_POW_TAG_OP_SWTAG_FULL = 1L, -+ /* -+ * switch the tag (and/or group) for this PP and de-schedule -+ * - OK to keep the tag the same and only change the group -+ * - fields used: op, no_sched, grp, type, tag -+ */ -+ CVMX_POW_TAG_OP_SWTAG_DESCH = 2L, -+ /* -+ * just de-schedule -+ * - fields used: op, no_sched -+ */ -+ CVMX_POW_TAG_OP_DESCH = 3L, -+ /* -+ * create an entirely new work queue entry -+ * - fields used: address, op, qos, grp, type, tag -+ */ -+ CVMX_POW_TAG_OP_ADDWQ = 4L, -+ /* -+ * just update the work queue pointer and grp for this PP -+ * - fields used: address, op, grp -+ */ -+ CVMX_POW_TAG_OP_UPDATE_WQP_GRP = 5L, -+ /* -+ * set the no_sched bit on the de-schedule list -+ * -+ * - does nothing if the selected entry is not on the -+ * de-schedule list -+ * -+ * - does nothing if the stored work queue pointer does not -+ * match the address field -+ * -+ * - fields used: address, index, op -+ * -+ * Before issuing a *_NSCHED operation, SW must guarantee -+ * that all prior deschedules and set/clr NSCHED operations -+ * are complete and all prior switches are complete. The -+ * hardware provides the opsdone bit and swdone bit for SW -+ * polling. After issuing a *_NSCHED operation, SW must -+ * guarantee that the set/clr NSCHED is complete before any -+ * subsequent operations. -+ */ -+ CVMX_POW_TAG_OP_SET_NSCHED = 6L, -+ /* -+ * clears the no_sched bit on the de-schedule list -+ * -+ * - does nothing if the selected entry is not on the -+ * de-schedule list -+ * -+ * - does nothing if the stored work queue pointer does not -+ * match the address field -+ * -+ * - fields used: address, index, op -+ * -+ * Before issuing a *_NSCHED operation, SW must guarantee that -+ * all prior deschedules and set/clr NSCHED operations are -+ * complete and all prior switches are complete. The hardware -+ * provides the opsdone bit and swdone bit for SW -+ * polling. After issuing a *_NSCHED operation, SW must -+ * guarantee that the set/clr NSCHED is complete before any -+ * subsequent operations. -+ */ -+ CVMX_POW_TAG_OP_CLR_NSCHED = 7L, -+ /* do nothing */ -+ CVMX_POW_TAG_OP_NOP = 15L -+} cvmx_pow_tag_op_t; -+ -+/** -+ * This structure defines the store data on a store to POW -+ */ -+typedef union { -+ uint64_t u64; -+ struct { -+ /* -+ * Don't reschedule this entry. no_sched is used for -+ * CVMX_POW_TAG_OP_SWTAG_DESCH and -+ * CVMX_POW_TAG_OP_DESCH -+ */ -+ uint64_t no_sched:1; -+ uint64_t unused:2; -+ /* Tontains index of entry for a CVMX_POW_TAG_OP_*_NSCHED */ -+ uint64_t index:13; -+ /* The operation to perform */ -+ cvmx_pow_tag_op_t op:4; -+ uint64_t unused2:2; -+ /* -+ * The QOS level for the packet. qos is only used for -+ * CVMX_POW_TAG_OP_ADDWQ -+ */ -+ uint64_t qos:3; -+ /* -+ * The group that the work queue entry will be -+ * scheduled to grp is used for CVMX_POW_TAG_OP_ADDWQ, -+ * CVMX_POW_TAG_OP_SWTAG_FULL, -+ * CVMX_POW_TAG_OP_SWTAG_DESCH, and -+ * CVMX_POW_TAG_OP_UPDATE_WQP_GRP -+ */ -+ uint64_t grp:4; -+ /* -+ * The type of the tag. type is used for everything -+ * except CVMX_POW_TAG_OP_DESCH, -+ * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and -+ * CVMX_POW_TAG_OP_*_NSCHED -+ */ -+ uint64_t type:3; -+ /* -+ * The actual tag. tag is used for everything except -+ * CVMX_POW_TAG_OP_DESCH, -+ * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and -+ * CVMX_POW_TAG_OP_*_NSCHED -+ */ -+ uint64_t tag:32; -+ } s; -+} cvmx_pow_tag_req_t; -+ -+/** -+ * This structure describes the address to load stuff from POW -+ */ -+typedef union { -+ uint64_t u64; -+ -+ /** -+ * Address for new work request loads (did<2:0> == 0) -+ */ -+ struct { -+ /* Mips64 address region. Should be CVMX_IO_SEG */ -+ uint64_t mem_region:2; -+ /* Must be zero */ -+ uint64_t reserved_49_61:13; -+ /* Must be one */ -+ uint64_t is_io:1; -+ /* the ID of POW -- did<2:0> == 0 in this case */ -+ uint64_t did:8; -+ /* Must be zero */ -+ uint64_t reserved_4_39:36; -+ /* -+ * If set, don't return load response until work is -+ * available. -+ */ -+ uint64_t wait:1; -+ /* Must be zero */ -+ uint64_t reserved_0_2:3; -+ } swork; -+ -+ /** -+ * Address for loads to get POW internal status -+ */ -+ struct { -+ /* Mips64 address region. Should be CVMX_IO_SEG */ -+ uint64_t mem_region:2; -+ /* Must be zero */ -+ uint64_t reserved_49_61:13; -+ /* Must be one */ -+ uint64_t is_io:1; -+ /* the ID of POW -- did<2:0> == 1 in this case */ -+ uint64_t did:8; -+ /* Must be zero */ -+ uint64_t reserved_10_39:30; -+ /* The core id to get status for */ -+ uint64_t coreid:4; -+ /* -+ * If set and get_cur is set, return reverse tag-list -+ * pointer rather than forward tag-list pointer. -+ */ -+ uint64_t get_rev:1; -+ /* -+ * If set, return current status rather than pending -+ * status. -+ */ -+ uint64_t get_cur:1; -+ /* -+ * If set, get the work-queue pointer rather than -+ * tag/type. -+ */ -+ uint64_t get_wqp:1; -+ /* Must be zero */ -+ uint64_t reserved_0_2:3; -+ } sstatus; -+ -+ /** -+ * Address for memory loads to get POW internal state -+ */ -+ struct { -+ /* Mips64 address region. Should be CVMX_IO_SEG */ -+ uint64_t mem_region:2; -+ /* Must be zero */ -+ uint64_t reserved_49_61:13; -+ /* Must be one */ -+ uint64_t is_io:1; -+ /* the ID of POW -- did<2:0> == 2 in this case */ -+ uint64_t did:8; -+ /* Must be zero */ -+ uint64_t reserved_16_39:24; -+ /* POW memory index */ -+ uint64_t index:11; -+ /* -+ * If set, return deschedule information rather than -+ * the standard response for work-queue index (invalid -+ * if the work-queue entry is not on the deschedule -+ * list). -+ */ -+ uint64_t get_des:1; -+ /* -+ * If set, get the work-queue pointer rather than -+ * tag/type (no effect when get_des set). -+ */ -+ uint64_t get_wqp:1; -+ /* Must be zero */ -+ uint64_t reserved_0_2:3; -+ } smemload; -+ -+ /** -+ * Address for index/pointer loads -+ */ -+ struct { -+ /* Mips64 address region. Should be CVMX_IO_SEG */ -+ uint64_t mem_region:2; -+ /* Must be zero */ -+ uint64_t reserved_49_61:13; -+ /* Must be one */ -+ uint64_t is_io:1; -+ /* the ID of POW -- did<2:0> == 3 in this case */ -+ uint64_t did:8; -+ /* Must be zero */ -+ uint64_t reserved_9_39:31; -+ /* -+ * when {get_rmt ==0 AND get_des_get_tail == 0}, this -+ * field selects one of eight POW internal-input -+ * queues (0-7), one per QOS level; values 8-15 are -+ * illegal in this case; when {get_rmt ==0 AND -+ * get_des_get_tail == 1}, this field selects one of -+ * 16 deschedule lists (per group); when get_rmt ==1, -+ * this field selects one of 16 memory-input queue -+ * lists. The two memory-input queue lists associated -+ * with each QOS level are: -+ * -+ * - qosgrp = 0, qosgrp = 8: QOS0 -+ * - qosgrp = 1, qosgrp = 9: QOS1 -+ * - qosgrp = 2, qosgrp = 10: QOS2 -+ * - qosgrp = 3, qosgrp = 11: QOS3 -+ * - qosgrp = 4, qosgrp = 12: QOS4 -+ * - qosgrp = 5, qosgrp = 13: QOS5 -+ * - qosgrp = 6, qosgrp = 14: QOS6 -+ * - qosgrp = 7, qosgrp = 15: QOS7 -+ */ -+ uint64_t qosgrp:4; -+ /* -+ * If set and get_rmt is clear, return deschedule list -+ * indexes rather than indexes for the specified qos -+ * level; if set and get_rmt is set, return the tail -+ * pointer rather than the head pointer for the -+ * specified qos level. -+ */ -+ uint64_t get_des_get_tail:1; -+ /* -+ * If set, return remote pointers rather than the -+ * local indexes for the specified qos level. -+ */ -+ uint64_t get_rmt:1; -+ /* Must be zero */ -+ uint64_t reserved_0_2:3; -+ } sindexload; -+ -+ /** -+ * address for NULL_RD request (did<2:0> == 4) when this is read, -+ * HW attempts to change the state to NULL if it is NULL_NULL (the -+ * hardware cannot switch from NULL_NULL to NULL if a POW entry is -+ * not available - software may need to recover by finishing -+ * another piece of work before a POW entry can ever become -+ * available.) -+ */ -+ struct { -+ /* Mips64 address region. Should be CVMX_IO_SEG */ -+ uint64_t mem_region:2; -+ /* Must be zero */ -+ uint64_t reserved_49_61:13; -+ /* Must be one */ -+ uint64_t is_io:1; -+ /* the ID of POW -- did<2:0> == 4 in this case */ -+ uint64_t did:8; -+ /* Must be zero */ -+ uint64_t reserved_0_39:40; -+ } snull_rd; -+} cvmx_pow_load_addr_t; -+ -+/** -+ * This structure defines the response to a load/SENDSINGLE to POW -+ * (except CSR reads) -+ */ -+typedef union { -+ uint64_t u64; -+ -+ /** -+ * Response to new work request loads -+ */ -+ struct { -+ /* -+ * Set when no new work queue entry was returned. * -+ * If there was de-scheduled work, the HW will -+ * definitely return it. When this bit is set, it -+ * could mean either mean: -+ * -+ * - There was no work, or -+ * -+ * - There was no work that the HW could find. This -+ * case can happen, regardless of the wait bit value -+ * in the original request, when there is work in -+ * the IQ's that is too deep down the list. -+ */ -+ uint64_t no_work:1; -+ /* Must be zero */ -+ uint64_t reserved_40_62:23; -+ /* 36 in O1 -- the work queue pointer */ -+ uint64_t addr:40; -+ } s_work; -+ -+ /** -+ * Result for a POW Status Load (when get_cur==0 and get_wqp==0) -+ */ -+ struct { -+ uint64_t reserved_62_63:2; -+ /* Set when there is a pending non-NULL SWTAG or -+ * SWTAG_FULL, and the POW entry has not left the list -+ * for the original tag. */ -+ uint64_t pend_switch:1; -+ /* Set when SWTAG_FULL and pend_switch is set. */ -+ uint64_t pend_switch_full:1; -+ /* -+ * Set when there is a pending NULL SWTAG, or an -+ * implicit switch to NULL. -+ */ -+ uint64_t pend_switch_null:1; -+ /* Set when there is a pending DESCHED or SWTAG_DESCHED. */ -+ uint64_t pend_desched:1; -+ /* -+ * Set when there is a pending SWTAG_DESCHED and -+ * pend_desched is set. -+ */ -+ uint64_t pend_desched_switch:1; -+ /* Set when nosched is desired and pend_desched is set. */ -+ uint64_t pend_nosched:1; -+ /* Set when there is a pending GET_WORK. */ -+ uint64_t pend_new_work:1; -+ /* -+ * When pend_new_work is set, this bit indicates that -+ * the wait bit was set. -+ */ -+ uint64_t pend_new_work_wait:1; -+ /* Set when there is a pending NULL_RD. */ -+ uint64_t pend_null_rd:1; -+ /* Set when there is a pending CLR_NSCHED. */ -+ uint64_t pend_nosched_clr:1; -+ uint64_t reserved_51:1; -+ /* This is the index when pend_nosched_clr is set. */ -+ uint64_t pend_index:11; -+ /* -+ * This is the new_grp when (pend_desched AND -+ * pend_desched_switch) is set. -+ */ -+ uint64_t pend_grp:4; -+ uint64_t reserved_34_35:2; -+ /* -+ * This is the tag type when pend_switch or -+ * (pend_desched AND pend_desched_switch) are set. -+ */ -+ uint64_t pend_type:2; -+ /* -+ * - this is the tag when pend_switch or (pend_desched -+ * AND pend_desched_switch) are set. -+ */ -+ uint64_t pend_tag:32; -+ } s_sstatus0; -+ -+ /** -+ * Result for a POW Status Load (when get_cur==0 and get_wqp==1) -+ */ -+ struct { -+ uint64_t reserved_62_63:2; -+ /* -+ * Set when there is a pending non-NULL SWTAG or -+ * SWTAG_FULL, and the POW entry has not left the list -+ * for the original tag. -+ */ -+ uint64_t pend_switch:1; -+ /* Set when SWTAG_FULL and pend_switch is set. */ -+ uint64_t pend_switch_full:1; -+ /* -+ * Set when there is a pending NULL SWTAG, or an -+ * implicit switch to NULL. -+ */ -+ uint64_t pend_switch_null:1; -+ /* -+ * Set when there is a pending DESCHED or -+ * SWTAG_DESCHED. -+ */ -+ uint64_t pend_desched:1; -+ /* -+ * Set when there is a pending SWTAG_DESCHED and -+ * pend_desched is set. -+ */ -+ uint64_t pend_desched_switch:1; -+ /* Set when nosched is desired and pend_desched is set. */ -+ uint64_t pend_nosched:1; -+ /* Set when there is a pending GET_WORK. */ -+ uint64_t pend_new_work:1; -+ /* -+ * When pend_new_work is set, this bit indicates that -+ * the wait bit was set. -+ */ -+ uint64_t pend_new_work_wait:1; -+ /* Set when there is a pending NULL_RD. */ -+ uint64_t pend_null_rd:1; -+ /* Set when there is a pending CLR_NSCHED. */ -+ uint64_t pend_nosched_clr:1; -+ uint64_t reserved_51:1; -+ /* This is the index when pend_nosched_clr is set. */ -+ uint64_t pend_index:11; -+ /* -+ * This is the new_grp when (pend_desched AND -+ * pend_desched_switch) is set. -+ */ -+ uint64_t pend_grp:4; -+ /* This is the wqp when pend_nosched_clr is set. */ -+ uint64_t pend_wqp:36; -+ } s_sstatus1; -+ -+ /** -+ * Result for a POW Status Load (when get_cur==1, get_wqp==0, and -+ * get_rev==0) -+ */ -+ struct { -+ uint64_t reserved_62_63:2; -+ /* -+ * Points to the next POW entry in the tag list when -+ * tail == 0 (and tag_type is not NULL or NULL_NULL). -+ */ -+ uint64_t link_index:11; -+ /* The POW entry attached to the core. */ -+ uint64_t index:11; -+ /* -+ * The group attached to the core (updated when new -+ * tag list entered on SWTAG_FULL). -+ */ -+ uint64_t grp:4; -+ /* -+ * Set when this POW entry is at the head of its tag -+ * list (also set when in the NULL or NULL_NULL -+ * state). -+ */ -+ uint64_t head:1; -+ /* -+ * Set when this POW entry is at the tail of its tag -+ * list (also set when in the NULL or NULL_NULL -+ * state). -+ */ -+ uint64_t tail:1; -+ /* -+ * The tag type attached to the core (updated when new -+ * tag list entered on SWTAG, SWTAG_FULL, or -+ * SWTAG_DESCHED). -+ */ -+ uint64_t tag_type:2; -+ /* -+ * The tag attached to the core (updated when new tag -+ * list entered on SWTAG, SWTAG_FULL, or -+ * SWTAG_DESCHED). -+ */ -+ uint64_t tag:32; -+ } s_sstatus2; -+ -+ /** -+ * Result for a POW Status Load (when get_cur==1, get_wqp==0, and get_rev==1) -+ */ -+ struct { -+ uint64_t reserved_62_63:2; -+ /* -+ * Points to the prior POW entry in the tag list when -+ * head == 0 (and tag_type is not NULL or -+ * NULL_NULL). This field is unpredictable when the -+ * core's state is NULL or NULL_NULL. -+ */ -+ uint64_t revlink_index:11; -+ /* The POW entry attached to the core. */ -+ uint64_t index:11; -+ /* -+ * The group attached to the core (updated when new -+ * tag list entered on SWTAG_FULL). -+ */ -+ uint64_t grp:4; -+ /* Set when this POW entry is at the head of its tag -+ * list (also set when in the NULL or NULL_NULL -+ * state). -+ */ -+ uint64_t head:1; -+ /* -+ * Set when this POW entry is at the tail of its tag -+ * list (also set when in the NULL or NULL_NULL -+ * state). -+ */ -+ uint64_t tail:1; -+ /* -+ * The tag type attached to the core (updated when new -+ * tag list entered on SWTAG, SWTAG_FULL, or -+ * SWTAG_DESCHED). -+ */ -+ uint64_t tag_type:2; -+ /* -+ * The tag attached to the core (updated when new tag -+ * list entered on SWTAG, SWTAG_FULL, or -+ * SWTAG_DESCHED). -+ */ -+ uint64_t tag:32; -+ } s_sstatus3; -+ -+ /** -+ * Result for a POW Status Load (when get_cur==1, get_wqp==1, and -+ * get_rev==0) -+ */ -+ struct { -+ uint64_t reserved_62_63:2; -+ /* -+ * Points to the next POW entry in the tag list when -+ * tail == 0 (and tag_type is not NULL or NULL_NULL). -+ */ -+ uint64_t link_index:11; -+ /* The POW entry attached to the core. */ -+ uint64_t index:11; -+ /* -+ * The group attached to the core (updated when new -+ * tag list entered on SWTAG_FULL). -+ */ -+ uint64_t grp:4; -+ /* -+ * The wqp attached to the core (updated when new tag -+ * list entered on SWTAG_FULL). -+ */ -+ uint64_t wqp:36; -+ } s_sstatus4; -+ -+ /** -+ * Result for a POW Status Load (when get_cur==1, get_wqp==1, and -+ * get_rev==1) -+ */ -+ struct { -+ uint64_t reserved_62_63:2; -+ /* -+ * Points to the prior POW entry in the tag list when -+ * head == 0 (and tag_type is not NULL or -+ * NULL_NULL). This field is unpredictable when the -+ * core's state is NULL or NULL_NULL. -+ */ -+ uint64_t revlink_index:11; -+ /* The POW entry attached to the core. */ -+ uint64_t index:11; -+ /* -+ * The group attached to the core (updated when new -+ * tag list entered on SWTAG_FULL). -+ */ -+ uint64_t grp:4; -+ /* -+ * The wqp attached to the core (updated when new tag -+ * list entered on SWTAG_FULL). -+ */ -+ uint64_t wqp:36; -+ } s_sstatus5; -+ -+ /** -+ * Result For POW Memory Load (get_des == 0 and get_wqp == 0) -+ */ -+ struct { -+ uint64_t reserved_51_63:13; -+ /* -+ * The next entry in the input, free, descheduled_head -+ * list (unpredictable if entry is the tail of the -+ * list). -+ */ -+ uint64_t next_index:11; -+ /* The group of the POW entry. */ -+ uint64_t grp:4; -+ uint64_t reserved_35:1; -+ /* -+ * Set when this POW entry is at the tail of its tag -+ * list (also set when in the NULL or NULL_NULL -+ * state). -+ */ -+ uint64_t tail:1; -+ /* The tag type of the POW entry. */ -+ uint64_t tag_type:2; -+ /* The tag of the POW entry. */ -+ uint64_t tag:32; -+ } s_smemload0; -+ -+ /** -+ * Result For POW Memory Load (get_des == 0 and get_wqp == 1) -+ */ -+ struct { -+ uint64_t reserved_51_63:13; -+ /* -+ * The next entry in the input, free, descheduled_head -+ * list (unpredictable if entry is the tail of the -+ * list). -+ */ -+ uint64_t next_index:11; -+ /* The group of the POW entry. */ -+ uint64_t grp:4; -+ /* The WQP held in the POW entry. */ -+ uint64_t wqp:36; -+ } s_smemload1; -+ -+ /** -+ * Result For POW Memory Load (get_des == 1) -+ */ -+ struct { -+ uint64_t reserved_51_63:13; -+ /* -+ * The next entry in the tag list connected to the -+ * descheduled head. -+ */ -+ uint64_t fwd_index:11; -+ /* The group of the POW entry. */ -+ uint64_t grp:4; -+ /* The nosched bit for the POW entry. */ -+ uint64_t nosched:1; -+ /* There is a pending tag switch */ -+ uint64_t pend_switch:1; -+ /* -+ * The next tag type for the new tag list when -+ * pend_switch is set. -+ */ -+ uint64_t pend_type:2; -+ /* -+ * The next tag for the new tag list when pend_switch -+ * is set. -+ */ -+ uint64_t pend_tag:32; -+ } s_smemload2; -+ -+ /** -+ * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 0) -+ */ -+ struct { -+ uint64_t reserved_52_63:12; -+ /* -+ * set when there is one or more POW entries on the -+ * free list. -+ */ -+ uint64_t free_val:1; -+ /* -+ * set when there is exactly one POW entry on the free -+ * list. -+ */ -+ uint64_t free_one:1; -+ uint64_t reserved_49:1; -+ /* -+ * when free_val is set, indicates the first entry on -+ * the free list. -+ */ -+ uint64_t free_head:11; -+ uint64_t reserved_37:1; -+ /* -+ * when free_val is set, indicates the last entry on -+ * the free list. -+ */ -+ uint64_t free_tail:11; -+ /* -+ * set when there is one or more POW entries on the -+ * input Q list selected by qosgrp. -+ */ -+ uint64_t loc_val:1; -+ /* -+ * set when there is exactly one POW entry on the -+ * input Q list selected by qosgrp. -+ */ -+ uint64_t loc_one:1; -+ uint64_t reserved_23:1; -+ /* -+ * when loc_val is set, indicates the first entry on -+ * the input Q list selected by qosgrp. -+ */ -+ uint64_t loc_head:11; -+ uint64_t reserved_11:1; -+ /* -+ * when loc_val is set, indicates the last entry on -+ * the input Q list selected by qosgrp. -+ */ -+ uint64_t loc_tail:11; -+ } sindexload0; -+ -+ /** -+ * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 1) -+ */ -+ struct { -+ uint64_t reserved_52_63:12; -+ /* -+ * set when there is one or more POW entries on the -+ * nosched list. -+ */ -+ uint64_t nosched_val:1; -+ /* -+ * set when there is exactly one POW entry on the -+ * nosched list. -+ */ -+ uint64_t nosched_one:1; -+ uint64_t reserved_49:1; -+ /* -+ * when nosched_val is set, indicates the first entry -+ * on the nosched list. -+ */ -+ uint64_t nosched_head:11; -+ uint64_t reserved_37:1; -+ /* -+ * when nosched_val is set, indicates the last entry -+ * on the nosched list. -+ */ -+ uint64_t nosched_tail:11; -+ /* -+ * set when there is one or more descheduled heads on -+ * the descheduled list selected by qosgrp. -+ */ -+ uint64_t des_val:1; -+ /* -+ * set when there is exactly one descheduled head on -+ * the descheduled list selected by qosgrp. -+ */ -+ uint64_t des_one:1; -+ uint64_t reserved_23:1; -+ /* -+ * when des_val is set, indicates the first -+ * descheduled head on the descheduled list selected -+ * by qosgrp. -+ */ -+ uint64_t des_head:11; -+ uint64_t reserved_11:1; -+ /* -+ * when des_val is set, indicates the last descheduled -+ * head on the descheduled list selected by qosgrp. -+ */ -+ uint64_t des_tail:11; -+ } sindexload1; -+ -+ /** -+ * Result For POW Index/Pointer Load (get_rmt == 1/get_des_get_tail == 0) -+ */ -+ struct { -+ uint64_t reserved_39_63:25; -+ /* -+ * Set when this DRAM list is the current head -+ * (i.e. is the next to be reloaded when the POW -+ * hardware reloads a POW entry from DRAM). The POW -+ * hardware alternates between the two DRAM lists -+ * associated with a QOS level when it reloads work -+ * from DRAM into the POW unit. -+ */ -+ uint64_t rmt_is_head:1; -+ /* -+ * Set when the DRAM portion of the input Q list -+ * selected by qosgrp contains one or more pieces of -+ * work. -+ */ -+ uint64_t rmt_val:1; -+ /* -+ * Set when the DRAM portion of the input Q list -+ * selected by qosgrp contains exactly one piece of -+ * work. -+ */ -+ uint64_t rmt_one:1; -+ /* -+ * When rmt_val is set, indicates the first piece of -+ * work on the DRAM input Q list selected by -+ * qosgrp. -+ */ -+ uint64_t rmt_head:36; -+ } sindexload2; -+ -+ /** -+ * Result For POW Index/Pointer Load (get_rmt == -+ * 1/get_des_get_tail == 1) -+ */ -+ struct { -+ uint64_t reserved_39_63:25; -+ /* -+ * set when this DRAM list is the current head -+ * (i.e. is the next to be reloaded when the POW -+ * hardware reloads a POW entry from DRAM). The POW -+ * hardware alternates between the two DRAM lists -+ * associated with a QOS level when it reloads work -+ * from DRAM into the POW unit. -+ */ -+ uint64_t rmt_is_head:1; -+ /* -+ * set when the DRAM portion of the input Q list -+ * selected by qosgrp contains one or more pieces of -+ * work. -+ */ -+ uint64_t rmt_val:1; -+ /* -+ * set when the DRAM portion of the input Q list -+ * selected by qosgrp contains exactly one piece of -+ * work. -+ */ -+ uint64_t rmt_one:1; -+ /* -+ * when rmt_val is set, indicates the last piece of -+ * work on the DRAM input Q list selected by -+ * qosgrp. -+ */ -+ uint64_t rmt_tail:36; -+ } sindexload3; -+ -+ /** -+ * Response to NULL_RD request loads -+ */ -+ struct { -+ uint64_t unused:62; -+ /* of type cvmx_pow_tag_type_t. state is one of the -+ * following: -+ * -+ * - CVMX_POW_TAG_TYPE_ORDERED -+ * - CVMX_POW_TAG_TYPE_ATOMIC -+ * - CVMX_POW_TAG_TYPE_NULL -+ * - CVMX_POW_TAG_TYPE_NULL_NULL -+ */ -+ uint64_t state:2; -+ } s_null_rd; -+ -+} cvmx_pow_tag_load_resp_t; -+ -+/** -+ * This structure describes the address used for stores to the POW. -+ * The store address is meaningful on stores to the POW. The -+ * hardware assumes that an aligned 64-bit store was used for all -+ * these stores. Note the assumption that the work queue entry is -+ * aligned on an 8-byte boundary (since the low-order 3 address bits -+ * must be zero). Note that not all fields are used by all -+ * operations. -+ * -+ * NOTE: The following is the behavior of the pending switch bit at the PP -+ * for POW stores (i.e. when did<7:3> == 0xc) -+ * - did<2:0> == 0 => pending switch bit is set -+ * - did<2:0> == 1 => no affect on the pending switch bit -+ * - did<2:0> == 3 => pending switch bit is cleared -+ * - did<2:0> == 7 => no affect on the pending switch bit -+ * - did<2:0> == others => must not be used -+ * - No other loads/stores have an affect on the pending switch bit -+ * - The switch bus from POW can clear the pending switch bit -+ * -+ * NOTE: did<2:0> == 2 is used by the HW for a special single-cycle -+ * ADDWQ command that only contains the pointer). SW must never use -+ * did<2:0> == 2. -+ */ -+typedef union { -+ /** -+ * Unsigned 64 bit integer representation of store address -+ */ -+ uint64_t u64; -+ -+ struct { -+ /* Memory region. Should be CVMX_IO_SEG in most cases */ -+ uint64_t mem_reg:2; -+ uint64_t reserved_49_61:13; /* Must be zero */ -+ uint64_t is_io:1; /* Must be one */ -+ /* Device ID of POW. Note that different sub-dids are used. */ -+ uint64_t did:8; -+ uint64_t reserved_36_39:4; /* Must be zero */ -+ /* Address field. addr<2:0> must be zero */ -+ uint64_t addr:36; -+ } stag; -+} cvmx_pow_tag_store_addr_t; -+ -+/** -+ * decode of the store data when an IOBDMA SENDSINGLE is sent to POW -+ */ -+typedef union { -+ uint64_t u64; -+ -+ struct { -+ /* -+ * the (64-bit word) location in scratchpad to write -+ * to (if len != 0) -+ */ -+ uint64_t scraddr:8; -+ /* the number of words in the response (0 => no response) */ -+ uint64_t len:8; -+ /* the ID of the device on the non-coherent bus */ -+ uint64_t did:8; -+ uint64_t unused:36; -+ /* if set, don't return load response until work is available */ -+ uint64_t wait:1; -+ uint64_t unused2:3; -+ } s; -+ -+} cvmx_pow_iobdma_store_t; -+ -+/* CSR typedefs have been moved to cvmx-csr-*.h */ -+ -+/** -+ * Get the POW tag for this core. This returns the current -+ * tag type, tag, group, and POW entry index associated with -+ * this core. Index is only valid if the tag type isn't NULL_NULL. -+ * If a tag switch is pending this routine returns the tag before -+ * the tag switch, not after. -+ * -+ * Returns Current tag -+ */ -+static inline cvmx_pow_tag_req_t cvmx_pow_get_current_tag(void) -+{ -+ cvmx_pow_load_addr_t load_addr; -+ cvmx_pow_tag_load_resp_t load_resp; -+ cvmx_pow_tag_req_t result; -+ -+ load_addr.u64 = 0; -+ load_addr.sstatus.mem_region = CVMX_IO_SEG; -+ load_addr.sstatus.is_io = 1; -+ load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1; -+ load_addr.sstatus.coreid = cvmx_get_core_num(); -+ load_addr.sstatus.get_cur = 1; -+ load_resp.u64 = cvmx_read_csr(load_addr.u64); -+ result.u64 = 0; -+ result.s.grp = load_resp.s_sstatus2.grp; -+ result.s.index = load_resp.s_sstatus2.index; -+ result.s.type = load_resp.s_sstatus2.tag_type; -+ result.s.tag = load_resp.s_sstatus2.tag; -+ return result; -+} -+ -+/** -+ * Get the POW WQE for this core. This returns the work queue -+ * entry currently associated with this core. -+ * -+ * Returns WQE pointer -+ */ -+static inline cvmx_wqe_t *cvmx_pow_get_current_wqp(void) -+{ -+ cvmx_pow_load_addr_t load_addr; -+ cvmx_pow_tag_load_resp_t load_resp; -+ -+ load_addr.u64 = 0; -+ load_addr.sstatus.mem_region = CVMX_IO_SEG; -+ load_addr.sstatus.is_io = 1; -+ load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1; -+ load_addr.sstatus.coreid = cvmx_get_core_num(); -+ load_addr.sstatus.get_cur = 1; -+ load_addr.sstatus.get_wqp = 1; -+ load_resp.u64 = cvmx_read_csr(load_addr.u64); -+ return (cvmx_wqe_t *) cvmx_phys_to_ptr(load_resp.s_sstatus4.wqp); -+} -+ -+#ifndef CVMX_MF_CHORD -+#define CVMX_MF_CHORD(dest) CVMX_RDHWR(dest, 30) -+#endif -+ -+/** -+ * Print a warning if a tag switch is pending for this core -+ * -+ * @function: Function name checking for a pending tag switch -+ */ -+static inline void __cvmx_pow_warn_if_pending_switch(const char *function) -+{ -+ uint64_t switch_complete; -+ CVMX_MF_CHORD(switch_complete); -+ if (!switch_complete) -+ pr_warning("%s called with tag switch in progress\n", function); -+} -+ -+/** -+ * Waits for a tag switch to complete by polling the completion bit. -+ * Note that switches to NULL complete immediately and do not need -+ * to be waited for. -+ */ -+static inline void cvmx_pow_tag_sw_wait(void) -+{ -+ const uint64_t MAX_CYCLES = 1ull << 31; -+ uint64_t switch_complete; -+ uint64_t start_cycle = cvmx_get_cycle(); -+ while (1) { -+ CVMX_MF_CHORD(switch_complete); -+ if (unlikely(switch_complete)) -+ break; -+ if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) { -+ pr_warning("Tag switch is taking a long time, " -+ "possible deadlock\n"); -+ start_cycle = -MAX_CYCLES - 1; -+ } -+ } -+} -+ -+/** -+ * Synchronous work request. Requests work from the POW. -+ * This function does NOT wait for previous tag switches to complete, -+ * so the caller must ensure that there is not a pending tag switch. -+ * -+ * @wait: When set, call stalls until work becomes avaiable, or times out. -+ * If not set, returns immediately. -+ * -+ * Returns Returns the WQE pointer from POW. Returns NULL if no work -+ * was available. -+ */ -+static inline cvmx_wqe_t *cvmx_pow_work_request_sync_nocheck(cvmx_pow_wait_t -+ wait) -+{ -+ cvmx_pow_load_addr_t ptr; -+ cvmx_pow_tag_load_resp_t result; -+ -+ if (CVMX_ENABLE_POW_CHECKS) -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ -+ ptr.u64 = 0; -+ ptr.swork.mem_region = CVMX_IO_SEG; -+ ptr.swork.is_io = 1; -+ ptr.swork.did = CVMX_OCT_DID_TAG_SWTAG; -+ ptr.swork.wait = wait; -+ -+ result.u64 = cvmx_read_csr(ptr.u64); -+ -+ if (result.s_work.no_work) -+ return NULL; -+ else -+ return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr); -+} -+ -+/** -+ * Synchronous work request. Requests work from the POW. -+ * This function waits for any previous tag switch to complete before -+ * requesting the new work. -+ * -+ * @wait: When set, call stalls until work becomes avaiable, or times out. -+ * If not set, returns immediately. -+ * -+ * Returns Returns the WQE pointer from POW. Returns NULL if no work -+ * was available. -+ */ -+static inline cvmx_wqe_t *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait) -+{ -+ if (CVMX_ENABLE_POW_CHECKS) -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ -+ /* Must not have a switch pending when requesting work */ -+ cvmx_pow_tag_sw_wait(); -+ return cvmx_pow_work_request_sync_nocheck(wait); -+ -+} -+ -+/** -+ * Synchronous null_rd request. Requests a switch out of NULL_NULL POW state. -+ * This function waits for any previous tag switch to complete before -+ * requesting the null_rd. -+ * -+ * Returns Returns the POW state of type cvmx_pow_tag_type_t. -+ */ -+static inline enum cvmx_pow_tag_type cvmx_pow_work_request_null_rd(void) -+{ -+ cvmx_pow_load_addr_t ptr; -+ cvmx_pow_tag_load_resp_t result; -+ -+ if (CVMX_ENABLE_POW_CHECKS) -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ -+ /* Must not have a switch pending when requesting work */ -+ cvmx_pow_tag_sw_wait(); -+ -+ ptr.u64 = 0; -+ ptr.snull_rd.mem_region = CVMX_IO_SEG; -+ ptr.snull_rd.is_io = 1; -+ ptr.snull_rd.did = CVMX_OCT_DID_TAG_NULL_RD; -+ -+ result.u64 = cvmx_read_csr(ptr.u64); -+ -+ return (enum cvmx_pow_tag_type) result.s_null_rd.state; -+} -+ -+/** -+ * Asynchronous work request. Work is requested from the POW unit, -+ * and should later be checked with function -+ * cvmx_pow_work_response_async. This function does NOT wait for -+ * previous tag switches to complete, so the caller must ensure that -+ * there is not a pending tag switch. -+ * -+ * @scr_addr: Scratch memory address that response will be returned -+ * to, which is either a valid WQE, or a response with the -+ * invalid bit set. Byte address, must be 8 byte aligned. -+ * -+ * @wait: 1 to cause response to wait for work to become available (or -+ * timeout), 0 to cause response to return immediately -+ */ -+static inline void cvmx_pow_work_request_async_nocheck(int scr_addr, -+ cvmx_pow_wait_t wait) -+{ -+ cvmx_pow_iobdma_store_t data; -+ -+ if (CVMX_ENABLE_POW_CHECKS) -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ -+ /* scr_addr must be 8 byte aligned */ -+ data.s.scraddr = scr_addr >> 3; -+ data.s.len = 1; -+ data.s.did = CVMX_OCT_DID_TAG_SWTAG; -+ data.s.wait = wait; -+ cvmx_send_single(data.u64); -+} -+ -+/** -+ * Asynchronous work request. Work is requested from the POW unit, -+ * and should later be checked with function -+ * cvmx_pow_work_response_async. This function waits for any previous -+ * tag switch to complete before requesting the new work. -+ * -+ * @scr_addr: Scratch memory address that response will be returned -+ * to, which is either a valid WQE, or a response with the -+ * invalid bit set. Byte address, must be 8 byte aligned. -+ * -+ * @wait: 1 to cause response to wait for work to become available (or -+ * timeout), 0 to cause response to return immediately -+ */ -+static inline void cvmx_pow_work_request_async(int scr_addr, -+ cvmx_pow_wait_t wait) -+{ -+ if (CVMX_ENABLE_POW_CHECKS) -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ -+ /* Must not have a switch pending when requesting work */ -+ cvmx_pow_tag_sw_wait(); -+ cvmx_pow_work_request_async_nocheck(scr_addr, wait); -+} -+ -+/** -+ * Gets result of asynchronous work request. Performs a IOBDMA sync -+ * to wait for the response. -+ * -+ * @scr_addr: Scratch memory address to get result from Byte address, -+ * must be 8 byte aligned. -+ * -+ * Returns Returns the WQE from the scratch register, or NULL if no -+ * work was available. -+ */ -+static inline cvmx_wqe_t *cvmx_pow_work_response_async(int scr_addr) -+{ -+ cvmx_pow_tag_load_resp_t result; -+ -+ CVMX_SYNCIOBDMA; -+ result.u64 = cvmx_scratch_read64(scr_addr); -+ -+ if (result.s_work.no_work) -+ return NULL; -+ else -+ return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr); -+} -+ -+/** -+ * Checks if a work queue entry pointer returned by a work -+ * request is valid. It may be invalid due to no work -+ * being available or due to a timeout. -+ * -+ * @wqe_ptr: pointer to a work queue entry returned by the POW -+ * -+ * Returns 0 if pointer is valid -+ * 1 if invalid (no work was returned) -+ */ -+static inline uint64_t cvmx_pow_work_invalid(cvmx_wqe_t *wqe_ptr) -+{ -+ return wqe_ptr == NULL; -+} -+ -+/** -+ * Starts a tag switch to the provided tag value and tag type. -+ * Completion for the tag switch must be checked for separately. This -+ * function does NOT update the work queue entry in dram to match tag -+ * value and type, so the application must keep track of these if they -+ * are important to the application. This tag switch command must not -+ * be used for switches to NULL, as the tag switch pending bit will be -+ * set by the switch request, but never cleared by the hardware. -+ * -+ * NOTE: This should not be used when switching from a NULL tag. Use -+ * cvmx_pow_tag_sw_full() instead. -+ * -+ * This function does no checks, so the caller must ensure that any -+ * previous tag switch has completed. -+ * -+ * @tag: new tag value -+ * @tag_type: new tag type (ordered or atomic) -+ */ -+static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag, -+ enum cvmx_pow_tag_type tag_type) -+{ -+ cvmx_addr_t ptr; -+ cvmx_pow_tag_req_t tag_req; -+ -+ if (CVMX_ENABLE_POW_CHECKS) { -+ cvmx_pow_tag_req_t current_tag; -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ current_tag = cvmx_pow_get_current_tag(); -+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) -+ pr_warning("%s called with NULL_NULL tag\n", -+ __func__); -+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) -+ pr_warning("%s called with NULL tag\n", __func__); -+ if ((current_tag.s.type == tag_type) -+ && (current_tag.s.tag == tag)) -+ pr_warning("%s called to perform a tag switch to the " -+ "same tag\n", -+ __func__); -+ if (tag_type == CVMX_POW_TAG_TYPE_NULL) -+ pr_warning("%s called to perform a tag switch to " -+ "NULL. Use cvmx_pow_tag_sw_null() instead\n", -+ __func__); -+ } -+ -+ /* -+ * Note that WQE in DRAM is not updated here, as the POW does -+ * not read from DRAM once the WQE is in flight. See hardware -+ * manual for complete details. It is the application's -+ * responsibility to keep track of the current tag value if -+ * that is important. -+ */ -+ -+ tag_req.u64 = 0; -+ tag_req.s.op = CVMX_POW_TAG_OP_SWTAG; -+ tag_req.s.tag = tag; -+ tag_req.s.type = tag_type; -+ -+ ptr.u64 = 0; -+ ptr.sio.mem_region = CVMX_IO_SEG; -+ ptr.sio.is_io = 1; -+ ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG; -+ -+ /* once this store arrives at POW, it will attempt the switch -+ software must wait for the switch to complete separately */ -+ cvmx_write_io(ptr.u64, tag_req.u64); -+} -+ -+/** -+ * Starts a tag switch to the provided tag value and tag type. -+ * Completion for the tag switch must be checked for separately. This -+ * function does NOT update the work queue entry in dram to match tag -+ * value and type, so the application must keep track of these if they -+ * are important to the application. This tag switch command must not -+ * be used for switches to NULL, as the tag switch pending bit will be -+ * set by the switch request, but never cleared by the hardware. -+ * -+ * NOTE: This should not be used when switching from a NULL tag. Use -+ * cvmx_pow_tag_sw_full() instead. -+ * -+ * This function waits for any previous tag switch to complete, and also -+ * displays an error on tag switches to NULL. -+ * -+ * @tag: new tag value -+ * @tag_type: new tag type (ordered or atomic) -+ */ -+static inline void cvmx_pow_tag_sw(uint32_t tag, -+ enum cvmx_pow_tag_type tag_type) -+{ -+ if (CVMX_ENABLE_POW_CHECKS) -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ -+ /* -+ * Note that WQE in DRAM is not updated here, as the POW does -+ * not read from DRAM once the WQE is in flight. See hardware -+ * manual for complete details. It is the application's -+ * responsibility to keep track of the current tag value if -+ * that is important. -+ */ -+ -+ /* -+ * Ensure that there is not a pending tag switch, as a tag -+ * switch cannot be started if a previous switch is still -+ * pending. -+ */ -+ cvmx_pow_tag_sw_wait(); -+ cvmx_pow_tag_sw_nocheck(tag, tag_type); -+} -+ -+/** -+ * Starts a tag switch to the provided tag value and tag type. -+ * Completion for the tag switch must be checked for separately. This -+ * function does NOT update the work queue entry in dram to match tag -+ * value and type, so the application must keep track of these if they -+ * are important to the application. This tag switch command must not -+ * be used for switches to NULL, as the tag switch pending bit will be -+ * set by the switch request, but never cleared by the hardware. -+ * -+ * This function must be used for tag switches from NULL. -+ * -+ * This function does no checks, so the caller must ensure that any -+ * previous tag switch has completed. -+ * -+ * @wqp: pointer to work queue entry to submit. This entry is -+ * updated to match the other parameters -+ * @tag: tag value to be assigned to work queue entry -+ * @tag_type: type of tag -+ * @group: group value for the work queue entry. -+ */ -+static inline void cvmx_pow_tag_sw_full_nocheck(cvmx_wqe_t *wqp, uint32_t tag, -+ enum cvmx_pow_tag_type tag_type, -+ uint64_t group) -+{ -+ cvmx_addr_t ptr; -+ cvmx_pow_tag_req_t tag_req; -+ -+ if (CVMX_ENABLE_POW_CHECKS) { -+ cvmx_pow_tag_req_t current_tag; -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ current_tag = cvmx_pow_get_current_tag(); -+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) -+ pr_warning("%s called with NULL_NULL tag\n", -+ __func__); -+ if ((current_tag.s.type == tag_type) -+ && (current_tag.s.tag == tag)) -+ pr_warning("%s called to perform a tag switch to " -+ "the same tag\n", -+ __func__); -+ if (tag_type == CVMX_POW_TAG_TYPE_NULL) -+ pr_warning("%s called to perform a tag switch to " -+ "NULL. Use cvmx_pow_tag_sw_null() instead\n", -+ __func__); -+ if (wqp != cvmx_phys_to_ptr(0x80)) -+ if (wqp != cvmx_pow_get_current_wqp()) -+ pr_warning("%s passed WQE(%p) doesn't match " -+ "the address in the POW(%p)\n", -+ __func__, wqp, -+ cvmx_pow_get_current_wqp()); -+ } -+ -+ /* -+ * Note that WQE in DRAM is not updated here, as the POW does -+ * not read from DRAM once the WQE is in flight. See hardware -+ * manual for complete details. It is the application's -+ * responsibility to keep track of the current tag value if -+ * that is important. -+ */ -+ -+ tag_req.u64 = 0; -+ tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_FULL; -+ tag_req.s.tag = tag; -+ tag_req.s.type = tag_type; -+ tag_req.s.grp = group; -+ -+ ptr.u64 = 0; -+ ptr.sio.mem_region = CVMX_IO_SEG; -+ ptr.sio.is_io = 1; -+ ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG; -+ ptr.sio.offset = CAST64(wqp); -+ -+ /* -+ * once this store arrives at POW, it will attempt the switch -+ * software must wait for the switch to complete separately. -+ */ -+ cvmx_write_io(ptr.u64, tag_req.u64); -+} -+ -+/** -+ * Starts a tag switch to the provided tag value and tag type. -+ * Completion for the tag switch must be checked for separately. This -+ * function does NOT update the work queue entry in dram to match tag -+ * value and type, so the application must keep track of these if they -+ * are important to the application. This tag switch command must not -+ * be used for switches to NULL, as the tag switch pending bit will be -+ * set by the switch request, but never cleared by the hardware. -+ * -+ * This function must be used for tag switches from NULL. -+ * -+ * This function waits for any pending tag switches to complete -+ * before requesting the tag switch. -+ * -+ * @wqp: pointer to work queue entry to submit. This entry is updated -+ * to match the other parameters -+ * @tag: tag value to be assigned to work queue entry -+ * @tag_type: type of tag -+ * @group: group value for the work queue entry. -+ */ -+static inline void cvmx_pow_tag_sw_full(cvmx_wqe_t *wqp, uint32_t tag, -+ enum cvmx_pow_tag_type tag_type, -+ uint64_t group) -+{ -+ if (CVMX_ENABLE_POW_CHECKS) -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ -+ /* -+ * Ensure that there is not a pending tag switch, as a tag -+ * switch cannot be started if a previous switch is still -+ * pending. -+ */ -+ cvmx_pow_tag_sw_wait(); -+ cvmx_pow_tag_sw_full_nocheck(wqp, tag, tag_type, group); -+} -+ -+/** -+ * Switch to a NULL tag, which ends any ordering or -+ * synchronization provided by the POW for the current -+ * work queue entry. This operation completes immediatly, -+ * so completetion should not be waited for. -+ * This function does NOT wait for previous tag switches to complete, -+ * so the caller must ensure that any previous tag switches have completed. -+ */ -+static inline void cvmx_pow_tag_sw_null_nocheck(void) -+{ -+ cvmx_addr_t ptr; -+ cvmx_pow_tag_req_t tag_req; -+ -+ if (CVMX_ENABLE_POW_CHECKS) { -+ cvmx_pow_tag_req_t current_tag; -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ current_tag = cvmx_pow_get_current_tag(); -+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) -+ pr_warning("%s called with NULL_NULL tag\n", -+ __func__); -+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) -+ pr_warning("%s called when we already have a " -+ "NULL tag\n", -+ __func__); -+ } -+ -+ tag_req.u64 = 0; -+ tag_req.s.op = CVMX_POW_TAG_OP_SWTAG; -+ tag_req.s.type = CVMX_POW_TAG_TYPE_NULL; -+ -+ ptr.u64 = 0; -+ ptr.sio.mem_region = CVMX_IO_SEG; -+ ptr.sio.is_io = 1; -+ ptr.sio.did = CVMX_OCT_DID_TAG_TAG1; -+ -+ cvmx_write_io(ptr.u64, tag_req.u64); -+ -+ /* switch to NULL completes immediately */ -+} -+ -+/** -+ * Switch to a NULL tag, which ends any ordering or -+ * synchronization provided by the POW for the current -+ * work queue entry. This operation completes immediatly, -+ * so completetion should not be waited for. -+ * This function waits for any pending tag switches to complete -+ * before requesting the switch to NULL. -+ */ -+static inline void cvmx_pow_tag_sw_null(void) -+{ -+ if (CVMX_ENABLE_POW_CHECKS) -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ -+ /* -+ * Ensure that there is not a pending tag switch, as a tag -+ * switch cannot be started if a previous switch is still -+ * pending. -+ */ -+ cvmx_pow_tag_sw_wait(); -+ cvmx_pow_tag_sw_null_nocheck(); -+ -+ /* switch to NULL completes immediately */ -+} -+ -+/** -+ * Submits work to an input queue. This function updates the work -+ * queue entry in DRAM to match the arguments given. Note that the -+ * tag provided is for the work queue entry submitted, and is -+ * unrelated to the tag that the core currently holds. -+ * -+ * @wqp: pointer to work queue entry to submit. This entry is -+ * updated to match the other parameters -+ * @tag: tag value to be assigned to work queue entry -+ * @tag_type: type of tag -+ * @qos: Input queue to add to. -+ * @grp: group value for the work queue entry. -+ */ -+static inline void cvmx_pow_work_submit(cvmx_wqe_t *wqp, uint32_t tag, -+ enum cvmx_pow_tag_type tag_type, -+ uint64_t qos, uint64_t grp) -+{ -+ cvmx_addr_t ptr; -+ cvmx_pow_tag_req_t tag_req; -+ -+ wqp->qos = qos; -+ wqp->tag = tag; -+ wqp->tag_type = tag_type; -+ wqp->grp = grp; -+ -+ tag_req.u64 = 0; -+ tag_req.s.op = CVMX_POW_TAG_OP_ADDWQ; -+ tag_req.s.type = tag_type; -+ tag_req.s.tag = tag; -+ tag_req.s.qos = qos; -+ tag_req.s.grp = grp; -+ -+ ptr.u64 = 0; -+ ptr.sio.mem_region = CVMX_IO_SEG; -+ ptr.sio.is_io = 1; -+ ptr.sio.did = CVMX_OCT_DID_TAG_TAG1; -+ ptr.sio.offset = cvmx_ptr_to_phys(wqp); -+ -+ /* -+ * SYNC write to memory before the work submit. This is -+ * necessary as POW may read values from DRAM at this time. -+ */ -+ CVMX_SYNCWS; -+ cvmx_write_io(ptr.u64, tag_req.u64); -+} -+ -+/** -+ * This function sets the group mask for a core. The group mask -+ * indicates which groups each core will accept work from. There are -+ * 16 groups. -+ * -+ * @core_num: core to apply mask to -+ * @mask: Group mask. There are 16 groups, so only bits 0-15 are valid, -+ * representing groups 0-15. -+ * Each 1 bit in the mask enables the core to accept work from -+ * the corresponding group. -+ */ -+static inline void cvmx_pow_set_group_mask(uint64_t core_num, uint64_t mask) -+{ -+ union cvmx_pow_pp_grp_mskx grp_msk; -+ -+ grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num)); -+ grp_msk.s.grp_msk = mask; -+ cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64); -+} -+ -+/** -+ * This function sets POW static priorities for a core. Each input queue has -+ * an associated priority value. -+ * -+ * @core_num: core to apply priorities to -+ * @priority: Vector of 8 priorities, one per POW Input Queue (0-7). -+ * Highest priority is 0 and lowest is 7. A priority value -+ * of 0xF instructs POW to skip the Input Queue when -+ * scheduling to this specific core. -+ * NOTE: priorities should not have gaps in values, meaning -+ * {0,1,1,1,1,1,1,1} is a valid configuration while -+ * {0,2,2,2,2,2,2,2} is not. -+ */ -+static inline void cvmx_pow_set_priority(uint64_t core_num, -+ const uint8_t priority[]) -+{ -+ /* POW priorities are supported on CN5xxx and later */ -+ if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) { -+ union cvmx_pow_pp_grp_mskx grp_msk; -+ -+ grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num)); -+ grp_msk.s.qos0_pri = priority[0]; -+ grp_msk.s.qos1_pri = priority[1]; -+ grp_msk.s.qos2_pri = priority[2]; -+ grp_msk.s.qos3_pri = priority[3]; -+ grp_msk.s.qos4_pri = priority[4]; -+ grp_msk.s.qos5_pri = priority[5]; -+ grp_msk.s.qos6_pri = priority[6]; -+ grp_msk.s.qos7_pri = priority[7]; -+ -+ /* Detect gaps between priorities and flag error */ -+ { -+ int i; -+ uint32_t prio_mask = 0; -+ -+ for (i = 0; i < 8; i++) -+ if (priority[i] != 0xF) -+ prio_mask |= 1 << priority[i]; -+ -+ if (prio_mask ^ ((1 << cvmx_pop(prio_mask)) - 1)) { -+ pr_err("POW static priorities should be " -+ "contiguous (0x%llx)\n", -+ (unsigned long long)prio_mask); -+ return; -+ } -+ } -+ -+ cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64); -+ } -+} -+ -+/** -+ * Performs a tag switch and then an immediate deschedule. This completes -+ * immediatly, so completion must not be waited for. This function does NOT -+ * update the wqe in DRAM to match arguments. -+ * -+ * This function does NOT wait for any prior tag switches to complete, so the -+ * calling code must do this. -+ * -+ * Note the following CAVEAT of the Octeon HW behavior when -+ * re-scheduling DE-SCHEDULEd items whose (next) state is -+ * ORDERED: -+ * - If there are no switches pending at the time that the -+ * HW executes the de-schedule, the HW will only re-schedule -+ * the head of the FIFO associated with the given tag. This -+ * means that in many respects, the HW treats this ORDERED -+ * tag as an ATOMIC tag. Note that in the SWTAG_DESCH -+ * case (to an ORDERED tag), the HW will do the switch -+ * before the deschedule whenever it is possible to do -+ * the switch immediately, so it may often look like -+ * this case. -+ * - If there is a pending switch to ORDERED at the time -+ * the HW executes the de-schedule, the HW will perform -+ * the switch at the time it re-schedules, and will be -+ * able to reschedule any/all of the entries with the -+ * same tag. -+ * Due to this behavior, the RECOMMENDATION to software is -+ * that they have a (next) state of ATOMIC when they -+ * DE-SCHEDULE. If an ORDERED tag is what was really desired, -+ * SW can choose to immediately switch to an ORDERED tag -+ * after the work (that has an ATOMIC tag) is re-scheduled. -+ * Note that since there are never any tag switches pending -+ * when the HW re-schedules, this switch can be IMMEDIATE upon -+ * the reception of the pointer during the re-schedule. -+ * -+ * @tag: New tag value -+ * @tag_type: New tag type -+ * @group: New group value -+ * @no_sched: Control whether this work queue entry will be rescheduled. -+ * - 1 : don't schedule this work -+ * - 0 : allow this work to be scheduled. -+ */ -+static inline void cvmx_pow_tag_sw_desched_nocheck( -+ uint32_t tag, -+ enum cvmx_pow_tag_type tag_type, -+ uint64_t group, -+ uint64_t no_sched) -+{ -+ cvmx_addr_t ptr; -+ cvmx_pow_tag_req_t tag_req; -+ -+ if (CVMX_ENABLE_POW_CHECKS) { -+ cvmx_pow_tag_req_t current_tag; -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ current_tag = cvmx_pow_get_current_tag(); -+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) -+ pr_warning("%s called with NULL_NULL tag\n", -+ __func__); -+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) -+ pr_warning("%s called with NULL tag. Deschedule not " -+ "allowed from NULL state\n", -+ __func__); -+ if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC) -+ && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC)) -+ pr_warning("%s called where neither the before or " -+ "after tag is ATOMIC\n", -+ __func__); -+ } -+ -+ tag_req.u64 = 0; -+ tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_DESCH; -+ tag_req.s.tag = tag; -+ tag_req.s.type = tag_type; -+ tag_req.s.grp = group; -+ tag_req.s.no_sched = no_sched; -+ -+ ptr.u64 = 0; -+ ptr.sio.mem_region = CVMX_IO_SEG; -+ ptr.sio.is_io = 1; -+ ptr.sio.did = CVMX_OCT_DID_TAG_TAG3; -+ /* -+ * since TAG3 is used, this store will clear the local pending -+ * switch bit. -+ */ -+ cvmx_write_io(ptr.u64, tag_req.u64); -+} -+ -+/** -+ * Performs a tag switch and then an immediate deschedule. This completes -+ * immediatly, so completion must not be waited for. This function does NOT -+ * update the wqe in DRAM to match arguments. -+ * -+ * This function waits for any prior tag switches to complete, so the -+ * calling code may call this function with a pending tag switch. -+ * -+ * Note the following CAVEAT of the Octeon HW behavior when -+ * re-scheduling DE-SCHEDULEd items whose (next) state is -+ * ORDERED: -+ * - If there are no switches pending at the time that the -+ * HW executes the de-schedule, the HW will only re-schedule -+ * the head of the FIFO associated with the given tag. This -+ * means that in many respects, the HW treats this ORDERED -+ * tag as an ATOMIC tag. Note that in the SWTAG_DESCH -+ * case (to an ORDERED tag), the HW will do the switch -+ * before the deschedule whenever it is possible to do -+ * the switch immediately, so it may often look like -+ * this case. -+ * - If there is a pending switch to ORDERED at the time -+ * the HW executes the de-schedule, the HW will perform -+ * the switch at the time it re-schedules, and will be -+ * able to reschedule any/all of the entries with the -+ * same tag. -+ * Due to this behavior, the RECOMMENDATION to software is -+ * that they have a (next) state of ATOMIC when they -+ * DE-SCHEDULE. If an ORDERED tag is what was really desired, -+ * SW can choose to immediately switch to an ORDERED tag -+ * after the work (that has an ATOMIC tag) is re-scheduled. -+ * Note that since there are never any tag switches pending -+ * when the HW re-schedules, this switch can be IMMEDIATE upon -+ * the reception of the pointer during the re-schedule. -+ * -+ * @tag: New tag value -+ * @tag_type: New tag type -+ * @group: New group value -+ * @no_sched: Control whether this work queue entry will be rescheduled. -+ * - 1 : don't schedule this work -+ * - 0 : allow this work to be scheduled. -+ */ -+static inline void cvmx_pow_tag_sw_desched(uint32_t tag, -+ enum cvmx_pow_tag_type tag_type, -+ uint64_t group, uint64_t no_sched) -+{ -+ if (CVMX_ENABLE_POW_CHECKS) -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ -+ /* Need to make sure any writes to the work queue entry are complete */ -+ CVMX_SYNCWS; -+ /* -+ * Ensure that there is not a pending tag switch, as a tag -+ * switch cannot be started if a previous switch is still -+ * pending. -+ */ -+ cvmx_pow_tag_sw_wait(); -+ cvmx_pow_tag_sw_desched_nocheck(tag, tag_type, group, no_sched); -+} -+ -+/** -+ * Descchedules the current work queue entry. -+ * -+ * @no_sched: no schedule flag value to be set on the work queue -+ * entry. If this is set the entry will not be -+ * rescheduled. -+ */ -+static inline void cvmx_pow_desched(uint64_t no_sched) -+{ -+ cvmx_addr_t ptr; -+ cvmx_pow_tag_req_t tag_req; -+ -+ if (CVMX_ENABLE_POW_CHECKS) { -+ cvmx_pow_tag_req_t current_tag; -+ __cvmx_pow_warn_if_pending_switch(__func__); -+ current_tag = cvmx_pow_get_current_tag(); -+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) -+ pr_warning("%s called with NULL_NULL tag\n", -+ __func__); -+ if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) -+ pr_warning("%s called with NULL tag. Deschedule not " -+ "expected from NULL state\n", -+ __func__); -+ } -+ -+ /* Need to make sure any writes to the work queue entry are complete */ -+ CVMX_SYNCWS; -+ -+ tag_req.u64 = 0; -+ tag_req.s.op = CVMX_POW_TAG_OP_DESCH; -+ tag_req.s.no_sched = no_sched; -+ -+ ptr.u64 = 0; -+ ptr.sio.mem_region = CVMX_IO_SEG; -+ ptr.sio.is_io = 1; -+ ptr.sio.did = CVMX_OCT_DID_TAG_TAG3; -+ /* -+ * since TAG3 is used, this store will clear the local pending -+ * switch bit. -+ */ -+ cvmx_write_io(ptr.u64, tag_req.u64); -+} -+ -+/**************************************************** -+* Define usage of bits within the 32 bit tag values. -+*****************************************************/ -+ -+/* -+ * Number of bits of the tag used by software. The SW bits are always -+ * a contiguous block of the high starting at bit 31. The hardware -+ * bits are always the low bits. By default, the top 8 bits of the -+ * tag are reserved for software, and the low 24 are set by the IPD -+ * unit. -+ */ -+#define CVMX_TAG_SW_BITS (8) -+#define CVMX_TAG_SW_SHIFT (32 - CVMX_TAG_SW_BITS) -+ -+/* Below is the list of values for the top 8 bits of the tag. */ -+/* -+ * Tag values with top byte of this value are reserved for internal -+ * executive uses. -+ */ -+#define CVMX_TAG_SW_BITS_INTERNAL 0x1 -+/* The executive divides the remaining 24 bits as follows: -+ * - the upper 8 bits (bits 23 - 16 of the tag) define a subgroup -+ * -+ * - the lower 16 bits (bits 15 - 0 of the tag) define are the value -+ * with the subgroup -+ * -+ * Note that this section describes the format of tags generated by -+ * software - refer to the hardware documentation for a description of -+ * the tags values generated by the packet input hardware. Subgroups -+ * are defined here. -+ */ -+/* Mask for the value portion of the tag */ -+#define CVMX_TAG_SUBGROUP_MASK 0xFFFF -+#define CVMX_TAG_SUBGROUP_SHIFT 16 -+#define CVMX_TAG_SUBGROUP_PKO 0x1 -+ -+/* End of executive tag subgroup definitions */ -+ -+/* -+ * The remaining values software bit values 0x2 - 0xff are available -+ * for application use. -+ */ -+ -+/** -+ * This function creates a 32 bit tag value from the two values provided. -+ * -+ * @sw_bits: The upper bits (number depends on configuration) are set -+ * to this value. The remainder of bits are set by the -+ * hw_bits parameter. -+ * -+ * @hw_bits: The lower bits (number depends on configuration) are set -+ * to this value. The remainder of bits are set by the -+ * sw_bits parameter. -+ * -+ * Returns 32 bit value of the combined hw and sw bits. -+ */ -+static inline uint32_t cvmx_pow_tag_compose(uint64_t sw_bits, uint64_t hw_bits) -+{ -+ return ((sw_bits & cvmx_build_mask(CVMX_TAG_SW_BITS)) << -+ CVMX_TAG_SW_SHIFT) | -+ (hw_bits & cvmx_build_mask(32 - CVMX_TAG_SW_BITS)); -+} -+ -+/** -+ * Extracts the bits allocated for software use from the tag -+ * -+ * @tag: 32 bit tag value -+ * -+ * Returns N bit software tag value, where N is configurable with the -+ * CVMX_TAG_SW_BITS define -+ */ -+static inline uint32_t cvmx_pow_tag_get_sw_bits(uint64_t tag) -+{ -+ return (tag >> (32 - CVMX_TAG_SW_BITS)) & -+ cvmx_build_mask(CVMX_TAG_SW_BITS); -+} -+ -+/** -+ * -+ * Extracts the bits allocated for hardware use from the tag -+ * -+ * @tag: 32 bit tag value -+ * -+ * Returns (32 - N) bit software tag value, where N is configurable -+ * with the CVMX_TAG_SW_BITS define -+ */ -+static inline uint32_t cvmx_pow_tag_get_hw_bits(uint64_t tag) -+{ -+ return tag & cvmx_build_mask(32 - CVMX_TAG_SW_BITS); -+} -+ -+/** -+ * Store the current POW internal state into the supplied -+ * buffer. It is recommended that you pass a buffer of at least -+ * 128KB. The format of the capture may change based on SDK -+ * version and Octeon chip. -+ * -+ * @buffer: Buffer to store capture into -+ * @buffer_size: -+ * The size of the supplied buffer -+ * -+ * Returns Zero on sucess, negative on failure -+ */ -+extern int cvmx_pow_capture(void *buffer, int buffer_size); -+ -+/** -+ * Dump a POW capture to the console in a human readable format. -+ * -+ * @buffer: POW capture from cvmx_pow_capture() -+ * @buffer_size: -+ * Size of the buffer -+ */ -+extern void cvmx_pow_display(void *buffer, int buffer_size); -+ -+/** -+ * Return the number of POW entries supported by this chip -+ * -+ * Returns Number of POW entries -+ */ -+extern int cvmx_pow_get_num_entries(void); -+ -+#endif /* __CVMX_POW_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-scratch.h -@@ -0,0 +1,139 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * This file provides support for the processor local scratch memory. -+ * Scratch memory is byte addressable - all addresses are byte addresses. -+ * -+ */ -+ -+#ifndef __CVMX_SCRATCH_H__ -+#define __CVMX_SCRATCH_H__ -+ -+/* -+ * Note: This define must be a long, not a long long in order to -+ * compile without warnings for both 32bit and 64bit. -+ */ -+#define CVMX_SCRATCH_BASE (-32768l) /* 0xffffffffffff8000 */ -+ -+/** -+ * Reads an 8 bit value from the processor local scratchpad memory. -+ * -+ * @address: byte address to read from -+ * -+ * Returns value read -+ */ -+static inline uint8_t cvmx_scratch_read8(uint64_t address) -+{ -+ return *CASTPTR(volatile uint8_t, CVMX_SCRATCH_BASE + address); -+} -+ -+/** -+ * Reads a 16 bit value from the processor local scratchpad memory. -+ * -+ * @address: byte address to read from -+ * -+ * Returns value read -+ */ -+static inline uint16_t cvmx_scratch_read16(uint64_t address) -+{ -+ return *CASTPTR(volatile uint16_t, CVMX_SCRATCH_BASE + address); -+} -+ -+/** -+ * Reads a 32 bit value from the processor local scratchpad memory. -+ * -+ * @address: byte address to read from -+ * -+ * Returns value read -+ */ -+static inline uint32_t cvmx_scratch_read32(uint64_t address) -+{ -+ return *CASTPTR(volatile uint32_t, CVMX_SCRATCH_BASE + address); -+} -+ -+/** -+ * Reads a 64 bit value from the processor local scratchpad memory. -+ * -+ * @address: byte address to read from -+ * -+ * Returns value read -+ */ -+static inline uint64_t cvmx_scratch_read64(uint64_t address) -+{ -+ return *CASTPTR(volatile uint64_t, CVMX_SCRATCH_BASE + address); -+} -+ -+/** -+ * Writes an 8 bit value to the processor local scratchpad memory. -+ * -+ * @address: byte address to write to -+ * @value: value to write -+ */ -+static inline void cvmx_scratch_write8(uint64_t address, uint64_t value) -+{ -+ *CASTPTR(volatile uint8_t, CVMX_SCRATCH_BASE + address) = -+ (uint8_t) value; -+} -+ -+/** -+ * Writes a 32 bit value to the processor local scratchpad memory. -+ * -+ * @address: byte address to write to -+ * @value: value to write -+ */ -+static inline void cvmx_scratch_write16(uint64_t address, uint64_t value) -+{ -+ *CASTPTR(volatile uint16_t, CVMX_SCRATCH_BASE + address) = -+ (uint16_t) value; -+} -+ -+/** -+ * Writes a 16 bit value to the processor local scratchpad memory. -+ * -+ * @address: byte address to write to -+ * @value: value to write -+ */ -+static inline void cvmx_scratch_write32(uint64_t address, uint64_t value) -+{ -+ *CASTPTR(volatile uint32_t, CVMX_SCRATCH_BASE + address) = -+ (uint32_t) value; -+} -+ -+/** -+ * Writes a 64 bit value to the processor local scratchpad memory. -+ * -+ * @address: byte address to write to -+ * @value: value to write -+ */ -+static inline void cvmx_scratch_write64(uint64_t address, uint64_t value) -+{ -+ *CASTPTR(volatile uint64_t, CVMX_SCRATCH_BASE + address) = value; -+} -+ -+#endif /* __CVMX_SCRATCH_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-smix-defs.h -@@ -0,0 +1,178 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_SMIX_DEFS_H__ -+#define __CVMX_SMIX_DEFS_H__ -+ -+#define CVMX_SMIX_CLK(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256)) -+#define CVMX_SMIX_CMD(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256)) -+#define CVMX_SMIX_EN(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256)) -+#define CVMX_SMIX_RD_DAT(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256)) -+#define CVMX_SMIX_WR_DAT(offset) \ -+ CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256)) -+ -+union cvmx_smix_clk { -+ uint64_t u64; -+ struct cvmx_smix_clk_s { -+ uint64_t reserved_25_63:39; -+ uint64_t mode:1; -+ uint64_t reserved_21_23:3; -+ uint64_t sample_hi:5; -+ uint64_t sample_mode:1; -+ uint64_t reserved_14_14:1; -+ uint64_t clk_idle:1; -+ uint64_t preamble:1; -+ uint64_t sample:4; -+ uint64_t phase:8; -+ } s; -+ struct cvmx_smix_clk_cn30xx { -+ uint64_t reserved_21_63:43; -+ uint64_t sample_hi:5; -+ uint64_t reserved_14_15:2; -+ uint64_t clk_idle:1; -+ uint64_t preamble:1; -+ uint64_t sample:4; -+ uint64_t phase:8; -+ } cn30xx; -+ struct cvmx_smix_clk_cn30xx cn31xx; -+ struct cvmx_smix_clk_cn30xx cn38xx; -+ struct cvmx_smix_clk_cn30xx cn38xxp2; -+ struct cvmx_smix_clk_cn50xx { -+ uint64_t reserved_25_63:39; -+ uint64_t mode:1; -+ uint64_t reserved_21_23:3; -+ uint64_t sample_hi:5; -+ uint64_t reserved_14_15:2; -+ uint64_t clk_idle:1; -+ uint64_t preamble:1; -+ uint64_t sample:4; -+ uint64_t phase:8; -+ } cn50xx; -+ struct cvmx_smix_clk_s cn52xx; -+ struct cvmx_smix_clk_cn50xx cn52xxp1; -+ struct cvmx_smix_clk_s cn56xx; -+ struct cvmx_smix_clk_cn50xx cn56xxp1; -+ struct cvmx_smix_clk_cn30xx cn58xx; -+ struct cvmx_smix_clk_cn30xx cn58xxp1; -+}; -+ -+union cvmx_smix_cmd { -+ uint64_t u64; -+ struct cvmx_smix_cmd_s { -+ uint64_t reserved_18_63:46; -+ uint64_t phy_op:2; -+ uint64_t reserved_13_15:3; -+ uint64_t phy_adr:5; -+ uint64_t reserved_5_7:3; -+ uint64_t reg_adr:5; -+ } s; -+ struct cvmx_smix_cmd_cn30xx { -+ uint64_t reserved_17_63:47; -+ uint64_t phy_op:1; -+ uint64_t reserved_13_15:3; -+ uint64_t phy_adr:5; -+ uint64_t reserved_5_7:3; -+ uint64_t reg_adr:5; -+ } cn30xx; -+ struct cvmx_smix_cmd_cn30xx cn31xx; -+ struct cvmx_smix_cmd_cn30xx cn38xx; -+ struct cvmx_smix_cmd_cn30xx cn38xxp2; -+ struct cvmx_smix_cmd_s cn50xx; -+ struct cvmx_smix_cmd_s cn52xx; -+ struct cvmx_smix_cmd_s cn52xxp1; -+ struct cvmx_smix_cmd_s cn56xx; -+ struct cvmx_smix_cmd_s cn56xxp1; -+ struct cvmx_smix_cmd_cn30xx cn58xx; -+ struct cvmx_smix_cmd_cn30xx cn58xxp1; -+}; -+ -+union cvmx_smix_en { -+ uint64_t u64; -+ struct cvmx_smix_en_s { -+ uint64_t reserved_1_63:63; -+ uint64_t en:1; -+ } s; -+ struct cvmx_smix_en_s cn30xx; -+ struct cvmx_smix_en_s cn31xx; -+ struct cvmx_smix_en_s cn38xx; -+ struct cvmx_smix_en_s cn38xxp2; -+ struct cvmx_smix_en_s cn50xx; -+ struct cvmx_smix_en_s cn52xx; -+ struct cvmx_smix_en_s cn52xxp1; -+ struct cvmx_smix_en_s cn56xx; -+ struct cvmx_smix_en_s cn56xxp1; -+ struct cvmx_smix_en_s cn58xx; -+ struct cvmx_smix_en_s cn58xxp1; -+}; -+ -+union cvmx_smix_rd_dat { -+ uint64_t u64; -+ struct cvmx_smix_rd_dat_s { -+ uint64_t reserved_18_63:46; -+ uint64_t pending:1; -+ uint64_t val:1; -+ uint64_t dat:16; -+ } s; -+ struct cvmx_smix_rd_dat_s cn30xx; -+ struct cvmx_smix_rd_dat_s cn31xx; -+ struct cvmx_smix_rd_dat_s cn38xx; -+ struct cvmx_smix_rd_dat_s cn38xxp2; -+ struct cvmx_smix_rd_dat_s cn50xx; -+ struct cvmx_smix_rd_dat_s cn52xx; -+ struct cvmx_smix_rd_dat_s cn52xxp1; -+ struct cvmx_smix_rd_dat_s cn56xx; -+ struct cvmx_smix_rd_dat_s cn56xxp1; -+ struct cvmx_smix_rd_dat_s cn58xx; -+ struct cvmx_smix_rd_dat_s cn58xxp1; -+}; -+ -+union cvmx_smix_wr_dat { -+ uint64_t u64; -+ struct cvmx_smix_wr_dat_s { -+ uint64_t reserved_18_63:46; -+ uint64_t pending:1; -+ uint64_t val:1; -+ uint64_t dat:16; -+ } s; -+ struct cvmx_smix_wr_dat_s cn30xx; -+ struct cvmx_smix_wr_dat_s cn31xx; -+ struct cvmx_smix_wr_dat_s cn38xx; -+ struct cvmx_smix_wr_dat_s cn38xxp2; -+ struct cvmx_smix_wr_dat_s cn50xx; -+ struct cvmx_smix_wr_dat_s cn52xx; -+ struct cvmx_smix_wr_dat_s cn52xxp1; -+ struct cvmx_smix_wr_dat_s cn56xx; -+ struct cvmx_smix_wr_dat_s cn56xxp1; -+ struct cvmx_smix_wr_dat_s cn58xx; -+ struct cvmx_smix_wr_dat_s cn58xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-spi.c -@@ -0,0 +1,667 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * -+ * Support library for the SPI -+ */ -+#include <asm/octeon/octeon.h> -+ -+#include "cvmx-config.h" -+ -+#include "cvmx-pko.h" -+#include "cvmx-spi.h" -+ -+#include "cvmx-spxx-defs.h" -+#include "cvmx-stxx-defs.h" -+#include "cvmx-srxx-defs.h" -+ -+#define INVOKE_CB(function_p, args...) \ -+ do { \ -+ if (function_p) { \ -+ res = function_p(args); \ -+ if (res) \ -+ return res; \ -+ } \ -+ } while (0) -+ -+#if CVMX_ENABLE_DEBUG_PRINTS -+static const char *modes[] = -+ { "UNKNOWN", "TX Halfplex", "Rx Halfplex", "Duplex" }; -+#endif -+ -+/* Default callbacks, can be overridden -+ * using cvmx_spi_get_callbacks/cvmx_spi_set_callbacks -+ */ -+static cvmx_spi_callbacks_t cvmx_spi_callbacks = { -+ .reset_cb = cvmx_spi_reset_cb, -+ .calendar_setup_cb = cvmx_spi_calendar_setup_cb, -+ .clock_detect_cb = cvmx_spi_clock_detect_cb, -+ .training_cb = cvmx_spi_training_cb, -+ .calendar_sync_cb = cvmx_spi_calendar_sync_cb, -+ .interface_up_cb = cvmx_spi_interface_up_cb -+}; -+ -+/** -+ * Get current SPI4 initialization callbacks -+ * -+ * @callbacks: Pointer to the callbacks structure.to fill -+ * -+ * Returns Pointer to cvmx_spi_callbacks_t structure. -+ */ -+void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks) -+{ -+ memcpy(callbacks, &cvmx_spi_callbacks, sizeof(cvmx_spi_callbacks)); -+} -+ -+/** -+ * Set new SPI4 initialization callbacks -+ * -+ * @new_callbacks: Pointer to an updated callbacks structure. -+ */ -+void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks) -+{ -+ memcpy(&cvmx_spi_callbacks, new_callbacks, sizeof(cvmx_spi_callbacks)); -+} -+ -+/** -+ * Initialize and start the SPI interface. -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * @timeout: Timeout to wait for clock synchronization in seconds -+ * @num_ports: Number of SPI ports to configure -+ * -+ * Returns Zero on success, negative of failure. -+ */ -+int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode, int timeout, -+ int num_ports) -+{ -+ int res = -1; -+ -+ if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))) -+ return res; -+ -+ /* Callback to perform SPI4 reset */ -+ INVOKE_CB(cvmx_spi_callbacks.reset_cb, interface, mode); -+ -+ /* Callback to perform calendar setup */ -+ INVOKE_CB(cvmx_spi_callbacks.calendar_setup_cb, interface, mode, -+ num_ports); -+ -+ /* Callback to perform clock detection */ -+ INVOKE_CB(cvmx_spi_callbacks.clock_detect_cb, interface, mode, timeout); -+ -+ /* Callback to perform SPI4 link training */ -+ INVOKE_CB(cvmx_spi_callbacks.training_cb, interface, mode, timeout); -+ -+ /* Callback to perform calendar sync */ -+ INVOKE_CB(cvmx_spi_callbacks.calendar_sync_cb, interface, mode, -+ timeout); -+ -+ /* Callback to handle interface coming up */ -+ INVOKE_CB(cvmx_spi_callbacks.interface_up_cb, interface, mode); -+ -+ return res; -+} -+ -+/** -+ * This routine restarts the SPI interface after it has lost synchronization -+ * with its correspondent system. -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * @timeout: Timeout to wait for clock synchronization in seconds -+ * -+ * Returns Zero on success, negative of failure. -+ */ -+int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode, int timeout) -+{ -+ int res = -1; -+ -+ if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))) -+ return res; -+ -+ cvmx_dprintf("SPI%d: Restart %s\n", interface, modes[mode]); -+ -+ /* Callback to perform SPI4 reset */ -+ INVOKE_CB(cvmx_spi_callbacks.reset_cb, interface, mode); -+ -+ /* NOTE: Calendar setup is not performed during restart */ -+ /* Refer to cvmx_spi_start_interface() for the full sequence */ -+ -+ /* Callback to perform clock detection */ -+ INVOKE_CB(cvmx_spi_callbacks.clock_detect_cb, interface, mode, timeout); -+ -+ /* Callback to perform SPI4 link training */ -+ INVOKE_CB(cvmx_spi_callbacks.training_cb, interface, mode, timeout); -+ -+ /* Callback to perform calendar sync */ -+ INVOKE_CB(cvmx_spi_callbacks.calendar_sync_cb, interface, mode, -+ timeout); -+ -+ /* Callback to handle interface coming up */ -+ INVOKE_CB(cvmx_spi_callbacks.interface_up_cb, interface, mode); -+ -+ return res; -+} -+ -+/** -+ * Callback to perform SPI4 reset -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * -+ * Returns Zero on success, non-zero error code on failure (will cause -+ * SPI initialization to abort) -+ */ -+int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode) -+{ -+ union cvmx_spxx_dbg_deskew_ctl spxx_dbg_deskew_ctl; -+ union cvmx_spxx_clk_ctl spxx_clk_ctl; -+ union cvmx_spxx_bist_stat spxx_bist_stat; -+ union cvmx_spxx_int_msk spxx_int_msk; -+ union cvmx_stxx_int_msk stxx_int_msk; -+ union cvmx_spxx_trn4_ctl spxx_trn4_ctl; -+ int index; -+ uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000; -+ -+ /* Disable SPI error events while we run BIST */ -+ spxx_int_msk.u64 = cvmx_read_csr(CVMX_SPXX_INT_MSK(interface)); -+ cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0); -+ stxx_int_msk.u64 = cvmx_read_csr(CVMX_STXX_INT_MSK(interface)); -+ cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0); -+ -+ /* Run BIST in the SPI interface */ -+ cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), 0); -+ cvmx_write_csr(CVMX_STXX_COM_CTL(interface), 0); -+ spxx_clk_ctl.u64 = 0; -+ spxx_clk_ctl.s.runbist = 1; -+ cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64); -+ cvmx_wait(10 * MS); -+ spxx_bist_stat.u64 = cvmx_read_csr(CVMX_SPXX_BIST_STAT(interface)); -+ if (spxx_bist_stat.s.stat0) -+ cvmx_dprintf -+ ("ERROR SPI%d: BIST failed on receive datapath FIFO\n", -+ interface); -+ if (spxx_bist_stat.s.stat1) -+ cvmx_dprintf("ERROR SPI%d: BIST failed on RX calendar table\n", -+ interface); -+ if (spxx_bist_stat.s.stat2) -+ cvmx_dprintf("ERROR SPI%d: BIST failed on TX calendar table\n", -+ interface); -+ -+ /* Clear the calendar table after BIST to fix parity errors */ -+ for (index = 0; index < 32; index++) { -+ union cvmx_srxx_spi4_calx srxx_spi4_calx; -+ union cvmx_stxx_spi4_calx stxx_spi4_calx; -+ -+ srxx_spi4_calx.u64 = 0; -+ srxx_spi4_calx.s.oddpar = 1; -+ cvmx_write_csr(CVMX_SRXX_SPI4_CALX(index, interface), -+ srxx_spi4_calx.u64); -+ -+ stxx_spi4_calx.u64 = 0; -+ stxx_spi4_calx.s.oddpar = 1; -+ cvmx_write_csr(CVMX_STXX_SPI4_CALX(index, interface), -+ stxx_spi4_calx.u64); -+ } -+ -+ /* Re enable reporting of error interrupts */ -+ cvmx_write_csr(CVMX_SPXX_INT_REG(interface), -+ cvmx_read_csr(CVMX_SPXX_INT_REG(interface))); -+ cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), spxx_int_msk.u64); -+ cvmx_write_csr(CVMX_STXX_INT_REG(interface), -+ cvmx_read_csr(CVMX_STXX_INT_REG(interface))); -+ cvmx_write_csr(CVMX_STXX_INT_MSK(interface), stxx_int_msk.u64); -+ -+ /* Setup the CLKDLY right in the middle */ -+ spxx_clk_ctl.u64 = 0; -+ spxx_clk_ctl.s.seetrn = 0; -+ spxx_clk_ctl.s.clkdly = 0x10; -+ spxx_clk_ctl.s.runbist = 0; -+ spxx_clk_ctl.s.statdrv = 0; -+ /* This should always be on the opposite edge as statdrv */ -+ spxx_clk_ctl.s.statrcv = 1; -+ spxx_clk_ctl.s.sndtrn = 0; -+ spxx_clk_ctl.s.drptrn = 0; -+ spxx_clk_ctl.s.rcvtrn = 0; -+ spxx_clk_ctl.s.srxdlck = 0; -+ cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64); -+ cvmx_wait(100 * MS); -+ -+ /* Reset SRX0 DLL */ -+ spxx_clk_ctl.s.srxdlck = 1; -+ cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64); -+ -+ /* Waiting for Inf0 Spi4 RX DLL to lock */ -+ cvmx_wait(100 * MS); -+ -+ /* Enable dynamic alignment */ -+ spxx_trn4_ctl.s.trntest = 0; -+ spxx_trn4_ctl.s.jitter = 1; -+ spxx_trn4_ctl.s.clr_boot = 1; -+ spxx_trn4_ctl.s.set_boot = 0; -+ if (OCTEON_IS_MODEL(OCTEON_CN58XX)) -+ spxx_trn4_ctl.s.maxdist = 3; -+ else -+ spxx_trn4_ctl.s.maxdist = 8; -+ spxx_trn4_ctl.s.macro_en = 1; -+ spxx_trn4_ctl.s.mux_en = 1; -+ cvmx_write_csr(CVMX_SPXX_TRN4_CTL(interface), spxx_trn4_ctl.u64); -+ -+ spxx_dbg_deskew_ctl.u64 = 0; -+ cvmx_write_csr(CVMX_SPXX_DBG_DESKEW_CTL(interface), -+ spxx_dbg_deskew_ctl.u64); -+ -+ return 0; -+} -+ -+/** -+ * Callback to setup calendar and miscellaneous settings before clock detection -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * @num_ports: Number of ports to configure on SPI -+ * -+ * Returns Zero on success, non-zero error code on failure (will cause -+ * SPI initialization to abort) -+ */ -+int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode, -+ int num_ports) -+{ -+ int port; -+ int index; -+ if (mode & CVMX_SPI_MODE_RX_HALFPLEX) { -+ union cvmx_srxx_com_ctl srxx_com_ctl; -+ union cvmx_srxx_spi4_stat srxx_spi4_stat; -+ -+ /* SRX0 number of Ports */ -+ srxx_com_ctl.u64 = 0; -+ srxx_com_ctl.s.prts = num_ports - 1; -+ srxx_com_ctl.s.st_en = 0; -+ srxx_com_ctl.s.inf_en = 0; -+ cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64); -+ -+ /* SRX0 Calendar Table. This round robbins through all ports */ -+ port = 0; -+ index = 0; -+ while (port < num_ports) { -+ union cvmx_srxx_spi4_calx srxx_spi4_calx; -+ srxx_spi4_calx.u64 = 0; -+ srxx_spi4_calx.s.prt0 = port++; -+ srxx_spi4_calx.s.prt1 = port++; -+ srxx_spi4_calx.s.prt2 = port++; -+ srxx_spi4_calx.s.prt3 = port++; -+ srxx_spi4_calx.s.oddpar = -+ ~(cvmx_dpop(srxx_spi4_calx.u64) & 1); -+ cvmx_write_csr(CVMX_SRXX_SPI4_CALX(index, interface), -+ srxx_spi4_calx.u64); -+ index++; -+ } -+ srxx_spi4_stat.u64 = 0; -+ srxx_spi4_stat.s.len = num_ports; -+ srxx_spi4_stat.s.m = 1; -+ cvmx_write_csr(CVMX_SRXX_SPI4_STAT(interface), -+ srxx_spi4_stat.u64); -+ } -+ -+ if (mode & CVMX_SPI_MODE_TX_HALFPLEX) { -+ union cvmx_stxx_arb_ctl stxx_arb_ctl; -+ union cvmx_gmxx_tx_spi_max gmxx_tx_spi_max; -+ union cvmx_gmxx_tx_spi_thresh gmxx_tx_spi_thresh; -+ union cvmx_gmxx_tx_spi_ctl gmxx_tx_spi_ctl; -+ union cvmx_stxx_spi4_stat stxx_spi4_stat; -+ union cvmx_stxx_spi4_dat stxx_spi4_dat; -+ -+ /* STX0 Config */ -+ stxx_arb_ctl.u64 = 0; -+ stxx_arb_ctl.s.igntpa = 0; -+ stxx_arb_ctl.s.mintrn = 0; -+ cvmx_write_csr(CVMX_STXX_ARB_CTL(interface), stxx_arb_ctl.u64); -+ -+ gmxx_tx_spi_max.u64 = 0; -+ gmxx_tx_spi_max.s.max1 = 8; -+ gmxx_tx_spi_max.s.max2 = 4; -+ gmxx_tx_spi_max.s.slice = 0; -+ cvmx_write_csr(CVMX_GMXX_TX_SPI_MAX(interface), -+ gmxx_tx_spi_max.u64); -+ -+ gmxx_tx_spi_thresh.u64 = 0; -+ gmxx_tx_spi_thresh.s.thresh = 4; -+ cvmx_write_csr(CVMX_GMXX_TX_SPI_THRESH(interface), -+ gmxx_tx_spi_thresh.u64); -+ -+ gmxx_tx_spi_ctl.u64 = 0; -+ gmxx_tx_spi_ctl.s.tpa_clr = 0; -+ gmxx_tx_spi_ctl.s.cont_pkt = 0; -+ cvmx_write_csr(CVMX_GMXX_TX_SPI_CTL(interface), -+ gmxx_tx_spi_ctl.u64); -+ -+ /* STX0 Training Control */ -+ stxx_spi4_dat.u64 = 0; -+ /*Minimum needed by dynamic alignment */ -+ stxx_spi4_dat.s.alpha = 32; -+ stxx_spi4_dat.s.max_t = 0xFFFF; /*Minimum interval is 0x20 */ -+ cvmx_write_csr(CVMX_STXX_SPI4_DAT(interface), -+ stxx_spi4_dat.u64); -+ -+ /* STX0 Calendar Table. This round robbins through all ports */ -+ port = 0; -+ index = 0; -+ while (port < num_ports) { -+ union cvmx_stxx_spi4_calx stxx_spi4_calx; -+ stxx_spi4_calx.u64 = 0; -+ stxx_spi4_calx.s.prt0 = port++; -+ stxx_spi4_calx.s.prt1 = port++; -+ stxx_spi4_calx.s.prt2 = port++; -+ stxx_spi4_calx.s.prt3 = port++; -+ stxx_spi4_calx.s.oddpar = -+ ~(cvmx_dpop(stxx_spi4_calx.u64) & 1); -+ cvmx_write_csr(CVMX_STXX_SPI4_CALX(index, interface), -+ stxx_spi4_calx.u64); -+ index++; -+ } -+ stxx_spi4_stat.u64 = 0; -+ stxx_spi4_stat.s.len = num_ports; -+ stxx_spi4_stat.s.m = 1; -+ cvmx_write_csr(CVMX_STXX_SPI4_STAT(interface), -+ stxx_spi4_stat.u64); -+ } -+ -+ return 0; -+} -+ -+/** -+ * Callback to perform clock detection -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * @timeout: Timeout to wait for clock synchronization in seconds -+ * -+ * Returns Zero on success, non-zero error code on failure (will cause -+ * SPI initialization to abort) -+ */ -+int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode, int timeout) -+{ -+ int clock_transitions; -+ union cvmx_spxx_clk_stat stat; -+ uint64_t timeout_time; -+ uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000; -+ -+ /* -+ * Regardless of operating mode, both Tx and Rx clocks must be -+ * present for the SPI interface to operate. -+ */ -+ cvmx_dprintf("SPI%d: Waiting to see TsClk...\n", interface); -+ timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout; -+ /* -+ * Require 100 clock transitions in order to avoid any noise -+ * in the beginning. -+ */ -+ clock_transitions = 100; -+ do { -+ stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface)); -+ if (stat.s.s4clk0 && stat.s.s4clk1 && clock_transitions) { -+ /* -+ * We've seen a clock transition, so decrement -+ * the number we still need. -+ */ -+ clock_transitions--; -+ cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64); -+ stat.s.s4clk0 = 0; -+ stat.s.s4clk1 = 0; -+ } -+ if (cvmx_get_cycle() > timeout_time) { -+ cvmx_dprintf("SPI%d: Timeout\n", interface); -+ return -1; -+ } -+ } while (stat.s.s4clk0 == 0 || stat.s.s4clk1 == 0); -+ -+ cvmx_dprintf("SPI%d: Waiting to see RsClk...\n", interface); -+ timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout; -+ /* -+ * Require 100 clock transitions in order to avoid any noise in the -+ * beginning. -+ */ -+ clock_transitions = 100; -+ do { -+ stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface)); -+ if (stat.s.d4clk0 && stat.s.d4clk1 && clock_transitions) { -+ /* -+ * We've seen a clock transition, so decrement -+ * the number we still need -+ */ -+ clock_transitions--; -+ cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64); -+ stat.s.d4clk0 = 0; -+ stat.s.d4clk1 = 0; -+ } -+ if (cvmx_get_cycle() > timeout_time) { -+ cvmx_dprintf("SPI%d: Timeout\n", interface); -+ return -1; -+ } -+ } while (stat.s.d4clk0 == 0 || stat.s.d4clk1 == 0); -+ -+ return 0; -+} -+ -+/** -+ * Callback to perform link training -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * @timeout: Timeout to wait for link to be trained (in seconds) -+ * -+ * Returns Zero on success, non-zero error code on failure (will cause -+ * SPI initialization to abort) -+ */ -+int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode, int timeout) -+{ -+ union cvmx_spxx_trn4_ctl spxx_trn4_ctl; -+ union cvmx_spxx_clk_stat stat; -+ uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000; -+ uint64_t timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout; -+ int rx_training_needed; -+ -+ /* SRX0 & STX0 Inf0 Links are configured - begin training */ -+ union cvmx_spxx_clk_ctl spxx_clk_ctl; -+ spxx_clk_ctl.u64 = 0; -+ spxx_clk_ctl.s.seetrn = 0; -+ spxx_clk_ctl.s.clkdly = 0x10; -+ spxx_clk_ctl.s.runbist = 0; -+ spxx_clk_ctl.s.statdrv = 0; -+ /* This should always be on the opposite edge as statdrv */ -+ spxx_clk_ctl.s.statrcv = 1; -+ spxx_clk_ctl.s.sndtrn = 1; -+ spxx_clk_ctl.s.drptrn = 1; -+ spxx_clk_ctl.s.rcvtrn = 1; -+ spxx_clk_ctl.s.srxdlck = 1; -+ cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64); -+ cvmx_wait(1000 * MS); -+ -+ /* SRX0 clear the boot bit */ -+ spxx_trn4_ctl.u64 = cvmx_read_csr(CVMX_SPXX_TRN4_CTL(interface)); -+ spxx_trn4_ctl.s.clr_boot = 1; -+ cvmx_write_csr(CVMX_SPXX_TRN4_CTL(interface), spxx_trn4_ctl.u64); -+ -+ /* Wait for the training sequence to complete */ -+ cvmx_dprintf("SPI%d: Waiting for training\n", interface); -+ cvmx_wait(1000 * MS); -+ /* Wait a really long time here */ -+ timeout_time = cvmx_get_cycle() + 1000ull * MS * 600; -+ /* -+ * The HRM says we must wait for 34 + 16 * MAXDIST training sequences. -+ * We'll be pessimistic and wait for a lot more. -+ */ -+ rx_training_needed = 500; -+ do { -+ stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface)); -+ if (stat.s.srxtrn && rx_training_needed) { -+ rx_training_needed--; -+ cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64); -+ stat.s.srxtrn = 0; -+ } -+ if (cvmx_get_cycle() > timeout_time) { -+ cvmx_dprintf("SPI%d: Timeout\n", interface); -+ return -1; -+ } -+ } while (stat.s.srxtrn == 0); -+ -+ return 0; -+} -+ -+/** -+ * Callback to perform calendar data synchronization -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * @timeout: Timeout to wait for calendar data in seconds -+ * -+ * Returns Zero on success, non-zero error code on failure (will cause -+ * SPI initialization to abort) -+ */ -+int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode, int timeout) -+{ -+ uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000; -+ if (mode & CVMX_SPI_MODE_RX_HALFPLEX) { -+ /* SRX0 interface should be good, send calendar data */ -+ union cvmx_srxx_com_ctl srxx_com_ctl; -+ cvmx_dprintf -+ ("SPI%d: Rx is synchronized, start sending calendar data\n", -+ interface); -+ srxx_com_ctl.u64 = cvmx_read_csr(CVMX_SRXX_COM_CTL(interface)); -+ srxx_com_ctl.s.inf_en = 1; -+ srxx_com_ctl.s.st_en = 1; -+ cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64); -+ } -+ -+ if (mode & CVMX_SPI_MODE_TX_HALFPLEX) { -+ /* STX0 has achieved sync */ -+ /* The corespondant board should be sending calendar data */ -+ /* Enable the STX0 STAT receiver. */ -+ union cvmx_spxx_clk_stat stat; -+ uint64_t timeout_time; -+ union cvmx_stxx_com_ctl stxx_com_ctl; -+ stxx_com_ctl.u64 = 0; -+ stxx_com_ctl.s.st_en = 1; -+ cvmx_write_csr(CVMX_STXX_COM_CTL(interface), stxx_com_ctl.u64); -+ -+ /* Waiting for calendar sync on STX0 STAT */ -+ cvmx_dprintf("SPI%d: Waiting to sync on STX[%d] STAT\n", -+ interface, interface); -+ timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout; -+ /* SPX0_CLK_STAT - SPX0_CLK_STAT[STXCAL] should be 1 (bit10) */ -+ do { -+ stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface)); -+ if (cvmx_get_cycle() > timeout_time) { -+ cvmx_dprintf("SPI%d: Timeout\n", interface); -+ return -1; -+ } -+ } while (stat.s.stxcal == 0); -+ } -+ -+ return 0; -+} -+ -+/** -+ * Callback to handle interface up -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * -+ * Returns Zero on success, non-zero error code on failure (will cause -+ * SPI initialization to abort) -+ */ -+int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode) -+{ -+ union cvmx_gmxx_rxx_frm_min gmxx_rxx_frm_min; -+ union cvmx_gmxx_rxx_frm_max gmxx_rxx_frm_max; -+ union cvmx_gmxx_rxx_jabber gmxx_rxx_jabber; -+ -+ if (mode & CVMX_SPI_MODE_RX_HALFPLEX) { -+ union cvmx_srxx_com_ctl srxx_com_ctl; -+ srxx_com_ctl.u64 = cvmx_read_csr(CVMX_SRXX_COM_CTL(interface)); -+ srxx_com_ctl.s.inf_en = 1; -+ cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64); -+ cvmx_dprintf("SPI%d: Rx is now up\n", interface); -+ } -+ -+ if (mode & CVMX_SPI_MODE_TX_HALFPLEX) { -+ union cvmx_stxx_com_ctl stxx_com_ctl; -+ stxx_com_ctl.u64 = cvmx_read_csr(CVMX_STXX_COM_CTL(interface)); -+ stxx_com_ctl.s.inf_en = 1; -+ cvmx_write_csr(CVMX_STXX_COM_CTL(interface), stxx_com_ctl.u64); -+ cvmx_dprintf("SPI%d: Tx is now up\n", interface); -+ } -+ -+ gmxx_rxx_frm_min.u64 = 0; -+ gmxx_rxx_frm_min.s.len = 64; -+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_MIN(0, interface), -+ gmxx_rxx_frm_min.u64); -+ gmxx_rxx_frm_max.u64 = 0; -+ gmxx_rxx_frm_max.s.len = 64 * 1024 - 4; -+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(0, interface), -+ gmxx_rxx_frm_max.u64); -+ gmxx_rxx_jabber.u64 = 0; -+ gmxx_rxx_jabber.s.cnt = 64 * 1024 - 4; -+ cvmx_write_csr(CVMX_GMXX_RXX_JABBER(0, interface), gmxx_rxx_jabber.u64); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-spi.h -@@ -0,0 +1,269 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/* -+ * -+ * This file contains defines for the SPI interface -+ */ -+#ifndef __CVMX_SPI_H__ -+#define __CVMX_SPI_H__ -+ -+#include "cvmx-gmxx-defs.h" -+ -+/* CSR typedefs have been moved to cvmx-csr-*.h */ -+ -+typedef enum { -+ CVMX_SPI_MODE_UNKNOWN = 0, -+ CVMX_SPI_MODE_TX_HALFPLEX = 1, -+ CVMX_SPI_MODE_RX_HALFPLEX = 2, -+ CVMX_SPI_MODE_DUPLEX = 3 -+} cvmx_spi_mode_t; -+ -+/** Callbacks structure to customize SPI4 initialization sequence */ -+typedef struct { -+ /** Called to reset SPI4 DLL */ -+ int (*reset_cb) (int interface, cvmx_spi_mode_t mode); -+ -+ /** Called to setup calendar */ -+ int (*calendar_setup_cb) (int interface, cvmx_spi_mode_t mode, -+ int num_ports); -+ -+ /** Called for Tx and Rx clock detection */ -+ int (*clock_detect_cb) (int interface, cvmx_spi_mode_t mode, -+ int timeout); -+ -+ /** Called to perform link training */ -+ int (*training_cb) (int interface, cvmx_spi_mode_t mode, int timeout); -+ -+ /** Called for calendar data synchronization */ -+ int (*calendar_sync_cb) (int interface, cvmx_spi_mode_t mode, -+ int timeout); -+ -+ /** Called when interface is up */ -+ int (*interface_up_cb) (int interface, cvmx_spi_mode_t mode); -+ -+} cvmx_spi_callbacks_t; -+ -+/** -+ * Return true if the supplied interface is configured for SPI -+ * -+ * @interface: Interface to check -+ * Returns True if interface is SPI -+ */ -+static inline int cvmx_spi_is_spi_interface(int interface) -+{ -+ uint64_t gmxState = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface)); -+ return (gmxState & 0x2) && (gmxState & 0x1); -+} -+ -+/** -+ * Initialize and start the SPI interface. -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * @timeout: Timeout to wait for clock synchronization in seconds -+ * @num_ports: Number of SPI ports to configure -+ * -+ * Returns Zero on success, negative of failure. -+ */ -+extern int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode, -+ int timeout, int num_ports); -+ -+/** -+ * This routine restarts the SPI interface after it has lost synchronization -+ * with its corespondant system. -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * @timeout: Timeout to wait for clock synchronization in seconds -+ * Returns Zero on success, negative of failure. -+ */ -+extern int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode, -+ int timeout); -+ -+/** -+ * Return non-zero if the SPI interface has a SPI4000 attached -+ * -+ * @interface: SPI interface the SPI4000 is connected to -+ * -+ * Returns -+ */ -+static inline int cvmx_spi4000_is_present(int interface) -+{ -+ return 0; -+} -+ -+/** -+ * Initialize the SPI4000 for use -+ * -+ * @interface: SPI interface the SPI4000 is connected to -+ */ -+static inline int cvmx_spi4000_initialize(int interface) -+{ -+ return 0; -+} -+ -+/** -+ * Poll all the SPI4000 port and check its speed -+ * -+ * @interface: Interface the SPI4000 is on -+ * @port: Port to poll (0-9) -+ * Returns Status of the port. 0=down. All other values the port is up. -+ */ -+static inline union cvmx_gmxx_rxx_rx_inbnd cvmx_spi4000_check_speed( -+ int interface, -+ int port) -+{ -+ union cvmx_gmxx_rxx_rx_inbnd r; -+ r.u64 = 0; -+ return r; -+} -+ -+/** -+ * Get current SPI4 initialization callbacks -+ * -+ * @callbacks: Pointer to the callbacks structure.to fill -+ * -+ * Returns Pointer to cvmx_spi_callbacks_t structure. -+ */ -+extern void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks); -+ -+/** -+ * Set new SPI4 initialization callbacks -+ * -+ * @new_callbacks: Pointer to an updated callbacks structure. -+ */ -+extern void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks); -+ -+/** -+ * Callback to perform SPI4 reset -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * -+ * Returns Zero on success, non-zero error code on failure (will cause -+ * SPI initialization to abort) -+ */ -+extern int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode); -+ -+/** -+ * Callback to setup calendar and miscellaneous settings before clock -+ * detection -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * @num_ports: Number of ports to configure on SPI -+ * -+ * Returns Zero on success, non-zero error code on failure (will cause -+ * SPI initialization to abort) -+ */ -+extern int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode, -+ int num_ports); -+ -+/** -+ * Callback to perform clock detection -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * @timeout: Timeout to wait for clock synchronization in seconds -+ * -+ * Returns Zero on success, non-zero error code on failure (will cause -+ * SPI initialization to abort) -+ */ -+extern int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode, -+ int timeout); -+ -+/** -+ * Callback to perform link training -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * @timeout: Timeout to wait for link to be trained (in seconds) -+ * -+ * Returns Zero on success, non-zero error code on failure (will cause -+ * SPI initialization to abort) -+ */ -+extern int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode, -+ int timeout); -+ -+/** -+ * Callback to perform calendar data synchronization -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * @timeout: Timeout to wait for calendar data in seconds -+ * -+ * Returns Zero on success, non-zero error code on failure (will cause -+ * SPI initialization to abort) -+ */ -+extern int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode, -+ int timeout); -+ -+/** -+ * Callback to handle interface up -+ * -+ * @interface: The identifier of the packet interface to configure and -+ * use as a SPI interface. -+ * @mode: The operating mode for the SPI interface. The interface -+ * can operate as a full duplex (both Tx and Rx data paths -+ * active) or as a halfplex (either the Tx data path is -+ * active or the Rx data path is active, but not both). -+ * -+ * Returns Zero on success, non-zero error code on failure (will cause -+ * SPI initialization to abort) -+ */ -+extern int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode); -+ -+#endif /* __CVMX_SPI_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-spxx-defs.h -@@ -0,0 +1,347 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_SPXX_DEFS_H__ -+#define __CVMX_SPXX_DEFS_H__ -+ -+#define CVMX_SPXX_BCKPRS_CNT(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000340ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_BIST_STAT(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800900007F8ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_CLK_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000348ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_CLK_STAT(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000350ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_DBG_DESKEW_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000368ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_DBG_DESKEW_STATE(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000370ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_DRV_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000358ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_ERR_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000320ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_INT_DAT(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000318ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_INT_MSK(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000308ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_INT_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000300ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_INT_SYNC(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000310ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_TPA_ACC(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000338ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_TPA_MAX(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000330ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_TPA_SEL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000328ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SPXX_TRN4_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000360ull + (((block_id) & 1) * 0x8000000ull)) -+ -+union cvmx_spxx_bckprs_cnt { -+ uint64_t u64; -+ struct cvmx_spxx_bckprs_cnt_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_spxx_bckprs_cnt_s cn38xx; -+ struct cvmx_spxx_bckprs_cnt_s cn38xxp2; -+ struct cvmx_spxx_bckprs_cnt_s cn58xx; -+ struct cvmx_spxx_bckprs_cnt_s cn58xxp1; -+}; -+ -+union cvmx_spxx_bist_stat { -+ uint64_t u64; -+ struct cvmx_spxx_bist_stat_s { -+ uint64_t reserved_3_63:61; -+ uint64_t stat2:1; -+ uint64_t stat1:1; -+ uint64_t stat0:1; -+ } s; -+ struct cvmx_spxx_bist_stat_s cn38xx; -+ struct cvmx_spxx_bist_stat_s cn38xxp2; -+ struct cvmx_spxx_bist_stat_s cn58xx; -+ struct cvmx_spxx_bist_stat_s cn58xxp1; -+}; -+ -+union cvmx_spxx_clk_ctl { -+ uint64_t u64; -+ struct cvmx_spxx_clk_ctl_s { -+ uint64_t reserved_17_63:47; -+ uint64_t seetrn:1; -+ uint64_t reserved_12_15:4; -+ uint64_t clkdly:5; -+ uint64_t runbist:1; -+ uint64_t statdrv:1; -+ uint64_t statrcv:1; -+ uint64_t sndtrn:1; -+ uint64_t drptrn:1; -+ uint64_t rcvtrn:1; -+ uint64_t srxdlck:1; -+ } s; -+ struct cvmx_spxx_clk_ctl_s cn38xx; -+ struct cvmx_spxx_clk_ctl_s cn38xxp2; -+ struct cvmx_spxx_clk_ctl_s cn58xx; -+ struct cvmx_spxx_clk_ctl_s cn58xxp1; -+}; -+ -+union cvmx_spxx_clk_stat { -+ uint64_t u64; -+ struct cvmx_spxx_clk_stat_s { -+ uint64_t reserved_11_63:53; -+ uint64_t stxcal:1; -+ uint64_t reserved_9_9:1; -+ uint64_t srxtrn:1; -+ uint64_t s4clk1:1; -+ uint64_t s4clk0:1; -+ uint64_t d4clk1:1; -+ uint64_t d4clk0:1; -+ uint64_t reserved_0_3:4; -+ } s; -+ struct cvmx_spxx_clk_stat_s cn38xx; -+ struct cvmx_spxx_clk_stat_s cn38xxp2; -+ struct cvmx_spxx_clk_stat_s cn58xx; -+ struct cvmx_spxx_clk_stat_s cn58xxp1; -+}; -+ -+union cvmx_spxx_dbg_deskew_ctl { -+ uint64_t u64; -+ struct cvmx_spxx_dbg_deskew_ctl_s { -+ uint64_t reserved_30_63:34; -+ uint64_t fallnop:1; -+ uint64_t fall8:1; -+ uint64_t reserved_26_27:2; -+ uint64_t sstep_go:1; -+ uint64_t sstep:1; -+ uint64_t reserved_22_23:2; -+ uint64_t clrdly:1; -+ uint64_t dec:1; -+ uint64_t inc:1; -+ uint64_t mux:1; -+ uint64_t offset:5; -+ uint64_t bitsel:5; -+ uint64_t offdly:6; -+ uint64_t dllfrc:1; -+ uint64_t dlldis:1; -+ } s; -+ struct cvmx_spxx_dbg_deskew_ctl_s cn38xx; -+ struct cvmx_spxx_dbg_deskew_ctl_s cn38xxp2; -+ struct cvmx_spxx_dbg_deskew_ctl_s cn58xx; -+ struct cvmx_spxx_dbg_deskew_ctl_s cn58xxp1; -+}; -+ -+union cvmx_spxx_dbg_deskew_state { -+ uint64_t u64; -+ struct cvmx_spxx_dbg_deskew_state_s { -+ uint64_t reserved_9_63:55; -+ uint64_t testres:1; -+ uint64_t unxterm:1; -+ uint64_t muxsel:2; -+ uint64_t offset:5; -+ } s; -+ struct cvmx_spxx_dbg_deskew_state_s cn38xx; -+ struct cvmx_spxx_dbg_deskew_state_s cn38xxp2; -+ struct cvmx_spxx_dbg_deskew_state_s cn58xx; -+ struct cvmx_spxx_dbg_deskew_state_s cn58xxp1; -+}; -+ -+union cvmx_spxx_drv_ctl { -+ uint64_t u64; -+ struct cvmx_spxx_drv_ctl_s { -+ uint64_t reserved_0_63:64; -+ } s; -+ struct cvmx_spxx_drv_ctl_cn38xx { -+ uint64_t reserved_16_63:48; -+ uint64_t stx4ncmp:4; -+ uint64_t stx4pcmp:4; -+ uint64_t srx4cmp:8; -+ } cn38xx; -+ struct cvmx_spxx_drv_ctl_cn38xx cn38xxp2; -+ struct cvmx_spxx_drv_ctl_cn58xx { -+ uint64_t reserved_24_63:40; -+ uint64_t stx4ncmp:4; -+ uint64_t stx4pcmp:4; -+ uint64_t reserved_10_15:6; -+ uint64_t srx4cmp:10; -+ } cn58xx; -+ struct cvmx_spxx_drv_ctl_cn58xx cn58xxp1; -+}; -+ -+union cvmx_spxx_err_ctl { -+ uint64_t u64; -+ struct cvmx_spxx_err_ctl_s { -+ uint64_t reserved_9_63:55; -+ uint64_t prtnxa:1; -+ uint64_t dipcls:1; -+ uint64_t dippay:1; -+ uint64_t reserved_4_5:2; -+ uint64_t errcnt:4; -+ } s; -+ struct cvmx_spxx_err_ctl_s cn38xx; -+ struct cvmx_spxx_err_ctl_s cn38xxp2; -+ struct cvmx_spxx_err_ctl_s cn58xx; -+ struct cvmx_spxx_err_ctl_s cn58xxp1; -+}; -+ -+union cvmx_spxx_int_dat { -+ uint64_t u64; -+ struct cvmx_spxx_int_dat_s { -+ uint64_t reserved_32_63:32; -+ uint64_t mul:1; -+ uint64_t reserved_14_30:17; -+ uint64_t calbnk:2; -+ uint64_t rsvop:4; -+ uint64_t prt:8; -+ } s; -+ struct cvmx_spxx_int_dat_s cn38xx; -+ struct cvmx_spxx_int_dat_s cn38xxp2; -+ struct cvmx_spxx_int_dat_s cn58xx; -+ struct cvmx_spxx_int_dat_s cn58xxp1; -+}; -+ -+union cvmx_spxx_int_msk { -+ uint64_t u64; -+ struct cvmx_spxx_int_msk_s { -+ uint64_t reserved_12_63:52; -+ uint64_t calerr:1; -+ uint64_t syncerr:1; -+ uint64_t diperr:1; -+ uint64_t tpaovr:1; -+ uint64_t rsverr:1; -+ uint64_t drwnng:1; -+ uint64_t clserr:1; -+ uint64_t spiovr:1; -+ uint64_t reserved_2_3:2; -+ uint64_t abnorm:1; -+ uint64_t prtnxa:1; -+ } s; -+ struct cvmx_spxx_int_msk_s cn38xx; -+ struct cvmx_spxx_int_msk_s cn38xxp2; -+ struct cvmx_spxx_int_msk_s cn58xx; -+ struct cvmx_spxx_int_msk_s cn58xxp1; -+}; -+ -+union cvmx_spxx_int_reg { -+ uint64_t u64; -+ struct cvmx_spxx_int_reg_s { -+ uint64_t reserved_32_63:32; -+ uint64_t spf:1; -+ uint64_t reserved_12_30:19; -+ uint64_t calerr:1; -+ uint64_t syncerr:1; -+ uint64_t diperr:1; -+ uint64_t tpaovr:1; -+ uint64_t rsverr:1; -+ uint64_t drwnng:1; -+ uint64_t clserr:1; -+ uint64_t spiovr:1; -+ uint64_t reserved_2_3:2; -+ uint64_t abnorm:1; -+ uint64_t prtnxa:1; -+ } s; -+ struct cvmx_spxx_int_reg_s cn38xx; -+ struct cvmx_spxx_int_reg_s cn38xxp2; -+ struct cvmx_spxx_int_reg_s cn58xx; -+ struct cvmx_spxx_int_reg_s cn58xxp1; -+}; -+ -+union cvmx_spxx_int_sync { -+ uint64_t u64; -+ struct cvmx_spxx_int_sync_s { -+ uint64_t reserved_12_63:52; -+ uint64_t calerr:1; -+ uint64_t syncerr:1; -+ uint64_t diperr:1; -+ uint64_t tpaovr:1; -+ uint64_t rsverr:1; -+ uint64_t drwnng:1; -+ uint64_t clserr:1; -+ uint64_t spiovr:1; -+ uint64_t reserved_2_3:2; -+ uint64_t abnorm:1; -+ uint64_t prtnxa:1; -+ } s; -+ struct cvmx_spxx_int_sync_s cn38xx; -+ struct cvmx_spxx_int_sync_s cn38xxp2; -+ struct cvmx_spxx_int_sync_s cn58xx; -+ struct cvmx_spxx_int_sync_s cn58xxp1; -+}; -+ -+union cvmx_spxx_tpa_acc { -+ uint64_t u64; -+ struct cvmx_spxx_tpa_acc_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_spxx_tpa_acc_s cn38xx; -+ struct cvmx_spxx_tpa_acc_s cn38xxp2; -+ struct cvmx_spxx_tpa_acc_s cn58xx; -+ struct cvmx_spxx_tpa_acc_s cn58xxp1; -+}; -+ -+union cvmx_spxx_tpa_max { -+ uint64_t u64; -+ struct cvmx_spxx_tpa_max_s { -+ uint64_t reserved_32_63:32; -+ uint64_t max:32; -+ } s; -+ struct cvmx_spxx_tpa_max_s cn38xx; -+ struct cvmx_spxx_tpa_max_s cn38xxp2; -+ struct cvmx_spxx_tpa_max_s cn58xx; -+ struct cvmx_spxx_tpa_max_s cn58xxp1; -+}; -+ -+union cvmx_spxx_tpa_sel { -+ uint64_t u64; -+ struct cvmx_spxx_tpa_sel_s { -+ uint64_t reserved_4_63:60; -+ uint64_t prtsel:4; -+ } s; -+ struct cvmx_spxx_tpa_sel_s cn38xx; -+ struct cvmx_spxx_tpa_sel_s cn38xxp2; -+ struct cvmx_spxx_tpa_sel_s cn58xx; -+ struct cvmx_spxx_tpa_sel_s cn58xxp1; -+}; -+ -+union cvmx_spxx_trn4_ctl { -+ uint64_t u64; -+ struct cvmx_spxx_trn4_ctl_s { -+ uint64_t reserved_13_63:51; -+ uint64_t trntest:1; -+ uint64_t jitter:3; -+ uint64_t clr_boot:1; -+ uint64_t set_boot:1; -+ uint64_t maxdist:5; -+ uint64_t macro_en:1; -+ uint64_t mux_en:1; -+ } s; -+ struct cvmx_spxx_trn4_ctl_s cn38xx; -+ struct cvmx_spxx_trn4_ctl_s cn38xxp2; -+ struct cvmx_spxx_trn4_ctl_s cn58xx; -+ struct cvmx_spxx_trn4_ctl_s cn58xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-srxx-defs.h -@@ -0,0 +1,126 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_SRXX_DEFS_H__ -+#define __CVMX_SRXX_DEFS_H__ -+ -+#define CVMX_SRXX_COM_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000200ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SRXX_IGN_RX_FULL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000218ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SRXX_SPI4_CALX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000000ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SRXX_SPI4_STAT(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000208ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SRXX_SW_TICK_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000220ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_SRXX_SW_TICK_DAT(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000228ull + (((block_id) & 1) * 0x8000000ull)) -+ -+union cvmx_srxx_com_ctl { -+ uint64_t u64; -+ struct cvmx_srxx_com_ctl_s { -+ uint64_t reserved_8_63:56; -+ uint64_t prts:4; -+ uint64_t st_en:1; -+ uint64_t reserved_1_2:2; -+ uint64_t inf_en:1; -+ } s; -+ struct cvmx_srxx_com_ctl_s cn38xx; -+ struct cvmx_srxx_com_ctl_s cn38xxp2; -+ struct cvmx_srxx_com_ctl_s cn58xx; -+ struct cvmx_srxx_com_ctl_s cn58xxp1; -+}; -+ -+union cvmx_srxx_ign_rx_full { -+ uint64_t u64; -+ struct cvmx_srxx_ign_rx_full_s { -+ uint64_t reserved_16_63:48; -+ uint64_t ignore:16; -+ } s; -+ struct cvmx_srxx_ign_rx_full_s cn38xx; -+ struct cvmx_srxx_ign_rx_full_s cn38xxp2; -+ struct cvmx_srxx_ign_rx_full_s cn58xx; -+ struct cvmx_srxx_ign_rx_full_s cn58xxp1; -+}; -+ -+union cvmx_srxx_spi4_calx { -+ uint64_t u64; -+ struct cvmx_srxx_spi4_calx_s { -+ uint64_t reserved_17_63:47; -+ uint64_t oddpar:1; -+ uint64_t prt3:4; -+ uint64_t prt2:4; -+ uint64_t prt1:4; -+ uint64_t prt0:4; -+ } s; -+ struct cvmx_srxx_spi4_calx_s cn38xx; -+ struct cvmx_srxx_spi4_calx_s cn38xxp2; -+ struct cvmx_srxx_spi4_calx_s cn58xx; -+ struct cvmx_srxx_spi4_calx_s cn58xxp1; -+}; -+ -+union cvmx_srxx_spi4_stat { -+ uint64_t u64; -+ struct cvmx_srxx_spi4_stat_s { -+ uint64_t reserved_16_63:48; -+ uint64_t m:8; -+ uint64_t reserved_7_7:1; -+ uint64_t len:7; -+ } s; -+ struct cvmx_srxx_spi4_stat_s cn38xx; -+ struct cvmx_srxx_spi4_stat_s cn38xxp2; -+ struct cvmx_srxx_spi4_stat_s cn58xx; -+ struct cvmx_srxx_spi4_stat_s cn58xxp1; -+}; -+ -+union cvmx_srxx_sw_tick_ctl { -+ uint64_t u64; -+ struct cvmx_srxx_sw_tick_ctl_s { -+ uint64_t reserved_14_63:50; -+ uint64_t eop:1; -+ uint64_t sop:1; -+ uint64_t mod:4; -+ uint64_t opc:4; -+ uint64_t adr:4; -+ } s; -+ struct cvmx_srxx_sw_tick_ctl_s cn38xx; -+ struct cvmx_srxx_sw_tick_ctl_s cn58xx; -+ struct cvmx_srxx_sw_tick_ctl_s cn58xxp1; -+}; -+ -+union cvmx_srxx_sw_tick_dat { -+ uint64_t u64; -+ struct cvmx_srxx_sw_tick_dat_s { -+ uint64_t dat:64; -+ } s; -+ struct cvmx_srxx_sw_tick_dat_s cn38xx; -+ struct cvmx_srxx_sw_tick_dat_s cn58xx; -+ struct cvmx_srxx_sw_tick_dat_s cn58xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-stxx-defs.h -@@ -0,0 +1,292 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_STXX_DEFS_H__ -+#define __CVMX_STXX_DEFS_H__ -+ -+#define CVMX_STXX_ARB_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000608ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_BCKPRS_CNT(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000688ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_COM_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000600ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_DIP_CNT(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000690ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_IGN_CAL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000610ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_INT_MSK(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800900006A0ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_INT_REG(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000698ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_INT_SYNC(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800900006A8ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_MIN_BST(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000618ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_SPI4_CALX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000400ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_SPI4_DAT(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000628ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_SPI4_STAT(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000630ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_STAT_BYTES_HI(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000648ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_STAT_BYTES_LO(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000680ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_STAT_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000638ull + (((block_id) & 1) * 0x8000000ull)) -+#define CVMX_STXX_STAT_PKT_XMT(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180090000640ull + (((block_id) & 1) * 0x8000000ull)) -+ -+union cvmx_stxx_arb_ctl { -+ uint64_t u64; -+ struct cvmx_stxx_arb_ctl_s { -+ uint64_t reserved_6_63:58; -+ uint64_t mintrn:1; -+ uint64_t reserved_4_4:1; -+ uint64_t igntpa:1; -+ uint64_t reserved_0_2:3; -+ } s; -+ struct cvmx_stxx_arb_ctl_s cn38xx; -+ struct cvmx_stxx_arb_ctl_s cn38xxp2; -+ struct cvmx_stxx_arb_ctl_s cn58xx; -+ struct cvmx_stxx_arb_ctl_s cn58xxp1; -+}; -+ -+union cvmx_stxx_bckprs_cnt { -+ uint64_t u64; -+ struct cvmx_stxx_bckprs_cnt_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_stxx_bckprs_cnt_s cn38xx; -+ struct cvmx_stxx_bckprs_cnt_s cn38xxp2; -+ struct cvmx_stxx_bckprs_cnt_s cn58xx; -+ struct cvmx_stxx_bckprs_cnt_s cn58xxp1; -+}; -+ -+union cvmx_stxx_com_ctl { -+ uint64_t u64; -+ struct cvmx_stxx_com_ctl_s { -+ uint64_t reserved_4_63:60; -+ uint64_t st_en:1; -+ uint64_t reserved_1_2:2; -+ uint64_t inf_en:1; -+ } s; -+ struct cvmx_stxx_com_ctl_s cn38xx; -+ struct cvmx_stxx_com_ctl_s cn38xxp2; -+ struct cvmx_stxx_com_ctl_s cn58xx; -+ struct cvmx_stxx_com_ctl_s cn58xxp1; -+}; -+ -+union cvmx_stxx_dip_cnt { -+ uint64_t u64; -+ struct cvmx_stxx_dip_cnt_s { -+ uint64_t reserved_8_63:56; -+ uint64_t frmmax:4; -+ uint64_t dipmax:4; -+ } s; -+ struct cvmx_stxx_dip_cnt_s cn38xx; -+ struct cvmx_stxx_dip_cnt_s cn38xxp2; -+ struct cvmx_stxx_dip_cnt_s cn58xx; -+ struct cvmx_stxx_dip_cnt_s cn58xxp1; -+}; -+ -+union cvmx_stxx_ign_cal { -+ uint64_t u64; -+ struct cvmx_stxx_ign_cal_s { -+ uint64_t reserved_16_63:48; -+ uint64_t igntpa:16; -+ } s; -+ struct cvmx_stxx_ign_cal_s cn38xx; -+ struct cvmx_stxx_ign_cal_s cn38xxp2; -+ struct cvmx_stxx_ign_cal_s cn58xx; -+ struct cvmx_stxx_ign_cal_s cn58xxp1; -+}; -+ -+union cvmx_stxx_int_msk { -+ uint64_t u64; -+ struct cvmx_stxx_int_msk_s { -+ uint64_t reserved_8_63:56; -+ uint64_t frmerr:1; -+ uint64_t unxfrm:1; -+ uint64_t nosync:1; -+ uint64_t diperr:1; -+ uint64_t datovr:1; -+ uint64_t ovrbst:1; -+ uint64_t calpar1:1; -+ uint64_t calpar0:1; -+ } s; -+ struct cvmx_stxx_int_msk_s cn38xx; -+ struct cvmx_stxx_int_msk_s cn38xxp2; -+ struct cvmx_stxx_int_msk_s cn58xx; -+ struct cvmx_stxx_int_msk_s cn58xxp1; -+}; -+ -+union cvmx_stxx_int_reg { -+ uint64_t u64; -+ struct cvmx_stxx_int_reg_s { -+ uint64_t reserved_9_63:55; -+ uint64_t syncerr:1; -+ uint64_t frmerr:1; -+ uint64_t unxfrm:1; -+ uint64_t nosync:1; -+ uint64_t diperr:1; -+ uint64_t datovr:1; -+ uint64_t ovrbst:1; -+ uint64_t calpar1:1; -+ uint64_t calpar0:1; -+ } s; -+ struct cvmx_stxx_int_reg_s cn38xx; -+ struct cvmx_stxx_int_reg_s cn38xxp2; -+ struct cvmx_stxx_int_reg_s cn58xx; -+ struct cvmx_stxx_int_reg_s cn58xxp1; -+}; -+ -+union cvmx_stxx_int_sync { -+ uint64_t u64; -+ struct cvmx_stxx_int_sync_s { -+ uint64_t reserved_8_63:56; -+ uint64_t frmerr:1; -+ uint64_t unxfrm:1; -+ uint64_t nosync:1; -+ uint64_t diperr:1; -+ uint64_t datovr:1; -+ uint64_t ovrbst:1; -+ uint64_t calpar1:1; -+ uint64_t calpar0:1; -+ } s; -+ struct cvmx_stxx_int_sync_s cn38xx; -+ struct cvmx_stxx_int_sync_s cn38xxp2; -+ struct cvmx_stxx_int_sync_s cn58xx; -+ struct cvmx_stxx_int_sync_s cn58xxp1; -+}; -+ -+union cvmx_stxx_min_bst { -+ uint64_t u64; -+ struct cvmx_stxx_min_bst_s { -+ uint64_t reserved_9_63:55; -+ uint64_t minb:9; -+ } s; -+ struct cvmx_stxx_min_bst_s cn38xx; -+ struct cvmx_stxx_min_bst_s cn38xxp2; -+ struct cvmx_stxx_min_bst_s cn58xx; -+ struct cvmx_stxx_min_bst_s cn58xxp1; -+}; -+ -+union cvmx_stxx_spi4_calx { -+ uint64_t u64; -+ struct cvmx_stxx_spi4_calx_s { -+ uint64_t reserved_17_63:47; -+ uint64_t oddpar:1; -+ uint64_t prt3:4; -+ uint64_t prt2:4; -+ uint64_t prt1:4; -+ uint64_t prt0:4; -+ } s; -+ struct cvmx_stxx_spi4_calx_s cn38xx; -+ struct cvmx_stxx_spi4_calx_s cn38xxp2; -+ struct cvmx_stxx_spi4_calx_s cn58xx; -+ struct cvmx_stxx_spi4_calx_s cn58xxp1; -+}; -+ -+union cvmx_stxx_spi4_dat { -+ uint64_t u64; -+ struct cvmx_stxx_spi4_dat_s { -+ uint64_t reserved_32_63:32; -+ uint64_t alpha:16; -+ uint64_t max_t:16; -+ } s; -+ struct cvmx_stxx_spi4_dat_s cn38xx; -+ struct cvmx_stxx_spi4_dat_s cn38xxp2; -+ struct cvmx_stxx_spi4_dat_s cn58xx; -+ struct cvmx_stxx_spi4_dat_s cn58xxp1; -+}; -+ -+union cvmx_stxx_spi4_stat { -+ uint64_t u64; -+ struct cvmx_stxx_spi4_stat_s { -+ uint64_t reserved_16_63:48; -+ uint64_t m:8; -+ uint64_t reserved_7_7:1; -+ uint64_t len:7; -+ } s; -+ struct cvmx_stxx_spi4_stat_s cn38xx; -+ struct cvmx_stxx_spi4_stat_s cn38xxp2; -+ struct cvmx_stxx_spi4_stat_s cn58xx; -+ struct cvmx_stxx_spi4_stat_s cn58xxp1; -+}; -+ -+union cvmx_stxx_stat_bytes_hi { -+ uint64_t u64; -+ struct cvmx_stxx_stat_bytes_hi_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_stxx_stat_bytes_hi_s cn38xx; -+ struct cvmx_stxx_stat_bytes_hi_s cn38xxp2; -+ struct cvmx_stxx_stat_bytes_hi_s cn58xx; -+ struct cvmx_stxx_stat_bytes_hi_s cn58xxp1; -+}; -+ -+union cvmx_stxx_stat_bytes_lo { -+ uint64_t u64; -+ struct cvmx_stxx_stat_bytes_lo_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_stxx_stat_bytes_lo_s cn38xx; -+ struct cvmx_stxx_stat_bytes_lo_s cn38xxp2; -+ struct cvmx_stxx_stat_bytes_lo_s cn58xx; -+ struct cvmx_stxx_stat_bytes_lo_s cn58xxp1; -+}; -+ -+union cvmx_stxx_stat_ctl { -+ uint64_t u64; -+ struct cvmx_stxx_stat_ctl_s { -+ uint64_t reserved_5_63:59; -+ uint64_t clr:1; -+ uint64_t bckprs:4; -+ } s; -+ struct cvmx_stxx_stat_ctl_s cn38xx; -+ struct cvmx_stxx_stat_ctl_s cn38xxp2; -+ struct cvmx_stxx_stat_ctl_s cn58xx; -+ struct cvmx_stxx_stat_ctl_s cn58xxp1; -+}; -+ -+union cvmx_stxx_stat_pkt_xmt { -+ uint64_t u64; -+ struct cvmx_stxx_stat_pkt_xmt_s { -+ uint64_t reserved_32_63:32; -+ uint64_t cnt:32; -+ } s; -+ struct cvmx_stxx_stat_pkt_xmt_s cn38xx; -+ struct cvmx_stxx_stat_pkt_xmt_s cn38xxp2; -+ struct cvmx_stxx_stat_pkt_xmt_s cn58xx; -+ struct cvmx_stxx_stat_pkt_xmt_s cn58xxp1; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/staging/octeon/cvmx-wqe.h -@@ -0,0 +1,397 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+/** -+ * -+ * This header file defines the work queue entry (wqe) data structure. -+ * Since this is a commonly used structure that depends on structures -+ * from several hardware blocks, those definitions have been placed -+ * in this file to create a single point of definition of the wqe -+ * format. -+ * Data structures are still named according to the block that they -+ * relate to. -+ * -+ */ -+ -+#ifndef __CVMX_WQE_H__ -+#define __CVMX_WQE_H__ -+ -+#include "cvmx-packet.h" -+ -+ -+#define OCT_TAG_TYPE_STRING(x) \ -+ (((x) == CVMX_POW_TAG_TYPE_ORDERED) ? "ORDERED" : \ -+ (((x) == CVMX_POW_TAG_TYPE_ATOMIC) ? "ATOMIC" : \ -+ (((x) == CVMX_POW_TAG_TYPE_NULL) ? "NULL" : \ -+ "NULL_NULL"))) -+ -+/** -+ * HW decode / err_code in work queue entry -+ */ -+typedef union { -+ uint64_t u64; -+ -+ /* Use this struct if the hardware determines that the packet is IP */ -+ struct { -+ /* HW sets this to the number of buffers used by this packet */ -+ uint64_t bufs:8; -+ /* HW sets to the number of L2 bytes prior to the IP */ -+ uint64_t ip_offset:8; -+ /* set to 1 if we found DSA/VLAN in the L2 */ -+ uint64_t vlan_valid:1; -+ /* Set to 1 if the DSA/VLAN tag is stacked */ -+ uint64_t vlan_stacked:1; -+ uint64_t unassigned:1; -+ /* HW sets to the DSA/VLAN CFI flag (valid when vlan_valid) */ -+ uint64_t vlan_cfi:1; -+ /* HW sets to the DSA/VLAN_ID field (valid when vlan_valid) */ -+ uint64_t vlan_id:12; -+ /* Ring Identifier (if PCIe). Requires PIP_GBL_CTL[RING_EN]=1 */ -+ uint64_t pr:4; -+ uint64_t unassigned2:8; -+ /* the packet needs to be decompressed */ -+ uint64_t dec_ipcomp:1; -+ /* the packet is either TCP or UDP */ -+ uint64_t tcp_or_udp:1; -+ /* the packet needs to be decrypted (ESP or AH) */ -+ uint64_t dec_ipsec:1; -+ /* the packet is IPv6 */ -+ uint64_t is_v6:1; -+ -+ /* -+ * (rcv_error, not_IP, IP_exc, is_frag, L4_error, -+ * software, etc.). -+ */ -+ -+ /* -+ * reserved for software use, hardware will clear on -+ * packet creation. -+ */ -+ uint64_t software:1; -+ /* exceptional conditions below */ -+ /* the receive interface hardware detected an L4 error -+ * (only applies if !is_frag) (only applies if -+ * !rcv_error && !not_IP && !IP_exc && !is_frag) -+ * failure indicated in err_code below, decode: -+ * -+ * - 1 = Malformed L4 -+ * - 2 = L4 Checksum Error: the L4 checksum value is -+ * - 3 = UDP Length Error: The UDP length field would -+ * make the UDP data longer than what remains in -+ * the IP packet (as defined by the IP header -+ * length field). -+ * - 4 = Bad L4 Port: either the source or destination -+ * TCP/UDP port is 0. -+ * - 8 = TCP FIN Only: the packet is TCP and only the -+ * FIN flag set. -+ * - 9 = TCP No Flags: the packet is TCP and no flags -+ * are set. -+ * - 10 = TCP FIN RST: the packet is TCP and both FIN -+ * and RST are set. -+ * - 11 = TCP SYN URG: the packet is TCP and both SYN -+ * and URG are set. -+ * - 12 = TCP SYN RST: the packet is TCP and both SYN -+ * and RST are set. -+ * - 13 = TCP SYN FIN: the packet is TCP and both SYN -+ * and FIN are set. -+ */ -+ uint64_t L4_error:1; -+ /* set if the packet is a fragment */ -+ uint64_t is_frag:1; -+ /* the receive interface hardware detected an IP error -+ * / exception (only applies if !rcv_error && !not_IP) -+ * failure indicated in err_code below, decode: -+ * -+ * - 1 = Not IP: the IP version field is neither 4 nor -+ * 6. -+ * - 2 = IPv4 Header Checksum Error: the IPv4 header -+ * has a checksum violation. -+ * - 3 = IP Malformed Header: the packet is not long -+ * enough to contain the IP header. -+ * - 4 = IP Malformed: the packet is not long enough -+ * to contain the bytes indicated by the IP -+ * header. Pad is allowed. -+ * - 5 = IP TTL Hop: the IPv4 TTL field or the IPv6 -+ * Hop Count field are zero. -+ * - 6 = IP Options -+ */ -+ uint64_t IP_exc:1; -+ /* -+ * Set if the hardware determined that the packet is a -+ * broadcast. -+ */ -+ uint64_t is_bcast:1; -+ /* -+ * St if the hardware determined that the packet is a -+ * multi-cast. -+ */ -+ uint64_t is_mcast:1; -+ /* -+ * Set if the packet may not be IP (must be zero in -+ * this case). -+ */ -+ uint64_t not_IP:1; -+ /* -+ * The receive interface hardware detected a receive -+ * error (must be zero in this case). -+ */ -+ uint64_t rcv_error:1; -+ /* lower err_code = first-level descriptor of the -+ * work */ -+ /* zero for packet submitted by hardware that isn't on -+ * the slow path */ -+ /* type is cvmx_pip_err_t */ -+ uint64_t err_code:8; -+ } s; -+ -+ /* use this to get at the 16 vlan bits */ -+ struct { -+ uint64_t unused1:16; -+ uint64_t vlan:16; -+ uint64_t unused2:32; -+ } svlan; -+ -+ /* -+ * use this struct if the hardware could not determine that -+ * the packet is ip. -+ */ -+ struct { -+ /* -+ * HW sets this to the number of buffers used by this -+ * packet. -+ */ -+ uint64_t bufs:8; -+ uint64_t unused:8; -+ /* set to 1 if we found DSA/VLAN in the L2 */ -+ uint64_t vlan_valid:1; -+ /* Set to 1 if the DSA/VLAN tag is stacked */ -+ uint64_t vlan_stacked:1; -+ uint64_t unassigned:1; -+ /* -+ * HW sets to the DSA/VLAN CFI flag (valid when -+ * vlan_valid) -+ */ -+ uint64_t vlan_cfi:1; -+ /* -+ * HW sets to the DSA/VLAN_ID field (valid when -+ * vlan_valid). -+ */ -+ uint64_t vlan_id:12; -+ /* -+ * Ring Identifier (if PCIe). Requires -+ * PIP_GBL_CTL[RING_EN]=1 -+ */ -+ uint64_t pr:4; -+ uint64_t unassigned2:12; -+ /* -+ * reserved for software use, hardware will clear on -+ * packet creation. -+ */ -+ uint64_t software:1; -+ uint64_t unassigned3:1; -+ /* -+ * set if the hardware determined that the packet is -+ * rarp. -+ */ -+ uint64_t is_rarp:1; -+ /* -+ * set if the hardware determined that the packet is -+ * arp -+ */ -+ uint64_t is_arp:1; -+ /* -+ * set if the hardware determined that the packet is a -+ * broadcast. -+ */ -+ uint64_t is_bcast:1; -+ /* -+ * set if the hardware determined that the packet is a -+ * multi-cast -+ */ -+ uint64_t is_mcast:1; -+ /* -+ * set if the packet may not be IP (must be one in -+ * this case) -+ */ -+ uint64_t not_IP:1; -+ /* The receive interface hardware detected a receive -+ * error. Failure indicated in err_code below, -+ * decode: -+ * -+ * - 1 = partial error: a packet was partially -+ * received, but internal buffering / bandwidth -+ * was not adequate to receive the entire -+ * packet. -+ * - 2 = jabber error: the RGMII packet was too large -+ * and is truncated. -+ * - 3 = overrun error: the RGMII packet is longer -+ * than allowed and had an FCS error. -+ * - 4 = oversize error: the RGMII packet is longer -+ * than allowed. -+ * - 5 = alignment error: the RGMII packet is not an -+ * integer number of bytes -+ * and had an FCS error (100M and 10M only). -+ * - 6 = fragment error: the RGMII packet is shorter -+ * than allowed and had an FCS error. -+ * - 7 = GMX FCS error: the RGMII packet had an FCS -+ * error. -+ * - 8 = undersize error: the RGMII packet is shorter -+ * than allowed. -+ * - 9 = extend error: the RGMII packet had an extend -+ * error. -+ * - 10 = length mismatch error: the RGMII packet had -+ * a length that did not match the length field -+ * in the L2 HDR. -+ * - 11 = RGMII RX error/SPI4 DIP4 Error: the RGMII -+ * packet had one or more data reception errors -+ * (RXERR) or the SPI4 packet had one or more -+ * DIP4 errors. -+ * - 12 = RGMII skip error/SPI4 Abort Error: the RGMII -+ * packet was not large enough to cover the -+ * skipped bytes or the SPI4 packet was -+ * terminated with an About EOPS. -+ * - 13 = RGMII nibble error/SPI4 Port NXA Error: the -+ * RGMII packet had a studder error (data not -+ * repeated - 10/100M only) or the SPI4 packet -+ * was sent to an NXA. -+ * - 16 = FCS error: a SPI4.2 packet had an FCS error. -+ * - 17 = Skip error: a packet was not large enough to -+ * cover the skipped bytes. -+ * - 18 = L2 header malformed: the packet is not long -+ * enough to contain the L2. -+ */ -+ -+ uint64_t rcv_error:1; -+ /* -+ * lower err_code = first-level descriptor of the -+ * work -+ */ -+ /* -+ * zero for packet submitted by hardware that isn't on -+ * the slow path -+ */ -+ /* type is cvmx_pip_err_t (union, so can't use directly */ -+ uint64_t err_code:8; -+ } snoip; -+ -+} cvmx_pip_wqe_word2; -+ -+/** -+ * Work queue entry format -+ * -+ * must be 8-byte aligned -+ */ -+typedef struct { -+ -+ /***************************************************************** -+ * WORD 0 -+ * HW WRITE: the following 64 bits are filled by HW when a packet arrives -+ */ -+ -+ /** -+ * raw chksum result generated by the HW -+ */ -+ uint16_t hw_chksum; -+ /** -+ * Field unused by hardware - available for software -+ */ -+ uint8_t unused; -+ /** -+ * Next pointer used by hardware for list maintenance. -+ * May be written/read by HW before the work queue -+ * entry is scheduled to a PP -+ * (Only 36 bits used in Octeon 1) -+ */ -+ uint64_t next_ptr:40; -+ -+ /***************************************************************** -+ * WORD 1 -+ * HW WRITE: the following 64 bits are filled by HW when a packet arrives -+ */ -+ -+ /** -+ * HW sets to the total number of bytes in the packet -+ */ -+ uint64_t len:16; -+ /** -+ * HW sets this to input physical port -+ */ -+ uint64_t ipprt:6; -+ -+ /** -+ * HW sets this to what it thought the priority of the input packet was -+ */ -+ uint64_t qos:3; -+ -+ /** -+ * the group that the work queue entry will be scheduled to -+ */ -+ uint64_t grp:4; -+ /** -+ * the type of the tag (ORDERED, ATOMIC, NULL) -+ */ -+ uint64_t tag_type:3; -+ /** -+ * the synchronization/ordering tag -+ */ -+ uint64_t tag:32; -+ -+ /** -+ * WORD 2 HW WRITE: the following 64-bits are filled in by -+ * hardware when a packet arrives This indicates a variety of -+ * status and error conditions. -+ */ -+ cvmx_pip_wqe_word2 word2; -+ -+ /** -+ * Pointer to the first segment of the packet. -+ */ -+ union cvmx_buf_ptr packet_ptr; -+ -+ /** -+ * HW WRITE: octeon will fill in a programmable amount from the -+ * packet, up to (at most, but perhaps less) the amount -+ * needed to fill the work queue entry to 128 bytes -+ * -+ * If the packet is recognized to be IP, the hardware starts -+ * (except that the IPv4 header is padded for appropriate -+ * alignment) writing here where the IP header starts. If the -+ * packet is not recognized to be IP, the hardware starts -+ * writing the beginning of the packet here. -+ */ -+ uint8_t packet_data[96]; -+ -+ /** -+ * If desired, SW can make the work Q entry any length. For the -+ * purposes of discussion here, Assume 128B always, as this is all that -+ * the hardware deals with. -+ * -+ */ -+ -+} CVMX_CACHE_LINE_ALIGNED cvmx_wqe_t; -+ -+#endif /* __CVMX_WQE_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-common.c -@@ -0,0 +1,328 @@ -+/********************************************************************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+**********************************************************************/ -+#include <linux/kernel.h> -+#include <linux/mii.h> -+#include <net/dst.h> -+ -+#include <asm/atomic.h> -+#include <asm/octeon/octeon.h> -+ -+#include "ethernet-defines.h" -+#include "ethernet-tx.h" -+#include "ethernet-mdio.h" -+#include "ethernet-util.h" -+#include "octeon-ethernet.h" -+#include "ethernet-common.h" -+ -+#include "cvmx-pip.h" -+#include "cvmx-pko.h" -+#include "cvmx-fau.h" -+#include "cvmx-helper.h" -+ -+#include "cvmx-gmxx-defs.h" -+ -+/** -+ * Get the low level ethernet statistics -+ * -+ * @dev: Device to get the statistics from -+ * Returns Pointer to the statistics -+ */ -+static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev) -+{ -+ cvmx_pip_port_status_t rx_status; -+ cvmx_pko_port_status_t tx_status; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ -+ if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) { -+ if (octeon_is_simulation()) { -+ /* The simulator doesn't support statistics */ -+ memset(&rx_status, 0, sizeof(rx_status)); -+ memset(&tx_status, 0, sizeof(tx_status)); -+ } else { -+ cvmx_pip_get_port_status(priv->port, 1, &rx_status); -+ cvmx_pko_get_port_status(priv->port, 1, &tx_status); -+ } -+ -+ priv->stats.rx_packets += rx_status.inb_packets; -+ priv->stats.tx_packets += tx_status.packets; -+ priv->stats.rx_bytes += rx_status.inb_octets; -+ priv->stats.tx_bytes += tx_status.octets; -+ priv->stats.multicast += rx_status.multicast_packets; -+ priv->stats.rx_crc_errors += rx_status.inb_errors; -+ priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets; -+ -+ /* -+ * The drop counter must be incremented atomically -+ * since the RX tasklet also increments it. -+ */ -+#ifdef CONFIG_64BIT -+ atomic64_add(rx_status.dropped_packets, -+ (atomic64_t *)&priv->stats.rx_dropped); -+#else -+ atomic_add(rx_status.dropped_packets, -+ (atomic_t *)&priv->stats.rx_dropped); -+#endif -+ } -+ -+ return &priv->stats; -+} -+ -+/** -+ * Set the multicast list. Currently unimplemented. -+ * -+ * @dev: Device to work on -+ */ -+static void cvm_oct_common_set_multicast_list(struct net_device *dev) -+{ -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ -+ if ((interface < 2) -+ && (cvmx_helper_interface_get_mode(interface) != -+ CVMX_HELPER_INTERFACE_MODE_SPI)) { -+ union cvmx_gmxx_rxx_adr_ctl control; -+ control.u64 = 0; -+ control.s.bcst = 1; /* Allow broadcast MAC addresses */ -+ -+ if (dev->mc_list || (dev->flags & IFF_ALLMULTI) || -+ (dev->flags & IFF_PROMISC)) -+ /* Force accept multicast packets */ -+ control.s.mcst = 2; -+ else -+ /* Force reject multicat packets */ -+ control.s.mcst = 1; -+ -+ if (dev->flags & IFF_PROMISC) -+ /* -+ * Reject matches if promisc. Since CAM is -+ * shut off, should accept everything. -+ */ -+ control.s.cam_mode = 0; -+ else -+ /* Filter packets based on the CAM */ -+ control.s.cam_mode = 1; -+ -+ gmx_cfg.u64 = -+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), -+ gmx_cfg.u64 & ~1ull); -+ -+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface), -+ control.u64); -+ if (dev->flags & IFF_PROMISC) -+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN -+ (index, interface), 0); -+ else -+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN -+ (index, interface), 1); -+ -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), -+ gmx_cfg.u64); -+ } -+} -+ -+/** -+ * Set the hardware MAC address for a device -+ * -+ * @dev: Device to change the MAC address for -+ * @addr: Address structure to change it too. MAC address is addr + 2. -+ * Returns Zero on success -+ */ -+static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ -+ memcpy(dev->dev_addr, addr + 2, 6); -+ -+ if ((interface < 2) -+ && (cvmx_helper_interface_get_mode(interface) != -+ CVMX_HELPER_INTERFACE_MODE_SPI)) { -+ int i; -+ uint8_t *ptr = addr; -+ uint64_t mac = 0; -+ for (i = 0; i < 6; i++) -+ mac = (mac << 8) | (uint64_t) (ptr[i + 2]); -+ -+ gmx_cfg.u64 = -+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), -+ gmx_cfg.u64 & ~1ull); -+ -+ cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac); -+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface), -+ ptr[2]); -+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface), -+ ptr[3]); -+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface), -+ ptr[4]); -+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface), -+ ptr[5]); -+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface), -+ ptr[6]); -+ cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface), -+ ptr[7]); -+ cvm_oct_common_set_multicast_list(dev); -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), -+ gmx_cfg.u64); -+ } -+ return 0; -+} -+ -+/** -+ * Change the link MTU. Unimplemented -+ * -+ * @dev: Device to change -+ * @new_mtu: The new MTU -+ * -+ * Returns Zero on success -+ */ -+static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -+ int vlan_bytes = 4; -+#else -+ int vlan_bytes = 0; -+#endif -+ -+ /* -+ * Limit the MTU to make sure the ethernet packets are between -+ * 64 bytes and 65535 bytes. -+ */ -+ if ((new_mtu + 14 + 4 + vlan_bytes < 64) -+ || (new_mtu + 14 + 4 + vlan_bytes > 65392)) { -+ pr_err("MTU must be between %d and %d.\n", -+ 64 - 14 - 4 - vlan_bytes, 65392 - 14 - 4 - vlan_bytes); -+ return -EINVAL; -+ } -+ dev->mtu = new_mtu; -+ -+ if ((interface < 2) -+ && (cvmx_helper_interface_get_mode(interface) != -+ CVMX_HELPER_INTERFACE_MODE_SPI)) { -+ /* Add ethernet header and FCS, and VLAN if configured. */ -+ int max_packet = new_mtu + 14 + 4 + vlan_bytes; -+ -+ if (OCTEON_IS_MODEL(OCTEON_CN3XXX) -+ || OCTEON_IS_MODEL(OCTEON_CN58XX)) { -+ /* Signal errors on packets larger than the MTU */ -+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface), -+ max_packet); -+ } else { -+ /* -+ * Set the hardware to truncate packets larger -+ * than the MTU and smaller the 64 bytes. -+ */ -+ union cvmx_pip_frm_len_chkx frm_len_chk; -+ frm_len_chk.u64 = 0; -+ frm_len_chk.s.minlen = 64; -+ frm_len_chk.s.maxlen = max_packet; -+ cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface), -+ frm_len_chk.u64); -+ } -+ /* -+ * Set the hardware to truncate packets larger than -+ * the MTU. The jabber register must be set to a -+ * multiple of 8 bytes, so round up. -+ */ -+ cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface), -+ (max_packet + 7) & ~7u); -+ } -+ return 0; -+} -+ -+/** -+ * Per network device initialization -+ * -+ * @dev: Device to initialize -+ * Returns Zero on success -+ */ -+int cvm_oct_common_init(struct net_device *dev) -+{ -+ static int count; -+ char mac[8] = { 0x00, 0x00, -+ octeon_bootinfo->mac_addr_base[0], -+ octeon_bootinfo->mac_addr_base[1], -+ octeon_bootinfo->mac_addr_base[2], -+ octeon_bootinfo->mac_addr_base[3], -+ octeon_bootinfo->mac_addr_base[4], -+ octeon_bootinfo->mac_addr_base[5] + count -+ }; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ -+ /* -+ * Force the interface to use the POW send if always_use_pow -+ * was specified or it is in the pow send list. -+ */ -+ if ((pow_send_group != -1) -+ && (always_use_pow || strstr(pow_send_list, dev->name))) -+ priv->queue = -1; -+ -+ if (priv->queue != -1) { -+ dev->hard_start_xmit = cvm_oct_xmit; -+ if (USE_HW_TCPUDP_CHECKSUM) -+ dev->features |= NETIF_F_IP_CSUM; -+ } else -+ dev->hard_start_xmit = cvm_oct_xmit_pow; -+ count++; -+ -+ dev->get_stats = cvm_oct_common_get_stats; -+ dev->set_mac_address = cvm_oct_common_set_mac_address; -+ dev->set_multicast_list = cvm_oct_common_set_multicast_list; -+ dev->change_mtu = cvm_oct_common_change_mtu; -+ dev->do_ioctl = cvm_oct_ioctl; -+ /* We do our own locking, Linux doesn't need to */ -+ dev->features |= NETIF_F_LLTX; -+ SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ dev->poll_controller = cvm_oct_poll_controller; -+#endif -+ -+ cvm_oct_mdio_setup_device(dev); -+ dev->set_mac_address(dev, mac); -+ dev->change_mtu(dev, dev->mtu); -+ -+ /* -+ * Zero out stats for port so we won't mistakenly show -+ * counters from the bootloader. -+ */ -+ memset(dev->get_stats(dev), 0, sizeof(struct net_device_stats)); -+ -+ return 0; -+} -+ -+void cvm_oct_common_uninit(struct net_device *dev) -+{ -+ /* Currently nothing to do */ -+} ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-common.h -@@ -0,0 +1,29 @@ -+/********************************************************************* -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+*********************************************************************/ -+ -+int cvm_oct_common_init(struct net_device *dev); -+void cvm_oct_common_uninit(struct net_device *dev); ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-defines.h -@@ -0,0 +1,134 @@ -+/********************************************************************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+**********************************************************************/ -+ -+/* -+ * A few defines are used to control the operation of this driver: -+ * CONFIG_CAVIUM_RESERVE32 -+ * This kernel config options controls the amount of memory configured -+ * in a wired TLB entry for all processes to share. If this is set, the -+ * driver will use this memory instead of kernel memory for pools. This -+ * allows 32bit userspace application to access the buffers, but also -+ * requires all received packets to be copied. -+ * CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS -+ * This kernel config option allows the user to control the number of -+ * packet and work queue buffers allocated by the driver. If this is zero, -+ * the driver uses the default from below. -+ * USE_SKBUFFS_IN_HW -+ * Tells the driver to populate the packet buffers with kernel skbuffs. -+ * This allows the driver to receive packets without copying them. It also -+ * means that 32bit userspace can't access the packet buffers. -+ * USE_32BIT_SHARED -+ * This define tells the driver to allocate memory for buffers from the -+ * 32bit sahred region instead of the kernel memory space. -+ * USE_HW_TCPUDP_CHECKSUM -+ * Controls if the Octeon TCP/UDP checksum engine is used for packet -+ * output. If this is zero, the kernel will perform the checksum in -+ * software. -+ * USE_MULTICORE_RECEIVE -+ * Process receive interrupts on multiple cores. This spreads the network -+ * load across the first 8 processors. If ths is zero, only one core -+ * processes incomming packets. -+ * USE_ASYNC_IOBDMA -+ * Use asynchronous IO access to hardware. This uses Octeon's asynchronous -+ * IOBDMAs to issue IO accesses without stalling. Set this to zero -+ * to disable this. Note that IOBDMAs require CVMSEG. -+ * REUSE_SKBUFFS_WITHOUT_FREE -+ * Allows the TX path to free an skbuff into the FPA hardware pool. This -+ * can significantly improve performance for forwarding and bridging, but -+ * may be somewhat dangerous. Checks are made, but if any buffer is reused -+ * without the proper Linux cleanup, the networking stack may have very -+ * bizarre bugs. -+ */ -+#ifndef __ETHERNET_DEFINES_H__ -+#define __ETHERNET_DEFINES_H__ -+ -+#include "cvmx-config.h" -+ -+ -+#define OCTEON_ETHERNET_VERSION "1.9" -+ -+#ifndef CONFIG_CAVIUM_RESERVE32 -+#define CONFIG_CAVIUM_RESERVE32 0 -+#endif -+ -+#if CONFIG_CAVIUM_RESERVE32 -+#define USE_32BIT_SHARED 1 -+#define USE_SKBUFFS_IN_HW 0 -+#define REUSE_SKBUFFS_WITHOUT_FREE 0 -+#else -+#define USE_32BIT_SHARED 0 -+#define USE_SKBUFFS_IN_HW 1 -+#ifdef CONFIG_NETFILTER -+#define REUSE_SKBUFFS_WITHOUT_FREE 0 -+#else -+#define REUSE_SKBUFFS_WITHOUT_FREE 1 -+#endif -+#endif -+ -+/* Max interrupts per second per core */ -+#define INTERRUPT_LIMIT 10000 -+ -+/* Don't limit the number of interrupts */ -+/*#define INTERRUPT_LIMIT 0 */ -+#define USE_HW_TCPUDP_CHECKSUM 1 -+ -+#define USE_MULTICORE_RECEIVE 1 -+ -+/* Enable Random Early Dropping under load */ -+#define USE_RED 1 -+#define USE_ASYNC_IOBDMA (CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0) -+ -+/* -+ * Allow SW based preamble removal at 10Mbps to workaround PHYs giving -+ * us bad preambles. -+ */ -+#define USE_10MBPS_PREAMBLE_WORKAROUND 1 -+/* -+ * Use this to have all FPA frees also tell the L2 not to write data -+ * to memory. -+ */ -+#define DONT_WRITEBACK(x) (x) -+/* Use this to not have FPA frees control L2 */ -+/*#define DONT_WRITEBACK(x) 0 */ -+ -+/* Maximum number of packets to process per interrupt. */ -+#define MAX_RX_PACKETS 120 -+#define MAX_OUT_QUEUE_DEPTH 1000 -+ -+#ifndef CONFIG_SMP -+#undef USE_MULTICORE_RECEIVE -+#define USE_MULTICORE_RECEIVE 0 -+#endif -+ -+#define IP_PROTOCOL_TCP 6 -+#define IP_PROTOCOL_UDP 0x11 -+ -+#define FAU_NUM_PACKET_BUFFERS_TO_FREE (CVMX_FAU_REG_END - sizeof(uint32_t)) -+#define TOTAL_NUMBER_OF_PORTS (CVMX_PIP_NUM_INPUT_PORTS+1) -+ -+ -+#endif /* __ETHERNET_DEFINES_H__ */ ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-mdio.c -@@ -0,0 +1,231 @@ -+/********************************************************************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+**********************************************************************/ -+#include <linux/kernel.h> -+#include <linux/ethtool.h> -+#include <linux/mii.h> -+#include <net/dst.h> -+ -+#include <asm/octeon/octeon.h> -+ -+#include "ethernet-defines.h" -+#include "octeon-ethernet.h" -+#include "ethernet-mdio.h" -+ -+#include "cvmx-helper-board.h" -+ -+#include "cvmx-smix-defs.h" -+ -+DECLARE_MUTEX(mdio_sem); -+ -+/** -+ * Perform an MII read. Called by the generic MII routines -+ * -+ * @dev: Device to perform read for -+ * @phy_id: The MII phy id -+ * @location: Register location to read -+ * Returns Result from the read or zero on failure -+ */ -+static int cvm_oct_mdio_read(struct net_device *dev, int phy_id, int location) -+{ -+ union cvmx_smix_cmd smi_cmd; -+ union cvmx_smix_rd_dat smi_rd; -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = 1; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = location; -+ cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64); -+ -+ do { -+ if (!in_interrupt()) -+ yield(); -+ smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(0)); -+ } while (smi_rd.s.pending); -+ -+ if (smi_rd.s.val) -+ return smi_rd.s.dat; -+ else -+ return 0; -+} -+ -+static int cvm_oct_mdio_dummy_read(struct net_device *dev, int phy_id, -+ int location) -+{ -+ return 0xffff; -+} -+ -+/** -+ * Perform an MII write. Called by the generic MII routines -+ * -+ * @dev: Device to perform write for -+ * @phy_id: The MII phy id -+ * @location: Register location to write -+ * @val: Value to write -+ */ -+static void cvm_oct_mdio_write(struct net_device *dev, int phy_id, int location, -+ int val) -+{ -+ union cvmx_smix_cmd smi_cmd; -+ union cvmx_smix_wr_dat smi_wr; -+ -+ smi_wr.u64 = 0; -+ smi_wr.s.dat = val; -+ cvmx_write_csr(CVMX_SMIX_WR_DAT(0), smi_wr.u64); -+ -+ smi_cmd.u64 = 0; -+ smi_cmd.s.phy_op = 0; -+ smi_cmd.s.phy_adr = phy_id; -+ smi_cmd.s.reg_adr = location; -+ cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64); -+ -+ do { -+ if (!in_interrupt()) -+ yield(); -+ smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(0)); -+ } while (smi_wr.s.pending); -+} -+ -+static void cvm_oct_mdio_dummy_write(struct net_device *dev, int phy_id, -+ int location, int val) -+{ -+} -+ -+static void cvm_oct_get_drvinfo(struct net_device *dev, -+ struct ethtool_drvinfo *info) -+{ -+ strcpy(info->driver, "cavium-ethernet"); -+ strcpy(info->version, OCTEON_ETHERNET_VERSION); -+ strcpy(info->bus_info, "Builtin"); -+} -+ -+static int cvm_oct_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int ret; -+ -+ down(&mdio_sem); -+ ret = mii_ethtool_gset(&priv->mii_info, cmd); -+ up(&mdio_sem); -+ -+ return ret; -+} -+ -+static int cvm_oct_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int ret; -+ -+ down(&mdio_sem); -+ ret = mii_ethtool_sset(&priv->mii_info, cmd); -+ up(&mdio_sem); -+ -+ return ret; -+} -+ -+static int cvm_oct_nway_reset(struct net_device *dev) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int ret; -+ -+ down(&mdio_sem); -+ ret = mii_nway_restart(&priv->mii_info); -+ up(&mdio_sem); -+ -+ return ret; -+} -+ -+static u32 cvm_oct_get_link(struct net_device *dev) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ u32 ret; -+ -+ down(&mdio_sem); -+ ret = mii_link_ok(&priv->mii_info); -+ up(&mdio_sem); -+ -+ return ret; -+} -+ -+struct ethtool_ops cvm_oct_ethtool_ops = { -+ .get_drvinfo = cvm_oct_get_drvinfo, -+ .get_settings = cvm_oct_get_settings, -+ .set_settings = cvm_oct_set_settings, -+ .nway_reset = cvm_oct_nway_reset, -+ .get_link = cvm_oct_get_link, -+ .get_sg = ethtool_op_get_sg, -+ .get_tx_csum = ethtool_op_get_tx_csum, -+}; -+ -+/** -+ * IOCTL support for PHY control -+ * -+ * @dev: Device to change -+ * @rq: the request -+ * @cmd: the command -+ * Returns Zero on success -+ */ -+int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ struct mii_ioctl_data *data = if_mii(rq); -+ unsigned int duplex_chg; -+ int ret; -+ -+ down(&mdio_sem); -+ ret = generic_mii_ioctl(&priv->mii_info, data, cmd, &duplex_chg); -+ up(&mdio_sem); -+ -+ return ret; -+} -+ -+/** -+ * Setup the MDIO device structures -+ * -+ * @dev: Device to setup -+ * -+ * Returns Zero on success, negative on failure -+ */ -+int cvm_oct_mdio_setup_device(struct net_device *dev) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int phy_id = cvmx_helper_board_get_mii_address(priv->port); -+ if (phy_id != -1) { -+ priv->mii_info.dev = dev; -+ priv->mii_info.phy_id = phy_id; -+ priv->mii_info.phy_id_mask = 0xff; -+ priv->mii_info.supports_gmii = 1; -+ priv->mii_info.reg_num_mask = 0x1f; -+ priv->mii_info.mdio_read = cvm_oct_mdio_read; -+ priv->mii_info.mdio_write = cvm_oct_mdio_write; -+ } else { -+ /* Supply dummy MDIO routines so the kernel won't crash -+ if the user tries to read them */ -+ priv->mii_info.mdio_read = cvm_oct_mdio_dummy_read; -+ priv->mii_info.mdio_write = cvm_oct_mdio_dummy_write; -+ } -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-mdio.h -@@ -0,0 +1,46 @@ -+/********************************************************************* -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+*********************************************************************/ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/netdevice.h> -+#include <linux/init.h> -+#include <linux/etherdevice.h> -+#include <linux/ip.h> -+#include <linux/string.h> -+#include <linux/ethtool.h> -+#include <linux/mii.h> -+#include <linux/seq_file.h> -+#include <linux/proc_fs.h> -+#include <net/dst.h> -+#ifdef CONFIG_XFRM -+#include <linux/xfrm.h> -+#include <net/xfrm.h> -+#endif /* CONFIG_XFRM */ -+ -+extern struct ethtool_ops cvm_oct_ethtool_ops; -+int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -+int cvm_oct_mdio_setup_device(struct net_device *dev); ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-mem.c -@@ -0,0 +1,198 @@ -+/********************************************************************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+**********************************************************************/ -+#include <linux/kernel.h> -+#include <linux/netdevice.h> -+#include <linux/mii.h> -+#include <net/dst.h> -+ -+#include <asm/octeon/octeon.h> -+ -+#include "ethernet-defines.h" -+ -+#include "cvmx-fpa.h" -+ -+/** -+ * Fill the supplied hardware pool with skbuffs -+ * -+ * @pool: Pool to allocate an skbuff for -+ * @size: Size of the buffer needed for the pool -+ * @elements: Number of buffers to allocate -+ */ -+static int cvm_oct_fill_hw_skbuff(int pool, int size, int elements) -+{ -+ int freed = elements; -+ while (freed) { -+ -+ struct sk_buff *skb = dev_alloc_skb(size + 128); -+ if (unlikely(skb == NULL)) { -+ pr_warning -+ ("Failed to allocate skb for hardware pool %d\n", -+ pool); -+ break; -+ } -+ -+ skb_reserve(skb, 128 - (((unsigned long)skb->data) & 0x7f)); -+ *(struct sk_buff **)(skb->data - sizeof(void *)) = skb; -+ cvmx_fpa_free(skb->data, pool, DONT_WRITEBACK(size / 128)); -+ freed--; -+ } -+ return elements - freed; -+} -+ -+/** -+ * Free the supplied hardware pool of skbuffs -+ * -+ * @pool: Pool to allocate an skbuff for -+ * @size: Size of the buffer needed for the pool -+ * @elements: Number of buffers to allocate -+ */ -+static void cvm_oct_free_hw_skbuff(int pool, int size, int elements) -+{ -+ char *memory; -+ -+ do { -+ memory = cvmx_fpa_alloc(pool); -+ if (memory) { -+ struct sk_buff *skb = -+ *(struct sk_buff **)(memory - sizeof(void *)); -+ elements--; -+ dev_kfree_skb(skb); -+ } -+ } while (memory); -+ -+ if (elements < 0) -+ pr_warning("Freeing of pool %u had too many skbuffs (%d)\n", -+ pool, elements); -+ else if (elements > 0) -+ pr_warning("Freeing of pool %u is missing %d skbuffs\n", -+ pool, elements); -+} -+ -+/** -+ * This function fills a hardware pool with memory. Depending -+ * on the config defines, this memory might come from the -+ * kernel or global 32bit memory allocated with -+ * cvmx_bootmem_alloc. -+ * -+ * @pool: Pool to populate -+ * @size: Size of each buffer in the pool -+ * @elements: Number of buffers to allocate -+ */ -+static int cvm_oct_fill_hw_memory(int pool, int size, int elements) -+{ -+ char *memory; -+ int freed = elements; -+ -+ if (USE_32BIT_SHARED) { -+ extern uint64_t octeon_reserve32_memory; -+ -+ memory = -+ cvmx_bootmem_alloc_range(elements * size, 128, -+ octeon_reserve32_memory, -+ octeon_reserve32_memory + -+ (CONFIG_CAVIUM_RESERVE32 << 20) - -+ 1); -+ if (memory == NULL) -+ panic("Unable to allocate %u bytes for FPA pool %d\n", -+ elements * size, pool); -+ -+ pr_notice("Memory range %p - %p reserved for " -+ "hardware\n", memory, -+ memory + elements * size - 1); -+ -+ while (freed) { -+ cvmx_fpa_free(memory, pool, 0); -+ memory += size; -+ freed--; -+ } -+ } else { -+ while (freed) { -+ /* We need to force alignment to 128 bytes here */ -+ memory = kmalloc(size + 127, GFP_ATOMIC); -+ if (unlikely(memory == NULL)) { -+ pr_warning("Unable to allocate %u bytes for " -+ "FPA pool %d\n", -+ elements * size, pool); -+ break; -+ } -+ memory = (char *)(((unsigned long)memory + 127) & -128); -+ cvmx_fpa_free(memory, pool, 0); -+ freed--; -+ } -+ } -+ return elements - freed; -+} -+ -+/** -+ * Free memory previously allocated with cvm_oct_fill_hw_memory -+ * -+ * @pool: FPA pool to free -+ * @size: Size of each buffer in the pool -+ * @elements: Number of buffers that should be in the pool -+ */ -+static void cvm_oct_free_hw_memory(int pool, int size, int elements) -+{ -+ if (USE_32BIT_SHARED) { -+ pr_warning("Warning: 32 shared memory is not freeable\n"); -+ } else { -+ char *memory; -+ do { -+ memory = cvmx_fpa_alloc(pool); -+ if (memory) { -+ elements--; -+ kfree(phys_to_virt(cvmx_ptr_to_phys(memory))); -+ } -+ } while (memory); -+ -+ if (elements < 0) -+ pr_warning("Freeing of pool %u had too many " -+ "buffers (%d)\n", -+ pool, elements); -+ else if (elements > 0) -+ pr_warning("Warning: Freeing of pool %u is " -+ "missing %d buffers\n", -+ pool, elements); -+ } -+} -+ -+int cvm_oct_mem_fill_fpa(int pool, int size, int elements) -+{ -+ int freed; -+ if (USE_SKBUFFS_IN_HW) -+ freed = cvm_oct_fill_hw_skbuff(pool, size, elements); -+ else -+ freed = cvm_oct_fill_hw_memory(pool, size, elements); -+ return freed; -+} -+ -+void cvm_oct_mem_empty_fpa(int pool, int size, int elements) -+{ -+ if (USE_SKBUFFS_IN_HW) -+ cvm_oct_free_hw_skbuff(pool, size, elements); -+ else -+ cvm_oct_free_hw_memory(pool, size, elements); -+} ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-mem.h -@@ -0,0 +1,29 @@ -+/********************************************************************* -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+********************************************************************/ -+ -+int cvm_oct_mem_fill_fpa(int pool, int size, int elements); -+void cvm_oct_mem_empty_fpa(int pool, int size, int elements); ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-proc.c -@@ -0,0 +1,256 @@ -+/********************************************************************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+**********************************************************************/ -+#include <linux/kernel.h> -+#include <linux/mii.h> -+#include <linux/seq_file.h> -+#include <linux/proc_fs.h> -+#include <net/dst.h> -+ -+#include <asm/octeon/octeon.h> -+ -+#include "octeon-ethernet.h" -+#include "ethernet-defines.h" -+ -+#include "cvmx-helper.h" -+#include "cvmx-pip.h" -+ -+static unsigned long long cvm_oct_stats_read_switch(struct net_device *dev, -+ int phy_id, int offset) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ -+ priv->mii_info.mdio_write(dev, phy_id, 0x1d, 0xcc00 | offset); -+ return ((uint64_t) priv->mii_info. -+ mdio_read(dev, phy_id, -+ 0x1e) << 16) | (uint64_t) priv->mii_info. -+ mdio_read(dev, phy_id, 0x1f); -+} -+ -+static int cvm_oct_stats_switch_show(struct seq_file *m, void *v) -+{ -+ static const int ports[] = { 0, 1, 2, 3, 9, -1 }; -+ struct net_device *dev = cvm_oct_device[0]; -+ int index = 0; -+ -+ while (ports[index] != -1) { -+ -+ /* Latch port */ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ -+ priv->mii_info.mdio_write(dev, 0x1b, 0x1d, -+ 0xdc00 | ports[index]); -+ seq_printf(m, "\nSwitch Port %d\n", ports[index]); -+ seq_printf(m, "InGoodOctets: %12llu\t" -+ "OutOctets: %12llu\t" -+ "64 Octets: %12llu\n", -+ cvm_oct_stats_read_switch(dev, 0x1b, -+ 0x00) | -+ (cvm_oct_stats_read_switch(dev, 0x1b, 0x01) << 32), -+ cvm_oct_stats_read_switch(dev, 0x1b, -+ 0x0E) | -+ (cvm_oct_stats_read_switch(dev, 0x1b, 0x0F) << 32), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x08)); -+ -+ seq_printf(m, "InBadOctets: %12llu\t" -+ "OutUnicast: %12llu\t" -+ "65-127 Octets: %12llu\n", -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x02), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x10), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x09)); -+ -+ seq_printf(m, "InUnicast: %12llu\t" -+ "OutBroadcasts: %12llu\t" -+ "128-255 Octets: %12llu\n", -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x04), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x13), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x0A)); -+ -+ seq_printf(m, "InBroadcasts: %12llu\t" -+ "OutMulticasts: %12llu\t" -+ "256-511 Octets: %12llu\n", -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x06), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x12), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x0B)); -+ -+ seq_printf(m, "InMulticasts: %12llu\t" -+ "OutPause: %12llu\t" -+ "512-1023 Octets:%12llu\n", -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x07), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x15), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x0C)); -+ -+ seq_printf(m, "InPause: %12llu\t" -+ "Excessive: %12llu\t" -+ "1024-Max Octets:%12llu\n", -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x16), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x11), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x0D)); -+ -+ seq_printf(m, "InUndersize: %12llu\t" -+ "Collisions: %12llu\n", -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x18), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x1E)); -+ -+ seq_printf(m, "InFragments: %12llu\t" -+ "Deferred: %12llu\n", -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x19), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x05)); -+ -+ seq_printf(m, "InOversize: %12llu\t" -+ "Single: %12llu\n", -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x1A), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x14)); -+ -+ seq_printf(m, "InJabber: %12llu\t" -+ "Multiple: %12llu\n", -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x1B), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x17)); -+ -+ seq_printf(m, "In RxErr: %12llu\t" -+ "OutFCSErr: %12llu\n", -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x1C), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x03)); -+ -+ seq_printf(m, "InFCSErr: %12llu\t" -+ "Late: %12llu\n", -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x1D), -+ cvm_oct_stats_read_switch(dev, 0x1b, 0x1F)); -+ index++; -+ } -+ return 0; -+} -+ -+/** -+ * User is reading /proc/octeon_ethernet_stats -+ * -+ * @m: -+ * @v: -+ * Returns -+ */ -+static int cvm_oct_stats_show(struct seq_file *m, void *v) -+{ -+ struct octeon_ethernet *priv; -+ int port; -+ -+ for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) { -+ -+ if (cvm_oct_device[port]) { -+ priv = netdev_priv(cvm_oct_device[port]); -+ -+ seq_printf(m, "\nOcteon Port %d (%s)\n", port, -+ cvm_oct_device[port]->name); -+ seq_printf(m, -+ "rx_packets: %12lu\t" -+ "tx_packets: %12lu\n", -+ priv->stats.rx_packets, -+ priv->stats.tx_packets); -+ seq_printf(m, -+ "rx_bytes: %12lu\t" -+ "tx_bytes: %12lu\n", -+ priv->stats.rx_bytes, priv->stats.tx_bytes); -+ seq_printf(m, -+ "rx_errors: %12lu\t" -+ "tx_errors: %12lu\n", -+ priv->stats.rx_errors, -+ priv->stats.tx_errors); -+ seq_printf(m, -+ "rx_dropped: %12lu\t" -+ "tx_dropped: %12lu\n", -+ priv->stats.rx_dropped, -+ priv->stats.tx_dropped); -+ seq_printf(m, -+ "rx_length_errors: %12lu\t" -+ "tx_aborted_errors: %12lu\n", -+ priv->stats.rx_length_errors, -+ priv->stats.tx_aborted_errors); -+ seq_printf(m, -+ "rx_over_errors: %12lu\t" -+ "tx_carrier_errors: %12lu\n", -+ priv->stats.rx_over_errors, -+ priv->stats.tx_carrier_errors); -+ seq_printf(m, -+ "rx_crc_errors: %12lu\t" -+ "tx_fifo_errors: %12lu\n", -+ priv->stats.rx_crc_errors, -+ priv->stats.tx_fifo_errors); -+ seq_printf(m, -+ "rx_frame_errors: %12lu\t" -+ "tx_heartbeat_errors: %12lu\n", -+ priv->stats.rx_frame_errors, -+ priv->stats.tx_heartbeat_errors); -+ seq_printf(m, -+ "rx_fifo_errors: %12lu\t" -+ "tx_window_errors: %12lu\n", -+ priv->stats.rx_fifo_errors, -+ priv->stats.tx_window_errors); -+ seq_printf(m, -+ "rx_missed_errors: %12lu\t" -+ "multicast: %12lu\n", -+ priv->stats.rx_missed_errors, -+ priv->stats.multicast); -+ } -+ } -+ -+ if (cvm_oct_device[0]) { -+ priv = netdev_priv(cvm_oct_device[0]); -+ if (priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII) -+ cvm_oct_stats_switch_show(m, v); -+ } -+ return 0; -+} -+ -+/** -+ * /proc/octeon_ethernet_stats was openned. Use the single_open iterator -+ * -+ * @inode: -+ * @file: -+ * Returns -+ */ -+static int cvm_oct_stats_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, cvm_oct_stats_show, NULL); -+} -+ -+static const struct file_operations cvm_oct_stats_operations = { -+ .open = cvm_oct_stats_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+void cvm_oct_proc_initialize(void) -+{ -+ struct proc_dir_entry *entry = -+ create_proc_entry("octeon_ethernet_stats", 0, NULL); -+ if (entry) -+ entry->proc_fops = &cvm_oct_stats_operations; -+} -+ -+void cvm_oct_proc_shutdown(void) -+{ -+ remove_proc_entry("octeon_ethernet_stats", NULL); -+} ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-proc.h -@@ -0,0 +1,29 @@ -+/********************************************************************* -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+*********************************************************************/ -+ -+void cvm_oct_proc_initialize(void); -+void cvm_oct_proc_shutdown(void); ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-rgmii.c -@@ -0,0 +1,397 @@ -+/********************************************************************* -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+**********************************************************************/ -+#include <linux/kernel.h> -+#include <linux/netdevice.h> -+#include <linux/mii.h> -+#include <net/dst.h> -+ -+#include <asm/octeon/octeon.h> -+ -+#include "ethernet-defines.h" -+#include "octeon-ethernet.h" -+#include "ethernet-common.h" -+#include "ethernet-util.h" -+ -+#include "cvmx-helper.h" -+ -+#include <asm/octeon/cvmx-ipd-defs.h> -+#include <asm/octeon/cvmx-npi-defs.h> -+#include "cvmx-gmxx-defs.h" -+ -+DEFINE_SPINLOCK(global_register_lock); -+ -+static int number_rgmii_ports; -+ -+static void cvm_oct_rgmii_poll(struct net_device *dev) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ unsigned long flags; -+ cvmx_helper_link_info_t link_info; -+ -+ /* -+ * Take the global register lock since we are going to touch -+ * registers that affect more than one port. -+ */ -+ spin_lock_irqsave(&global_register_lock, flags); -+ -+ link_info = cvmx_helper_link_get(priv->port); -+ if (link_info.u64 == priv->link_info) { -+ -+ /* -+ * If the 10Mbps preamble workaround is supported and we're -+ * at 10Mbps we may need to do some special checking. -+ */ -+ if (USE_10MBPS_PREAMBLE_WORKAROUND && (link_info.s.speed == 10)) { -+ -+ /* -+ * Read the GMXX_RXX_INT_REG[PCTERR] bit and -+ * see if we are getting preamble errors. -+ */ -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg; -+ gmxx_rxx_int_reg.u64 = -+ cvmx_read_csr(CVMX_GMXX_RXX_INT_REG -+ (index, interface)); -+ if (gmxx_rxx_int_reg.s.pcterr) { -+ -+ /* -+ * We are getting preamble errors at -+ * 10Mbps. Most likely the PHY is -+ * giving us packets with mis aligned -+ * preambles. In order to get these -+ * packets we need to disable preamble -+ * checking and do it in software. -+ */ -+ union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl; -+ union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs; -+ -+ /* Disable preamble checking */ -+ gmxx_rxx_frm_ctl.u64 = -+ cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL -+ (index, interface)); -+ gmxx_rxx_frm_ctl.s.pre_chk = 0; -+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL -+ (index, interface), -+ gmxx_rxx_frm_ctl.u64); -+ -+ /* Disable FCS stripping */ -+ ipd_sub_port_fcs.u64 = -+ cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS); -+ ipd_sub_port_fcs.s.port_bit &= -+ 0xffffffffull ^ (1ull << priv->port); -+ cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, -+ ipd_sub_port_fcs.u64); -+ -+ /* Clear any error bits */ -+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG -+ (index, interface), -+ gmxx_rxx_int_reg.u64); -+ DEBUGPRINT("%s: Using 10Mbps with software " -+ "preamble removal\n", -+ dev->name); -+ } -+ } -+ spin_unlock_irqrestore(&global_register_lock, flags); -+ return; -+ } -+ -+ /* If the 10Mbps preamble workaround is allowed we need to on -+ preamble checking, FCS stripping, and clear error bits on -+ every speed change. If errors occur during 10Mbps operation -+ the above code will change this stuff */ -+ if (USE_10MBPS_PREAMBLE_WORKAROUND) { -+ -+ union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl; -+ union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs; -+ union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg; -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ -+ /* Enable preamble checking */ -+ gmxx_rxx_frm_ctl.u64 = -+ cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface)); -+ gmxx_rxx_frm_ctl.s.pre_chk = 1; -+ cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface), -+ gmxx_rxx_frm_ctl.u64); -+ /* Enable FCS stripping */ -+ ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS); -+ ipd_sub_port_fcs.s.port_bit |= 1ull << priv->port; -+ cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64); -+ /* Clear any error bits */ -+ gmxx_rxx_int_reg.u64 = -+ cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, interface)); -+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface), -+ gmxx_rxx_int_reg.u64); -+ } -+ -+ link_info = cvmx_helper_link_autoconf(priv->port); -+ priv->link_info = link_info.u64; -+ spin_unlock_irqrestore(&global_register_lock, flags); -+ -+ /* Tell Linux */ -+ if (link_info.s.link_up) { -+ -+ if (!netif_carrier_ok(dev)) -+ netif_carrier_on(dev); -+ if (priv->queue != -1) -+ DEBUGPRINT -+ ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", -+ dev->name, link_info.s.speed, -+ (link_info.s.full_duplex) ? "Full" : "Half", -+ priv->port, priv->queue); -+ else -+ DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n", -+ dev->name, link_info.s.speed, -+ (link_info.s.full_duplex) ? "Full" : "Half", -+ priv->port); -+ } else { -+ -+ if (netif_carrier_ok(dev)) -+ netif_carrier_off(dev); -+ DEBUGPRINT("%s: Link down\n", dev->name); -+ } -+} -+ -+static irqreturn_t cvm_oct_rgmii_rml_interrupt(int cpl, void *dev_id) -+{ -+ union cvmx_npi_rsl_int_blocks rsl_int_blocks; -+ int index; -+ irqreturn_t return_status = IRQ_NONE; -+ -+ rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS); -+ -+ /* Check and see if this interrupt was caused by the GMX0 block */ -+ if (rsl_int_blocks.s.gmx0) { -+ -+ int interface = 0; -+ /* Loop through every port of this interface */ -+ for (index = 0; -+ index < cvmx_helper_ports_on_interface(interface); -+ index++) { -+ -+ /* Read the GMX interrupt status bits */ -+ union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg; -+ gmx_rx_int_reg.u64 = -+ cvmx_read_csr(CVMX_GMXX_RXX_INT_REG -+ (index, interface)); -+ gmx_rx_int_reg.u64 &= -+ cvmx_read_csr(CVMX_GMXX_RXX_INT_EN -+ (index, interface)); -+ /* Poll the port if inband status changed */ -+ if (gmx_rx_int_reg.s.phy_dupx -+ || gmx_rx_int_reg.s.phy_link -+ || gmx_rx_int_reg.s.phy_spd) { -+ -+ struct net_device *dev = -+ cvm_oct_device[cvmx_helper_get_ipd_port -+ (interface, index)]; -+ if (dev) -+ cvm_oct_rgmii_poll(dev); -+ gmx_rx_int_reg.u64 = 0; -+ gmx_rx_int_reg.s.phy_dupx = 1; -+ gmx_rx_int_reg.s.phy_link = 1; -+ gmx_rx_int_reg.s.phy_spd = 1; -+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG -+ (index, interface), -+ gmx_rx_int_reg.u64); -+ return_status = IRQ_HANDLED; -+ } -+ } -+ } -+ -+ /* Check and see if this interrupt was caused by the GMX1 block */ -+ if (rsl_int_blocks.s.gmx1) { -+ -+ int interface = 1; -+ /* Loop through every port of this interface */ -+ for (index = 0; -+ index < cvmx_helper_ports_on_interface(interface); -+ index++) { -+ -+ /* Read the GMX interrupt status bits */ -+ union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg; -+ gmx_rx_int_reg.u64 = -+ cvmx_read_csr(CVMX_GMXX_RXX_INT_REG -+ (index, interface)); -+ gmx_rx_int_reg.u64 &= -+ cvmx_read_csr(CVMX_GMXX_RXX_INT_EN -+ (index, interface)); -+ /* Poll the port if inband status changed */ -+ if (gmx_rx_int_reg.s.phy_dupx -+ || gmx_rx_int_reg.s.phy_link -+ || gmx_rx_int_reg.s.phy_spd) { -+ -+ struct net_device *dev = -+ cvm_oct_device[cvmx_helper_get_ipd_port -+ (interface, index)]; -+ if (dev) -+ cvm_oct_rgmii_poll(dev); -+ gmx_rx_int_reg.u64 = 0; -+ gmx_rx_int_reg.s.phy_dupx = 1; -+ gmx_rx_int_reg.s.phy_link = 1; -+ gmx_rx_int_reg.s.phy_spd = 1; -+ cvmx_write_csr(CVMX_GMXX_RXX_INT_REG -+ (index, interface), -+ gmx_rx_int_reg.u64); -+ return_status = IRQ_HANDLED; -+ } -+ } -+ } -+ return return_status; -+} -+ -+static int cvm_oct_rgmii_open(struct net_device *dev) -+{ -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ cvmx_helper_link_info_t link_info; -+ -+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ gmx_cfg.s.en = 1; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); -+ -+ if (!octeon_is_simulation()) { -+ link_info = cvmx_helper_link_get(priv->port); -+ if (!link_info.s.link_up) -+ netif_carrier_off(dev); -+ } -+ -+ return 0; -+} -+ -+static int cvm_oct_rgmii_stop(struct net_device *dev) -+{ -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ -+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ gmx_cfg.s.en = 0; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); -+ return 0; -+} -+ -+int cvm_oct_rgmii_init(struct net_device *dev) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int r; -+ -+ cvm_oct_common_init(dev); -+ dev->open = cvm_oct_rgmii_open; -+ dev->stop = cvm_oct_rgmii_stop; -+ dev->stop(dev); -+ -+ /* -+ * Due to GMX errata in CN3XXX series chips, it is necessary -+ * to take the link down immediately whne the PHY changes -+ * state. In order to do this we call the poll function every -+ * time the RGMII inband status changes. This may cause -+ * problems if the PHY doesn't implement inband status -+ * properly. -+ */ -+ if (number_rgmii_ports == 0) { -+ r = request_irq(OCTEON_IRQ_RML, cvm_oct_rgmii_rml_interrupt, -+ IRQF_SHARED, "RGMII", &number_rgmii_ports); -+ } -+ number_rgmii_ports++; -+ -+ /* -+ * Only true RGMII ports need to be polled. In GMII mode, port -+ * 0 is really a RGMII port. -+ */ -+ if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII) -+ && (priv->port == 0)) -+ || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) { -+ -+ if (!octeon_is_simulation()) { -+ -+ union cvmx_gmxx_rxx_int_en gmx_rx_int_en; -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ -+ /* -+ * Enable interrupts on inband status changes -+ * for this port. -+ */ -+ gmx_rx_int_en.u64 = -+ cvmx_read_csr(CVMX_GMXX_RXX_INT_EN -+ (index, interface)); -+ gmx_rx_int_en.s.phy_dupx = 1; -+ gmx_rx_int_en.s.phy_link = 1; -+ gmx_rx_int_en.s.phy_spd = 1; -+ cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface), -+ gmx_rx_int_en.u64); -+ priv->poll = cvm_oct_rgmii_poll; -+ } -+ } -+ -+ return 0; -+} -+ -+void cvm_oct_rgmii_uninit(struct net_device *dev) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ cvm_oct_common_uninit(dev); -+ -+ /* -+ * Only true RGMII ports need to be polled. In GMII mode, port -+ * 0 is really a RGMII port. -+ */ -+ if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII) -+ && (priv->port == 0)) -+ || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) { -+ -+ if (!octeon_is_simulation()) { -+ -+ union cvmx_gmxx_rxx_int_en gmx_rx_int_en; -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ -+ /* -+ * Disable interrupts on inband status changes -+ * for this port. -+ */ -+ gmx_rx_int_en.u64 = -+ cvmx_read_csr(CVMX_GMXX_RXX_INT_EN -+ (index, interface)); -+ gmx_rx_int_en.s.phy_dupx = 0; -+ gmx_rx_int_en.s.phy_link = 0; -+ gmx_rx_int_en.s.phy_spd = 0; -+ cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface), -+ gmx_rx_int_en.u64); -+ } -+ } -+ -+ /* Remove the interrupt handler when the last port is removed. */ -+ number_rgmii_ports--; -+ if (number_rgmii_ports == 0) -+ free_irq(OCTEON_IRQ_RML, &number_rgmii_ports); -+} ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-rx.c -@@ -0,0 +1,505 @@ -+/********************************************************************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+**********************************************************************/ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/cache.h> -+#include <linux/netdevice.h> -+#include <linux/init.h> -+#include <linux/etherdevice.h> -+#include <linux/ip.h> -+#include <linux/string.h> -+#include <linux/prefetch.h> -+#include <linux/ethtool.h> -+#include <linux/mii.h> -+#include <linux/seq_file.h> -+#include <linux/proc_fs.h> -+#include <net/dst.h> -+#ifdef CONFIG_XFRM -+#include <linux/xfrm.h> -+#include <net/xfrm.h> -+#endif /* CONFIG_XFRM */ -+ -+#include <asm/atomic.h> -+ -+#include <asm/octeon/octeon.h> -+ -+#include "ethernet-defines.h" -+#include "octeon-ethernet.h" -+#include "ethernet-mem.h" -+#include "ethernet-util.h" -+ -+#include "cvmx-helper.h" -+#include "cvmx-wqe.h" -+#include "cvmx-fau.h" -+#include "cvmx-pow.h" -+#include "cvmx-pip.h" -+#include "cvmx-scratch.h" -+ -+#include "cvmx-gmxx-defs.h" -+ -+struct cvm_tasklet_wrapper { -+ struct tasklet_struct t; -+}; -+ -+/* -+ * Aligning the tasklet_struct on cachline boundries seems to decrease -+ * throughput even though in theory it would reduce contantion on the -+ * cache lines containing the locks. -+ */ -+ -+static struct cvm_tasklet_wrapper cvm_oct_tasklet[NR_CPUS]; -+ -+/** -+ * Interrupt handler. The interrupt occurs whenever the POW -+ * transitions from 0->1 packets in our group. -+ * -+ * @cpl: -+ * @dev_id: -+ * @regs: -+ * Returns -+ */ -+irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id) -+{ -+ /* Acknowledge the interrupt */ -+ if (INTERRUPT_LIMIT) -+ cvmx_write_csr(CVMX_POW_WQ_INT, 1 << pow_receive_group); -+ else -+ cvmx_write_csr(CVMX_POW_WQ_INT, 0x10001 << pow_receive_group); -+ preempt_disable(); -+ tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t); -+ preempt_enable(); -+ return IRQ_HANDLED; -+} -+ -+#ifdef CONFIG_NET_POLL_CONTROLLER -+/** -+ * This is called when the kernel needs to manually poll the -+ * device. For Octeon, this is simply calling the interrupt -+ * handler. We actually poll all the devices, not just the -+ * one supplied. -+ * -+ * @dev: Device to poll. Unused -+ */ -+void cvm_oct_poll_controller(struct net_device *dev) -+{ -+ preempt_disable(); -+ tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t); -+ preempt_enable(); -+} -+#endif -+ -+/** -+ * This is called on receive errors, and determines if the packet -+ * can be dropped early-on in cvm_oct_tasklet_rx(). -+ * -+ * @work: Work queue entry pointing to the packet. -+ * Returns Non-zero if the packet can be dropped, zero otherwise. -+ */ -+static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) -+{ -+ if ((work->word2.snoip.err_code == 10) && (work->len <= 64)) { -+ /* -+ * Ignore length errors on min size packets. Some -+ * equipment incorrectly pads packets to 64+4FCS -+ * instead of 60+4FCS. Note these packets still get -+ * counted as frame errors. -+ */ -+ } else -+ if (USE_10MBPS_PREAMBLE_WORKAROUND -+ && ((work->word2.snoip.err_code == 5) -+ || (work->word2.snoip.err_code == 7))) { -+ -+ /* -+ * We received a packet with either an alignment error -+ * or a FCS error. This may be signalling that we are -+ * running 10Mbps with GMXX_RXX_FRM_CTL[PRE_CHK} -+ * off. If this is the case we need to parse the -+ * packet to determine if we can remove a non spec -+ * preamble and generate a correct packet. -+ */ -+ int interface = cvmx_helper_get_interface_num(work->ipprt); -+ int index = cvmx_helper_get_interface_index_num(work->ipprt); -+ union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl; -+ gmxx_rxx_frm_ctl.u64 = -+ cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface)); -+ if (gmxx_rxx_frm_ctl.s.pre_chk == 0) { -+ -+ uint8_t *ptr = -+ cvmx_phys_to_ptr(work->packet_ptr.s.addr); -+ int i = 0; -+ -+ while (i < work->len - 1) { -+ if (*ptr != 0x55) -+ break; -+ ptr++; -+ i++; -+ } -+ -+ if (*ptr == 0xd5) { -+ /* -+ DEBUGPRINT("Port %d received 0xd5 preamble\n", work->ipprt); -+ */ -+ work->packet_ptr.s.addr += i + 1; -+ work->len -= i + 5; -+ } else if ((*ptr & 0xf) == 0xd) { -+ /* -+ DEBUGPRINT("Port %d received 0x?d preamble\n", work->ipprt); -+ */ -+ work->packet_ptr.s.addr += i; -+ work->len -= i + 4; -+ for (i = 0; i < work->len; i++) { -+ *ptr = -+ ((*ptr & 0xf0) >> 4) | -+ ((*(ptr + 1) & 0xf) << 4); -+ ptr++; -+ } -+ } else { -+ DEBUGPRINT("Port %d unknown preamble, packet " -+ "dropped\n", -+ work->ipprt); -+ /* -+ cvmx_helper_dump_packet(work); -+ */ -+ cvm_oct_free_work(work); -+ return 1; -+ } -+ } -+ } else { -+ DEBUGPRINT("Port %d receive error code %d, packet dropped\n", -+ work->ipprt, work->word2.snoip.err_code); -+ cvm_oct_free_work(work); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/** -+ * Tasklet function that is scheduled on a core when an interrupt occurs. -+ * -+ * @unused: -+ */ -+void cvm_oct_tasklet_rx(unsigned long unused) -+{ -+ const int coreid = cvmx_get_core_num(); -+ uint64_t old_group_mask; -+ uint64_t old_scratch; -+ int rx_count = 0; -+ int number_to_free; -+ int num_freed; -+ int packet_not_copied; -+ -+ /* Prefetch cvm_oct_device since we know we need it soon */ -+ prefetch(cvm_oct_device); -+ -+ if (USE_ASYNC_IOBDMA) { -+ /* Save scratch in case userspace is using it */ -+ CVMX_SYNCIOBDMA; -+ old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH); -+ } -+ -+ /* Only allow work for our group (and preserve priorities) */ -+ old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid)); -+ cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), -+ (old_group_mask & ~0xFFFFull) | 1 << pow_receive_group); -+ -+ if (USE_ASYNC_IOBDMA) -+ cvmx_pow_work_request_async(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT); -+ -+ while (1) { -+ struct sk_buff *skb = NULL; -+ int skb_in_hw; -+ cvmx_wqe_t *work; -+ -+ if (USE_ASYNC_IOBDMA) { -+ work = cvmx_pow_work_response_async(CVMX_SCR_SCRATCH); -+ } else { -+ if ((INTERRUPT_LIMIT == 0) -+ || likely(rx_count < MAX_RX_PACKETS)) -+ work = -+ cvmx_pow_work_request_sync -+ (CVMX_POW_NO_WAIT); -+ else -+ work = NULL; -+ } -+ prefetch(work); -+ if (work == NULL) -+ break; -+ -+ /* -+ * Limit each core to processing MAX_RX_PACKETS -+ * packets without a break. This way the RX can't -+ * starve the TX task. -+ */ -+ if (USE_ASYNC_IOBDMA) { -+ -+ if ((INTERRUPT_LIMIT == 0) -+ || likely(rx_count < MAX_RX_PACKETS)) -+ cvmx_pow_work_request_async_nocheck -+ (CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT); -+ else { -+ cvmx_scratch_write64(CVMX_SCR_SCRATCH, -+ 0x8000000000000000ull); -+ cvmx_pow_tag_sw_null_nocheck(); -+ } -+ } -+ -+ skb_in_hw = USE_SKBUFFS_IN_HW && work->word2.s.bufs == 1; -+ if (likely(skb_in_hw)) { -+ skb = -+ *(struct sk_buff -+ **)(cvm_oct_get_buffer_ptr(work->packet_ptr) - -+ sizeof(void *)); -+ prefetch(&skb->head); -+ prefetch(&skb->len); -+ } -+ prefetch(cvm_oct_device[work->ipprt]); -+ -+ rx_count++; -+ /* Immediately throw away all packets with receive errors */ -+ if (unlikely(work->word2.snoip.rcv_error)) { -+ if (cvm_oct_check_rcv_error(work)) -+ continue; -+ } -+ -+ /* -+ * We can only use the zero copy path if skbuffs are -+ * in the FPA pool and the packet fits in a single -+ * buffer. -+ */ -+ if (likely(skb_in_hw)) { -+ /* -+ * This calculation was changed in case the -+ * skb header is using a different address -+ * aliasing type than the buffer. It doesn't -+ * make any differnece now, but the new one is -+ * more correct. -+ */ -+ skb->data = -+ skb->head + work->packet_ptr.s.addr - -+ cvmx_ptr_to_phys(skb->head); -+ prefetch(skb->data); -+ skb->len = work->len; -+ skb_set_tail_pointer(skb, skb->len); -+ packet_not_copied = 1; -+ } else { -+ -+ /* -+ * We have to copy the packet. First allocate -+ * an skbuff for it. -+ */ -+ skb = dev_alloc_skb(work->len); -+ if (!skb) { -+ DEBUGPRINT("Port %d failed to allocate " -+ "skbuff, packet dropped\n", -+ work->ipprt); -+ cvm_oct_free_work(work); -+ continue; -+ } -+ -+ /* -+ * Check if we've received a packet that was -+ * entirely stored in the work entry. This is -+ * untested. -+ */ -+ if (unlikely(work->word2.s.bufs == 0)) { -+ uint8_t *ptr = work->packet_data; -+ -+ if (likely(!work->word2.s.not_IP)) { -+ /* -+ * The beginning of the packet -+ * moves for IP packets. -+ */ -+ if (work->word2.s.is_v6) -+ ptr += 2; -+ else -+ ptr += 6; -+ } -+ memcpy(skb_put(skb, work->len), ptr, work->len); -+ /* No packet buffers to free */ -+ } else { -+ int segments = work->word2.s.bufs; -+ union cvmx_buf_ptr segment_ptr = -+ work->packet_ptr; -+ int len = work->len; -+ -+ while (segments--) { -+ union cvmx_buf_ptr next_ptr = -+ *(union cvmx_buf_ptr *) -+ cvmx_phys_to_ptr(segment_ptr.s. -+ addr - 8); -+ /* -+ * Octeon Errata PKI-100: The segment size is -+ * wrong. Until it is fixed, calculate the -+ * segment size based on the packet pool -+ * buffer size. When it is fixed, the -+ * following line should be replaced with this -+ * one: int segment_size = -+ * segment_ptr.s.size; -+ */ -+ int segment_size = -+ CVMX_FPA_PACKET_POOL_SIZE - -+ (segment_ptr.s.addr - -+ (((segment_ptr.s.addr >> 7) - -+ segment_ptr.s.back) << 7)); -+ /* Don't copy more than what is left -+ in the packet */ -+ if (segment_size > len) -+ segment_size = len; -+ /* Copy the data into the packet */ -+ memcpy(skb_put(skb, segment_size), -+ cvmx_phys_to_ptr(segment_ptr.s. -+ addr), -+ segment_size); -+ /* Reduce the amount of bytes left -+ to copy */ -+ len -= segment_size; -+ segment_ptr = next_ptr; -+ } -+ } -+ packet_not_copied = 0; -+ } -+ -+ if (likely((work->ipprt < TOTAL_NUMBER_OF_PORTS) && -+ cvm_oct_device[work->ipprt])) { -+ struct net_device *dev = cvm_oct_device[work->ipprt]; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ -+ /* Only accept packets for devices -+ that are currently up */ -+ if (likely(dev->flags & IFF_UP)) { -+ skb->protocol = eth_type_trans(skb, dev); -+ skb->dev = dev; -+ -+ if (unlikely -+ (work->word2.s.not_IP -+ || work->word2.s.IP_exc -+ || work->word2.s.L4_error)) -+ skb->ip_summed = CHECKSUM_NONE; -+ else -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ -+ /* Increment RX stats for virtual ports */ -+ if (work->ipprt >= CVMX_PIP_NUM_INPUT_PORTS) { -+#ifdef CONFIG_64BIT -+ atomic64_add(1, (atomic64_t *)&priv->stats.rx_packets); -+ atomic64_add(skb->len, (atomic64_t *)&priv->stats.rx_bytes); -+#else -+ atomic_add(1, (atomic_t *)&priv->stats.rx_packets); -+ atomic_add(skb->len, (atomic_t *)&priv->stats.rx_bytes); -+#endif -+ } -+ netif_receive_skb(skb); -+ } else { -+ /* -+ * Drop any packet received for a -+ * device that isn't up. -+ */ -+ /* -+ DEBUGPRINT("%s: Device not up, packet dropped\n", -+ dev->name); -+ */ -+#ifdef CONFIG_64BIT -+ atomic64_add(1, (atomic64_t *)&priv->stats.rx_dropped); -+#else -+ atomic_add(1, (atomic_t *)&priv->stats.rx_dropped); -+#endif -+ dev_kfree_skb_irq(skb); -+ } -+ } else { -+ /* -+ * Drop any packet received for a device that -+ * doesn't exist. -+ */ -+ DEBUGPRINT("Port %d not controlled by Linux, packet " -+ "dropped\n", -+ work->ipprt); -+ dev_kfree_skb_irq(skb); -+ } -+ /* -+ * Check to see if the skbuff and work share the same -+ * packet buffer. -+ */ -+ if (USE_SKBUFFS_IN_HW && likely(packet_not_copied)) { -+ /* -+ * This buffer needs to be replaced, increment -+ * the number of buffers we need to free by -+ * one. -+ */ -+ cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, -+ 1); -+ -+ cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, -+ DONT_WRITEBACK(1)); -+ } else { -+ cvm_oct_free_work(work); -+ } -+ } -+ -+ /* Restore the original POW group mask */ -+ cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), old_group_mask); -+ if (USE_ASYNC_IOBDMA) { -+ /* Restore the scratch area */ -+ cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch); -+ } -+ -+ if (USE_SKBUFFS_IN_HW) { -+ /* Refill the packet buffer pool */ -+ number_to_free = -+ cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0); -+ -+ if (number_to_free > 0) { -+ cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, -+ -number_to_free); -+ num_freed = -+ cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, -+ CVMX_FPA_PACKET_POOL_SIZE, -+ number_to_free); -+ if (num_freed != number_to_free) { -+ cvmx_fau_atomic_add32 -+ (FAU_NUM_PACKET_BUFFERS_TO_FREE, -+ number_to_free - num_freed); -+ } -+ } -+ } -+} -+ -+void cvm_oct_rx_initialize(void) -+{ -+ int i; -+ /* Initialize all of the tasklets */ -+ for (i = 0; i < NR_CPUS; i++) -+ tasklet_init(&cvm_oct_tasklet[i].t, cvm_oct_tasklet_rx, 0); -+} -+ -+void cvm_oct_rx_shutdown(void) -+{ -+ int i; -+ /* Shutdown all of the tasklets */ -+ for (i = 0; i < NR_CPUS; i++) -+ tasklet_kill(&cvm_oct_tasklet[i].t); -+} ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-rx.h -@@ -0,0 +1,33 @@ -+/********************************************************************* -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+*********************************************************************/ -+ -+irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id); -+void cvm_oct_poll_controller(struct net_device *dev); -+void cvm_oct_tasklet_rx(unsigned long unused); -+ -+void cvm_oct_rx_initialize(void); -+void cvm_oct_rx_shutdown(void); ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-sgmii.c -@@ -0,0 +1,129 @@ -+/********************************************************************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+**********************************************************************/ -+#include <linux/kernel.h> -+#include <linux/netdevice.h> -+#include <linux/mii.h> -+#include <net/dst.h> -+ -+#include <asm/octeon/octeon.h> -+ -+#include "ethernet-defines.h" -+#include "octeon-ethernet.h" -+#include "ethernet-util.h" -+#include "ethernet-common.h" -+ -+#include "cvmx-helper.h" -+ -+#include "cvmx-gmxx-defs.h" -+ -+static int cvm_oct_sgmii_open(struct net_device *dev) -+{ -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ cvmx_helper_link_info_t link_info; -+ -+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ gmx_cfg.s.en = 1; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); -+ -+ if (!octeon_is_simulation()) { -+ link_info = cvmx_helper_link_get(priv->port); -+ if (!link_info.s.link_up) -+ netif_carrier_off(dev); -+ } -+ -+ return 0; -+} -+ -+static int cvm_oct_sgmii_stop(struct net_device *dev) -+{ -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ -+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ gmx_cfg.s.en = 0; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); -+ return 0; -+} -+ -+static void cvm_oct_sgmii_poll(struct net_device *dev) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ cvmx_helper_link_info_t link_info; -+ -+ link_info = cvmx_helper_link_get(priv->port); -+ if (link_info.u64 == priv->link_info) -+ return; -+ -+ link_info = cvmx_helper_link_autoconf(priv->port); -+ priv->link_info = link_info.u64; -+ -+ /* Tell Linux */ -+ if (link_info.s.link_up) { -+ -+ if (!netif_carrier_ok(dev)) -+ netif_carrier_on(dev); -+ if (priv->queue != -1) -+ DEBUGPRINT -+ ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", -+ dev->name, link_info.s.speed, -+ (link_info.s.full_duplex) ? "Full" : "Half", -+ priv->port, priv->queue); -+ else -+ DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n", -+ dev->name, link_info.s.speed, -+ (link_info.s.full_duplex) ? "Full" : "Half", -+ priv->port); -+ } else { -+ if (netif_carrier_ok(dev)) -+ netif_carrier_off(dev); -+ DEBUGPRINT("%s: Link down\n", dev->name); -+ } -+} -+ -+int cvm_oct_sgmii_init(struct net_device *dev) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ cvm_oct_common_init(dev); -+ dev->open = cvm_oct_sgmii_open; -+ dev->stop = cvm_oct_sgmii_stop; -+ dev->stop(dev); -+ if (!octeon_is_simulation()) -+ priv->poll = cvm_oct_sgmii_poll; -+ -+ /* FIXME: Need autoneg logic */ -+ return 0; -+} -+ -+void cvm_oct_sgmii_uninit(struct net_device *dev) -+{ -+ cvm_oct_common_uninit(dev); -+} ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-spi.c -@@ -0,0 +1,323 @@ -+/********************************************************************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+**********************************************************************/ -+#include <linux/kernel.h> -+#include <linux/netdevice.h> -+#include <linux/mii.h> -+#include <net/dst.h> -+ -+#include <asm/octeon/octeon.h> -+ -+#include "ethernet-defines.h" -+#include "octeon-ethernet.h" -+#include "ethernet-common.h" -+#include "ethernet-util.h" -+ -+#include "cvmx-spi.h" -+ -+#include <asm/octeon/cvmx-npi-defs.h> -+#include "cvmx-spxx-defs.h" -+#include "cvmx-stxx-defs.h" -+ -+static int number_spi_ports; -+static int need_retrain[2] = { 0, 0 }; -+ -+static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id) -+{ -+ irqreturn_t return_status = IRQ_NONE; -+ union cvmx_npi_rsl_int_blocks rsl_int_blocks; -+ -+ /* Check and see if this interrupt was caused by the GMX block */ -+ rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS); -+ if (rsl_int_blocks.s.spx1) { /* 19 - SPX1_INT_REG & STX1_INT_REG */ -+ -+ union cvmx_spxx_int_reg spx_int_reg; -+ union cvmx_stxx_int_reg stx_int_reg; -+ -+ spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(1)); -+ cvmx_write_csr(CVMX_SPXX_INT_REG(1), spx_int_reg.u64); -+ if (!need_retrain[1]) { -+ -+ spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(1)); -+ if (spx_int_reg.s.spf) -+ pr_err("SPI1: SRX Spi4 interface down\n"); -+ if (spx_int_reg.s.calerr) -+ pr_err("SPI1: SRX Spi4 Calendar table " -+ "parity error\n"); -+ if (spx_int_reg.s.syncerr) -+ pr_err("SPI1: SRX Consecutive Spi4 DIP4 " -+ "errors have exceeded " -+ "SPX_ERR_CTL[ERRCNT]\n"); -+ if (spx_int_reg.s.diperr) -+ pr_err("SPI1: SRX Spi4 DIP4 error\n"); -+ if (spx_int_reg.s.tpaovr) -+ pr_err("SPI1: SRX Selected port has hit " -+ "TPA overflow\n"); -+ if (spx_int_reg.s.rsverr) -+ pr_err("SPI1: SRX Spi4 reserved control " -+ "word detected\n"); -+ if (spx_int_reg.s.drwnng) -+ pr_err("SPI1: SRX Spi4 receive FIFO " -+ "drowning/overflow\n"); -+ if (spx_int_reg.s.clserr) -+ pr_err("SPI1: SRX Spi4 packet closed on " -+ "non-16B alignment without EOP\n"); -+ if (spx_int_reg.s.spiovr) -+ pr_err("SPI1: SRX Spi4 async FIFO overflow\n"); -+ if (spx_int_reg.s.abnorm) -+ pr_err("SPI1: SRX Abnormal packet " -+ "termination (ERR bit)\n"); -+ if (spx_int_reg.s.prtnxa) -+ pr_err("SPI1: SRX Port out of range\n"); -+ } -+ -+ stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(1)); -+ cvmx_write_csr(CVMX_STXX_INT_REG(1), stx_int_reg.u64); -+ if (!need_retrain[1]) { -+ -+ stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(1)); -+ if (stx_int_reg.s.syncerr) -+ pr_err("SPI1: STX Interface encountered a " -+ "fatal error\n"); -+ if (stx_int_reg.s.frmerr) -+ pr_err("SPI1: STX FRMCNT has exceeded " -+ "STX_DIP_CNT[MAXFRM]\n"); -+ if (stx_int_reg.s.unxfrm) -+ pr_err("SPI1: STX Unexpected framing " -+ "sequence\n"); -+ if (stx_int_reg.s.nosync) -+ pr_err("SPI1: STX ERRCNT has exceeded " -+ "STX_DIP_CNT[MAXDIP]\n"); -+ if (stx_int_reg.s.diperr) -+ pr_err("SPI1: STX DIP2 error on the Spi4 " -+ "Status channel\n"); -+ if (stx_int_reg.s.datovr) -+ pr_err("SPI1: STX Spi4 FIFO overflow error\n"); -+ if (stx_int_reg.s.ovrbst) -+ pr_err("SPI1: STX Transmit packet burst " -+ "too big\n"); -+ if (stx_int_reg.s.calpar1) -+ pr_err("SPI1: STX Calendar Table Parity " -+ "Error Bank1\n"); -+ if (stx_int_reg.s.calpar0) -+ pr_err("SPI1: STX Calendar Table Parity " -+ "Error Bank0\n"); -+ } -+ -+ cvmx_write_csr(CVMX_SPXX_INT_MSK(1), 0); -+ cvmx_write_csr(CVMX_STXX_INT_MSK(1), 0); -+ need_retrain[1] = 1; -+ return_status = IRQ_HANDLED; -+ } -+ -+ if (rsl_int_blocks.s.spx0) { /* 18 - SPX0_INT_REG & STX0_INT_REG */ -+ union cvmx_spxx_int_reg spx_int_reg; -+ union cvmx_stxx_int_reg stx_int_reg; -+ -+ spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(0)); -+ cvmx_write_csr(CVMX_SPXX_INT_REG(0), spx_int_reg.u64); -+ if (!need_retrain[0]) { -+ -+ spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(0)); -+ if (spx_int_reg.s.spf) -+ pr_err("SPI0: SRX Spi4 interface down\n"); -+ if (spx_int_reg.s.calerr) -+ pr_err("SPI0: SRX Spi4 Calendar table " -+ "parity error\n"); -+ if (spx_int_reg.s.syncerr) -+ pr_err("SPI0: SRX Consecutive Spi4 DIP4 " -+ "errors have exceeded " -+ "SPX_ERR_CTL[ERRCNT]\n"); -+ if (spx_int_reg.s.diperr) -+ pr_err("SPI0: SRX Spi4 DIP4 error\n"); -+ if (spx_int_reg.s.tpaovr) -+ pr_err("SPI0: SRX Selected port has hit " -+ "TPA overflow\n"); -+ if (spx_int_reg.s.rsverr) -+ pr_err("SPI0: SRX Spi4 reserved control " -+ "word detected\n"); -+ if (spx_int_reg.s.drwnng) -+ pr_err("SPI0: SRX Spi4 receive FIFO " -+ "drowning/overflow\n"); -+ if (spx_int_reg.s.clserr) -+ pr_err("SPI0: SRX Spi4 packet closed on " -+ "non-16B alignment without EOP\n"); -+ if (spx_int_reg.s.spiovr) -+ pr_err("SPI0: SRX Spi4 async FIFO overflow\n"); -+ if (spx_int_reg.s.abnorm) -+ pr_err("SPI0: SRX Abnormal packet " -+ "termination (ERR bit)\n"); -+ if (spx_int_reg.s.prtnxa) -+ pr_err("SPI0: SRX Port out of range\n"); -+ } -+ -+ stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(0)); -+ cvmx_write_csr(CVMX_STXX_INT_REG(0), stx_int_reg.u64); -+ if (!need_retrain[0]) { -+ -+ stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(0)); -+ if (stx_int_reg.s.syncerr) -+ pr_err("SPI0: STX Interface encountered a " -+ "fatal error\n"); -+ if (stx_int_reg.s.frmerr) -+ pr_err("SPI0: STX FRMCNT has exceeded " -+ "STX_DIP_CNT[MAXFRM]\n"); -+ if (stx_int_reg.s.unxfrm) -+ pr_err("SPI0: STX Unexpected framing " -+ "sequence\n"); -+ if (stx_int_reg.s.nosync) -+ pr_err("SPI0: STX ERRCNT has exceeded " -+ "STX_DIP_CNT[MAXDIP]\n"); -+ if (stx_int_reg.s.diperr) -+ pr_err("SPI0: STX DIP2 error on the Spi4 " -+ "Status channel\n"); -+ if (stx_int_reg.s.datovr) -+ pr_err("SPI0: STX Spi4 FIFO overflow error\n"); -+ if (stx_int_reg.s.ovrbst) -+ pr_err("SPI0: STX Transmit packet burst " -+ "too big\n"); -+ if (stx_int_reg.s.calpar1) -+ pr_err("SPI0: STX Calendar Table Parity " -+ "Error Bank1\n"); -+ if (stx_int_reg.s.calpar0) -+ pr_err("SPI0: STX Calendar Table Parity " -+ "Error Bank0\n"); -+ } -+ -+ cvmx_write_csr(CVMX_SPXX_INT_MSK(0), 0); -+ cvmx_write_csr(CVMX_STXX_INT_MSK(0), 0); -+ need_retrain[0] = 1; -+ return_status = IRQ_HANDLED; -+ } -+ -+ return return_status; -+} -+ -+static void cvm_oct_spi_enable_error_reporting(int interface) -+{ -+ union cvmx_spxx_int_msk spxx_int_msk; -+ union cvmx_stxx_int_msk stxx_int_msk; -+ -+ spxx_int_msk.u64 = cvmx_read_csr(CVMX_SPXX_INT_MSK(interface)); -+ spxx_int_msk.s.calerr = 1; -+ spxx_int_msk.s.syncerr = 1; -+ spxx_int_msk.s.diperr = 1; -+ spxx_int_msk.s.tpaovr = 1; -+ spxx_int_msk.s.rsverr = 1; -+ spxx_int_msk.s.drwnng = 1; -+ spxx_int_msk.s.clserr = 1; -+ spxx_int_msk.s.spiovr = 1; -+ spxx_int_msk.s.abnorm = 1; -+ spxx_int_msk.s.prtnxa = 1; -+ cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), spxx_int_msk.u64); -+ -+ stxx_int_msk.u64 = cvmx_read_csr(CVMX_STXX_INT_MSK(interface)); -+ stxx_int_msk.s.frmerr = 1; -+ stxx_int_msk.s.unxfrm = 1; -+ stxx_int_msk.s.nosync = 1; -+ stxx_int_msk.s.diperr = 1; -+ stxx_int_msk.s.datovr = 1; -+ stxx_int_msk.s.ovrbst = 1; -+ stxx_int_msk.s.calpar1 = 1; -+ stxx_int_msk.s.calpar0 = 1; -+ cvmx_write_csr(CVMX_STXX_INT_MSK(interface), stxx_int_msk.u64); -+} -+ -+static void cvm_oct_spi_poll(struct net_device *dev) -+{ -+ static int spi4000_port; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int interface; -+ -+ for (interface = 0; interface < 2; interface++) { -+ -+ if ((priv->port == interface * 16) && need_retrain[interface]) { -+ -+ if (cvmx_spi_restart_interface -+ (interface, CVMX_SPI_MODE_DUPLEX, 10) == 0) { -+ need_retrain[interface] = 0; -+ cvm_oct_spi_enable_error_reporting(interface); -+ } -+ } -+ -+ /* -+ * The SPI4000 TWSI interface is very slow. In order -+ * not to bring the system to a crawl, we only poll a -+ * single port every second. This means negotiation -+ * speed changes take up to 10 seconds, but at least -+ * we don't waste absurd amounts of time waiting for -+ * TWSI. -+ */ -+ if (priv->port == spi4000_port) { -+ /* -+ * This function does nothing if it is called on an -+ * interface without a SPI4000. -+ */ -+ cvmx_spi4000_check_speed(interface, priv->port); -+ /* -+ * Normal ordering increments. By decrementing -+ * we only match once per iteration. -+ */ -+ spi4000_port--; -+ if (spi4000_port < 0) -+ spi4000_port = 10; -+ } -+ } -+} -+ -+int cvm_oct_spi_init(struct net_device *dev) -+{ -+ int r; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ -+ if (number_spi_ports == 0) { -+ r = request_irq(OCTEON_IRQ_RML, cvm_oct_spi_rml_interrupt, -+ IRQF_SHARED, "SPI", &number_spi_ports); -+ } -+ number_spi_ports++; -+ -+ if ((priv->port == 0) || (priv->port == 16)) { -+ cvm_oct_spi_enable_error_reporting(INTERFACE(priv->port)); -+ priv->poll = cvm_oct_spi_poll; -+ } -+ cvm_oct_common_init(dev); -+ return 0; -+} -+ -+void cvm_oct_spi_uninit(struct net_device *dev) -+{ -+ int interface; -+ -+ cvm_oct_common_uninit(dev); -+ number_spi_ports--; -+ if (number_spi_ports == 0) { -+ for (interface = 0; interface < 2; interface++) { -+ cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0); -+ cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0); -+ } -+ free_irq(8 + 46, &number_spi_ports); -+ } -+} ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-tx.c -@@ -0,0 +1,634 @@ -+/********************************************************************* -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+*********************************************************************/ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/netdevice.h> -+#include <linux/init.h> -+#include <linux/etherdevice.h> -+#include <linux/ip.h> -+#include <linux/string.h> -+#include <linux/ethtool.h> -+#include <linux/mii.h> -+#include <linux/seq_file.h> -+#include <linux/proc_fs.h> -+#include <net/dst.h> -+#ifdef CONFIG_XFRM -+#include <linux/xfrm.h> -+#include <net/xfrm.h> -+#endif /* CONFIG_XFRM */ -+ -+#include <asm/atomic.h> -+ -+#include <asm/octeon/octeon.h> -+ -+#include "ethernet-defines.h" -+#include "octeon-ethernet.h" -+#include "ethernet-util.h" -+ -+#include "cvmx-wqe.h" -+#include "cvmx-fau.h" -+#include "cvmx-pko.h" -+#include "cvmx-helper.h" -+ -+#include "cvmx-gmxx-defs.h" -+ -+/* -+ * You can define GET_SKBUFF_QOS() to override how the skbuff output -+ * function determines which output queue is used. The default -+ * implementation always uses the base queue for the port. If, for -+ * example, you wanted to use the skb->priority fieid, define -+ * GET_SKBUFF_QOS as: #define GET_SKBUFF_QOS(skb) ((skb)->priority) -+ */ -+#ifndef GET_SKBUFF_QOS -+#define GET_SKBUFF_QOS(skb) 0 -+#endif -+ -+/** -+ * Packet transmit -+ * -+ * @skb: Packet to send -+ * @dev: Device info structure -+ * Returns Always returns zero -+ */ -+int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ cvmx_pko_command_word0_t pko_command; -+ union cvmx_buf_ptr hw_buffer; -+ uint64_t old_scratch; -+ uint64_t old_scratch2; -+ int dropped; -+ int qos; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int32_t in_use; -+ int32_t buffers_to_free; -+#if REUSE_SKBUFFS_WITHOUT_FREE -+ unsigned char *fpa_head; -+#endif -+ -+ /* -+ * Prefetch the private data structure. It is larger that one -+ * cache line. -+ */ -+ prefetch(priv); -+ -+ /* Start off assuming no drop */ -+ dropped = 0; -+ -+ /* -+ * The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to -+ * completely remove "qos" in the event neither interface -+ * supports multiple queues per port. -+ */ -+ if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) || -+ (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) { -+ qos = GET_SKBUFF_QOS(skb); -+ if (qos <= 0) -+ qos = 0; -+ else if (qos >= cvmx_pko_get_num_queues(priv->port)) -+ qos = 0; -+ } else -+ qos = 0; -+ -+ if (USE_ASYNC_IOBDMA) { -+ /* Save scratch in case userspace is using it */ -+ CVMX_SYNCIOBDMA; -+ old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH); -+ old_scratch2 = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8); -+ -+ /* -+ * Assume we're going to be able t osend this -+ * packet. Fetch and increment the number of pending -+ * packets for output. -+ */ -+ cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH + 8, -+ FAU_NUM_PACKET_BUFFERS_TO_FREE, -+ 0); -+ cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH, -+ priv->fau + qos * 4, 1); -+ } -+ -+ /* -+ * The CN3XXX series of parts has an errata (GMX-401) which -+ * causes the GMX block to hang if a collision occurs towards -+ * the end of a <68 byte packet. As a workaround for this, we -+ * pad packets to be 68 bytes whenever we are in half duplex -+ * mode. We don't handle the case of having a small packet but -+ * no room to add the padding. The kernel should always give -+ * us at least a cache line -+ */ -+ if ((skb->len < 64) && OCTEON_IS_MODEL(OCTEON_CN3XXX)) { -+ union cvmx_gmxx_prtx_cfg gmx_prt_cfg; -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ -+ if (interface < 2) { -+ /* We only need to pad packet in half duplex mode */ -+ gmx_prt_cfg.u64 = -+ cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ if (gmx_prt_cfg.s.duplex == 0) { -+ int add_bytes = 64 - skb->len; -+ if ((skb_tail_pointer(skb) + add_bytes) <= -+ skb_end_pointer(skb)) -+ memset(__skb_put(skb, add_bytes), 0, -+ add_bytes); -+ } -+ } -+ } -+ -+ /* Build the PKO buffer pointer */ -+ hw_buffer.u64 = 0; -+ hw_buffer.s.addr = cvmx_ptr_to_phys(skb->data); -+ hw_buffer.s.pool = 0; -+ hw_buffer.s.size = -+ (unsigned long)skb_end_pointer(skb) - (unsigned long)skb->head; -+ -+ /* Build the PKO command */ -+ pko_command.u64 = 0; -+ pko_command.s.n2 = 1; /* Don't pollute L2 with the outgoing packet */ -+ pko_command.s.segs = 1; -+ pko_command.s.total_bytes = skb->len; -+ pko_command.s.size0 = CVMX_FAU_OP_SIZE_32; -+ pko_command.s.subone0 = 1; -+ -+ pko_command.s.dontfree = 1; -+ pko_command.s.reg0 = priv->fau + qos * 4; -+ /* -+ * See if we can put this skb in the FPA pool. Any strange -+ * behavior from the Linux networking stack will most likely -+ * be caused by a bug in the following code. If some field is -+ * in use by the network stack and get carried over when a -+ * buffer is reused, bad thing may happen. If in doubt and -+ * you dont need the absolute best performance, disable the -+ * define REUSE_SKBUFFS_WITHOUT_FREE. The reuse of buffers has -+ * shown a 25% increase in performance under some loads. -+ */ -+#if REUSE_SKBUFFS_WITHOUT_FREE -+ fpa_head = skb->head + 128 - ((unsigned long)skb->head & 0x7f); -+ if (unlikely(skb->data < fpa_head)) { -+ /* -+ * printk("TX buffer beginning can't meet FPA -+ * alignment constraints\n"); -+ */ -+ goto dont_put_skbuff_in_hw; -+ } -+ if (unlikely -+ ((skb_end_pointer(skb) - fpa_head) < CVMX_FPA_PACKET_POOL_SIZE)) { -+ /* -+ printk("TX buffer isn't large enough for the FPA\n"); -+ */ -+ goto dont_put_skbuff_in_hw; -+ } -+ if (unlikely(skb_shared(skb))) { -+ /* -+ printk("TX buffer sharing data with someone else\n"); -+ */ -+ goto dont_put_skbuff_in_hw; -+ } -+ if (unlikely(skb_cloned(skb))) { -+ /* -+ printk("TX buffer has been cloned\n"); -+ */ -+ goto dont_put_skbuff_in_hw; -+ } -+ if (unlikely(skb_header_cloned(skb))) { -+ /* -+ printk("TX buffer header has been cloned\n"); -+ */ -+ goto dont_put_skbuff_in_hw; -+ } -+ if (unlikely(skb->destructor)) { -+ /* -+ printk("TX buffer has a destructor\n"); -+ */ -+ goto dont_put_skbuff_in_hw; -+ } -+ if (unlikely(skb_shinfo(skb)->nr_frags)) { -+ /* -+ printk("TX buffer has fragments\n"); -+ */ -+ goto dont_put_skbuff_in_hw; -+ } -+ if (unlikely -+ (skb->truesize != -+ sizeof(*skb) + skb_end_pointer(skb) - skb->head)) { -+ /* -+ printk("TX buffer truesize has been changed\n"); -+ */ -+ goto dont_put_skbuff_in_hw; -+ } -+ -+ /* -+ * We can use this buffer in the FPA. We don't need the FAU -+ * update anymore -+ */ -+ pko_command.s.reg0 = 0; -+ pko_command.s.dontfree = 0; -+ -+ hw_buffer.s.back = (skb->data - fpa_head) >> 7; -+ *(struct sk_buff **)(fpa_head - sizeof(void *)) = skb; -+ -+ /* -+ * The skbuff will be reused without ever being freed. We must -+ * cleanup a bunch of Linux stuff. -+ */ -+ dst_release(skb->dst); -+ skb->dst = NULL; -+#ifdef CONFIG_XFRM -+ secpath_put(skb->sp); -+ skb->sp = NULL; -+#endif -+ nf_reset(skb); -+ -+#ifdef CONFIG_NET_SCHED -+ skb->tc_index = 0; -+#ifdef CONFIG_NET_CLS_ACT -+ skb->tc_verd = 0; -+#endif /* CONFIG_NET_CLS_ACT */ -+#endif /* CONFIG_NET_SCHED */ -+ -+dont_put_skbuff_in_hw: -+#endif /* REUSE_SKBUFFS_WITHOUT_FREE */ -+ -+ /* Check if we can use the hardware checksumming */ -+ if (USE_HW_TCPUDP_CHECKSUM && (skb->protocol == htons(ETH_P_IP)) && -+ (ip_hdr(skb)->version == 4) && (ip_hdr(skb)->ihl == 5) && -+ ((ip_hdr(skb)->frag_off == 0) || (ip_hdr(skb)->frag_off == 1 << 14)) -+ && ((ip_hdr(skb)->protocol == IP_PROTOCOL_TCP) -+ || (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP))) { -+ /* Use hardware checksum calc */ -+ pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1; -+ } -+ -+ if (USE_ASYNC_IOBDMA) { -+ /* Get the number of skbuffs in use by the hardware */ -+ CVMX_SYNCIOBDMA; -+ in_use = cvmx_scratch_read64(CVMX_SCR_SCRATCH); -+ buffers_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8); -+ } else { -+ /* Get the number of skbuffs in use by the hardware */ -+ in_use = cvmx_fau_fetch_and_add32(priv->fau + qos * 4, 1); -+ buffers_to_free = -+ cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0); -+ } -+ -+ /* -+ * If we're sending faster than the receive can free them then -+ * don't do the HW free. -+ */ -+ if ((buffers_to_free < -100) && !pko_command.s.dontfree) { -+ pko_command.s.dontfree = 1; -+ pko_command.s.reg0 = priv->fau + qos * 4; -+ } -+ -+ cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos, -+ CVMX_PKO_LOCK_CMD_QUEUE); -+ -+ /* Drop this packet if we have too many already queued to the HW */ -+ if (unlikely -+ (skb_queue_len(&priv->tx_free_list[qos]) >= MAX_OUT_QUEUE_DEPTH)) { -+ /* -+ DEBUGPRINT("%s: Tx dropped. Too many queued\n", dev->name); -+ */ -+ dropped = 1; -+ } -+ /* Send the packet to the output queue */ -+ else if (unlikely -+ (cvmx_pko_send_packet_finish -+ (priv->port, priv->queue + qos, pko_command, hw_buffer, -+ CVMX_PKO_LOCK_CMD_QUEUE))) { -+ DEBUGPRINT("%s: Failed to send the packet\n", dev->name); -+ dropped = 1; -+ } -+ -+ if (USE_ASYNC_IOBDMA) { -+ /* Restore the scratch area */ -+ cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch); -+ cvmx_scratch_write64(CVMX_SCR_SCRATCH + 8, old_scratch2); -+ } -+ -+ if (unlikely(dropped)) { -+ dev_kfree_skb_any(skb); -+ cvmx_fau_atomic_add32(priv->fau + qos * 4, -1); -+ priv->stats.tx_dropped++; -+ } else { -+ if (USE_SKBUFFS_IN_HW) { -+ /* Put this packet on the queue to be freed later */ -+ if (pko_command.s.dontfree) -+ skb_queue_tail(&priv->tx_free_list[qos], skb); -+ else { -+ cvmx_fau_atomic_add32 -+ (FAU_NUM_PACKET_BUFFERS_TO_FREE, -1); -+ cvmx_fau_atomic_add32(priv->fau + qos * 4, -1); -+ } -+ } else { -+ /* Put this packet on the queue to be freed later */ -+ skb_queue_tail(&priv->tx_free_list[qos], skb); -+ } -+ } -+ -+ /* Free skbuffs not in use by the hardware, possibly two at a time */ -+ if (skb_queue_len(&priv->tx_free_list[qos]) > in_use) { -+ spin_lock(&priv->tx_free_list[qos].lock); -+ /* -+ * Check again now that we have the lock. It might -+ * have changed. -+ */ -+ if (skb_queue_len(&priv->tx_free_list[qos]) > in_use) -+ dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos])); -+ if (skb_queue_len(&priv->tx_free_list[qos]) > in_use) -+ dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos])); -+ spin_unlock(&priv->tx_free_list[qos].lock); -+ } -+ -+ return 0; -+} -+ -+/** -+ * Packet transmit to the POW -+ * -+ * @skb: Packet to send -+ * @dev: Device info structure -+ * Returns Always returns zero -+ */ -+int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ void *packet_buffer; -+ void *copy_location; -+ -+ /* Get a work queue entry */ -+ cvmx_wqe_t *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL); -+ if (unlikely(work == NULL)) { -+ DEBUGPRINT("%s: Failed to allocate a work queue entry\n", -+ dev->name); -+ priv->stats.tx_dropped++; -+ dev_kfree_skb(skb); -+ return 0; -+ } -+ -+ /* Get a packet buffer */ -+ packet_buffer = cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL); -+ if (unlikely(packet_buffer == NULL)) { -+ DEBUGPRINT("%s: Failed to allocate a packet buffer\n", -+ dev->name); -+ cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1)); -+ priv->stats.tx_dropped++; -+ dev_kfree_skb(skb); -+ return 0; -+ } -+ -+ /* -+ * Calculate where we need to copy the data to. We need to -+ * leave 8 bytes for a next pointer (unused). We also need to -+ * include any configure skip. Then we need to align the IP -+ * packet src and dest into the same 64bit word. The below -+ * calculation may add a little extra, but that doesn't -+ * hurt. -+ */ -+ copy_location = packet_buffer + sizeof(uint64_t); -+ copy_location += ((CVMX_HELPER_FIRST_MBUFF_SKIP + 7) & 0xfff8) + 6; -+ -+ /* -+ * We have to copy the packet since whoever processes this -+ * packet will free it to a hardware pool. We can't use the -+ * trick of counting outstanding packets like in -+ * cvm_oct_xmit. -+ */ -+ memcpy(copy_location, skb->data, skb->len); -+ -+ /* -+ * Fill in some of the work queue fields. We may need to add -+ * more if the software at the other end needs them. -+ */ -+ work->hw_chksum = skb->csum; -+ work->len = skb->len; -+ work->ipprt = priv->port; -+ work->qos = priv->port & 0x7; -+ work->grp = pow_send_group; -+ work->tag_type = CVMX_HELPER_INPUT_TAG_TYPE; -+ work->tag = pow_send_group; /* FIXME */ -+ /* Default to zero. Sets of zero later are commented out */ -+ work->word2.u64 = 0; -+ work->word2.s.bufs = 1; -+ work->packet_ptr.u64 = 0; -+ work->packet_ptr.s.addr = cvmx_ptr_to_phys(copy_location); -+ work->packet_ptr.s.pool = CVMX_FPA_PACKET_POOL; -+ work->packet_ptr.s.size = CVMX_FPA_PACKET_POOL_SIZE; -+ work->packet_ptr.s.back = (copy_location - packet_buffer) >> 7; -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ work->word2.s.ip_offset = 14; -+#if 0 -+ work->word2.s.vlan_valid = 0; /* FIXME */ -+ work->word2.s.vlan_cfi = 0; /* FIXME */ -+ work->word2.s.vlan_id = 0; /* FIXME */ -+ work->word2.s.dec_ipcomp = 0; /* FIXME */ -+#endif -+ work->word2.s.tcp_or_udp = -+ (ip_hdr(skb)->protocol == IP_PROTOCOL_TCP) -+ || (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP); -+#if 0 -+ /* FIXME */ -+ work->word2.s.dec_ipsec = 0; -+ /* We only support IPv4 right now */ -+ work->word2.s.is_v6 = 0; -+ /* Hardware would set to zero */ -+ work->word2.s.software = 0; -+ /* No error, packet is internal */ -+ work->word2.s.L4_error = 0; -+#endif -+ work->word2.s.is_frag = !((ip_hdr(skb)->frag_off == 0) -+ || (ip_hdr(skb)->frag_off == -+ 1 << 14)); -+#if 0 -+ /* Assume Linux is sending a good packet */ -+ work->word2.s.IP_exc = 0; -+#endif -+ work->word2.s.is_bcast = (skb->pkt_type == PACKET_BROADCAST); -+ work->word2.s.is_mcast = (skb->pkt_type == PACKET_MULTICAST); -+#if 0 -+ /* This is an IP packet */ -+ work->word2.s.not_IP = 0; -+ /* No error, packet is internal */ -+ work->word2.s.rcv_error = 0; -+ /* No error, packet is internal */ -+ work->word2.s.err_code = 0; -+#endif -+ -+ /* -+ * When copying the data, include 4 bytes of the -+ * ethernet header to align the same way hardware -+ * does. -+ */ -+ memcpy(work->packet_data, skb->data + 10, -+ sizeof(work->packet_data)); -+ } else { -+#if 0 -+ work->word2.snoip.vlan_valid = 0; /* FIXME */ -+ work->word2.snoip.vlan_cfi = 0; /* FIXME */ -+ work->word2.snoip.vlan_id = 0; /* FIXME */ -+ work->word2.snoip.software = 0; /* Hardware would set to zero */ -+#endif -+ work->word2.snoip.is_rarp = skb->protocol == htons(ETH_P_RARP); -+ work->word2.snoip.is_arp = skb->protocol == htons(ETH_P_ARP); -+ work->word2.snoip.is_bcast = -+ (skb->pkt_type == PACKET_BROADCAST); -+ work->word2.snoip.is_mcast = -+ (skb->pkt_type == PACKET_MULTICAST); -+ work->word2.snoip.not_IP = 1; /* IP was done up above */ -+#if 0 -+ /* No error, packet is internal */ -+ work->word2.snoip.rcv_error = 0; -+ /* No error, packet is internal */ -+ work->word2.snoip.err_code = 0; -+#endif -+ memcpy(work->packet_data, skb->data, sizeof(work->packet_data)); -+ } -+ -+ /* Submit the packet to the POW */ -+ cvmx_pow_work_submit(work, work->tag, work->tag_type, work->qos, -+ work->grp); -+ priv->stats.tx_packets++; -+ priv->stats.tx_bytes += skb->len; -+ dev_kfree_skb(skb); -+ return 0; -+} -+ -+/** -+ * Transmit a work queue entry out of the ethernet port. Both -+ * the work queue entry and the packet data can optionally be -+ * freed. The work will be freed on error as well. -+ * -+ * @dev: Device to transmit out. -+ * @work_queue_entry: -+ * Work queue entry to send -+ * @do_free: True if the work queue entry and packet data should be -+ * freed. If false, neither will be freed. -+ * @qos: Index into the queues for this port to transmit on. This -+ * is used to implement QoS if their are multiple queues per -+ * port. This parameter must be between 0 and the number of -+ * queues per port minus 1. Values outside of this range will -+ * be change to zero. -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry, -+ int do_free, int qos) -+{ -+ unsigned long flags; -+ union cvmx_buf_ptr hw_buffer; -+ cvmx_pko_command_word0_t pko_command; -+ int dropped; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ cvmx_wqe_t *work = work_queue_entry; -+ -+ if (!(dev->flags & IFF_UP)) { -+ DEBUGPRINT("%s: Device not up\n", dev->name); -+ if (do_free) -+ cvm_oct_free_work(work); -+ return -1; -+ } -+ -+ /* The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to completely -+ remove "qos" in the event neither interface supports -+ multiple queues per port */ -+ if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) || -+ (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) { -+ if (qos <= 0) -+ qos = 0; -+ else if (qos >= cvmx_pko_get_num_queues(priv->port)) -+ qos = 0; -+ } else -+ qos = 0; -+ -+ /* Start off assuming no drop */ -+ dropped = 0; -+ -+ local_irq_save(flags); -+ cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos, -+ CVMX_PKO_LOCK_CMD_QUEUE); -+ -+ /* Build the PKO buffer pointer */ -+ hw_buffer.u64 = 0; -+ hw_buffer.s.addr = work->packet_ptr.s.addr; -+ hw_buffer.s.pool = CVMX_FPA_PACKET_POOL; -+ hw_buffer.s.size = CVMX_FPA_PACKET_POOL_SIZE; -+ hw_buffer.s.back = work->packet_ptr.s.back; -+ -+ /* Build the PKO command */ -+ pko_command.u64 = 0; -+ pko_command.s.n2 = 1; /* Don't pollute L2 with the outgoing packet */ -+ pko_command.s.dontfree = !do_free; -+ pko_command.s.segs = work->word2.s.bufs; -+ pko_command.s.total_bytes = work->len; -+ -+ /* Check if we can use the hardware checksumming */ -+ if (unlikely(work->word2.s.not_IP || work->word2.s.IP_exc)) -+ pko_command.s.ipoffp1 = 0; -+ else -+ pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1; -+ -+ /* Send the packet to the output queue */ -+ if (unlikely -+ (cvmx_pko_send_packet_finish -+ (priv->port, priv->queue + qos, pko_command, hw_buffer, -+ CVMX_PKO_LOCK_CMD_QUEUE))) { -+ DEBUGPRINT("%s: Failed to send the packet\n", dev->name); -+ dropped = -1; -+ } -+ local_irq_restore(flags); -+ -+ if (unlikely(dropped)) { -+ if (do_free) -+ cvm_oct_free_work(work); -+ priv->stats.tx_dropped++; -+ } else if (do_free) -+ cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1)); -+ -+ return dropped; -+} -+EXPORT_SYMBOL(cvm_oct_transmit_qos); -+ -+/** -+ * This function frees all skb that are currenty queued for TX. -+ * -+ * @dev: Device being shutdown -+ */ -+void cvm_oct_tx_shutdown(struct net_device *dev) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ unsigned long flags; -+ int qos; -+ -+ for (qos = 0; qos < 16; qos++) { -+ spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags); -+ while (skb_queue_len(&priv->tx_free_list[qos])) -+ dev_kfree_skb_any(__skb_dequeue -+ (&priv->tx_free_list[qos])); -+ spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags); -+ } -+} ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-tx.h -@@ -0,0 +1,32 @@ -+/********************************************************************* -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+*********************************************************************/ -+ -+int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev); -+int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev); -+int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry, -+ int do_free, int qos); -+void cvm_oct_tx_shutdown(struct net_device *dev); ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-util.h -@@ -0,0 +1,81 @@ -+/********************************************************************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+*********************************************************************/ -+ -+#define DEBUGPRINT(format, ...) do { if (printk_ratelimit()) \ -+ printk(format, ##__VA_ARGS__); \ -+ } while (0) -+ -+/** -+ * Given a packet data address, return a pointer to the -+ * beginning of the packet buffer. -+ * -+ * @packet_ptr: Packet data hardware address -+ * Returns Packet buffer pointer -+ */ -+static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr) -+{ -+ return cvmx_phys_to_ptr(((packet_ptr.s.addr >> 7) - packet_ptr.s.back) -+ << 7); -+} -+ -+/** -+ * Given an IPD/PKO port number, return the logical interface it is -+ * on. -+ * -+ * @ipd_port: Port to check -+ * -+ * Returns Logical interface -+ */ -+static inline int INTERFACE(int ipd_port) -+{ -+ if (ipd_port < 32) /* Interface 0 or 1 for RGMII,GMII,SPI, etc */ -+ return ipd_port >> 4; -+ else if (ipd_port < 36) /* Interface 2 for NPI */ -+ return 2; -+ else if (ipd_port < 40) /* Interface 3 for loopback */ -+ return 3; -+ else if (ipd_port == 40) /* Non existant interface for POW0 */ -+ return 4; -+ else -+ panic("Illegal ipd_port %d passed to INTERFACE\n", ipd_port); -+} -+ -+/** -+ * Given an IPD/PKO port number, return the port's index on a -+ * logical interface. -+ * -+ * @ipd_port: Port to check -+ * -+ * Returns Index into interface port list -+ */ -+static inline int INDEX(int ipd_port) -+{ -+ if (ipd_port < 32) -+ return ipd_port & 15; -+ else -+ return ipd_port & 3; -+} ---- /dev/null -+++ b/drivers/staging/octeon/ethernet-xaui.c -@@ -0,0 +1,127 @@ -+/********************************************************************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+**********************************************************************/ -+#include <linux/kernel.h> -+#include <linux/netdevice.h> -+#include <linux/mii.h> -+#include <net/dst.h> -+ -+#include <asm/octeon/octeon.h> -+ -+#include "ethernet-defines.h" -+#include "octeon-ethernet.h" -+#include "ethernet-common.h" -+#include "ethernet-util.h" -+ -+#include "cvmx-helper.h" -+ -+#include "cvmx-gmxx-defs.h" -+ -+static int cvm_oct_xaui_open(struct net_device *dev) -+{ -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ cvmx_helper_link_info_t link_info; -+ -+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ gmx_cfg.s.en = 1; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); -+ -+ if (!octeon_is_simulation()) { -+ link_info = cvmx_helper_link_get(priv->port); -+ if (!link_info.s.link_up) -+ netif_carrier_off(dev); -+ } -+ return 0; -+} -+ -+static int cvm_oct_xaui_stop(struct net_device *dev) -+{ -+ union cvmx_gmxx_prtx_cfg gmx_cfg; -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ int interface = INTERFACE(priv->port); -+ int index = INDEX(priv->port); -+ -+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); -+ gmx_cfg.s.en = 0; -+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); -+ return 0; -+} -+ -+static void cvm_oct_xaui_poll(struct net_device *dev) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ cvmx_helper_link_info_t link_info; -+ -+ link_info = cvmx_helper_link_get(priv->port); -+ if (link_info.u64 == priv->link_info) -+ return; -+ -+ link_info = cvmx_helper_link_autoconf(priv->port); -+ priv->link_info = link_info.u64; -+ -+ /* Tell Linux */ -+ if (link_info.s.link_up) { -+ -+ if (!netif_carrier_ok(dev)) -+ netif_carrier_on(dev); -+ if (priv->queue != -1) -+ DEBUGPRINT -+ ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", -+ dev->name, link_info.s.speed, -+ (link_info.s.full_duplex) ? "Full" : "Half", -+ priv->port, priv->queue); -+ else -+ DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n", -+ dev->name, link_info.s.speed, -+ (link_info.s.full_duplex) ? "Full" : "Half", -+ priv->port); -+ } else { -+ if (netif_carrier_ok(dev)) -+ netif_carrier_off(dev); -+ DEBUGPRINT("%s: Link down\n", dev->name); -+ } -+} -+ -+int cvm_oct_xaui_init(struct net_device *dev) -+{ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ cvm_oct_common_init(dev); -+ dev->open = cvm_oct_xaui_open; -+ dev->stop = cvm_oct_xaui_stop; -+ dev->stop(dev); -+ if (!octeon_is_simulation()) -+ priv->poll = cvm_oct_xaui_poll; -+ -+ return 0; -+} -+ -+void cvm_oct_xaui_uninit(struct net_device *dev) -+{ -+ cvm_oct_common_uninit(dev); -+} ---- /dev/null -+++ b/drivers/staging/octeon/ethernet.c -@@ -0,0 +1,507 @@ -+/********************************************************************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+**********************************************************************/ -+#include <linux/kernel.h> -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/delay.h> -+#include <linux/mii.h> -+ -+#include <net/dst.h> -+ -+#include <asm/octeon/octeon.h> -+ -+#include "ethernet-defines.h" -+#include "ethernet-mem.h" -+#include "ethernet-rx.h" -+#include "ethernet-tx.h" -+#include "ethernet-util.h" -+#include "ethernet-proc.h" -+#include "ethernet-common.h" -+#include "octeon-ethernet.h" -+ -+#include "cvmx-pip.h" -+#include "cvmx-pko.h" -+#include "cvmx-fau.h" -+#include "cvmx-ipd.h" -+#include "cvmx-helper.h" -+ -+#include "cvmx-smix-defs.h" -+ -+#if defined(CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS) \ -+ && CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS -+int num_packet_buffers = CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS; -+#else -+int num_packet_buffers = 1024; -+#endif -+module_param(num_packet_buffers, int, 0444); -+MODULE_PARM_DESC(num_packet_buffers, "\n" -+ "\tNumber of packet buffers to allocate and store in the\n" -+ "\tFPA. By default, 1024 packet buffers are used unless\n" -+ "\tCONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS is defined."); -+ -+int pow_receive_group = 15; -+module_param(pow_receive_group, int, 0444); -+MODULE_PARM_DESC(pow_receive_group, "\n" -+ "\tPOW group to receive packets from. All ethernet hardware\n" -+ "\twill be configured to send incomming packets to this POW\n" -+ "\tgroup. Also any other software can submit packets to this\n" -+ "\tgroup for the kernel to process."); -+ -+int pow_send_group = -1; -+module_param(pow_send_group, int, 0644); -+MODULE_PARM_DESC(pow_send_group, "\n" -+ "\tPOW group to send packets to other software on. This\n" -+ "\tcontrols the creation of the virtual device pow0.\n" -+ "\talways_use_pow also depends on this value."); -+ -+int always_use_pow; -+module_param(always_use_pow, int, 0444); -+MODULE_PARM_DESC(always_use_pow, "\n" -+ "\tWhen set, always send to the pow group. This will cause\n" -+ "\tpackets sent to real ethernet devices to be sent to the\n" -+ "\tPOW group instead of the hardware. Unless some other\n" -+ "\tapplication changes the config, packets will still be\n" -+ "\treceived from the low level hardware. Use this option\n" -+ "\tto allow a CVMX app to intercept all packets from the\n" -+ "\tlinux kernel. You must specify pow_send_group along with\n" -+ "\tthis option."); -+ -+char pow_send_list[128] = ""; -+module_param_string(pow_send_list, pow_send_list, sizeof(pow_send_list), 0444); -+MODULE_PARM_DESC(pow_send_list, "\n" -+ "\tComma separated list of ethernet devices that should use the\n" -+ "\tPOW for transmit instead of the actual ethernet hardware. This\n" -+ "\tis a per port version of always_use_pow. always_use_pow takes\n" -+ "\tprecedence over this list. For example, setting this to\n" -+ "\t\"eth2,spi3,spi7\" would cause these three devices to transmit\n" -+ "\tusing the pow_send_group."); -+ -+static int disable_core_queueing = 1; -+module_param(disable_core_queueing, int, 0444); -+MODULE_PARM_DESC(disable_core_queueing, "\n" -+ "\tWhen set the networking core's tx_queue_len is set to zero. This\n" -+ "\tallows packets to be sent without lock contention in the packet\n" -+ "\tscheduler resulting in some cases in improved throughput.\n"); -+ -+/** -+ * Periodic timer to check auto negotiation -+ */ -+static struct timer_list cvm_oct_poll_timer; -+ -+/** -+ * Array of every ethernet device owned by this driver indexed by -+ * the ipd input port number. -+ */ -+struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS]; -+ -+extern struct semaphore mdio_sem; -+ -+/** -+ * Periodic timer tick for slow management operations -+ * -+ * @arg: Device to check -+ */ -+static void cvm_do_timer(unsigned long arg) -+{ -+ static int port; -+ if (port < CVMX_PIP_NUM_INPUT_PORTS) { -+ if (cvm_oct_device[port]) { -+ int queues_per_port; -+ int qos; -+ struct octeon_ethernet *priv = -+ netdev_priv(cvm_oct_device[port]); -+ if (priv->poll) { -+ /* skip polling if we don't get the lock */ -+ if (!down_trylock(&mdio_sem)) { -+ priv->poll(cvm_oct_device[port]); -+ up(&mdio_sem); -+ } -+ } -+ -+ queues_per_port = cvmx_pko_get_num_queues(port); -+ /* Drain any pending packets in the free list */ -+ for (qos = 0; qos < queues_per_port; qos++) { -+ if (skb_queue_len(&priv->tx_free_list[qos])) { -+ spin_lock(&priv->tx_free_list[qos]. -+ lock); -+ while (skb_queue_len -+ (&priv->tx_free_list[qos]) > -+ cvmx_fau_fetch_and_add32(priv-> -+ fau + -+ qos * 4, -+ 0)) -+ dev_kfree_skb(__skb_dequeue -+ (&priv-> -+ tx_free_list -+ [qos])); -+ spin_unlock(&priv->tx_free_list[qos]. -+ lock); -+ } -+ } -+ cvm_oct_device[port]->get_stats(cvm_oct_device[port]); -+ } -+ port++; -+ /* Poll the next port in a 50th of a second. -+ This spreads the polling of ports out a little bit */ -+ mod_timer(&cvm_oct_poll_timer, jiffies + HZ / 50); -+ } else { -+ port = 0; -+ /* All ports have been polled. Start the next iteration through -+ the ports in one second */ -+ mod_timer(&cvm_oct_poll_timer, jiffies + HZ); -+ } -+} -+ -+/** -+ * Configure common hardware for all interfaces -+ */ -+static __init void cvm_oct_configure_common_hw(void) -+{ -+ int r; -+ /* Setup the FPA */ -+ cvmx_fpa_enable(); -+ cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE, -+ num_packet_buffers); -+ cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE, -+ num_packet_buffers); -+ if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL) -+ cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL, -+ CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128); -+ -+ if (USE_RED) -+ cvmx_helper_setup_red(num_packet_buffers / 4, -+ num_packet_buffers / 8); -+ -+ /* Enable the MII interface */ -+ if (!octeon_is_simulation()) -+ cvmx_write_csr(CVMX_SMIX_EN(0), 1); -+ -+ /* Register an IRQ hander for to receive POW interrupts */ -+ r = request_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group, -+ cvm_oct_do_interrupt, IRQF_SHARED, "Ethernet", -+ cvm_oct_device); -+ -+#if defined(CONFIG_SMP) && 0 -+ if (USE_MULTICORE_RECEIVE) { -+ irq_set_affinity(OCTEON_IRQ_WORKQ0 + pow_receive_group, -+ cpu_online_mask); -+ } -+#endif -+} -+ -+/** -+ * Free a work queue entry received in a intercept callback. -+ * -+ * @work_queue_entry: -+ * Work queue entry to free -+ * Returns Zero on success, Negative on failure. -+ */ -+int cvm_oct_free_work(void *work_queue_entry) -+{ -+ cvmx_wqe_t *work = work_queue_entry; -+ -+ int segments = work->word2.s.bufs; -+ union cvmx_buf_ptr segment_ptr = work->packet_ptr; -+ -+ while (segments--) { -+ union cvmx_buf_ptr next_ptr = *(union cvmx_buf_ptr *) -+ cvmx_phys_to_ptr(segment_ptr.s.addr - 8); -+ if (unlikely(!segment_ptr.s.i)) -+ cvmx_fpa_free(cvm_oct_get_buffer_ptr(segment_ptr), -+ segment_ptr.s.pool, -+ DONT_WRITEBACK(CVMX_FPA_PACKET_POOL_SIZE / -+ 128)); -+ segment_ptr = next_ptr; -+ } -+ cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1)); -+ -+ return 0; -+} -+EXPORT_SYMBOL(cvm_oct_free_work); -+ -+/** -+ * Module/ driver initialization. Creates the linux network -+ * devices. -+ * -+ * Returns Zero on success -+ */ -+static int __init cvm_oct_init_module(void) -+{ -+ int num_interfaces; -+ int interface; -+ int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE; -+ int qos; -+ -+ pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION); -+ -+ cvm_oct_proc_initialize(); -+ cvm_oct_rx_initialize(); -+ cvm_oct_configure_common_hw(); -+ -+ cvmx_helper_initialize_packet_io_global(); -+ -+ /* Change the input group for all ports before input is enabled */ -+ num_interfaces = cvmx_helper_get_number_of_interfaces(); -+ for (interface = 0; interface < num_interfaces; interface++) { -+ int num_ports = cvmx_helper_ports_on_interface(interface); -+ int port; -+ -+ for (port = cvmx_helper_get_ipd_port(interface, 0); -+ port < cvmx_helper_get_ipd_port(interface, num_ports); -+ port++) { -+ union cvmx_pip_prt_tagx pip_prt_tagx; -+ pip_prt_tagx.u64 = -+ cvmx_read_csr(CVMX_PIP_PRT_TAGX(port)); -+ pip_prt_tagx.s.grp = pow_receive_group; -+ cvmx_write_csr(CVMX_PIP_PRT_TAGX(port), -+ pip_prt_tagx.u64); -+ } -+ } -+ -+ cvmx_helper_ipd_and_packet_input_enable(); -+ -+ memset(cvm_oct_device, 0, sizeof(cvm_oct_device)); -+ -+ /* -+ * Initialize the FAU used for counting packet buffers that -+ * need to be freed. -+ */ -+ cvmx_fau_atomic_write32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0); -+ -+ if ((pow_send_group != -1)) { -+ struct net_device *dev; -+ pr_info("\tConfiguring device for POW only access\n"); -+ dev = alloc_etherdev(sizeof(struct octeon_ethernet)); -+ if (dev) { -+ /* Initialize the device private structure. */ -+ struct octeon_ethernet *priv = netdev_priv(dev); -+ memset(priv, 0, sizeof(struct octeon_ethernet)); -+ -+ dev->init = cvm_oct_common_init; -+ priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED; -+ priv->port = CVMX_PIP_NUM_INPUT_PORTS; -+ priv->queue = -1; -+ strcpy(dev->name, "pow%d"); -+ for (qos = 0; qos < 16; qos++) -+ skb_queue_head_init(&priv->tx_free_list[qos]); -+ -+ if (register_netdev(dev) < 0) { -+ pr_err("Failed to register ethernet " -+ "device for POW\n"); -+ kfree(dev); -+ } else { -+ cvm_oct_device[CVMX_PIP_NUM_INPUT_PORTS] = dev; -+ pr_info("%s: POW send group %d, receive " -+ "group %d\n", -+ dev->name, pow_send_group, -+ pow_receive_group); -+ } -+ } else { -+ pr_err("Failed to allocate ethernet device " -+ "for POW\n"); -+ } -+ } -+ -+ num_interfaces = cvmx_helper_get_number_of_interfaces(); -+ for (interface = 0; interface < num_interfaces; interface++) { -+ cvmx_helper_interface_mode_t imode = -+ cvmx_helper_interface_get_mode(interface); -+ int num_ports = cvmx_helper_ports_on_interface(interface); -+ int port; -+ -+ for (port = cvmx_helper_get_ipd_port(interface, 0); -+ port < cvmx_helper_get_ipd_port(interface, num_ports); -+ port++) { -+ struct octeon_ethernet *priv; -+ struct net_device *dev = -+ alloc_etherdev(sizeof(struct octeon_ethernet)); -+ if (!dev) { -+ pr_err("Failed to allocate ethernet device " -+ "for port %d\n", port); -+ continue; -+ } -+ if (disable_core_queueing) -+ dev->tx_queue_len = 0; -+ -+ /* Initialize the device private structure. */ -+ priv = netdev_priv(dev); -+ memset(priv, 0, sizeof(struct octeon_ethernet)); -+ -+ priv->imode = imode; -+ priv->port = port; -+ priv->queue = cvmx_pko_get_base_queue(priv->port); -+ priv->fau = fau - cvmx_pko_get_num_queues(port) * 4; -+ for (qos = 0; qos < 16; qos++) -+ skb_queue_head_init(&priv->tx_free_list[qos]); -+ for (qos = 0; qos < cvmx_pko_get_num_queues(port); -+ qos++) -+ cvmx_fau_atomic_write32(priv->fau + qos * 4, 0); -+ -+ switch (priv->imode) { -+ -+ /* These types don't support ports to IPD/PKO */ -+ case CVMX_HELPER_INTERFACE_MODE_DISABLED: -+ case CVMX_HELPER_INTERFACE_MODE_PCIE: -+ case CVMX_HELPER_INTERFACE_MODE_PICMG: -+ break; -+ -+ case CVMX_HELPER_INTERFACE_MODE_NPI: -+ dev->init = cvm_oct_common_init; -+ dev->uninit = cvm_oct_common_uninit; -+ strcpy(dev->name, "npi%d"); -+ break; -+ -+ case CVMX_HELPER_INTERFACE_MODE_XAUI: -+ dev->init = cvm_oct_xaui_init; -+ dev->uninit = cvm_oct_xaui_uninit; -+ strcpy(dev->name, "xaui%d"); -+ break; -+ -+ case CVMX_HELPER_INTERFACE_MODE_LOOP: -+ dev->init = cvm_oct_common_init; -+ dev->uninit = cvm_oct_common_uninit; -+ strcpy(dev->name, "loop%d"); -+ break; -+ -+ case CVMX_HELPER_INTERFACE_MODE_SGMII: -+ dev->init = cvm_oct_sgmii_init; -+ dev->uninit = cvm_oct_sgmii_uninit; -+ strcpy(dev->name, "eth%d"); -+ break; -+ -+ case CVMX_HELPER_INTERFACE_MODE_SPI: -+ dev->init = cvm_oct_spi_init; -+ dev->uninit = cvm_oct_spi_uninit; -+ strcpy(dev->name, "spi%d"); -+ break; -+ -+ case CVMX_HELPER_INTERFACE_MODE_RGMII: -+ case CVMX_HELPER_INTERFACE_MODE_GMII: -+ dev->init = cvm_oct_rgmii_init; -+ dev->uninit = cvm_oct_rgmii_uninit; -+ strcpy(dev->name, "eth%d"); -+ break; -+ } -+ -+ if (!dev->init) { -+ kfree(dev); -+ } else if (register_netdev(dev) < 0) { -+ pr_err("Failed to register ethernet device " -+ "for interface %d, port %d\n", -+ interface, priv->port); -+ kfree(dev); -+ } else { -+ cvm_oct_device[priv->port] = dev; -+ fau -= -+ cvmx_pko_get_num_queues(priv->port) * -+ sizeof(uint32_t); -+ } -+ } -+ } -+ -+ if (INTERRUPT_LIMIT) { -+ /* -+ * Set the POW timer rate to give an interrupt at most -+ * INTERRUPT_LIMIT times per second. -+ */ -+ cvmx_write_csr(CVMX_POW_WQ_INT_PC, -+ octeon_bootinfo->eclock_hz / (INTERRUPT_LIMIT * -+ 16 * 256) << 8); -+ -+ /* -+ * Enable POW timer interrupt. It will count when -+ * there are packets available. -+ */ -+ cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), -+ 0x1ful << 24); -+ } else { -+ /* Enable POW interrupt when our port has at least one packet */ -+ cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0x1001); -+ } -+ -+ /* Enable the poll timer for checking RGMII status */ -+ init_timer(&cvm_oct_poll_timer); -+ cvm_oct_poll_timer.data = 0; -+ cvm_oct_poll_timer.function = cvm_do_timer; -+ mod_timer(&cvm_oct_poll_timer, jiffies + HZ); -+ -+ return 0; -+} -+ -+/** -+ * Module / driver shutdown -+ * -+ * Returns Zero on success -+ */ -+static void __exit cvm_oct_cleanup_module(void) -+{ -+ int port; -+ -+ /* Disable POW interrupt */ -+ cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0); -+ -+ cvmx_ipd_disable(); -+ -+ /* Free the interrupt handler */ -+ free_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group, cvm_oct_device); -+ -+ del_timer(&cvm_oct_poll_timer); -+ cvm_oct_rx_shutdown(); -+ cvmx_pko_disable(); -+ -+ /* Free the ethernet devices */ -+ for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) { -+ if (cvm_oct_device[port]) { -+ cvm_oct_tx_shutdown(cvm_oct_device[port]); -+ unregister_netdev(cvm_oct_device[port]); -+ kfree(cvm_oct_device[port]); -+ cvm_oct_device[port] = NULL; -+ } -+ } -+ -+ cvmx_pko_shutdown(); -+ cvm_oct_proc_shutdown(); -+ -+ cvmx_ipd_free_ptr(); -+ -+ /* Free the HW pools */ -+ cvm_oct_mem_empty_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE, -+ num_packet_buffers); -+ cvm_oct_mem_empty_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE, -+ num_packet_buffers); -+ if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL) -+ cvm_oct_mem_empty_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL, -+ CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128); -+} -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>"); -+MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver."); -+module_init(cvm_oct_init_module); -+module_exit(cvm_oct_cleanup_module); ---- /dev/null -+++ b/drivers/staging/octeon/octeon-ethernet.h -@@ -0,0 +1,127 @@ -+/********************************************************************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2007 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+**********************************************************************/ -+ -+/* -+ * External interface for the Cavium Octeon ethernet driver. -+ */ -+#ifndef OCTEON_ETHERNET_H -+#define OCTEON_ETHERNET_H -+ -+/** -+ * This is the definition of the Ethernet driver's private -+ * driver state stored in netdev_priv(dev). -+ */ -+struct octeon_ethernet { -+ /* PKO hardware output port */ -+ int port; -+ /* PKO hardware queue for the port */ -+ int queue; -+ /* Hardware fetch and add to count outstanding tx buffers */ -+ int fau; -+ /* -+ * Type of port. This is one of the enums in -+ * cvmx_helper_interface_mode_t -+ */ -+ int imode; -+ /* List of outstanding tx buffers per queue */ -+ struct sk_buff_head tx_free_list[16]; -+ /* Device statistics */ -+ struct net_device_stats stats -+; /* Generic MII info structure */ -+ struct mii_if_info mii_info; -+ /* Last negotiated link state */ -+ uint64_t link_info; -+ /* Called periodically to check link status */ -+ void (*poll) (struct net_device *dev); -+}; -+ -+/** -+ * Free a work queue entry received in a intercept callback. -+ * -+ * @work_queue_entry: -+ * Work queue entry to free -+ * Returns Zero on success, Negative on failure. -+ */ -+int cvm_oct_free_work(void *work_queue_entry); -+ -+/** -+ * Transmit a work queue entry out of the ethernet port. Both -+ * the work queue entry and the packet data can optionally be -+ * freed. The work will be freed on error as well. -+ * -+ * @dev: Device to transmit out. -+ * @work_queue_entry: -+ * Work queue entry to send -+ * @do_free: True if the work queue entry and packet data should be -+ * freed. If false, neither will be freed. -+ * @qos: Index into the queues for this port to transmit on. This -+ * is used to implement QoS if their are multiple queues per -+ * port. This parameter must be between 0 and the number of -+ * queues per port minus 1. Values outside of this range will -+ * be change to zero. -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry, -+ int do_free, int qos); -+ -+/** -+ * Transmit a work queue entry out of the ethernet port. Both -+ * the work queue entry and the packet data can optionally be -+ * freed. The work will be freed on error as well. This simply -+ * wraps cvmx_oct_transmit_qos() for backwards compatability. -+ * -+ * @dev: Device to transmit out. -+ * @work_queue_entry: -+ * Work queue entry to send -+ * @do_free: True if the work queue entry and packet data should be -+ * freed. If false, neither will be freed. -+ * -+ * Returns Zero on success, negative on failure. -+ */ -+static inline int cvm_oct_transmit(struct net_device *dev, -+ void *work_queue_entry, int do_free) -+{ -+ return cvm_oct_transmit_qos(dev, work_queue_entry, do_free, 0); -+} -+ -+extern int cvm_oct_rgmii_init(struct net_device *dev); -+extern void cvm_oct_rgmii_uninit(struct net_device *dev); -+extern int cvm_oct_sgmii_init(struct net_device *dev); -+extern void cvm_oct_sgmii_uninit(struct net_device *dev); -+extern int cvm_oct_spi_init(struct net_device *dev); -+extern void cvm_oct_spi_uninit(struct net_device *dev); -+extern int cvm_oct_xaui_init(struct net_device *dev); -+extern void cvm_oct_xaui_uninit(struct net_device *dev); -+ -+extern int always_use_pow; -+extern int pow_send_group; -+extern int pow_receive_group; -+extern char pow_send_list[]; -+extern struct net_device *cvm_oct_device[]; -+ -+#endif diff --git a/target/linux/octeon/patches-2.6.30/012-hook_up_eth_driver.patch b/target/linux/octeon/patches-2.6.30/012-hook_up_eth_driver.patch deleted file mode 100644 index 1a9dc00649..0000000000 --- a/target/linux/octeon/patches-2.6.30/012-hook_up_eth_driver.patch +++ /dev/null @@ -1,26 +0,0 @@ -The previous patch adds the driver files for octeon-ethernet. Here we -hook them up into the main kernel build system. - -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - drivers/staging/Kconfig | 2 ++ - drivers/staging/Makefile | 1 + - 2 files changed, 3 insertions(+), 0 deletions(-) - ---- a/drivers/staging/Kconfig -+++ b/drivers/staging/Kconfig -@@ -115,5 +115,7 @@ source "drivers/staging/line6/Kconfig" - - source "drivers/staging/serqt_usb/Kconfig" - -+source "drivers/staging/octeon/Kconfig" -+ - endif # !STAGING_EXCLUDE_BUILD - endif # STAGING ---- a/drivers/staging/Makefile -+++ b/drivers/staging/Makefile -@@ -40,3 +40,4 @@ obj-$(CONFIG_PLAN9AUTH) += p9auth/ - obj-$(CONFIG_HECI) += heci/ - obj-$(CONFIG_LINE6_USB) += line6/ - obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100) += serqt_usb/ -+obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ diff --git a/target/linux/octeon/patches-2.6.30/013-compile_fixes.patch b/target/linux/octeon/patches-2.6.30/013-compile_fixes.patch deleted file mode 100644 index 89338f4e8f..0000000000 --- a/target/linux/octeon/patches-2.6.30/013-compile_fixes.patch +++ /dev/null @@ -1,85 +0,0 @@ ---- a/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c -+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c -@@ -272,6 +272,7 @@ fix_ipd_exit: - * - * Returns Zero on success, negative on failure - */ -+#if 0 - int __cvmx_helper_errata_asx_pass1(int interface, int port, int cpu_clock_hz) - { - /* Set hi water mark as per errata GMX-4 */ -@@ -289,6 +290,7 @@ int __cvmx_helper_errata_asx_pass1(int i - cpu_clock_hz); - return 0; - } -+#endif - - /** - * This function needs to be called on all Octeon chips with ---- a/arch/mips/include/asm/octeon/cvmx-helper-errata.h -+++ b/arch/mips/include/asm/octeon/cvmx-helper-errata.h -@@ -60,8 +60,8 @@ extern int __cvmx_helper_errata_fix_ipd_ - * - * Returns Zero on success, negative on failure - */ --extern int __cvmx_helper_errata_asx_pass1(int interface, int port, -- int cpu_clock_hz); -+//extern int __cvmx_helper_errata_asx_pass1(int interface, int port, -+// int cpu_clock_hz); - - /** - * This function needs to be called on all Octeon chips with ---- a/arch/mips/cavium-octeon/executive/cvmx-helper-util.c -+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-util.c -@@ -356,6 +356,7 @@ int cvmx_helper_get_ipd_port(int interfa - * - * Returns Interface number - */ -+#if 0 - int cvmx_helper_get_interface_num(int ipd_port) - { - if (ipd_port < 16) -@@ -372,6 +373,7 @@ int cvmx_helper_get_interface_num(int ip - - return -1; - } -+#endif - - /** - * Returns the interface index number for an IPD/PKO port -@@ -381,6 +383,7 @@ int cvmx_helper_get_interface_num(int ip - * - * Returns Interface index number - */ -+#if 0 - int cvmx_helper_get_interface_index_num(int ipd_port) - { - if (ipd_port < 32) -@@ -395,6 +398,7 @@ int cvmx_helper_get_interface_index_num( - - return -1; - } -+#endif - - /** - * Initialize the internal QLM JTAG logic to allow programming ---- a/arch/mips/include/asm/octeon/cvmx-helper-util.h -+++ b/arch/mips/include/asm/octeon/cvmx-helper-util.h -@@ -205,7 +205,7 @@ static inline void cvmx_helper_free_pack - * - * Returns Interface number - */ --extern int cvmx_helper_get_interface_num(int ipd_port); -+//extern int cvmx_helper_get_interface_num(int ipd_port); - - /** - * Returns the interface index number for an IPD/PKO port -@@ -215,7 +215,7 @@ extern int cvmx_helper_get_interface_num - * - * Returns Interface index number - */ --extern int cvmx_helper_get_interface_index_num(int ipd_port); -+//extern int cvmx_helper_get_interface_index_num(int ipd_port); - - /** - * Initialize the internal QLM JTAG logic to allow programming diff --git a/target/linux/octeon/patches-2.6.30/015-no_werror.patch b/target/linux/octeon/patches-2.6.30/015-no_werror.patch deleted file mode 100644 index 71842dd1aa..0000000000 --- a/target/linux/octeon/patches-2.6.30/015-no_werror.patch +++ /dev/null @@ -1,8 +0,0 @@ ---- a/arch/mips/cavium-octeon/Makefile -+++ b/arch/mips/cavium-octeon/Makefile -@@ -18,5 +18,3 @@ obj-$(CONFIG_PCI) += - obj-$(CONFIG_PCI) += pci.o - obj-$(CONFIG_PCI) += pcie.o - obj-$(CONFIG_PCI_MSI) += msi.o -- --EXTRA_CFLAGS += -Werror diff --git a/target/linux/octeon/patches-2.6.30/016-octeon_hw_rng.patch b/target/linux/octeon/patches-2.6.30/016-octeon_hw_rng.patch deleted file mode 100644 index 65afe7705a..0000000000 --- a/target/linux/octeon/patches-2.6.30/016-octeon_hw_rng.patch +++ /dev/null @@ -1,351 +0,0 @@ -From: David Daney <ddaney@caviumnetworks.com> -Date: Thu, 20 Aug 2009 21:10:22 +0000 (-0700) -Subject: MIPS: Octeon: Add hardware RNG platform device. -X-Git-Tag: linux-2.6.32-rc1~34 -X-Git-Url: http://www.linux-mips.org/git?p=linux.git;a=commitdiff_plain;h=c691b963;hp=a68577bc6ce2b5e422cdb7a993b1c07cc410e02a - -MIPS: Octeon: Add hardware RNG platform device. - -Add a platform device for the Octeon Random Number Generator (RNG). - -Signed-off-by: David Daney <ddaney@caviumnetworks.com> -Acked-by: Herbert Xu <herbert@gondor.apana.org.au> -Signed-off-by: Ralf Baechle <ralf@linux-mips.org> ---- - -Index: linux-2.6.30.8/arch/mips/cavium-octeon/setup.c -=================================================================== ---- linux-2.6.30.8.orig/arch/mips/cavium-octeon/setup.c 2009-09-24 17:28:02.000000000 +0200 -+++ linux-2.6.30.8/arch/mips/cavium-octeon/setup.c 2009-10-08 13:10:09.000000000 +0200 -@@ -32,6 +32,7 @@ - #include <asm/time.h> - - #include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-rnm-defs.h> - - #ifdef CONFIG_CAVIUM_DECODE_RSL - extern void cvmx_interrupt_rsl_decode(void); -@@ -925,3 +926,45 @@ - return ret; - } - device_initcall(octeon_cf_device_init); -+ -+/* Octeon Random Number Generator. */ -+static int __init octeon_rng_device_init(void) -+{ -+ struct platform_device *pd; -+ int ret = 0; -+ -+ struct resource rng_resources[] = { -+ { -+ .flags = IORESOURCE_MEM, -+ .start = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS), -+ .end = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS) + 0xf -+ }, { -+ .flags = IORESOURCE_MEM, -+ .start = cvmx_build_io_address(8, 0), -+ .end = cvmx_build_io_address(8, 0) + 0x7 -+ } -+ }; -+ -+ pd = platform_device_alloc("octeon_rng", -1); -+ if (!pd) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ ret = platform_device_add_resources(pd, rng_resources, -+ ARRAY_SIZE(rng_resources)); -+ if (ret) -+ goto fail; -+ -+ ret = platform_device_add(pd); -+ if (ret) -+ goto fail; -+ -+ return ret; -+fail: -+ platform_device_put(pd); -+ -+out: -+ return ret; -+} -+device_initcall(octeon_rng_device_init); -Index: linux-2.6.30.8/arch/mips/include/asm/octeon/cvmx-rnm-defs.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.30.8/arch/mips/include/asm/octeon/cvmx-rnm-defs.h 2009-10-08 13:10:09.000000000 +0200 -@@ -0,0 +1,88 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_RNM_DEFS_H__ -+#define __CVMX_RNM_DEFS_H__ -+ -+#include <linux/types.h> -+ -+#define CVMX_RNM_BIST_STATUS \ -+ CVMX_ADD_IO_SEG(0x0001180040000008ull) -+#define CVMX_RNM_CTL_STATUS \ -+ CVMX_ADD_IO_SEG(0x0001180040000000ull) -+ -+union cvmx_rnm_bist_status { -+ uint64_t u64; -+ struct cvmx_rnm_bist_status_s { -+ uint64_t reserved_2_63:62; -+ uint64_t rrc:1; -+ uint64_t mem:1; -+ } s; -+ struct cvmx_rnm_bist_status_s cn30xx; -+ struct cvmx_rnm_bist_status_s cn31xx; -+ struct cvmx_rnm_bist_status_s cn38xx; -+ struct cvmx_rnm_bist_status_s cn38xxp2; -+ struct cvmx_rnm_bist_status_s cn50xx; -+ struct cvmx_rnm_bist_status_s cn52xx; -+ struct cvmx_rnm_bist_status_s cn52xxp1; -+ struct cvmx_rnm_bist_status_s cn56xx; -+ struct cvmx_rnm_bist_status_s cn56xxp1; -+ struct cvmx_rnm_bist_status_s cn58xx; -+ struct cvmx_rnm_bist_status_s cn58xxp1; -+}; -+ -+union cvmx_rnm_ctl_status { -+ uint64_t u64; -+ struct cvmx_rnm_ctl_status_s { -+ uint64_t reserved_9_63:55; -+ uint64_t ent_sel:4; -+ uint64_t exp_ent:1; -+ uint64_t rng_rst:1; -+ uint64_t rnm_rst:1; -+ uint64_t rng_en:1; -+ uint64_t ent_en:1; -+ } s; -+ struct cvmx_rnm_ctl_status_cn30xx { -+ uint64_t reserved_4_63:60; -+ uint64_t rng_rst:1; -+ uint64_t rnm_rst:1; -+ uint64_t rng_en:1; -+ uint64_t ent_en:1; -+ } cn30xx; -+ struct cvmx_rnm_ctl_status_cn30xx cn31xx; -+ struct cvmx_rnm_ctl_status_cn30xx cn38xx; -+ struct cvmx_rnm_ctl_status_cn30xx cn38xxp2; -+ struct cvmx_rnm_ctl_status_s cn50xx; -+ struct cvmx_rnm_ctl_status_s cn52xx; -+ struct cvmx_rnm_ctl_status_s cn52xxp1; -+ struct cvmx_rnm_ctl_status_s cn56xx; -+ struct cvmx_rnm_ctl_status_s cn56xxp1; -+ struct cvmx_rnm_ctl_status_s cn58xx; -+ struct cvmx_rnm_ctl_status_s cn58xxp1; -+}; -+ -+#endif -Index: linux-2.6.30.8/drivers/char/hw_random/Kconfig -=================================================================== ---- linux-2.6.30.8.orig/drivers/char/hw_random/Kconfig 2009-09-24 17:28:02.000000000 +0200 -+++ linux-2.6.30.8/drivers/char/hw_random/Kconfig 2009-10-08 13:10:09.000000000 +0200 -@@ -126,6 +126,19 @@ - - If unsure, say Y. - -+config HW_RANDOM_OCTEON -+ tristate "Octeon Random Number Generator support" -+ depends on HW_RANDOM && CPU_CAVIUM_OCTEON -+ default HW_RANDOM -+ ---help--- -+ This driver provides kernel-side support for the Random Number -+ Generator hardware found on Octeon processors. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called octeon-rng. -+ -+ If unsure, say Y. -+ - config HW_RANDOM_PASEMI - tristate "PA Semi HW Random Number Generator support" - depends on HW_RANDOM && PPC_PASEMI -Index: linux-2.6.30.8/drivers/char/hw_random/Makefile -=================================================================== ---- linux-2.6.30.8.orig/drivers/char/hw_random/Makefile 2009-09-24 17:28:02.000000000 +0200 -+++ linux-2.6.30.8/drivers/char/hw_random/Makefile 2009-10-08 13:10:23.000000000 +0200 -@@ -15,3 +15,4 @@ - obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o - obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o - obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o -+obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o -Index: linux-2.6.30.8/drivers/char/hw_random/octeon-rng.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.30.8/drivers/char/hw_random/octeon-rng.c 2009-10-08 13:10:09.000000000 +0200 -@@ -0,0 +1,147 @@ -+/* -+ * Hardware Random Number Generator support for Cavium Networks -+ * Octeon processor family. -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2009 Cavium Networks -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/platform_device.h> -+#include <linux/device.h> -+#include <linux/hw_random.h> -+#include <linux/io.h> -+ -+#include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-rnm-defs.h> -+ -+struct octeon_rng { -+ struct hwrng ops; -+ void __iomem *control_status; -+ void __iomem *result; -+}; -+ -+static int octeon_rng_init(struct hwrng *rng) -+{ -+ union cvmx_rnm_ctl_status ctl; -+ struct octeon_rng *p = container_of(rng, struct octeon_rng, ops); -+ -+ ctl.u64 = 0; -+ ctl.s.ent_en = 1; /* Enable the entropy source. */ -+ ctl.s.rng_en = 1; /* Enable the RNG hardware. */ -+ cvmx_write_csr((u64)p->control_status, ctl.u64); -+ return 0; -+} -+ -+static void octeon_rng_cleanup(struct hwrng *rng) -+{ -+ union cvmx_rnm_ctl_status ctl; -+ struct octeon_rng *p = container_of(rng, struct octeon_rng, ops); -+ -+ ctl.u64 = 0; -+ /* Disable everything. */ -+ cvmx_write_csr((u64)p->control_status, ctl.u64); -+} -+ -+static int octeon_rng_data_read(struct hwrng *rng, u32 *data) -+{ -+ struct octeon_rng *p = container_of(rng, struct octeon_rng, ops); -+ -+ *data = cvmx_read64_uint32((u64)p->result); -+ return sizeof(u32); -+} -+ -+static int __devinit octeon_rng_probe(struct platform_device *pdev) -+{ -+ struct resource *res_ports; -+ struct resource *res_result; -+ struct octeon_rng *rng; -+ int ret; -+ struct hwrng ops = { -+ .name = "octeon", -+ .init = octeon_rng_init, -+ .cleanup = octeon_rng_cleanup, -+ .data_read = octeon_rng_data_read -+ }; -+ -+ rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL); -+ if (!rng) -+ return -ENOMEM; -+ -+ res_ports = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res_ports) -+ goto err_ports; -+ -+ res_result = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (!res_result) -+ goto err_ports; -+ -+ -+ rng->control_status = devm_ioremap_nocache(&pdev->dev, -+ res_ports->start, -+ sizeof(u64)); -+ if (!rng->control_status) -+ goto err_ports; -+ -+ rng->result = devm_ioremap_nocache(&pdev->dev, -+ res_result->start, -+ sizeof(u64)); -+ if (!rng->result) -+ goto err_r; -+ -+ rng->ops = ops; -+ -+ dev_set_drvdata(&pdev->dev, &rng->ops); -+ ret = hwrng_register(&rng->ops); -+ if (ret) -+ goto err; -+ -+ dev_info(&pdev->dev, "Octeon Random Number Generator\n"); -+ -+ return 0; -+err: -+ devm_iounmap(&pdev->dev, rng->control_status); -+err_r: -+ devm_iounmap(&pdev->dev, rng->result); -+err_ports: -+ devm_kfree(&pdev->dev, rng); -+ return -ENOENT; -+} -+ -+static int __exit octeon_rng_remove(struct platform_device *pdev) -+{ -+ struct hwrng *rng = dev_get_drvdata(&pdev->dev); -+ -+ hwrng_unregister(rng); -+ -+ return 0; -+} -+ -+static struct platform_driver octeon_rng_driver = { -+ .driver = { -+ .name = "octeon_rng", -+ .owner = THIS_MODULE, -+ }, -+ .probe = octeon_rng_probe, -+ .remove = __exit_p(octeon_rng_remove), -+}; -+ -+static int __init octeon_rng_mod_init(void) -+{ -+ return platform_driver_register(&octeon_rng_driver); -+} -+ -+static void __exit octeon_rng_mod_exit(void) -+{ -+ platform_driver_unregister(&octeon_rng_driver); -+} -+ -+module_init(octeon_rng_mod_init); -+module_exit(octeon_rng_mod_exit); -+ -+MODULE_AUTHOR("David Daney"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/octeon/patches-2.6.30/017-platform_devices.patch b/target/linux/octeon/patches-2.6.30/017-platform_devices.patch deleted file mode 100644 index 12c2ef181f..0000000000 --- a/target/linux/octeon/patches-2.6.30/017-platform_devices.patch +++ /dev/null @@ -1,371 +0,0 @@ -From: David Daney <ddaney@caviumnetworks.com> -Date: Wed, 16 Sep 2009 21:54:18 +0000 (-0700) -Subject: MIPS: Octeon: Move some platform device registration to its own file. -X-Git-Tag: linux-2.6.32-rc1~29 -X-Git-Url: http://www.linux-mips.org/git?p=linux.git;a=commitdiff_plain;h=936c111e;hp=e1302af3482d3955f5a6100160e595e792d5f1e4 - -MIPS: Octeon: Move some platform device registration to its own file. - -There is a bunch of platform device registration in -arch/mips/cavium-octeon/setup.c. We move it to its own file in -preparation for adding more platform devices. - -Signed-off-by: David Daney <ddaney@caviumnetworks.com> -Signed-off-by: Ralf Baechle <ralf@linux-mips.org> ---- - -diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile -index d6903c3..1394362 100644 ---- a/arch/mips/cavium-octeon/Makefile -+++ b/arch/mips/cavium-octeon/Makefile -@@ -6,10 +6,10 @@ - # License. See the file "COPYING" in the main directory of this archive - # for more details. - # --# Copyright (C) 2005-2008 Cavium Networks -+# Copyright (C) 2005-2009 Cavium Networks - # - --obj-y := setup.o serial.o octeon-irq.o csrc-octeon.o -+obj-y := setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o - obj-y += dma-octeon.o flash_setup.o - obj-y += octeon-memcpy.o - -diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c -new file mode 100644 -index 0000000..be711dd ---- /dev/null -+++ b/arch/mips/cavium-octeon/octeon-platform.c -@@ -0,0 +1,164 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2004-2009 Cavium Networks -+ * Copyright (C) 2008 Wind River Systems -+ */ -+ -+#include <linux/init.h> -+#include <linux/irq.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+ -+#include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-rnm-defs.h> -+ -+static struct octeon_cf_data octeon_cf_data; -+ -+static int __init octeon_cf_device_init(void) -+{ -+ union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg; -+ unsigned long base_ptr, region_base, region_size; -+ struct platform_device *pd; -+ struct resource cf_resources[3]; -+ unsigned int num_resources; -+ int i; -+ int ret = 0; -+ -+ /* Setup octeon-cf platform device if present. */ -+ base_ptr = 0; -+ if (octeon_bootinfo->major_version == 1 -+ && octeon_bootinfo->minor_version >= 1) { -+ if (octeon_bootinfo->compact_flash_common_base_addr) -+ base_ptr = -+ octeon_bootinfo->compact_flash_common_base_addr; -+ } else { -+ base_ptr = 0x1d000800; -+ } -+ -+ if (!base_ptr) -+ return ret; -+ -+ /* Find CS0 region. */ -+ for (i = 0; i < 8; i++) { -+ mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i)); -+ region_base = mio_boot_reg_cfg.s.base << 16; -+ region_size = (mio_boot_reg_cfg.s.size + 1) << 16; -+ if (mio_boot_reg_cfg.s.en && base_ptr >= region_base -+ && base_ptr < region_base + region_size) -+ break; -+ } -+ if (i >= 7) { -+ /* i and i + 1 are CS0 and CS1, both must be less than 8. */ -+ goto out; -+ } -+ octeon_cf_data.base_region = i; -+ octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width; -+ octeon_cf_data.base_region_bias = base_ptr - region_base; -+ memset(cf_resources, 0, sizeof(cf_resources)); -+ num_resources = 0; -+ cf_resources[num_resources].flags = IORESOURCE_MEM; -+ cf_resources[num_resources].start = region_base; -+ cf_resources[num_resources].end = region_base + region_size - 1; -+ num_resources++; -+ -+ -+ if (!(base_ptr & 0xfffful)) { -+ /* -+ * Boot loader signals availability of DMA (true_ide -+ * mode) by setting low order bits of base_ptr to -+ * zero. -+ */ -+ -+ /* Asume that CS1 immediately follows. */ -+ mio_boot_reg_cfg.u64 = -+ cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1)); -+ region_base = mio_boot_reg_cfg.s.base << 16; -+ region_size = (mio_boot_reg_cfg.s.size + 1) << 16; -+ if (!mio_boot_reg_cfg.s.en) -+ goto out; -+ -+ cf_resources[num_resources].flags = IORESOURCE_MEM; -+ cf_resources[num_resources].start = region_base; -+ cf_resources[num_resources].end = region_base + region_size - 1; -+ num_resources++; -+ -+ octeon_cf_data.dma_engine = 0; -+ cf_resources[num_resources].flags = IORESOURCE_IRQ; -+ cf_resources[num_resources].start = OCTEON_IRQ_BOOTDMA; -+ cf_resources[num_resources].end = OCTEON_IRQ_BOOTDMA; -+ num_resources++; -+ } else { -+ octeon_cf_data.dma_engine = -1; -+ } -+ -+ pd = platform_device_alloc("pata_octeon_cf", -1); -+ if (!pd) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ pd->dev.platform_data = &octeon_cf_data; -+ -+ ret = platform_device_add_resources(pd, cf_resources, num_resources); -+ if (ret) -+ goto fail; -+ -+ ret = platform_device_add(pd); -+ if (ret) -+ goto fail; -+ -+ return ret; -+fail: -+ platform_device_put(pd); -+out: -+ return ret; -+} -+device_initcall(octeon_cf_device_init); -+ -+/* Octeon Random Number Generator. */ -+static int __init octeon_rng_device_init(void) -+{ -+ struct platform_device *pd; -+ int ret = 0; -+ -+ struct resource rng_resources[] = { -+ { -+ .flags = IORESOURCE_MEM, -+ .start = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS), -+ .end = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS) + 0xf -+ }, { -+ .flags = IORESOURCE_MEM, -+ .start = cvmx_build_io_address(8, 0), -+ .end = cvmx_build_io_address(8, 0) + 0x7 -+ } -+ }; -+ -+ pd = platform_device_alloc("octeon_rng", -1); -+ if (!pd) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ ret = platform_device_add_resources(pd, rng_resources, -+ ARRAY_SIZE(rng_resources)); -+ if (ret) -+ goto fail; -+ -+ ret = platform_device_add(pd); -+ if (ret) -+ goto fail; -+ -+ return ret; -+fail: -+ platform_device_put(pd); -+ -+out: -+ return ret; -+} -+device_initcall(octeon_rng_device_init); -+ -+MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Platform driver for Octeon SOC"); -diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c -index 468a120..b321d3b 100644 ---- a/arch/mips/cavium-octeon/setup.c -+++ b/arch/mips/cavium-octeon/setup.c -@@ -11,7 +11,6 @@ - #include <linux/delay.h> - #include <linux/interrupt.h> - #include <linux/io.h> --#include <linux/irq.h> - #include <linux/serial.h> - #include <linux/smp.h> - #include <linux/types.h> -@@ -33,7 +32,6 @@ - #include <asm/time.h> - - #include <asm/octeon/octeon.h> --#include <asm/octeon/cvmx-rnm-defs.h> - - #ifdef CONFIG_CAVIUM_DECODE_RSL - extern void cvmx_interrupt_rsl_decode(void); -@@ -825,147 +823,3 @@ void prom_free_prom_memory(void) - CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */ - octeon_hal_setup_reserved32(); - } -- --static struct octeon_cf_data octeon_cf_data; -- --static int __init octeon_cf_device_init(void) --{ -- union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg; -- unsigned long base_ptr, region_base, region_size; -- struct platform_device *pd; -- struct resource cf_resources[3]; -- unsigned int num_resources; -- int i; -- int ret = 0; -- -- /* Setup octeon-cf platform device if present. */ -- base_ptr = 0; -- if (octeon_bootinfo->major_version == 1 -- && octeon_bootinfo->minor_version >= 1) { -- if (octeon_bootinfo->compact_flash_common_base_addr) -- base_ptr = -- octeon_bootinfo->compact_flash_common_base_addr; -- } else { -- base_ptr = 0x1d000800; -- } -- -- if (!base_ptr) -- return ret; -- -- /* Find CS0 region. */ -- for (i = 0; i < 8; i++) { -- mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i)); -- region_base = mio_boot_reg_cfg.s.base << 16; -- region_size = (mio_boot_reg_cfg.s.size + 1) << 16; -- if (mio_boot_reg_cfg.s.en && base_ptr >= region_base -- && base_ptr < region_base + region_size) -- break; -- } -- if (i >= 7) { -- /* i and i + 1 are CS0 and CS1, both must be less than 8. */ -- goto out; -- } -- octeon_cf_data.base_region = i; -- octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width; -- octeon_cf_data.base_region_bias = base_ptr - region_base; -- memset(cf_resources, 0, sizeof(cf_resources)); -- num_resources = 0; -- cf_resources[num_resources].flags = IORESOURCE_MEM; -- cf_resources[num_resources].start = region_base; -- cf_resources[num_resources].end = region_base + region_size - 1; -- num_resources++; -- -- -- if (!(base_ptr & 0xfffful)) { -- /* -- * Boot loader signals availability of DMA (true_ide -- * mode) by setting low order bits of base_ptr to -- * zero. -- */ -- -- /* Asume that CS1 immediately follows. */ -- mio_boot_reg_cfg.u64 = -- cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1)); -- region_base = mio_boot_reg_cfg.s.base << 16; -- region_size = (mio_boot_reg_cfg.s.size + 1) << 16; -- if (!mio_boot_reg_cfg.s.en) -- goto out; -- -- cf_resources[num_resources].flags = IORESOURCE_MEM; -- cf_resources[num_resources].start = region_base; -- cf_resources[num_resources].end = region_base + region_size - 1; -- num_resources++; -- -- octeon_cf_data.dma_engine = 0; -- cf_resources[num_resources].flags = IORESOURCE_IRQ; -- cf_resources[num_resources].start = OCTEON_IRQ_BOOTDMA; -- cf_resources[num_resources].end = OCTEON_IRQ_BOOTDMA; -- num_resources++; -- } else { -- octeon_cf_data.dma_engine = -1; -- } -- -- pd = platform_device_alloc("pata_octeon_cf", -1); -- if (!pd) { -- ret = -ENOMEM; -- goto out; -- } -- pd->dev.platform_data = &octeon_cf_data; -- -- ret = platform_device_add_resources(pd, cf_resources, num_resources); -- if (ret) -- goto fail; -- -- ret = platform_device_add(pd); -- if (ret) -- goto fail; -- -- return ret; --fail: -- platform_device_put(pd); --out: -- return ret; --} --device_initcall(octeon_cf_device_init); -- --/* Octeon Random Number Generator. */ --static int __init octeon_rng_device_init(void) --{ -- struct platform_device *pd; -- int ret = 0; -- -- struct resource rng_resources[] = { -- { -- .flags = IORESOURCE_MEM, -- .start = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS), -- .end = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS) + 0xf -- }, { -- .flags = IORESOURCE_MEM, -- .start = cvmx_build_io_address(8, 0), -- .end = cvmx_build_io_address(8, 0) + 0x7 -- } -- }; -- -- pd = platform_device_alloc("octeon_rng", -1); -- if (!pd) { -- ret = -ENOMEM; -- goto out; -- } -- -- ret = platform_device_add_resources(pd, rng_resources, -- ARRAY_SIZE(rng_resources)); -- if (ret) -- goto fail; -- -- ret = platform_device_add(pd); -- if (ret) -- goto fail; -- -- return ret; --fail: -- platform_device_put(pd); -- --out: -- return ret; --} --device_initcall(octeon_rng_device_init); diff --git a/target/linux/octeon/patches-2.6.30/018-dwc_otg.patch b/target/linux/octeon/patches-2.6.30/018-dwc_otg.patch deleted file mode 100644 index 6f4a4d68ba..0000000000 --- a/target/linux/octeon/patches-2.6.30/018-dwc_otg.patch +++ /dev/null @@ -1,17496 +0,0 @@ -Signed-off-by: David Daney <ddaney@caviumnetworks.com> ---- - arch/mips/cavium-octeon/octeon-platform.c | 105 ++ - arch/mips/include/asm/octeon/cvmx-usbcx-defs.h | 1199 ++++++++++++++++++++++++ - arch/mips/include/asm/octeon/cvmx-usbnx-defs.h | 760 +++++++++++++++ - 3 files changed, 2064 insertions(+), 0 deletions(-) - create mode 100644 arch/mips/include/asm/octeon/cvmx-usbcx-defs.h - create mode 100644 arch/mips/include/asm/octeon/cvmx-usbnx-defs.h - -diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c -index cfdb4c2..20698a6 100644 ---- a/arch/mips/cavium-octeon/octeon-platform.c -+++ b/arch/mips/cavium-octeon/octeon-platform.c -@@ -7,13 +7,19 @@ - * Copyright (C) 2008 Wind River Systems - */ - -+#include <linux/delay.h> - #include <linux/init.h> - #include <linux/irq.h> -+#include <linux/kernel.h> - #include <linux/module.h> - #include <linux/platform_device.h> - -+#include <asm/time.h> -+ - #include <asm/octeon/octeon.h> - #include <asm/octeon/cvmx-rnm-defs.h> -+#include <asm/octeon/cvmx-usbnx-defs.h> -+#include <asm/octeon/cvmx-usbcx-defs.h> - - static struct octeon_cf_data octeon_cf_data; - -@@ -247,6 +253,105 @@ out: - } - device_initcall(octeon_mgmt_device_init); - -+/* Octeon USB. */ -+static int __init octeon_usb_device_init(void) -+{ -+ int p_rtype_ref_clk = 2; -+ int number_usb_ports; -+ int usb_port; -+ int ret = 0; -+ -+ if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) { -+ number_usb_ports = 0; -+ } else if (OCTEON_IS_MODEL(OCTEON_CN52XX)) { -+ number_usb_ports = 2; -+ /* CN52XX encodes this field differently */ -+ p_rtype_ref_clk = 1; -+ } else { -+ number_usb_ports = 1; -+ } -+ -+ for (usb_port = 0; usb_port < number_usb_ports; usb_port++) { -+ int divisor; -+ union cvmx_usbnx_clk_ctl usbn_clk_ctl; -+ struct platform_device *pdev; -+ struct resource usb_resource[2]; -+ -+ /* -+ * Divide the core clock down such that USB is as -+ * close as possible to 125Mhz. -+ */ -+ divisor = DIV_ROUND_UP(mips_hpt_frequency, 125000000); -+ /* Lower than 4 doesn't seem to work properly */ -+ if (divisor < 4) -+ divisor = 4; -+ -+ /* Fetch the value of the Register, and de-assert POR */ -+ usbn_clk_ctl.u64 = cvmx_read_csr(CVMX_USBNX_CLK_CTL(usb_port)); -+ usbn_clk_ctl.s.por = 0; -+ if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) { -+ usbn_clk_ctl.cn31xx.p_rclk = 1; -+ usbn_clk_ctl.cn31xx.p_xenbn = 0; -+ } else { -+ if (cvmx_sysinfo_get()->board_type != -+ CVMX_BOARD_TYPE_BBGW_REF) -+ usbn_clk_ctl.cn56xx.p_rtype = p_rtype_ref_clk; -+ else -+ usbn_clk_ctl.cn56xx.p_rtype = 0; -+ } -+ usbn_clk_ctl.s.divide = divisor; -+ usbn_clk_ctl.s.divide2 = 0; -+ cvmx_write_csr(CVMX_USBNX_CLK_CTL(usb_port), usbn_clk_ctl.u64); -+ -+ /* Wait for POR */ -+ udelay(850); -+ -+ usbn_clk_ctl.u64 = cvmx_read_csr(CVMX_USBNX_CLK_CTL(usb_port)); -+ usbn_clk_ctl.s.por = 0; -+ if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) { -+ usbn_clk_ctl.cn31xx.p_rclk = 1; -+ usbn_clk_ctl.cn31xx.p_xenbn = 0; -+ } else { -+ if (cvmx_sysinfo_get()->board_type != -+ CVMX_BOARD_TYPE_BBGW_REF) -+ usbn_clk_ctl.cn56xx.p_rtype = p_rtype_ref_clk; -+ else -+ usbn_clk_ctl.cn56xx.p_rtype = 0; -+ } -+ usbn_clk_ctl.s.prst = 1; -+ cvmx_write_csr(CVMX_USBNX_CLK_CTL(usb_port), usbn_clk_ctl.u64); -+ -+ udelay(1); -+ -+ usbn_clk_ctl.s.hrst = 1; -+ cvmx_write_csr(CVMX_USBNX_CLK_CTL(usb_port), usbn_clk_ctl.u64); -+ udelay(1); -+ -+ memset(usb_resource, 0, sizeof(usb_resource)); -+ usb_resource[0].start = -+ XKPHYS_TO_PHYS(CVMX_USBCX_GOTGCTL(usb_port)); -+ usb_resource[0].end = usb_resource[0].start + 0x10000; -+ usb_resource[0].flags = IORESOURCE_MEM; -+ -+ usb_resource[1].start = (usb_port == 0) ? -+ OCTEON_IRQ_USB0 : OCTEON_IRQ_USB1; -+ usb_resource[1].end = usb_resource[1].start; -+ usb_resource[1].flags = IORESOURCE_IRQ; -+ -+ pdev = platform_device_register_simple("dwc_otg", -+ usb_port, -+ usb_resource, 2); -+ if (!pdev) { -+ pr_err("dwc_otg: Failed to allocate platform device " -+ "for USB%d\n", usb_port); -+ ret = -ENOMEM; -+ } -+ } -+ -+ return ret; -+} -+device_initcall(octeon_usb_device_init); -+ - MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>"); - MODULE_LICENSE("GPL"); - MODULE_DESCRIPTION("Platform driver for Octeon SOC"); -diff --git a/arch/mips/include/asm/octeon/cvmx-usbcx-defs.h b/arch/mips/include/asm/octeon/cvmx-usbcx-defs.h -new file mode 100644 -index 0000000..c1e078e ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-usbcx-defs.h -@@ -0,0 +1,1199 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_USBCX_DEFS_H__ -+#define __CVMX_USBCX_DEFS_H__ -+ -+#define CVMX_USBCX_DAINT(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000818ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DAINTMSK(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F001000081Cull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DCFG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000800ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DCTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000804ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DIEPCTLX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000900ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DIEPINTX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000908ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DIEPMSK(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000810ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DIEPTSIZX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000910ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DOEPCTLX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000B00ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DOEPINTX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000B08ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DOEPMSK(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000814ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DOEPTSIZX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000B10ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DPTXFSIZX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000100ull + (((offset) & 7) * 4) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DSTS(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000808ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DTKNQR1(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000820ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DTKNQR2(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000824ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DTKNQR3(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000830ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_DTKNQR4(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000834ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GAHBCFG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000008ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GHWCFG1(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000044ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GHWCFG2(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000048ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GHWCFG3(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F001000004Cull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GHWCFG4(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000050ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GINTMSK(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000018ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GINTSTS(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000014ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GNPTXFSIZ(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000028ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GNPTXSTS(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F001000002Cull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GOTGCTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000000ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GOTGINT(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000004ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GRSTCTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000010ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GRXFSIZ(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000024ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GRXSTSPD(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010040020ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GRXSTSPH(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000020ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GRXSTSRD(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F001004001Cull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GRXSTSRH(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F001000001Cull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GSNPSID(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000040ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_GUSBCFG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F001000000Cull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HAINT(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000414ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HAINTMSK(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000418ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HCCHARX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000500ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HCFG(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000400ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HCINTMSKX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F001000050Cull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HCINTX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000508ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HCSPLTX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000504ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HCTSIZX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000510ull + (((offset) & 7) * 32) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HFIR(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000404ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HFNUM(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000408ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HPRT(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000440ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HPTXFSIZ(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000100ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_HPTXSTS(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000410ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_NPTXDFIFOX(offset, block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010001000ull + (((offset) & 7) * 4096) + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBCX_PCGCCTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0010000E00ull + (((block_id) & 1) * 0x100000000000ull)) -+ -+union cvmx_usbcx_daint { -+ uint32_t u32; -+ struct cvmx_usbcx_daint_s { -+ uint32_t outepint:16; -+ uint32_t inepint:16; -+ } s; -+ struct cvmx_usbcx_daint_s cn30xx; -+ struct cvmx_usbcx_daint_s cn31xx; -+ struct cvmx_usbcx_daint_s cn50xx; -+ struct cvmx_usbcx_daint_s cn52xx; -+ struct cvmx_usbcx_daint_s cn52xxp1; -+ struct cvmx_usbcx_daint_s cn56xx; -+ struct cvmx_usbcx_daint_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_daintmsk { -+ uint32_t u32; -+ struct cvmx_usbcx_daintmsk_s { -+ uint32_t outepmsk:16; -+ uint32_t inepmsk:16; -+ } s; -+ struct cvmx_usbcx_daintmsk_s cn30xx; -+ struct cvmx_usbcx_daintmsk_s cn31xx; -+ struct cvmx_usbcx_daintmsk_s cn50xx; -+ struct cvmx_usbcx_daintmsk_s cn52xx; -+ struct cvmx_usbcx_daintmsk_s cn52xxp1; -+ struct cvmx_usbcx_daintmsk_s cn56xx; -+ struct cvmx_usbcx_daintmsk_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_dcfg { -+ uint32_t u32; -+ struct cvmx_usbcx_dcfg_s { -+ uint32_t reserved_23_31:9; -+ uint32_t epmiscnt:5; -+ uint32_t reserved_13_17:5; -+ uint32_t perfrint:2; -+ uint32_t devaddr:7; -+ uint32_t reserved_3_3:1; -+ uint32_t nzstsouthshk:1; -+ uint32_t devspd:2; -+ } s; -+ struct cvmx_usbcx_dcfg_s cn30xx; -+ struct cvmx_usbcx_dcfg_s cn31xx; -+ struct cvmx_usbcx_dcfg_s cn50xx; -+ struct cvmx_usbcx_dcfg_s cn52xx; -+ struct cvmx_usbcx_dcfg_s cn52xxp1; -+ struct cvmx_usbcx_dcfg_s cn56xx; -+ struct cvmx_usbcx_dcfg_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_dctl { -+ uint32_t u32; -+ struct cvmx_usbcx_dctl_s { -+ uint32_t reserved_12_31:20; -+ uint32_t pwronprgdone:1; -+ uint32_t cgoutnak:1; -+ uint32_t sgoutnak:1; -+ uint32_t cgnpinnak:1; -+ uint32_t sgnpinnak:1; -+ uint32_t tstctl:3; -+ uint32_t goutnaksts:1; -+ uint32_t gnpinnaksts:1; -+ uint32_t sftdiscon:1; -+ uint32_t rmtwkupsig:1; -+ } s; -+ struct cvmx_usbcx_dctl_s cn30xx; -+ struct cvmx_usbcx_dctl_s cn31xx; -+ struct cvmx_usbcx_dctl_s cn50xx; -+ struct cvmx_usbcx_dctl_s cn52xx; -+ struct cvmx_usbcx_dctl_s cn52xxp1; -+ struct cvmx_usbcx_dctl_s cn56xx; -+ struct cvmx_usbcx_dctl_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_diepctlx { -+ uint32_t u32; -+ struct cvmx_usbcx_diepctlx_s { -+ uint32_t epena:1; -+ uint32_t epdis:1; -+ uint32_t setd1pid:1; -+ uint32_t setd0pid:1; -+ uint32_t snak:1; -+ uint32_t cnak:1; -+ uint32_t txfnum:4; -+ uint32_t stall:1; -+ uint32_t reserved_20_20:1; -+ uint32_t eptype:2; -+ uint32_t naksts:1; -+ uint32_t dpid:1; -+ uint32_t usbactep:1; -+ uint32_t nextep:4; -+ uint32_t mps:11; -+ } s; -+ struct cvmx_usbcx_diepctlx_s cn30xx; -+ struct cvmx_usbcx_diepctlx_s cn31xx; -+ struct cvmx_usbcx_diepctlx_s cn50xx; -+ struct cvmx_usbcx_diepctlx_s cn52xx; -+ struct cvmx_usbcx_diepctlx_s cn52xxp1; -+ struct cvmx_usbcx_diepctlx_s cn56xx; -+ struct cvmx_usbcx_diepctlx_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_diepintx { -+ uint32_t u32; -+ struct cvmx_usbcx_diepintx_s { -+ uint32_t reserved_7_31:25; -+ uint32_t inepnakeff:1; -+ uint32_t intknepmis:1; -+ uint32_t intkntxfemp:1; -+ uint32_t timeout:1; -+ uint32_t ahberr:1; -+ uint32_t epdisbld:1; -+ uint32_t xfercompl:1; -+ } s; -+ struct cvmx_usbcx_diepintx_s cn30xx; -+ struct cvmx_usbcx_diepintx_s cn31xx; -+ struct cvmx_usbcx_diepintx_s cn50xx; -+ struct cvmx_usbcx_diepintx_s cn52xx; -+ struct cvmx_usbcx_diepintx_s cn52xxp1; -+ struct cvmx_usbcx_diepintx_s cn56xx; -+ struct cvmx_usbcx_diepintx_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_diepmsk { -+ uint32_t u32; -+ struct cvmx_usbcx_diepmsk_s { -+ uint32_t reserved_7_31:25; -+ uint32_t inepnakeffmsk:1; -+ uint32_t intknepmismsk:1; -+ uint32_t intkntxfempmsk:1; -+ uint32_t timeoutmsk:1; -+ uint32_t ahberrmsk:1; -+ uint32_t epdisbldmsk:1; -+ uint32_t xfercomplmsk:1; -+ } s; -+ struct cvmx_usbcx_diepmsk_s cn30xx; -+ struct cvmx_usbcx_diepmsk_s cn31xx; -+ struct cvmx_usbcx_diepmsk_s cn50xx; -+ struct cvmx_usbcx_diepmsk_s cn52xx; -+ struct cvmx_usbcx_diepmsk_s cn52xxp1; -+ struct cvmx_usbcx_diepmsk_s cn56xx; -+ struct cvmx_usbcx_diepmsk_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_dieptsizx { -+ uint32_t u32; -+ struct cvmx_usbcx_dieptsizx_s { -+ uint32_t reserved_31_31:1; -+ uint32_t mc:2; -+ uint32_t pktcnt:10; -+ uint32_t xfersize:19; -+ } s; -+ struct cvmx_usbcx_dieptsizx_s cn30xx; -+ struct cvmx_usbcx_dieptsizx_s cn31xx; -+ struct cvmx_usbcx_dieptsizx_s cn50xx; -+ struct cvmx_usbcx_dieptsizx_s cn52xx; -+ struct cvmx_usbcx_dieptsizx_s cn52xxp1; -+ struct cvmx_usbcx_dieptsizx_s cn56xx; -+ struct cvmx_usbcx_dieptsizx_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_doepctlx { -+ uint32_t u32; -+ struct cvmx_usbcx_doepctlx_s { -+ uint32_t epena:1; -+ uint32_t epdis:1; -+ uint32_t setd1pid:1; -+ uint32_t setd0pid:1; -+ uint32_t snak:1; -+ uint32_t cnak:1; -+ uint32_t reserved_22_25:4; -+ uint32_t stall:1; -+ uint32_t snp:1; -+ uint32_t eptype:2; -+ uint32_t naksts:1; -+ uint32_t dpid:1; -+ uint32_t usbactep:1; -+ uint32_t reserved_11_14:4; -+ uint32_t mps:11; -+ } s; -+ struct cvmx_usbcx_doepctlx_s cn30xx; -+ struct cvmx_usbcx_doepctlx_s cn31xx; -+ struct cvmx_usbcx_doepctlx_s cn50xx; -+ struct cvmx_usbcx_doepctlx_s cn52xx; -+ struct cvmx_usbcx_doepctlx_s cn52xxp1; -+ struct cvmx_usbcx_doepctlx_s cn56xx; -+ struct cvmx_usbcx_doepctlx_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_doepintx { -+ uint32_t u32; -+ struct cvmx_usbcx_doepintx_s { -+ uint32_t reserved_5_31:27; -+ uint32_t outtknepdis:1; -+ uint32_t setup:1; -+ uint32_t ahberr:1; -+ uint32_t epdisbld:1; -+ uint32_t xfercompl:1; -+ } s; -+ struct cvmx_usbcx_doepintx_s cn30xx; -+ struct cvmx_usbcx_doepintx_s cn31xx; -+ struct cvmx_usbcx_doepintx_s cn50xx; -+ struct cvmx_usbcx_doepintx_s cn52xx; -+ struct cvmx_usbcx_doepintx_s cn52xxp1; -+ struct cvmx_usbcx_doepintx_s cn56xx; -+ struct cvmx_usbcx_doepintx_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_doepmsk { -+ uint32_t u32; -+ struct cvmx_usbcx_doepmsk_s { -+ uint32_t reserved_5_31:27; -+ uint32_t outtknepdismsk:1; -+ uint32_t setupmsk:1; -+ uint32_t ahberrmsk:1; -+ uint32_t epdisbldmsk:1; -+ uint32_t xfercomplmsk:1; -+ } s; -+ struct cvmx_usbcx_doepmsk_s cn30xx; -+ struct cvmx_usbcx_doepmsk_s cn31xx; -+ struct cvmx_usbcx_doepmsk_s cn50xx; -+ struct cvmx_usbcx_doepmsk_s cn52xx; -+ struct cvmx_usbcx_doepmsk_s cn52xxp1; -+ struct cvmx_usbcx_doepmsk_s cn56xx; -+ struct cvmx_usbcx_doepmsk_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_doeptsizx { -+ uint32_t u32; -+ struct cvmx_usbcx_doeptsizx_s { -+ uint32_t reserved_31_31:1; -+ uint32_t mc:2; -+ uint32_t pktcnt:10; -+ uint32_t xfersize:19; -+ } s; -+ struct cvmx_usbcx_doeptsizx_s cn30xx; -+ struct cvmx_usbcx_doeptsizx_s cn31xx; -+ struct cvmx_usbcx_doeptsizx_s cn50xx; -+ struct cvmx_usbcx_doeptsizx_s cn52xx; -+ struct cvmx_usbcx_doeptsizx_s cn52xxp1; -+ struct cvmx_usbcx_doeptsizx_s cn56xx; -+ struct cvmx_usbcx_doeptsizx_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_dptxfsizx { -+ uint32_t u32; -+ struct cvmx_usbcx_dptxfsizx_s { -+ uint32_t dptxfsize:16; -+ uint32_t dptxfstaddr:16; -+ } s; -+ struct cvmx_usbcx_dptxfsizx_s cn30xx; -+ struct cvmx_usbcx_dptxfsizx_s cn31xx; -+ struct cvmx_usbcx_dptxfsizx_s cn50xx; -+ struct cvmx_usbcx_dptxfsizx_s cn52xx; -+ struct cvmx_usbcx_dptxfsizx_s cn52xxp1; -+ struct cvmx_usbcx_dptxfsizx_s cn56xx; -+ struct cvmx_usbcx_dptxfsizx_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_dsts { -+ uint32_t u32; -+ struct cvmx_usbcx_dsts_s { -+ uint32_t reserved_22_31:10; -+ uint32_t soffn:14; -+ uint32_t reserved_4_7:4; -+ uint32_t errticerr:1; -+ uint32_t enumspd:2; -+ uint32_t suspsts:1; -+ } s; -+ struct cvmx_usbcx_dsts_s cn30xx; -+ struct cvmx_usbcx_dsts_s cn31xx; -+ struct cvmx_usbcx_dsts_s cn50xx; -+ struct cvmx_usbcx_dsts_s cn52xx; -+ struct cvmx_usbcx_dsts_s cn52xxp1; -+ struct cvmx_usbcx_dsts_s cn56xx; -+ struct cvmx_usbcx_dsts_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_dtknqr1 { -+ uint32_t u32; -+ struct cvmx_usbcx_dtknqr1_s { -+ uint32_t eptkn:24; -+ uint32_t wrapbit:1; -+ uint32_t reserved_5_6:2; -+ uint32_t intknwptr:5; -+ } s; -+ struct cvmx_usbcx_dtknqr1_s cn30xx; -+ struct cvmx_usbcx_dtknqr1_s cn31xx; -+ struct cvmx_usbcx_dtknqr1_s cn50xx; -+ struct cvmx_usbcx_dtknqr1_s cn52xx; -+ struct cvmx_usbcx_dtknqr1_s cn52xxp1; -+ struct cvmx_usbcx_dtknqr1_s cn56xx; -+ struct cvmx_usbcx_dtknqr1_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_dtknqr2 { -+ uint32_t u32; -+ struct cvmx_usbcx_dtknqr2_s { -+ uint32_t eptkn:32; -+ } s; -+ struct cvmx_usbcx_dtknqr2_s cn30xx; -+ struct cvmx_usbcx_dtknqr2_s cn31xx; -+ struct cvmx_usbcx_dtknqr2_s cn50xx; -+ struct cvmx_usbcx_dtknqr2_s cn52xx; -+ struct cvmx_usbcx_dtknqr2_s cn52xxp1; -+ struct cvmx_usbcx_dtknqr2_s cn56xx; -+ struct cvmx_usbcx_dtknqr2_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_dtknqr3 { -+ uint32_t u32; -+ struct cvmx_usbcx_dtknqr3_s { -+ uint32_t eptkn:32; -+ } s; -+ struct cvmx_usbcx_dtknqr3_s cn30xx; -+ struct cvmx_usbcx_dtknqr3_s cn31xx; -+ struct cvmx_usbcx_dtknqr3_s cn50xx; -+ struct cvmx_usbcx_dtknqr3_s cn52xx; -+ struct cvmx_usbcx_dtknqr3_s cn52xxp1; -+ struct cvmx_usbcx_dtknqr3_s cn56xx; -+ struct cvmx_usbcx_dtknqr3_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_dtknqr4 { -+ uint32_t u32; -+ struct cvmx_usbcx_dtknqr4_s { -+ uint32_t eptkn:32; -+ } s; -+ struct cvmx_usbcx_dtknqr4_s cn30xx; -+ struct cvmx_usbcx_dtknqr4_s cn31xx; -+ struct cvmx_usbcx_dtknqr4_s cn50xx; -+ struct cvmx_usbcx_dtknqr4_s cn52xx; -+ struct cvmx_usbcx_dtknqr4_s cn52xxp1; -+ struct cvmx_usbcx_dtknqr4_s cn56xx; -+ struct cvmx_usbcx_dtknqr4_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_gahbcfg { -+ uint32_t u32; -+ struct cvmx_usbcx_gahbcfg_s { -+ uint32_t reserved_9_31:23; -+ uint32_t ptxfemplvl:1; -+ uint32_t nptxfemplvl:1; -+ uint32_t reserved_6_6:1; -+ uint32_t dmaen:1; -+ uint32_t hbstlen:4; -+ uint32_t glblintrmsk:1; -+ } s; -+ struct cvmx_usbcx_gahbcfg_s cn30xx; -+ struct cvmx_usbcx_gahbcfg_s cn31xx; -+ struct cvmx_usbcx_gahbcfg_s cn50xx; -+ struct cvmx_usbcx_gahbcfg_s cn52xx; -+ struct cvmx_usbcx_gahbcfg_s cn52xxp1; -+ struct cvmx_usbcx_gahbcfg_s cn56xx; -+ struct cvmx_usbcx_gahbcfg_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_ghwcfg1 { -+ uint32_t u32; -+ struct cvmx_usbcx_ghwcfg1_s { -+ uint32_t epdir:32; -+ } s; -+ struct cvmx_usbcx_ghwcfg1_s cn30xx; -+ struct cvmx_usbcx_ghwcfg1_s cn31xx; -+ struct cvmx_usbcx_ghwcfg1_s cn50xx; -+ struct cvmx_usbcx_ghwcfg1_s cn52xx; -+ struct cvmx_usbcx_ghwcfg1_s cn52xxp1; -+ struct cvmx_usbcx_ghwcfg1_s cn56xx; -+ struct cvmx_usbcx_ghwcfg1_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_ghwcfg2 { -+ uint32_t u32; -+ struct cvmx_usbcx_ghwcfg2_s { -+ uint32_t reserved_31_31:1; -+ uint32_t tknqdepth:5; -+ uint32_t ptxqdepth:2; -+ uint32_t nptxqdepth:2; -+ uint32_t reserved_20_21:2; -+ uint32_t dynfifosizing:1; -+ uint32_t periosupport:1; -+ uint32_t numhstchnl:4; -+ uint32_t numdeveps:4; -+ uint32_t fsphytype:2; -+ uint32_t hsphytype:2; -+ uint32_t singpnt:1; -+ uint32_t otgarch:2; -+ uint32_t otgmode:3; -+ } s; -+ struct cvmx_usbcx_ghwcfg2_s cn30xx; -+ struct cvmx_usbcx_ghwcfg2_s cn31xx; -+ struct cvmx_usbcx_ghwcfg2_s cn50xx; -+ struct cvmx_usbcx_ghwcfg2_s cn52xx; -+ struct cvmx_usbcx_ghwcfg2_s cn52xxp1; -+ struct cvmx_usbcx_ghwcfg2_s cn56xx; -+ struct cvmx_usbcx_ghwcfg2_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_ghwcfg3 { -+ uint32_t u32; -+ struct cvmx_usbcx_ghwcfg3_s { -+ uint32_t dfifodepth:16; -+ uint32_t reserved_13_15:3; -+ uint32_t ahbphysync:1; -+ uint32_t rsttype:1; -+ uint32_t optfeature:1; -+ uint32_t vendor_control_interface_support:1; -+ uint32_t i2c_selection:1; -+ uint32_t otgen:1; -+ uint32_t pktsizewidth:3; -+ uint32_t xfersizewidth:4; -+ } s; -+ struct cvmx_usbcx_ghwcfg3_s cn30xx; -+ struct cvmx_usbcx_ghwcfg3_s cn31xx; -+ struct cvmx_usbcx_ghwcfg3_s cn50xx; -+ struct cvmx_usbcx_ghwcfg3_s cn52xx; -+ struct cvmx_usbcx_ghwcfg3_s cn52xxp1; -+ struct cvmx_usbcx_ghwcfg3_s cn56xx; -+ struct cvmx_usbcx_ghwcfg3_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_ghwcfg4 { -+ uint32_t u32; -+ struct cvmx_usbcx_ghwcfg4_s { -+ uint32_t reserved_30_31:2; -+ uint32_t numdevmodinend:4; -+ uint32_t endedtrfifo:1; -+ uint32_t sessendfltr:1; -+ uint32_t bvalidfltr:1; -+ uint32_t avalidfltr:1; -+ uint32_t vbusvalidfltr:1; -+ uint32_t iddgfltr:1; -+ uint32_t numctleps:4; -+ uint32_t phydatawidth:2; -+ uint32_t reserved_6_13:8; -+ uint32_t ahbfreq:1; -+ uint32_t enablepwropt:1; -+ uint32_t numdevperioeps:4; -+ } s; -+ struct cvmx_usbcx_ghwcfg4_cn30xx { -+ uint32_t reserved_25_31:7; -+ uint32_t sessendfltr:1; -+ uint32_t bvalidfltr:1; -+ uint32_t avalidfltr:1; -+ uint32_t vbusvalidfltr:1; -+ uint32_t iddgfltr:1; -+ uint32_t numctleps:4; -+ uint32_t phydatawidth:2; -+ uint32_t reserved_6_13:8; -+ uint32_t ahbfreq:1; -+ uint32_t enablepwropt:1; -+ uint32_t numdevperioeps:4; -+ } cn30xx; -+ struct cvmx_usbcx_ghwcfg4_cn30xx cn31xx; -+ struct cvmx_usbcx_ghwcfg4_s cn50xx; -+ struct cvmx_usbcx_ghwcfg4_s cn52xx; -+ struct cvmx_usbcx_ghwcfg4_s cn52xxp1; -+ struct cvmx_usbcx_ghwcfg4_s cn56xx; -+ struct cvmx_usbcx_ghwcfg4_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_gintmsk { -+ uint32_t u32; -+ struct cvmx_usbcx_gintmsk_s { -+ uint32_t wkupintmsk:1; -+ uint32_t sessreqintmsk:1; -+ uint32_t disconnintmsk:1; -+ uint32_t conidstschngmsk:1; -+ uint32_t reserved_27_27:1; -+ uint32_t ptxfempmsk:1; -+ uint32_t hchintmsk:1; -+ uint32_t prtintmsk:1; -+ uint32_t reserved_23_23:1; -+ uint32_t fetsuspmsk:1; -+ uint32_t incomplpmsk:1; -+ uint32_t incompisoinmsk:1; -+ uint32_t oepintmsk:1; -+ uint32_t inepintmsk:1; -+ uint32_t epmismsk:1; -+ uint32_t reserved_16_16:1; -+ uint32_t eopfmsk:1; -+ uint32_t isooutdropmsk:1; -+ uint32_t enumdonemsk:1; -+ uint32_t usbrstmsk:1; -+ uint32_t usbsuspmsk:1; -+ uint32_t erlysuspmsk:1; -+ uint32_t i2cint:1; -+ uint32_t ulpickintmsk:1; -+ uint32_t goutnakeffmsk:1; -+ uint32_t ginnakeffmsk:1; -+ uint32_t nptxfempmsk:1; -+ uint32_t rxflvlmsk:1; -+ uint32_t sofmsk:1; -+ uint32_t otgintmsk:1; -+ uint32_t modemismsk:1; -+ uint32_t reserved_0_0:1; -+ } s; -+ struct cvmx_usbcx_gintmsk_s cn30xx; -+ struct cvmx_usbcx_gintmsk_s cn31xx; -+ struct cvmx_usbcx_gintmsk_s cn50xx; -+ struct cvmx_usbcx_gintmsk_s cn52xx; -+ struct cvmx_usbcx_gintmsk_s cn52xxp1; -+ struct cvmx_usbcx_gintmsk_s cn56xx; -+ struct cvmx_usbcx_gintmsk_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_gintsts { -+ uint32_t u32; -+ struct cvmx_usbcx_gintsts_s { -+ uint32_t wkupint:1; -+ uint32_t sessreqint:1; -+ uint32_t disconnint:1; -+ uint32_t conidstschng:1; -+ uint32_t reserved_27_27:1; -+ uint32_t ptxfemp:1; -+ uint32_t hchint:1; -+ uint32_t prtint:1; -+ uint32_t reserved_23_23:1; -+ uint32_t fetsusp:1; -+ uint32_t incomplp:1; -+ uint32_t incompisoin:1; -+ uint32_t oepint:1; -+ uint32_t iepint:1; -+ uint32_t epmis:1; -+ uint32_t reserved_16_16:1; -+ uint32_t eopf:1; -+ uint32_t isooutdrop:1; -+ uint32_t enumdone:1; -+ uint32_t usbrst:1; -+ uint32_t usbsusp:1; -+ uint32_t erlysusp:1; -+ uint32_t i2cint:1; -+ uint32_t ulpickint:1; -+ uint32_t goutnakeff:1; -+ uint32_t ginnakeff:1; -+ uint32_t nptxfemp:1; -+ uint32_t rxflvl:1; -+ uint32_t sof:1; -+ uint32_t otgint:1; -+ uint32_t modemis:1; -+ uint32_t curmod:1; -+ } s; -+ struct cvmx_usbcx_gintsts_s cn30xx; -+ struct cvmx_usbcx_gintsts_s cn31xx; -+ struct cvmx_usbcx_gintsts_s cn50xx; -+ struct cvmx_usbcx_gintsts_s cn52xx; -+ struct cvmx_usbcx_gintsts_s cn52xxp1; -+ struct cvmx_usbcx_gintsts_s cn56xx; -+ struct cvmx_usbcx_gintsts_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_gnptxfsiz { -+ uint32_t u32; -+ struct cvmx_usbcx_gnptxfsiz_s { -+ uint32_t nptxfdep:16; -+ uint32_t nptxfstaddr:16; -+ } s; -+ struct cvmx_usbcx_gnptxfsiz_s cn30xx; -+ struct cvmx_usbcx_gnptxfsiz_s cn31xx; -+ struct cvmx_usbcx_gnptxfsiz_s cn50xx; -+ struct cvmx_usbcx_gnptxfsiz_s cn52xx; -+ struct cvmx_usbcx_gnptxfsiz_s cn52xxp1; -+ struct cvmx_usbcx_gnptxfsiz_s cn56xx; -+ struct cvmx_usbcx_gnptxfsiz_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_gnptxsts { -+ uint32_t u32; -+ struct cvmx_usbcx_gnptxsts_s { -+ uint32_t reserved_31_31:1; -+ uint32_t nptxqtop:7; -+ uint32_t nptxqspcavail:8; -+ uint32_t nptxfspcavail:16; -+ } s; -+ struct cvmx_usbcx_gnptxsts_s cn30xx; -+ struct cvmx_usbcx_gnptxsts_s cn31xx; -+ struct cvmx_usbcx_gnptxsts_s cn50xx; -+ struct cvmx_usbcx_gnptxsts_s cn52xx; -+ struct cvmx_usbcx_gnptxsts_s cn52xxp1; -+ struct cvmx_usbcx_gnptxsts_s cn56xx; -+ struct cvmx_usbcx_gnptxsts_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_gotgctl { -+ uint32_t u32; -+ struct cvmx_usbcx_gotgctl_s { -+ uint32_t reserved_20_31:12; -+ uint32_t bsesvld:1; -+ uint32_t asesvld:1; -+ uint32_t dbnctime:1; -+ uint32_t conidsts:1; -+ uint32_t reserved_12_15:4; -+ uint32_t devhnpen:1; -+ uint32_t hstsethnpen:1; -+ uint32_t hnpreq:1; -+ uint32_t hstnegscs:1; -+ uint32_t reserved_2_7:6; -+ uint32_t sesreq:1; -+ uint32_t sesreqscs:1; -+ } s; -+ struct cvmx_usbcx_gotgctl_s cn30xx; -+ struct cvmx_usbcx_gotgctl_s cn31xx; -+ struct cvmx_usbcx_gotgctl_s cn50xx; -+ struct cvmx_usbcx_gotgctl_s cn52xx; -+ struct cvmx_usbcx_gotgctl_s cn52xxp1; -+ struct cvmx_usbcx_gotgctl_s cn56xx; -+ struct cvmx_usbcx_gotgctl_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_gotgint { -+ uint32_t u32; -+ struct cvmx_usbcx_gotgint_s { -+ uint32_t reserved_20_31:12; -+ uint32_t dbncedone:1; -+ uint32_t adevtoutchg:1; -+ uint32_t hstnegdet:1; -+ uint32_t reserved_10_16:7; -+ uint32_t hstnegsucstschng:1; -+ uint32_t sesreqsucstschng:1; -+ uint32_t reserved_3_7:5; -+ uint32_t sesenddet:1; -+ uint32_t reserved_0_1:2; -+ } s; -+ struct cvmx_usbcx_gotgint_s cn30xx; -+ struct cvmx_usbcx_gotgint_s cn31xx; -+ struct cvmx_usbcx_gotgint_s cn50xx; -+ struct cvmx_usbcx_gotgint_s cn52xx; -+ struct cvmx_usbcx_gotgint_s cn52xxp1; -+ struct cvmx_usbcx_gotgint_s cn56xx; -+ struct cvmx_usbcx_gotgint_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_grstctl { -+ uint32_t u32; -+ struct cvmx_usbcx_grstctl_s { -+ uint32_t ahbidle:1; -+ uint32_t dmareq:1; -+ uint32_t reserved_11_29:19; -+ uint32_t txfnum:5; -+ uint32_t txfflsh:1; -+ uint32_t rxfflsh:1; -+ uint32_t intknqflsh:1; -+ uint32_t frmcntrrst:1; -+ uint32_t hsftrst:1; -+ uint32_t csftrst:1; -+ } s; -+ struct cvmx_usbcx_grstctl_s cn30xx; -+ struct cvmx_usbcx_grstctl_s cn31xx; -+ struct cvmx_usbcx_grstctl_s cn50xx; -+ struct cvmx_usbcx_grstctl_s cn52xx; -+ struct cvmx_usbcx_grstctl_s cn52xxp1; -+ struct cvmx_usbcx_grstctl_s cn56xx; -+ struct cvmx_usbcx_grstctl_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_grxfsiz { -+ uint32_t u32; -+ struct cvmx_usbcx_grxfsiz_s { -+ uint32_t reserved_16_31:16; -+ uint32_t rxfdep:16; -+ } s; -+ struct cvmx_usbcx_grxfsiz_s cn30xx; -+ struct cvmx_usbcx_grxfsiz_s cn31xx; -+ struct cvmx_usbcx_grxfsiz_s cn50xx; -+ struct cvmx_usbcx_grxfsiz_s cn52xx; -+ struct cvmx_usbcx_grxfsiz_s cn52xxp1; -+ struct cvmx_usbcx_grxfsiz_s cn56xx; -+ struct cvmx_usbcx_grxfsiz_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_grxstspd { -+ uint32_t u32; -+ struct cvmx_usbcx_grxstspd_s { -+ uint32_t reserved_25_31:7; -+ uint32_t fn:4; -+ uint32_t pktsts:4; -+ uint32_t dpid:2; -+ uint32_t bcnt:11; -+ uint32_t epnum:4; -+ } s; -+ struct cvmx_usbcx_grxstspd_s cn30xx; -+ struct cvmx_usbcx_grxstspd_s cn31xx; -+ struct cvmx_usbcx_grxstspd_s cn50xx; -+ struct cvmx_usbcx_grxstspd_s cn52xx; -+ struct cvmx_usbcx_grxstspd_s cn52xxp1; -+ struct cvmx_usbcx_grxstspd_s cn56xx; -+ struct cvmx_usbcx_grxstspd_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_grxstsph { -+ uint32_t u32; -+ struct cvmx_usbcx_grxstsph_s { -+ uint32_t reserved_21_31:11; -+ uint32_t pktsts:4; -+ uint32_t dpid:2; -+ uint32_t bcnt:11; -+ uint32_t chnum:4; -+ } s; -+ struct cvmx_usbcx_grxstsph_s cn30xx; -+ struct cvmx_usbcx_grxstsph_s cn31xx; -+ struct cvmx_usbcx_grxstsph_s cn50xx; -+ struct cvmx_usbcx_grxstsph_s cn52xx; -+ struct cvmx_usbcx_grxstsph_s cn52xxp1; -+ struct cvmx_usbcx_grxstsph_s cn56xx; -+ struct cvmx_usbcx_grxstsph_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_grxstsrd { -+ uint32_t u32; -+ struct cvmx_usbcx_grxstsrd_s { -+ uint32_t reserved_25_31:7; -+ uint32_t fn:4; -+ uint32_t pktsts:4; -+ uint32_t dpid:2; -+ uint32_t bcnt:11; -+ uint32_t epnum:4; -+ } s; -+ struct cvmx_usbcx_grxstsrd_s cn30xx; -+ struct cvmx_usbcx_grxstsrd_s cn31xx; -+ struct cvmx_usbcx_grxstsrd_s cn50xx; -+ struct cvmx_usbcx_grxstsrd_s cn52xx; -+ struct cvmx_usbcx_grxstsrd_s cn52xxp1; -+ struct cvmx_usbcx_grxstsrd_s cn56xx; -+ struct cvmx_usbcx_grxstsrd_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_grxstsrh { -+ uint32_t u32; -+ struct cvmx_usbcx_grxstsrh_s { -+ uint32_t reserved_21_31:11; -+ uint32_t pktsts:4; -+ uint32_t dpid:2; -+ uint32_t bcnt:11; -+ uint32_t chnum:4; -+ } s; -+ struct cvmx_usbcx_grxstsrh_s cn30xx; -+ struct cvmx_usbcx_grxstsrh_s cn31xx; -+ struct cvmx_usbcx_grxstsrh_s cn50xx; -+ struct cvmx_usbcx_grxstsrh_s cn52xx; -+ struct cvmx_usbcx_grxstsrh_s cn52xxp1; -+ struct cvmx_usbcx_grxstsrh_s cn56xx; -+ struct cvmx_usbcx_grxstsrh_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_gsnpsid { -+ uint32_t u32; -+ struct cvmx_usbcx_gsnpsid_s { -+ uint32_t synopsysid:32; -+ } s; -+ struct cvmx_usbcx_gsnpsid_s cn30xx; -+ struct cvmx_usbcx_gsnpsid_s cn31xx; -+ struct cvmx_usbcx_gsnpsid_s cn50xx; -+ struct cvmx_usbcx_gsnpsid_s cn52xx; -+ struct cvmx_usbcx_gsnpsid_s cn52xxp1; -+ struct cvmx_usbcx_gsnpsid_s cn56xx; -+ struct cvmx_usbcx_gsnpsid_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_gusbcfg { -+ uint32_t u32; -+ struct cvmx_usbcx_gusbcfg_s { -+ uint32_t reserved_17_31:15; -+ uint32_t otgi2csel:1; -+ uint32_t phylpwrclksel:1; -+ uint32_t reserved_14_14:1; -+ uint32_t usbtrdtim:4; -+ uint32_t hnpcap:1; -+ uint32_t srpcap:1; -+ uint32_t ddrsel:1; -+ uint32_t physel:1; -+ uint32_t fsintf:1; -+ uint32_t ulpi_utmi_sel:1; -+ uint32_t phyif:1; -+ uint32_t toutcal:3; -+ } s; -+ struct cvmx_usbcx_gusbcfg_s cn30xx; -+ struct cvmx_usbcx_gusbcfg_s cn31xx; -+ struct cvmx_usbcx_gusbcfg_s cn50xx; -+ struct cvmx_usbcx_gusbcfg_s cn52xx; -+ struct cvmx_usbcx_gusbcfg_s cn52xxp1; -+ struct cvmx_usbcx_gusbcfg_s cn56xx; -+ struct cvmx_usbcx_gusbcfg_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_haint { -+ uint32_t u32; -+ struct cvmx_usbcx_haint_s { -+ uint32_t reserved_16_31:16; -+ uint32_t haint:16; -+ } s; -+ struct cvmx_usbcx_haint_s cn30xx; -+ struct cvmx_usbcx_haint_s cn31xx; -+ struct cvmx_usbcx_haint_s cn50xx; -+ struct cvmx_usbcx_haint_s cn52xx; -+ struct cvmx_usbcx_haint_s cn52xxp1; -+ struct cvmx_usbcx_haint_s cn56xx; -+ struct cvmx_usbcx_haint_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_haintmsk { -+ uint32_t u32; -+ struct cvmx_usbcx_haintmsk_s { -+ uint32_t reserved_16_31:16; -+ uint32_t haintmsk:16; -+ } s; -+ struct cvmx_usbcx_haintmsk_s cn30xx; -+ struct cvmx_usbcx_haintmsk_s cn31xx; -+ struct cvmx_usbcx_haintmsk_s cn50xx; -+ struct cvmx_usbcx_haintmsk_s cn52xx; -+ struct cvmx_usbcx_haintmsk_s cn52xxp1; -+ struct cvmx_usbcx_haintmsk_s cn56xx; -+ struct cvmx_usbcx_haintmsk_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_hccharx { -+ uint32_t u32; -+ struct cvmx_usbcx_hccharx_s { -+ uint32_t chena:1; -+ uint32_t chdis:1; -+ uint32_t oddfrm:1; -+ uint32_t devaddr:7; -+ uint32_t ec:2; -+ uint32_t eptype:2; -+ uint32_t lspddev:1; -+ uint32_t reserved_16_16:1; -+ uint32_t epdir:1; -+ uint32_t epnum:4; -+ uint32_t mps:11; -+ } s; -+ struct cvmx_usbcx_hccharx_s cn30xx; -+ struct cvmx_usbcx_hccharx_s cn31xx; -+ struct cvmx_usbcx_hccharx_s cn50xx; -+ struct cvmx_usbcx_hccharx_s cn52xx; -+ struct cvmx_usbcx_hccharx_s cn52xxp1; -+ struct cvmx_usbcx_hccharx_s cn56xx; -+ struct cvmx_usbcx_hccharx_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_hcfg { -+ uint32_t u32; -+ struct cvmx_usbcx_hcfg_s { -+ uint32_t reserved_3_31:29; -+ uint32_t fslssupp:1; -+ uint32_t fslspclksel:2; -+ } s; -+ struct cvmx_usbcx_hcfg_s cn30xx; -+ struct cvmx_usbcx_hcfg_s cn31xx; -+ struct cvmx_usbcx_hcfg_s cn50xx; -+ struct cvmx_usbcx_hcfg_s cn52xx; -+ struct cvmx_usbcx_hcfg_s cn52xxp1; -+ struct cvmx_usbcx_hcfg_s cn56xx; -+ struct cvmx_usbcx_hcfg_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_hcintx { -+ uint32_t u32; -+ struct cvmx_usbcx_hcintx_s { -+ uint32_t reserved_11_31:21; -+ uint32_t datatglerr:1; -+ uint32_t frmovrun:1; -+ uint32_t bblerr:1; -+ uint32_t xacterr:1; -+ uint32_t nyet:1; -+ uint32_t ack:1; -+ uint32_t nak:1; -+ uint32_t stall:1; -+ uint32_t ahberr:1; -+ uint32_t chhltd:1; -+ uint32_t xfercompl:1; -+ } s; -+ struct cvmx_usbcx_hcintx_s cn30xx; -+ struct cvmx_usbcx_hcintx_s cn31xx; -+ struct cvmx_usbcx_hcintx_s cn50xx; -+ struct cvmx_usbcx_hcintx_s cn52xx; -+ struct cvmx_usbcx_hcintx_s cn52xxp1; -+ struct cvmx_usbcx_hcintx_s cn56xx; -+ struct cvmx_usbcx_hcintx_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_hcintmskx { -+ uint32_t u32; -+ struct cvmx_usbcx_hcintmskx_s { -+ uint32_t reserved_11_31:21; -+ uint32_t datatglerrmsk:1; -+ uint32_t frmovrunmsk:1; -+ uint32_t bblerrmsk:1; -+ uint32_t xacterrmsk:1; -+ uint32_t nyetmsk:1; -+ uint32_t ackmsk:1; -+ uint32_t nakmsk:1; -+ uint32_t stallmsk:1; -+ uint32_t ahberrmsk:1; -+ uint32_t chhltdmsk:1; -+ uint32_t xfercomplmsk:1; -+ } s; -+ struct cvmx_usbcx_hcintmskx_s cn30xx; -+ struct cvmx_usbcx_hcintmskx_s cn31xx; -+ struct cvmx_usbcx_hcintmskx_s cn50xx; -+ struct cvmx_usbcx_hcintmskx_s cn52xx; -+ struct cvmx_usbcx_hcintmskx_s cn52xxp1; -+ struct cvmx_usbcx_hcintmskx_s cn56xx; -+ struct cvmx_usbcx_hcintmskx_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_hcspltx { -+ uint32_t u32; -+ struct cvmx_usbcx_hcspltx_s { -+ uint32_t spltena:1; -+ uint32_t reserved_17_30:14; -+ uint32_t compsplt:1; -+ uint32_t xactpos:2; -+ uint32_t hubaddr:7; -+ uint32_t prtaddr:7; -+ } s; -+ struct cvmx_usbcx_hcspltx_s cn30xx; -+ struct cvmx_usbcx_hcspltx_s cn31xx; -+ struct cvmx_usbcx_hcspltx_s cn50xx; -+ struct cvmx_usbcx_hcspltx_s cn52xx; -+ struct cvmx_usbcx_hcspltx_s cn52xxp1; -+ struct cvmx_usbcx_hcspltx_s cn56xx; -+ struct cvmx_usbcx_hcspltx_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_hctsizx { -+ uint32_t u32; -+ struct cvmx_usbcx_hctsizx_s { -+ uint32_t dopng:1; -+ uint32_t pid:2; -+ uint32_t pktcnt:10; -+ uint32_t xfersize:19; -+ } s; -+ struct cvmx_usbcx_hctsizx_s cn30xx; -+ struct cvmx_usbcx_hctsizx_s cn31xx; -+ struct cvmx_usbcx_hctsizx_s cn50xx; -+ struct cvmx_usbcx_hctsizx_s cn52xx; -+ struct cvmx_usbcx_hctsizx_s cn52xxp1; -+ struct cvmx_usbcx_hctsizx_s cn56xx; -+ struct cvmx_usbcx_hctsizx_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_hfir { -+ uint32_t u32; -+ struct cvmx_usbcx_hfir_s { -+ uint32_t reserved_16_31:16; -+ uint32_t frint:16; -+ } s; -+ struct cvmx_usbcx_hfir_s cn30xx; -+ struct cvmx_usbcx_hfir_s cn31xx; -+ struct cvmx_usbcx_hfir_s cn50xx; -+ struct cvmx_usbcx_hfir_s cn52xx; -+ struct cvmx_usbcx_hfir_s cn52xxp1; -+ struct cvmx_usbcx_hfir_s cn56xx; -+ struct cvmx_usbcx_hfir_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_hfnum { -+ uint32_t u32; -+ struct cvmx_usbcx_hfnum_s { -+ uint32_t frrem:16; -+ uint32_t frnum:16; -+ } s; -+ struct cvmx_usbcx_hfnum_s cn30xx; -+ struct cvmx_usbcx_hfnum_s cn31xx; -+ struct cvmx_usbcx_hfnum_s cn50xx; -+ struct cvmx_usbcx_hfnum_s cn52xx; -+ struct cvmx_usbcx_hfnum_s cn52xxp1; -+ struct cvmx_usbcx_hfnum_s cn56xx; -+ struct cvmx_usbcx_hfnum_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_hprt { -+ uint32_t u32; -+ struct cvmx_usbcx_hprt_s { -+ uint32_t reserved_19_31:13; -+ uint32_t prtspd:2; -+ uint32_t prttstctl:4; -+ uint32_t prtpwr:1; -+ uint32_t prtlnsts:2; -+ uint32_t reserved_9_9:1; -+ uint32_t prtrst:1; -+ uint32_t prtsusp:1; -+ uint32_t prtres:1; -+ uint32_t prtovrcurrchng:1; -+ uint32_t prtovrcurract:1; -+ uint32_t prtenchng:1; -+ uint32_t prtena:1; -+ uint32_t prtconndet:1; -+ uint32_t prtconnsts:1; -+ } s; -+ struct cvmx_usbcx_hprt_s cn30xx; -+ struct cvmx_usbcx_hprt_s cn31xx; -+ struct cvmx_usbcx_hprt_s cn50xx; -+ struct cvmx_usbcx_hprt_s cn52xx; -+ struct cvmx_usbcx_hprt_s cn52xxp1; -+ struct cvmx_usbcx_hprt_s cn56xx; -+ struct cvmx_usbcx_hprt_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_hptxfsiz { -+ uint32_t u32; -+ struct cvmx_usbcx_hptxfsiz_s { -+ uint32_t ptxfsize:16; -+ uint32_t ptxfstaddr:16; -+ } s; -+ struct cvmx_usbcx_hptxfsiz_s cn30xx; -+ struct cvmx_usbcx_hptxfsiz_s cn31xx; -+ struct cvmx_usbcx_hptxfsiz_s cn50xx; -+ struct cvmx_usbcx_hptxfsiz_s cn52xx; -+ struct cvmx_usbcx_hptxfsiz_s cn52xxp1; -+ struct cvmx_usbcx_hptxfsiz_s cn56xx; -+ struct cvmx_usbcx_hptxfsiz_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_hptxsts { -+ uint32_t u32; -+ struct cvmx_usbcx_hptxsts_s { -+ uint32_t ptxqtop:8; -+ uint32_t ptxqspcavail:8; -+ uint32_t ptxfspcavail:16; -+ } s; -+ struct cvmx_usbcx_hptxsts_s cn30xx; -+ struct cvmx_usbcx_hptxsts_s cn31xx; -+ struct cvmx_usbcx_hptxsts_s cn50xx; -+ struct cvmx_usbcx_hptxsts_s cn52xx; -+ struct cvmx_usbcx_hptxsts_s cn52xxp1; -+ struct cvmx_usbcx_hptxsts_s cn56xx; -+ struct cvmx_usbcx_hptxsts_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_nptxdfifox { -+ uint32_t u32; -+ struct cvmx_usbcx_nptxdfifox_s { -+ uint32_t data:32; -+ } s; -+ struct cvmx_usbcx_nptxdfifox_s cn30xx; -+ struct cvmx_usbcx_nptxdfifox_s cn31xx; -+ struct cvmx_usbcx_nptxdfifox_s cn50xx; -+ struct cvmx_usbcx_nptxdfifox_s cn52xx; -+ struct cvmx_usbcx_nptxdfifox_s cn52xxp1; -+ struct cvmx_usbcx_nptxdfifox_s cn56xx; -+ struct cvmx_usbcx_nptxdfifox_s cn56xxp1; -+}; -+ -+union cvmx_usbcx_pcgcctl { -+ uint32_t u32; -+ struct cvmx_usbcx_pcgcctl_s { -+ uint32_t reserved_5_31:27; -+ uint32_t physuspended:1; -+ uint32_t rstpdwnmodule:1; -+ uint32_t pwrclmp:1; -+ uint32_t gatehclk:1; -+ uint32_t stoppclk:1; -+ } s; -+ struct cvmx_usbcx_pcgcctl_s cn30xx; -+ struct cvmx_usbcx_pcgcctl_s cn31xx; -+ struct cvmx_usbcx_pcgcctl_s cn50xx; -+ struct cvmx_usbcx_pcgcctl_s cn52xx; -+ struct cvmx_usbcx_pcgcctl_s cn52xxp1; -+ struct cvmx_usbcx_pcgcctl_s cn56xx; -+ struct cvmx_usbcx_pcgcctl_s cn56xxp1; -+}; -+ -+#endif -diff --git a/arch/mips/include/asm/octeon/cvmx-usbnx-defs.h b/arch/mips/include/asm/octeon/cvmx-usbnx-defs.h -new file mode 100644 -index 0000000..90be974 ---- /dev/null -+++ b/arch/mips/include/asm/octeon/cvmx-usbnx-defs.h -@@ -0,0 +1,760 @@ -+/***********************license start*************** -+ * Author: Cavium Networks -+ * -+ * Contact: support@caviumnetworks.com -+ * This file is part of the OCTEON SDK -+ * -+ * Copyright (c) 2003-2008 Cavium Networks -+ * -+ * This file is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, Version 2, as -+ * published by the Free Software Foundation. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or -+ * NONINFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ * or visit http://www.gnu.org/licenses/. -+ * -+ * This file may also be available under a different license from Cavium. -+ * Contact Cavium Networks for more information -+ ***********************license end**************************************/ -+ -+#ifndef __CVMX_USBNX_DEFS_H__ -+#define __CVMX_USBNX_DEFS_H__ -+ -+#define CVMX_USBNX_BIST_STATUS(block_id) \ -+ CVMX_ADD_IO_SEG(0x00011800680007F8ull + (((block_id) & 1) * 0x10000000ull)) -+#define CVMX_USBNX_CLK_CTL(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180068000010ull + (((block_id) & 1) * 0x10000000ull)) -+#define CVMX_USBNX_CTL_STATUS(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000800ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_INB_CHN0(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000818ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_INB_CHN1(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000820ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_INB_CHN2(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000828ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_INB_CHN3(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000830ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_INB_CHN4(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000838ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_INB_CHN5(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000840ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_INB_CHN6(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000848ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_INB_CHN7(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000850ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_OUTB_CHN0(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000858ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_OUTB_CHN1(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000860ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_OUTB_CHN2(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000868ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_OUTB_CHN3(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000870ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_OUTB_CHN4(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000878ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_OUTB_CHN5(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000880ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_OUTB_CHN6(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000888ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA0_OUTB_CHN7(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000890ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_DMA_TEST(block_id) \ -+ CVMX_ADD_IO_SEG(0x00016F0000000808ull + (((block_id) & 1) * 0x100000000000ull)) -+#define CVMX_USBNX_INT_ENB(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180068000008ull + (((block_id) & 1) * 0x10000000ull)) -+#define CVMX_USBNX_INT_SUM(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180068000000ull + (((block_id) & 1) * 0x10000000ull)) -+#define CVMX_USBNX_USBP_CTL_STATUS(block_id) \ -+ CVMX_ADD_IO_SEG(0x0001180068000018ull + (((block_id) & 1) * 0x10000000ull)) -+ -+union cvmx_usbnx_bist_status { -+ uint64_t u64; -+ struct cvmx_usbnx_bist_status_s { -+ uint64_t reserved_7_63:57; -+ uint64_t u2nc_bis:1; -+ uint64_t u2nf_bis:1; -+ uint64_t e2hc_bis:1; -+ uint64_t n2uf_bis:1; -+ uint64_t usbc_bis:1; -+ uint64_t nif_bis:1; -+ uint64_t nof_bis:1; -+ } s; -+ struct cvmx_usbnx_bist_status_cn30xx { -+ uint64_t reserved_3_63:61; -+ uint64_t usbc_bis:1; -+ uint64_t nif_bis:1; -+ uint64_t nof_bis:1; -+ } cn30xx; -+ struct cvmx_usbnx_bist_status_cn30xx cn31xx; -+ struct cvmx_usbnx_bist_status_s cn50xx; -+ struct cvmx_usbnx_bist_status_s cn52xx; -+ struct cvmx_usbnx_bist_status_s cn52xxp1; -+ struct cvmx_usbnx_bist_status_s cn56xx; -+ struct cvmx_usbnx_bist_status_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_clk_ctl { -+ uint64_t u64; -+ struct cvmx_usbnx_clk_ctl_s { -+ uint64_t reserved_20_63:44; -+ uint64_t divide2:2; -+ uint64_t hclk_rst:1; -+ uint64_t p_x_on:1; -+ uint64_t reserved_14_15:2; -+ uint64_t p_com_on:1; -+ uint64_t p_c_sel:2; -+ uint64_t cdiv_byp:1; -+ uint64_t sd_mode:2; -+ uint64_t s_bist:1; -+ uint64_t por:1; -+ uint64_t enable:1; -+ uint64_t prst:1; -+ uint64_t hrst:1; -+ uint64_t divide:3; -+ } s; -+ struct cvmx_usbnx_clk_ctl_cn30xx { -+ uint64_t reserved_18_63:46; -+ uint64_t hclk_rst:1; -+ uint64_t p_x_on:1; -+ uint64_t p_rclk:1; -+ uint64_t p_xenbn:1; -+ uint64_t p_com_on:1; -+ uint64_t p_c_sel:2; -+ uint64_t cdiv_byp:1; -+ uint64_t sd_mode:2; -+ uint64_t s_bist:1; -+ uint64_t por:1; -+ uint64_t enable:1; -+ uint64_t prst:1; -+ uint64_t hrst:1; -+ uint64_t divide:3; -+ } cn30xx; -+ struct cvmx_usbnx_clk_ctl_cn30xx cn31xx; -+ struct cvmx_usbnx_clk_ctl_cn50xx { -+ uint64_t reserved_20_63:44; -+ uint64_t divide2:2; -+ uint64_t hclk_rst:1; -+ uint64_t reserved_16_16:1; -+ uint64_t p_rtype:2; -+ uint64_t p_com_on:1; -+ uint64_t p_c_sel:2; -+ uint64_t cdiv_byp:1; -+ uint64_t sd_mode:2; -+ uint64_t s_bist:1; -+ uint64_t por:1; -+ uint64_t enable:1; -+ uint64_t prst:1; -+ uint64_t hrst:1; -+ uint64_t divide:3; -+ } cn50xx; -+ struct cvmx_usbnx_clk_ctl_cn50xx cn52xx; -+ struct cvmx_usbnx_clk_ctl_cn50xx cn52xxp1; -+ struct cvmx_usbnx_clk_ctl_cn50xx cn56xx; -+ struct cvmx_usbnx_clk_ctl_cn50xx cn56xxp1; -+}; -+ -+union cvmx_usbnx_ctl_status { -+ uint64_t u64; -+ struct cvmx_usbnx_ctl_status_s { -+ uint64_t reserved_6_63:58; -+ uint64_t dma_0pag:1; -+ uint64_t dma_stt:1; -+ uint64_t dma_test:1; -+ uint64_t inv_a2:1; -+ uint64_t l2c_emod:2; -+ } s; -+ struct cvmx_usbnx_ctl_status_s cn30xx; -+ struct cvmx_usbnx_ctl_status_s cn31xx; -+ struct cvmx_usbnx_ctl_status_s cn50xx; -+ struct cvmx_usbnx_ctl_status_s cn52xx; -+ struct cvmx_usbnx_ctl_status_s cn52xxp1; -+ struct cvmx_usbnx_ctl_status_s cn56xx; -+ struct cvmx_usbnx_ctl_status_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_inb_chn0 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_inb_chn0_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_inb_chn0_s cn30xx; -+ struct cvmx_usbnx_dma0_inb_chn0_s cn31xx; -+ struct cvmx_usbnx_dma0_inb_chn0_s cn50xx; -+ struct cvmx_usbnx_dma0_inb_chn0_s cn52xx; -+ struct cvmx_usbnx_dma0_inb_chn0_s cn52xxp1; -+ struct cvmx_usbnx_dma0_inb_chn0_s cn56xx; -+ struct cvmx_usbnx_dma0_inb_chn0_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_inb_chn1 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_inb_chn1_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_inb_chn1_s cn30xx; -+ struct cvmx_usbnx_dma0_inb_chn1_s cn31xx; -+ struct cvmx_usbnx_dma0_inb_chn1_s cn50xx; -+ struct cvmx_usbnx_dma0_inb_chn1_s cn52xx; -+ struct cvmx_usbnx_dma0_inb_chn1_s cn52xxp1; -+ struct cvmx_usbnx_dma0_inb_chn1_s cn56xx; -+ struct cvmx_usbnx_dma0_inb_chn1_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_inb_chn2 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_inb_chn2_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_inb_chn2_s cn30xx; -+ struct cvmx_usbnx_dma0_inb_chn2_s cn31xx; -+ struct cvmx_usbnx_dma0_inb_chn2_s cn50xx; -+ struct cvmx_usbnx_dma0_inb_chn2_s cn52xx; -+ struct cvmx_usbnx_dma0_inb_chn2_s cn52xxp1; -+ struct cvmx_usbnx_dma0_inb_chn2_s cn56xx; -+ struct cvmx_usbnx_dma0_inb_chn2_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_inb_chn3 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_inb_chn3_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_inb_chn3_s cn30xx; -+ struct cvmx_usbnx_dma0_inb_chn3_s cn31xx; -+ struct cvmx_usbnx_dma0_inb_chn3_s cn50xx; -+ struct cvmx_usbnx_dma0_inb_chn3_s cn52xx; -+ struct cvmx_usbnx_dma0_inb_chn3_s cn52xxp1; -+ struct cvmx_usbnx_dma0_inb_chn3_s cn56xx; -+ struct cvmx_usbnx_dma0_inb_chn3_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_inb_chn4 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_inb_chn4_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_inb_chn4_s cn30xx; -+ struct cvmx_usbnx_dma0_inb_chn4_s cn31xx; -+ struct cvmx_usbnx_dma0_inb_chn4_s cn50xx; -+ struct cvmx_usbnx_dma0_inb_chn4_s cn52xx; -+ struct cvmx_usbnx_dma0_inb_chn4_s cn52xxp1; -+ struct cvmx_usbnx_dma0_inb_chn4_s cn56xx; -+ struct cvmx_usbnx_dma0_inb_chn4_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_inb_chn5 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_inb_chn5_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_inb_chn5_s cn30xx; -+ struct cvmx_usbnx_dma0_inb_chn5_s cn31xx; -+ struct cvmx_usbnx_dma0_inb_chn5_s cn50xx; -+ struct cvmx_usbnx_dma0_inb_chn5_s cn52xx; -+ struct cvmx_usbnx_dma0_inb_chn5_s cn52xxp1; -+ struct cvmx_usbnx_dma0_inb_chn5_s cn56xx; -+ struct cvmx_usbnx_dma0_inb_chn5_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_inb_chn6 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_inb_chn6_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_inb_chn6_s cn30xx; -+ struct cvmx_usbnx_dma0_inb_chn6_s cn31xx; -+ struct cvmx_usbnx_dma0_inb_chn6_s cn50xx; -+ struct cvmx_usbnx_dma0_inb_chn6_s cn52xx; -+ struct cvmx_usbnx_dma0_inb_chn6_s cn52xxp1; -+ struct cvmx_usbnx_dma0_inb_chn6_s cn56xx; -+ struct cvmx_usbnx_dma0_inb_chn6_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_inb_chn7 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_inb_chn7_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_inb_chn7_s cn30xx; -+ struct cvmx_usbnx_dma0_inb_chn7_s cn31xx; -+ struct cvmx_usbnx_dma0_inb_chn7_s cn50xx; -+ struct cvmx_usbnx_dma0_inb_chn7_s cn52xx; -+ struct cvmx_usbnx_dma0_inb_chn7_s cn52xxp1; -+ struct cvmx_usbnx_dma0_inb_chn7_s cn56xx; -+ struct cvmx_usbnx_dma0_inb_chn7_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_outb_chn0 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_outb_chn0_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_outb_chn0_s cn30xx; -+ struct cvmx_usbnx_dma0_outb_chn0_s cn31xx; -+ struct cvmx_usbnx_dma0_outb_chn0_s cn50xx; -+ struct cvmx_usbnx_dma0_outb_chn0_s cn52xx; -+ struct cvmx_usbnx_dma0_outb_chn0_s cn52xxp1; -+ struct cvmx_usbnx_dma0_outb_chn0_s cn56xx; -+ struct cvmx_usbnx_dma0_outb_chn0_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_outb_chn1 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_outb_chn1_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_outb_chn1_s cn30xx; -+ struct cvmx_usbnx_dma0_outb_chn1_s cn31xx; -+ struct cvmx_usbnx_dma0_outb_chn1_s cn50xx; -+ struct cvmx_usbnx_dma0_outb_chn1_s cn52xx; -+ struct cvmx_usbnx_dma0_outb_chn1_s cn52xxp1; -+ struct cvmx_usbnx_dma0_outb_chn1_s cn56xx; -+ struct cvmx_usbnx_dma0_outb_chn1_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_outb_chn2 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_outb_chn2_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_outb_chn2_s cn30xx; -+ struct cvmx_usbnx_dma0_outb_chn2_s cn31xx; -+ struct cvmx_usbnx_dma0_outb_chn2_s cn50xx; -+ struct cvmx_usbnx_dma0_outb_chn2_s cn52xx; -+ struct cvmx_usbnx_dma0_outb_chn2_s cn52xxp1; -+ struct cvmx_usbnx_dma0_outb_chn2_s cn56xx; -+ struct cvmx_usbnx_dma0_outb_chn2_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_outb_chn3 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_outb_chn3_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_outb_chn3_s cn30xx; -+ struct cvmx_usbnx_dma0_outb_chn3_s cn31xx; -+ struct cvmx_usbnx_dma0_outb_chn3_s cn50xx; -+ struct cvmx_usbnx_dma0_outb_chn3_s cn52xx; -+ struct cvmx_usbnx_dma0_outb_chn3_s cn52xxp1; -+ struct cvmx_usbnx_dma0_outb_chn3_s cn56xx; -+ struct cvmx_usbnx_dma0_outb_chn3_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_outb_chn4 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_outb_chn4_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_outb_chn4_s cn30xx; -+ struct cvmx_usbnx_dma0_outb_chn4_s cn31xx; -+ struct cvmx_usbnx_dma0_outb_chn4_s cn50xx; -+ struct cvmx_usbnx_dma0_outb_chn4_s cn52xx; -+ struct cvmx_usbnx_dma0_outb_chn4_s cn52xxp1; -+ struct cvmx_usbnx_dma0_outb_chn4_s cn56xx; -+ struct cvmx_usbnx_dma0_outb_chn4_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_outb_chn5 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_outb_chn5_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_outb_chn5_s cn30xx; -+ struct cvmx_usbnx_dma0_outb_chn5_s cn31xx; -+ struct cvmx_usbnx_dma0_outb_chn5_s cn50xx; -+ struct cvmx_usbnx_dma0_outb_chn5_s cn52xx; -+ struct cvmx_usbnx_dma0_outb_chn5_s cn52xxp1; -+ struct cvmx_usbnx_dma0_outb_chn5_s cn56xx; -+ struct cvmx_usbnx_dma0_outb_chn5_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_outb_chn6 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_outb_chn6_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_outb_chn6_s cn30xx; -+ struct cvmx_usbnx_dma0_outb_chn6_s cn31xx; -+ struct cvmx_usbnx_dma0_outb_chn6_s cn50xx; -+ struct cvmx_usbnx_dma0_outb_chn6_s cn52xx; -+ struct cvmx_usbnx_dma0_outb_chn6_s cn52xxp1; -+ struct cvmx_usbnx_dma0_outb_chn6_s cn56xx; -+ struct cvmx_usbnx_dma0_outb_chn6_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma0_outb_chn7 { -+ uint64_t u64; -+ struct cvmx_usbnx_dma0_outb_chn7_s { -+ uint64_t reserved_36_63:28; -+ uint64_t addr:36; -+ } s; -+ struct cvmx_usbnx_dma0_outb_chn7_s cn30xx; -+ struct cvmx_usbnx_dma0_outb_chn7_s cn31xx; -+ struct cvmx_usbnx_dma0_outb_chn7_s cn50xx; -+ struct cvmx_usbnx_dma0_outb_chn7_s cn52xx; -+ struct cvmx_usbnx_dma0_outb_chn7_s cn52xxp1; -+ struct cvmx_usbnx_dma0_outb_chn7_s cn56xx; -+ struct cvmx_usbnx_dma0_outb_chn7_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_dma_test { -+ uint64_t u64; -+ struct cvmx_usbnx_dma_test_s { -+ uint64_t reserved_40_63:24; -+ uint64_t done:1; -+ uint64_t req:1; -+ uint64_t f_addr:18; -+ uint64_t count:11; -+ uint64_t channel:5; -+ uint64_t burst:4; -+ } s; -+ struct cvmx_usbnx_dma_test_s cn30xx; -+ struct cvmx_usbnx_dma_test_s cn31xx; -+ struct cvmx_usbnx_dma_test_s cn50xx; -+ struct cvmx_usbnx_dma_test_s cn52xx; -+ struct cvmx_usbnx_dma_test_s cn52xxp1; -+ struct cvmx_usbnx_dma_test_s cn56xx; -+ struct cvmx_usbnx_dma_test_s cn56xxp1; -+}; -+ -+union cvmx_usbnx_int_enb { -+ uint64_t u64; -+ struct cvmx_usbnx_int_enb_s { -+ uint64_t reserved_38_63:26; -+ uint64_t nd4o_dpf:1; -+ uint64_t nd4o_dpe:1; -+ uint64_t nd4o_rpf:1; -+ uint64_t nd4o_rpe:1; -+ uint64_t ltl_f_pf:1; -+ uint64_t ltl_f_pe:1; -+ uint64_t u2n_c_pe:1; -+ uint64_t u2n_c_pf:1; -+ uint64_t u2n_d_pf:1; -+ uint64_t u2n_d_pe:1; -+ uint64_t n2u_pe:1; -+ uint64_t n2u_pf:1; -+ uint64_t uod_pf:1; -+ uint64_t uod_pe:1; -+ uint64_t rq_q3_e:1; -+ uint64_t rq_q3_f:1; -+ uint64_t rq_q2_e:1; -+ uint64_t rq_q2_f:1; -+ uint64_t rg_fi_f:1; -+ uint64_t rg_fi_e:1; -+ uint64_t l2_fi_f:1; -+ uint64_t l2_fi_e:1; -+ uint64_t l2c_a_f:1; -+ uint64_t l2c_s_e:1; -+ uint64_t dcred_f:1; -+ uint64_t dcred_e:1; -+ uint64_t lt_pu_f:1; -+ uint64_t lt_po_e:1; -+ uint64_t nt_pu_f:1; -+ uint64_t nt_po_e:1; -+ uint64_t pt_pu_f:1; -+ uint64_t pt_po_e:1; -+ uint64_t lr_pu_f:1; -+ uint64_t lr_po_e:1; -+ uint64_t nr_pu_f:1; -+ uint64_t nr_po_e:1; -+ uint64_t pr_pu_f:1; -+ uint64_t pr_po_e:1; -+ } s; -+ struct cvmx_usbnx_int_enb_s cn30xx; -+ struct cvmx_usbnx_int_enb_s cn31xx; -+ struct cvmx_usbnx_int_enb_cn50xx { -+ uint64_t reserved_38_63:26; -+ uint64_t nd4o_dpf:1; -+ uint64_t nd4o_dpe:1; -+ uint64_t nd4o_rpf:1; -+ uint64_t nd4o_rpe:1; -+ uint64_t ltl_f_pf:1; -+ uint64_t ltl_f_pe:1; -+ uint64_t reserved_26_31:6; -+ uint64_t uod_pf:1; -+ uint64_t uod_pe:1; -+ uint64_t rq_q3_e:1; -+ uint64_t rq_q3_f:1; -+ uint64_t rq_q2_e:1; -+ uint64_t rq_q2_f:1; -+ uint64_t rg_fi_f:1; -+ uint64_t rg_fi_e:1; -+ uint64_t l2_fi_f:1; -+ uint64_t l2_fi_e:1; -+ uint64_t l2c_a_f:1; -+ uint64_t l2c_s_e:1; -+ uint64_t dcred_f:1; -+ uint64_t dcred_e:1; -+ uint64_t lt_pu_f:1; -+ uint64_t lt_po_e:1; -+ uint64_t nt_pu_f:1; -+ uint64_t nt_po_e:1; -+ uint64_t pt_pu_f:1; -+ uint64_t pt_po_e:1; -+ uint64_t lr_pu_f:1; -+ uint64_t lr_po_e:1; -+ uint64_t nr_pu_f:1; -+ uint64_t nr_po_e:1; -+ uint64_t pr_pu_f:1; -+ uint64_t pr_po_e:1; -+ } cn50xx; -+ struct cvmx_usbnx_int_enb_cn50xx cn52xx; -+ struct cvmx_usbnx_int_enb_cn50xx cn52xxp1; -+ struct cvmx_usbnx_int_enb_cn50xx cn56xx; -+ struct cvmx_usbnx_int_enb_cn50xx cn56xxp1; -+}; -+ -+union cvmx_usbnx_int_sum { -+ uint64_t u64; -+ struct cvmx_usbnx_int_sum_s { -+ uint64_t reserved_38_63:26; -+ uint64_t nd4o_dpf:1; -+ uint64_t nd4o_dpe:1; -+ uint64_t nd4o_rpf:1; -+ uint64_t nd4o_rpe:1; -+ uint64_t ltl_f_pf:1; -+ uint64_t ltl_f_pe:1; -+ uint64_t u2n_c_pe:1; -+ uint64_t u2n_c_pf:1; -+ uint64_t u2n_d_pf:1; -+ uint64_t u2n_d_pe:1; -+ uint64_t n2u_pe:1; -+ uint64_t n2u_pf:1; -+ uint64_t uod_pf:1; -+ uint64_t uod_pe:1; -+ uint64_t rq_q3_e:1; -+ uint64_t rq_q3_f:1; -+ uint64_t rq_q2_e:1; -+ uint64_t rq_q2_f:1; -+ uint64_t rg_fi_f:1; -+ uint64_t rg_fi_e:1; -+ uint64_t lt_fi_f:1; -+ uint64_t lt_fi_e:1; -+ uint64_t l2c_a_f:1; -+ uint64_t l2c_s_e:1; -+ uint64_t dcred_f:1; -+ uint64_t dcred_e:1; -+ uint64_t lt_pu_f:1; -+ uint64_t lt_po_e:1; -+ uint64_t nt_pu_f:1; -+ uint64_t nt_po_e:1; -+ uint64_t pt_pu_f:1; -+ uint64_t pt_po_e:1; -+ uint64_t lr_pu_f:1; -+ uint64_t lr_po_e:1; -+ uint64_t nr_pu_f:1; -+ uint64_t nr_po_e:1; -+ uint64_t pr_pu_f:1; -+ uint64_t pr_po_e:1; -+ } s; -+ struct cvmx_usbnx_int_sum_s cn30xx; -+ struct cvmx_usbnx_int_sum_s cn31xx; -+ struct cvmx_usbnx_int_sum_cn50xx { -+ uint64_t reserved_38_63:26; -+ uint64_t nd4o_dpf:1; -+ uint64_t nd4o_dpe:1; -+ uint64_t nd4o_rpf:1; -+ uint64_t nd4o_rpe:1; -+ uint64_t ltl_f_pf:1; -+ uint64_t ltl_f_pe:1; -+ uint64_t reserved_26_31:6; -+ uint64_t uod_pf:1; -+ uint64_t uod_pe:1; -+ uint64_t rq_q3_e:1; -+ uint64_t rq_q3_f:1; -+ uint64_t rq_q2_e:1; -+ uint64_t rq_q2_f:1; -+ uint64_t rg_fi_f:1; -+ uint64_t rg_fi_e:1; -+ uint64_t lt_fi_f:1; -+ uint64_t lt_fi_e:1; -+ uint64_t l2c_a_f:1; -+ uint64_t l2c_s_e:1; -+ uint64_t dcred_f:1; -+ uint64_t dcred_e:1; -+ uint64_t lt_pu_f:1; -+ uint64_t lt_po_e:1; -+ uint64_t nt_pu_f:1; -+ uint64_t nt_po_e:1; -+ uint64_t pt_pu_f:1; -+ uint64_t pt_po_e:1; -+ uint64_t lr_pu_f:1; -+ uint64_t lr_po_e:1; -+ uint64_t nr_pu_f:1; -+ uint64_t nr_po_e:1; -+ uint64_t pr_pu_f:1; -+ uint64_t pr_po_e:1; -+ } cn50xx; -+ struct cvmx_usbnx_int_sum_cn50xx cn52xx; -+ struct cvmx_usbnx_int_sum_cn50xx cn52xxp1; -+ struct cvmx_usbnx_int_sum_cn50xx cn56xx; -+ struct cvmx_usbnx_int_sum_cn50xx cn56xxp1; -+}; -+ -+union cvmx_usbnx_usbp_ctl_status { -+ uint64_t u64; -+ struct cvmx_usbnx_usbp_ctl_status_s { -+ uint64_t txrisetune:1; -+ uint64_t txvreftune:4; -+ uint64_t txfslstune:4; -+ uint64_t txhsxvtune:2; -+ uint64_t sqrxtune:3; -+ uint64_t compdistune:3; -+ uint64_t otgtune:3; -+ uint64_t otgdisable:1; -+ uint64_t portreset:1; -+ uint64_t drvvbus:1; -+ uint64_t lsbist:1; -+ uint64_t fsbist:1; -+ uint64_t hsbist:1; -+ uint64_t bist_done:1; -+ uint64_t bist_err:1; -+ uint64_t tdata_out:4; -+ uint64_t siddq:1; -+ uint64_t txpreemphasistune:1; -+ uint64_t dma_bmode:1; -+ uint64_t usbc_end:1; -+ uint64_t usbp_bist:1; -+ uint64_t tclk:1; -+ uint64_t dp_pulld:1; -+ uint64_t dm_pulld:1; -+ uint64_t hst_mode:1; -+ uint64_t tuning:4; -+ uint64_t tx_bs_enh:1; -+ uint64_t tx_bs_en:1; -+ uint64_t loop_enb:1; -+ uint64_t vtest_enb:1; -+ uint64_t bist_enb:1; -+ uint64_t tdata_sel:1; -+ uint64_t taddr_in:4; -+ uint64_t tdata_in:8; -+ uint64_t ate_reset:1; -+ } s; -+ struct cvmx_usbnx_usbp_ctl_status_cn30xx { -+ uint64_t reserved_38_63:26; -+ uint64_t bist_done:1; -+ uint64_t bist_err:1; -+ uint64_t tdata_out:4; -+ uint64_t reserved_30_31:2; -+ uint64_t dma_bmode:1; -+ uint64_t usbc_end:1; -+ uint64_t usbp_bist:1; -+ uint64_t tclk:1; -+ uint64_t dp_pulld:1; -+ uint64_t dm_pulld:1; -+ uint64_t hst_mode:1; -+ uint64_t tuning:4; -+ uint64_t tx_bs_enh:1; -+ uint64_t tx_bs_en:1; -+ uint64_t loop_enb:1; -+ uint64_t vtest_enb:1; -+ uint64_t bist_enb:1; -+ uint64_t tdata_sel:1; -+ uint64_t taddr_in:4; -+ uint64_t tdata_in:8; -+ uint64_t ate_reset:1; -+ } cn30xx; -+ struct cvmx_usbnx_usbp_ctl_status_cn30xx cn31xx; -+ struct cvmx_usbnx_usbp_ctl_status_cn50xx { -+ uint64_t txrisetune:1; -+ uint64_t txvreftune:4; -+ uint64_t txfslstune:4; -+ uint64_t txhsxvtune:2; -+ uint64_t sqrxtune:3; -+ uint64_t compdistune:3; -+ uint64_t otgtune:3; -+ uint64_t otgdisable:1; -+ uint64_t portreset:1; -+ uint64_t drvvbus:1; -+ uint64_t lsbist:1; -+ uint64_t fsbist:1; -+ uint64_t hsbist:1; -+ uint64_t bist_done:1; -+ uint64_t bist_err:1; -+ uint64_t tdata_out:4; -+ uint64_t reserved_31_31:1; -+ uint64_t txpreemphasistune:1; -+ uint64_t dma_bmode:1; -+ uint64_t usbc_end:1; -+ uint64_t usbp_bist:1; -+ uint64_t tclk:1; -+ uint64_t dp_pulld:1; -+ uint64_t dm_pulld:1; -+ uint64_t hst_mode:1; -+ uint64_t reserved_19_22:4; -+ uint64_t tx_bs_enh:1; -+ uint64_t tx_bs_en:1; -+ uint64_t loop_enb:1; -+ uint64_t vtest_enb:1; -+ uint64_t bist_enb:1; -+ uint64_t tdata_sel:1; -+ uint64_t taddr_in:4; -+ uint64_t tdata_in:8; -+ uint64_t ate_reset:1; -+ } cn50xx; -+ struct cvmx_usbnx_usbp_ctl_status_cn50xx cn52xx; -+ struct cvmx_usbnx_usbp_ctl_status_cn50xx cn52xxp1; -+ struct cvmx_usbnx_usbp_ctl_status_cn56xx { -+ uint64_t txrisetune:1; -+ uint64_t txvreftune:4; -+ uint64_t txfslstune:4; -+ uint64_t txhsxvtune:2; -+ uint64_t sqrxtune:3; -+ uint64_t compdistune:3; -+ uint64_t otgtune:3; -+ uint64_t otgdisable:1; -+ uint64_t portreset:1; -+ uint64_t drvvbus:1; -+ uint64_t lsbist:1; -+ uint64_t fsbist:1; -+ uint64_t hsbist:1; -+ uint64_t bist_done:1; -+ uint64_t bist_err:1; -+ uint64_t tdata_out:4; -+ uint64_t siddq:1; -+ uint64_t txpreemphasistune:1; -+ uint64_t dma_bmode:1; -+ uint64_t usbc_end:1; -+ uint64_t usbp_bist:1; -+ uint64_t tclk:1; -+ uint64_t dp_pulld:1; -+ uint64_t dm_pulld:1; -+ uint64_t hst_mode:1; -+ uint64_t reserved_19_22:4; -+ uint64_t tx_bs_enh:1; -+ uint64_t tx_bs_en:1; -+ uint64_t loop_enb:1; -+ uint64_t vtest_enb:1; -+ uint64_t bist_enb:1; -+ uint64_t tdata_sel:1; -+ uint64_t taddr_in:4; -+ uint64_t tdata_in:8; -+ uint64_t ate_reset:1; -+ } cn56xx; -+ struct cvmx_usbnx_usbp_ctl_status_cn50xx cn56xxp1; -+}; -+ -+#endif --- -1.6.0.6 - --- -To unsubscribe from this list: send the line "unsubscribe linux-usb" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.htmlSigned-off-by: David Daney <ddaney@caviumnetworks.com> ---- - drivers/usb/host/Kconfig | 8 + - drivers/usb/host/Makefile | 1 + - drivers/usb/host/dwc_otg/Kbuild | 16 + - drivers/usb/host/dwc_otg/dwc_otg_attr.c | 854 ++++++++ - drivers/usb/host/dwc_otg/dwc_otg_attr.h | 63 + - drivers/usb/host/dwc_otg/dwc_otg_cil.c | 2887 ++++++++++++++++++++++++++ - drivers/usb/host/dwc_otg/dwc_otg_cil.h | 866 ++++++++ - drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 689 ++++++ - drivers/usb/host/dwc_otg/dwc_otg_driver.h | 63 + - drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 2878 +++++++++++++++++++++++++ - drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 661 ++++++ - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 1890 +++++++++++++++++ - drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 695 +++++++ - drivers/usb/host/dwc_otg/dwc_otg_octeon.c | 1078 ++++++++++ - drivers/usb/host/dwc_otg/dwc_otg_plat.h | 236 +++ - drivers/usb/host/dwc_otg/dwc_otg_regs.h | 2355 +++++++++++++++++++++ - 16 files changed, 15240 insertions(+), 0 deletions(-) - create mode 100644 drivers/usb/host/dwc_otg/Kbuild - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_attr.c - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_attr.h - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_cil.c - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_cil.h - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_driver.h - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd.c - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd.h - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_octeon.c - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_plat.h - create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_regs.h - -diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig -index 9b43b22..342dc54 100644 ---- a/drivers/usb/host/Kconfig -+++ b/drivers/usb/host/Kconfig -@@ -381,3 +381,11 @@ config USB_HWA_HCD - - To compile this driver a module, choose M here: the module - will be called "hwa-hc". -+ -+config USB_DWC_OTG -+ tristate "Cavium Octeon USB" -+ depends on USB && CPU_CAVIUM_OCTEON -+ ---help--- -+ The Cavium Octeon on-chip USB controller. To compile this -+ driver as a module, choose M here: the module will be called -+ "dwc_otg". -diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile -index f58b249..76faf12 100644 ---- a/drivers/usb/host/Makefile -+++ b/drivers/usb/host/Makefile -@@ -15,6 +15,7 @@ endif - xhci-objs := xhci-hcd.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o - - obj-$(CONFIG_USB_WHCI_HCD) += whci/ -+obj-$(CONFIG_USB_DWC_OTG) += dwc_otg/ - - obj-$(CONFIG_PCI) += pci-quirks.o - -diff --git a/drivers/usb/host/dwc_otg/Kbuild b/drivers/usb/host/dwc_otg/Kbuild -new file mode 100644 -index 0000000..cb32638 ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/Kbuild -@@ -0,0 +1,16 @@ -+# -+# Makefile for DWC_otg Highspeed USB controller driver -+# -+ -+# Use one of the following flags to compile the software in host-only or -+# device-only mode. -+#EXTRA_CFLAGS += -DDWC_HOST_ONLY -+#EXTRA_CFLAGS += -DDWC_DEVICE_ONLY -+ -+EXTRA_CFLAGS += -DDWC_HOST_ONLY -+obj-$(CONFIG_USB_DWC_OTG) += dwc_otg.o -+ -+dwc_otg-y := dwc_otg_octeon.o dwc_otg_attr.o -+dwc_otg-y += dwc_otg_cil.o dwc_otg_cil_intr.o -+dwc_otg-y += dwc_otg_hcd.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o -+ -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_attr.c b/drivers/usb/host/dwc_otg/dwc_otg_attr.c -new file mode 100644 -index 0000000..d854a79 ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_attr.c -@@ -0,0 +1,854 @@ -+/* ========================================================================== -+ * -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+ -+/* -+ * -+ * The diagnostic interface will provide access to the controller for -+ * bringing up the hardware and testing. The Linux driver attributes -+ * feature will be used to provide the Linux Diagnostic -+ * Interface. These attributes are accessed through sysfs. -+ */ -+ -+/** @page "Linux Module Attributes" -+ * -+ * The Linux module attributes feature is used to provide the Linux -+ * Diagnostic Interface. These attributes are accessed through sysfs. -+ * The diagnostic interface will provide access to the controller for -+ * bringing up the hardware and testing. -+ -+ The following table shows the attributes. -+ <table> -+ <tr> -+ <td><b> Name</b></td> -+ <td><b> Description</b></td> -+ <td><b> Access</b></td> -+ </tr> -+ -+ <tr> -+ <td> mode </td> -+ <td> Returns the current mode: 0 for device mode, 1 for host mode</td> -+ <td> Read</td> -+ </tr> -+ -+ <tr> -+ <td> hnpcapable </td> -+ <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register. -+ Read returns the current value.</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> srpcapable </td> -+ <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register. -+ Read returns the current value.</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> hnp </td> -+ <td> Initiates the Host Negotiation Protocol. Read returns the status.</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> srp </td> -+ <td> Initiates the Session Request Protocol. Read returns the status.</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> buspower </td> -+ <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> bussuspend </td> -+ <td> Suspends the USB bus.</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> busconnected </td> -+ <td> Gets the connection status of the bus</td> -+ <td> Read</td> -+ </tr> -+ -+ <tr> -+ <td> gotgctl </td> -+ <td> Gets or sets the Core Control Status Register.</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> gusbcfg </td> -+ <td> Gets or sets the Core USB Configuration Register</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> grxfsiz </td> -+ <td> Gets or sets the Receive FIFO Size Register</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> gnptxfsiz </td> -+ <td> Gets or sets the non-periodic Transmit Size Register</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> gpvndctl </td> -+ <td> Gets or sets the PHY Vendor Control Register</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> ggpio </td> -+ <td> Gets the value in the lower 16-bits of the General Purpose IO Register -+ or sets the upper 16 bits.</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> guid </td> -+ <td> Gets or sets the value of the User ID Register</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> gsnpsid </td> -+ <td> Gets the value of the Synopsys ID Regester</td> -+ <td> Read</td> -+ </tr> -+ -+ <tr> -+ <td> devspeed </td> -+ <td> Gets or sets the device speed setting in the DCFG register</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> enumspeed </td> -+ <td> Gets the device enumeration Speed.</td> -+ <td> Read</td> -+ </tr> -+ -+ <tr> -+ <td> hptxfsiz </td> -+ <td> Gets the value of the Host Periodic Transmit FIFO</td> -+ <td> Read</td> -+ </tr> -+ -+ <tr> -+ <td> hprt0 </td> -+ <td> Gets or sets the value in the Host Port Control and Status Register</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> regoffset </td> -+ <td> Sets the register offset for the next Register Access</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> regvalue </td> -+ <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> remote_wakeup </td> -+ <td> On read, shows the status of Remote Wakeup. On write, initiates a remote -+ wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote -+ Wakeup signalling bit in the Device Control Register is set for 1 -+ milli-second.</td> -+ <td> Read/Write</td> -+ </tr> -+ -+ <tr> -+ <td> regdump </td> -+ <td> Dumps the contents of core registers.</td> -+ <td> Read</td> -+ </tr> -+ -+ <tr> -+ <td> hcddump </td> -+ <td> Dumps the current HCD state.</td> -+ <td> Read</td> -+ </tr> -+ -+ <tr> -+ <td> hcd_frrem </td> -+ <td> Shows the average value of the Frame Remaining -+ field in the Host Frame Number/Frame Remaining register when an SOF interrupt -+ occurs. This can be used to determine the average interrupt latency. Also -+ shows the average Frame Remaining value for start_transfer and the "a" and -+ "b" sample points. The "a" and "b" sample points may be used during debugging -+ bto determine how long it takes to execute a section of the HCD code.</td> -+ <td> Read</td> -+ </tr> -+ -+ <tr> -+ <td> rd_reg_test </td> -+ <td> Displays the time required to read the GNPTXFSIZ register many times -+ (the output shows the number of times the register is read). -+ <td> Read</td> -+ </tr> -+ -+ <tr> -+ <td> wr_reg_test </td> -+ <td> Displays the time required to write the GNPTXFSIZ register many times -+ (the output shows the number of times the register is written). -+ <td> Read</td> -+ </tr> -+ -+ </table> -+ -+ Example usage: -+ To get the current mode: -+ cat /sys/devices/lm0/mode -+ -+ To power down the USB: -+ echo 0 > /sys/devices/lm0/buspower -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/init.h> -+#include <linux/device.h> -+#include <linux/errno.h> -+#include <linux/types.h> -+#include <linux/stat.h> /* permission constants */ -+ -+#include <asm/io.h> -+ -+#include "dwc_otg_plat.h" -+#include "dwc_otg_attr.h" -+#include "dwc_otg_driver.h" -+#ifndef DWC_HOST_ONLY -+#include "dwc_otg_pcd.h" -+#endif -+#include "dwc_otg_hcd.h" -+ -+/* -+ * MACROs for defining sysfs attribute -+ */ -+#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_, _addr_, \ -+ _mask_, _shift_, _string_) \ -+ static ssize_t _otg_attr_name_##_show (struct device *_dev, \ -+ struct device_attribute *attr, \ -+ char *buf) \ -+ { \ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; \ -+ uint32_t val; \ -+ val = dwc_read_reg32(_addr_); \ -+ val = (val & (_mask_)) >> _shift_; \ -+ return sprintf(buf, "%s = 0x%x\n", _string_, val); \ -+ } -+ -+#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_, _addr_, \ -+ _mask_, _shift_, _string_) \ -+ static ssize_t _otg_attr_name_##_store (struct device *_dev, \ -+ struct device_attribute *attr, \ -+ const char *buf, size_t count) \ -+ { \ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; \ -+ uint32_t set = simple_strtoul(buf, NULL, 16); \ -+ uint32_t clear = set; \ -+ clear = ((~clear) << _shift_) & _mask_; \ -+ set = (set << _shift_) & _mask_; \ -+ dev_dbg(_dev, \ -+ "Storing Address=%p Set=0x%08x Clear=0x%08x\n", \ -+ _addr_, set, clear); \ -+ dwc_modify_reg32(_addr_, clear, set); \ -+ return count; \ -+ } -+ -+#define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_, _addr_, \ -+ _mask_, _shift_, _string_) \ -+ DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_, _addr_, \ -+ _mask_, _shift_, _string_) \ -+ DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_, _addr_, \ -+ _mask_, _shift_, _string_) \ -+ DEVICE_ATTR(_otg_attr_name_, 0644, _otg_attr_name_##_show, \ -+ _otg_attr_name_##_store); -+ -+#define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_, _addr_, \ -+ _mask_, _shift_, _string_) \ -+ DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_, \ -+ _addr_, _mask_, _shift_, _string_) \ -+ DEVICE_ATTR(_otg_attr_name_, 0444, _otg_attr_name_##_show, NULL); -+ -+/* -+ * MACROs for defining sysfs attribute for 32-bit registers -+ */ -+#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_, _addr_, _string_) \ -+ static ssize_t _otg_attr_name_##_show(struct device *_dev, \ -+ struct device_attribute *attr, \ -+ char *buf) \ -+ { \ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; \ -+ uint32_t val; \ -+ val = dwc_read_reg32(_addr_); \ -+ return sprintf(buf, "%s = 0x%08x\n", _string_, val); \ -+ } -+ -+#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_, _addr_, _string_) \ -+ static ssize_t _otg_attr_name_##_store(struct device *_dev, \ -+ struct device_attribute *attr, \ -+ const char *buf, size_t count) \ -+ { \ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; \ -+ uint32_t val = simple_strtoul(buf, NULL, 16); \ -+ dev_dbg(_dev, "Storing Address=%p Val=0x%08x\n", _addr_, val); \ -+ dwc_write_reg32(_addr_, val); \ -+ return count; \ -+ } -+ -+#define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_, _addr_, _string_) \ -+ DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_, _addr_, _string_) \ -+ DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_, _addr_, _string_) \ -+ DEVICE_ATTR(_otg_attr_name_, 0644, _otg_attr_name_##_show, \ -+ _otg_attr_name_##_store); -+ -+#define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_, _addr_, _string_) \ -+ DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_, _addr_, _string_) \ -+ DEVICE_ATTR(_otg_attr_name_, 0444, _otg_attr_name_##_show, NULL); -+ -+/** -+ * Show the register offset of the Register Access. -+ */ -+static ssize_t regoffset_show(struct device *_dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ return snprintf(buf, sizeof("0xFFFFFFFF\n") + 1, "0x%08x\n", -+ otg_dev->reg_offset); -+} -+ -+/** -+ * Set the register offset for the next Register Access Read/Write -+ */ -+static ssize_t regoffset_store(struct device *_dev, -+ struct device_attribute *attr, const char *buf, -+ size_t count) -+{ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ uint32_t offset = simple_strtoul(buf, NULL, 16); -+ -+ if (offset < SZ_256K) -+ otg_dev->reg_offset = offset; -+ else -+ dev_err(_dev, "invalid offset\n"); -+ -+ return count; -+} -+ -+DEVICE_ATTR(regoffset, S_IRUGO | S_IWUSR, regoffset_show, regoffset_store); -+ -+/** -+ * Show the value of the register at the offset in the reg_offset -+ * attribute. -+ */ -+static ssize_t regvalue_show(struct device *_dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ uint32_t val; -+ uint32_t *addr; -+ -+ if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) { -+ /* Calculate the address */ -+ addr = (uint32_t *) (otg_dev->reg_offset + -+ (uint8_t *) otg_dev->base); -+ -+ val = dwc_read_reg32(addr); -+ return snprintf(buf, -+ sizeof("Reg@0xFFFFFFFF = 0xFFFFFFFF\n") + 1, -+ "Reg@0x%06x = 0x%08x\n", otg_dev->reg_offset, -+ val); -+ } else { -+ dev_err(_dev, "Invalid offset (0x%0x)\n", otg_dev->reg_offset); -+ return sprintf(buf, "invalid offset\n"); -+ } -+} -+ -+/** -+ * Store the value in the register at the offset in the reg_offset -+ * attribute. -+ * -+ */ -+static ssize_t regvalue_store(struct device *_dev, -+ struct device_attribute *attr, const char *buf, -+ size_t count) -+{ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ uint32_t *addr; -+ uint32_t val = simple_strtoul(buf, NULL, 16); -+ -+ if (otg_dev->reg_offset != 0xFFFFFFFF && 0 != otg_dev->base) { -+ /* Calculate the address */ -+ addr = (uint32_t *) (otg_dev->reg_offset + -+ (uint8_t *) otg_dev->base); -+ -+ dwc_write_reg32(addr, val); -+ } else { -+ dev_err(_dev, "Invalid Register Offset (0x%08x)\n", -+ otg_dev->reg_offset); -+ } -+ return count; -+} -+ -+DEVICE_ATTR(regvalue, S_IRUGO | S_IWUSR, regvalue_show, regvalue_store); -+ -+/* -+ * Attributes -+ */ -+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode, -+ &(otg_dev->core_if->core_global_regs->gotgctl), -+ (1 << 20), 20, "Mode"); -+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable, -+ &(otg_dev->core_if->core_global_regs->gusbcfg), -+ (1 << 9), 9, "Mode"); -+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable, -+ &(otg_dev->core_if->core_global_regs->gusbcfg), -+ (1 << 8), 8, "Mode"); -+#if 0 -+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower, &(otg_dev->core_if->core_global_regs->gotgctl), (1<<8), 8, "Mode"); -+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend, &(otg_dev->core_if->core_global_regs->gotgctl), (1<<8), 8, "Mode"); -+#endif -+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected, otg_dev->core_if->host_if->hprt0, -+ 0x01, 0, "Bus Connected"); -+ -+DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl, -+ &(otg_dev->core_if->core_global_regs->gotgctl), -+ "GOTGCTL"); -+DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg, -+ &(otg_dev->core_if->core_global_regs->gusbcfg), -+ "GUSBCFG"); -+DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz, -+ &(otg_dev->core_if->core_global_regs->grxfsiz), -+ "GRXFSIZ"); -+DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz, -+ &(otg_dev->core_if->core_global_regs->gnptxfsiz), -+ "GNPTXFSIZ"); -+DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl, -+ &(otg_dev->core_if->core_global_regs->gpvndctl), -+ "GPVNDCTL"); -+DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio, -+ &(otg_dev->core_if->core_global_regs->ggpio), -+ "GGPIO"); -+DWC_OTG_DEVICE_ATTR_REG32_RW(guid, &(otg_dev->core_if->core_global_regs->guid), -+ "GUID"); -+DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid, -+ &(otg_dev->core_if->core_global_regs->gsnpsid), -+ "GSNPSID"); -+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed, -+ &(otg_dev->core_if->dev_if->dev_global_regs-> -+ dcfg), 0x3, 0, "Device Speed"); -+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed, -+ &(otg_dev->core_if->dev_if->dev_global_regs-> -+ dsts), 0x6, 1, "Device Enumeration Speed"); -+ -+DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz, -+ &(otg_dev->core_if->core_global_regs->hptxfsiz), -+ "HPTXFSIZ"); -+DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0, otg_dev->core_if->host_if->hprt0, "HPRT0"); -+ -+/** -+ * @todo Add code to initiate the HNP. -+ */ -+/** -+ * Show the HNP status bit -+ */ -+static ssize_t hnp_show(struct device *_dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ union gotgctl_data val; -+ val.d32 = -+ dwc_read_reg32(&(otg_dev->core_if->core_global_regs->gotgctl)); -+ return sprintf(buf, "HstNegScs = 0x%x\n", val.b.hstnegscs); -+} -+ -+/** -+ * Set the HNP Request bit -+ */ -+static ssize_t hnp_store(struct device *_dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ uint32_t in = simple_strtoul(buf, NULL, 16); -+ uint32_t *addr = -+ (uint32_t *) &(otg_dev->core_if->core_global_regs->gotgctl); -+ union gotgctl_data mem; -+ mem.d32 = dwc_read_reg32(addr); -+ mem.b.hnpreq = in; -+ dev_dbg(_dev, "Storing Address=%p Data=0x%08x\n", addr, mem.d32); -+ dwc_write_reg32(addr, mem.d32); -+ return count; -+} -+ -+DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store); -+ -+/** -+ * @todo Add code to initiate the SRP. -+ */ -+/** -+ * Show the SRP status bit -+ */ -+static ssize_t srp_show(struct device *_dev, struct device_attribute *attr, -+ char *buf) -+{ -+#ifndef DWC_HOST_ONLY -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ union gotgctl_data val; -+ val.d32 = -+ dwc_read_reg32(&(otg_dev->core_if->core_global_regs->gotgctl)); -+ return sprintf(buf, "SesReqScs = 0x%x\n", val.b.sesreqscs); -+#else -+ return sprintf(buf, "Host Only Mode!\n"); -+#endif -+} -+ -+/** -+ * Set the SRP Request bit -+ */ -+static ssize_t srp_store(struct device *_dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+#ifndef DWC_HOST_ONLY -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ dwc_otg_pcd_initiate_srp(otg_dev->pcd); -+#endif -+ return count; -+} -+ -+DEVICE_ATTR(srp, 0644, srp_show, srp_store); -+ -+/** -+ * @todo Need to do more for power on/off? -+ */ -+/** -+ * Show the Bus Power status -+ */ -+static ssize_t buspower_show(struct device *_dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ union hprt0_data val; -+ val.d32 = dwc_read_reg32(otg_dev->core_if->host_if->hprt0); -+ return sprintf(buf, "Bus Power = 0x%x\n", val.b.prtpwr); -+} -+ -+/** -+ * Set the Bus Power status -+ */ -+static ssize_t buspower_store(struct device *_dev, -+ struct device_attribute *attr, const char *buf, -+ size_t count) -+{ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ uint32_t on = simple_strtoul(buf, NULL, 16); -+ uint32_t *addr = (uint32_t *) otg_dev->core_if->host_if->hprt0; -+ union hprt0_data mem; -+ -+ mem.d32 = dwc_read_reg32(addr); -+ mem.b.prtpwr = on; -+ -+ dwc_write_reg32(addr, mem.d32); -+ -+ return count; -+} -+ -+DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store); -+ -+/** -+ * @todo Need to do more for suspend? -+ */ -+/** -+ * Show the Bus Suspend status -+ */ -+static ssize_t bussuspend_show(struct device *_dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ union hprt0_data val; -+ val.d32 = dwc_read_reg32(otg_dev->core_if->host_if->hprt0); -+ return sprintf(buf, "Bus Suspend = 0x%x\n", val.b.prtsusp); -+} -+ -+/** -+ * Set the Bus Suspend status -+ */ -+static ssize_t bussuspend_store(struct device *_dev, -+ struct device_attribute *attr, const char *buf, -+ size_t count) -+{ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ uint32_t in = simple_strtoul(buf, NULL, 16); -+ uint32_t *addr = (uint32_t *) otg_dev->core_if->host_if->hprt0; -+ union hprt0_data mem; -+ mem.d32 = dwc_read_reg32(addr); -+ mem.b.prtsusp = in; -+ dev_dbg(_dev, "Storing Address=%p Data=0x%08x\n", addr, mem.d32); -+ dwc_write_reg32(addr, mem.d32); -+ return count; -+} -+ -+DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store); -+ -+/** -+ * Show the status of Remote Wakeup. -+ */ -+static ssize_t remote_wakeup_show(struct device *_dev, -+ struct device_attribute *attr, char *buf) -+{ -+#ifndef DWC_HOST_ONLY -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ union dctl_data val; -+ val.d32 = -+ dwc_read_reg32(&otg_dev->core_if->dev_if->dev_global_regs->dctl); -+ return sprintf(buf, "Remote Wakeup = %d Enabled = %d\n", -+ val.b.rmtwkupsig, otg_dev->pcd->remote_wakeup_enable); -+#else -+ return sprintf(buf, "Host Only Mode!\n"); -+#endif -+} -+ -+/** -+ * Initiate a remote wakeup of the host. The Device control register -+ * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable -+ * flag is set. -+ * -+ */ -+static ssize_t remote_wakeup_store(struct device *_dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+#ifndef DWC_HOST_ONLY -+ uint32_t val = simple_strtoul(buf, NULL, 16); -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ if (val & 1) -+ dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1); -+ else -+ dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0); -+#endif -+ return count; -+} -+ -+DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR, remote_wakeup_show, -+ remote_wakeup_store); -+ -+/** -+ * Dump global registers and either host or device registers (depending on the -+ * current mode of the core). -+ */ -+static ssize_t regdump_show(struct device *_dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ -+ dwc_otg_dump_global_registers(otg_dev->core_if); -+ if (dwc_otg_is_host_mode(otg_dev->core_if)) -+ dwc_otg_dump_host_registers(otg_dev->core_if); -+ else -+ dwc_otg_dump_dev_registers(otg_dev->core_if); -+ -+ return sprintf(buf, "Register Dump\n"); -+} -+ -+DEVICE_ATTR(regdump, S_IRUGO | S_IWUSR, regdump_show, 0); -+ -+/** -+ * Dump the current hcd state. -+ */ -+static ssize_t hcddump_show(struct device *_dev, struct device_attribute *attr, -+ char *buf) -+{ -+#ifndef DWC_DEVICE_ONLY -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ dwc_otg_hcd_dump_state(otg_dev->hcd); -+#endif -+ return sprintf(buf, "HCD Dump\n"); -+} -+ -+DEVICE_ATTR(hcddump, S_IRUGO | S_IWUSR, hcddump_show, 0); -+ -+/** -+ * Dump the average frame remaining at SOF. This can be used to -+ * determine average interrupt latency. Frame remaining is also shown for -+ * start transfer and two additional sample points. -+ */ -+static ssize_t hcd_frrem_show(struct device *_dev, -+ struct device_attribute *attr, char *buf) -+{ -+#ifndef DWC_DEVICE_ONLY -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ dwc_otg_hcd_dump_frrem(otg_dev->hcd); -+#endif -+ return sprintf(buf, "HCD Dump Frame Remaining\n"); -+} -+ -+DEVICE_ATTR(hcd_frrem, S_IRUGO | S_IWUSR, hcd_frrem_show, 0); -+ -+/** -+ * Displays the time required to read the GNPTXFSIZ register many times (the -+ * output shows the number of times the register is read). -+ */ -+#define RW_REG_COUNT 10000000 -+#define MSEC_PER_JIFFIE (1000/HZ) -+static ssize_t rd_reg_test_show(struct device *_dev, -+ struct device_attribute *attr, char *buf) -+{ -+ int i; -+ int time; -+ int start_jiffies; -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ -+ pr_info("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", -+ HZ, MSEC_PER_JIFFIE, loops_per_jiffy); -+ start_jiffies = jiffies; -+ for (i = 0; i < RW_REG_COUNT; i++) -+ dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz); -+ -+ time = jiffies - start_jiffies; -+ return sprintf(buf, -+ "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n", -+ RW_REG_COUNT, time * MSEC_PER_JIFFIE, time); -+} -+ -+DEVICE_ATTR(rd_reg_test, S_IRUGO | S_IWUSR, rd_reg_test_show, 0); -+ -+/** -+ * Displays the time required to write the GNPTXFSIZ register many times (the -+ * output shows the number of times the register is written). -+ */ -+static ssize_t wr_reg_test_show(struct device *_dev, -+ struct device_attribute *attr, char *buf) -+{ -+ int i; -+ int time; -+ int start_jiffies; -+ struct dwc_otg_device *otg_dev = _dev->platform_data; -+ uint32_t reg_val; -+ -+ pr_info("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n", -+ HZ, MSEC_PER_JIFFIE, loops_per_jiffy); -+ reg_val = -+ dwc_read_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz); -+ start_jiffies = jiffies; -+ for (i = 0; i < RW_REG_COUNT; i++) -+ dwc_write_reg32(&otg_dev->core_if->core_global_regs->gnptxfsiz, -+ reg_val); -+ -+ time = jiffies - start_jiffies; -+ return sprintf(buf, -+ "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n", -+ RW_REG_COUNT, time * MSEC_PER_JIFFIE, time); -+} -+ -+DEVICE_ATTR(wr_reg_test, S_IRUGO | S_IWUSR, wr_reg_test_show, 0); -+ -+/* -+ * Create the device files -+ */ -+void dwc_otg_attr_create(struct device *dev) -+{ -+ int error; -+ error = device_create_file(dev, &dev_attr_regoffset); -+ error |= device_create_file(dev, &dev_attr_regvalue); -+ error |= device_create_file(dev, &dev_attr_mode); -+ error |= device_create_file(dev, &dev_attr_hnpcapable); -+ error |= device_create_file(dev, &dev_attr_srpcapable); -+ error |= device_create_file(dev, &dev_attr_hnp); -+ error |= device_create_file(dev, &dev_attr_srp); -+ error |= device_create_file(dev, &dev_attr_buspower); -+ error |= device_create_file(dev, &dev_attr_bussuspend); -+ error |= device_create_file(dev, &dev_attr_busconnected); -+ error |= device_create_file(dev, &dev_attr_gotgctl); -+ error |= device_create_file(dev, &dev_attr_gusbcfg); -+ error |= device_create_file(dev, &dev_attr_grxfsiz); -+ error |= device_create_file(dev, &dev_attr_gnptxfsiz); -+ error |= device_create_file(dev, &dev_attr_gpvndctl); -+ error |= device_create_file(dev, &dev_attr_ggpio); -+ error |= device_create_file(dev, &dev_attr_guid); -+ error |= device_create_file(dev, &dev_attr_gsnpsid); -+ error |= device_create_file(dev, &dev_attr_devspeed); -+ error |= device_create_file(dev, &dev_attr_enumspeed); -+ error |= device_create_file(dev, &dev_attr_hptxfsiz); -+ error |= device_create_file(dev, &dev_attr_hprt0); -+ error |= device_create_file(dev, &dev_attr_remote_wakeup); -+ error |= device_create_file(dev, &dev_attr_regdump); -+ error |= device_create_file(dev, &dev_attr_hcddump); -+ error |= device_create_file(dev, &dev_attr_hcd_frrem); -+ error |= device_create_file(dev, &dev_attr_rd_reg_test); -+ error |= device_create_file(dev, &dev_attr_wr_reg_test); -+ if (error) -+ pr_err("DWC_OTG: Creating some device files failed\n"); -+} -+ -+/* -+ * Remove the device files -+ */ -+void dwc_otg_attr_remove(struct device *dev) -+{ -+ device_remove_file(dev, &dev_attr_regoffset); -+ device_remove_file(dev, &dev_attr_regvalue); -+ device_remove_file(dev, &dev_attr_mode); -+ device_remove_file(dev, &dev_attr_hnpcapable); -+ device_remove_file(dev, &dev_attr_srpcapable); -+ device_remove_file(dev, &dev_attr_hnp); -+ device_remove_file(dev, &dev_attr_srp); -+ device_remove_file(dev, &dev_attr_buspower); -+ device_remove_file(dev, &dev_attr_bussuspend); -+ device_remove_file(dev, &dev_attr_busconnected); -+ device_remove_file(dev, &dev_attr_gotgctl); -+ device_remove_file(dev, &dev_attr_gusbcfg); -+ device_remove_file(dev, &dev_attr_grxfsiz); -+ device_remove_file(dev, &dev_attr_gnptxfsiz); -+ device_remove_file(dev, &dev_attr_gpvndctl); -+ device_remove_file(dev, &dev_attr_ggpio); -+ device_remove_file(dev, &dev_attr_guid); -+ device_remove_file(dev, &dev_attr_gsnpsid); -+ device_remove_file(dev, &dev_attr_devspeed); -+ device_remove_file(dev, &dev_attr_enumspeed); -+ device_remove_file(dev, &dev_attr_hptxfsiz); -+ device_remove_file(dev, &dev_attr_hprt0); -+ device_remove_file(dev, &dev_attr_remote_wakeup); -+ device_remove_file(dev, &dev_attr_regdump); -+ device_remove_file(dev, &dev_attr_hcddump); -+ device_remove_file(dev, &dev_attr_hcd_frrem); -+ device_remove_file(dev, &dev_attr_rd_reg_test); -+ device_remove_file(dev, &dev_attr_wr_reg_test); -+} -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_attr.h b/drivers/usb/host/dwc_otg/dwc_otg_attr.h -new file mode 100644 -index 0000000..925524f ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_attr.h -@@ -0,0 +1,63 @@ -+/* ========================================================================== -+ * -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+ -+#if !defined(__DWC_OTG_ATTR_H__) -+#define __DWC_OTG_ATTR_H__ -+ -+/* -+ * This file contains the interface to the Linux device attributes. -+ */ -+extern struct device_attribute dev_attr_regoffset; -+extern struct device_attribute dev_attr_regvalue; -+ -+extern struct device_attribute dev_attr_mode; -+extern struct device_attribute dev_attr_hnpcapable; -+extern struct device_attribute dev_attr_srpcapable; -+extern struct device_attribute dev_attr_hnp; -+extern struct device_attribute dev_attr_srp; -+extern struct device_attribute dev_attr_buspower; -+extern struct device_attribute dev_attr_bussuspend; -+extern struct device_attribute dev_attr_busconnected; -+extern struct device_attribute dev_attr_gotgctl; -+extern struct device_attribute dev_attr_gusbcfg; -+extern struct device_attribute dev_attr_grxfsiz; -+extern struct device_attribute dev_attr_gnptxfsiz; -+extern struct device_attribute dev_attr_gpvndctl; -+extern struct device_attribute dev_attr_ggpio; -+extern struct device_attribute dev_attr_guid; -+extern struct device_attribute dev_attr_gsnpsid; -+extern struct device_attribute dev_attr_devspeed; -+extern struct device_attribute dev_attr_enumspeed; -+extern struct device_attribute dev_attr_hptxfsiz; -+extern struct device_attribute dev_attr_hprt0; -+ -+void dwc_otg_attr_create(struct device *dev); -+void dwc_otg_attr_remove(struct device *dev); -+ -+#endif -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil.c b/drivers/usb/host/dwc_otg/dwc_otg_cil.c -new file mode 100644 -index 0000000..86153ba ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.c -@@ -0,0 +1,2887 @@ -+/* ========================================================================== -+ * -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+ -+/* -+ * -+ * The Core Interface Layer provides basic services for accessing and -+ * managing the DWC_otg hardware. These services are used by both the -+ * Host Controller Driver and the Peripheral Controller Driver. -+ * -+ * The CIL manages the memory map for the core so that the HCD and PCD -+ * don't have to do this separately. It also handles basic tasks like -+ * reading/writing the registers and data FIFOs in the controller. -+ * Some of the data access functions provide encapsulation of several -+ * operations required to perform a task, such as writing multiple -+ * registers to start a transfer. Finally, the CIL performs basic -+ * services that are not specific to either the host or device modes -+ * of operation. These services include management of the OTG Host -+ * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A -+ * Diagnostic API is also provided to allow testing of the controller -+ * hardware. -+ * -+ * The Core Interface Layer has the following requirements: -+ * - Provides basic controller operations. -+ * - Minimal use of OS services. -+ * - The OS services used will be abstracted by using inline functions -+ * or macros. -+ * -+ */ -+#include <asm/unaligned.h> -+#ifdef DEBUG -+#include <linux/jiffies.h> -+#endif -+ -+#include "dwc_otg_plat.h" -+#include "dwc_otg_regs.h" -+#include "dwc_otg_cil.h" -+ -+/** -+ * This function is called to initialize the DWC_otg CSR data -+ * structures. The register addresses in the device and host -+ * structures are initialized from the base address supplied by the -+ * caller. The calling function must make the OS calls to get the -+ * base address of the DWC_otg controller registers. The core_params -+ * argument holds the parameters that specify how the core should be -+ * configured. -+ * -+ * @reg_base_addr: Base address of DWC_otg core registers -+ * @core_params: Pointer to the core configuration parameters -+ * -+ */ -+struct dwc_otg_core_if *dwc_otg_cil_init(const uint32_t *reg_base_addr, -+ struct dwc_otg_core_params *core_params) -+{ -+ struct dwc_otg_core_if *core_if = 0; -+ struct dwc_otg_dev_if *dev_if = 0; -+ struct dwc_otg_host_if *host_if = 0; -+ uint8_t *reg_base = (uint8_t *) reg_base_addr; -+ int i = 0; -+ -+ DWC_DEBUGPL(DBG_CILV, "%s(%p,%p)\n", __func__, reg_base_addr, -+ core_params); -+ -+ core_if = kmalloc(sizeof(struct dwc_otg_core_if), GFP_KERNEL); -+ if (core_if == 0) { -+ DWC_DEBUGPL(DBG_CIL, -+ "Allocation of struct dwc_otg_core_if failed\n"); -+ return 0; -+ } -+ memset(core_if, 0, sizeof(struct dwc_otg_core_if)); -+ -+ core_if->core_params = core_params; -+ core_if->core_global_regs = -+ (struct dwc_otg_core_global_regs *)reg_base; -+ /* -+ * Allocate the Device Mode structures. -+ */ -+ dev_if = kmalloc(sizeof(struct dwc_otg_dev_if), GFP_KERNEL); -+ if (dev_if == 0) { -+ DWC_DEBUGPL(DBG_CIL, "Allocation of struct dwc_otg_dev_if " -+ "failed\n"); -+ kfree(core_if); -+ return 0; -+ } -+ -+ dev_if->dev_global_regs = -+ (struct dwc_otg_dev_global_regs *) (reg_base + -+ DWC_DEV_GLOBAL_REG_OFFSET); -+ -+ for (i = 0; i < MAX_EPS_CHANNELS; i++) { -+ dev_if->in_ep_regs[i] = (struct dwc_otg_dev_in_ep_regs *) -+ (reg_base + DWC_DEV_IN_EP_REG_OFFSET + -+ (i * DWC_EP_REG_OFFSET)); -+ -+ dev_if->out_ep_regs[i] = (struct dwc_otg_dev_out_ep_regs *) -+ (reg_base + DWC_DEV_OUT_EP_REG_OFFSET + -+ (i * DWC_EP_REG_OFFSET)); -+ DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n", -+ i, &dev_if->in_ep_regs[i]->diepctl); -+ DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n", -+ i, &dev_if->out_ep_regs[i]->doepctl); -+ } -+ dev_if->speed = 0; /* unknown */ -+ dev_if->num_eps = MAX_EPS_CHANNELS; -+ dev_if->num_perio_eps = 0; -+ -+ core_if->dev_if = dev_if; -+ /* -+ * Allocate the Host Mode structures. -+ */ -+ host_if = kmalloc(sizeof(struct dwc_otg_host_if), GFP_KERNEL); -+ if (host_if == 0) { -+ DWC_DEBUGPL(DBG_CIL, -+ "Allocation of struct dwc_otg_host_if failed\n"); -+ kfree(dev_if); -+ kfree(core_if); -+ return 0; -+ } -+ -+ host_if->host_global_regs = (struct dwc_otg_host_global_regs *) -+ (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET); -+ host_if->hprt0 = -+ (uint32_t *) (reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET); -+ for (i = 0; i < MAX_EPS_CHANNELS; i++) { -+ host_if->hc_regs[i] = (struct dwc_otg_hc_regs *) -+ (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET + -+ (i * DWC_OTG_CHAN_REGS_OFFSET)); -+ DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n", -+ i, &host_if->hc_regs[i]->hcchar); -+ } -+ host_if->num_host_channels = MAX_EPS_CHANNELS; -+ core_if->host_if = host_if; -+ -+ for (i = 0; i < MAX_EPS_CHANNELS; i++) { -+ core_if->data_fifo[i] = -+ (uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET + -+ (i * DWC_OTG_DATA_FIFO_SIZE)); -+ DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=%p\n", -+ i, core_if->data_fifo[i]); -+ } -+ -+ core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET); -+ -+ /* -+ * Store the contents of the hardware configuration registers here for -+ * easy access later. -+ */ -+ core_if->hwcfg1.d32 = -+ dwc_read_reg32(&core_if->core_global_regs->ghwcfg1); -+ core_if->hwcfg2.d32 = -+ dwc_read_reg32(&core_if->core_global_regs->ghwcfg2); -+ core_if->hwcfg3.d32 = -+ dwc_read_reg32(&core_if->core_global_regs->ghwcfg3); -+ core_if->hwcfg4.d32 = -+ dwc_read_reg32(&core_if->core_global_regs->ghwcfg4); -+ -+ DWC_DEBUGPL(DBG_CILV, "hwcfg1=%08x\n", core_if->hwcfg1.d32); -+ DWC_DEBUGPL(DBG_CILV, "hwcfg2=%08x\n", core_if->hwcfg2.d32); -+ DWC_DEBUGPL(DBG_CILV, "hwcfg3=%08x\n", core_if->hwcfg3.d32); -+ DWC_DEBUGPL(DBG_CILV, "hwcfg4=%08x\n", core_if->hwcfg4.d32); -+ -+ DWC_DEBUGPL(DBG_CILV, "op_mode=%0x\n", core_if->hwcfg2.b.op_mode); -+ DWC_DEBUGPL(DBG_CILV, "arch=%0x\n", core_if->hwcfg2.b.architecture); -+ DWC_DEBUGPL(DBG_CILV, "num_dev_ep=%d\n", core_if->hwcfg2.b.num_dev_ep); -+ DWC_DEBUGPL(DBG_CILV, "num_host_chan=%d\n", -+ core_if->hwcfg2.b.num_host_chan); -+ DWC_DEBUGPL(DBG_CILV, "nonperio_tx_q_depth=0x%0x\n", -+ core_if->hwcfg2.b.nonperio_tx_q_depth); -+ DWC_DEBUGPL(DBG_CILV, "host_perio_tx_q_depth=0x%0x\n", -+ core_if->hwcfg2.b.host_perio_tx_q_depth); -+ DWC_DEBUGPL(DBG_CILV, "dev_token_q_depth=0x%0x\n", -+ core_if->hwcfg2.b.dev_token_q_depth); -+ -+ DWC_DEBUGPL(DBG_CILV, "Total FIFO SZ=%d\n", -+ core_if->hwcfg3.b.dfifo_depth); -+ DWC_DEBUGPL(DBG_CILV, "xfer_size_cntr_width=%0x\n", -+ core_if->hwcfg3.b.xfer_size_cntr_width); -+ -+ /* -+ * Set the SRP sucess bit for FS-I2c -+ */ -+ core_if->srp_success = 0; -+ core_if->srp_timer_started = 0; -+ -+ return core_if; -+} -+ -+/** -+ * This function frees the structures allocated by dwc_otg_cil_init(). -+ * -+ * @core_if: The core interface pointer returned from -+ * dwc_otg_cil_init(). -+ * -+ */ -+void dwc_otg_cil_remove(struct dwc_otg_core_if *core_if) -+{ -+ /* Disable all interrupts */ -+ dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 1, 0); -+ dwc_write_reg32(&core_if->core_global_regs->gintmsk, 0); -+ -+ kfree(core_if->dev_if); -+ kfree(core_if->host_if); -+ -+ kfree(core_if); -+} -+ -+/** -+ * This function enables the controller's Global Interrupt in the AHB Config -+ * register. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+extern void dwc_otg_enable_global_interrupts(struct dwc_otg_core_if *core_if) -+{ -+ union gahbcfg_data ahbcfg = {.d32 = 0 }; -+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ -+ dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32); -+} -+ -+/** -+ * This function disables the controller's Global Interrupt in the AHB Config -+ * register. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+extern void dwc_otg_disable_global_interrupts(struct dwc_otg_core_if *core_if) -+{ -+ union gahbcfg_data ahbcfg = {.d32 = 0 }; -+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */ -+ dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0); -+} -+ -+/** -+ * This function initializes the commmon interrupts, used in both -+ * device and host modes. -+ * -+ * @core_if: Programming view of the DWC_otg controller -+ * -+ */ -+static void dwc_otg_enable_common_interrupts(struct dwc_otg_core_if *core_if) -+{ -+ struct dwc_otg_core_global_regs *global_regs = -+ core_if->core_global_regs; -+ union gintmsk_data intr_mask = {.d32 = 0 }; -+ /* Clear any pending OTG Interrupts */ -+ dwc_write_reg32(&global_regs->gotgint, 0xFFFFFFFF); -+ /* Clear any pending interrupts */ -+ dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF); -+ /* -+ * Enable the interrupts in the GINTMSK. -+ */ -+ intr_mask.b.modemismatch = 1; -+ intr_mask.b.otgintr = 1; -+ if (!core_if->dma_enable) -+ intr_mask.b.rxstsqlvl = 1; -+ -+ intr_mask.b.conidstschng = 1; -+ intr_mask.b.wkupintr = 1; -+ intr_mask.b.disconnect = 1; -+ intr_mask.b.usbsuspend = 1; -+ intr_mask.b.sessreqintr = 1; -+ dwc_write_reg32(&global_regs->gintmsk, intr_mask.d32); -+} -+ -+/** -+ * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY -+ * type. -+ */ -+static void init_fslspclksel(struct dwc_otg_core_if *core_if) -+{ -+ uint32_t val; -+ union hcfg_data hcfg; -+ -+ if (((core_if->hwcfg2.b.hs_phy_type == 2) && -+ (core_if->hwcfg2.b.fs_phy_type == 1) && -+ (core_if->core_params->ulpi_fs_ls)) || -+ (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) { -+ /* Full speed PHY */ -+ val = DWC_HCFG_48_MHZ; -+ } else { -+ /* High speed PHY running at full speed or high speed */ -+ val = DWC_HCFG_30_60_MHZ; -+ } -+ -+ DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val); -+ hcfg.d32 = dwc_read_reg32(&core_if->host_if->host_global_regs->hcfg); -+ hcfg.b.fslspclksel = val; -+ dwc_write_reg32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32); -+} -+ -+/** -+ * Initializes the DevSpd field of the DCFG register depending on the PHY type -+ * and the enumeration speed of the device. -+ */ -+static void init_devspd(struct dwc_otg_core_if *core_if) -+{ -+ uint32_t val; -+ union dcfg_data dcfg; -+ -+ if (((core_if->hwcfg2.b.hs_phy_type == 2) && -+ (core_if->hwcfg2.b.fs_phy_type == 1) && -+ (core_if->core_params->ulpi_fs_ls)) || -+ (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) { -+ /* Full speed PHY */ -+ val = 0x3; -+ } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) { -+ /* High speed PHY running at full speed */ -+ val = 0x1; -+ } else { -+ /* High speed PHY running at high speed */ -+ val = 0x0; -+ } -+ -+ DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val); -+ dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg); -+ dcfg.b.devspd = val; -+ dwc_write_reg32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32); -+} -+ -+/** -+ * This function initializes the DWC_otg controller registers and -+ * prepares the core for device mode or host mode operation. -+ * -+ * @core_if: Programming view of the DWC_otg controller -+ * -+ */ -+void dwc_otg_core_init(struct dwc_otg_core_if *core_if) -+{ -+ struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs; -+ struct dwc_otg_dev_if *dev_if = core_if->dev_if; -+ int i = 0; -+ union gahbcfg_data ahbcfg = {.d32 = 0 }; -+ union gusbcfg_data usbcfg = {.d32 = 0 }; -+ union gi2cctl_data i2cctl = {.d32 = 0 }; -+ -+ DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if); -+ -+ /* Common Initialization */ -+ -+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg); -+ -+ /* Program the ULPI External VBUS bit if needed */ -+ usbcfg.b.ulpi_ext_vbus_drv = -+ (core_if->core_params->phy_ulpi_ext_vbus == -+ DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0; -+ -+ /* Set external TS Dline pulsing */ -+ usbcfg.b.term_sel_dl_pulse = -+ (core_if->core_params->ts_dline == 1) ? 1 : 0; -+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32); -+ -+ /* Reset the Controller */ -+ dwc_otg_core_reset(core_if); -+ -+ /* Initialize parameters from Hardware configuration registers. */ -+ dev_if->num_eps = core_if->hwcfg2.b.num_dev_ep; -+ dev_if->num_perio_eps = core_if->hwcfg4.b.num_dev_perio_in_ep; -+ -+ DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n", -+ core_if->hwcfg4.b.num_dev_perio_in_ep); -+ for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) { -+ dev_if->perio_tx_fifo_size[i] = -+ dwc_read_reg32(&global_regs->dptxfsiz[i]) >> 16; -+ DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n", -+ i, dev_if->perio_tx_fifo_size[i]); -+ } -+ -+ core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth; -+ core_if->rx_fifo_size = dwc_read_reg32(&global_regs->grxfsiz); -+ core_if->nperio_tx_fifo_size = -+ dwc_read_reg32(&global_regs->gnptxfsiz) >> 16; -+ -+ DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size); -+ DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size); -+ DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n", -+ core_if->nperio_tx_fifo_size); -+ -+ /* This programming sequence needs to happen in FS mode before any other -+ * programming occurs */ -+ if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) && -+ (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) { -+ /* If FS mode with FS PHY */ -+ -+ /* core_init() is now called on every switch so only call the -+ * following for the first time through. */ -+ if (!core_if->phy_init_done) { -+ core_if->phy_init_done = 1; -+ DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n"); -+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg); -+ usbcfg.b.physel = 1; -+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32); -+ -+ /* Reset after a PHY select */ -+ dwc_otg_core_reset(core_if); -+ } -+ -+ /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also -+ * do this on HNP Dev/Host mode switches (done in dev_init and -+ * host_init). */ -+ if (dwc_otg_is_host_mode(core_if)) -+ init_fslspclksel(core_if); -+ else -+ init_devspd(core_if); -+ -+ if (core_if->core_params->i2c_enable) { -+ DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n"); -+ /* Program GUSBCFG.OtgUtmifsSel to I2C */ -+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg); -+ usbcfg.b.otgutmifssel = 1; -+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32); -+ -+ /* Program GI2CCTL.I2CEn */ -+ i2cctl.d32 = dwc_read_reg32(&global_regs->gi2cctl); -+ i2cctl.b.i2cdevaddr = 1; -+ i2cctl.b.i2cen = 0; -+ dwc_write_reg32(&global_regs->gi2cctl, i2cctl.d32); -+ i2cctl.b.i2cen = 1; -+ dwc_write_reg32(&global_regs->gi2cctl, i2cctl.d32); -+ } -+ -+ } -+ /* endif speed == DWC_SPEED_PARAM_FULL */ -+ else { -+ /* High speed PHY. */ -+ if (!core_if->phy_init_done) { -+ core_if->phy_init_done = 1; -+ /* HS PHY parameters. These parameters are preserved -+ * during soft reset so only program the first time. Do -+ * a soft reset immediately after setting phyif. */ -+ usbcfg.b.ulpi_utmi_sel = -+ (core_if->core_params->phy_type == -+ DWC_PHY_TYPE_PARAM_ULPI); -+ if (usbcfg.b.ulpi_utmi_sel == 1) { -+ /* ULPI interface */ -+ usbcfg.b.phyif = 0; -+ usbcfg.b.ddrsel = -+ core_if->core_params->phy_ulpi_ddr; -+ } else { -+ /* UTMI+ interface */ -+ if (core_if->core_params->phy_utmi_width == 16) -+ usbcfg.b.phyif = 1; -+ else -+ usbcfg.b.phyif = 0; -+ } -+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32); -+ -+ /* Reset after setting the PHY parameters */ -+ dwc_otg_core_reset(core_if); -+ } -+ } -+ -+ if ((core_if->hwcfg2.b.hs_phy_type == 2) && -+ (core_if->hwcfg2.b.fs_phy_type == 1) && -+ (core_if->core_params->ulpi_fs_ls)) { -+ DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n"); -+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg); -+ usbcfg.b.ulpi_fsls = 1; -+ usbcfg.b.ulpi_clk_sus_m = 1; -+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32); -+ } else { -+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg); -+ usbcfg.b.ulpi_fsls = 0; -+ usbcfg.b.ulpi_clk_sus_m = 0; -+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32); -+ } -+ -+ /* Program the GAHBCFG Register. */ -+ switch (core_if->hwcfg2.b.architecture) { -+ -+ case DWC_SLAVE_ONLY_ARCH: -+ DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n"); -+ ahbcfg.b.nptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY; -+ ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY; -+ core_if->dma_enable = 0; -+ break; -+ -+ case DWC_EXT_DMA_ARCH: -+ DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n"); -+ ahbcfg.b.hburstlen = core_if->core_params->dma_burst_size; -+ core_if->dma_enable = (core_if->core_params->dma_enable != 0); -+ break; -+ -+ case DWC_INT_DMA_ARCH: -+ DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n"); -+ ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR; -+ core_if->dma_enable = (core_if->core_params->dma_enable != 0); -+ break; -+ -+ } -+ ahbcfg.b.dmaenable = core_if->dma_enable; -+ dwc_write_reg32(&global_regs->gahbcfg, ahbcfg.d32); -+ -+ /* -+ * Program the GUSBCFG register. -+ */ -+ usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg); -+ -+ switch (core_if->hwcfg2.b.op_mode) { -+ case DWC_MODE_HNP_SRP_CAPABLE: -+ usbcfg.b.hnpcap = (core_if->core_params->otg_cap == -+ DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE); -+ usbcfg.b.srpcap = (core_if->core_params->otg_cap != -+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE); -+ break; -+ -+ case DWC_MODE_SRP_ONLY_CAPABLE: -+ usbcfg.b.hnpcap = 0; -+ usbcfg.b.srpcap = (core_if->core_params->otg_cap != -+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE); -+ break; -+ -+ case DWC_MODE_NO_HNP_SRP_CAPABLE: -+ usbcfg.b.hnpcap = 0; -+ usbcfg.b.srpcap = 0; -+ break; -+ -+ case DWC_MODE_SRP_CAPABLE_DEVICE: -+ usbcfg.b.hnpcap = 0; -+ usbcfg.b.srpcap = (core_if->core_params->otg_cap != -+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE); -+ break; -+ -+ case DWC_MODE_NO_SRP_CAPABLE_DEVICE: -+ usbcfg.b.hnpcap = 0; -+ usbcfg.b.srpcap = 0; -+ break; -+ -+ case DWC_MODE_SRP_CAPABLE_HOST: -+ usbcfg.b.hnpcap = 0; -+ usbcfg.b.srpcap = (core_if->core_params->otg_cap != -+ DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE); -+ break; -+ -+ case DWC_MODE_NO_SRP_CAPABLE_HOST: -+ usbcfg.b.hnpcap = 0; -+ usbcfg.b.srpcap = 0; -+ break; -+ } -+ -+ dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32); -+ -+ /* Enable common interrupts */ -+ dwc_otg_enable_common_interrupts(core_if); -+ -+ /* Do device or host intialization based on mode during PCD -+ * and HCD initialization */ -+ if (dwc_otg_is_host_mode(core_if)) { -+ DWC_DEBUGPL(DBG_ANY, "Host Mode\n"); -+ core_if->op_state = A_HOST; -+ } else { -+ DWC_DEBUGPL(DBG_ANY, "Device Mode\n"); -+ core_if->op_state = B_PERIPHERAL; -+#ifdef DWC_DEVICE_ONLY -+ dwc_otg_core_dev_init(core_if); -+#endif -+ } -+} -+ -+/** -+ * This function enables the Device mode interrupts. -+ * -+ * @core_if: Programming view of DWC_otg controller -+ */ -+void dwc_otg_enable_device_interrupts(struct dwc_otg_core_if *core_if) -+{ -+ union gintmsk_data intr_mask = {.d32 = 0 }; -+ struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs; -+ -+ DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__); -+ -+ /* Disable all interrupts. */ -+ dwc_write_reg32(&global_regs->gintmsk, 0); -+ -+ /* Clear any pending interrupts */ -+ dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF); -+ -+ /* Enable the common interrupts */ -+ dwc_otg_enable_common_interrupts(core_if); -+ -+ /* Enable interrupts */ -+ intr_mask.b.usbreset = 1; -+ intr_mask.b.enumdone = 1; -+ intr_mask.b.epmismatch = 1; -+ intr_mask.b.inepintr = 1; -+ intr_mask.b.outepintr = 1; -+ intr_mask.b.erlysuspend = 1; -+ -+#ifdef USE_PERIODIC_EP -+ /** @todo NGS: Should this be a module parameter? */ -+ intr_mask.b.isooutdrop = 1; -+ intr_mask.b.eopframe = 1; -+ intr_mask.b.incomplisoin = 1; -+ intr_mask.b.incomplisoout = 1; -+#endif -+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32); -+ -+ DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__, -+ dwc_read_reg32(&global_regs->gintmsk)); -+} -+ -+/** -+ * This function initializes the DWC_otg controller registers for -+ * device mode. -+ * -+ * @core_if: Programming view of DWC_otg controller -+ * -+ */ -+void dwc_otg_core_dev_init(struct dwc_otg_core_if *core_if) -+{ -+ struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs; -+ struct dwc_otg_dev_if *dev_if = core_if->dev_if; -+ struct dwc_otg_core_params *params = core_if->core_params; -+ union dcfg_data dcfg = {.d32 = 0 }; -+ union grstctl_data resetctl = {.d32 = 0 }; -+ int i; -+ uint32_t rx_fifo_size; -+ union fifosize_data nptxfifosize; -+#ifdef USE_PERIODIC_EP -+ union fifosize_data ptxfifosize; -+#endif -+ -+ /* Restart the Phy Clock */ -+ dwc_write_reg32(core_if->pcgcctl, 0); -+ -+ /* Device configuration register */ -+ init_devspd(core_if); -+ dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg); -+ dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80; -+ dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32); -+ -+ /* Configure data FIFO sizes */ -+ if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) { -+ -+ DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n", -+ core_if->total_fifo_size); -+ DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n", -+ params->dev_rx_fifo_size); -+ DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n", -+ params->dev_nperio_tx_fifo_size); -+ -+ /* Rx FIFO */ -+ DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n", -+ dwc_read_reg32(&global_regs->grxfsiz)); -+ rx_fifo_size = params->dev_rx_fifo_size; -+ dwc_write_reg32(&global_regs->grxfsiz, rx_fifo_size); -+ DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n", -+ dwc_read_reg32(&global_regs->grxfsiz)); -+ -+ /* Non-periodic Tx FIFO */ -+ DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n", -+ dwc_read_reg32(&global_regs->gnptxfsiz)); -+ nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size; -+ nptxfifosize.b.startaddr = params->dev_rx_fifo_size; -+ dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32); -+ DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n", -+ dwc_read_reg32(&global_regs->gnptxfsiz)); -+ -+#ifdef USE_PERIODIC_EP -+ /**@todo NGS: Fix Periodic FIFO Sizing! */ -+ /* -+ * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15. -+ * Indexes of the FIFO size module parameters in the -+ * dev_perio_tx_fifo_size array and the FIFO size registers in -+ * the dptxfsiz array run from 0 to 14. -+ */ -+ /** @todo Finish debug of this */ -+ ptxfifosize.b.startaddr = -+ nptxfifosize.b.startaddr + nptxfifosize.b.depth; -+ for (i = 0; i < dev_if->num_perio_eps; i++) { -+ ptxfifosize.b.depth = params->dev_perio_tx_fifo_size[i]; -+ DWC_DEBUGPL(DBG_CIL, "initial dptxfsiz[%d]=%08x\n", i, -+ dwc_read_reg32(&global_regs->dptxfsiz[i])); -+ dwc_write_reg32(&global_regs->dptxfsiz[i], -+ ptxfifosize.d32); -+ DWC_DEBUGPL(DBG_CIL, "new dptxfsiz[%d]=%08x\n", i, -+ dwc_read_reg32(&global_regs->dptxfsiz[i])); -+ ptxfifosize.b.startaddr += ptxfifosize.b.depth; -+ } -+#endif -+ } -+ /* Flush the FIFOs */ -+ dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */ -+ dwc_otg_flush_rx_fifo(core_if); -+ -+ /* Flush the Learning Queue. */ -+ resetctl.b.intknqflsh = 1; -+ dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32); -+ -+ /* Clear all pending Device Interrupts */ -+ dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, 0); -+ dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, 0); -+ dwc_write_reg32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF); -+ dwc_write_reg32(&dev_if->dev_global_regs->daintmsk, 0); -+ -+ for (i = 0; i < dev_if->num_eps; i++) { -+ union depctl_data depctl; -+ depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl); -+ if (depctl.b.epena) { -+ depctl.d32 = 0; -+ depctl.b.epdis = 1; -+ depctl.b.snak = 1; -+ } else { -+ depctl.d32 = 0; -+ } -+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32); -+ -+ depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl); -+ if (depctl.b.epena) { -+ depctl.d32 = 0; -+ depctl.b.epdis = 1; -+ depctl.b.snak = 1; -+ } else { -+ depctl.d32 = 0; -+ } -+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32); -+ -+ dwc_write_reg32(&dev_if->in_ep_regs[i]->dieptsiz, 0); -+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doeptsiz, 0); -+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepdma, 0); -+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doepdma, 0); -+ dwc_write_reg32(&dev_if->in_ep_regs[i]->diepint, 0xFF); -+ dwc_write_reg32(&dev_if->out_ep_regs[i]->doepint, 0xFF); -+ } -+ -+ dwc_otg_enable_device_interrupts(core_if); -+} -+ -+/** -+ * This function enables the Host mode interrupts. -+ * -+ * @core_if: Programming view of DWC_otg controller -+ */ -+void dwc_otg_enable_host_interrupts(struct dwc_otg_core_if *core_if) -+{ -+ struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs; -+ union gintmsk_data intr_mask = {.d32 = 0 }; -+ -+ DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__); -+ -+ /* Disable all interrupts. */ -+ dwc_write_reg32(&global_regs->gintmsk, 0); -+ -+ /* Clear any pending interrupts. */ -+ dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF); -+ -+ /* Enable the common interrupts */ -+ dwc_otg_enable_common_interrupts(core_if); -+ -+ /* -+ * Enable host mode interrupts without disturbing common -+ * interrupts. -+ */ -+ intr_mask.b.sofintr = 1; -+ intr_mask.b.portintr = 1; -+ intr_mask.b.hcintr = 1; -+ -+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32); -+} -+ -+/** -+ * This function disables the Host Mode interrupts. -+ * -+ * @core_if: Programming view of DWC_otg controller -+ */ -+void dwc_otg_disable_host_interrupts(struct dwc_otg_core_if *core_if) -+{ -+ struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs; -+ union gintmsk_data intr_mask = {.d32 = 0 }; -+ -+ DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__); -+ -+ /* -+ * Disable host mode interrupts without disturbing common -+ * interrupts. -+ */ -+ intr_mask.b.sofintr = 1; -+ intr_mask.b.portintr = 1; -+ intr_mask.b.hcintr = 1; -+ intr_mask.b.ptxfempty = 1; -+ intr_mask.b.nptxfempty = 1; -+ -+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0); -+} -+ -+/** -+ * The FIFOs are established based on a default percentage of the -+ * total FIFO depth. This function converts the percentage into the -+ * proper setting. -+ * -+ */ -+static inline uint32_t fifo_percentage(uint16_t total_fifo_size, -+ int32_t percentage) -+{ -+ /* 16-byte aligned */ -+ return ((total_fifo_size * percentage) / 100) & (-1 << 3); -+} -+ -+/** -+ * This function initializes the DWC_otg controller registers for -+ * host mode. -+ * -+ * This function flushes the Tx and Rx FIFOs and it flushes any entries in the -+ * request queues. Host channels are reset to ensure that they are ready for -+ * performing transfers. -+ * -+ * @core_if: Programming view of DWC_otg controller -+ * -+ */ -+void dwc_otg_core_host_init(struct dwc_otg_core_if *core_if) -+{ -+ struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs; -+ struct dwc_otg_host_if *host_if = core_if->host_if; -+ struct dwc_otg_core_params *params = core_if->core_params; -+ union hprt0_data hprt0 = {.d32 = 0 }; -+ union fifosize_data nptxfifosize; -+ union fifosize_data ptxfifosize; -+ int i; -+ union hcchar_data hcchar; -+ union hcfg_data hcfg; -+ struct dwc_otg_hc_regs *hc_regs; -+ int num_channels; -+ union gotgctl_data gotgctl = {.d32 = 0 }; -+ -+ DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if); -+ -+ /* Restart the Phy Clock */ -+ dwc_write_reg32(core_if->pcgcctl, 0); -+ -+ /* Initialize Host Configuration Register */ -+ init_fslspclksel(core_if); -+ if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) { -+ hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg); -+ hcfg.b.fslssupp = 1; -+ dwc_write_reg32(&host_if->host_global_regs->hcfg, hcfg.d32); -+ } -+ -+ /* Configure data FIFO sizes */ -+ if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) { -+ DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n", -+ core_if->total_fifo_size); -+ DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n", -+ params->host_rx_fifo_size); -+ DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n", -+ params->host_nperio_tx_fifo_size); -+ DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n", -+ params->host_perio_tx_fifo_size); -+ -+ /* Rx FIFO */ -+ DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n", -+ dwc_read_reg32(&global_regs->grxfsiz)); -+ dwc_write_reg32(&global_regs->grxfsiz, -+ fifo_percentage(core_if->total_fifo_size, -+ dwc_param_host_rx_fifo_size_percentage)); -+ DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n", -+ dwc_read_reg32(&global_regs->grxfsiz)); -+ -+ /* Non-periodic Tx FIFO */ -+ DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n", -+ dwc_read_reg32(&global_regs->gnptxfsiz)); -+ nptxfifosize.b.depth = -+ fifo_percentage(core_if->total_fifo_size, -+ dwc_param_host_nperio_tx_fifo_size_percentage); -+ nptxfifosize.b.startaddr = -+ dwc_read_reg32(&global_regs->grxfsiz); -+ dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32); -+ DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n", -+ dwc_read_reg32(&global_regs->gnptxfsiz)); -+ -+ /* Periodic Tx FIFO */ -+ DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n", -+ dwc_read_reg32(&global_regs->hptxfsiz)); -+ ptxfifosize.b.depth = -+ core_if->total_fifo_size - -+ dwc_read_reg32(&global_regs->grxfsiz) - -+ nptxfifosize.b.depth; -+ ptxfifosize.b.startaddr = -+ nptxfifosize.b.startaddr + nptxfifosize.b.depth; -+ dwc_write_reg32(&global_regs->hptxfsiz, ptxfifosize.d32); -+ DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n", -+ dwc_read_reg32(&global_regs->hptxfsiz)); -+ } -+ -+ /* Clear Host Set HNP Enable in the OTG Control Register */ -+ gotgctl.b.hstsethnpen = 1; -+ dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0); -+ -+ /* Make sure the FIFOs are flushed. */ -+ dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */ -+ dwc_otg_flush_rx_fifo(core_if); -+ -+ /* Flush out any leftover queued requests. */ -+ num_channels = core_if->core_params->host_channels; -+ for (i = 0; i < num_channels; i++) { -+ hc_regs = core_if->host_if->hc_regs[i]; -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hcchar.b.chen = 0; -+ hcchar.b.chdis = 1; -+ hcchar.b.epdir = 0; -+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); -+ } -+ -+ /* Halt all channels to put them into a known state. */ -+ for (i = 0; i < num_channels; i++) { -+ int count = 0; -+ hc_regs = core_if->host_if->hc_regs[i]; -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hcchar.b.chen = 1; -+ hcchar.b.chdis = 1; -+ hcchar.b.epdir = 0; -+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); -+ DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i); -+ do { -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ if (++count > 1000) { -+ DWC_ERROR -+ ("%s: Unable to clear halt on channel %d\n", -+ __func__, i); -+ break; -+ } -+ } while (hcchar.b.chen); -+ } -+ -+ /* Turn on the vbus power. */ -+ DWC_PRINT("Init: Port Power? op_state=%d\n", core_if->op_state); -+ if (core_if->op_state == A_HOST) { -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ DWC_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr); -+ if (hprt0.b.prtpwr == 0) { -+ hprt0.b.prtpwr = 1; -+ dwc_write_reg32(host_if->hprt0, hprt0.d32); -+ } -+ } -+ -+ dwc_otg_enable_host_interrupts(core_if); -+} -+ -+/** -+ * Prepares a host channel for transferring packets to/from a specific -+ * endpoint. The HCCHARn register is set up with the characteristics specified -+ * in hc. Host channel interrupts that may need to be serviced while this -+ * transfer is in progress are enabled. -+ * -+ * @core_if: Programming view of DWC_otg controller -+ * @hc: Information needed to initialize the host channel -+ */ -+void dwc_otg_hc_init(struct dwc_otg_core_if *core_if, struct dwc_hc *hc) -+{ -+ uint32_t intr_enable; -+ union hcintmsk_data hc_intr_mask; -+ union gintmsk_data gintmsk = {.d32 = 0 }; -+ union hcchar_data hcchar; -+ union hcsplt_data hcsplt; -+ -+ uint8_t hc_num = hc->hc_num; -+ struct dwc_otg_host_if *host_if = core_if->host_if; -+ struct dwc_otg_hc_regs *hc_regs = host_if->hc_regs[hc_num]; -+ -+ /* Clear old interrupt conditions for this host channel. */ -+ hc_intr_mask.d32 = 0xFFFFFFFF; -+ hc_intr_mask.b.reserved = 0; -+ dwc_write_reg32(&hc_regs->hcint, hc_intr_mask.d32); -+ -+ /* Enable channel interrupts required for this transfer. */ -+ hc_intr_mask.d32 = 0; -+ hc_intr_mask.b.chhltd = 1; -+ if (core_if->dma_enable) { -+ hc_intr_mask.b.ahberr = 1; -+ if (hc->error_state && !hc->do_split && -+ hc->ep_type != DWC_OTG_EP_TYPE_ISOC) { -+ hc_intr_mask.b.ack = 1; -+ if (hc->ep_is_in) { -+ hc_intr_mask.b.datatglerr = 1; -+ if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) -+ hc_intr_mask.b.nak = 1; -+ } -+ } -+ } else { -+ switch (hc->ep_type) { -+ case DWC_OTG_EP_TYPE_CONTROL: -+ case DWC_OTG_EP_TYPE_BULK: -+ hc_intr_mask.b.xfercompl = 1; -+ hc_intr_mask.b.stall = 1; -+ hc_intr_mask.b.xacterr = 1; -+ hc_intr_mask.b.datatglerr = 1; -+ if (hc->ep_is_in) { -+ hc_intr_mask.b.bblerr = 1; -+ } else { -+ hc_intr_mask.b.nak = 1; -+ hc_intr_mask.b.nyet = 1; -+ if (hc->do_ping) -+ hc_intr_mask.b.ack = 1; -+ } -+ -+ if (hc->do_split) { -+ hc_intr_mask.b.nak = 1; -+ if (hc->complete_split) -+ hc_intr_mask.b.nyet = 1; -+ else -+ hc_intr_mask.b.ack = 1; -+ } -+ -+ if (hc->error_state) -+ hc_intr_mask.b.ack = 1; -+ break; -+ case DWC_OTG_EP_TYPE_INTR: -+ hc_intr_mask.b.xfercompl = 1; -+ hc_intr_mask.b.nak = 1; -+ hc_intr_mask.b.stall = 1; -+ hc_intr_mask.b.xacterr = 1; -+ hc_intr_mask.b.datatglerr = 1; -+ hc_intr_mask.b.frmovrun = 1; -+ -+ if (hc->ep_is_in) -+ hc_intr_mask.b.bblerr = 1; -+ if (hc->error_state) -+ hc_intr_mask.b.ack = 1; -+ if (hc->do_split) { -+ if (hc->complete_split) -+ hc_intr_mask.b.nyet = 1; -+ else -+ hc_intr_mask.b.ack = 1; -+ } -+ break; -+ case DWC_OTG_EP_TYPE_ISOC: -+ hc_intr_mask.b.xfercompl = 1; -+ hc_intr_mask.b.frmovrun = 1; -+ hc_intr_mask.b.ack = 1; -+ -+ if (hc->ep_is_in) { -+ hc_intr_mask.b.xacterr = 1; -+ hc_intr_mask.b.bblerr = 1; -+ } -+ break; -+ } -+ } -+ dwc_write_reg32(&hc_regs->hcintmsk, hc_intr_mask.d32); -+ -+ /* Enable the top level host channel interrupt. */ -+ intr_enable = (1 << hc_num); -+ dwc_modify_reg32(&host_if->host_global_regs->haintmsk, 0, intr_enable); -+ -+ /* Make sure host channel interrupts are enabled. */ -+ gintmsk.b.hcintr = 1; -+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32); -+ -+ /* -+ * Program the HCCHARn register with the endpoint characteristics for -+ * the current transfer. -+ */ -+ hcchar.d32 = 0; -+ hcchar.b.devaddr = hc->dev_addr; -+ hcchar.b.epnum = hc->ep_num; -+ hcchar.b.epdir = hc->ep_is_in; -+ hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW); -+ hcchar.b.eptype = hc->ep_type; -+ hcchar.b.mps = hc->max_packet; -+ -+ dwc_write_reg32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32); -+ -+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num); -+ DWC_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n", hcchar.b.devaddr); -+ DWC_DEBUGPL(DBG_HCDV, " Ep Num: %d\n", hcchar.b.epnum); -+ DWC_DEBUGPL(DBG_HCDV, " Is In: %d\n", hcchar.b.epdir); -+ DWC_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev); -+ DWC_DEBUGPL(DBG_HCDV, " Ep Type: %d\n", hcchar.b.eptype); -+ DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps); -+ DWC_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n", hcchar.b.multicnt); -+ -+ /* -+ * Program the HCSPLIT register for SPLITs -+ */ -+ hcsplt.d32 = 0; -+ if (hc->do_split) { -+ DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n", -+ hc->hc_num, -+ hc->complete_split ? "CSPLIT" : "SSPLIT"); -+ hcsplt.b.compsplt = hc->complete_split; -+ hcsplt.b.xactpos = hc->xact_pos; -+ hcsplt.b.hubaddr = hc->hub_addr; -+ hcsplt.b.prtaddr = hc->port_addr; -+ DWC_DEBUGPL(DBG_HCDV, " comp split %d\n", -+ hc->complete_split); -+ DWC_DEBUGPL(DBG_HCDV, " xact pos %d\n", hc->xact_pos); -+ DWC_DEBUGPL(DBG_HCDV, " hub addr %d\n", hc->hub_addr); -+ DWC_DEBUGPL(DBG_HCDV, " port addr %d\n", hc->port_addr); -+ DWC_DEBUGPL(DBG_HCDV, " is_in %d\n", hc->ep_is_in); -+ DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps); -+ DWC_DEBUGPL(DBG_HCDV, " xferlen: %d\n", hc->xfer_len); -+ } -+ dwc_write_reg32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32); -+ -+} -+ -+/** -+ * Attempts to halt a host channel. This function should only be called in -+ * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under -+ * normal circumstances in DMA mode, the controller halts the channel when the -+ * transfer is complete or a condition occurs that requires application -+ * intervention. -+ * -+ * In slave mode, checks for a free request queue entry, then sets the Channel -+ * Enable and Channel Disable bits of the Host Channel Characteristics -+ * register of the specified channel to intiate the halt. If there is no free -+ * request queue entry, sets only the Channel Disable bit of the HCCHARn -+ * register to flush requests for this channel. In the latter case, sets a -+ * flag to indicate that the host channel needs to be halted when a request -+ * queue slot is open. -+ * -+ * In DMA mode, always sets the Channel Enable and Channel Disable bits of the -+ * HCCHARn register. The controller ensures there is space in the request -+ * queue before submitting the halt request. -+ * -+ * Some time may elapse before the core flushes any posted requests for this -+ * host channel and halts. The Channel Halted interrupt handler completes the -+ * deactivation of the host channel. -+ * -+ * @core_if: Controller register interface. -+ * @hc: Host channel to halt. -+ * @halt_status: Reason for halting the channel. -+ */ -+void dwc_otg_hc_halt(struct dwc_otg_core_if *core_if, -+ struct dwc_hc *hc, enum dwc_otg_halt_status halt_status) -+{ -+ union gnptxsts_data nptxsts; -+ union hptxsts_data hptxsts; -+ union hcchar_data hcchar; -+ struct dwc_otg_hc_regs *hc_regs; -+ struct dwc_otg_core_global_regs *global_regs; -+ struct dwc_otg_host_global_regs *host_global_regs; -+ -+ hc_regs = core_if->host_if->hc_regs[hc->hc_num]; -+ global_regs = core_if->core_global_regs; -+ host_global_regs = core_if->host_if->host_global_regs; -+ -+ WARN_ON(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS); -+ -+ if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE || -+ halt_status == DWC_OTG_HC_XFER_AHB_ERR) { -+ /* -+ * Disable all channel interrupts except Ch Halted. The QTD -+ * and QH state associated with this transfer has been cleared -+ * (in the case of URB_DEQUEUE), so the channel needs to be -+ * shut down carefully to prevent crashes. -+ */ -+ union hcintmsk_data hcintmsk; -+ hcintmsk.d32 = 0; -+ hcintmsk.b.chhltd = 1; -+ dwc_write_reg32(&hc_regs->hcintmsk, hcintmsk.d32); -+ -+ /* -+ * Make sure no other interrupts besides halt are currently -+ * pending. Handling another interrupt could cause a crash due -+ * to the QTD and QH state. -+ */ -+ dwc_write_reg32(&hc_regs->hcint, ~hcintmsk.d32); -+ -+ /* -+ * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR -+ * even if the channel was already halted for some other -+ * reason. -+ */ -+ hc->halt_status = halt_status; -+ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ if (hcchar.b.chen == 0) { -+ /* -+ * The channel is either already halted or it hasn't -+ * started yet. In DMA mode, the transfer may halt if -+ * it finishes normally or a condition occurs that -+ * requires driver intervention. Don't want to halt -+ * the channel again. In either Slave or DMA mode, -+ * it's possible that the transfer has been assigned -+ * to a channel, but not started yet when an URB is -+ * dequeued. Don't want to halt a channel that hasn't -+ * started yet. -+ */ -+ return; -+ } -+ } -+ -+ if (hc->halt_pending) { -+ /* -+ * A halt has already been issued for this channel. This might -+ * happen when a transfer is aborted by a higher level in -+ * the stack. -+ */ -+#ifdef DEBUG -+ DWC_PRINT -+ ("*** %s: Channel %d, hc->halt_pending already set ***\n", -+ __func__, hc->hc_num); -+ -+/* dwc_otg_dump_global_registers(core_if); */ -+/* dwc_otg_dump_host_registers(core_if); */ -+#endif -+ return; -+ } -+ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hcchar.b.chen = 1; -+ hcchar.b.chdis = 1; -+ -+ if (!core_if->dma_enable) { -+ /* Check for space in the request queue to issue the halt. */ -+ if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL || -+ hc->ep_type == DWC_OTG_EP_TYPE_BULK) { -+ nptxsts.d32 = dwc_read_reg32(&global_regs->gnptxsts); -+ if (nptxsts.b.nptxqspcavail == 0) -+ hcchar.b.chen = 0; -+ } else { -+ hptxsts.d32 = -+ dwc_read_reg32(&host_global_regs->hptxsts); -+ if ((hptxsts.b.ptxqspcavail == 0) -+ || (core_if->queuing_high_bandwidth)) { -+ hcchar.b.chen = 0; -+ } -+ } -+ } -+ -+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); -+ -+ hc->halt_status = halt_status; -+ -+ if (hcchar.b.chen) { -+ hc->halt_pending = 1; -+ hc->halt_on_queue = 0; -+ } else { -+ hc->halt_on_queue = 1; -+ } -+ -+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num); -+ DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32); -+ DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", hc->halt_pending); -+ DWC_DEBUGPL(DBG_HCDV, " halt_on_queue: %d\n", hc->halt_on_queue); -+ DWC_DEBUGPL(DBG_HCDV, " halt_status: %d\n", hc->halt_status); -+ -+ return; -+} -+ -+/** -+ * Clears the transfer state for a host channel. This function is normally -+ * called after a transfer is done and the host channel is being released. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @hc: Identifies the host channel to clean up. -+ */ -+void dwc_otg_hc_cleanup(struct dwc_otg_core_if *core_if, struct dwc_hc *hc) -+{ -+ struct dwc_otg_hc_regs *hc_regs; -+ -+ hc->xfer_started = 0; -+ -+ /* -+ * Clear channel interrupt enables and any unhandled channel interrupt -+ * conditions. -+ */ -+ hc_regs = core_if->host_if->hc_regs[hc->hc_num]; -+ dwc_write_reg32(&hc_regs->hcintmsk, 0); -+ dwc_write_reg32(&hc_regs->hcint, 0xFFFFFFFF); -+ -+#ifdef DEBUG -+ del_timer(&core_if->hc_xfer_timer[hc->hc_num]); -+ { -+ union hcchar_data hcchar; -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ if (hcchar.b.chdis) { -+ DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", -+ __func__, hc->hc_num, hcchar.d32); -+ } -+ } -+#endif -+} -+ -+/** -+ * Sets the channel property that indicates in which frame a periodic transfer -+ * should occur. This is always set to the _next_ frame. This function has no -+ * effect on non-periodic transfers. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @hc: Identifies the host channel to set up and its properties. -+ * @hcchar: Current value of the HCCHAR register for the specified host -+ * channel. -+ */ -+static inline void hc_set_even_odd_frame(struct dwc_otg_core_if *core_if, -+ struct dwc_hc *hc, -+ union hcchar_data *hcchar) -+{ -+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || -+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { -+ union hfnum_data hfnum; -+ hfnum.d32 = -+ dwc_read_reg32(&core_if->host_if->host_global_regs->hfnum); -+ /* 1 if _next_ frame is odd, 0 if it's even */ -+ hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1; -+#ifdef DEBUG -+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split -+ && !hc->complete_split) { -+ switch (hfnum.b.frnum & 0x7) { -+ case 7: -+ core_if->hfnum_7_samples++; -+ core_if->hfnum_7_frrem_accum += hfnum.b.frrem; -+ break; -+ case 0: -+ core_if->hfnum_0_samples++; -+ core_if->hfnum_0_frrem_accum += hfnum.b.frrem; -+ break; -+ default: -+ core_if->hfnum_other_samples++; -+ core_if->hfnum_other_frrem_accum += -+ hfnum.b.frrem; -+ break; -+ } -+ } -+#endif -+ } -+} -+ -+#ifdef DEBUG -+static void hc_xfer_timeout(unsigned long _ptr) -+{ -+ struct hc_xfer_info *xfer_info = (struct hc_xfer_info *) _ptr; -+ int hc_num = xfer_info->hc->hc_num; -+ DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num); -+ DWC_WARN(" start_hcchar_val 0x%08x\n", -+ xfer_info->core_if->start_hcchar_val[hc_num]); -+} -+#endif -+ -+/** -+ * This function does the setup for a data transfer for a host channel and -+ * starts the transfer. May be called in either Slave mode or DMA mode. In -+ * Slave mode, the caller must ensure that there is sufficient space in the -+ * request queue and Tx Data FIFO. -+ * -+ * For an OUT transfer in Slave mode, it loads a data packet into the -+ * appropriate FIFO. If necessary, additional data packets will be loaded in -+ * the Host ISR. -+ * -+ * For an IN transfer in Slave mode, a data packet is requested. The data -+ * packets are unloaded from the Rx FIFO in the Host ISR. If necessary, -+ * additional data packets are requested in the Host ISR. -+ * -+ * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ -+ * register along with a packet count of 1 and the channel is enabled. This -+ * causes a single PING transaction to occur. Other fields in HCTSIZ are -+ * simply set to 0 since no data transfer occurs in this case. -+ * -+ * For a PING transfer in DMA mode, the HCTSIZ register is initialized with -+ * all the information required to perform the subsequent data transfer. In -+ * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the -+ * controller performs the entire PING protocol, then starts the data -+ * transfer. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @hc: Information needed to initialize the host channel. The xfer_len -+ * value may be reduced to accommodate the max widths of the XferSize and -+ * PktCnt fields in the HCTSIZn register. The multi_count value may be changed -+ * to reflect the final xfer_len value. -+ */ -+void dwc_otg_hc_start_transfer(struct dwc_otg_core_if *core_if, -+ struct dwc_hc *hc) -+{ -+ union hcchar_data hcchar; -+ union hctsiz_data hctsiz; -+ uint16_t num_packets; -+ uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size; -+ uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count; -+ struct dwc_otg_hc_regs *hc_regs = core_if->host_if->hc_regs[hc->hc_num]; -+ -+ hctsiz.d32 = 0; -+ -+ if (hc->do_ping) { -+ if (!core_if->dma_enable) { -+ dwc_otg_hc_do_ping(core_if, hc); -+ hc->xfer_started = 1; -+ return; -+ } else { -+ hctsiz.b.dopng = 1; -+ } -+ } -+ -+ if (hc->do_split) { -+ num_packets = 1; -+ -+ if (hc->complete_split && !hc->ep_is_in) { -+ /* For CSPLIT OUT Transfer, set the size to 0 so the -+ * core doesn't expect any data written to the FIFO */ -+ hc->xfer_len = 0; -+ } else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) { -+ hc->xfer_len = hc->max_packet; -+ } else if (!hc->ep_is_in && (hc->xfer_len > 188)) { -+ hc->xfer_len = 188; -+ } -+ -+ hctsiz.b.xfersize = hc->xfer_len; -+ } else { -+ /* -+ * Ensure that the transfer length and packet count will fit -+ * in the widths allocated for them in the HCTSIZn register. -+ */ -+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || -+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { -+ /* -+ * Make sure the transfer size is no larger than one -+ * (micro)frame's worth of data. (A check was done -+ * when the periodic transfer was accepted to ensure -+ * that a (micro)frame's worth of data can be -+ * programmed into a channel.) -+ */ -+ uint32_t max_periodic_len = -+ hc->multi_count * hc->max_packet; -+ if (hc->xfer_len > max_periodic_len) -+ hc->xfer_len = max_periodic_len; -+ } else if (hc->xfer_len > max_hc_xfer_size) { -+ /* -+ * Make sure that xfer_len is a multiple of -+ * max packet size. -+ */ -+ hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1; -+ } -+ -+ if (hc->xfer_len > 0) { -+ num_packets = -+ (hc->xfer_len + hc->max_packet - -+ 1) / hc->max_packet; -+ if (num_packets > max_hc_pkt_count) { -+ num_packets = max_hc_pkt_count; -+ hc->xfer_len = num_packets * hc->max_packet; -+ } -+ } else { -+ /* Need 1 packet for transfer length of 0. */ -+ num_packets = 1; -+ } -+ -+ if (hc->ep_is_in) { -+ /* -+ * Always program an integral # of max packets -+ * for IN transfers. -+ */ -+ hc->xfer_len = num_packets * hc->max_packet; -+ } -+ -+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || -+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { -+ /* -+ * Make sure that the multi_count field matches the -+ * actual transfer length. -+ */ -+ hc->multi_count = num_packets; -+ -+ } -+ -+ if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { -+ /* Set up the initial PID for the transfer. */ -+ if (hc->speed == DWC_OTG_EP_SPEED_HIGH) { -+ if (hc->ep_is_in) { -+ if (hc->multi_count == 1) { -+ hc->data_pid_start = -+ DWC_OTG_HC_PID_DATA0; -+ } else if (hc->multi_count == 2) { -+ hc->data_pid_start = -+ DWC_OTG_HC_PID_DATA1; -+ } else { -+ hc->data_pid_start = -+ DWC_OTG_HC_PID_DATA2; -+ } -+ } else { -+ if (hc->multi_count == 1) { -+ hc->data_pid_start = -+ DWC_OTG_HC_PID_DATA0; -+ } else { -+ hc->data_pid_start = -+ DWC_OTG_HC_PID_MDATA; -+ } -+ } -+ } else { -+ hc->data_pid_start = DWC_OTG_HC_PID_DATA0; -+ } -+ } -+ -+ hctsiz.b.xfersize = hc->xfer_len; -+ } -+ -+ hc->start_pkt_count = num_packets; -+ hctsiz.b.pktcnt = num_packets; -+ hctsiz.b.pid = hc->data_pid_start; -+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32); -+ -+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num); -+ DWC_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize); -+ DWC_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n", hctsiz.b.pktcnt); -+ DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid); -+ -+ if (core_if->dma_enable) { -+#ifdef CONFIG_CPU_CAVIUM_OCTEON -+ /* Octeon uses external DMA */ -+ const uint64_t USBN_DMA0_OUTB_CHN0 = -+ CVMX_USBNX_DMA0_OUTB_CHN0(core_if->usb_num); -+ wmb(); -+ cvmx_write_csr(USBN_DMA0_OUTB_CHN0 + hc->hc_num * 8, -+ (unsigned long)hc->xfer_buff); -+ cvmx_read_csr(USBN_DMA0_OUTB_CHN0 + hc->hc_num * 8); -+ DWC_DEBUGPL(DBG_HCDV, -+ "OUT: hc->hc_num = %d, hc->xfer_buff = %p\n", -+ hc->hc_num, hc->xfer_buff); -+#else -+ dwc_write_reg32(&hc_regs->hcdma, -+ (uint32_t) (long)hc->xfer_buff); -+#endif /* CONFIG_CPU_CAVIUM_OCTEON */ -+ } -+ -+ /* Start the split */ -+ if (hc->do_split) { -+ union hcsplt_data hcsplt; -+ hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt); -+ hcsplt.b.spltena = 1; -+ dwc_write_reg32(&hc_regs->hcsplt, hcsplt.d32); -+ } -+ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hcchar.b.multicnt = hc->multi_count; -+ hc_set_even_odd_frame(core_if, hc, &hcchar); -+#ifdef DEBUG -+ core_if->start_hcchar_val[hc->hc_num] = hcchar.d32; -+ if (hcchar.b.chdis) { -+ DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", -+ __func__, hc->hc_num, hcchar.d32); -+ } -+#endif -+ -+ /* Set host channel enable after all other setup is complete. */ -+ hcchar.b.chen = 1; -+ hcchar.b.chdis = 0; -+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); -+ -+ hc->xfer_started = 1; -+ hc->requests++; -+ -+ if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0) { -+ /* Load OUT packet into the appropriate Tx FIFO. */ -+ dwc_otg_hc_write_packet(core_if, hc); -+ } -+#ifdef DEBUG -+ /* Start a timer for this transfer. */ -+ core_if->hc_xfer_timer[hc->hc_num].function = hc_xfer_timeout; -+ core_if->hc_xfer_info[hc->hc_num].core_if = core_if; -+ core_if->hc_xfer_info[hc->hc_num].hc = hc; -+ core_if->hc_xfer_timer[hc->hc_num].data = -+ (unsigned long)(&core_if->hc_xfer_info[hc->hc_num]); -+ core_if->hc_xfer_timer[hc->hc_num].expires = jiffies + (HZ * 10); -+ add_timer(&core_if->hc_xfer_timer[hc->hc_num]); -+#endif -+} -+ -+/** -+ * This function continues a data transfer that was started by previous call -+ * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is -+ * sufficient space in the request queue and Tx Data FIFO. This function -+ * should only be called in Slave mode. In DMA mode, the controller acts -+ * autonomously to complete transfers programmed to a host channel. -+ * -+ * For an OUT transfer, a new data packet is loaded into the appropriate FIFO -+ * if there is any data remaining to be queued. For an IN transfer, another -+ * data packet is always requested. For the SETUP phase of a control transfer, -+ * this function does nothing. -+ * -+ * Returns 1 if a new request is queued, 0 if no more requests are required -+ * for this transfer. -+ */ -+int dwc_otg_hc_continue_transfer(struct dwc_otg_core_if *core_if, -+ struct dwc_hc *hc) -+{ -+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num); -+ -+ if (hc->do_split) { -+ /* SPLITs always queue just once per channel */ -+ return 0; -+ } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) { -+ /* SETUPs are queued only once since they can't be NAKed. */ -+ return 0; -+ } else if (hc->ep_is_in) { -+ /* -+ * Always queue another request for other IN transfers. If -+ * back-to-back INs are issued and NAKs are received for both, -+ * the driver may still be processing the first NAK when the -+ * second NAK is received. When the interrupt handler clears -+ * the NAK interrupt for the first NAK, the second NAK will -+ * not be seen. So we can't depend on the NAK interrupt -+ * handler to requeue a NAKed request. Instead, IN requests -+ * are issued each time this function is called. When the -+ * transfer completes, the extra requests for the channel will -+ * be flushed. -+ */ -+ union hcchar_data hcchar; -+ struct dwc_otg_hc_regs *hc_regs = -+ core_if->host_if->hc_regs[hc->hc_num]; -+ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hc_set_even_odd_frame(core_if, hc, &hcchar); -+ hcchar.b.chen = 1; -+ hcchar.b.chdis = 0; -+ DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n", -+ hcchar.d32); -+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); -+ hc->requests++; -+ return 1; -+ } else { -+ /* OUT transfers. */ -+ if (hc->xfer_count < hc->xfer_len) { -+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || -+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { -+ union hcchar_data hcchar; -+ struct dwc_otg_hc_regs *hc_regs; -+ hc_regs = -+ core_if->host_if->hc_regs[hc->hc_num]; -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hc_set_even_odd_frame(core_if, hc, &hcchar); -+ } -+ -+ /* Load OUT packet into the appropriate Tx FIFO. */ -+ dwc_otg_hc_write_packet(core_if, hc); -+ hc->requests++; -+ return 1; -+ } else { -+ return 0; -+ } -+ } -+} -+ -+/** -+ * Starts a PING transfer. This function should only be called in Slave mode. -+ * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled. -+ */ -+void dwc_otg_hc_do_ping(struct dwc_otg_core_if *core_if, struct dwc_hc *hc) -+{ -+ union hcchar_data hcchar; -+ union hctsiz_data hctsiz; -+ struct dwc_otg_hc_regs *hc_regs = core_if->host_if->hc_regs[hc->hc_num]; -+ -+ DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num); -+ -+ hctsiz.d32 = 0; -+ hctsiz.b.dopng = 1; -+ hctsiz.b.pktcnt = 1; -+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32); -+ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hcchar.b.chen = 1; -+ hcchar.b.chdis = 0; -+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); -+} -+ -+/* -+ * This function writes a packet into the Tx FIFO associated with the Host -+ * Channel. For a channel associated with a non-periodic EP, the non-periodic -+ * Tx FIFO is written. For a channel associated with a periodic EP, the -+ * periodic Tx FIFO is written. This function should only be called in Slave -+ * mode. -+ * -+ * Upon return the xfer_buff and xfer_count fields in hc are incremented by -+ * then number of bytes written to the Tx FIFO. -+ */ -+void dwc_otg_hc_write_packet(struct dwc_otg_core_if *core_if, struct dwc_hc *hc) -+{ -+ uint32_t i; -+ uint32_t remaining_count; -+ uint32_t byte_count; -+ uint32_t dword_count; -+ -+ uint32_t *data_buff = (uint32_t *) (hc->xfer_buff); -+ uint32_t *data_fifo = core_if->data_fifo[hc->hc_num]; -+ -+ remaining_count = hc->xfer_len - hc->xfer_count; -+ if (remaining_count > hc->max_packet) -+ byte_count = hc->max_packet; -+ else -+ byte_count = remaining_count; -+ -+ dword_count = (byte_count + 3) / 4; -+ -+ if ((((unsigned long)data_buff) & 0x3) == 0) { -+ /* xfer_buff is DWORD aligned. */ -+ for (i = 0; i < dword_count; i++, data_buff++) -+ dwc_write_reg32(data_fifo, *data_buff); -+ } else { -+ /* xfer_buff is not DWORD aligned. */ -+ for (i = 0; i < dword_count; i++, data_buff++) -+ dwc_write_reg32(data_fifo, get_unaligned(data_buff)); -+ } -+ -+ hc->xfer_count += byte_count; -+ hc->xfer_buff += byte_count; -+} -+ -+/** -+ * Gets the current USB frame number. This is the frame number from the last -+ * SOF packet. -+ */ -+uint32_t dwc_otg_get_frame_number(struct dwc_otg_core_if *core_if) -+{ -+ union dsts_data dsts; -+ dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts); -+ -+ /* read current frame/microfreme number from DSTS register */ -+ return dsts.b.soffn; -+} -+ -+/** -+ * This function reads a setup packet from the Rx FIFO into the destination -+ * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl) -+ * Interrupt routine when a SETUP packet has been received in Slave mode. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @dest: Destination buffer for packet data. -+ */ -+void dwc_otg_read_setup_packet(struct dwc_otg_core_if *core_if, uint32_t *dest) -+{ -+ /* Get the 8 bytes of a setup transaction data */ -+ -+ /* Pop 2 DWORDS off the receive data FIFO into memory */ -+ dest[0] = dwc_read_reg32(core_if->data_fifo[0]); -+ dest[1] = dwc_read_reg32(core_if->data_fifo[0]); -+} -+ -+/** -+ * This function enables EP0 OUT to receive SETUP packets and configures EP0 -+ * IN for transmitting packets. It is normally called when the -+ * "Enumeration Done" interrupt occurs. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @ep: The EP0 data. -+ */ -+void dwc_otg_ep0_activate(struct dwc_otg_core_if *core_if, struct dwc_ep *ep) -+{ -+ struct dwc_otg_dev_if *dev_if = core_if->dev_if; -+ union dsts_data dsts; -+ union depctl_data diepctl; -+ union depctl_data doepctl; -+ union dctl_data dctl = {.d32 = 0 }; -+ -+ /* Read the Device Status and Endpoint 0 Control registers */ -+ dsts.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dsts); -+ diepctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl); -+ doepctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl); -+ -+ /* Set the MPS of the IN EP based on the enumeration speed */ -+ switch (dsts.b.enumspd) { -+ case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: -+ case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: -+ case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ: -+ diepctl.b.mps = DWC_DEP0CTL_MPS_64; -+ break; -+ case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ: -+ diepctl.b.mps = DWC_DEP0CTL_MPS_8; -+ break; -+ } -+ -+ dwc_write_reg32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32); -+ -+ /* Enable OUT EP for receive */ -+ doepctl.b.epena = 1; -+ dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32); -+ -+#ifdef VERBOSE -+ DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n", -+ dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl)); -+ DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n", -+ dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl)); -+#endif -+ dctl.b.cgnpinnak = 1; -+ dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32); -+ DWC_DEBUGPL(DBG_PCDV, "dctl=%0x\n", -+ dwc_read_reg32(&dev_if->dev_global_regs->dctl)); -+} -+ -+/** -+ * This function activates an EP. The Device EP control register for -+ * the EP is configured as defined in the ep structure. Note: This -+ * function is not used for EP0. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @ep: The EP to activate. -+ */ -+void dwc_otg_ep_activate(struct dwc_otg_core_if *core_if, struct dwc_ep *ep) -+{ -+ struct dwc_otg_dev_if *dev_if = core_if->dev_if; -+ union depctl_data depctl; -+ uint32_t *addr; -+ union daint_data daintmsk = {.d32 = 0 }; -+ -+ DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num, -+ (ep->is_in ? "IN" : "OUT")); -+ -+ /* Read DEPCTLn register */ -+ if (ep->is_in == 1) { -+ addr = &dev_if->in_ep_regs[ep->num]->diepctl; -+ daintmsk.ep.in = 1 << ep->num; -+ } else { -+ addr = &dev_if->out_ep_regs[ep->num]->doepctl; -+ daintmsk.ep.out = 1 << ep->num; -+ } -+ -+ /* If the EP is already active don't change the EP Control -+ * register. */ -+ depctl.d32 = dwc_read_reg32(addr); -+ if (!depctl.b.usbactep) { -+ depctl.b.mps = ep->maxpacket; -+ depctl.b.eptype = ep->type; -+ depctl.b.txfnum = ep->tx_fifo_num; -+ -+ if (ep->type != DWC_OTG_EP_TYPE_ISOC) -+ depctl.b.setd0pid = 1; -+ -+ depctl.b.usbactep = 1; -+ -+ dwc_write_reg32(addr, depctl.d32); -+ DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", dwc_read_reg32(addr)); -+ } -+ -+ /* Enable the Interrupt for this EP */ -+ dwc_modify_reg32(&dev_if->dev_global_regs->daintmsk, 0, daintmsk.d32); -+ DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n", -+ dwc_read_reg32(&dev_if->dev_global_regs->daintmsk)); -+ return; -+} -+ -+/** -+ * This function deactivates an EP. This is done by clearing the USB Active -+ * EP bit in the Device EP control register. Note: This function is not used -+ * for EP0. EP0 cannot be deactivated. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @ep: The EP to deactivate. -+ */ -+void dwc_otg_ep_deactivate(struct dwc_otg_core_if *core_if, struct dwc_ep *ep) -+{ -+ union depctl_data depctl = {.d32 = 0 }; -+ uint32_t *addr; -+ union daint_data daintmsk = {.d32 = 0 }; -+ -+ /* Read DEPCTLn register */ -+ if (ep->is_in == 1) { -+ addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl; -+ daintmsk.ep.in = 1 << ep->num; -+ } else { -+ addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl; -+ daintmsk.ep.out = 1 << ep->num; -+ } -+ -+ depctl.b.usbactep = 0; -+ dwc_write_reg32(addr, depctl.d32); -+ -+ /* Disable the Interrupt for this EP */ -+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->daintmsk, -+ daintmsk.d32, 0); -+ -+ return; -+} -+ -+/** -+ * This function does the setup for a data transfer for an EP and -+ * starts the transfer. For an IN transfer, the packets will be -+ * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers, -+ * the packets are unloaded from the Rx FIFO in the ISR. the ISR. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @ep: The EP to start the transfer on. -+ */ -+void dwc_otg_ep_start_transfer(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep) -+{ -+ /* -+ * @todo Refactor this funciton to check the transfer size -+ * count value does not execed the number bits in the Transfer -+ * count register. -+ */ -+ union depctl_data depctl; -+ union deptsiz_data deptsiz; -+ union gintmsk_data intr_mask = {.d32 = 0 }; -+ -+#ifdef CHECK_PACKET_COUNTER_WIDTH -+ const uint32_t MAX_XFER_SIZE = core_if->core_params->max_transfer_size; -+ const uint32_t MAX_PKT_COUNT = core_if->core_params->max_packet_count; -+ uint32_t num_packets; -+ uint32_t transfer_len; -+ struct dwc_otg_dev_out_ep_regs *out_regs = -+ core_if->dev_if->out_ep_regs[ep->num]; -+ struct dwc_otg_dev_in_ep_regs *in_regs = -+ core_if->dev_if->in_ep_regs[ep->num]; -+ union gnptxsts_data txstatus; -+ -+ int lvl = SET_DEBUG_LEVEL(DBG_PCD); -+ -+ DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d " -+ "xfer_buff=%p start_xfer_buff=%p\n", -+ ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len, -+ ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff); -+ -+ transfer_len = ep->xfer_len - ep->xfer_count; -+ if (transfer_len > MAX_XFER_SIZE) -+ transfer_len = MAX_XFER_SIZE; -+ -+ if (transfer_len == 0) { -+ num_packets = 1; -+ /* OUT EP to recieve Zero-length packet set transfer -+ * size to maxpacket size. */ -+ if (!ep->is_in) -+ transfer_len = ep->maxpacket; -+ } else { -+ num_packets = -+ (transfer_len + ep->maxpacket - 1) / ep->maxpacket; -+ if (num_packets > MAX_PKT_COUNT) -+ num_packets = MAX_PKT_COUNT; -+ } -+ DWC_DEBUGPL(DBG_PCD, "transfer_len=%d #pckt=%d\n", transfer_len, -+ num_packets); -+ -+ deptsiz.b.xfersize = transfer_len; -+ deptsiz.b.pktcnt = num_packets; -+ -+ /* IN endpoint */ -+ if (ep->is_in == 1) { -+ depctl.d32 = dwc_read_reg32(&in_regs->diepctl); -+ } else { /* OUT endpoint */ -+ depctl.d32 = dwc_read_reg32(&out_regs->doepctl); -+ } -+ -+ /* EP enable, IN data in FIFO */ -+ depctl.b.cnak = 1; -+ depctl.b.epena = 1; -+ /* IN endpoint */ -+ if (ep->is_in == 1) { -+ txstatus.d32 = -+ dwc_read_reg32(&core_if->core_global_regs->gnptxsts); -+ if (txstatus.b.nptxqspcavail == 0) { -+ DWC_DEBUGPL(DBG_ANY, "TX Queue Full (0x%0x)\n", -+ txstatus.d32); -+ return; -+ } -+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32); -+ dwc_write_reg32(&in_regs->diepctl, depctl.d32); -+ /* -+ * Enable the Non-Periodic Tx FIFO empty interrupt, the -+ * data will be written into the fifo by the ISR. -+ */ -+ if (core_if->dma_enable) { -+ dwc_write_reg32(&in_regs->diepdma, -+ (uint32_t) ep->xfer_buff); -+ } else { -+ intr_mask.b.nptxfempty = 1; -+ dwc_modify_reg32(&core_if->core_global_regs->gintsts, -+ intr_mask.d32, 0); -+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, -+ intr_mask.d32, intr_mask.d32); -+ } -+ } else { /* OUT endpoint */ -+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32); -+ dwc_write_reg32(&out_regs->doepctl, depctl.d32); -+ if (core_if->dma_enable) { -+ dwc_write_reg32(&out_regs->doepdma, -+ (uint32_t) ep->xfer_buff); -+ } -+ } -+ DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n", -+ dwc_read_reg32(&out_regs->doepctl), -+ dwc_read_reg32(&out_regs->doeptsiz)); -+ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n", -+ dwc_read_reg32(&core_if->dev_if->dev_global_regs-> -+ daintmsk), -+ dwc_read_reg32(&core_if->core_global_regs->gintmsk)); -+ -+ SET_DEBUG_LEVEL(lvl); -+#endif -+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__); -+ -+ DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d " -+ "xfer_buff=%p start_xfer_buff=%p\n", -+ ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len, -+ ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff); -+ -+ /* IN endpoint */ -+ if (ep->is_in == 1) { -+ struct dwc_otg_dev_in_ep_regs *in_regs = -+ core_if->dev_if->in_ep_regs[ep->num]; -+ union gnptxsts_data txstatus; -+ -+ txstatus.d32 = -+ dwc_read_reg32(&core_if->core_global_regs->gnptxsts); -+ if (txstatus.b.nptxqspcavail == 0) { -+#ifdef DEBUG -+ DWC_PRINT("TX Queue Full (0x%0x)\n", txstatus.d32); -+#endif -+ return; -+ } -+ -+ depctl.d32 = dwc_read_reg32(&(in_regs->diepctl)); -+ deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz)); -+ -+ /* Zero Length Packet? */ -+ if (ep->xfer_len == 0) { -+ deptsiz.b.xfersize = 0; -+ deptsiz.b.pktcnt = 1; -+ } else { -+ -+ /* Program the transfer size and packet count -+ * as follows: xfersize = N * maxpacket + -+ * short_packet pktcnt = N + (short_packet -+ * exist ? 1 : 0) -+ */ -+ deptsiz.b.xfersize = ep->xfer_len; -+ deptsiz.b.pktcnt = -+ (ep->xfer_len - 1 + ep->maxpacket) / -+ ep->maxpacket; -+ } -+ -+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32); -+ -+ /* Write the DMA register */ -+ if (core_if->dma_enable) { -+ dwc_write_reg32(&(in_regs->diepdma), -+ (uint32_t) ep->dma_addr); -+ } else { -+ /* -+ * Enable the Non-Periodic Tx FIFO empty interrupt, -+ * the data will be written into the fifo by the ISR. -+ */ -+ intr_mask.b.nptxfempty = 1; -+ dwc_modify_reg32(&core_if->core_global_regs->gintsts, -+ intr_mask.d32, 0); -+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, -+ intr_mask.d32, intr_mask.d32); -+ } -+ -+ /* EP enable, IN data in FIFO */ -+ depctl.b.cnak = 1; -+ depctl.b.epena = 1; -+ dwc_write_reg32(&in_regs->diepctl, depctl.d32); -+ -+ depctl.d32 = -+ dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl); -+ depctl.b.nextep = ep->num; -+ dwc_write_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl, -+ depctl.d32); -+ -+ } else { -+ /* OUT endpoint */ -+ struct dwc_otg_dev_out_ep_regs *out_regs = -+ core_if->dev_if->out_ep_regs[ep->num]; -+ -+ depctl.d32 = dwc_read_reg32(&(out_regs->doepctl)); -+ deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz)); -+ -+ /* Program the transfer size and packet count as follows: -+ * -+ * pktcnt = N -+ * xfersize = N * maxpacket -+ */ -+ if (ep->xfer_len == 0) { -+ /* Zero Length Packet */ -+ deptsiz.b.xfersize = ep->maxpacket; -+ deptsiz.b.pktcnt = 1; -+ } else { -+ deptsiz.b.pktcnt = -+ (ep->xfer_len + (ep->maxpacket - 1)) / -+ ep->maxpacket; -+ deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket; -+ } -+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32); -+ -+ DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n", -+ ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt); -+ -+ if (core_if->dma_enable) { -+ dwc_write_reg32(&(out_regs->doepdma), -+ (uint32_t) ep->dma_addr); -+ } -+ -+ if (ep->type == DWC_OTG_EP_TYPE_ISOC) { -+ /* -+ * @todo NGS: dpid is read-only. Use setd0pid -+ * or setd1pid. -+ */ -+ depctl.b.dpid = ep->even_odd_frame; -+ } -+ -+ /* EP enable */ -+ depctl.b.cnak = 1; -+ depctl.b.epena = 1; -+ -+ dwc_write_reg32(&out_regs->doepctl, depctl.d32); -+ -+ DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n", -+ dwc_read_reg32(&out_regs->doepctl), -+ dwc_read_reg32(&out_regs->doeptsiz)); -+ DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n", -+ dwc_read_reg32(&core_if->dev_if->dev_global_regs-> -+ daintmsk), -+ dwc_read_reg32(&core_if->core_global_regs-> -+ gintmsk)); -+ } -+} -+ -+/** -+ * This function does the setup for a data transfer for EP0 and starts -+ * the transfer. For an IN transfer, the packets will be loaded into -+ * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are -+ * unloaded from the Rx FIFO in the ISR. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @ep: The EP0 data. -+ */ -+void dwc_otg_ep0_start_transfer(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep) -+{ -+ union depctl_data depctl; -+ union deptsiz0_data deptsiz; -+ union gintmsk_data intr_mask = {.d32 = 0 }; -+ -+ DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d " -+ "xfer_buff=%p start_xfer_buff=%p total_len=%d\n", -+ ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len, -+ ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff, -+ ep->total_len); -+ ep->total_len = ep->xfer_len; -+ -+ /* IN endpoint */ -+ if (ep->is_in == 1) { -+ struct dwc_otg_dev_in_ep_regs *in_regs = -+ core_if->dev_if->in_ep_regs[0]; -+ union gnptxsts_data tx_status = {.d32 = 0 }; -+ -+ tx_status.d32 = -+ dwc_read_reg32(&core_if->core_global_regs->gnptxsts); -+ if (tx_status.b.nptxqspcavail == 0) { -+#ifdef DEBUG -+ deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz); -+ DWC_DEBUGPL(DBG_PCD, "DIEPCTL0=%0x\n", -+ dwc_read_reg32(&in_regs->diepctl)); -+ DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n", -+ deptsiz.d32, -+ deptsiz.b.xfersize, deptsiz.b.pktcnt); -+ DWC_PRINT("TX Queue or FIFO Full (0x%0x)\n", -+ tx_status.d32); -+#endif -+ -+ return; -+ } -+ -+ depctl.d32 = dwc_read_reg32(&in_regs->diepctl); -+ deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz); -+ -+ /* Zero Length Packet? */ -+ if (ep->xfer_len == 0) { -+ deptsiz.b.xfersize = 0; -+ deptsiz.b.pktcnt = 1; -+ } else { -+ /* Program the transfer size and packet count -+ * as follows: xfersize = N * maxpacket + -+ * short_packet pktcnt = N + (short_packet -+ * exist ? 1 : 0) -+ */ -+ if (ep->xfer_len > ep->maxpacket) { -+ ep->xfer_len = ep->maxpacket; -+ deptsiz.b.xfersize = ep->maxpacket; -+ } else { -+ deptsiz.b.xfersize = ep->xfer_len; -+ } -+ deptsiz.b.pktcnt = 1; -+ -+ } -+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32); -+ DWC_DEBUGPL(DBG_PCDV, -+ "IN len=%d xfersize=%d pktcnt=%d [%08x]\n", -+ ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt, -+ deptsiz.d32); -+ -+ /* Write the DMA register */ -+ if (core_if->dma_enable) { -+ dwc_write_reg32(&(in_regs->diepdma), -+ (uint32_t) ep->dma_addr); -+ } -+ -+ /* EP enable, IN data in FIFO */ -+ depctl.b.cnak = 1; -+ depctl.b.epena = 1; -+ dwc_write_reg32(&in_regs->diepctl, depctl.d32); -+ -+ /* -+ * Enable the Non-Periodic Tx FIFO empty interrupt, the -+ * data will be written into the fifo by the ISR. -+ */ -+ if (!core_if->dma_enable) { -+ /* First clear it from GINTSTS */ -+ intr_mask.b.nptxfempty = 1; -+ dwc_modify_reg32(&core_if->core_global_regs->gintsts, -+ intr_mask.d32, 0); -+ -+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, -+ intr_mask.d32, intr_mask.d32); -+ } -+ -+ } else { /* OUT endpoint */ -+ struct dwc_otg_dev_out_ep_regs *out_regs = -+ core_if->dev_if->out_ep_regs[ep->num]; -+ -+ depctl.d32 = dwc_read_reg32(&out_regs->doepctl); -+ deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz); -+ -+ /* Program the transfer size and packet count as follows: -+ * xfersize = N * (maxpacket + 4 - (maxpacket % 4)) -+ * pktcnt = N */ -+ if (ep->xfer_len == 0) { -+ /* Zero Length Packet */ -+ deptsiz.b.xfersize = ep->maxpacket; -+ deptsiz.b.pktcnt = 1; -+ } else { -+ deptsiz.b.pktcnt = -+ (ep->xfer_len + (ep->maxpacket - 1)) / -+ ep->maxpacket; -+ deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket; -+ } -+ -+ dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32); -+ DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n", -+ ep->xfer_len, -+ deptsiz.b.xfersize, deptsiz.b.pktcnt); -+ -+ if (core_if->dma_enable) { -+ dwc_write_reg32(&(out_regs->doepdma), -+ (uint32_t) ep->dma_addr); -+ } -+ -+ /* EP enable */ -+ depctl.b.cnak = 1; -+ depctl.b.epena = 1; -+ dwc_write_reg32(&(out_regs->doepctl), depctl.d32); -+ } -+} -+ -+/** -+ * This function continues control IN transfers started by -+ * dwc_otg_ep0_start_transfer, when the transfer does not fit in a -+ * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one -+ * bit for the packet count. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @ep: The EP0 data. -+ */ -+void dwc_otg_ep0_continue_transfer(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep) -+{ -+ union depctl_data depctl; -+ union deptsiz0_data deptsiz; -+ union gintmsk_data intr_mask = {.d32 = 0 }; -+ -+ if (ep->is_in == 1) { -+ struct dwc_otg_dev_in_ep_regs *in_regs = -+ core_if->dev_if->in_ep_regs[0]; -+ union gnptxsts_data tx_status = {.d32 = 0 }; -+ -+ tx_status.d32 = -+ dwc_read_reg32(&core_if->core_global_regs->gnptxsts); -+ /* -+ * @todo Should there be check for room in the Tx -+ * Status Queue. If not remove the code above this comment. -+ */ -+ -+ depctl.d32 = dwc_read_reg32(&in_regs->diepctl); -+ deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz); -+ -+ /* -+ * Program the transfer size and packet count -+ * as follows: xfersize = N * maxpacket + -+ * short_packet pktcnt = N + (short_packet -+ * exist ? 1 : 0) -+ */ -+ deptsiz.b.xfersize = -+ (ep->total_len - ep->xfer_count) > -+ ep->maxpacket ? ep->maxpacket : (ep->total_len - -+ ep->xfer_count); -+ deptsiz.b.pktcnt = 1; -+ ep->xfer_len += deptsiz.b.xfersize; -+ -+ dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32); -+ DWC_DEBUGPL(DBG_PCDV, -+ "IN len=%d xfersize=%d pktcnt=%d [%08x]\n", -+ ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt, -+ deptsiz.d32); -+ -+ /* Write the DMA register */ -+ if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) { -+ dwc_write_reg32(&(in_regs->diepdma), -+ (uint32_t) ep->dma_addr); -+ } -+ -+ /* EP enable, IN data in FIFO */ -+ depctl.b.cnak = 1; -+ depctl.b.epena = 1; -+ dwc_write_reg32(&in_regs->diepctl, depctl.d32); -+ -+ /* -+ * Enable the Non-Periodic Tx FIFO empty interrupt, the -+ * data will be written into the fifo by the ISR. -+ */ -+ if (!core_if->dma_enable) { -+ /* First clear it from GINTSTS */ -+ intr_mask.b.nptxfempty = 1; -+ dwc_write_reg32(&core_if->core_global_regs->gintsts, -+ intr_mask.d32); -+ -+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, -+ intr_mask.d32, intr_mask.d32); -+ } -+ -+ } -+ -+} -+ -+#ifdef DEBUG -+void dump_msg(const u8 *buf, unsigned int length) -+{ -+ unsigned int start, num, i; -+ char line[52], *p; -+ -+ if (length >= 512) -+ return; -+ start = 0; -+ while (length > 0) { -+ num = min(length, 16u); -+ p = line; -+ for (i = 0; i < num; ++i) { -+ if (i == 8) -+ *p++ = ' '; -+ sprintf(p, " %02x", buf[i]); -+ p += 3; -+ } -+ *p = 0; -+ DWC_PRINT("%6x: %s\n", start, line); -+ buf += num; -+ start += num; -+ length -= num; -+ } -+} -+#else -+static inline void dump_msg(const u8 *buf, unsigned int length) -+{ -+} -+#endif -+ -+/** -+ * This function writes a packet into the Tx FIFO associated with the -+ * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For -+ * periodic EPs the periodic Tx FIFO associated with the EP is written -+ * with all packets for the next micro-frame. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @ep: The EP to write packet for. -+ * @_dma: Indicates if DMA is being used. -+ */ -+void dwc_otg_ep_write_packet(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep, -+ int _dma) -+{ -+ /** -+ * The buffer is padded to DWORD on a per packet basis in -+ * slave/dma mode if the MPS is not DWORD aligned. The last -+ * packet, if short, is also padded to a multiple of DWORD. -+ * -+ * ep->xfer_buff always starts DWORD aligned in memory and is a -+ * multiple of DWORD in length -+ * -+ * ep->xfer_len can be any number of bytes -+ * -+ * ep->xfer_count is a multiple of ep->maxpacket until the last -+ * packet -+ * -+ * FIFO access is DWORD */ -+ -+ uint32_t i; -+ uint32_t byte_count; -+ uint32_t dword_count; -+ uint32_t *fifo; -+ uint32_t *data_buff = (uint32_t *) ep->xfer_buff; -+ -+ if (ep->xfer_count >= ep->xfer_len) { -+ DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num); -+ return; -+ } -+ -+ /* Find the byte length of the packet either short packet or MPS */ -+ if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) -+ byte_count = ep->xfer_len - ep->xfer_count; -+ else -+ byte_count = ep->maxpacket; -+ -+ /* Find the DWORD length, padded by extra bytes as neccessary if MPS -+ * is not a multiple of DWORD */ -+ dword_count = (byte_count + 3) / 4; -+ -+#ifdef VERBOSE -+ dump_msg(ep->xfer_buff, byte_count); -+#endif -+ if (ep->type == DWC_OTG_EP_TYPE_ISOC) -+ /* -+ *@todo NGS Where are the Periodic Tx FIFO addresses -+ * intialized? What should this be? -+ */ -+ fifo = core_if->data_fifo[ep->tx_fifo_num]; -+ else -+ fifo = core_if->data_fifo[ep->num]; -+ -+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n", -+ fifo, data_buff, *data_buff, byte_count); -+ -+ if (!_dma) { -+ for (i = 0; i < dword_count; i++, data_buff++) -+ dwc_write_reg32(fifo, *data_buff); -+ } -+ -+ ep->xfer_count += byte_count; -+ ep->xfer_buff += byte_count; -+} -+ -+/** -+ * Set the EP STALL. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @ep: The EP to set the stall on. -+ */ -+void dwc_otg_ep_set_stall(struct dwc_otg_core_if *core_if, struct dwc_ep *ep) -+{ -+ union depctl_data depctl; -+ uint32_t *depctl_addr; -+ -+ DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num, -+ (ep->is_in ? "IN" : "OUT")); -+ -+ if (ep->is_in == 1) { -+ depctl_addr = -+ &(core_if->dev_if->in_ep_regs[ep->num]->diepctl); -+ depctl.d32 = dwc_read_reg32(depctl_addr); -+ -+ /* set the disable and stall bits */ -+ if (depctl.b.epena) -+ depctl.b.epdis = 1; -+ depctl.b.stall = 1; -+ dwc_write_reg32(depctl_addr, depctl.d32); -+ -+ } else { -+ depctl_addr = -+ &(core_if->dev_if->out_ep_regs[ep->num]->doepctl); -+ depctl.d32 = dwc_read_reg32(depctl_addr); -+ -+ /* set the stall bit */ -+ depctl.b.stall = 1; -+ dwc_write_reg32(depctl_addr, depctl.d32); -+ } -+ DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", dwc_read_reg32(depctl_addr)); -+ return; -+} -+ -+/** -+ * Clear the EP STALL. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @ep: The EP to clear stall from. -+ */ -+void dwc_otg_ep_clear_stall(struct dwc_otg_core_if *core_if, struct dwc_ep *ep) -+{ -+ union depctl_data depctl; -+ uint32_t *depctl_addr; -+ -+ DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num, -+ (ep->is_in ? "IN" : "OUT")); -+ -+ if (ep->is_in == 1) { -+ depctl_addr = -+ &(core_if->dev_if->in_ep_regs[ep->num]->diepctl); -+ } else { -+ depctl_addr = -+ &(core_if->dev_if->out_ep_regs[ep->num]->doepctl); -+ } -+ -+ depctl.d32 = dwc_read_reg32(depctl_addr); -+ -+ /* clear the stall bits */ -+ depctl.b.stall = 0; -+ -+ /* -+ * USB Spec 9.4.5: For endpoints using data toggle, regardless -+ * of whether an endpoint has the Halt feature set, a -+ * ClearFeature(ENDPOINT_HALT) request always results in the -+ * data toggle being reinitialized to DATA0. -+ */ -+ if (ep->type == DWC_OTG_EP_TYPE_INTR || -+ ep->type == DWC_OTG_EP_TYPE_BULK) { -+ depctl.b.setd0pid = 1; /* DATA0 */ -+ } -+ -+ dwc_write_reg32(depctl_addr, depctl.d32); -+ DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", dwc_read_reg32(depctl_addr)); -+ return; -+} -+ -+/** -+ * This function reads a packet from the Rx FIFO into the destination -+ * buffer. To read SETUP data use dwc_otg_read_setup_packet. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @dest: Destination buffer for the packet. -+ * @bytes: Number of bytes to copy to the destination. -+ */ -+void dwc_otg_read_packet(struct dwc_otg_core_if *core_if, -+ uint8_t *dest, uint16_t bytes) -+{ -+ int i; -+ int word_count = (bytes + 3) / 4; -+ -+ uint32_t *fifo = core_if->data_fifo[0]; -+ uint32_t *data_buff = (uint32_t *) dest; -+ -+ /** -+ * @todo Account for the case where dest is not dword aligned. This -+ * requires reading data from the FIFO into a uint32_t temp buffer, -+ * then moving it into the data buffer. -+ */ -+ -+ DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__, -+ core_if, dest, bytes); -+ -+ for (i = 0; i < word_count; i++, data_buff++) -+ *data_buff = dwc_read_reg32(fifo); -+ return; -+} -+ -+/** -+ * This functions reads the device registers and prints them -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+void dwc_otg_dump_dev_registers(struct dwc_otg_core_if *core_if) -+{ -+ int i; -+ uint32_t *addr; -+ -+ DWC_PRINT("Device Global Registers\n"); -+ addr = &core_if->dev_if->dev_global_regs->dcfg; -+ DWC_PRINT("DCFG @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->dev_global_regs->dctl; -+ DWC_PRINT("DCTL @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->dev_global_regs->dsts; -+ DWC_PRINT("DSTS @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->dev_global_regs->diepmsk; -+ DWC_PRINT("DIEPMSK @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->dev_global_regs->doepmsk; -+ DWC_PRINT("DOEPMSK @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->dev_global_regs->daint; -+ DWC_PRINT("DAINT @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->dev_global_regs->dtknqr1; -+ DWC_PRINT("DTKNQR1 @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ if (core_if->hwcfg2.b.dev_token_q_depth > 6) { -+ addr = &core_if->dev_if->dev_global_regs->dtknqr2; -+ DWC_PRINT("DTKNQR2 @%p : 0x%08X\n", -+ addr, dwc_read_reg32(addr)); -+ } -+ -+ addr = &core_if->dev_if->dev_global_regs->dvbusdis; -+ DWC_PRINT("DVBUSID @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ -+ addr = &core_if->dev_if->dev_global_regs->dvbuspulse; -+ DWC_PRINT("DVBUSPULSE @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ -+ if (core_if->hwcfg2.b.dev_token_q_depth > 14) { -+ addr = &core_if->dev_if->dev_global_regs->dtknqr3; -+ DWC_PRINT("DTKNQR3 @%p : 0x%08X\n", -+ addr, dwc_read_reg32(addr)); -+ } -+ -+ if (core_if->hwcfg2.b.dev_token_q_depth > 22) { -+ addr = &core_if->dev_if->dev_global_regs->dtknqr4; -+ DWC_PRINT("DTKNQR4 @%p : 0x%08X\n", -+ addr, dwc_read_reg32(addr)); -+ } -+ -+ for (i = 0; i < core_if->dev_if->num_eps; i++) { -+ DWC_PRINT("Device IN EP %d Registers\n", i); -+ addr = &core_if->dev_if->in_ep_regs[i]->diepctl; -+ DWC_PRINT("DIEPCTL @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->in_ep_regs[i]->diepint; -+ DWC_PRINT("DIEPINT @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->in_ep_regs[i]->dieptsiz; -+ DWC_PRINT("DIETSIZ @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->in_ep_regs[i]->diepdma; -+ DWC_PRINT("DIEPDMA @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ -+ DWC_PRINT("Device OUT EP %d Registers\n", i); -+ addr = &core_if->dev_if->out_ep_regs[i]->doepctl; -+ DWC_PRINT("DOEPCTL @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->out_ep_regs[i]->doepfn; -+ DWC_PRINT("DOEPFN @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->out_ep_regs[i]->doepint; -+ DWC_PRINT("DOEPINT @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->out_ep_regs[i]->doeptsiz; -+ DWC_PRINT("DOETSIZ @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ addr = &core_if->dev_if->out_ep_regs[i]->doepdma; -+ DWC_PRINT("DOEPDMA @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ } -+ return; -+} -+ -+/** -+ * This function reads the host registers and prints them -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+void dwc_otg_dump_host_registers(struct dwc_otg_core_if *core_if) -+{ -+ int i; -+ uint32_t *addr; -+ -+ DWC_PRINT("Host Global Registers\n"); -+ addr = &core_if->host_if->host_global_regs->hcfg; -+ DWC_PRINT("HCFG @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->host_if->host_global_regs->hfir; -+ DWC_PRINT("HFIR @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->host_if->host_global_regs->hfnum; -+ DWC_PRINT("HFNUM @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->host_if->host_global_regs->hptxsts; -+ DWC_PRINT("HPTXSTS @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->host_if->host_global_regs->haint; -+ DWC_PRINT("HAINT @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->host_if->host_global_regs->haintmsk; -+ DWC_PRINT("HAINTMSK @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = core_if->host_if->hprt0; -+ DWC_PRINT("HPRT0 @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ -+ for (i = 0; i < core_if->core_params->host_channels; i++) { -+ DWC_PRINT("Host Channel %d Specific Registers\n", i); -+ addr = &core_if->host_if->hc_regs[i]->hcchar; -+ DWC_PRINT("HCCHAR @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ addr = &core_if->host_if->hc_regs[i]->hcsplt; -+ DWC_PRINT("HCSPLT @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ addr = &core_if->host_if->hc_regs[i]->hcint; -+ DWC_PRINT("HCINT @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ addr = &core_if->host_if->hc_regs[i]->hcintmsk; -+ DWC_PRINT("HCINTMSK @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ addr = &core_if->host_if->hc_regs[i]->hctsiz; -+ DWC_PRINT("HCTSIZ @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ addr = &core_if->host_if->hc_regs[i]->hcdma; -+ DWC_PRINT("HCDMA @%p : 0x%08X\n", addr, -+ dwc_read_reg32(addr)); -+ -+ } -+ return; -+} -+ -+/** -+ * This function reads the core global registers and prints them -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+void dwc_otg_dump_global_registers(struct dwc_otg_core_if *core_if) -+{ -+ int i; -+ uint32_t *addr; -+ -+ DWC_PRINT("Core Global Registers\n"); -+ addr = &core_if->core_global_regs->gotgctl; -+ DWC_PRINT("GOTGCTL @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->gotgint; -+ DWC_PRINT("GOTGINT @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->gahbcfg; -+ DWC_PRINT("GAHBCFG @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->gusbcfg; -+ DWC_PRINT("GUSBCFG @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->grstctl; -+ DWC_PRINT("GRSTCTL @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->gintsts; -+ DWC_PRINT("GINTSTS @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->gintmsk; -+ DWC_PRINT("GINTMSK @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->grxstsr; -+ DWC_PRINT("GRXSTSR @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->grxfsiz; -+ DWC_PRINT("GRXFSIZ @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->gnptxfsiz; -+ DWC_PRINT("GNPTXFSIZ @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->gnptxsts; -+ DWC_PRINT("GNPTXSTS @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->gi2cctl; -+ DWC_PRINT("GI2CCTL @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->gpvndctl; -+ DWC_PRINT("GPVNDCTL @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->ggpio; -+ DWC_PRINT("GGPIO @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->guid; -+ DWC_PRINT("GUID @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->gsnpsid; -+ DWC_PRINT("GSNPSID @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->ghwcfg1; -+ DWC_PRINT("GHWCFG1 @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->ghwcfg2; -+ DWC_PRINT("GHWCFG2 @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->ghwcfg3; -+ DWC_PRINT("GHWCFG3 @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->ghwcfg4; -+ DWC_PRINT("GHWCFG4 @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ addr = &core_if->core_global_regs->hptxfsiz; -+ DWC_PRINT("HPTXFSIZ @%p : 0x%08X\n", addr, dwc_read_reg32(addr)); -+ -+ for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) { -+ addr = &core_if->core_global_regs->dptxfsiz[i]; -+ DWC_PRINT("DPTXFSIZ[%d] @%p : 0x%08X\n", i, addr, -+ dwc_read_reg32(addr)); -+ } -+ -+} -+ -+/** -+ * Flush a Tx FIFO. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @_num: Tx FIFO to flush. -+ */ -+extern void dwc_otg_flush_tx_fifo(struct dwc_otg_core_if *core_if, const int _num) -+{ -+ struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs; -+ union grstctl_data greset = {.d32 = 0 }; -+ int count = 0; -+ -+ DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", _num); -+ -+ greset.b.txfflsh = 1; -+ greset.b.txfnum = _num; -+ dwc_write_reg32(&global_regs->grstctl, greset.d32); -+ -+ do { -+ greset.d32 = dwc_read_reg32(&global_regs->grstctl); -+ if (++count > 10000) { -+ DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n", -+ __func__, greset.d32, -+ dwc_read_reg32(&global_regs->gnptxsts)); -+ break; -+ } -+ -+ } while (greset.b.txfflsh == 1); -+ /* Wait for 3 PHY Clocks */ -+ udelay(1); -+} -+ -+/** -+ * Flush Rx FIFO. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+extern void dwc_otg_flush_rx_fifo(struct dwc_otg_core_if *core_if) -+{ -+ struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs; -+ union grstctl_data greset = {.d32 = 0 }; -+ int count = 0; -+ -+ DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__); -+ /* -+ * -+ */ -+ greset.b.rxfflsh = 1; -+ dwc_write_reg32(&global_regs->grstctl, greset.d32); -+ -+ do { -+ greset.d32 = dwc_read_reg32(&global_regs->grstctl); -+ if (++count > 10000) { -+ DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__, -+ greset.d32); -+ break; -+ } -+ } while (greset.b.rxfflsh == 1); -+ /* Wait for 3 PHY Clocks */ -+ udelay(1); -+} -+ -+/** -+ * Do core a soft reset of the core. Be careful with this because it -+ * resets all the internal state machines of the core. -+ */ -+void dwc_otg_core_reset(struct dwc_otg_core_if *core_if) -+{ -+ struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs; -+ union grstctl_data greset = {.d32 = 0 }; -+ int count = 0; -+ -+ DWC_DEBUGPL(DBG_CILV, "%s\n", __func__); -+ /* Wait for AHB master IDLE state. */ -+ do { -+ udelay(10); -+ greset.d32 = dwc_read_reg32(&global_regs->grstctl); -+ if (++count > 100000) { -+ DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__, -+ greset.d32); -+ return; -+ } -+ } while (greset.b.ahbidle == 0); -+ -+ /* Core Soft Reset */ -+ count = 0; -+ greset.b.csftrst = 1; -+ dwc_write_reg32(&global_regs->grstctl, greset.d32); -+ do { -+ greset.d32 = dwc_read_reg32(&global_regs->grstctl); -+ if (++count > 10000) { -+ DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n", -+ __func__, greset.d32); -+ break; -+ } -+ } while (greset.b.csftrst == 1); -+ /* Wait for 3 PHY Clocks */ -+ mdelay(100); -+} -+ -+/** -+ * Register HCD callbacks. The callbacks are used to start and stop -+ * the HCD for interrupt processing. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @_cb: the HCD callback structure. -+ * @_p: pointer to be passed to callback function (usb_hcd*). -+ */ -+extern void dwc_otg_cil_register_hcd_callbacks(struct dwc_otg_core_if *core_if, -+ struct dwc_otg_cil_callbacks *_cb, -+ void *_p) -+{ -+ core_if->hcd_cb = _cb; -+ _cb->p = _p; -+} -+ -+/** -+ * Register PCD callbacks. The callbacks are used to start and stop -+ * the PCD for interrupt processing. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ * @_cb: the PCD callback structure. -+ * @_p: pointer to be passed to callback function (pcd*). -+ */ -+extern void dwc_otg_cil_register_pcd_callbacks(struct dwc_otg_core_if *core_if, -+ struct dwc_otg_cil_callbacks *_cb, -+ void *_p) -+{ -+ core_if->pcd_cb = _cb; -+ _cb->p = _p; -+} -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil.h b/drivers/usb/host/dwc_otg/dwc_otg_cil.h -new file mode 100644 -index 0000000..36ef561 ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.h -@@ -0,0 +1,866 @@ -+/* ========================================================================== -+ * -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+ -+#if !defined(__DWC_CIL_H__) -+#define __DWC_CIL_H__ -+ -+#include "dwc_otg_plat.h" -+#include "dwc_otg_regs.h" -+#ifdef DEBUG -+#include "linux/timer.h" -+#endif -+ -+/* -+ * This file contains the interface to the Core Interface Layer. -+ */ -+ -+/** -+ * The <code>dwc_ep</code> structure represents the state of a single -+ * endpoint when acting in device mode. It contains the data items -+ * needed for an endpoint to be activated and transfer packets. -+ */ -+struct dwc_ep { -+ /** EP number used for register address lookup */ -+ uint8_t num; -+ /** EP direction 0 = OUT */ -+ unsigned is_in:1; -+ /** EP active. */ -+ unsigned active:1; -+ -+ /* -+ * Periodic Tx FIFO # for IN EPs For INTR EP set to 0 to use -+ * non-periodic Tx FIFO -+ */ -+ unsigned tx_fifo_num:4; -+ /** EP type: 0 - Control, 1 - ISOC, 2 - BULK, 3 - INTR */ -+ unsigned type:2; -+#define DWC_OTG_EP_TYPE_CONTROL 0 -+#define DWC_OTG_EP_TYPE_ISOC 1 -+#define DWC_OTG_EP_TYPE_BULK 2 -+#define DWC_OTG_EP_TYPE_INTR 3 -+ -+ /** DATA start PID for INTR and BULK EP */ -+ unsigned data_pid_start:1; -+ /** Frame (even/odd) for ISOC EP */ -+ unsigned even_odd_frame:1; -+ /** Max Packet bytes */ -+ unsigned maxpacket:11; -+ -+ /** @name Transfer state */ -+ /** @{ */ -+ -+ /** -+ * Pointer to the beginning of the transfer buffer -- do not modify -+ * during transfer. -+ */ -+ -+ uint32_t dma_addr; -+ -+ uint8_t *start_xfer_buff; -+ /** pointer to the transfer buffer */ -+ uint8_t *xfer_buff; -+ /** Number of bytes to transfer */ -+ unsigned xfer_len:19; -+ /** Number of bytes transferred. */ -+ unsigned xfer_count:19; -+ /** Sent ZLP */ -+ unsigned sent_zlp:1; -+ /** Total len for control transfer */ -+ unsigned total_len:19; -+ -+ /** @} */ -+}; -+ -+/* -+ * Reasons for halting a host channel. -+ */ -+enum dwc_otg_halt_status { -+ DWC_OTG_HC_XFER_NO_HALT_STATUS, -+ DWC_OTG_HC_XFER_COMPLETE, -+ DWC_OTG_HC_XFER_URB_COMPLETE, -+ DWC_OTG_HC_XFER_ACK, -+ DWC_OTG_HC_XFER_NAK, -+ DWC_OTG_HC_XFER_NYET, -+ DWC_OTG_HC_XFER_STALL, -+ DWC_OTG_HC_XFER_XACT_ERR, -+ DWC_OTG_HC_XFER_FRAME_OVERRUN, -+ DWC_OTG_HC_XFER_BABBLE_ERR, -+ DWC_OTG_HC_XFER_DATA_TOGGLE_ERR, -+ DWC_OTG_HC_XFER_AHB_ERR, -+ DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE, -+ DWC_OTG_HC_XFER_URB_DEQUEUE -+}; -+ -+/** -+ * Host channel descriptor. This structure represents the state of a single -+ * host channel when acting in host mode. It contains the data items needed to -+ * transfer packets to an endpoint via a host channel. -+ */ -+struct dwc_hc { -+ /** Host channel number used for register address lookup */ -+ uint8_t hc_num; -+ -+ /** Device to access */ -+ unsigned dev_addr:7; -+ -+ /** EP to access */ -+ unsigned ep_num:4; -+ -+ /** EP direction. 0: OUT, 1: IN */ -+ unsigned ep_is_in:1; -+ -+ /** -+ * EP speed. -+ * One of the following values: -+ * - DWC_OTG_EP_SPEED_LOW -+ * - DWC_OTG_EP_SPEED_FULL -+ * - DWC_OTG_EP_SPEED_HIGH -+ */ -+ unsigned speed:2; -+#define DWC_OTG_EP_SPEED_LOW 0 -+#define DWC_OTG_EP_SPEED_FULL 1 -+#define DWC_OTG_EP_SPEED_HIGH 2 -+ -+ /** -+ * Endpoint type. -+ * One of the following values: -+ * - DWC_OTG_EP_TYPE_CONTROL: 0 -+ * - DWC_OTG_EP_TYPE_ISOC: 1 -+ * - DWC_OTG_EP_TYPE_BULK: 2 -+ * - DWC_OTG_EP_TYPE_INTR: 3 -+ */ -+ unsigned ep_type:2; -+ -+ /** Max packet size in bytes */ -+ unsigned max_packet:11; -+ -+ /** -+ * PID for initial transaction. -+ * 0: DATA0,<br> -+ * 1: DATA2,<br> -+ * 2: DATA1,<br> -+ * 3: MDATA (non-Control EP), -+ * SETUP (Control EP) -+ */ -+ unsigned data_pid_start:2; -+#define DWC_OTG_HC_PID_DATA0 0 -+#define DWC_OTG_HC_PID_DATA2 1 -+#define DWC_OTG_HC_PID_DATA1 2 -+#define DWC_OTG_HC_PID_MDATA 3 -+#define DWC_OTG_HC_PID_SETUP 3 -+ -+ /** Number of periodic transactions per (micro)frame */ -+ unsigned multi_count:2; -+ -+ /** @name Transfer State */ -+ /** @{ */ -+ -+ /** Pointer to the current transfer buffer position. */ -+ uint8_t *xfer_buff; -+ /** Total number of bytes to transfer. */ -+ uint32_t xfer_len; -+ /** Number of bytes transferred so far. */ -+ uint32_t xfer_count; -+ /** Packet count at start of transfer.*/ -+ uint16_t start_pkt_count; -+ -+ /** -+ * Flag to indicate whether the transfer has been started. Set to 1 if -+ * it has been started, 0 otherwise. -+ */ -+ uint8_t xfer_started; -+ -+ /** -+ * Set to 1 to indicate that a PING request should be issued on this -+ * channel. If 0, process normally. -+ */ -+ uint8_t do_ping; -+ -+ /** -+ * Set to 1 to indicate that the error count for this transaction is -+ * non-zero. Set to 0 if the error count is 0. -+ */ -+ uint8_t error_state; -+ -+ /** -+ * Set to 1 to indicate that this channel should be halted the next -+ * time a request is queued for the channel. This is necessary in -+ * slave mode if no request queue space is available when an attempt -+ * is made to halt the channel. -+ */ -+ uint8_t halt_on_queue; -+ -+ /** -+ * Set to 1 if the host channel has been halted, but the core is not -+ * finished flushing queued requests. Otherwise 0. -+ */ -+ uint8_t halt_pending; -+ -+ /** -+ * Reason for halting the host channel. -+ */ -+ enum dwc_otg_halt_status halt_status; -+ -+ /* -+ * Split settings for the host channel -+ */ -+ uint8_t do_split; /**< Enable split for the channel */ -+ uint8_t complete_split; /**< Enable complete split */ -+ uint8_t hub_addr; /**< Address of high speed hub */ -+ -+ uint8_t port_addr; /**< Port of the low/full speed device */ -+ /** Split transaction position -+ * One of the following values: -+ * - DWC_HCSPLIT_XACTPOS_MID -+ * - DWC_HCSPLIT_XACTPOS_BEGIN -+ * - DWC_HCSPLIT_XACTPOS_END -+ * - DWC_HCSPLIT_XACTPOS_ALL */ -+ uint8_t xact_pos; -+ -+ /** Set when the host channel does a short read. */ -+ uint8_t short_read; -+ -+ /** -+ * Number of requests issued for this channel since it was assigned to -+ * the current transfer (not counting PINGs). -+ */ -+ uint8_t requests; -+ -+ /** -+ * Queue Head for the transfer being processed by this channel. -+ */ -+ struct dwc_otg_qh *qh; -+ -+ /** @} */ -+ -+ /** Entry in list of host channels. */ -+ struct list_head hc_list_entry; -+}; -+ -+/** -+ * The following parameters may be specified when starting the module. These -+ * parameters define how the DWC_otg controller should be configured. -+ * Parameter values are passed to the CIL initialization function -+ * dwc_otg_cil_init. -+ */ -+struct dwc_otg_core_params { -+ int32_t opt; -+#define dwc_param_opt_default 1 -+ -+ /* -+ * Specifies the OTG capabilities. The driver will automatically -+ * detect the value for this parameter if none is specified. -+ * 0 - HNP and SRP capable (default) -+ * 1 - SRP Only capable -+ * 2 - No HNP/SRP capable -+ */ -+ int32_t otg_cap; -+#define DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE 0 -+#define DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE 1 -+#define DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE 2 -+#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE -+ -+ /* -+ * Specifies whether to use slave or DMA mode for accessing the data -+ * FIFOs. The driver will automatically detect the value for this -+ * parameter if none is specified. -+ * 0 - Slave -+ * 1 - DMA (default, if available) -+ */ -+ int32_t dma_enable; -+#define dwc_param_dma_enable_default 1 -+ -+ /* -+ * The DMA Burst size (applicable only for External DMA -+ * Mode). 1, 4, 8 16, 32, 64, 128, 256 (default 32) -+ */ -+ int32_t dma_burst_size; /* Translate this to GAHBCFG values */ -+#define dwc_param_dma_burst_size_default 32 -+ -+ /* -+ * Specifies the maximum speed of operation in host and device mode. -+ * The actual speed depends on the speed of the attached device and -+ * the value of phy_type. The actual speed depends on the speed of the -+ * attached device. -+ * 0 - High Speed (default) -+ * 1 - Full Speed -+ */ -+ int32_t speed; -+#define dwc_param_speed_default 0 -+#define DWC_SPEED_PARAM_HIGH 0 -+#define DWC_SPEED_PARAM_FULL 1 -+ -+ /** Specifies whether low power mode is supported when attached -+ * to a Full Speed or Low Speed device in host mode. -+ * 0 - Don't support low power mode (default) -+ * 1 - Support low power mode -+ */ -+ int32_t host_support_fs_ls_low_power; -+#define dwc_param_host_support_fs_ls_low_power_default 0 -+ -+ /** Specifies the PHY clock rate in low power mode when connected to a -+ * Low Speed device in host mode. This parameter is applicable only if -+ * HOST_SUPPORT_FS_LS_LOW_POWER is enabled. If PHY_TYPE is set to FS -+ * then defaults to 6 MHZ otherwise 48 MHZ. -+ * -+ * 0 - 48 MHz -+ * 1 - 6 MHz -+ */ -+ int32_t host_ls_low_power_phy_clk; -+#define dwc_param_host_ls_low_power_phy_clk_default 0 -+#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0 -+#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1 -+ -+ /** -+ * 0 - Use cC FIFO size parameters -+ * 1 - Allow dynamic FIFO sizing (default) -+ */ -+ int32_t enable_dynamic_fifo; -+#define dwc_param_enable_dynamic_fifo_default 1 -+ -+ /** Total number of 4-byte words in the data FIFO memory. This -+ * memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic -+ * Tx FIFOs. -+ * 32 to 32768 (default 8192) -+ * Note: The total FIFO memory depth in the FPGA configuration is 8192. -+ */ -+ int32_t data_fifo_size; -+#define dwc_param_data_fifo_size_default 8192 -+ -+ /** Number of 4-byte words in the Rx FIFO in device mode when dynamic -+ * FIFO sizing is enabled. -+ * 16 to 32768 (default 1064) -+ */ -+ int32_t dev_rx_fifo_size; -+#define dwc_param_dev_rx_fifo_size_default 1064 -+ -+ /** Number of 4-byte words in the non-periodic Tx FIFO in device mode -+ * when dynamic FIFO sizing is enabled. -+ * 16 to 32768 (default 1024) -+ */ -+ int32_t dev_nperio_tx_fifo_size; -+#define dwc_param_dev_nperio_tx_fifo_size_default 1024 -+ -+ /** Number of 4-byte words in each of the periodic Tx FIFOs in device -+ * mode when dynamic FIFO sizing is enabled. -+ * 4 to 768 (default 256) -+ */ -+ uint32_t dev_perio_tx_fifo_size[MAX_PERIO_FIFOS]; -+#define dwc_param_dev_perio_tx_fifo_size_default 256 -+ -+ /** Number of 4-byte words in the Rx FIFO in host mode when dynamic -+ * FIFO sizing is enabled. -+ * 16 to 32768 (default 1024) -+ */ -+ int32_t host_rx_fifo_size; -+#define dwc_param_host_rx_fifo_size_default 1024 -+#define dwc_param_host_rx_fifo_size_percentage 30 -+ -+ /** Number of 4-byte words in the non-periodic Tx FIFO in host mode -+ * when Dynamic FIFO sizing is enabled in the core. -+ * 16 to 32768 (default 1024) -+ */ -+ int32_t host_nperio_tx_fifo_size; -+#define dwc_param_host_nperio_tx_fifo_size_default 1024 -+#define dwc_param_host_nperio_tx_fifo_size_percentage 40 -+ -+ /* -+ * Number of 4-byte words in the host periodic Tx FIFO when dynamic -+ * FIFO sizing is enabled. -+ * 16 to 32768 (default 1024) -+ */ -+ int32_t host_perio_tx_fifo_size; -+#define dwc_param_host_perio_tx_fifo_size_default 1024 -+#define dwc_param_host_perio_tx_fifo_size_percentage 30 -+ -+ /* -+ * The maximum transfer size supported in bytes. -+ * 2047 to 65,535 (default 65,535) -+ */ -+ int32_t max_transfer_size; -+#define dwc_param_max_transfer_size_default 65535 -+ -+ /* -+ * The maximum number of packets in a transfer. -+ * 15 to 511 (default 511) -+ */ -+ int32_t max_packet_count; -+#define dwc_param_max_packet_count_default 511 -+ -+ /* -+ * The number of host channel registers to use. -+ * 1 to 16 (default 12) -+ * Note: The FPGA configuration supports a maximum of 12 host channels. -+ */ -+ int32_t host_channels; -+#define dwc_param_host_channels_default 12 -+ -+ /* -+ * The number of endpoints in addition to EP0 available for device -+ * mode operations. -+ * 1 to 15 (default 6 IN and OUT) -+ * Note: The FPGA configuration supports a maximum of 6 IN and OUT -+ * endpoints in addition to EP0. -+ */ -+ int32_t dev_endpoints; -+#define dwc_param_dev_endpoints_default 6 -+ -+ /* -+ * Specifies the type of PHY interface to use. By default, the driver -+ * will automatically detect the phy_type. -+ * -+ * 0 - Full Speed PHY -+ * 1 - UTMI+ (default) -+ * 2 - ULPI -+ */ -+ int32_t phy_type; -+#define DWC_PHY_TYPE_PARAM_FS 0 -+#define DWC_PHY_TYPE_PARAM_UTMI 1 -+#define DWC_PHY_TYPE_PARAM_ULPI 2 -+#define dwc_param_phy_type_default DWC_PHY_TYPE_PARAM_UTMI -+ -+ /* -+ * Specifies the UTMI+ Data Width. This parameter is -+ * applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI -+ * PHY_TYPE, this parameter indicates the data width between -+ * the MAC and the ULPI Wrapper.) Also, this parameter is -+ * applicable only if the OTG_HSPHY_WIDTH cC parameter was set -+ * to "8 and 16 bits", meaning that the core has been -+ * configured to work at either data path width. -+ * -+ * 8 or 16 bits (default 16) -+ */ -+ int32_t phy_utmi_width; -+#define dwc_param_phy_utmi_width_default 16 -+ -+ /* -+ * Specifies whether the ULPI operates at double or single -+ * data rate. This parameter is only applicable if PHY_TYPE is -+ * ULPI. -+ * -+ * 0 - single data rate ULPI interface with 8 bit wide data -+ * bus (default) -+ * 1 - double data rate ULPI interface with 4 bit wide data -+ * bus -+ */ -+ int32_t phy_ulpi_ddr; -+#define dwc_param_phy_ulpi_ddr_default 0 -+ -+ /* -+ * Specifies whether to use the internal or external supply to -+ * drive the vbus with a ULPI phy. -+ */ -+ int32_t phy_ulpi_ext_vbus; -+#define DWC_PHY_ULPI_INTERNAL_VBUS 0 -+#define DWC_PHY_ULPI_EXTERNAL_VBUS 1 -+#define dwc_param_phy_ulpi_ext_vbus_default DWC_PHY_ULPI_INTERNAL_VBUS -+ -+ /* -+ * Specifies whether to use the I2Cinterface for full speed PHY. This -+ * parameter is only applicable if PHY_TYPE is FS. -+ * 0 - No (default) -+ * 1 - Yes -+ */ -+ int32_t i2c_enable; -+#define dwc_param_i2c_enable_default 0 -+ -+ int32_t ulpi_fs_ls; -+#define dwc_param_ulpi_fs_ls_default 0 -+ -+ int32_t ts_dline; -+#define dwc_param_ts_dline_default 0 -+ -+}; -+ -+/** -+ * The FIFOs are established based on a default percentage of the total -+ * FIFO depth. This check insures that the defaults are reasonable. -+ */ -+#if (((dwc_param_host_rx_fifo_size_percentage) \ -+ +(dwc_param_host_nperio_tx_fifo_size_percentage) \ -+ +(dwc_param_host_perio_tx_fifo_size_percentage)) > 100) -+#error Invalid FIFO allocation -+#endif -+ -+#ifdef DEBUG -+struct dwc_otg_core_if; -+struct hc_xfer_info { -+ struct dwc_otg_core_if *core_if; -+ struct dwc_hc *hc; -+}; -+#endif -+ -+/* -+ * The <code>dwc_otg_core_if</code> structure contains information -+ * needed to manage the DWC_otg controller acting in either host or -+ * device mode. It represents the programming view of the controller -+ * as a whole. -+ */ -+struct dwc_otg_core_if { -+ /** USB block index number for Octeon's that support multiple */ -+ int usb_num; -+ -+ /** Parameters that define how the core should be configured.*/ -+ struct dwc_otg_core_params *core_params; -+ -+ /** Core Global registers starting at offset 000h. */ -+ struct dwc_otg_core_global_regs *core_global_regs; -+ -+ /** Device-specific information */ -+ struct dwc_otg_dev_if *dev_if; -+ /** Host-specific information */ -+ struct dwc_otg_host_if *host_if; -+ -+ /* -+ * Set to 1 if the core PHY interface bits in USBCFG have been -+ * initialized. -+ */ -+ uint8_t phy_init_done; -+ -+ /* -+ * SRP Success flag, set by srp success interrupt in FS I2C mode -+ */ -+ uint8_t srp_success; -+ uint8_t srp_timer_started; -+ -+ /* Common configuration information */ -+ /** Power and Clock Gating Control Register */ -+ uint32_t *pcgcctl; -+#define DWC_OTG_PCGCCTL_OFFSET 0xE00 -+ -+ /** Push/pop addresses for endpoints or host channels.*/ -+ uint32_t *data_fifo[MAX_EPS_CHANNELS]; -+#define DWC_OTG_DATA_FIFO_OFFSET 0x1000 -+#define DWC_OTG_DATA_FIFO_SIZE 0x1000 -+ -+ /** Total RAM for FIFOs (Bytes) */ -+ uint16_t total_fifo_size; -+ /** Size of Rx FIFO (Bytes) */ -+ uint16_t rx_fifo_size; -+ /** Size of Non-periodic Tx FIFO (Bytes) */ -+ uint16_t nperio_tx_fifo_size; -+ -+ /** 1 if DMA is enabled, 0 otherwise. */ -+ uint8_t dma_enable; -+ -+ /** Set to 1 if multiple packets of a high-bandwidth transfer is in -+ * process of being queued */ -+ uint8_t queuing_high_bandwidth; -+ -+ /** Hardware Configuration -- stored here for convenience.*/ -+ union hwcfg1_data hwcfg1; -+ union hwcfg2_data hwcfg2; -+ union hwcfg3_data hwcfg3; -+ union hwcfg4_data hwcfg4; -+ -+ /* -+ * The operational State, during transations -+ * (a_host>>a_peripherial and b_device=>b_host) this may not -+ * match the core but allows the software to determine -+ * transitions. -+ */ -+ uint8_t op_state; -+ -+ /* -+ * Set to 1 if the HCD needs to be restarted on a session request -+ * interrupt. This is required if no connector ID status change has -+ * occurred since the HCD was last disconnected. -+ */ -+ uint8_t restart_hcd_on_session_req; -+ -+ /** HCD callbacks */ -+ /** A-Device is a_host */ -+#define A_HOST (1) -+ /** A-Device is a_suspend */ -+#define A_SUSPEND (2) -+ /** A-Device is a_peripherial */ -+#define A_PERIPHERAL (3) -+ /** B-Device is operating as a Peripheral. */ -+#define B_PERIPHERAL (4) -+ /** B-Device is operating as a Host. */ -+#define B_HOST (5) -+ -+ /** HCD callbacks */ -+ struct dwc_otg_cil_callbacks *hcd_cb; -+ /** PCD callbacks */ -+ struct dwc_otg_cil_callbacks *pcd_cb; -+ -+#ifdef DEBUG -+ uint32_t start_hcchar_val[MAX_EPS_CHANNELS]; -+ -+ struct hc_xfer_info hc_xfer_info[MAX_EPS_CHANNELS]; -+ struct timer_list hc_xfer_timer[MAX_EPS_CHANNELS]; -+ -+ uint32_t hfnum_7_samples; -+ uint64_t hfnum_7_frrem_accum; -+ uint32_t hfnum_0_samples; -+ uint64_t hfnum_0_frrem_accum; -+ uint32_t hfnum_other_samples; -+ uint64_t hfnum_other_frrem_accum; -+#endif -+ -+}; -+ -+/* -+ * The following functions support initialization of the CIL driver component -+ * and the DWC_otg controller. -+ */ -+extern struct dwc_otg_core_if *dwc_otg_cil_init(const uint32_t *reg_base_addr, -+ struct dwc_otg_core_params * -+ _core_params); -+extern void dwc_otg_cil_remove(struct dwc_otg_core_if *core_if); -+extern void dwc_otg_core_init(struct dwc_otg_core_if *core_if); -+extern void dwc_otg_core_host_init(struct dwc_otg_core_if *core_if); -+extern void dwc_otg_core_dev_init(struct dwc_otg_core_if *core_if); -+extern void dwc_otg_enable_global_interrupts(struct dwc_otg_core_if *core_if); -+extern void dwc_otg_disable_global_interrupts(struct dwc_otg_core_if *core_if); -+ -+/* Device CIL Functions -+ * The following functions support managing the DWC_otg controller in device -+ * mode. -+ */ -+ -+extern void dwc_otg_wakeup(struct dwc_otg_core_if *core_if); -+extern void dwc_otg_read_setup_packet(struct dwc_otg_core_if *core_if, -+ uint32_t *dest); -+extern uint32_t dwc_otg_get_frame_number(struct dwc_otg_core_if *core_if); -+extern void dwc_otg_ep0_activate(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep); -+extern void dwc_otg_ep_activate(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep); -+extern void dwc_otg_ep_deactivate(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep); -+extern void dwc_otg_ep_start_transfer(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep); -+extern void dwc_otg_ep0_start_transfer(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep); -+extern void dwc_otg_ep0_continue_transfer(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep); -+extern void dwc_otg_ep_write_packet(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep, int _dma); -+extern void dwc_otg_ep_set_stall(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep); -+extern void dwc_otg_ep_clear_stall(struct dwc_otg_core_if *core_if, -+ struct dwc_ep *ep); -+extern void dwc_otg_enable_device_interrupts(struct dwc_otg_core_if *core_if); -+extern void dwc_otg_dump_dev_registers(struct dwc_otg_core_if *core_if); -+ -+/* Host CIL Functions -+ * The following functions support managing the DWC_otg controller in host -+ * mode. -+ */ -+ -+extern void dwc_otg_hc_init(struct dwc_otg_core_if *core_if, struct dwc_hc *hc); -+extern void dwc_otg_hc_halt(struct dwc_otg_core_if *core_if, -+ struct dwc_hc *hc, -+ enum dwc_otg_halt_status halt_status); -+extern void dwc_otg_hc_cleanup(struct dwc_otg_core_if *core_if, -+ struct dwc_hc *hc); -+extern void dwc_otg_hc_start_transfer(struct dwc_otg_core_if *core_if, -+ struct dwc_hc *hc); -+extern int dwc_otg_hc_continue_transfer(struct dwc_otg_core_if *core_if, -+ struct dwc_hc *hc); -+extern void dwc_otg_hc_do_ping(struct dwc_otg_core_if *core_if, -+ struct dwc_hc *hc); -+extern void dwc_otg_hc_write_packet(struct dwc_otg_core_if *core_if, -+ struct dwc_hc *hc); -+extern void dwc_otg_enable_host_interrupts(struct dwc_otg_core_if *core_if); -+extern void dwc_otg_disable_host_interrupts(struct dwc_otg_core_if *core_if); -+ -+/** -+ * This function Reads HPRT0 in preparation to modify. It keeps the -+ * WC bits 0 so that if they are read as 1, they won't clear when you -+ * write it back -+ */ -+static inline uint32_t dwc_otg_read_hprt0(struct dwc_otg_core_if *core_if) -+{ -+ union hprt0_data hprt0; -+ hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0); -+ hprt0.b.prtena = 0; -+ hprt0.b.prtconndet = 0; -+ hprt0.b.prtenchng = 0; -+ hprt0.b.prtovrcurrchng = 0; -+ return hprt0.d32; -+} -+ -+extern void dwc_otg_dump_host_registers(struct dwc_otg_core_if *core_if); -+ -+/* Common CIL Functions -+ * The following functions support managing the DWC_otg controller in either -+ * device or host mode. -+ */ -+ -+ -+extern void dwc_otg_read_packet(struct dwc_otg_core_if *core_if, -+ uint8_t *dest, uint16_t bytes); -+ -+extern void dwc_otg_dump_global_registers(struct dwc_otg_core_if *core_if); -+ -+extern void dwc_otg_flush_tx_fifo(struct dwc_otg_core_if *core_if, -+ const int _num); -+extern void dwc_otg_flush_rx_fifo(struct dwc_otg_core_if *core_if); -+extern void dwc_otg_core_reset(struct dwc_otg_core_if *core_if); -+ -+/** -+ * This function returns the Core Interrupt register. -+ */ -+static inline uint32_t dwc_otg_read_core_intr(struct dwc_otg_core_if *core_if) -+{ -+ return dwc_read_reg32(&core_if->core_global_regs->gintsts) & -+ dwc_read_reg32(&core_if->core_global_regs->gintmsk); -+} -+ -+/** -+ * This function returns the OTG Interrupt register. -+ */ -+static inline uint32_t dwc_otg_read_otg_intr(struct dwc_otg_core_if *core_if) -+{ -+ return dwc_read_reg32(&core_if->core_global_regs->gotgint); -+} -+ -+/** -+ * This function reads the Device All Endpoints Interrupt register and -+ * returns the IN endpoint interrupt bits. -+ */ -+static inline uint32_t dwc_otg_read_dev_all_in_ep_intr(struct dwc_otg_core_if * -+ core_if) -+{ -+ uint32_t v; -+ v = dwc_read_reg32(&core_if->dev_if->dev_global_regs->daint) & -+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk); -+ return v & 0xffff; -+ -+} -+ -+/** -+ * This function reads the Device All Endpoints Interrupt register and -+ * returns the OUT endpoint interrupt bits. -+ */ -+static inline uint32_t -+dwc_otg_read_dev_all_out_ep_intr(struct dwc_otg_core_if *core_if) -+{ -+ uint32_t v; -+ v = dwc_read_reg32(&core_if->dev_if->dev_global_regs->daint) & -+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->daintmsk); -+ return (v & 0xffff0000) >> 16; -+} -+ -+/** -+ * This function returns the Device IN EP Interrupt register -+ */ -+static inline uint32_t -+dwc_otg_read_dev_in_ep_intr(struct dwc_otg_core_if *core_if, struct dwc_ep *ep) -+{ -+ struct dwc_otg_dev_if *dev_if = core_if->dev_if; -+ uint32_t v; -+ v = dwc_read_reg32(&dev_if->in_ep_regs[ep->num]->diepint) & -+ dwc_read_reg32(&dev_if->dev_global_regs->diepmsk); -+ return v; -+} -+ -+/** -+ * This function returns the Device OUT EP Interrupt register -+ */ -+static inline uint32_t dwc_otg_read_dev_out_ep_intr(struct dwc_otg_core_if * -+ core_if, struct dwc_ep *ep) -+{ -+ struct dwc_otg_dev_if *dev_if = core_if->dev_if; -+ uint32_t v; -+ v = dwc_read_reg32(&dev_if->out_ep_regs[ep->num]->doepint) & -+ dwc_read_reg32(&dev_if->dev_global_regs->diepmsk); -+ return v; -+} -+ -+/** -+ * This function returns the Host All Channel Interrupt register -+ */ -+static inline uint32_t -+dwc_otg_read_host_all_channels_intr(struct dwc_otg_core_if *core_if) -+{ -+ return dwc_read_reg32(&core_if->host_if->host_global_regs->haint); -+} -+ -+static inline uint32_t -+dwc_otg_read_host_channel_intr(struct dwc_otg_core_if *core_if, -+ struct dwc_hc *hc) -+{ -+ return dwc_read_reg32(&core_if->host_if->hc_regs[hc->hc_num]->hcint); -+} -+ -+/** -+ * This function returns the mode of the operation, host or device. -+ * -+ * Returns 0 - Device Mode, 1 - Host Mode -+ */ -+static inline uint32_t dwc_otg_mode(struct dwc_otg_core_if *core_if) -+{ -+ return dwc_read_reg32(&core_if->core_global_regs->gintsts) & 0x1; -+} -+ -+static inline uint8_t dwc_otg_is_device_mode(struct dwc_otg_core_if *core_if) -+{ -+ return dwc_otg_mode(core_if) != DWC_HOST_MODE; -+} -+ -+static inline uint8_t dwc_otg_is_host_mode(struct dwc_otg_core_if *core_if) -+{ -+ return dwc_otg_mode(core_if) == DWC_HOST_MODE; -+} -+ -+extern int32_t dwc_otg_handle_common_intr(struct dwc_otg_core_if *core_if); -+ -+/* -+ * DWC_otg CIL callback structure. This structure allows the HCD and -+ * PCD to register functions used for starting and stopping the PCD -+ * and HCD for role change on for a DRD. -+ */ -+struct dwc_otg_cil_callbacks { -+ /* Start function for role change */ -+ int (*start) (void *p); -+ /* Stop Function for role change */ -+ int (*stop) (void *p); -+ /* Disconnect Function for role change */ -+ int (*disconnect) (void *p); -+ /* Resume/Remote wakeup Function */ -+ int (*resume_wakeup) (void *p); -+ /* Suspend function */ -+ int (*suspend) (void *p); -+ /* Session Start (SRP) */ -+ int (*session_start) (void *p); -+ /* Pointer passed to start() and stop() */ -+ void *p; -+}; -+ -+extern void dwc_otg_cil_register_pcd_callbacks(struct dwc_otg_core_if *core_if, -+ struct dwc_otg_cil_callbacks *cb, -+ void *p); -+extern void dwc_otg_cil_register_hcd_callbacks(struct dwc_otg_core_if *core_if, -+ struct dwc_otg_cil_callbacks *cb, -+ void *p); -+#endif -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c -new file mode 100644 -index 0000000..38c46df ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c -@@ -0,0 +1,689 @@ -+/* ========================================================================== -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+ -+/** -+ * -+ * The Core Interface Layer provides basic services for accessing and -+ * managing the DWC_otg hardware. These services are used by both the -+ * Host Controller Driver and the Peripheral Controller Driver. -+ * -+ * This file contains the Common Interrupt handlers. -+ */ -+#include "dwc_otg_plat.h" -+#include "dwc_otg_regs.h" -+#include "dwc_otg_cil.h" -+ -+#ifdef DEBUG -+inline const char *op_state_str(struct dwc_otg_core_if *core_if) -+{ -+ return (core_if->op_state == A_HOST ? "a_host" : -+ (core_if->op_state == A_SUSPEND ? "a_suspend" : -+ (core_if->op_state == A_PERIPHERAL ? "a_peripheral" : -+ (core_if->op_state == B_PERIPHERAL ? "b_peripheral" : -+ (core_if->op_state == B_HOST ? "b_host" : "unknown"))))); -+} -+#endif -+ -+/** This function will log a debug message -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+int32_t dwc_otg_handle_mode_mismatch_intr(struct dwc_otg_core_if *core_if) -+{ -+ union gintsts_data gintsts; -+ DWC_WARN("Mode Mismatch Interrupt: currently in %s mode\n", -+ dwc_otg_mode(core_if) ? "Host" : "Device"); -+ -+ /* Clear interrupt */ -+ gintsts.d32 = 0; -+ gintsts.b.modemismatch = 1; -+ dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32); -+ return 1; -+} -+ -+/** Start the HCD. Helper function for using the HCD callbacks. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+static inline void hcd_start(struct dwc_otg_core_if *core_if) -+{ -+ if (core_if->hcd_cb && core_if->hcd_cb->start) -+ core_if->hcd_cb->start(core_if->hcd_cb->p); -+} -+ -+/** Stop the HCD. Helper function for using the HCD callbacks. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+static inline void hcd_stop(struct dwc_otg_core_if *core_if) -+{ -+ if (core_if->hcd_cb && core_if->hcd_cb->stop) -+ core_if->hcd_cb->stop(core_if->hcd_cb->p); -+} -+ -+/** Disconnect the HCD. Helper function for using the HCD callbacks. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+static inline void hcd_disconnect(struct dwc_otg_core_if *core_if) -+{ -+ if (core_if->hcd_cb && core_if->hcd_cb->disconnect) -+ core_if->hcd_cb->disconnect(core_if->hcd_cb->p); -+} -+ -+/** Inform the HCD the a New Session has begun. Helper function for -+ * using the HCD callbacks. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+static inline void hcd_session_start(struct dwc_otg_core_if *core_if) -+{ -+ if (core_if->hcd_cb && core_if->hcd_cb->session_start) -+ core_if->hcd_cb->session_start(core_if->hcd_cb->p); -+} -+ -+/** Start the PCD. Helper function for using the PCD callbacks. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+static inline void pcd_start(struct dwc_otg_core_if *core_if) -+{ -+ if (core_if->pcd_cb && core_if->pcd_cb->start) -+ core_if->pcd_cb->start(core_if->pcd_cb->p); -+} -+ -+/** Stop the PCD. Helper function for using the PCD callbacks. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+static inline void pcd_stop(struct dwc_otg_core_if *core_if) -+{ -+ if (core_if->pcd_cb && core_if->pcd_cb->stop) -+ core_if->pcd_cb->stop(core_if->pcd_cb->p); -+} -+ -+/** Suspend the PCD. Helper function for using the PCD callbacks. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+static inline void pcd_suspend(struct dwc_otg_core_if *core_if) -+{ -+ if (core_if->pcd_cb && core_if->pcd_cb->suspend) -+ core_if->pcd_cb->suspend(core_if->pcd_cb->p); -+} -+ -+/** Resume the PCD. Helper function for using the PCD callbacks. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+static inline void pcd_resume(struct dwc_otg_core_if *core_if) -+{ -+ if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) -+ core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p); -+} -+ -+/** -+ * This function handles the OTG Interrupts. It reads the OTG -+ * Interrupt Register (GOTGINT) to determine what interrupt has -+ * occurred. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+int32_t dwc_otg_handle_otg_intr(struct dwc_otg_core_if *core_if) -+{ -+ struct dwc_otg_core_global_regs *global_regs = core_if->core_global_regs; -+ union gotgint_data gotgint; -+ union gotgctl_data gotgctl; -+ union gintmsk_data gintmsk; -+ -+ gotgint.d32 = dwc_read_reg32(&global_regs->gotgint); -+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl); -+ DWC_DEBUGPL(DBG_CIL, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint.d32, -+ op_state_str(core_if)); -+ -+ if (gotgint.b.sesenddet) { -+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " -+ "Session End Detected++ (%s)\n", -+ op_state_str(core_if)); -+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl); -+ -+ if (core_if->op_state == B_HOST) { -+ pcd_start(core_if); -+ core_if->op_state = B_PERIPHERAL; -+ } else { -+ /* If not B_HOST and Device HNP still set. HNP -+ * Did not succeed!*/ -+ if (gotgctl.b.devhnpen) { -+ DWC_DEBUGPL(DBG_ANY, "Session End Detected\n"); -+ DWC_ERROR("Device Not Connected/Responding!\n"); -+ } -+ -+ /* If Session End Detected the B-Cable has -+ * been disconnected. */ -+ /* Reset PCD and Gadget driver to a -+ * clean state. */ -+ pcd_stop(core_if); -+ } -+ gotgctl.d32 = 0; -+ gotgctl.b.devhnpen = 1; -+ dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0); -+ } -+ if (gotgint.b.sesreqsucstschng) { -+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " -+ "Session Reqeust Success Status Change++\n"); -+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl); -+ if (gotgctl.b.sesreqscs) { -+ if ((core_if->core_params->phy_type == -+ DWC_PHY_TYPE_PARAM_FS) -+ && (core_if->core_params->i2c_enable)) { -+ core_if->srp_success = 1; -+ } else { -+ pcd_resume(core_if); -+ /* Clear Session Request */ -+ gotgctl.d32 = 0; -+ gotgctl.b.sesreq = 1; -+ dwc_modify_reg32(&global_regs->gotgctl, -+ gotgctl.d32, 0); -+ } -+ } -+ } -+ if (gotgint.b.hstnegsucstschng) { -+ /* Print statements during the HNP interrupt handling -+ * can cause it to fail.*/ -+ gotgctl.d32 = dwc_read_reg32(&global_regs->gotgctl); -+ if (gotgctl.b.hstnegscs) { -+ if (dwc_otg_is_host_mode(core_if)) { -+ core_if->op_state = B_HOST; -+ /* -+ * Need to disable SOF interrupt immediately. -+ * When switching from device to host, the PCD -+ * interrupt handler won't handle the -+ * interrupt if host mode is already set. The -+ * HCD interrupt handler won't get called if -+ * the HCD state is HALT. This means that the -+ * interrupt does not get handled and Linux -+ * complains loudly. -+ */ -+ gintmsk.d32 = 0; -+ gintmsk.b.sofintr = 1; -+ dwc_modify_reg32(&global_regs->gintmsk, -+ gintmsk.d32, 0); -+ pcd_stop(core_if); -+ /* -+ * Initialize the Core for Host mode. -+ */ -+ hcd_start(core_if); -+ core_if->op_state = B_HOST; -+ } -+ } else { -+ gotgctl.d32 = 0; -+ gotgctl.b.hnpreq = 1; -+ gotgctl.b.devhnpen = 1; -+ dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0); -+ DWC_DEBUGPL(DBG_ANY, "HNP Failed\n"); -+ DWC_ERROR("Device Not Connected/Responding\n"); -+ } -+ } -+ if (gotgint.b.hstnegdet) { -+ /* The disconnect interrupt is set at the same time as -+ * Host Negotiation Detected. During the mode -+ * switch all interrupts are cleared so the disconnect -+ * interrupt handler will not get executed. -+ */ -+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " -+ "Host Negotiation Detected++ (%s)\n", -+ (dwc_otg_is_host_mode(core_if) ? "Host" : -+ "Device")); -+ if (dwc_otg_is_device_mode(core_if)) { -+ DWC_DEBUGPL(DBG_ANY, "a_suspend->a_peripheral (%d)\n", -+ core_if->op_state); -+ hcd_disconnect(core_if); -+ pcd_start(core_if); -+ core_if->op_state = A_PERIPHERAL; -+ } else { -+ /* -+ * Need to disable SOF interrupt immediately. When -+ * switching from device to host, the PCD interrupt -+ * handler won't handle the interrupt if host mode is -+ * already set. The HCD interrupt handler won't get -+ * called if the HCD state is HALT. This means that -+ * the interrupt does not get handled and Linux -+ * complains loudly. -+ */ -+ gintmsk.d32 = 0; -+ gintmsk.b.sofintr = 1; -+ dwc_modify_reg32(&global_regs->gintmsk, gintmsk.d32, 0); -+ pcd_stop(core_if); -+ hcd_start(core_if); -+ core_if->op_state = A_HOST; -+ } -+ } -+ if (gotgint.b.adevtoutchng) -+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " -+ "A-Device Timeout Change++\n"); -+ if (gotgint.b.debdone) -+ DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " "Debounce Done++\n"); -+ -+ /* Clear GOTGINT */ -+ dwc_write_reg32(&core_if->core_global_regs->gotgint, gotgint.d32); -+ -+ return 1; -+} -+ -+/** -+ * This function handles the Connector ID Status Change Interrupt. It -+ * reads the OTG Interrupt Register (GOTCTL) to determine whether this -+ * is a Device to Host Mode transition or a Host Mode to Device -+ * Transition. -+ * -+ * This only occurs when the cable is connected/removed from the PHY -+ * connector. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+int32_t dwc_otg_handle_conn_id_status_change_intr(struct dwc_otg_core_if *core_if) -+{ -+ uint32_t count = 0; -+ -+ union gintsts_data gintsts = {.d32 = 0 }; -+ union gintmsk_data gintmsk = {.d32 = 0 }; -+ union gotgctl_data gotgctl = {.d32 = 0 }; -+ -+ /* -+ * Need to disable SOF interrupt immediately. If switching from device -+ * to host, the PCD interrupt handler won't handle the interrupt if -+ * host mode is already set. The HCD interrupt handler won't get -+ * called if the HCD state is HALT. This means that the interrupt does -+ * not get handled and Linux complains loudly. -+ */ -+ gintmsk.b.sofintr = 1; -+ dwc_modify_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0); -+ -+ DWC_DEBUGPL(DBG_CIL, -+ " ++Connector ID Status Change Interrupt++ (%s)\n", -+ (dwc_otg_is_host_mode(core_if) ? "Host" : "Device")); -+ gotgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl); -+ DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32); -+ DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts); -+ -+ /* B-Device connector (Device Mode) */ -+ if (gotgctl.b.conidsts) { -+ /* Wait for switch to device mode. */ -+ while (!dwc_otg_is_device_mode(core_if)) { -+ DWC_PRINT("Waiting for Peripheral Mode, Mode=%s\n", -+ (dwc_otg_is_host_mode(core_if) ? "Host" : -+ "Peripheral")); -+ mdelay(100); -+ if (++count > 10000) -+ *(uint32_t *) NULL = 0; -+ } -+ core_if->op_state = B_PERIPHERAL; -+ dwc_otg_core_init(core_if); -+ dwc_otg_enable_global_interrupts(core_if); -+ pcd_start(core_if); -+ } else { -+ /* A-Device connector (Host Mode) */ -+ while (!dwc_otg_is_host_mode(core_if)) { -+ DWC_PRINT("Waiting for Host Mode, Mode=%s\n", -+ (dwc_otg_is_host_mode(core_if) ? "Host" : -+ "Peripheral")); -+ mdelay(100); -+ if (++count > 10000) -+ *(uint32_t *) NULL = 0; -+ } -+ core_if->op_state = A_HOST; -+ /* -+ * Initialize the Core for Host mode. -+ */ -+ dwc_otg_core_init(core_if); -+ dwc_otg_enable_global_interrupts(core_if); -+ hcd_start(core_if); -+ } -+ -+ /* Set flag and clear interrupt */ -+ gintsts.b.conidstschng = 1; -+ dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32); -+ -+ return 1; -+} -+ -+/** -+ * This interrupt indicates that a device is initiating the Session -+ * Request Protocol to request the host to turn on bus power so a new -+ * session can begin. The handler responds by turning on bus power. If -+ * the DWC_otg controller is in low power mode, the handler brings the -+ * controller out of low power mode before turning on bus power. -+ * -+ * @core_if: Programming view of DWC_otg controller. -+ */ -+int32_t dwc_otg_handle_session_req_intr(struct dwc_otg_core_if *core_if) -+{ -+ union gintsts_data gintsts; -+#ifndef DWC_HOST_ONLY -+ union hprt0_data hprt0; -+ -+ DWC_DEBUGPL(DBG_ANY, "++Session Request Interrupt++\n"); -+ -+ if (dwc_otg_is_device_mode(core_if)) { -+ DWC_PRINT("SRP: Device mode\n"); -+ } else { -+ DWC_PRINT("SRP: Host mode\n"); -+ -+ /* Turn on the port power bit. */ -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ hprt0.b.prtpwr = 1; -+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); -+ -+ /* Start the Connection timer. So a message can be displayed -+ * if connect does not occur within 10 seconds. */ -+ hcd_session_start(core_if); -+ } -+#endif -+ -+ /* Clear interrupt */ -+ gintsts.d32 = 0; -+ gintsts.b.sessreqintr = 1; -+ dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32); -+ -+ return 1; -+} -+ -+/** -+ * This interrupt indicates that the DWC_otg controller has detected a -+ * resume or remote wakeup sequence. If the DWC_otg controller is in -+ * low power mode, the handler must brings the controller out of low -+ * power mode. The controller automatically begins resume -+ * signaling. The handler schedules a time to stop resume signaling. -+ */ -+int32_t dwc_otg_handle_wakeup_detected_intr(struct dwc_otg_core_if *core_if) -+{ -+ union gintsts_data gintsts; -+ -+ DWC_DEBUGPL(DBG_ANY, -+ "++Resume and Remote Wakeup Detected Interrupt++\n"); -+ -+ if (dwc_otg_is_device_mode(core_if)) { -+ union dctl_data dctl = {.d32 = 0 }; -+ DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n", -+ dwc_read_reg32(&core_if->dev_if->dev_global_regs-> -+ dsts)); -+#ifdef PARTIAL_POWER_DOWN -+ if (core_if->hwcfg4.b.power_optimiz) { -+ union pcgcctl_data power = {.d32 = 0 }; -+ -+ power.d32 = dwc_read_reg32(core_if->pcgcctl); -+ DWC_DEBUGPL(DBG_CIL, "PCGCCTL=%0x\n", power.d32); -+ -+ power.b.stoppclk = 0; -+ dwc_write_reg32(core_if->pcgcctl, power.d32); -+ -+ power.b.pwrclmp = 0; -+ dwc_write_reg32(core_if->pcgcctl, power.d32); -+ -+ power.b.rstpdwnmodule = 0; -+ dwc_write_reg32(core_if->pcgcctl, power.d32); -+ } -+#endif -+ /* Clear the Remote Wakeup Signalling */ -+ dctl.b.rmtwkupsig = 1; -+ dwc_modify_reg32(&core_if->dev_if->dev_global_regs->dctl, -+ dctl.d32, 0); -+ -+ if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) -+ core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p); -+ } else { -+ /* -+ * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms -+ * so that OPT tests pass with all PHYs). -+ */ -+ union hprt0_data hprt0 = {.d32 = 0 }; -+ union pcgcctl_data pcgcctl = {.d32 = 0 }; -+ /* Restart the Phy Clock */ -+ pcgcctl.b.stoppclk = 1; -+ dwc_modify_reg32(core_if->pcgcctl, pcgcctl.d32, 0); -+ udelay(10); -+ -+ /* Now wait for 70 ms. */ -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ DWC_DEBUGPL(DBG_ANY, "Resume: HPRT0=%0x\n", hprt0.d32); -+ mdelay(70); -+ hprt0.b.prtres = 0; /* Resume */ -+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); -+ DWC_DEBUGPL(DBG_ANY, "Clear Resume: HPRT0=%0x\n", -+ dwc_read_reg32(core_if->host_if->hprt0)); -+ } -+ -+ /* Clear interrupt */ -+ gintsts.d32 = 0; -+ gintsts.b.wkupintr = 1; -+ dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32); -+ -+ return 1; -+} -+ -+/** -+ * This interrupt indicates that a device has been disconnected from -+ * the root port. -+ */ -+int32_t dwc_otg_handle_disconnect_intr(struct dwc_otg_core_if *core_if) -+{ -+ union gintsts_data gintsts; -+ -+ DWC_DEBUGPL(DBG_ANY, "++Disconnect Detected Interrupt++ (%s) %s\n", -+ (dwc_otg_is_host_mode(core_if) ? "Host" : "Device"), -+ op_state_str(core_if)); -+ -+/** @todo Consolidate this if statement. */ -+#ifndef DWC_HOST_ONLY -+ if (core_if->op_state == B_HOST) { -+ /* If in device mode Disconnect and stop the HCD, then -+ * start the PCD. */ -+ hcd_disconnect(core_if); -+ pcd_start(core_if); -+ core_if->op_state = B_PERIPHERAL; -+ } else if (dwc_otg_is_device_mode(core_if)) { -+ union gotgctl_data gotgctl = {.d32 = 0 }; -+ gotgctl.d32 = -+ dwc_read_reg32(&core_if->core_global_regs->gotgctl); -+ if (gotgctl.b.hstsethnpen == 1) { -+ /* Do nothing, if HNP in process the OTG -+ * interrupt "Host Negotiation Detected" -+ * interrupt will do the mode switch. -+ */ -+ } else if (gotgctl.b.devhnpen == 0) { -+ /* If in device mode Disconnect and stop the HCD, then -+ * start the PCD. */ -+ hcd_disconnect(core_if); -+ pcd_start(core_if); -+ core_if->op_state = B_PERIPHERAL; -+ } else { -+ DWC_DEBUGPL(DBG_ANY, "!a_peripheral && !devhnpen\n"); -+ } -+ } else { -+ if (core_if->op_state == A_HOST) { -+ /* A-Cable still connected but device disconnected. */ -+ hcd_disconnect(core_if); -+ } -+ } -+#endif -+ -+ gintsts.d32 = 0; -+ gintsts.b.disconnect = 1; -+ dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32); -+ return 1; -+} -+ -+/** -+ * This interrupt indicates that SUSPEND state has been detected on -+ * the USB. -+ * -+ * For HNP the USB Suspend interrupt signals the change from -+ * "a_peripheral" to "a_host". -+ * -+ * When power management is enabled the core will be put in low power -+ * mode. -+ */ -+int32_t dwc_otg_handle_usb_suspend_intr(struct dwc_otg_core_if *core_if) -+{ -+ union dsts_data dsts; -+ union gintsts_data gintsts; -+ -+ DWC_DEBUGPL(DBG_ANY, "USB SUSPEND\n"); -+ -+ if (dwc_otg_is_device_mode(core_if)) { -+ /* Check the Device status register to determine if the Suspend -+ * state is active. */ -+ dsts.d32 = -+ dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts); -+ DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n", dsts.d32); -+ DWC_DEBUGPL(DBG_PCD, "DSTS.Suspend Status=%d " -+ "HWCFG4.power Optimize=%d\n", -+ dsts.b.suspsts, core_if->hwcfg4.b.power_optimiz); -+ -+#ifdef PARTIAL_POWER_DOWN -+/** @todo Add a module parameter for power management. */ -+ -+ if (dsts.b.suspsts && core_if->hwcfg4.b.power_optimiz) { -+ union pcgcctl_data_t power = {.d32 = 0 }; -+ DWC_DEBUGPL(DBG_CIL, "suspend\n"); -+ -+ power.b.pwrclmp = 1; -+ dwc_write_reg32(core_if->pcgcctl, power.d32); -+ -+ power.b.rstpdwnmodule = 1; -+ dwc_modify_reg32(core_if->pcgcctl, 0, power.d32); -+ -+ power.b.stoppclk = 1; -+ dwc_modify_reg32(core_if->pcgcctl, 0, power.d32); -+ -+ } else { -+ DWC_DEBUGPL(DBG_ANY, "disconnect?\n"); -+ } -+#endif -+ /* PCD callback for suspend. */ -+ pcd_suspend(core_if); -+ } else { -+ if (core_if->op_state == A_PERIPHERAL) { -+ DWC_DEBUGPL(DBG_ANY, "a_peripheral->a_host\n"); -+ /* Clear the a_peripheral flag, back to a_host. */ -+ pcd_stop(core_if); -+ hcd_start(core_if); -+ core_if->op_state = A_HOST; -+ } -+ } -+ -+ /* Clear interrupt */ -+ gintsts.d32 = 0; -+ gintsts.b.usbsuspend = 1; -+ dwc_write_reg32(&core_if->core_global_regs->gintsts, gintsts.d32); -+ -+ return 1; -+} -+ -+/** -+ * This function returns the Core Interrupt register. -+ */ -+static inline uint32_t dwc_otg_read_common_intr(struct dwc_otg_core_if *core_if) -+{ -+ union gintsts_data gintsts; -+ union gintmsk_data gintmsk; -+ union gintmsk_data gintmsk_common = {.d32 = 0 }; -+ gintmsk_common.b.wkupintr = 1; -+ gintmsk_common.b.sessreqintr = 1; -+ gintmsk_common.b.conidstschng = 1; -+ gintmsk_common.b.otgintr = 1; -+ gintmsk_common.b.modemismatch = 1; -+ gintmsk_common.b.disconnect = 1; -+ gintmsk_common.b.usbsuspend = 1; -+ /* -+ * @todo: The port interrupt occurs while in device -+ * mode. Added code to CIL to clear the interrupt for now! -+ */ -+ gintmsk_common.b.portintr = 1; -+ -+ gintsts.d32 = dwc_read_reg32(&core_if->core_global_regs->gintsts); -+ gintmsk.d32 = dwc_read_reg32(&core_if->core_global_regs->gintmsk); -+#ifdef DEBUG -+ /* if any common interrupts set */ -+ if (gintsts.d32 & gintmsk_common.d32) { -+ DWC_DEBUGPL(DBG_ANY, "gintsts=%08x gintmsk=%08x\n", -+ gintsts.d32, gintmsk.d32); -+ } -+#endif -+ -+ return (gintsts.d32 & gintmsk.d32) & gintmsk_common.d32; -+ -+} -+ -+/** -+ * Common interrupt handler. -+ * -+ * The common interrupts are those that occur in both Host and Device mode. -+ * This handler handles the following interrupts: -+ * - Mode Mismatch Interrupt -+ * - Disconnect Interrupt -+ * - OTG Interrupt -+ * - Connector ID Status Change Interrupt -+ * - Session Request Interrupt. -+ * - Resume / Remote Wakeup Detected Interrupt. -+ * -+ */ -+extern int32_t dwc_otg_handle_common_intr(struct dwc_otg_core_if *core_if) -+{ -+ int retval = 0; -+ union gintsts_data gintsts; -+ -+ gintsts.d32 = dwc_otg_read_common_intr(core_if); -+ -+ if (gintsts.b.modemismatch) -+ retval |= dwc_otg_handle_mode_mismatch_intr(core_if); -+ if (gintsts.b.otgintr) -+ retval |= dwc_otg_handle_otg_intr(core_if); -+ if (gintsts.b.conidstschng) -+ retval |= dwc_otg_handle_conn_id_status_change_intr(core_if); -+ if (gintsts.b.disconnect) -+ retval |= dwc_otg_handle_disconnect_intr(core_if); -+ if (gintsts.b.sessreqintr) -+ retval |= dwc_otg_handle_session_req_intr(core_if); -+ if (gintsts.b.wkupintr) -+ retval |= dwc_otg_handle_wakeup_detected_intr(core_if); -+ if (gintsts.b.usbsuspend) -+ retval |= dwc_otg_handle_usb_suspend_intr(core_if); -+ if (gintsts.b.portintr && dwc_otg_is_device_mode(core_if)) { -+ /* The port interrupt occurs while in device mode with HPRT0 -+ * Port Enable/Disable. -+ */ -+ gintsts.d32 = 0; -+ gintsts.b.portintr = 1; -+ dwc_write_reg32(&core_if->core_global_regs->gintsts, -+ gintsts.d32); -+ retval |= 1; -+ -+ } -+ return retval; -+} -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.h b/drivers/usb/host/dwc_otg/dwc_otg_driver.h -new file mode 100644 -index 0000000..1cc116d ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.h -@@ -0,0 +1,63 @@ -+/* ========================================================================== -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+ -+#ifndef __DWC_OTG_DRIVER_H__ -+#define __DWC_OTG_DRIVER_H__ -+ -+#include "dwc_otg_cil.h" -+ -+/* Type declarations */ -+struct dwc_otg_pcd; -+struct dwc_otg_hcd; -+ -+/** -+ * This structure is a wrapper that encapsulates the driver components used to -+ * manage a single DWC_otg controller. -+ */ -+struct dwc_otg_device { -+ /** Base address returned from ioremap() */ -+ void *base; -+ -+ /** Pointer to the core interface structure. */ -+ struct dwc_otg_core_if *core_if; -+ -+ /** Register offset for Diagnostic API.*/ -+ uint32_t reg_offset; -+ -+ /** Pointer to the PCD structure. */ -+ struct dwc_otg_pcd *pcd; -+ -+ /** Pointer to the HCD structure. */ -+ struct dwc_otg_hcd *hcd; -+ -+ /** Flag to indicate whether the common IRQ handler is installed. */ -+ uint8_t common_irq_installed; -+ -+}; -+ -+#endif -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -new file mode 100644 -index 0000000..a4392f5 ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -@@ -0,0 +1,2878 @@ -+/* ========================================================================== -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+#ifndef DWC_DEVICE_ONLY -+ -+/** -+ * -+ * This file contains the implementation of the HCD. In Linux, the HCD -+ * implements the hc_driver API. -+ */ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/init.h> -+#include <linux/device.h> -+#include <linux/errno.h> -+#include <linux/list.h> -+#include <linux/interrupt.h> -+#include <linux/string.h> -+#include <linux/dma-mapping.h> -+#include <linux/workqueue.h> -+#include <linux/platform_device.h> -+ -+#include "dwc_otg_driver.h" -+#include "dwc_otg_hcd.h" -+#include "dwc_otg_regs.h" -+ -+static const char dwc_otg_hcd_name[] = "dwc_otg_hcd"; -+ -+static const struct hc_driver dwc_otg_hc_driver = { -+ -+ .description = dwc_otg_hcd_name, -+ .product_desc = "DWC OTG Controller", -+ .hcd_priv_size = sizeof(struct dwc_otg_hcd), -+ -+ .irq = dwc_otg_hcd_irq, -+ -+ .flags = HCD_MEMORY | HCD_USB2, -+ -+ .start = dwc_otg_hcd_start, -+ .stop = dwc_otg_hcd_stop, -+ -+ .urb_enqueue = dwc_otg_hcd_urb_enqueue, -+ .urb_dequeue = dwc_otg_hcd_urb_dequeue, -+ .endpoint_disable = dwc_otg_hcd_endpoint_disable, -+ -+ .get_frame_number = dwc_otg_hcd_get_frame_number, -+ -+ .hub_status_data = dwc_otg_hcd_hub_status_data, -+ .hub_control = dwc_otg_hcd_hub_control, -+}; -+ -+/** -+ * Work queue function for starting the HCD when A-Cable is connected. -+ * The dwc_otg_hcd_start() must be called in a process context. -+ */ -+static void hcd_start_func(struct work_struct *work) -+{ -+ void *_vp = -+ (void *)(atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK); -+ struct usb_hcd *usb_hcd = (struct usb_hcd *)_vp; -+ DWC_DEBUGPL(DBG_HCDV, "%s() %p\n", __func__, usb_hcd); -+ if (usb_hcd) -+ dwc_otg_hcd_start(usb_hcd); -+} -+ -+/** -+ * HCD Callback function for starting the HCD when A-Cable is -+ * connected. -+ * -+ * @_p: void pointer to the <code>struct usb_hcd</code> -+ */ -+static int32_t dwc_otg_hcd_start_cb(void *_p) -+{ -+ struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_p); -+ struct dwc_otg_core_if *core_if = dwc_otg_hcd->core_if; -+ union hprt0_data hprt0; -+ -+ if (core_if->op_state == B_HOST) { -+ /* -+ * Reset the port. During a HNP mode switch the reset -+ * needs to occur within 1ms and have a duration of at -+ * least 50ms. -+ */ -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ hprt0.b.prtrst = 1; -+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); -+ ((struct usb_hcd *)_p)->self.is_b_host = 1; -+ } else { -+ ((struct usb_hcd *)_p)->self.is_b_host = 0; -+ } -+ -+ /* Need to start the HCD in a non-interrupt context. */ -+ INIT_WORK(&dwc_otg_hcd->start_work, hcd_start_func); -+ atomic_long_set(&dwc_otg_hcd->start_work.data, (long)_p); -+ schedule_work(&dwc_otg_hcd->start_work); -+ -+ return 1; -+} -+ -+/** -+ * HCD Callback function for stopping the HCD. -+ * -+ * @_p: void pointer to the <code>struct usb_hcd</code> -+ */ -+static int32_t dwc_otg_hcd_stop_cb(void *_p) -+{ -+ struct usb_hcd *usb_hcd = (struct usb_hcd *)_p; -+ DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p); -+ dwc_otg_hcd_stop(usb_hcd); -+ return 1; -+} -+ -+static void del_xfer_timers(struct dwc_otg_hcd *hcd) -+{ -+#ifdef DEBUG -+ int i; -+ int num_channels = hcd->core_if->core_params->host_channels; -+ for (i = 0; i < num_channels; i++) -+ del_timer(&hcd->core_if->hc_xfer_timer[i]); -+#endif -+} -+ -+static void del_timers(struct dwc_otg_hcd *hcd) -+{ -+ del_xfer_timers(hcd); -+ del_timer(&hcd->conn_timer); -+} -+ -+/** -+ * Processes all the URBs in a single list of QHs. Completes them with -+ * -ETIMEDOUT and frees the QTD. -+ */ -+static void kill_urbs_in_qh_list(struct dwc_otg_hcd *hcd, -+ struct list_head *_qh_list) -+{ -+ struct dwc_otg_qh *qh; -+ struct dwc_otg_qtd *qtd; -+ struct dwc_otg_qtd *qtd_next; -+ -+ list_for_each_entry(qh, _qh_list, qh_list_entry) { -+ list_for_each_entry_safe(qtd, qtd_next, &qh->qtd_list, -+ qtd_list_entry) { -+ if (qtd->urb != NULL) { -+ dwc_otg_hcd_complete_urb(hcd, qtd->urb, -+ -ETIMEDOUT); -+ qtd->urb = NULL; -+ } -+ dwc_otg_hcd_qtd_remove_and_free(qtd); -+ } -+ } -+} -+ -+/** -+ * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic -+ * and periodic schedules. The QTD associated with each URB is removed from -+ * the schedule and freed. This function may be called when a disconnect is -+ * detected or when the HCD is being stopped. -+ */ -+static void kill_all_urbs(struct dwc_otg_hcd *hcd) -+{ -+ kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_inactive); -+ kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_active); -+ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_inactive); -+ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_ready); -+ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_assigned); -+ kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_queued); -+} -+ -+/** -+ * HCD Callback function for disconnect of the HCD. -+ * -+ * @_p: void pointer to the <code>struct usb_hcd</code> -+ */ -+static int32_t dwc_otg_hcd_disconnect_cb(void *_p) -+{ -+ union gintsts_data intr; -+ struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_p); -+ -+ /* -+ * Set status flags for the hub driver. -+ */ -+ dwc_otg_hcd->flags.b.port_connect_status_change = 1; -+ dwc_otg_hcd->flags.b.port_connect_status = 0; -+ -+ /* -+ * Shutdown any transfers in process by clearing the Tx FIFO Empty -+ * interrupt mask and status bits and disabling subsequent host -+ * channel interrupts. -+ */ -+ intr.d32 = 0; -+ intr.b.nptxfempty = 1; -+ intr.b.ptxfempty = 1; -+ intr.b.hcintr = 1; -+ dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk, -+ intr.d32, 0); -+ dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintsts, -+ intr.d32, 0); -+ -+ del_timers(dwc_otg_hcd); -+ -+ /* -+ * Turn off the vbus power only if the core has transitioned to device -+ * mode. If still in host mode, need to keep power on to detect a -+ * reconnection. -+ */ -+ if (dwc_otg_is_device_mode(dwc_otg_hcd->core_if)) { -+ if (dwc_otg_hcd->core_if->op_state != A_SUSPEND) { -+ union hprt0_data hprt0 = {.d32 = 0 }; -+ DWC_PRINT("Disconnect: PortPower off\n"); -+ hprt0.b.prtpwr = 0; -+ dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, -+ hprt0.d32); -+ } -+ -+ dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if); -+ } -+ -+ /* Respond with an error status to all URBs in the schedule. */ -+ kill_all_urbs(dwc_otg_hcd); -+ -+ if (dwc_otg_is_host_mode(dwc_otg_hcd->core_if)) { -+ /* Clean up any host channels that were in use. */ -+ int num_channels; -+ int i; -+ struct dwc_hc *channel; -+ struct dwc_otg_hc_regs *hc_regs; -+ union hcchar_data hcchar; -+ -+ num_channels = dwc_otg_hcd->core_if->core_params->host_channels; -+ -+ if (!dwc_otg_hcd->core_if->dma_enable) { -+ /* Flush out any channel requests in slave mode. */ -+ for (i = 0; i < num_channels; i++) { -+ channel = dwc_otg_hcd->hc_ptr_array[i]; -+ if (list_empty(&channel->hc_list_entry)) { -+ hc_regs = -+ dwc_otg_hcd->core_if->host_if-> -+ hc_regs[i]; -+ hcchar.d32 = -+ dwc_read_reg32(&hc_regs->hcchar); -+ if (hcchar.b.chen) { -+ hcchar.b.chen = 0; -+ hcchar.b.chdis = 1; -+ hcchar.b.epdir = 0; -+ dwc_write_reg32(&hc_regs-> -+ hcchar, -+ hcchar.d32); -+ } -+ } -+ } -+ } -+ -+ for (i = 0; i < num_channels; i++) { -+ channel = dwc_otg_hcd->hc_ptr_array[i]; -+ if (list_empty(&channel->hc_list_entry)) { -+ hc_regs = -+ dwc_otg_hcd->core_if->host_if->hc_regs[i]; -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ if (hcchar.b.chen) { -+ /* Halt the channel. */ -+ hcchar.b.chdis = 1; -+ dwc_write_reg32(&hc_regs->hcchar, -+ hcchar.d32); -+ } -+ -+ dwc_otg_hc_cleanup(dwc_otg_hcd->core_if, -+ channel); -+ list_add_tail(&channel->hc_list_entry, -+ &dwc_otg_hcd->free_hc_list); -+ } -+ } -+ } -+ -+ /* A disconnect will end the session so the B-Device is no -+ * longer a B-host. */ -+ ((struct usb_hcd *)_p)->self.is_b_host = 0; -+ return 1; -+} -+ -+/** -+ * Connection timeout function. An OTG host is required to display a -+ * message if the device does not connect within 10 seconds. -+ */ -+void dwc_otg_hcd_connect_timeout(unsigned long _ptr) -+{ -+ DWC_DEBUGPL(DBG_HCDV, "%s(%x)\n", __func__, (int)_ptr); -+ DWC_PRINT("Connect Timeout\n"); -+ DWC_ERROR("Device Not Connected/Responding\n"); -+} -+ -+/** -+ * Start the connection timer. An OTG host is required to display a -+ * message if the device does not connect within 10 seconds. The -+ * timer is deleted if a port connect interrupt occurs before the -+ * timer expires. -+ */ -+static void dwc_otg_hcd_start_connect_timer(struct dwc_otg_hcd *hcd) -+{ -+ init_timer(&hcd->conn_timer); -+ hcd->conn_timer.function = dwc_otg_hcd_connect_timeout; -+ hcd->conn_timer.data = (unsigned long)0; -+ hcd->conn_timer.expires = jiffies + (HZ * 10); -+ add_timer(&hcd->conn_timer); -+} -+ -+/** -+ * HCD Callback function for disconnect of the HCD. -+ * -+ * @_p: void pointer to the <code>struct usb_hcd</code> -+ */ -+static int32_t dwc_otg_hcd_session_start_cb(void *_p) -+{ -+ struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_p); -+ DWC_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _p); -+ dwc_otg_hcd_start_connect_timer(dwc_otg_hcd); -+ return 1; -+} -+ -+/** -+ * HCD Callback structure for handling mode switching. -+ */ -+static struct dwc_otg_cil_callbacks hcd_cil_callbacks = { -+ .start = dwc_otg_hcd_start_cb, -+ .stop = dwc_otg_hcd_stop_cb, -+ .disconnect = dwc_otg_hcd_disconnect_cb, -+ .session_start = dwc_otg_hcd_session_start_cb, -+ .p = 0, -+}; -+ -+/** -+ * Reset tasklet function -+ */ -+static void reset_tasklet_func(unsigned long data) -+{ -+ struct dwc_otg_hcd *dwc_otg_hcd = (struct dwc_otg_hcd *)data; -+ struct dwc_otg_core_if *core_if = dwc_otg_hcd->core_if; -+ union hprt0_data hprt0; -+ -+ DWC_DEBUGPL(DBG_HCDV, "USB RESET tasklet called\n"); -+ -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ hprt0.b.prtrst = 1; -+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); -+ mdelay(60); -+ -+ hprt0.b.prtrst = 0; -+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); -+ dwc_otg_hcd->flags.b.port_reset_change = 1; -+ -+ return; -+} -+ -+static struct tasklet_struct reset_tasklet = { -+ .next = NULL, -+ .state = 0, -+ .count = ATOMIC_INIT(0), -+ .func = reset_tasklet_func, -+ .data = 0, -+}; -+ -+static enum hrtimer_restart delayed_enable(struct hrtimer *t) -+{ -+ struct dwc_otg_hcd *hcd = container_of(t, struct dwc_otg_hcd, -+ poll_rate_limit); -+ struct dwc_otg_core_global_regs *global_regs = -+ hcd->core_if->core_global_regs; -+ union gintmsk_data intr_mask = {.d32 = 0 }; -+ intr_mask.b.nptxfempty = 1; -+ dwc_modify_reg32(&global_regs->gintmsk, 0, intr_mask.d32); -+ -+ return HRTIMER_NORESTART; -+} -+ -+/** -+ * Initializes the HCD. This function allocates memory for and initializes the -+ * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the -+ * USB bus with the core and calls the hc_driver->start() function. It returns -+ * a negative error on failure. -+ */ -+int __devinit dwc_otg_hcd_init(struct device *dev) -+{ -+ struct usb_hcd *hcd = NULL; -+ struct dwc_otg_hcd *dwc_otg_hcd = NULL; -+ struct dwc_otg_device *otg_dev = dev->platform_data; -+ -+ int num_channels; -+ int i; -+ struct dwc_hc *channel; -+ -+ int retval = 0; -+ -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n"); -+ -+ /* Set device flags indicating whether the HCD supports DMA. */ -+ if (otg_dev->core_if->dma_enable) { -+ DWC_PRINT("Using DMA mode\n"); -+ dev->coherent_dma_mask = ~0; -+ dev->dma_mask = &dev->coherent_dma_mask; -+ } else { -+ DWC_PRINT("Using Slave mode\n"); -+ dev->coherent_dma_mask = 0; -+ dev->dma_mask = NULL; -+ } -+ -+ /* -+ * Allocate memory for the base HCD plus the DWC OTG HCD. -+ * Initialize the base HCD. -+ */ -+ hcd = usb_create_hcd(&dwc_otg_hc_driver, dev, dev_name(dev)); -+ if (hcd == NULL) { -+ retval = -ENOMEM; -+ goto error1; -+ } -+ hcd->regs = otg_dev->base; -+ hcd->self.otg_port = 1; -+ -+ /* Integrate TT in root hub, by default this is disbled. */ -+ hcd->has_tt = 1; -+ -+ /* Initialize the DWC OTG HCD. */ -+ dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); -+ -+ spin_lock_init(&dwc_otg_hcd->global_lock); -+ -+ dwc_otg_hcd->core_if = otg_dev->core_if; -+ otg_dev->hcd = dwc_otg_hcd; -+ -+ /* Register the HCD CIL Callbacks */ -+ dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if, -+ &hcd_cil_callbacks, hcd); -+ -+ /* Initialize the non-periodic schedule. */ -+ INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_inactive); -+ INIT_LIST_HEAD(&dwc_otg_hcd->non_periodic_sched_active); -+ -+ /* Initialize the periodic schedule. */ -+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_inactive); -+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_ready); -+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_assigned); -+ INIT_LIST_HEAD(&dwc_otg_hcd->periodic_sched_queued); -+ -+ /* -+ * Create a host channel descriptor for each host channel implemented -+ * in the controller. Initialize the channel descriptor array. -+ */ -+ INIT_LIST_HEAD(&dwc_otg_hcd->free_hc_list); -+ num_channels = dwc_otg_hcd->core_if->core_params->host_channels; -+ for (i = 0; i < num_channels; i++) { -+ channel = kmalloc(sizeof(struct dwc_hc), GFP_KERNEL); -+ if (channel == NULL) { -+ retval = -ENOMEM; -+ DWC_ERROR("%s: host channel allocation failed\n", -+ __func__); -+ goto error2; -+ } -+ memset(channel, 0, sizeof(struct dwc_hc)); -+ channel->hc_num = i; -+ dwc_otg_hcd->hc_ptr_array[i] = channel; -+#ifdef DEBUG -+ init_timer(&dwc_otg_hcd->core_if->hc_xfer_timer[i]); -+#endif -+ -+ DWC_DEBUGPL(DBG_HCDV, "HCD Added channel #%d, hc=%p\n", i, -+ channel); -+ } -+ -+ /* Initialize the Connection timeout timer. */ -+ init_timer(&dwc_otg_hcd->conn_timer); -+ -+ /* Initialize reset tasklet. */ -+ reset_tasklet.data = (unsigned long)dwc_otg_hcd; -+ dwc_otg_hcd->reset_tasklet = &reset_tasklet; -+ -+ hrtimer_init(&dwc_otg_hcd->poll_rate_limit, CLOCK_MONOTONIC, -+ HRTIMER_MODE_REL); -+ dwc_otg_hcd->poll_rate_limit.function = delayed_enable; -+ -+ /* -+ * Finish generic HCD initialization and start the HCD. This function -+ * allocates the DMA buffer pool, registers the USB bus, requests the -+ * IRQ line, and calls dwc_otg_hcd_start method. -+ */ -+ retval = -+ usb_add_hcd(hcd, platform_get_irq(to_platform_device(dev), 0), -+ IRQF_SHARED); -+ if (retval < 0) -+ goto error2; -+ -+ /* -+ * Allocate space for storing data on status transactions. Normally no -+ * data is sent, but this space acts as a bit bucket. This must be -+ * done after usb_add_hcd since that function allocates the DMA buffer -+ * pool. -+ */ -+ if (otg_dev->core_if->dma_enable) { -+ dwc_otg_hcd->status_buf = -+ dma_alloc_coherent(dev, -+ DWC_OTG_HCD_STATUS_BUF_SIZE, -+ &dwc_otg_hcd->status_buf_dma, -+ GFP_KERNEL | GFP_DMA); -+ } else { -+ dwc_otg_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE, -+ GFP_KERNEL); -+ } -+ if (dwc_otg_hcd->status_buf == NULL) { -+ retval = -ENOMEM; -+ DWC_ERROR("%s: status_buf allocation failed\n", __func__); -+ goto error3; -+ } -+ -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Initialized HCD, usbbus=%d\n", -+ hcd->self.busnum); -+ -+ return 0; -+ -+ /* Error conditions */ -+error3: -+ usb_remove_hcd(hcd); -+error2: -+ dwc_otg_hcd_free(hcd); -+ usb_put_hcd(hcd); -+error1: -+ return retval; -+} -+ -+/** -+ * Removes the HCD. -+ * Frees memory and resources associated with the HCD and deregisters the bus. -+ */ -+void dwc_otg_hcd_remove(struct device *dev) -+{ -+ struct dwc_otg_device *otg_dev = dev->platform_data; -+ struct dwc_otg_hcd *dwc_otg_hcd = otg_dev->hcd; -+ struct usb_hcd *hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd); -+ -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n"); -+ -+ /* Turn off all interrupts */ -+ dwc_write_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk, 0); -+ dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gahbcfg, 1, -+ 0); -+ -+ usb_remove_hcd(hcd); -+ dwc_otg_hcd_free(hcd); -+ usb_put_hcd(hcd); -+ -+ return; -+} -+ -+/* ========================================================================= -+ * Linux HC Driver Functions -+ * ========================================================================= */ -+ -+/** -+ * Initializes dynamic portions of the DWC_otg HCD state. -+ */ -+static void hcd_reinit(struct dwc_otg_hcd *hcd) -+{ -+ struct list_head *item; -+ int num_channels; -+ int i; -+ struct dwc_hc *channel; -+ -+ hcd->flags.d32 = 0; -+ -+ hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active; -+ hcd->non_periodic_channels = 0; -+ hcd->periodic_channels = 0; -+ -+ /* -+ * Put all channels in the free channel list and clean up channel -+ * states. -+ */ -+ item = hcd->free_hc_list.next; -+ while (item != &hcd->free_hc_list) { -+ list_del(item); -+ item = hcd->free_hc_list.next; -+ } -+ num_channels = hcd->core_if->core_params->host_channels; -+ for (i = 0; i < num_channels; i++) { -+ channel = hcd->hc_ptr_array[i]; -+ list_add_tail(&channel->hc_list_entry, &hcd->free_hc_list); -+ dwc_otg_hc_cleanup(hcd->core_if, channel); -+ } -+ -+ /* Initialize the DWC core for host mode operation. */ -+ dwc_otg_core_host_init(hcd->core_if); -+} -+ -+/** Initializes the DWC_otg controller and its root hub and prepares it for host -+ * mode operation. Activates the root port. Returns 0 on success and a negative -+ * error code on failure. */ -+int dwc_otg_hcd_start(struct usb_hcd *hcd) -+{ -+ struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); -+ struct dwc_otg_core_if *core_if = dwc_otg_hcd->core_if; -+ unsigned long flags; -+ -+ struct usb_bus *bus; -+ -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n"); -+ -+ spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); -+ -+ bus = hcd_to_bus(hcd); -+ -+ /* Initialize the bus state. If the core is in Device Mode -+ * HALT the USB bus and return. */ -+ if (dwc_otg_is_device_mode(core_if)) { -+ hcd->state = HC_STATE_HALT; -+ goto out; -+ } -+ hcd->state = HC_STATE_RUNNING; -+ -+ hcd_reinit(dwc_otg_hcd); -+out: -+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); -+ -+ return 0; -+} -+ -+static void qh_list_free(struct dwc_otg_hcd *hcd, struct list_head *_qh_list) -+{ -+ struct list_head *item; -+ struct dwc_otg_qh *qh; -+ -+ if (_qh_list->next == NULL) { -+ /* The list hasn't been initialized yet. */ -+ return; -+ } -+ -+ /* Ensure there are no QTDs or URBs left. */ -+ kill_urbs_in_qh_list(hcd, _qh_list); -+ -+ for (item = _qh_list->next; item != _qh_list; item = _qh_list->next) { -+ qh = list_entry(item, struct dwc_otg_qh, qh_list_entry); -+ dwc_otg_hcd_qh_remove_and_free(hcd, qh); -+ } -+} -+ -+/** -+ * Halts the DWC_otg host mode operations in a clean manner. USB transfers are -+ * stopped. -+ */ -+void dwc_otg_hcd_stop(struct usb_hcd *hcd) -+{ -+ struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); -+ union hprt0_data hprt0 = {.d32 = 0 }; -+ -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n"); -+ -+ /* Turn off all host-specific interrupts. */ -+ dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if); -+ -+ /* -+ * The root hub should be disconnected before this function is called. -+ * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue) -+ * and the QH lists (via ..._hcd_endpoint_disable). -+ */ -+ -+ /* Turn off the vbus power */ -+ DWC_PRINT("PortPower off\n"); -+ hprt0.b.prtpwr = 0; -+ dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, hprt0.d32); -+ -+ return; -+} -+ -+/** Returns the current frame number. */ -+int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd) -+{ -+ struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); -+ union hfnum_data hfnum; -+ -+ hfnum.d32 = -+ dwc_read_reg32(&dwc_otg_hcd->core_if->host_if->host_global_regs-> -+ hfnum); -+ -+#ifdef DEBUG_SOF -+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD GET FRAME NUMBER %d\n", -+ hfnum.b.frnum); -+#endif -+ return hfnum.b.frnum; -+} -+ -+/** -+ * Frees secondary storage associated with the dwc_otg_hcd structure contained -+ * in the struct usb_hcd field. -+ */ -+void dwc_otg_hcd_free(struct usb_hcd *hcd) -+{ -+ struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); -+ int i; -+ -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD FREE\n"); -+ -+ del_timers(dwc_otg_hcd); -+ -+ /* Free memory for QH/QTD lists */ -+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_inactive); -+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->non_periodic_sched_active); -+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_inactive); -+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_ready); -+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_assigned); -+ qh_list_free(dwc_otg_hcd, &dwc_otg_hcd->periodic_sched_queued); -+ -+ /* Free memory for the host channels. */ -+ for (i = 0; i < MAX_EPS_CHANNELS; i++) { -+ struct dwc_hc *hc = dwc_otg_hcd->hc_ptr_array[i]; -+ if (hc != NULL) { -+ DWC_DEBUGPL(DBG_HCDV, "HCD Free channel #%i, hc=%p\n", -+ i, hc); -+ kfree(hc); -+ } -+ } -+ -+ if (dwc_otg_hcd->core_if->dma_enable) { -+ if (dwc_otg_hcd->status_buf_dma) { -+ dma_free_coherent(hcd->self.controller, -+ DWC_OTG_HCD_STATUS_BUF_SIZE, -+ dwc_otg_hcd->status_buf, -+ dwc_otg_hcd->status_buf_dma); -+ } -+ } else if (dwc_otg_hcd->status_buf != NULL) { -+ kfree(dwc_otg_hcd->status_buf); -+ } -+ -+ return; -+} -+ -+#ifdef DEBUG -+static void dump_urb_info(struct urb *urb, char *_fn_name) -+{ -+ DWC_PRINT("%s, urb %p\n", _fn_name, urb); -+ DWC_PRINT(" Device address: %d\n", usb_pipedevice(urb->pipe)); -+ DWC_PRINT(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe), -+ (usb_pipein(urb->pipe) ? "IN" : "OUT")); -+ DWC_PRINT(" Endpoint type: %s\n", -+ ({ -+ char *pipetype; -+ switch (usb_pipetype(urb->pipe)) { -+ case PIPE_CONTROL: -+ pipetype = "CONTROL"; -+ break; -+ case PIPE_BULK: -+ pipetype = "BULK"; -+ break; -+ case PIPE_INTERRUPT: -+ pipetype = "INTERRUPT"; -+ break; -+ case PIPE_ISOCHRONOUS: -+ pipetype = "ISOCHRONOUS"; -+ break; -+ default: -+ pipetype = "UNKNOWN"; -+ break; -+ } -+ pipetype; -+ })) ; -+ DWC_PRINT(" Speed: %s\n", -+ ({ -+ char *speed; -+ switch (urb->dev->speed) { -+ case USB_SPEED_HIGH: -+ speed = "HIGH"; -+ break; -+ case USB_SPEED_FULL: -+ speed = "FULL"; -+ break; -+ case USB_SPEED_LOW: -+ speed = "LOW"; -+ break; -+ default: -+ speed = "UNKNOWN"; -+ break; -+ } -+ speed; -+ })); -+ DWC_PRINT(" Max packet size: %d\n", -+ usb_maxpacket(urb->dev, urb->pipe, -+ usb_pipeout(urb->pipe))); -+ DWC_PRINT(" Data buffer length: %d\n", urb->transfer_buffer_length); -+ DWC_PRINT(" Transfer buffer: %p, Transfer DMA: %p\n", -+ urb->transfer_buffer, (void *)urb->transfer_dma); -+ DWC_PRINT(" Setup buffer: %p, Setup DMA: %p\n", -+ urb->setup_packet, (void *)urb->setup_dma); -+ DWC_PRINT(" Interval: %d\n", urb->interval); -+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { -+ int i; -+ for (i = 0; i < urb->number_of_packets; i++) { -+ DWC_PRINT(" ISO Desc %d:\n", i); -+ DWC_PRINT(" offset: %d, length %d\n", -+ urb->iso_frame_desc[i].offset, -+ urb->iso_frame_desc[i].length); -+ } -+ } -+} -+ -+static void dump_channel_info(struct dwc_otg_hcd *hcd, struct dwc_otg_qh * qh) -+{ -+ if (qh->channel != NULL) { -+ struct dwc_hc *hc = qh->channel; -+ struct list_head *item; -+ struct dwc_otg_qh *qh_item; -+ int num_channels = hcd->core_if->core_params->host_channels; -+ int i; -+ -+ struct dwc_otg_hc_regs *hc_regs; -+ union hcchar_data hcchar; -+ union hcsplt_data hcsplt; -+ union hctsiz_data hctsiz; -+ uint32_t hcdma; -+ -+ hc_regs = hcd->core_if->host_if->hc_regs[hc->hc_num]; -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt); -+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz); -+ hcdma = dwc_read_reg32(&hc_regs->hcdma); -+ -+ DWC_PRINT(" Assigned to channel %p:\n", hc); -+ DWC_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, -+ hcsplt.d32); -+ DWC_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, -+ hcdma); -+ DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n", -+ hc->dev_addr, hc->ep_num, hc->ep_is_in); -+ DWC_PRINT(" ep_type: %d\n", hc->ep_type); -+ DWC_PRINT(" max_packet: %d\n", hc->max_packet); -+ DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start); -+ DWC_PRINT(" xfer_started: %d\n", hc->xfer_started); -+ DWC_PRINT(" halt_status: %d\n", hc->halt_status); -+ DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff); -+ DWC_PRINT(" xfer_len: %d\n", hc->xfer_len); -+ DWC_PRINT(" qh: %p\n", hc->qh); -+ DWC_PRINT(" NP inactive sched:\n"); -+ list_for_each(item, &hcd->non_periodic_sched_inactive) { -+ qh_item = list_entry(item, struct dwc_otg_qh, -+ qh_list_entry); -+ DWC_PRINT(" %p\n", qh_item); -+ } -+ DWC_PRINT(" NP active sched:\n"); -+ list_for_each(item, &hcd->non_periodic_sched_active) { -+ qh_item = list_entry(item, struct dwc_otg_qh, -+ qh_list_entry); -+ DWC_PRINT(" %p\n", qh_item); -+ } -+ DWC_PRINT(" Channels: \n"); -+ for (i = 0; i < num_channels; i++) { -+ struct dwc_hc *hc = hcd->hc_ptr_array[i]; -+ DWC_PRINT(" %2d: %p\n", i, hc); -+ } -+ } -+} -+#endif -+ -+/* Starts processing a USB transfer request specified by a USB Request Block -+ * (URB). mem_flags indicates the type of memory allocation to use while -+ * processing this URB. */ -+int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd, -+ struct urb *urb, unsigned _mem_flags) -+{ -+ unsigned long flags; -+ int retval = 0; -+ struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); -+ struct dwc_otg_qtd *qtd; -+ -+ spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); -+ -+ /* -+ * Make sure the start of frame interrupt is enabled now that -+ * we know we should have queued data. The SOF interrupt -+ * handler automatically disables itself when idle to reduce -+ * the number of interrupts. See dwc_otg_hcd_handle_sof_intr() -+ * for the disable -+ */ -+ dwc_modify_reg32(&dwc_otg_hcd->core_if->core_global_regs->gintmsk, 0, -+ DWC_SOF_INTR_MASK); -+ -+#ifdef DEBUG -+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) -+ dump_urb_info(urb, "dwc_otg_hcd_urb_enqueue"); -+#endif -+ if (!dwc_otg_hcd->flags.b.port_connect_status) { -+ /* No longer connected. */ -+ retval = -ENODEV; -+ goto out; -+ } -+ -+ qtd = dwc_otg_hcd_qtd_create(urb); -+ if (qtd == NULL) { -+ DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n"); -+ retval = -ENOMEM; -+ goto out; -+ } -+ -+ retval = dwc_otg_hcd_qtd_add(qtd, dwc_otg_hcd); -+ if (retval < 0) { -+ DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. " -+ "Error status %d\n", retval); -+ dwc_otg_hcd_qtd_free(qtd); -+ } -+out: -+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); -+ -+ return retval; -+} -+ -+/** Aborts/cancels a USB transfer request. Always returns 0 to indicate -+ * success. */ -+int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) -+{ -+ unsigned long flags; -+ struct dwc_otg_hcd *dwc_otg_hcd; -+ struct dwc_otg_qtd *urb_qtd; -+ -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n"); -+ -+ dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); -+ -+ spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); -+ -+ urb_qtd = urb->hcpriv; -+ -+#ifdef DEBUG -+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) { -+ dump_urb_info(urb, "dwc_otg_hcd_urb_dequeue"); -+ if (urb_qtd == urb_qtd->qh->qtd_in_process) -+ dump_channel_info(dwc_otg_hcd, urb_qtd->qh); -+ } -+#endif -+ -+ if (urb_qtd == urb_qtd->qh->qtd_in_process) { -+ /* The QTD is in process (it has been assigned to a channel). */ -+ -+ if (dwc_otg_hcd->flags.b.port_connect_status) { -+ /* -+ * If still connected (i.e. in host mode), halt the -+ * channel so it can be used for other transfers. If -+ * no longer connected, the host registers can't be -+ * written to halt the channel since the core is in -+ * device mode. -+ */ -+ dwc_otg_hc_halt(dwc_otg_hcd->core_if, -+ urb_qtd->qh->channel, -+ DWC_OTG_HC_XFER_URB_DEQUEUE); -+ } -+ } -+ -+ /* -+ * Free the QTD and clean up the associated QH. Leave the QH in the -+ * schedule if it has any remaining QTDs. -+ */ -+ dwc_otg_hcd_qtd_remove_and_free(urb_qtd); -+ if (urb_qtd == urb_qtd->qh->qtd_in_process) { -+ dwc_otg_hcd_qh_deactivate(dwc_otg_hcd, urb_qtd->qh, 0); -+ urb_qtd->qh->channel = NULL; -+ urb_qtd->qh->qtd_in_process = NULL; -+ } else if (list_empty(&urb_qtd->qh->qtd_list)) { -+ dwc_otg_hcd_qh_remove(dwc_otg_hcd, urb_qtd->qh); -+ } -+ -+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); -+ -+ urb->hcpriv = NULL; -+ -+ /* Higher layer software sets URB status. */ -+ usb_hcd_giveback_urb(hcd, urb, status); -+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) { -+ DWC_PRINT("Called usb_hcd_giveback_urb()\n"); -+ DWC_PRINT(" urb->status = %d\n", urb->status); -+ } -+ -+ return 0; -+} -+ -+/* Frees resources in the DWC_otg controller related to a given endpoint. Also -+ * clears state in the HCD related to the endpoint. Any URBs for the endpoint -+ * must already be dequeued. */ -+void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd, -+ struct usb_host_endpoint *_ep) -+{ -+ unsigned long flags; -+ struct dwc_otg_qh *qh; -+ struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); -+ -+ spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); -+ -+ DWC_DEBUGPL(DBG_HCD, -+ "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, " -+ "endpoint=%d\n", _ep->desc.bEndpointAddress, -+ dwc_ep_addr_to_endpoint(_ep->desc.bEndpointAddress)); -+ -+ qh = _ep->hcpriv; -+ if (qh != NULL) { -+#if 1 -+ /* -+ * FIXME: Kludge to not crash on Octeon in SMP -+ * mode. Normally dwc_otg_hcd_qh_remove_and_free() is -+ * called even if the list isn't empty. This causes a -+ * crash on SMP, so we don't call it now. It works -+ * better, but probably does evil things I don't know -+ * about. -+ */ -+ /* Check that the QTD list is really empty */ -+ if (!list_empty(&qh->qtd_list)) { -+ pr_err("DWC OTG HCD EP DISABLE:" -+ " QTD List for this endpoint is not empty\n"); -+ } else -+#endif -+ { -+ dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd, qh); -+ _ep->hcpriv = NULL; -+ } -+ } -+ -+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); -+ -+ return; -+} -+ -+/* Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if -+ * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid -+ * interrupt. -+ * -+ * This function is called by the USB core when an interrupt occurs */ -+irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd) -+{ -+ irqreturn_t result; -+ unsigned long flags; -+ struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); -+ -+ spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); -+ -+ result = IRQ_RETVAL(dwc_otg_hcd_handle_intr(dwc_otg_hcd)); -+ -+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); -+ -+ return result; -+} -+ -+/** Creates Status Change bitmap for the root hub and root port. The bitmap is -+ * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1 -+ * is the status change indicator for the single root port. Returns 1 if either -+ * change indicator is 1, otherwise returns 0. */ -+int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd, char *_buf) -+{ -+ struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); -+ -+ _buf[0] = 0; -+ _buf[0] |= (dwc_otg_hcd->flags.b.port_connect_status_change || -+ dwc_otg_hcd->flags.b.port_reset_change || -+ dwc_otg_hcd->flags.b.port_enable_change || -+ dwc_otg_hcd->flags.b.port_suspend_change || -+ dwc_otg_hcd->flags.b.port_over_current_change) << 1; -+ -+#ifdef DEBUG -+ if (_buf[0]) { -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB STATUS DATA:" -+ " Root port status changed\n"); -+ DWC_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n", -+ dwc_otg_hcd->flags.b.port_connect_status_change); -+ DWC_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n", -+ dwc_otg_hcd->flags.b.port_reset_change); -+ DWC_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n", -+ dwc_otg_hcd->flags.b.port_enable_change); -+ DWC_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n", -+ dwc_otg_hcd->flags.b.port_suspend_change); -+ DWC_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n", -+ dwc_otg_hcd->flags.b.port_over_current_change); -+ } -+#endif -+ return (_buf[0] != 0); -+} -+ -+#ifdef DWC_HS_ELECT_TST -+/* -+ * Quick and dirty hack to implement the HS Electrical Test -+ * SINGLE_STEP_GET_DEVICE_DESCRIPTOR feature. -+ * -+ * This code was copied from our userspace app "hset". It sends a -+ * Get Device Descriptor control sequence in two parts, first the -+ * Setup packet by itself, followed some time later by the In and -+ * Ack packets. Rather than trying to figure out how to add this -+ * functionality to the normal driver code, we just hijack the -+ * hardware, using these two function to drive the hardware -+ * directly. -+ */ -+ -+struct dwc_otg_core_global_regs *global_regs; -+struct dwc_otg_host_global_regs *hc_global_regs; -+struct dwc_otg_hc_regs *hc_regs; -+uint32_t *data_fifo; -+ -+static void do_setup(void) -+{ -+ union gintsts_data gintsts; -+ union hctsiz_data hctsiz; -+ union hcchar_data hcchar; -+ union haint_data haint; -+ union hcint_data hcint; -+ -+ /* Enable HAINTs */ -+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001); -+ -+ /* Enable HCINTs */ -+ dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* Read HAINT */ -+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); -+ -+ /* Read HCINT */ -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ -+ /* Clear HCINT */ -+ dwc_write_reg32(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ dwc_write_reg32(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* -+ * Send Setup packet (Get Device Descriptor) -+ */ -+ -+ /* Make sure channel is disabled */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ if (hcchar.b.chen) { -+ hcchar.b.chdis = 1; -+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); -+ -+ mdelay(1000); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* Read HAINT */ -+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); -+ -+ /* Read HCINT */ -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ -+ /* Clear HCINT */ -+ dwc_write_reg32(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ dwc_write_reg32(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); -+ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ } -+ -+ /* Set HCTSIZ */ -+ hctsiz.d32 = 0; -+ hctsiz.b.xfersize = 8; -+ hctsiz.b.pktcnt = 1; -+ hctsiz.b.pid = DWC_OTG_HC_PID_SETUP; -+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32); -+ -+ /* Set HCCHAR */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL; -+ hcchar.b.epdir = 0; -+ hcchar.b.epnum = 0; -+ hcchar.b.mps = 8; -+ hcchar.b.chen = 1; -+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); -+ -+ /* Fill FIFO with Setup data for Get Device Descriptor */ -+ data_fifo = (uint32_t *) ((char *)global_regs + 0x1000); -+ dwc_write_reg32(data_fifo++, 0x01000680); -+ dwc_write_reg32(data_fifo++, 0x00080000); -+ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* Wait for host channel interrupt */ -+ do { -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ } while (gintsts.b.hcintr == 0); -+ -+ -+ /* Disable HCINTs */ -+ dwc_write_reg32(&hc_regs->hcintmsk, 0x0000); -+ -+ /* Disable HAINTs */ -+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000); -+ -+ /* Read HAINT */ -+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); -+ -+ /* Read HCINT */ -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ -+ /* Clear HCINT */ -+ dwc_write_reg32(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ dwc_write_reg32(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+} -+ -+static void do_in_ack(void) -+{ -+ union gintsts_data gintsts; -+ union hctsiz_data hctsiz; -+ union hcchar_data hcchar; -+ union haint_data haint; -+ union hcint_data hcint; -+ union host_grxsts_data grxsts; -+ -+ /* Enable HAINTs */ -+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0001); -+ -+ /* Enable HCINTs */ -+ dwc_write_reg32(&hc_regs->hcintmsk, 0x04a3); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* Read HAINT */ -+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); -+ -+ /* Read HCINT */ -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ -+ /* Clear HCINT */ -+ dwc_write_reg32(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ dwc_write_reg32(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* -+ * Receive Control In packet -+ */ -+ -+ /* Make sure channel is disabled */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ if (hcchar.b.chen) { -+ hcchar.b.chdis = 1; -+ hcchar.b.chen = 1; -+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); -+ -+ mdelay(1000); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* Read HAINT */ -+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); -+ -+ /* Read HCINT */ -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ -+ /* Clear HCINT */ -+ dwc_write_reg32(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ dwc_write_reg32(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); -+ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ } -+ -+ /* Set HCTSIZ */ -+ hctsiz.d32 = 0; -+ hctsiz.b.xfersize = 8; -+ hctsiz.b.pktcnt = 1; -+ hctsiz.b.pid = DWC_OTG_HC_PID_DATA1; -+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32); -+ -+ /* Set HCCHAR */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL; -+ hcchar.b.epdir = 1; -+ hcchar.b.epnum = 0; -+ hcchar.b.mps = 8; -+ hcchar.b.chen = 1; -+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); -+ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* Wait for receive status queue interrupt */ -+ do { -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ } while (gintsts.b.rxstsqlvl == 0); -+ -+ /* Read RXSTS */ -+ grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp); -+ -+ /* Clear RXSTSQLVL in GINTSTS */ -+ gintsts.d32 = 0; -+ gintsts.b.rxstsqlvl = 1; -+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); -+ -+ switch (grxsts.b.pktsts) { -+ case DWC_GRXSTS_PKTSTS_IN: -+ /* Read the data into the host buffer */ -+ if (grxsts.b.bcnt > 0) { -+ int i; -+ int word_count = (grxsts.b.bcnt + 3) / 4; -+ -+ data_fifo = (uint32_t *) ((char *)global_regs + 0x1000); -+ -+ for (i = 0; i < word_count; i++) -+ (void)dwc_read_reg32(data_fifo++); -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* Wait for receive status queue interrupt */ -+ do { -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ } while (gintsts.b.rxstsqlvl == 0); -+ -+ -+ /* Read RXSTS */ -+ grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp); -+ -+ /* Clear RXSTSQLVL in GINTSTS */ -+ gintsts.d32 = 0; -+ gintsts.b.rxstsqlvl = 1; -+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); -+ -+ switch (grxsts.b.pktsts) { -+ case DWC_GRXSTS_PKTSTS_IN_XFER_COMP: -+ break; -+ -+ default: -+ break; -+ } -+ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* Wait for host channel interrupt */ -+ do { -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ } while (gintsts.b.hcintr == 0); -+ -+ -+ /* Read HAINT */ -+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); -+ -+ /* Read HCINT */ -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ -+ /* Clear HCINT */ -+ dwc_write_reg32(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ dwc_write_reg32(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ mdelay(1); -+ -+ /* -+ * Send handshake packet -+ */ -+ -+ /* Read HAINT */ -+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); -+ -+ /* Read HCINT */ -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ -+ /* Clear HCINT */ -+ dwc_write_reg32(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ dwc_write_reg32(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* Make sure channel is disabled */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ if (hcchar.b.chen) { -+ hcchar.b.chdis = 1; -+ hcchar.b.chen = 1; -+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); -+ -+ mdelay(1000); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* Read HAINT */ -+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); -+ -+ /* Read HCINT */ -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ -+ /* Clear HCINT */ -+ dwc_write_reg32(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ dwc_write_reg32(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); -+ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ } -+ -+ /* Set HCTSIZ */ -+ hctsiz.d32 = 0; -+ hctsiz.b.xfersize = 0; -+ hctsiz.b.pktcnt = 1; -+ hctsiz.b.pid = DWC_OTG_HC_PID_DATA1; -+ dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32); -+ -+ /* Set HCCHAR */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL; -+ hcchar.b.epdir = 0; -+ hcchar.b.epnum = 0; -+ hcchar.b.mps = 8; -+ hcchar.b.chen = 1; -+ dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); -+ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ -+ /* Wait for host channel interrupt */ -+ do { -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+ } while (gintsts.b.hcintr == 0); -+ -+ -+ /* Disable HCINTs */ -+ dwc_write_reg32(&hc_regs->hcintmsk, 0x0000); -+ -+ /* Disable HAINTs */ -+ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000); -+ -+ /* Read HAINT */ -+ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); -+ -+ /* Read HCINT */ -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ -+ /* Read HCCHAR */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ -+ /* Clear HCINT */ -+ dwc_write_reg32(&hc_regs->hcint, hcint.d32); -+ -+ /* Clear HAINT */ -+ dwc_write_reg32(&hc_global_regs->haint, haint.d32); -+ -+ /* Clear GINTSTS */ -+ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); -+ -+ /* Read GINTSTS */ -+ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); -+} -+#endif /* DWC_HS_ELECT_TST */ -+ -+/* Handles hub class-specific requests.*/ -+int dwc_otg_hcd_hub_control(struct usb_hcd *hcd, -+ u16 _typeReq, -+ u16 _wValue, u16 _wIndex, char *_buf, u16 _wLength) -+{ -+ int retval = 0; -+ unsigned long flags; -+ -+ struct dwc_otg_hcd *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); -+ struct dwc_otg_core_if *core_if = hcd_to_dwc_otg_hcd(hcd)->core_if; -+ struct usb_hub_descriptor *desc; -+ union hprt0_data hprt0 = {.d32 = 0 }; -+ -+ uint32_t port_status; -+#ifdef DWC_HS_ELECT_TST -+ uint32_t t; -+ union gintmsk_data gintmsk; -+#endif -+ spin_lock_irqsave(&dwc_otg_hcd->global_lock, flags); -+ -+ switch (_typeReq) { -+ case ClearHubFeature: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "ClearHubFeature 0x%x\n", _wValue); -+ switch (_wValue) { -+ case C_HUB_LOCAL_POWER: -+ case C_HUB_OVER_CURRENT: -+ /* Nothing required here */ -+ break; -+ default: -+ retval = -EINVAL; -+ DWC_ERROR("DWC OTG HCD - " -+ "ClearHubFeature request %xh unknown\n", -+ _wValue); -+ } -+ break; -+ case ClearPortFeature: -+ if (!_wIndex || _wIndex > 1) -+ goto error; -+ -+ switch (_wValue) { -+ case USB_PORT_FEAT_ENABLE: -+ DWC_DEBUGPL(DBG_ANY, "DWC OTG HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_ENABLE\n"); -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ hprt0.b.prtena = 1; -+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); -+ break; -+ case USB_PORT_FEAT_SUSPEND: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ hprt0.b.prtres = 1; -+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); -+ /* Clear Resume bit */ -+ mdelay(100); -+ hprt0.b.prtres = 0; -+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); -+ break; -+ case USB_PORT_FEAT_POWER: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_POWER\n"); -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ hprt0.b.prtpwr = 0; -+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); -+ break; -+ case USB_PORT_FEAT_INDICATOR: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_INDICATOR\n"); -+ /* Port inidicator not supported */ -+ break; -+ case USB_PORT_FEAT_C_CONNECTION: -+ /* Clears drivers internal connect status change -+ * flag */ -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n"); -+ dwc_otg_hcd->flags.b.port_connect_status_change = 0; -+ break; -+ case USB_PORT_FEAT_C_RESET: -+ /* Clears the driver's internal Port Reset Change -+ * flag */ -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_C_RESET\n"); -+ dwc_otg_hcd->flags.b.port_reset_change = 0; -+ break; -+ case USB_PORT_FEAT_C_ENABLE: -+ /* Clears the driver's internal Port -+ * Enable/Disable Change flag */ -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n"); -+ dwc_otg_hcd->flags.b.port_enable_change = 0; -+ break; -+ case USB_PORT_FEAT_C_SUSPEND: -+ /* Clears the driver's internal Port Suspend -+ * Change flag, which is set when resume signaling on -+ * the host port is complete */ -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n"); -+ dwc_otg_hcd->flags.b.port_suspend_change = 0; -+ break; -+ case USB_PORT_FEAT_C_OVER_CURRENT: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n"); -+ dwc_otg_hcd->flags.b.port_over_current_change = 0; -+ break; -+ default: -+ retval = -EINVAL; -+ DWC_ERROR("DWC OTG HCD - " -+ "ClearPortFeature request %xh " -+ "unknown or unsupported\n", _wValue); -+ } -+ break; -+ case GetHubDescriptor: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "GetHubDescriptor\n"); -+ desc = (struct usb_hub_descriptor *)_buf; -+ desc->bDescLength = 9; -+ desc->bDescriptorType = 0x29; -+ desc->bNbrPorts = 1; -+ desc->wHubCharacteristics = 0x08; -+ desc->bPwrOn2PwrGood = 1; -+ desc->bHubContrCurrent = 0; -+ desc->bitmap[0] = 0; -+ desc->bitmap[1] = 0xff; -+ break; -+ case GetHubStatus: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "GetHubStatus\n"); -+ memset(_buf, 0, 4); -+ break; -+ case GetPortStatus: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "GetPortStatus\n"); -+ -+ if (!_wIndex || _wIndex > 1) -+ goto error; -+ -+ port_status = 0; -+ -+ if (dwc_otg_hcd->flags.b.port_connect_status_change) -+ port_status |= (1 << USB_PORT_FEAT_C_CONNECTION); -+ -+ if (dwc_otg_hcd->flags.b.port_enable_change) -+ port_status |= (1 << USB_PORT_FEAT_C_ENABLE); -+ -+ if (dwc_otg_hcd->flags.b.port_suspend_change) -+ port_status |= (1 << USB_PORT_FEAT_C_SUSPEND); -+ -+ if (dwc_otg_hcd->flags.b.port_reset_change) -+ port_status |= (1 << USB_PORT_FEAT_C_RESET); -+ -+ if (dwc_otg_hcd->flags.b.port_over_current_change) { -+ DWC_ERROR("Device Not Supported\n"); -+ port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT); -+ } -+ -+ if (!dwc_otg_hcd->flags.b.port_connect_status) { -+ /* -+ * The port is disconnected, which means the core is -+ * either in device mode or it soon will be. Just -+ * return 0's for the remainder of the port status -+ * since the port register can't be read if the core -+ * is in device mode. -+ */ -+ *((__le32 *) _buf) = cpu_to_le32(port_status); -+ break; -+ } -+ -+ hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0); -+ DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32); -+ -+ if (hprt0.b.prtconnsts) -+ port_status |= (1 << USB_PORT_FEAT_CONNECTION); -+ -+ if (hprt0.b.prtena) -+ port_status |= (1 << USB_PORT_FEAT_ENABLE); -+ -+ if (hprt0.b.prtsusp) -+ port_status |= (1 << USB_PORT_FEAT_SUSPEND); -+ -+ if (hprt0.b.prtovrcurract) -+ port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT); -+ -+ if (hprt0.b.prtrst) -+ port_status |= (1 << USB_PORT_FEAT_RESET); -+ -+ if (hprt0.b.prtpwr) -+ port_status |= (1 << USB_PORT_FEAT_POWER); -+ -+ if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) -+ port_status |= (1 << USB_PORT_FEAT_HIGHSPEED); -+ else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED) -+ port_status |= (1 << USB_PORT_FEAT_LOWSPEED); -+ -+ if (hprt0.b.prttstctl) -+ port_status |= (1 << USB_PORT_FEAT_TEST); -+ -+ /* USB_PORT_FEAT_INDICATOR unsupported always 0 */ -+ -+ *((__le32 *) _buf) = cpu_to_le32(port_status); -+ -+ break; -+ case SetHubFeature: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "SetHubFeature\n"); -+ /* No HUB features supported */ -+ break; -+ case SetPortFeature: -+ if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1)) -+ goto error; -+ -+ if (!dwc_otg_hcd->flags.b.port_connect_status) { -+ /* -+ * The port is disconnected, which means the core is -+ * either in device mode or it soon will be. Just -+ * return without doing anything since the port -+ * register can't be written if the core is in device -+ * mode. -+ */ -+ break; -+ } -+ -+ switch (_wValue) { -+ case USB_PORT_FEAT_SUSPEND: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "SetPortFeature - USB_PORT_FEAT_SUSPEND\n"); -+ if (hcd->self.otg_port == _wIndex && -+ hcd->self.b_hnp_enable) { -+ union gotgctl_data gotgctl = {.d32 = 0 }; -+ gotgctl.b.hstsethnpen = 1; -+ dwc_modify_reg32(&core_if->core_global_regs-> -+ gotgctl, 0, gotgctl.d32); -+ core_if->op_state = A_SUSPEND; -+ } -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ hprt0.b.prtsusp = 1; -+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); -+ /* Suspend the Phy Clock */ -+ { -+ union pcgcctl_data pcgcctl = {.d32 = 0 }; -+ pcgcctl.b.stoppclk = 1; -+ dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32); -+ } -+ -+ /* -+ * For HNP the bus must be suspended for at -+ * least 200ms. -+ */ -+ if (hcd->self.b_hnp_enable) -+ mdelay(200); -+ break; -+ case USB_PORT_FEAT_POWER: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "SetPortFeature - USB_PORT_FEAT_POWER\n"); -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ hprt0.b.prtpwr = 1; -+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); -+ break; -+ case USB_PORT_FEAT_RESET: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "SetPortFeature - USB_PORT_FEAT_RESET\n"); -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ /* When B-Host the Port reset bit is set in -+ * the Start HCD Callback function, so that -+ * the reset is started within 1ms of the HNP -+ * success interrupt. */ -+ if (!hcd->self.is_b_host) { -+ hprt0.b.prtrst = 1; -+ dwc_write_reg32(core_if->host_if->hprt0, -+ hprt0.d32); -+ } -+ /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */ -+ mdelay(60); -+ hprt0.b.prtrst = 0; -+ dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); -+ break; -+ -+#ifdef DWC_HS_ELECT_TST -+ case USB_PORT_FEAT_TEST: -+ t = (_wIndex >> 8); /* MSB wIndex USB */ -+ DWC_DEBUGPL(DBG_HCD, -+ "DWC OTG HCD HUB CONTROL - " -+ "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t); -+ warn("USB_PORT_FEAT_TEST %d\n", t); -+ if (t < 6) { -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ hprt0.b.prttstctl = t; -+ dwc_write_reg32(core_if->host_if->hprt0, -+ hprt0.d32); -+ } else { -+ /* Setup global vars with reg -+ * addresses (quick and dirty hack, -+ * should be cleaned up) -+ */ -+ global_regs = core_if->core_global_regs; -+ hc_global_regs = -+ core_if->host_if->host_global_regs; -+ hc_regs = -+ (struct dwc_otg_hc_regs *) ((char *) -+ global_regs + -+ 0x500); -+ data_fifo = -+ (uint32_t *) ((char *)global_regs + -+ 0x1000); -+ -+ if (t == 6) { /* HS_HOST_PORT_SUSPEND_RESUME */ -+ /* Save current interrupt mask */ -+ gintmsk.d32 = -+ dwc_read_reg32(&global_regs->gintmsk); -+ -+ /* Disable all interrupts -+ * while we muck with the -+ * hardware directly -+ */ -+ dwc_write_reg32(&global_regs->gintmsk, -+ 0); -+ -+ /* 15 second delay per the test spec */ -+ mdelay(15000); -+ -+ /* Drive suspend on the root port */ -+ hprt0.d32 = -+ dwc_otg_read_hprt0(core_if); -+ hprt0.b.prtsusp = 1; -+ hprt0.b.prtres = 0; -+ dwc_write_reg32(core_if->host_if->hprt0, -+ hprt0.d32); -+ -+ /* 15 second delay per the test spec */ -+ mdelay(15000); -+ -+ /* Drive resume on the root port */ -+ hprt0.d32 = dwc_otg_read_hprt0(core_if); -+ hprt0.b.prtsusp = 0; -+ hprt0.b.prtres = 1; -+ dwc_write_reg32(core_if->host_if->hprt0, -+ hprt0.d32); -+ mdelay(100); -+ -+ /* Clear the resume bit */ -+ hprt0.b.prtres = 0; -+ dwc_write_reg32(core_if->host_if->hprt0, -+ hprt0.d32); -+ -+ /* Restore interrupts */ -+ dwc_write_reg32(&global_regs->gintmsk, -+ gintmsk.d32); -+ } else if (t == 7) { -+ /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */ -+ /* Save current interrupt mask */ -+ gintmsk.d32 = -+ dwc_read_reg32(&global_regs->gintmsk); -+ -+ /* -+ * Disable all interrupts -+ * while we muck with the -+ * hardware directly -+ */ -+ dwc_write_reg32(&global_regs->gintmsk, -+ 0); -+ -+ /* 15 second delay per the test spec */ -+ mdelay(15000); -+ -+ /* Send the Setup packet */ -+ do_setup(); -+ -+ /* -+ * 15 second delay so nothing -+ * else happens for awhile. -+ */ -+ mdelay(15000); -+ -+ /* Restore interrupts */ -+ dwc_write_reg32(&global_regs->gintmsk, -+ gintmsk.d32); -+ } else if (t == 8) { -+ /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */ -+ /* Save current interrupt mask */ -+ gintmsk.d32 = -+ dwc_read_reg32(&global_regs->gintmsk); -+ -+ /* -+ * Disable all interrupts -+ * while we muck with the -+ * hardware directly -+ */ -+ dwc_write_reg32(&global_regs->gintmsk, -+ 0); -+ -+ /* Send the Setup packet */ -+ do_setup(); -+ -+ /* 15 second delay so nothing else happens for awhile */ -+ mdelay(15000); -+ -+ /* Send the In and Ack packets */ -+ do_in_ack(); -+ -+ /* 15 second delay so nothing else happens for awhile */ -+ mdelay(15000); -+ -+ /* Restore interrupts */ -+ dwc_write_reg32(&global_regs->gintmsk, -+ gintmsk.d32); -+ } -+ } -+ break; -+#endif /* DWC_HS_ELECT_TST */ -+ -+ case USB_PORT_FEAT_INDICATOR: -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " -+ "SetPortFeature - USB_PORT_FEAT_INDICATOR\n"); -+ /* Not supported */ -+ break; -+ default: -+ retval = -EINVAL; -+ DWC_ERROR("DWC OTG HCD - " -+ "SetPortFeature request %xh " -+ "unknown or unsupported\n", _wValue); -+ break; -+ } -+ break; -+ default: -+error: -+ retval = -EINVAL; -+ DWC_WARN("DWC OTG HCD - Unknown hub control request type or " -+ "invalid typeReq: %xh wIndex: %xh wValue: %xh\n", -+ _typeReq, _wIndex, _wValue); -+ break; -+ } -+ -+ spin_unlock_irqrestore(&dwc_otg_hcd->global_lock, flags); -+ -+ return retval; -+} -+ -+/** -+ * Assigns transactions from a QTD to a free host channel and initializes the -+ * host channel to perform the transactions. The host channel is removed from -+ * the free list. -+ * -+ * @hcd: The HCD state structure. -+ * @_qh: Transactions from the first QTD for this QH are selected and -+ * assigned to a free host channel. -+ */ -+static void assign_and_init_hc(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *_qh) -+{ -+ struct dwc_hc *hc; -+ struct dwc_otg_qtd *qtd; -+ struct urb *urb; -+ -+ DWC_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, hcd, _qh); -+ -+ hc = list_entry(hcd->free_hc_list.next, struct dwc_hc, hc_list_entry); -+ -+ /* Remove the host channel from the free list. */ -+ list_del_init(&hc->hc_list_entry); -+ -+ qtd = list_entry(_qh->qtd_list.next, struct dwc_otg_qtd, -+ qtd_list_entry); -+ urb = qtd->urb; -+ _qh->channel = hc; -+ _qh->qtd_in_process = qtd; -+ -+ /* -+ * Use usb_pipedevice to determine device address. This address is -+ * 0 before the SET_ADDRESS command and the correct address afterward. -+ */ -+ hc->dev_addr = usb_pipedevice(urb->pipe); -+ hc->ep_num = usb_pipeendpoint(urb->pipe); -+ -+ if (urb->dev->speed == USB_SPEED_LOW) -+ hc->speed = DWC_OTG_EP_SPEED_LOW; -+ else if (urb->dev->speed == USB_SPEED_FULL) -+ hc->speed = DWC_OTG_EP_SPEED_FULL; -+ else -+ hc->speed = DWC_OTG_EP_SPEED_HIGH; -+ -+ hc->max_packet = dwc_max_packet(_qh->maxp); -+ -+ hc->xfer_started = 0; -+ hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS; -+ hc->error_state = (qtd->error_count > 0); -+ hc->halt_on_queue = 0; -+ hc->halt_pending = 0; -+ hc->requests = 0; -+ -+ /* -+ * The following values may be modified in the transfer type section -+ * below. The xfer_len value may be reduced when the transfer is -+ * started to accommodate the max widths of the XferSize and PktCnt -+ * fields in the HCTSIZn register. -+ */ -+ hc->do_ping = _qh->ping_state; -+ hc->ep_is_in = (usb_pipein(urb->pipe) != 0); -+ hc->data_pid_start = _qh->data_toggle; -+ hc->multi_count = 1; -+ -+ if (hcd->core_if->dma_enable) { -+#ifdef CONFIG_CPU_CAVIUM_OCTEON -+ const uint64_t USBN_DMA0_INB_CHN0 = -+ CVMX_USBNX_DMA0_INB_CHN0(hcd->core_if->usb_num); -+#endif /* CONFIG_CPU_CAVIUM_OCTEON */ -+ hc->xfer_buff = -+ (uint8_t *) (unsigned long)urb->transfer_dma + -+ urb->actual_length; -+#ifdef CONFIG_CPU_CAVIUM_OCTEON -+ /* Octeon uses external DMA */ -+ wmb(); -+ cvmx_write_csr(USBN_DMA0_INB_CHN0 + hc->hc_num * 8, -+ (unsigned long)hc->xfer_buff); -+ cvmx_read_csr(USBN_DMA0_INB_CHN0 + hc->hc_num * 8); -+ DWC_DEBUGPL(DBG_HCDV, -+ "IN: hc->hc_num = %d, hc->xfer_buff = %p\n", -+ hc->hc_num, hc->xfer_buff); -+#endif /* CONFIG_CPU_CAVIUM_OCTEON */ -+ } else { -+ hc->xfer_buff = -+ (uint8_t *) urb->transfer_buffer + urb->actual_length; -+ } -+ hc->xfer_len = urb->transfer_buffer_length - urb->actual_length; -+ hc->xfer_count = 0; -+ -+ /* -+ * Set the split attributes -+ */ -+ hc->do_split = 0; -+ if (_qh->do_split) { -+ hc->do_split = 1; -+ hc->xact_pos = qtd->isoc_split_pos; -+ hc->complete_split = qtd->complete_split; -+ hc->hub_addr = urb->dev->tt->hub->devnum; -+ hc->port_addr = urb->dev->ttport; -+ } -+ -+ switch (usb_pipetype(urb->pipe)) { -+ case PIPE_CONTROL: -+ hc->ep_type = DWC_OTG_EP_TYPE_CONTROL; -+ switch (qtd->control_phase) { -+ case DWC_OTG_CONTROL_SETUP: -+ DWC_DEBUGPL(DBG_HCDV, " Control setup transaction\n"); -+ hc->do_ping = 0; -+ hc->ep_is_in = 0; -+ hc->data_pid_start = DWC_OTG_HC_PID_SETUP; -+ if (hcd->core_if->dma_enable) { -+ hc->xfer_buff = -+ (uint8_t *) (unsigned long)urb->setup_dma; -+ } else { -+ hc->xfer_buff = (uint8_t *) urb->setup_packet; -+ } -+ hc->xfer_len = 8; -+ break; -+ case DWC_OTG_CONTROL_DATA: -+ DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n"); -+ hc->data_pid_start = qtd->data_toggle; -+ break; -+ case DWC_OTG_CONTROL_STATUS: -+ /* -+ * Direction is opposite of data direction or IN if no -+ * data. -+ */ -+ DWC_DEBUGPL(DBG_HCDV, " Control status transaction\n"); -+ if (urb->transfer_buffer_length == 0) { -+ hc->ep_is_in = 1; -+ } else { -+ hc->ep_is_in = -+ (usb_pipein(urb->pipe) != USB_DIR_IN); -+ } -+ if (hc->ep_is_in) -+ hc->do_ping = 0; -+ hc->data_pid_start = DWC_OTG_HC_PID_DATA1; -+ hc->xfer_len = 0; -+ if (hcd->core_if->dma_enable) { -+ hc->xfer_buff = -+ (uint8_t *) (unsigned long)hcd-> -+ status_buf_dma; -+ } else { -+ hc->xfer_buff = (uint8_t *) hcd->status_buf; -+ } -+ break; -+ } -+ break; -+ case PIPE_BULK: -+ hc->ep_type = DWC_OTG_EP_TYPE_BULK; -+ break; -+ case PIPE_INTERRUPT: -+ hc->ep_type = DWC_OTG_EP_TYPE_INTR; -+ break; -+ case PIPE_ISOCHRONOUS: -+ { -+ struct usb_iso_packet_descriptor *frame_desc; -+ frame_desc = -+ &urb->iso_frame_desc[qtd->isoc_frame_index]; -+ hc->ep_type = DWC_OTG_EP_TYPE_ISOC; -+ if (hcd->core_if->dma_enable) { -+ hc->xfer_buff = -+ (uint8_t *) (unsigned long)urb-> -+ transfer_dma; -+ } else { -+ hc->xfer_buff = -+ (uint8_t *) urb->transfer_buffer; -+ } -+ hc->xfer_buff += -+ frame_desc->offset + qtd->isoc_split_offset; -+ hc->xfer_len = -+ frame_desc->length - qtd->isoc_split_offset; -+ -+ if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) { -+ if (hc->xfer_len <= 188) { -+ hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL; -+ } else { -+ hc->xact_pos = -+ DWC_HCSPLIT_XACTPOS_BEGIN; -+ } -+ } -+ } -+ break; -+ } -+ -+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || -+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { -+ /* -+ * This value may be modified when the transfer is started to -+ * reflect the actual transfer length. -+ */ -+ hc->multi_count = dwc_hb_mult(_qh->maxp); -+ } -+ -+ dwc_otg_hc_init(hcd->core_if, hc); -+ hc->qh = _qh; -+} -+ -+/** -+ * This function selects transactions from the HCD transfer schedule and -+ * assigns them to available host channels. It is called from HCD interrupt -+ * handler functions. -+ * -+ * @hcd: The HCD state structure. -+ * -+ * Returns The types of new transactions that were assigned to host channels. -+ */ -+enum dwc_otg_transaction_type dwc_otg_hcd_select_transactions(struct dwc_otg_hcd -+ *hcd) -+{ -+ struct list_head *qh_ptr; -+ struct dwc_otg_qh *qh; -+ int num_channels; -+ enum dwc_otg_transaction_type ret_val = DWC_OTG_TRANSACTION_NONE; -+ -+#ifdef DEBUG_SOF -+ DWC_DEBUGPL(DBG_HCD, " Select Transactions\n"); -+#endif -+ -+ /* Process entries in the periodic ready list. */ -+ qh_ptr = hcd->periodic_sched_ready.next; -+ while (qh_ptr != &hcd->periodic_sched_ready && -+ !list_empty(&hcd->free_hc_list)) { -+ -+ qh = list_entry(qh_ptr, struct dwc_otg_qh, qh_list_entry); -+ assign_and_init_hc(hcd, qh); -+ -+ /* -+ * Move the QH from the periodic ready schedule to the -+ * periodic assigned schedule. -+ */ -+ qh_ptr = qh_ptr->next; -+ list_move(&qh->qh_list_entry, &hcd->periodic_sched_assigned); -+ -+ ret_val = DWC_OTG_TRANSACTION_PERIODIC; -+ } -+ -+ /* -+ * Process entries in the inactive portion of the non-periodic -+ * schedule. Some free host channels may not be used if they are -+ * reserved for periodic transfers. -+ */ -+ qh_ptr = hcd->non_periodic_sched_inactive.next; -+ num_channels = hcd->core_if->core_params->host_channels; -+ while (qh_ptr != &hcd->non_periodic_sched_inactive && -+ (hcd->non_periodic_channels < -+ num_channels - hcd->periodic_channels) && -+ !list_empty(&hcd->free_hc_list)) { -+ -+ qh = list_entry(qh_ptr, struct dwc_otg_qh, qh_list_entry); -+ assign_and_init_hc(hcd, qh); -+ -+ /* -+ * Move the QH from the non-periodic inactive schedule to the -+ * non-periodic active schedule. -+ */ -+ qh_ptr = qh_ptr->next; -+ list_move(&qh->qh_list_entry, &hcd->non_periodic_sched_active); -+ -+ if (ret_val == DWC_OTG_TRANSACTION_NONE) -+ ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC; -+ else -+ ret_val = DWC_OTG_TRANSACTION_ALL; -+ -+ hcd->non_periodic_channels++; -+ } -+ -+ return ret_val; -+} -+ -+/** -+ * Attempts to queue a single transaction request for a host channel -+ * associated with either a periodic or non-periodic transfer. This function -+ * assumes that there is space available in the appropriate request queue. For -+ * an OUT transfer or SETUP transaction in Slave mode, it checks whether space -+ * is available in the appropriate Tx FIFO. -+ * -+ * @hcd: The HCD state structure. -+ * @_hc: Host channel descriptor associated with either a periodic or -+ * non-periodic transfer. -+ * @_fifo_dwords_avail: Number of DWORDs available in the periodic Tx -+ * FIFO for periodic transfers or the non-periodic Tx FIFO for non-periodic -+ * transfers. -+ * -+ * Returns 1 if a request is queued and more requests may be needed to -+ * complete the transfer, 0 if no more requests are required for this -+ * transfer, -1 if there is insufficient space in the Tx FIFO. -+ */ -+static int queue_transaction(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *_hc, uint16_t _fifo_dwords_avail) -+{ -+ int retval; -+ -+ if (hcd->core_if->dma_enable) { -+ if (!_hc->xfer_started) { -+ dwc_otg_hc_start_transfer(hcd->core_if, _hc); -+ _hc->qh->ping_state = 0; -+ } -+ retval = 0; -+ } else if (_hc->halt_pending) { -+ /* Don't queue a request if the channel has been halted. */ -+ retval = 0; -+ } else if (_hc->halt_on_queue) { -+ dwc_otg_hc_halt(hcd->core_if, _hc, _hc->halt_status); -+ retval = 0; -+ } else if (_hc->do_ping) { -+ if (!_hc->xfer_started) -+ dwc_otg_hc_start_transfer(hcd->core_if, _hc); -+ retval = 0; -+ } else if (!_hc->ep_is_in || -+ _hc->data_pid_start == DWC_OTG_HC_PID_SETUP) { -+ if ((_fifo_dwords_avail * 4) >= _hc->max_packet) { -+ if (!_hc->xfer_started) { -+ dwc_otg_hc_start_transfer(hcd->core_if, _hc); -+ retval = 1; -+ } else { -+ retval = -+ dwc_otg_hc_continue_transfer(hcd->core_if, -+ _hc); -+ } -+ } else { -+ retval = -1; -+ } -+ } else { -+ if (!_hc->xfer_started) { -+ dwc_otg_hc_start_transfer(hcd->core_if, _hc); -+ retval = 1; -+ } else { -+ retval = -+ dwc_otg_hc_continue_transfer(hcd->core_if, _hc); -+ } -+ } -+ -+ return retval; -+} -+ -+/** -+ * Processes active non-periodic channels and queues transactions for these -+ * channels to the DWC_otg controller. After queueing transactions, the NP Tx -+ * FIFO Empty interrupt is enabled if there are more transactions to queue as -+ * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx -+ * FIFO Empty interrupt is disabled. -+ */ -+static void process_non_periodic_channels(struct dwc_otg_hcd *hcd) -+{ -+ union gnptxsts_data tx_status; -+ struct list_head *orig_qh_ptr; -+ struct dwc_otg_qh *qh; -+ int status; -+ int no_queue_space = 0; -+ int no_fifo_space = 0; -+ int more_to_do = 0; -+ -+ struct dwc_otg_core_global_regs *global_regs = -+ hcd->core_if->core_global_regs; -+ -+ DWC_DEBUGPL(DBG_HCDV, "Queue non-periodic transactions\n"); -+#ifdef DEBUG -+ tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts); -+ DWC_DEBUGPL(DBG_HCDV, -+ " NP Tx Req Queue Space Avail (before queue): %d\n", -+ tx_status.b.nptxqspcavail); -+ DWC_DEBUGPL(DBG_HCDV, " NP Tx FIFO Space Avail (before queue): %d\n", -+ tx_status.b.nptxfspcavail); -+#endif -+ /* -+ * Keep track of the starting point. Skip over the start-of-list -+ * entry. -+ */ -+ if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) -+ hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next; -+ -+ orig_qh_ptr = hcd->non_periodic_qh_ptr; -+ -+ /* -+ * Process once through the active list or until no more space is -+ * available in the request queue or the Tx FIFO. -+ */ -+ do { -+ tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts); -+ if (!hcd->core_if->dma_enable -+ && tx_status.b.nptxqspcavail == 0) { -+ no_queue_space = 1; -+ break; -+ } -+ -+ qh = list_entry(hcd->non_periodic_qh_ptr, struct dwc_otg_qh, -+ qh_list_entry); -+ status = -+ queue_transaction(hcd, qh->channel, -+ tx_status.b.nptxfspcavail); -+ -+ if (status > 0) { -+ more_to_do = 1; -+ } else if (status < 0) { -+ no_fifo_space = 1; -+ break; -+ } -+ -+ /* Advance to next QH, skipping start-of-list entry. */ -+ hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next; -+ if (hcd->non_periodic_qh_ptr == -+ &hcd->non_periodic_sched_active) { -+ hcd->non_periodic_qh_ptr = -+ hcd->non_periodic_qh_ptr->next; -+ } -+ -+ } while (hcd->non_periodic_qh_ptr != orig_qh_ptr); -+ -+ if (!hcd->core_if->dma_enable) { -+ union gintmsk_data intr_mask = {.d32 = 0 }; -+ intr_mask.b.nptxfempty = 1; -+ -+#ifdef DEBUG -+ tx_status.d32 = dwc_read_reg32(&global_regs->gnptxsts); -+ DWC_DEBUGPL(DBG_HCDV, -+ " NP Tx Req Queue Space Avail (after queue): %d\n", -+ tx_status.b.nptxqspcavail); -+ DWC_DEBUGPL(DBG_HCDV, -+ " NP Tx FIFO Space Avail (after queue): %d\n", -+ tx_status.b.nptxfspcavail); -+#endif -+ if (no_queue_space || no_fifo_space) { -+ /* -+ * May need to queue more transactions as the request -+ * queue or Tx FIFO empties. Enable the non-periodic -+ * Tx FIFO empty interrupt. (Always use the half-empty -+ * level to ensure that new requests are loaded as -+ * soon as possible.) -+ */ -+ dwc_modify_reg32(&global_regs->gintmsk, 0, -+ intr_mask.d32); -+ } else { -+ /* -+ * Disable the Tx FIFO empty interrupt since there are -+ * no more transactions that need to be queued right -+ * now. This function is called from interrupt -+ * handlers to queue more transactions as transfer -+ * states change. -+ */ -+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, -+ 0); -+ if (more_to_do) { -+ /* When not using DMA, many USB -+ * devices cause excessive loads on -+ * the serial bus simply because they -+ * continuously poll the device for -+ * status. Here we use the timer to -+ * rate limit how fast we can get the -+ * the NP TX fifo empty interrupt. We -+ * leave the interrupt disable until -+ * the timer fires and reenables it */ -+ -+ /* We'll rate limit the interrupt at -+ * 20000 per second. Making this -+ * faster improves USB performance but -+ * uses more CPU */ -+ hrtimer_start_range_ns(&hcd->poll_rate_limit, -+ ktime_set(0, 50000), -+ 5000, HRTIMER_MODE_REL); -+ } -+ } -+ } -+} -+ -+/** -+ * Processes periodic channels for the next frame and queues transactions for -+ * these channels to the DWC_otg controller. After queueing transactions, the -+ * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions -+ * to queue as Periodic Tx FIFO or request queue space becomes available. -+ * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled. -+ */ -+static void process_periodic_channels(struct dwc_otg_hcd *hcd) -+{ -+ union hptxsts_data tx_status; -+ struct list_head *qh_ptr; -+ struct dwc_otg_qh *qh; -+ int status; -+ int no_queue_space = 0; -+ int no_fifo_space = 0; -+ -+ struct dwc_otg_host_global_regs *host_regs; -+ host_regs = hcd->core_if->host_if->host_global_regs; -+ -+ DWC_DEBUGPL(DBG_HCDV, "Queue periodic transactions\n"); -+#ifdef DEBUG -+ tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts); -+ DWC_DEBUGPL(DBG_HCDV, -+ " P Tx Req Queue Space Avail (before queue): %d\n", -+ tx_status.b.ptxqspcavail); -+ DWC_DEBUGPL(DBG_HCDV, " P Tx FIFO Space Avail (before queue): %d\n", -+ tx_status.b.ptxfspcavail); -+#endif -+ -+ qh_ptr = hcd->periodic_sched_assigned.next; -+ while (qh_ptr != &hcd->periodic_sched_assigned) { -+ tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts); -+ if (tx_status.b.ptxqspcavail == 0) { -+ no_queue_space = 1; -+ break; -+ } -+ -+ qh = list_entry(qh_ptr, struct dwc_otg_qh, qh_list_entry); -+ -+ /* -+ * Set a flag if we're queuing high-bandwidth in slave mode. -+ * The flag prevents any halts to get into the request queue in -+ * the middle of multiple high-bandwidth packets getting queued. -+ */ -+ if ((!hcd->core_if->dma_enable) && -+ (qh->channel->multi_count > 1)) { -+ hcd->core_if->queuing_high_bandwidth = 1; -+ } -+ -+ status = -+ queue_transaction(hcd, qh->channel, -+ tx_status.b.ptxfspcavail); -+ if (status < 0) { -+ no_fifo_space = 1; -+ break; -+ } -+ -+ /* -+ * In Slave mode, stay on the current transfer until there is -+ * nothing more to do or the high-bandwidth request count is -+ * reached. In DMA mode, only need to queue one request. The -+ * controller automatically handles multiple packets for -+ * high-bandwidth transfers. -+ */ -+ if (hcd->core_if->dma_enable || -+ (status == 0 || -+ qh->channel->requests == qh->channel->multi_count)) { -+ qh_ptr = qh_ptr->next; -+ /* -+ * Move the QH from the periodic assigned schedule to -+ * the periodic queued schedule. -+ */ -+ list_move(&qh->qh_list_entry, -+ &hcd->periodic_sched_queued); -+ -+ /* done queuing high bandwidth */ -+ hcd->core_if->queuing_high_bandwidth = 0; -+ } -+ } -+ -+ if (!hcd->core_if->dma_enable) { -+ struct dwc_otg_core_global_regs *global_regs; -+ union gintmsk_data intr_mask = {.d32 = 0 }; -+ -+ global_regs = hcd->core_if->core_global_regs; -+ intr_mask.b.ptxfempty = 1; -+#ifdef DEBUG -+ tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts); -+ DWC_DEBUGPL(DBG_HCDV, -+ " P Tx Req Queue Space Avail (after queue): %d\n", -+ tx_status.b.ptxqspcavail); -+ DWC_DEBUGPL(DBG_HCDV, -+ " P Tx FIFO Space Avail (after queue): %d\n", -+ tx_status.b.ptxfspcavail); -+#endif -+ if (!(list_empty(&hcd->periodic_sched_assigned)) || -+ no_queue_space || no_fifo_space) { -+ /* -+ * May need to queue more transactions as the request -+ * queue or Tx FIFO empties. Enable the periodic Tx -+ * FIFO empty interrupt. (Always use the half-empty -+ * level to ensure that new requests are loaded as -+ * soon as possible.) -+ */ -+ dwc_modify_reg32(&global_regs->gintmsk, 0, -+ intr_mask.d32); -+ } else { -+ /* -+ * Disable the Tx FIFO empty interrupt since there are -+ * no more transactions that need to be queued right -+ * now. This function is called from interrupt -+ * handlers to queue more transactions as transfer -+ * states change. -+ */ -+ dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, -+ 0); -+ } -+ } -+} -+ -+/** -+ * This function processes the currently active host channels and queues -+ * transactions for these channels to the DWC_otg controller. It is called -+ * from HCD interrupt handler functions. -+ * -+ * @hcd: The HCD state structure. -+ * @_tr_type: The type(s) of transactions to queue (non-periodic, -+ * periodic, or both). -+ */ -+void dwc_otg_hcd_queue_transactions(struct dwc_otg_hcd *hcd, -+ enum dwc_otg_transaction_type _tr_type) -+{ -+#ifdef DEBUG_SOF -+ DWC_DEBUGPL(DBG_HCD, "Queue Transactions\n"); -+#endif -+ /* Process host channels associated with periodic transfers. */ -+ if ((_tr_type == DWC_OTG_TRANSACTION_PERIODIC || -+ _tr_type == DWC_OTG_TRANSACTION_ALL) && -+ !list_empty(&hcd->periodic_sched_assigned)) { -+ -+ process_periodic_channels(hcd); -+ } -+ -+ /* Process host channels associated with non-periodic transfers. */ -+ if ((_tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC || -+ _tr_type == DWC_OTG_TRANSACTION_ALL)) { -+ if (!list_empty(&hcd->non_periodic_sched_active)) { -+ process_non_periodic_channels(hcd); -+ } else { -+ /* -+ * Ensure NP Tx FIFO empty interrupt is disabled when -+ * there are no non-periodic transfers to process. -+ */ -+ union gintmsk_data gintmsk = {.d32 = 0 }; -+ gintmsk.b.nptxfempty = 1; -+ dwc_modify_reg32(&hcd->core_if->core_global_regs-> -+ gintmsk, gintmsk.d32, 0); -+ } -+ } -+} -+ -+/** -+ * Sets the final status of an URB and returns it to the device driver. Any -+ * required cleanup of the URB is performed. -+ */ -+void dwc_otg_hcd_complete_urb(struct dwc_otg_hcd *hcd, struct urb *urb, -+ int status) -+{ -+#ifdef DEBUG -+ if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) { -+ DWC_PRINT("%s: urb %p, device %d, ep %d %s, status=%d\n", -+ __func__, urb, usb_pipedevice(urb->pipe), -+ usb_pipeendpoint(urb->pipe), -+ usb_pipein(urb->pipe) ? "IN" : "OUT", status); -+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { -+ int i; -+ for (i = 0; i < urb->number_of_packets; i++) { -+ DWC_PRINT(" ISO Desc %d status: %d\n", -+ i, urb->iso_frame_desc[i].status); -+ } -+ } -+ } -+#endif -+ -+ urb->status = status; -+ urb->hcpriv = NULL; -+ -+ usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status); -+} -+ -+/* -+ * Returns the Queue Head for an URB. -+ */ -+struct dwc_otg_qh *dwc_urb_to_qh(struct urb *urb) -+{ -+ struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb); -+ return ep->hcpriv; -+} -+ -+#ifdef DEBUG -+void dwc_print_setup_data(uint8_t *setup) -+{ -+ int i; -+ if (CHK_DEBUG_LEVEL(DBG_HCD)) { -+ DWC_PRINT("Setup Data = MSB "); -+ for (i = 7; i >= 0; i--) -+ DWC_PRINT("%02x ", setup[i]); -+ DWC_PRINT("\n"); -+ DWC_PRINT(" bmRequestType Tranfer = %s\n", -+ (setup[0] & 0x80) ? "Device-to-Host" : -+ "Host-to-Device"); -+ DWC_PRINT(" bmRequestType Type = "); -+ switch ((setup[0] & 0x60) >> 5) { -+ case 0: -+ DWC_PRINT("Standard\n"); -+ break; -+ case 1: -+ DWC_PRINT("Class\n"); -+ break; -+ case 2: -+ DWC_PRINT("Vendor\n"); -+ break; -+ case 3: -+ DWC_PRINT("Reserved\n"); -+ break; -+ } -+ DWC_PRINT(" bmRequestType Recipient = "); -+ switch (setup[0] & 0x1f) { -+ case 0: -+ DWC_PRINT("Device\n"); -+ break; -+ case 1: -+ DWC_PRINT("Interface\n"); -+ break; -+ case 2: -+ DWC_PRINT("Endpoint\n"); -+ break; -+ case 3: -+ DWC_PRINT("Other\n"); -+ break; -+ default: -+ DWC_PRINT("Reserved\n"); -+ break; -+ } -+ DWC_PRINT(" bRequest = 0x%0x\n", setup[1]); -+ DWC_PRINT(" wValue = 0x%0x\n", *((uint16_t *) &setup[2])); -+ DWC_PRINT(" wIndex = 0x%0x\n", *((uint16_t *) &setup[4])); -+ DWC_PRINT(" wLength = 0x%0x\n\n", *((uint16_t *) &setup[6])); -+ } -+} -+#endif -+ -+void dwc_otg_hcd_dump_frrem(struct dwc_otg_hcd *hcd) -+{ -+#ifdef DEBUG -+ DWC_PRINT("Frame remaining at SOF:\n"); -+ DWC_PRINT(" samples %u, accum %lu, avg %lu\n", -+ hcd->frrem_samples, hcd->frrem_accum, -+ (hcd->frrem_samples > 0) ? -+ hcd->frrem_accum / hcd->frrem_samples : 0); -+ -+ DWC_PRINT("\n"); -+ DWC_PRINT("Frame remaining at start_transfer (uframe 7):\n"); -+ DWC_PRINT(" samples %u, accum %lu, avg %lu\n", -+ hcd->core_if->hfnum_7_samples, -+ hcd->core_if->hfnum_7_frrem_accum, -+ (hcd->core_if->hfnum_7_samples > -+ 0) ? hcd->core_if->hfnum_7_frrem_accum / -+ hcd->core_if->hfnum_7_samples : 0); -+ DWC_PRINT("Frame remaining at start_transfer (uframe 0):\n"); -+ DWC_PRINT(" samples %u, accum %lu, avg %lu\n", -+ hcd->core_if->hfnum_0_samples, -+ hcd->core_if->hfnum_0_frrem_accum, -+ (hcd->core_if->hfnum_0_samples > -+ 0) ? hcd->core_if->hfnum_0_frrem_accum / -+ hcd->core_if->hfnum_0_samples : 0); -+ DWC_PRINT("Frame remaining at start_transfer (uframe 1-6):\n"); -+ DWC_PRINT(" samples %u, accum %lu, avg %lu\n", -+ hcd->core_if->hfnum_other_samples, -+ hcd->core_if->hfnum_other_frrem_accum, -+ (hcd->core_if->hfnum_other_samples > -+ 0) ? hcd->core_if->hfnum_other_frrem_accum / -+ hcd->core_if->hfnum_other_samples : 0); -+ -+ DWC_PRINT("\n"); -+ DWC_PRINT("Frame remaining at sample point A (uframe 7):\n"); -+ DWC_PRINT(" samples %u, accum %lu, avg %lu\n", -+ hcd->hfnum_7_samples_a, hcd->hfnum_7_frrem_accum_a, -+ (hcd->hfnum_7_samples_a > 0) ? -+ hcd->hfnum_7_frrem_accum_a / hcd->hfnum_7_samples_a : 0); -+ DWC_PRINT("Frame remaining at sample point A (uframe 0):\n"); -+ DWC_PRINT(" samples %u, accum %lu, avg %lu\n", -+ hcd->hfnum_0_samples_a, hcd->hfnum_0_frrem_accum_a, -+ (hcd->hfnum_0_samples_a > 0) ? -+ hcd->hfnum_0_frrem_accum_a / hcd->hfnum_0_samples_a : 0); -+ DWC_PRINT("Frame remaining at sample point A (uframe 1-6):\n"); -+ DWC_PRINT(" samples %u, accum %lu, avg %lu\n", -+ hcd->hfnum_other_samples_a, hcd->hfnum_other_frrem_accum_a, -+ (hcd->hfnum_other_samples_a > 0) ? -+ hcd->hfnum_other_frrem_accum_a / -+ hcd->hfnum_other_samples_a : 0); -+ -+ DWC_PRINT("\n"); -+ DWC_PRINT("Frame remaining at sample point B (uframe 7):\n"); -+ DWC_PRINT(" samples %u, accum %lu, avg %lu\n", -+ hcd->hfnum_7_samples_b, hcd->hfnum_7_frrem_accum_b, -+ (hcd->hfnum_7_samples_b > 0) ? -+ hcd->hfnum_7_frrem_accum_b / hcd->hfnum_7_samples_b : 0); -+ DWC_PRINT("Frame remaining at sample point B (uframe 0):\n"); -+ DWC_PRINT(" samples %u, accum %lu, avg %lu\n", -+ hcd->hfnum_0_samples_b, hcd->hfnum_0_frrem_accum_b, -+ (hcd->hfnum_0_samples_b > 0) ? -+ hcd->hfnum_0_frrem_accum_b / hcd->hfnum_0_samples_b : 0); -+ DWC_PRINT("Frame remaining at sample point B (uframe 1-6):\n"); -+ DWC_PRINT(" samples %u, accum %lu, avg %lu\n", -+ hcd->hfnum_other_samples_b, hcd->hfnum_other_frrem_accum_b, -+ (hcd->hfnum_other_samples_b > 0) ? -+ hcd->hfnum_other_frrem_accum_b / -+ hcd->hfnum_other_samples_b : 0); -+#endif -+} -+ -+void dwc_otg_hcd_dump_state(struct dwc_otg_hcd *hcd) -+{ -+#ifdef DEBUG -+ int num_channels; -+ int i; -+ union gnptxsts_data np_tx_status; -+ union hptxsts_data p_tx_status; -+ -+ num_channels = hcd->core_if->core_params->host_channels; -+ DWC_PRINT("\n"); -+ DWC_PRINT -+ ("************************************************************\n"); -+ DWC_PRINT("HCD State:\n"); -+ DWC_PRINT(" Num channels: %d\n", num_channels); -+ for (i = 0; i < num_channels; i++) { -+ struct dwc_hc *hc = hcd->hc_ptr_array[i]; -+ DWC_PRINT(" Channel %d:\n", i); -+ DWC_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n", -+ hc->dev_addr, hc->ep_num, hc->ep_is_in); -+ DWC_PRINT(" speed: %d\n", hc->speed); -+ DWC_PRINT(" ep_type: %d\n", hc->ep_type); -+ DWC_PRINT(" max_packet: %d\n", hc->max_packet); -+ DWC_PRINT(" data_pid_start: %d\n", hc->data_pid_start); -+ DWC_PRINT(" multi_count: %d\n", hc->multi_count); -+ DWC_PRINT(" xfer_started: %d\n", hc->xfer_started); -+ DWC_PRINT(" xfer_buff: %p\n", hc->xfer_buff); -+ DWC_PRINT(" xfer_len: %d\n", hc->xfer_len); -+ DWC_PRINT(" xfer_count: %d\n", hc->xfer_count); -+ DWC_PRINT(" halt_on_queue: %d\n", hc->halt_on_queue); -+ DWC_PRINT(" halt_pending: %d\n", hc->halt_pending); -+ DWC_PRINT(" halt_status: %d\n", hc->halt_status); -+ DWC_PRINT(" do_split: %d\n", hc->do_split); -+ DWC_PRINT(" complete_split: %d\n", hc->complete_split); -+ DWC_PRINT(" hub_addr: %d\n", hc->hub_addr); -+ DWC_PRINT(" port_addr: %d\n", hc->port_addr); -+ DWC_PRINT(" xact_pos: %d\n", hc->xact_pos); -+ DWC_PRINT(" requests: %d\n", hc->requests); -+ DWC_PRINT(" qh: %p\n", hc->qh); -+ if (hc->xfer_started) { -+ union hfnum_data hfnum; -+ union hcchar_data hcchar; -+ union hctsiz_data hctsiz; -+ union hcint_data hcint; -+ union hcintmsk_data hcintmsk; -+ hfnum.d32 = -+ dwc_read_reg32(&hcd->core_if->host_if-> -+ host_global_regs->hfnum); -+ hcchar.d32 = -+ dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]-> -+ hcchar); -+ hctsiz.d32 = -+ dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]-> -+ hctsiz); -+ hcint.d32 = -+ dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]-> -+ hcint); -+ hcintmsk.d32 = -+ dwc_read_reg32(&hcd->core_if->host_if->hc_regs[i]-> -+ hcintmsk); -+ DWC_PRINT(" hfnum: 0x%08x\n", hfnum.d32); -+ DWC_PRINT(" hcchar: 0x%08x\n", hcchar.d32); -+ DWC_PRINT(" hctsiz: 0x%08x\n", hctsiz.d32); -+ DWC_PRINT(" hcint: 0x%08x\n", hcint.d32); -+ DWC_PRINT(" hcintmsk: 0x%08x\n", hcintmsk.d32); -+ } -+ if (hc->xfer_started && (hc->qh != NULL) -+ && (hc->qh->qtd_in_process != NULL)) { -+ struct dwc_otg_qtd *qtd; -+ struct urb *urb; -+ qtd = hc->qh->qtd_in_process; -+ urb = qtd->urb; -+ DWC_PRINT(" URB Info:\n"); -+ DWC_PRINT(" qtd: %p, urb: %p\n", qtd, urb); -+ if (urb != NULL) { -+ DWC_PRINT(" Dev: %d, EP: %d %s\n", -+ usb_pipedevice(urb->pipe), -+ usb_pipeendpoint(urb->pipe), -+ usb_pipein(urb->pipe) ? "IN" : "OUT"); -+ DWC_PRINT(" Max packet size: %d\n", -+ usb_maxpacket(urb->dev, urb->pipe, -+ usb_pipeout(urb-> -+ pipe))); -+ DWC_PRINT(" transfer_buffer: %p\n", -+ urb->transfer_buffer); -+ DWC_PRINT(" transfer_dma: %p\n", -+ (void *)urb->transfer_dma); -+ DWC_PRINT(" transfer_buffer_length: %d\n", -+ urb->transfer_buffer_length); -+ DWC_PRINT(" actual_length: %d\n", -+ urb->actual_length); -+ } -+ } -+ } -+ DWC_PRINT(" non_periodic_channels: %d\n", hcd->non_periodic_channels); -+ DWC_PRINT(" periodic_channels: %d\n", hcd->periodic_channels); -+ DWC_PRINT(" periodic_usecs: %d\n", hcd->periodic_usecs); -+ np_tx_status.d32 = -+ dwc_read_reg32(&hcd->core_if->core_global_regs->gnptxsts); -+ DWC_PRINT(" NP Tx Req Queue Space Avail: %d\n", -+ np_tx_status.b.nptxqspcavail); -+ DWC_PRINT(" NP Tx FIFO Space Avail: %d\n", -+ np_tx_status.b.nptxfspcavail); -+ p_tx_status.d32 = -+ dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hptxsts); -+ DWC_PRINT(" P Tx Req Queue Space Avail: %d\n", -+ p_tx_status.b.ptxqspcavail); -+ DWC_PRINT(" P Tx FIFO Space Avail: %d\n", p_tx_status.b.ptxfspcavail); -+ dwc_otg_hcd_dump_frrem(hcd); -+ dwc_otg_dump_global_registers(hcd->core_if); -+ dwc_otg_dump_host_registers(hcd->core_if); -+ DWC_PRINT -+ ("************************************************************\n"); -+ DWC_PRINT("\n"); -+#endif -+} -+#endif /* DWC_DEVICE_ONLY */ -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h -new file mode 100644 -index 0000000..6dcf1f5 ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h -@@ -0,0 +1,661 @@ -+/* ========================================================================== -+ * -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+#ifndef DWC_DEVICE_ONLY -+#if !defined(__DWC_HCD_H__) -+#define __DWC_HCD_H__ -+ -+#include <linux/list.h> -+#include <linux/usb.h> -+#include <linux/hrtimer.h> -+ -+#include <../drivers/usb/core/hcd.h> -+ -+struct dwc_otg_device; -+ -+#include "dwc_otg_cil.h" -+ -+/** -+ * -+ * This file contains the structures, constants, and interfaces for -+ * the Host Contoller Driver (HCD). -+ * -+ * The Host Controller Driver (HCD) is responsible for translating requests -+ * from the USB Driver into the appropriate actions on the DWC_otg controller. -+ * It isolates the USBD from the specifics of the controller by providing an -+ * API to the USBD. -+ */ -+ -+/** -+ * Phases for control transfers. -+ */ -+enum dwc_otg_control_phase { -+ DWC_OTG_CONTROL_SETUP, -+ DWC_OTG_CONTROL_DATA, -+ DWC_OTG_CONTROL_STATUS -+}; -+ -+/** Transaction types. */ -+enum dwc_otg_transaction_type { -+ DWC_OTG_TRANSACTION_NONE, -+ DWC_OTG_TRANSACTION_PERIODIC, -+ DWC_OTG_TRANSACTION_NON_PERIODIC, -+ DWC_OTG_TRANSACTION_ALL -+}; -+ -+struct dwc_otg_qh; -+ -+/* -+ * A Queue Transfer Descriptor (QTD) holds the state of a bulk, control, -+ * interrupt, or isochronous transfer. A single QTD is created for each URB -+ * (of one of these types) submitted to the HCD. The transfer associated with -+ * a QTD may require one or multiple transactions. -+ * -+ * A QTD is linked to a Queue Head, which is entered in either the -+ * non-periodic or periodic schedule for execution. When a QTD is chosen for -+ * execution, some or all of its transactions may be executed. After -+ * execution, the state of the QTD is updated. The QTD may be retired if all -+ * its transactions are complete or if an error occurred. Otherwise, it -+ * remains in the schedule so more transactions can be executed later. -+ */ -+struct dwc_otg_qtd { -+ /* -+ * Determines the PID of the next data packet for the data phase of -+ * control transfers. Ignored for other transfer types.<br> -+ * One of the following values: -+ * - DWC_OTG_HC_PID_DATA0 -+ * - DWC_OTG_HC_PID_DATA1 -+ */ -+ uint8_t data_toggle; -+ -+ /** Current phase for control transfers (Setup, Data, or Status). */ -+ enum dwc_otg_control_phase control_phase; -+ -+ /** Keep track of the current split type -+ * for FS/LS endpoints on a HS Hub */ -+ uint8_t complete_split; -+ -+ /** How many bytes transferred during SSPLIT OUT */ -+ uint32_t ssplit_out_xfer_count; -+ -+ /** -+ * Holds the number of bus errors that have occurred for a transaction -+ * within this transfer. -+ */ -+ uint8_t error_count; -+ -+ /** -+ * Index of the next frame descriptor for an isochronous transfer. A -+ * frame descriptor describes the buffer position and length of the -+ * data to be transferred in the next scheduled (micro)frame of an -+ * isochronous transfer. It also holds status for that transaction. -+ * The frame index starts at 0. -+ */ -+ int isoc_frame_index; -+ -+ /** Position of the ISOC split on full/low speed */ -+ uint8_t isoc_split_pos; -+ -+ /** Position of the ISOC split in the buffer for the current frame */ -+ uint16_t isoc_split_offset; -+ -+ /** URB for this transfer */ -+ struct urb *urb; -+ -+ /* The queue head for this transfer. */ -+ struct dwc_otg_qh *qh; -+ -+ /** This list of QTDs */ -+ struct list_head qtd_list_entry; -+ -+}; -+ -+/** -+ * A Queue Head (QH) holds the static characteristics of an endpoint and -+ * maintains a list of transfers (QTDs) for that endpoint. A QH structure may -+ * be entered in either the non-periodic or periodic schedule. -+ */ -+struct dwc_otg_qh { -+ /** -+ * Endpoint type. -+ * One of the following values: -+ * - USB_ENDPOINT_XFER_CONTROL -+ * - USB_ENDPOINT_XFER_ISOC -+ * - USB_ENDPOINT_XFER_BULK -+ * - USB_ENDPOINT_XFER_INT -+ */ -+ uint8_t ep_type; -+ uint8_t ep_is_in; -+ -+ /** wMaxPacketSize Field of Endpoint Descriptor. */ -+ uint16_t maxp; -+ -+ /** -+ * Determines the PID of the next data packet for non-control -+ * transfers. Ignored for control transfers.<br> -+ * One of the following values: -+ * - DWC_OTG_HC_PID_DATA0 -+ * - DWC_OTG_HC_PID_DATA1 -+ */ -+ uint8_t data_toggle; -+ -+ /** Ping state if 1. */ -+ uint8_t ping_state; -+ -+ /** -+ * List of QTDs for this QH. -+ */ -+ struct list_head qtd_list; -+ -+ /** Host channel currently processing transfers for this QH. */ -+ struct dwc_hc *channel; -+ -+ /** QTD currently assigned to a host channel for this QH. */ -+ struct dwc_otg_qtd *qtd_in_process; -+ -+ /** Full/low speed endpoint on high-speed hub requires split. */ -+ uint8_t do_split; -+ -+ /** @name Periodic schedule information */ -+ /** @{ */ -+ -+ /** Bandwidth in microseconds per (micro)frame. */ -+ uint8_t usecs; -+ -+ /** Interval between transfers in (micro)frames. */ -+ uint16_t interval; -+ -+ /** -+ * (micro)frame to initialize a periodic transfer. The transfer -+ * executes in the following (micro)frame. -+ */ -+ uint16_t sched_frame; -+ -+ /** (micro)frame at which last start split was initialized. */ -+ uint16_t start_split_frame; -+ -+ /** @} */ -+ -+ /** Entry for QH in either the periodic or non-periodic schedule. */ -+ struct list_head qh_list_entry; -+}; -+ -+/** -+ * This structure holds the state of the HCD, including the non-periodic and -+ * periodic schedules. -+ */ -+struct dwc_otg_hcd { -+ -+ /** DWC OTG Core Interface Layer */ -+ struct dwc_otg_core_if *core_if; -+ -+ /** Internal DWC HCD Flags */ -+ union dwc_otg_hcd_internal_flags { -+ uint32_t d32; -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:26; -+ unsigned port_over_current_change:1; -+ unsigned port_suspend_change:1; -+ unsigned port_enable_change:1; -+ unsigned port_reset_change:1; -+ unsigned port_connect_status:1; -+ unsigned port_connect_status_change:1; -+#else -+ unsigned port_connect_status_change:1; -+ unsigned port_connect_status:1; -+ unsigned port_reset_change:1; -+ unsigned port_enable_change:1; -+ unsigned port_suspend_change:1; -+ unsigned port_over_current_change:1; -+ unsigned reserved:26; -+#endif -+ } b; -+ } flags; -+ -+ /** -+ * Inactive items in the non-periodic schedule. This is a list of -+ * Queue Heads. Transfers associated with these Queue Heads are not -+ * currently assigned to a host channel. -+ */ -+ struct list_head non_periodic_sched_inactive; -+ -+ /** -+ * Active items in the non-periodic schedule. This is a list of -+ * Queue Heads. Transfers associated with these Queue Heads are -+ * currently assigned to a host channel. -+ */ -+ struct list_head non_periodic_sched_active; -+ -+ /** -+ * Pointer to the next Queue Head to process in the active -+ * non-periodic schedule. -+ */ -+ struct list_head *non_periodic_qh_ptr; -+ -+ /** -+ * Inactive items in the periodic schedule. This is a list of QHs for -+ * periodic transfers that are _not_ scheduled for the next frame. -+ * Each QH in the list has an interval counter that determines when it -+ * needs to be scheduled for execution. This scheduling mechanism -+ * allows only a simple calculation for periodic bandwidth used (i.e. -+ * must assume that all periodic transfers may need to execute in the -+ * same frame). However, it greatly simplifies scheduling and should -+ * be sufficient for the vast majority of OTG hosts, which need to -+ * connect to a small number of peripherals at one time. -+ * -+ * Items move from this list to periodic_sched_ready when the QH -+ * interval counter is 0 at SOF. -+ */ -+ struct list_head periodic_sched_inactive; -+ -+ /** -+ * List of periodic QHs that are ready for execution in the next -+ * frame, but have not yet been assigned to host channels. -+ * -+ * Items move from this list to periodic_sched_assigned as host -+ * channels become available during the current frame. -+ */ -+ struct list_head periodic_sched_ready; -+ -+ /** -+ * List of periodic QHs to be executed in the next frame that are -+ * assigned to host channels. -+ * -+ * Items move from this list to periodic_sched_queued as the -+ * transactions for the QH are queued to the DWC_otg controller. -+ */ -+ struct list_head periodic_sched_assigned; -+ -+ /** -+ * List of periodic QHs that have been queued for execution. -+ * -+ * Items move from this list to either periodic_sched_inactive or -+ * periodic_sched_ready when the channel associated with the transfer -+ * is released. If the interval for the QH is 1, the item moves to -+ * periodic_sched_ready because it must be rescheduled for the next -+ * frame. Otherwise, the item moves to periodic_sched_inactive. -+ */ -+ struct list_head periodic_sched_queued; -+ -+ /** -+ * Total bandwidth claimed so far for periodic transfers. This value -+ * is in microseconds per (micro)frame. The assumption is that all -+ * periodic transfers may occur in the same (micro)frame. -+ */ -+ uint16_t periodic_usecs; -+ -+ /** -+ * Frame number read from the core at SOF. The value ranges from 0 to -+ * DWC_HFNUM_MAX_FRNUM. -+ */ -+ uint16_t frame_number; -+ -+ /** -+ * Free host channels in the controller. This is a list of -+ * struct dwc_hc items. -+ */ -+ struct list_head free_hc_list; -+ -+ /** -+ * Number of host channels assigned to periodic transfers. Currently -+ * assuming that there is a dedicated host channel for each periodic -+ * transaction and at least one host channel available for -+ * non-periodic transactions. -+ */ -+ int periodic_channels; -+ -+ /** -+ * Number of host channels assigned to non-periodic transfers. -+ */ -+ int non_periodic_channels; -+ -+ /** -+ * Array of pointers to the host channel descriptors. Allows accessing -+ * a host channel descriptor given the host channel number. This is -+ * useful in interrupt handlers. -+ */ -+ struct dwc_hc *hc_ptr_array[MAX_EPS_CHANNELS]; -+ -+ /** -+ * Buffer to use for any data received during the status phase of a -+ * control transfer. Normally no data is transferred during the status -+ * phase. This buffer is used as a bit bucket. -+ */ -+ uint8_t *status_buf; -+ -+ /** -+ * DMA address for status_buf. -+ */ -+ dma_addr_t status_buf_dma; -+#define DWC_OTG_HCD_STATUS_BUF_SIZE 64 -+ -+ /** -+ * Structure to allow starting the HCD in a non-interrupt context -+ * during an OTG role change. -+ */ -+ struct work_struct start_work; -+ -+ /** -+ * Connection timer. An OTG host must display a message if the device -+ * does not connect. Started when the VBus power is turned on via -+ * sysfs attribute "buspower". -+ */ -+ struct timer_list conn_timer; -+ -+ /* Tasket to do a reset */ -+ struct tasklet_struct *reset_tasklet; -+ -+ struct hrtimer poll_rate_limit; -+ -+ spinlock_t global_lock; -+ -+#ifdef DEBUG -+ uint32_t frrem_samples; -+ uint64_t frrem_accum; -+ -+ uint32_t hfnum_7_samples_a; -+ uint64_t hfnum_7_frrem_accum_a; -+ uint32_t hfnum_0_samples_a; -+ uint64_t hfnum_0_frrem_accum_a; -+ uint32_t hfnum_other_samples_a; -+ uint64_t hfnum_other_frrem_accum_a; -+ -+ uint32_t hfnum_7_samples_b; -+ uint64_t hfnum_7_frrem_accum_b; -+ uint32_t hfnum_0_samples_b; -+ uint64_t hfnum_0_frrem_accum_b; -+ uint32_t hfnum_other_samples_b; -+ uint64_t hfnum_other_frrem_accum_b; -+#endif -+ -+}; -+ -+/** Gets the dwc_otg_hcd from a struct usb_hcd */ -+static inline struct dwc_otg_hcd *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd) -+{ -+ return (struct dwc_otg_hcd *)(hcd->hcd_priv); -+} -+ -+/** Gets the struct usb_hcd that contains a struct dwc_otg_hcd. */ -+static inline struct usb_hcd *dwc_otg_hcd_to_hcd(struct dwc_otg_hcd -+ *dwc_otg_hcd) -+{ -+ return container_of((void *)dwc_otg_hcd, struct usb_hcd, hcd_priv); -+} -+ -+/** @name HCD Create/Destroy Functions */ -+/** @{ */ -+extern int __init dwc_otg_hcd_init(struct device *_dev); -+extern void dwc_otg_hcd_remove(struct device *_dev); -+/** @} */ -+ -+/** @name Linux HC Driver API Functions */ -+ -+extern int dwc_otg_hcd_start(struct usb_hcd *hcd); -+extern void dwc_otg_hcd_stop(struct usb_hcd *hcd); -+extern int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd); -+extern void dwc_otg_hcd_free(struct usb_hcd *hcd); -+extern int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd, -+ struct urb *urb, unsigned mem_flags); -+extern int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd, -+ struct urb *urb, int status); -+extern void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd, -+ struct usb_host_endpoint *ep); -+extern irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd); -+extern int dwc_otg_hcd_hub_status_data(struct usb_hcd *hcd, char *buf); -+extern int dwc_otg_hcd_hub_control(struct usb_hcd *hcd, -+ u16 typeReq, -+ u16 wValue, -+ u16 wIndex, char *buf, u16 wLength); -+ -+ -+/** @name Transaction Execution Functions */ -+extern enum dwc_otg_transaction_type dwc_otg_hcd_select_transactions(struct -+ dwc_otg_hcd -+ *hcd); -+extern void dwc_otg_hcd_queue_transactions(struct dwc_otg_hcd *hcd, -+ enum dwc_otg_transaction_type tr_type); -+extern void dwc_otg_hcd_complete_urb(struct dwc_otg_hcd *hcd, struct urb *urb, -+ int status); -+ -+/** @name Interrupt Handler Functions */ -+extern int32_t dwc_otg_hcd_handle_intr(struct dwc_otg_hcd *dwc_otg_hcd); -+extern int32_t dwc_otg_hcd_handle_sof_intr(struct dwc_otg_hcd *dwc_otg_hcd); -+extern int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(struct dwc_otg_hcd -+ *dwc_otg_hcd); -+extern int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(struct dwc_otg_hcd -+ *dwc_otg_hcd); -+extern int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(struct dwc_otg_hcd -+ *dwc_otg_hcd); -+extern int32_t dwc_otg_hcd_handle_incomplete_periodic_intr(struct dwc_otg_hcd -+ *dwc_otg_hcd); -+extern int32_t dwc_otg_hcd_handle_port_intr(struct dwc_otg_hcd *dwc_otg_hcd); -+extern int32_t dwc_otg_hcd_handle_conn_id_status_change_intr(struct dwc_otg_hcd -+ *dwc_otg_hcd); -+extern int32_t dwc_otg_hcd_handle_disconnect_intr(struct dwc_otg_hcd -+ *dwc_otg_hcd); -+extern int32_t dwc_otg_hcd_handle_hc_intr(struct dwc_otg_hcd *dwc_otg_hcd); -+extern int32_t dwc_otg_hcd_handle_hc_n_intr(struct dwc_otg_hcd *dwc_otg_hcd, -+ uint32_t num); -+extern int32_t dwc_otg_hcd_handle_session_req_intr(struct dwc_otg_hcd -+ *dwc_otg_hcd); -+extern int32_t dwc_otg_hcd_handle_wakeup_detected_intr(struct dwc_otg_hcd -+ *dwc_otg_hcd); -+ -+/** @name Schedule Queue Functions */ -+ -+/* Implemented in dwc_otg_hcd_queue.c */ -+extern struct dwc_otg_qh *dwc_otg_hcd_qh_create(struct dwc_otg_hcd *hcd, -+ struct urb *urb); -+extern void dwc_otg_hcd_qh_init(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh, -+ struct urb *urb); -+extern void dwc_otg_hcd_qh_free(struct dwc_otg_qh *qh); -+extern int dwc_otg_hcd_qh_add(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh); -+extern void dwc_otg_hcd_qh_remove(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh); -+extern void dwc_otg_hcd_qh_deactivate(struct dwc_otg_hcd *hcd, -+ struct dwc_otg_qh *qh, int sched_csplit); -+ -+/** Remove and free a QH */ -+static inline void dwc_otg_hcd_qh_remove_and_free(struct dwc_otg_hcd *hcd, -+ struct dwc_otg_qh *qh) -+{ -+ dwc_otg_hcd_qh_remove(hcd, qh); -+ dwc_otg_hcd_qh_free(qh); -+} -+ -+/** Allocates memory for a QH structure. -+ * Returns Returns the memory allocate or NULL on error. */ -+static inline struct dwc_otg_qh *dwc_otg_hcd_qh_alloc(void) -+{ -+ return kmalloc(sizeof(struct dwc_otg_qh), GFP_ATOMIC); -+} -+ -+extern struct dwc_otg_qtd *dwc_otg_hcd_qtd_create(struct urb *urb); -+extern void dwc_otg_hcd_qtd_init(struct dwc_otg_qtd *qtd, struct urb *urb); -+extern int dwc_otg_hcd_qtd_add(struct dwc_otg_qtd *qtd, -+ struct dwc_otg_hcd *dwc_otg_hcd); -+ -+/** Allocates memory for a QTD structure. -+ * Returns Returns the memory allocate or NULL on error. */ -+static inline struct dwc_otg_qtd *dwc_otg_hcd_qtd_alloc(void) -+{ -+ return kmalloc(sizeof(struct dwc_otg_qtd), GFP_ATOMIC); -+} -+ -+/** -+ * Frees the memory for a QTD structure. QTD should already be removed from -+ * list. -+ * @qtd: QTD to free. -+ */ -+static inline void dwc_otg_hcd_qtd_free(struct dwc_otg_qtd *qtd) -+{ -+ kfree(qtd); -+} -+ -+/** -+ * Removes a QTD from list. -+ * @qtd: QTD to remove from list. -+ */ -+static inline void dwc_otg_hcd_qtd_remove(struct dwc_otg_qtd *qtd) -+{ -+ list_del(&qtd->qtd_list_entry); -+} -+ -+/** Remove and free a QTD */ -+static inline void dwc_otg_hcd_qtd_remove_and_free(struct dwc_otg_qtd *qtd) -+{ -+ dwc_otg_hcd_qtd_remove(qtd); -+ dwc_otg_hcd_qtd_free(qtd); -+} -+ -+/** @name Internal Functions */ -+struct dwc_otg_qh *dwc_urb_to_qh(struct urb *urb); -+void dwc_otg_hcd_dump_frrem(struct dwc_otg_hcd *hcd); -+void dwc_otg_hcd_dump_state(struct dwc_otg_hcd *hcd); -+ -+/** Gets the usb_host_endpoint associated with an URB. */ -+static inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb) -+{ -+ struct usb_device *dev = urb->dev; -+ int ep_num = usb_pipeendpoint(urb->pipe); -+ -+ if (usb_pipein(urb->pipe)) -+ return dev->ep_in[ep_num]; -+ else -+ return dev->ep_out[ep_num]; -+} -+ -+/* -+ * Gets the endpoint number from a bEndpointAddress argument. The endpoint is -+ * qualified with its direction (possible 32 endpoints per device). -+ */ -+#define dwc_ep_addr_to_endpoint(_bEndpointAddress_) \ -+ ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \ -+ ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4) -+ -+/** Gets the QH that contains the list_head */ -+#define dwc_list_to_qh(_list_head_ptr_) \ -+ (container_of(_list_head_ptr_, struct dwc_otg_qh, qh_list_entry)) -+ -+/** Gets the QTD that contains the list_head */ -+#define dwc_list_to_qtd(_list_head_ptr_) \ -+ (container_of(_list_head_ptr_, struct dwc_otg_qtd, qtd_list_entry)) -+ -+/** Check if QH is non-periodic */ -+#define dwc_qh_is_non_per(_qh_ptr_) \ -+ ((_qh_ptr_->ep_type == USB_ENDPOINT_XFER_BULK) || \ -+ (_qh_ptr_->ep_type == USB_ENDPOINT_XFER_CONTROL)) -+ -+/** High bandwidth multiplier as encoded in highspeed endpoint descriptors */ -+#define dwc_hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) -+ -+/** Packet size for any kind of endpoint descriptor */ -+#define dwc_max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) -+ -+/** -+ * Returns true if frame1 is less than or equal to frame2. The comparison is -+ * done modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the -+ * frame number when the max frame number is reached. -+ */ -+static inline int dwc_frame_num_le(uint16_t frame1, uint16_t frame2) -+{ -+ return ((frame2 - frame1) & DWC_HFNUM_MAX_FRNUM) <= -+ (DWC_HFNUM_MAX_FRNUM >> 1); -+} -+ -+/** -+ * Returns true if frame1 is greater than frame2. The comparison is done -+ * modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the frame -+ * number when the max frame number is reached. -+ */ -+static inline int dwc_frame_num_gt(uint16_t frame1, uint16_t frame2) -+{ -+ return (frame1 != frame2) && -+ (((frame1 - frame2) & DWC_HFNUM_MAX_FRNUM) < -+ (DWC_HFNUM_MAX_FRNUM >> 1)); -+} -+ -+/** -+ * Increments frame by the amount specified by inc. The addition is done -+ * modulo DWC_HFNUM_MAX_FRNUM. Returns the incremented value. -+ */ -+static inline uint16_t dwc_frame_num_inc(uint16_t frame, uint16_t inc) -+{ -+ return (frame + inc) & DWC_HFNUM_MAX_FRNUM; -+} -+ -+static inline uint16_t dwc_full_frame_num(uint16_t frame) -+{ -+ return (frame & DWC_HFNUM_MAX_FRNUM) >> 3; -+} -+ -+static inline uint16_t dwc_micro_frame_num(uint16_t frame) -+{ -+ return frame & 0x7; -+} -+ -+#ifdef DEBUG -+/** -+ * Macro to sample the remaining PHY clocks left in the current frame. This -+ * may be used during debugging to determine the average time it takes to -+ * execute sections of code. There are two possible sample points, "a" and -+ * "b", so the letter argument must be one of these values. -+ * -+ * To dump the average sample times, read the "hcd_frrem" sysfs attribute. For -+ * example, "cat /sys/devices/lm0/hcd_frrem". -+ */ -+#define dwc_sample_frrem(_hcd, _qh, _letter) \ -+{ \ -+ union hfnum_data hfnum; \ -+ struct dwc_otg_qtd *qtd; \ -+ qtd = list_entry(_qh->qtd_list.next, struct dwc_otg_qtd, qtd_list_entry); \ -+ if (usb_pipeint(qtd->urb->pipe) && qh->start_split_frame != 0 && !qtd->complete_split) { \ -+ hfnum.d32 = dwc_read_reg32(&_hcd->core_if->host_if->host_global_regs->hfnum); \ -+ switch (hfnum.b.frnum & 0x7) { \ -+ case 7: \ -+ _hcd->hfnum_7_samples_##_letter++; \ -+ _hcd->hfnum_7_frrem_accum_##_letter += hfnum.b.frrem; \ -+ break; \ -+ case 0: \ -+ _hcd->hfnum_0_samples_##_letter++; \ -+ _hcd->hfnum_0_frrem_accum_##_letter += hfnum.b.frrem; \ -+ break; \ -+ default: \ -+ _hcd->hfnum_other_samples_##_letter++; \ -+ _hcd->hfnum_other_frrem_accum_##_letter += \ -+ hfnum.b.frrem; \ -+ break; \ -+ } \ -+ } \ -+} -+#else -+#define dwc_sample_frrem(hcd, qh, letter) -+#endif -+#endif -+#endif /* DWC_DEVICE_ONLY */ -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -new file mode 100644 -index 0000000..2c4266f ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -0,0 +1,1890 @@ -+/* ========================================================================== -+ * -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+#ifndef DWC_DEVICE_ONLY -+ -+#include "dwc_otg_driver.h" -+#include "dwc_otg_hcd.h" -+#include "dwc_otg_regs.h" -+ -+/* -+ * This file contains the implementation of the HCD Interrupt handlers. -+ */ -+ -+/* This function handles interrupts for the HCD. */ -+int32_t dwc_otg_hcd_handle_intr(struct dwc_otg_hcd *dwc_otg_hcd) -+{ -+ int retval = 0; -+ -+ struct dwc_otg_core_if *core_if = dwc_otg_hcd->core_if; -+ union gintsts_data gintsts; -+#ifdef DEBUG -+ struct dwc_otg_core_global_regs *global_regs = -+ core_if->core_global_regs; -+#endif -+ -+ /* Check if HOST Mode */ -+ if (dwc_otg_is_host_mode(core_if)) { -+ gintsts.d32 = dwc_otg_read_core_intr(core_if); -+ if (!gintsts.d32) -+ return 0; -+#ifdef DEBUG -+ /* Don't print debug message in the interrupt handler on SOF */ -+# ifndef DEBUG_SOF -+ if (gintsts.d32 != DWC_SOF_INTR_MASK) -+# endif -+ DWC_DEBUGPL(DBG_HCD, "\n"); -+#endif -+ -+#ifdef DEBUG -+# ifndef DEBUG_SOF -+ if (gintsts.d32 != DWC_SOF_INTR_MASK) -+# endif -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Interrupt Detected " -+ "gintsts&gintmsk=0x%08x\n", -+ gintsts.d32); -+#endif -+ -+ if (gintsts.b.sofintr) -+ retval |= dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd); -+ -+ if (gintsts.b.rxstsqlvl) -+ retval |= -+ dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd); -+ -+ if (gintsts.b.nptxfempty) -+ retval |= -+ dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd); -+ -+ if (gintsts.b.i2cintr) -+ ;/** @todo Implement i2cintr handler. */ -+ -+ if (gintsts.b.portintr) -+ retval |= dwc_otg_hcd_handle_port_intr(dwc_otg_hcd); -+ -+ if (gintsts.b.hcintr) -+ retval |= dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd); -+ -+ if (gintsts.b.ptxfempty) { -+ retval |= -+ dwc_otg_hcd_handle_perio_tx_fifo_empty_intr -+ (dwc_otg_hcd); -+ } -+#ifdef DEBUG -+# ifndef DEBUG_SOF -+ if (gintsts.d32 != DWC_SOF_INTR_MASK) -+# endif -+ { -+ DWC_DEBUGPL(DBG_HCD, -+ "DWC OTG HCD Finished Servicing Interrupts\n"); -+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintsts=0x%08x\n", -+ dwc_read_reg32(&global_regs->gintsts)); -+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD gintmsk=0x%08x\n", -+ dwc_read_reg32(&global_regs->gintmsk)); -+ } -+#endif -+ -+#ifdef DEBUG -+# ifndef DEBUG_SOF -+ if (gintsts.d32 != DWC_SOF_INTR_MASK) -+# endif -+ DWC_DEBUGPL(DBG_HCD, "\n"); -+#endif -+ -+ } -+ -+ return retval; -+} -+ -+#ifdef DWC_TRACK_MISSED_SOFS -+#warning Compiling code to track missed SOFs -+#define FRAME_NUM_ARRAY_SIZE 1000 -+/** -+ * This function is for debug only. -+ */ -+static inline void track_missed_sofs(uint16_t _curr_frame_number) -+{ -+ static uint16_t frame_num_array[FRAME_NUM_ARRAY_SIZE]; -+ static uint16_t last_frame_num_array[FRAME_NUM_ARRAY_SIZE]; -+ static int frame_num_idx; -+ static uint16_t last_frame_num = DWC_HFNUM_MAX_FRNUM; -+ static int dumped_frame_num_array; -+ -+ if (frame_num_idx < FRAME_NUM_ARRAY_SIZE) { -+ if ((((last_frame_num + 1) & DWC_HFNUM_MAX_FRNUM) != -+ _curr_frame_number)) { -+ frame_num_array[frame_num_idx] = _curr_frame_number; -+ last_frame_num_array[frame_num_idx++] = last_frame_num; -+ } -+ } else if (!dumped_frame_num_array) { -+ int i; -+ printk(KERN_EMERG USB_DWC "Frame Last Frame\n"); -+ printk(KERN_EMERG USB_DWC "----- ----------\n"); -+ for (i = 0; i < FRAME_NUM_ARRAY_SIZE; i++) { -+ printk(KERN_EMERG USB_DWC "0x%04x 0x%04x\n", -+ frame_num_array[i], last_frame_num_array[i]); -+ } -+ dumped_frame_num_array = 1; -+ } -+ last_frame_num = _curr_frame_number; -+} -+#endif -+ -+/** -+ * Handles the start-of-frame interrupt in host mode. Non-periodic -+ * transactions may be queued to the DWC_otg controller for the current -+ * (micro)frame. Periodic transactions may be queued to the controller for the -+ * next (micro)frame. -+ */ -+int32_t dwc_otg_hcd_handle_sof_intr(struct dwc_otg_hcd *hcd) -+{ -+ union hfnum_data hfnum; -+ struct list_head *qh_entry; -+ struct dwc_otg_qh *qh; -+ enum dwc_otg_transaction_type tr_type; -+ union gintsts_data gintsts = {.d32 = 0 }; -+ -+ hfnum.d32 = -+ dwc_read_reg32(&hcd->core_if->host_if->host_global_regs->hfnum); -+ -+#ifdef DEBUG_SOF -+ DWC_DEBUGPL(DBG_HCD, "--Start of Frame Interrupt--\n"); -+#endif -+ -+ hcd->frame_number = hfnum.b.frnum; -+ -+#ifdef DEBUG -+ hcd->frrem_accum += hfnum.b.frrem; -+ hcd->frrem_samples++; -+#endif -+ -+#ifdef DWC_TRACK_MISSED_SOFS -+ track_missed_sofs(hcd->frame_number); -+#endif -+ -+ /* Determine whether any periodic QHs should be executed. */ -+ qh_entry = hcd->periodic_sched_inactive.next; -+ while (qh_entry != &hcd->periodic_sched_inactive) { -+ qh = list_entry(qh_entry, struct dwc_otg_qh, qh_list_entry); -+ qh_entry = qh_entry->next; -+ if (dwc_frame_num_le(qh->sched_frame, hcd->frame_number)) { -+ /* -+ * Move QH to the ready list to be executed next -+ * (micro)frame. -+ */ -+ list_move(&qh->qh_list_entry, -+ &hcd->periodic_sched_ready); -+ } -+ } -+ -+ tr_type = dwc_otg_hcd_select_transactions(hcd); -+ if (tr_type != DWC_OTG_TRANSACTION_NONE) { -+ dwc_otg_hcd_queue_transactions(hcd, tr_type); -+ } else if (list_empty(&hcd->periodic_sched_inactive) && -+ list_empty(&hcd->periodic_sched_ready) && -+ list_empty(&hcd->periodic_sched_assigned) && -+ list_empty(&hcd->periodic_sched_queued)) { -+ /* -+ * We don't have USB data to send. Unfortunately the -+ * Synopsis block continues to generate interrupts at -+ * about 8k/sec. In order not waste time on these -+ * useless interrupts, we're going to disable the SOF -+ * interrupt. It will be re-enabled when a new packet -+ * is enqueued in dwc_otg_hcd_urb_enqueue() -+ */ -+ dwc_modify_reg32(&hcd->core_if->core_global_regs->gintmsk, -+ DWC_SOF_INTR_MASK, 0); -+ } -+ -+ /* Clear interrupt */ -+ gintsts.b.sofintr = 1; -+ dwc_write_reg32(&hcd->core_if->core_global_regs->gintsts, gintsts.d32); -+ -+ return 1; -+} -+ -+/* Handles the Rx Status Queue Level Interrupt, which indicates that -+ * there is at least one packet in the Rx FIFO. The packets are moved -+ * from the FIFO to memory if the DWC_otg controller is operating in -+ * Slave mode. */ -+int32_t -+dwc_otg_hcd_handle_rx_status_q_level_intr(struct dwc_otg_hcd *dwc_otg_hcd) -+{ -+ union host_grxsts_data grxsts; -+ struct dwc_hc *hc = NULL; -+ -+ DWC_DEBUGPL(DBG_HCD, "--RxStsQ Level Interrupt--\n"); -+ -+ grxsts.d32 = -+ dwc_read_reg32(&dwc_otg_hcd->core_if->core_global_regs->grxstsp); -+ -+ hc = dwc_otg_hcd->hc_ptr_array[grxsts.b.chnum]; -+ -+ /* Packet Status */ -+ DWC_DEBUGPL(DBG_HCDV, " Ch num = %d\n", grxsts.b.chnum); -+ DWC_DEBUGPL(DBG_HCDV, " Count = %d\n", grxsts.b.bcnt); -+ DWC_DEBUGPL(DBG_HCDV, " DPID = %d, hc.dpid = %d\n", grxsts.b.dpid, -+ hc->data_pid_start); -+ DWC_DEBUGPL(DBG_HCDV, " PStatus = %d\n", grxsts.b.pktsts); -+ -+ switch (grxsts.b.pktsts) { -+ case DWC_GRXSTS_PKTSTS_IN: -+ /* Read the data into the host buffer. */ -+ if (grxsts.b.bcnt > 0) { -+ dwc_otg_read_packet(dwc_otg_hcd->core_if, -+ hc->xfer_buff, grxsts.b.bcnt); -+ -+ /* Update the HC fields for the next packet received. */ -+ hc->xfer_count += grxsts.b.bcnt; -+ hc->xfer_buff += grxsts.b.bcnt; -+ } -+ -+ case DWC_GRXSTS_PKTSTS_IN_XFER_COMP: -+ case DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR: -+ case DWC_GRXSTS_PKTSTS_CH_HALTED: -+ /* Handled in interrupt, just ignore data */ -+ break; -+ default: -+ DWC_ERROR("RX_STS_Q Interrupt: Unknown status %d\n", -+ grxsts.b.pktsts); -+ break; -+ } -+ -+ return 1; -+} -+ -+/* This interrupt occurs when the non-periodic Tx FIFO is -+ * half-empty. More data packets may be written to the FIFO for OUT -+ * transfers. More requests may be written to the non-periodic request -+ * queue for IN transfers. This interrupt is enabled only in Slave -+ * mode. */ -+int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(struct dwc_otg_hcd * -+ dwc_otg_hcd) -+{ -+ DWC_DEBUGPL(DBG_HCD, "--Non-Periodic TxFIFO Empty Interrupt--\n"); -+ dwc_otg_hcd_queue_transactions(dwc_otg_hcd, -+ DWC_OTG_TRANSACTION_NON_PERIODIC); -+ return 1; -+} -+ -+/* This interrupt occurs when the periodic Tx FIFO is half-empty. More -+ * data packets may be written to the FIFO for OUT transfers. More -+ * requests may be written to the periodic request queue for IN -+ * transfers. This interrupt is enabled only in Slave mode. */ -+int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(struct dwc_otg_hcd * -+ dwc_otg_hcd) -+{ -+ DWC_DEBUGPL(DBG_HCD, "--Periodic TxFIFO Empty Interrupt--\n"); -+ dwc_otg_hcd_queue_transactions(dwc_otg_hcd, -+ DWC_OTG_TRANSACTION_PERIODIC); -+ return 1; -+} -+ -+/* There are multiple conditions that can cause a port interrupt. This -+ * function determines which interrupt conditions have occurred and -+ * handles them appropriately. */ -+int32_t dwc_otg_hcd_handle_port_intr(struct dwc_otg_hcd *dwc_otg_hcd) -+{ -+ int retval = 0; -+ union hprt0_data hprt0; -+ union hprt0_data hprt0_modify; -+ -+ hprt0.d32 = dwc_read_reg32(dwc_otg_hcd->core_if->host_if->hprt0); -+ hprt0_modify.d32 = -+ dwc_read_reg32(dwc_otg_hcd->core_if->host_if->hprt0); -+ -+ /* Clear appropriate bits in HPRT0 to clear the interrupt bit in -+ * GINTSTS */ -+ -+ hprt0_modify.b.prtena = 0; -+ hprt0_modify.b.prtconndet = 0; -+ hprt0_modify.b.prtenchng = 0; -+ hprt0_modify.b.prtovrcurrchng = 0; -+ -+ /* Port Connect Detected -+ * Set flag and clear if detected */ -+ if (hprt0.b.prtconndet) { -+ DWC_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x " -+ "Port Connect Detected--\n", hprt0.d32); -+ dwc_otg_hcd->flags.b.port_connect_status_change = 1; -+ dwc_otg_hcd->flags.b.port_connect_status = 1; -+ hprt0_modify.b.prtconndet = 1; -+ -+ /* B-Device has connected, Delete the connection timer. */ -+ del_timer(&dwc_otg_hcd->conn_timer); -+ -+ /* The Hub driver asserts a reset when it sees port connect -+ * status change flag */ -+ retval |= 1; -+ } -+ -+ /* Port Enable Changed -+ * Clear if detected - Set internal flag if disabled */ -+ if (hprt0.b.prtenchng) { -+ DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x " -+ "Port Enable Changed--\n", hprt0.d32); -+ hprt0_modify.b.prtenchng = 1; -+ if (hprt0.b.prtena == 1) { -+ int do_reset = 0; -+ struct dwc_otg_core_params *params = -+ dwc_otg_hcd->core_if->core_params; -+ struct dwc_otg_core_global_regs *global_regs = -+ dwc_otg_hcd->core_if->core_global_regs; -+ struct dwc_otg_host_if *host_if = -+ dwc_otg_hcd->core_if->host_if; -+ -+ /* Check if we need to adjust the PHY clock speed for -+ * low power and adjust it */ -+ if (params->host_support_fs_ls_low_power) { -+ union gusbcfg_data usbcfg; -+ -+ usbcfg.d32 = -+ dwc_read_reg32(&global_regs->gusbcfg); -+ -+ if ((hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED) -+ || (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_FULL_SPEED)) { -+ /* -+ * Low power -+ */ -+ union hcfg_data hcfg; -+ if (usbcfg.b.phylpwrclksel == 0) { -+ /* Set PHY low power clock select for FS/LS devices */ -+ usbcfg.b.phylpwrclksel = 1; -+ dwc_write_reg32(&global_regs->gusbcfg, -+ usbcfg.d32); -+ do_reset = 1; -+ } -+ -+ hcfg.d32 = -+ dwc_read_reg32(&host_if->host_global_regs->hcfg); -+ -+ if ((hprt0.b.prtspd == -+ DWC_HPRT0_PRTSPD_LOW_SPEED) -+ && (params-> -+ host_ls_low_power_phy_clk == -+ DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ)) { -+ /* 6 MHZ */ -+ DWC_DEBUGPL(DBG_CIL, -+ "FS_PHY programming HCFG to 6 MHz (Low Power)\n"); -+ if (hcfg.b.fslspclksel != -+ DWC_HCFG_6_MHZ) { -+ hcfg.b.fslspclksel = -+ DWC_HCFG_6_MHZ; -+ dwc_write_reg32(&host_if->host_global_regs->hcfg, -+ hcfg.d32); -+ do_reset = 1; -+ } -+ } else { -+ /* 48 MHZ */ -+ DWC_DEBUGPL(DBG_CIL, -+ "FS_PHY programming HCFG to 48 MHz ()\n"); -+ if (hcfg.b.fslspclksel != -+ DWC_HCFG_48_MHZ) { -+ hcfg.b.fslspclksel = DWC_HCFG_48_MHZ; -+ dwc_write_reg32(&host_if->host_global_regs->hcfg, -+ hcfg.d32); -+ do_reset = 1; -+ } -+ } -+ } else { -+ /* -+ * Not low power -+ */ -+ if (usbcfg.b.phylpwrclksel == 1) { -+ usbcfg.b.phylpwrclksel = 0; -+ dwc_write_reg32(&global_regs->gusbcfg, -+ usbcfg.d32); -+ do_reset = 1; -+ } -+ } -+ if (do_reset) -+ tasklet_schedule(dwc_otg_hcd->reset_tasklet); -+ } -+ if (!do_reset) -+ /* -+ * Port has been enabled set the reset -+ * change flag -+ */ -+ dwc_otg_hcd->flags.b.port_reset_change = 1; -+ } else { -+ dwc_otg_hcd->flags.b.port_enable_change = 1; -+ } -+ retval |= 1; -+ } -+ -+ /** Overcurrent Change Interrupt */ -+ if (hprt0.b.prtovrcurrchng) { -+ DWC_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x " -+ "Port Overcurrent Changed--\n", hprt0.d32); -+ dwc_otg_hcd->flags.b.port_over_current_change = 1; -+ hprt0_modify.b.prtovrcurrchng = 1; -+ retval |= 1; -+ } -+ -+ /* Clear Port Interrupts */ -+ dwc_write_reg32(dwc_otg_hcd->core_if->host_if->hprt0, -+ hprt0_modify.d32); -+ -+ return retval; -+} -+ -+/** This interrupt indicates that one or more host channels has a pending -+ * interrupt. There are multiple conditions that can cause each host channel -+ * interrupt. This function determines which conditions have occurred for each -+ * host channel interrupt and handles them appropriately. */ -+int32_t dwc_otg_hcd_handle_hc_intr(struct dwc_otg_hcd *dwc_otg_hcd) -+{ -+ int i; -+ int retval = 0; -+ union haint_data haint; -+ -+ /* Clear appropriate bits in HCINTn to clear the interrupt bit in -+ * GINTSTS */ -+ -+ haint.d32 = dwc_otg_read_host_all_channels_intr(dwc_otg_hcd->core_if); -+ -+ for (i = 0; i < dwc_otg_hcd->core_if->core_params->host_channels; i++) { -+ if (haint.b2.chint & (1 << i)) -+ retval |= dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd, i); -+ } -+ -+ return retval; -+} -+ -+/* Macro used to clear one channel interrupt */ -+#define clear_hc_int(_hc_regs_, _intr_) \ -+do { \ -+ union hcint_data hcint_clear = {.d32 = 0}; \ -+ hcint_clear.b._intr_ = 1; \ -+ dwc_write_reg32(&((_hc_regs_)->hcint), hcint_clear.d32); \ -+} while (0) -+ -+/* -+ * Macro used to disable one channel interrupt. Channel interrupts are -+ * disabled when the channel is halted or released by the interrupt handler. -+ * There is no need to handle further interrupts of that type until the -+ * channel is re-assigned. In fact, subsequent handling may cause crashes -+ * because the channel structures are cleaned up when the channel is released. -+ */ -+#define disable_hc_int(_hc_regs_, _intr_) \ -+ do { \ -+ union hcintmsk_data hcintmsk = {.d32 = 0}; \ -+ hcintmsk.b._intr_ = 1; \ -+ dwc_modify_reg32(&((_hc_regs_)->hcintmsk), hcintmsk.d32, 0); \ -+ } while (0) -+ -+/** -+ * Gets the actual length of a transfer after the transfer halts. _halt_status -+ * holds the reason for the halt. -+ * -+ * For IN transfers where _halt_status is DWC_OTG_HC_XFER_COMPLETE, -+ * *_short_read is set to 1 upon return if less than the requested -+ * number of bytes were transferred. Otherwise, *_short_read is set to 0 upon -+ * return. _short_read may also be NULL on entry, in which case it remains -+ * unchanged. -+ */ -+static uint32_t get_actual_xfer_length(struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd, -+ enum dwc_otg_halt_status _halt_status, -+ int *_short_read) -+{ -+ union hctsiz_data hctsiz; -+ uint32_t length; -+ -+ if (_short_read != NULL) -+ *_short_read = 0; -+ -+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz); -+ -+ if (_halt_status == DWC_OTG_HC_XFER_COMPLETE) { -+ if (hc->ep_is_in) { -+ length = hc->xfer_len - hctsiz.b.xfersize; -+ if (_short_read != NULL) -+ *_short_read = (hctsiz.b.xfersize != 0); -+ } else if (hc->qh->do_split) { -+ length = qtd->ssplit_out_xfer_count; -+ } else { -+ length = hc->xfer_len; -+ } -+ } else { -+ /* -+ * Must use the hctsiz.pktcnt field to determine how much data -+ * has been transferred. This field reflects the number of -+ * packets that have been transferred via the USB. This is -+ * always an integral number of packets if the transfer was -+ * halted before its normal completion. (Can't use the -+ * hctsiz.xfersize field because that reflects the number of -+ * bytes transferred via the AHB, not the USB). -+ */ -+ length = -+ (hc->start_pkt_count - hctsiz.b.pktcnt) * hc->max_packet; -+ } -+ -+ return length; -+} -+ -+/** -+ * Updates the state of the URB after a Transfer Complete interrupt on the -+ * host channel. Updates the actual_length field of the URB based on the -+ * number of bytes transferred via the host channel. Sets the URB status -+ * if the data transfer is finished. -+ * -+ * Returns 1 if the data transfer specified by the URB is completely finished, -+ * 0 otherwise. -+ */ -+static int update_urb_state_xfer_comp(struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct urb *urb, struct dwc_otg_qtd *qtd) -+{ -+ int xfer_done = 0; -+ int short_read = 0; -+ -+ urb->actual_length += get_actual_xfer_length(hc, hc_regs, qtd, -+ DWC_OTG_HC_XFER_COMPLETE, -+ &short_read); -+ -+ if (short_read || (urb->actual_length == urb->transfer_buffer_length)) { -+ xfer_done = 1; -+ if (short_read && (urb->transfer_flags & URB_SHORT_NOT_OK)) -+ urb->status = -EREMOTEIO; -+ else -+ urb->status = 0; -+ } -+#ifdef DEBUG -+ { -+ union hctsiz_data hctsiz; -+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz); -+ DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n", -+ __func__, (hc->ep_is_in ? "IN" : "OUT"), -+ hc->hc_num); -+ DWC_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", hc->xfer_len); -+ DWC_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n", -+ hctsiz.b.xfersize); -+ DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n", -+ urb->transfer_buffer_length); -+ DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", -+ urb->actual_length); -+ DWC_DEBUGPL(DBG_HCDV, " short_read %d, xfer_done %d\n", -+ short_read, xfer_done); -+ } -+#endif -+ -+ return xfer_done; -+} -+ -+/* -+ * Save the starting data toggle for the next transfer. The data toggle is -+ * saved in the QH for non-control transfers and it's saved in the QTD for -+ * control transfers. -+ */ -+static void save_data_toggle(struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ union hctsiz_data hctsiz; -+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz); -+ -+ if (hc->ep_type != DWC_OTG_EP_TYPE_CONTROL) { -+ struct dwc_otg_qh *qh = hc->qh; -+ if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) -+ qh->data_toggle = DWC_OTG_HC_PID_DATA0; -+ else -+ qh->data_toggle = DWC_OTG_HC_PID_DATA1; -+ } else { -+ if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) -+ qtd->data_toggle = DWC_OTG_HC_PID_DATA0; -+ else -+ qtd->data_toggle = DWC_OTG_HC_PID_DATA1; -+ } -+} -+ -+/** -+ * Frees the first QTD in the QH's list if free_qtd is 1. For non-periodic -+ * QHs, removes the QH from the active non-periodic schedule. If any QTDs are -+ * still linked to the QH, the QH is added to the end of the inactive -+ * non-periodic schedule. For periodic QHs, removes the QH from the periodic -+ * schedule if no more QTDs are linked to the QH. -+ */ -+static void deactivate_qh(struct dwc_otg_hcd *hcd, -+ struct dwc_otg_qh *qh, int free_qtd) -+{ -+ int continue_split = 0; -+ struct dwc_otg_qtd *qtd; -+ -+ DWC_DEBUGPL(DBG_HCDV, " %s(%p,%p,%d)\n", __func__, hcd, qh, free_qtd); -+ -+ qtd = list_entry(qh->qtd_list.next, struct dwc_otg_qtd, qtd_list_entry); -+ -+ if (qtd->complete_split) { -+ continue_split = 1; -+ } else if ((qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_MID) || -+ (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_END)) { -+ continue_split = 1; -+ } -+ -+ if (free_qtd) { -+ dwc_otg_hcd_qtd_remove_and_free(qtd); -+ continue_split = 0; -+ } -+ -+ qh->channel = NULL; -+ qh->qtd_in_process = NULL; -+ dwc_otg_hcd_qh_deactivate(hcd, qh, continue_split); -+} -+ -+/** -+ * Updates the state of an Isochronous URB when the transfer is stopped for -+ * any reason. The fields of the current entry in the frame descriptor array -+ * are set based on the transfer state and the input _halt_status. Completes -+ * the Isochronous URB if all the URB frames have been completed. -+ * -+ * Returns DWC_OTG_HC_XFER_COMPLETE if there are more frames remaining to be -+ * transferred in the URB. Otherwise return DWC_OTG_HC_XFER_URB_COMPLETE. -+ */ -+static enum dwc_otg_halt_status -+update_isoc_urb_state(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd, -+ enum dwc_otg_halt_status halt_status) -+{ -+ struct urb *urb = qtd->urb; -+ enum dwc_otg_halt_status ret_val = halt_status; -+ struct usb_iso_packet_descriptor *frame_desc; -+ -+ frame_desc = &urb->iso_frame_desc[qtd->isoc_frame_index]; -+ switch (halt_status) { -+ case DWC_OTG_HC_XFER_COMPLETE: -+ frame_desc->status = 0; -+ frame_desc->actual_length = -+ get_actual_xfer_length(hc, hc_regs, qtd, -+ halt_status, NULL); -+ break; -+ case DWC_OTG_HC_XFER_FRAME_OVERRUN: -+ urb->error_count++; -+ if (hc->ep_is_in) -+ frame_desc->status = -ENOSR; -+ else -+ frame_desc->status = -ECOMM; -+ frame_desc->actual_length = 0; -+ break; -+ case DWC_OTG_HC_XFER_BABBLE_ERR: -+ urb->error_count++; -+ frame_desc->status = -EOVERFLOW; -+ /* Don't need to update actual_length in this case. */ -+ break; -+ case DWC_OTG_HC_XFER_XACT_ERR: -+ urb->error_count++; -+ frame_desc->status = -EPROTO; -+ frame_desc->actual_length = -+ get_actual_xfer_length(hc, hc_regs, qtd, -+ halt_status, NULL); -+ break; -+ default: -+ DWC_ERROR("%s: Unhandled halt_status (%d)\n", __func__, -+ halt_status); -+ BUG(); -+ break; -+ } -+ -+ if (++qtd->isoc_frame_index == urb->number_of_packets) { -+ /* -+ * urb->status is not used for isoc transfers. -+ * The individual frame_desc statuses are used instead. -+ */ -+ dwc_otg_hcd_complete_urb(hcd, urb, 0); -+ qtd->urb = NULL; -+ ret_val = DWC_OTG_HC_XFER_URB_COMPLETE; -+ } else { -+ ret_val = DWC_OTG_HC_XFER_COMPLETE; -+ } -+ -+ return ret_val; -+} -+ -+/** -+ * Releases a host channel for use by other transfers. Attempts to select and -+ * queue more transactions since at least one host channel is available. -+ * -+ * @hcd: The HCD state structure. -+ * @hc: The host channel to release. -+ * @qtd: The QTD associated with the host channel. This QTD may be freed -+ * if the transfer is complete or an error has occurred. -+ * @_halt_status: Reason the channel is being released. This status -+ * determines the actions taken by this function. -+ */ -+static void release_channel(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_qtd *qtd, -+ enum dwc_otg_halt_status halt_status) -+{ -+ enum dwc_otg_transaction_type tr_type; -+ int free_qtd; -+ -+ DWC_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n", -+ __func__, hc->hc_num, halt_status); -+ -+ switch (halt_status) { -+ case DWC_OTG_HC_XFER_URB_COMPLETE: -+ free_qtd = 1; -+ break; -+ case DWC_OTG_HC_XFER_AHB_ERR: -+ case DWC_OTG_HC_XFER_STALL: -+ case DWC_OTG_HC_XFER_BABBLE_ERR: -+ free_qtd = 1; -+ break; -+ case DWC_OTG_HC_XFER_XACT_ERR: -+ if (qtd->error_count >= 3) { -+ DWC_DEBUGPL(DBG_HCDV, -+ " Complete URB with transaction error\n"); -+ free_qtd = 1; -+ qtd->urb->status = -EPROTO; -+ dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EPROTO); -+ qtd->urb = NULL; -+ } else { -+ free_qtd = 0; -+ } -+ break; -+ case DWC_OTG_HC_XFER_URB_DEQUEUE: -+ /* -+ * The QTD has already been removed and the QH has been -+ * deactivated. Don't want to do anything except release the -+ * host channel and try to queue more transfers. -+ */ -+ goto cleanup; -+ case DWC_OTG_HC_XFER_NO_HALT_STATUS: -+ DWC_ERROR("%s: No halt_status, channel %d\n", __func__, -+ hc->hc_num); -+ free_qtd = 0; -+ break; -+ default: -+ free_qtd = 0; -+ break; -+ } -+ -+ deactivate_qh(hcd, hc->qh, free_qtd); -+ -+cleanup: -+ /* -+ * Release the host channel for use by other transfers. The cleanup -+ * function clears the channel interrupt enables and conditions, so -+ * there's no need to clear the Channel Halted interrupt separately. -+ */ -+ dwc_otg_hc_cleanup(hcd->core_if, hc); -+ list_add_tail(&hc->hc_list_entry, &hcd->free_hc_list); -+ -+ switch (hc->ep_type) { -+ case DWC_OTG_EP_TYPE_CONTROL: -+ case DWC_OTG_EP_TYPE_BULK: -+ hcd->non_periodic_channels--; -+ break; -+ -+ default: -+ /* -+ * Don't release reservations for periodic channels here. -+ * That's done when a periodic transfer is descheduled (i.e. -+ * when the QH is removed from the periodic schedule). -+ */ -+ break; -+ } -+ -+ /* Try to queue more transfers now that there's a free channel. */ -+ tr_type = dwc_otg_hcd_select_transactions(hcd); -+ if (tr_type != DWC_OTG_TRANSACTION_NONE) -+ dwc_otg_hcd_queue_transactions(hcd, tr_type); -+} -+ -+/** -+ * Halts a host channel. If the channel cannot be halted immediately because -+ * the request queue is full, this function ensures that the FIFO empty -+ * interrupt for the appropriate queue is enabled so that the halt request can -+ * be queued when there is space in the request queue. -+ * -+ * This function may also be called in DMA mode. In that case, the channel is -+ * simply released since the core always halts the channel automatically in -+ * DMA mode. -+ */ -+static void halt_channel(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_qtd *qtd, -+ enum dwc_otg_halt_status halt_status) -+{ -+ if (hcd->core_if->dma_enable) { -+ release_channel(hcd, hc, qtd, halt_status); -+ return; -+ } -+ -+ /* Slave mode processing... */ -+ dwc_otg_hc_halt(hcd->core_if, hc, halt_status); -+ -+ if (hc->halt_on_queue) { -+ union gintmsk_data gintmsk = {.d32 = 0 }; -+ struct dwc_otg_core_global_regs *global_regs; -+ global_regs = hcd->core_if->core_global_regs; -+ -+ if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL || -+ hc->ep_type == DWC_OTG_EP_TYPE_BULK) { -+ /* -+ * Make sure the Non-periodic Tx FIFO empty interrupt -+ * is enabled so that the non-periodic schedule will -+ * be processed. -+ */ -+ gintmsk.b.nptxfempty = 1; -+ dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32); -+ } else { -+ /* -+ * Move the QH from the periodic queued schedule to -+ * the periodic assigned schedule. This allows the -+ * halt to be queued when the periodic schedule is -+ * processed. -+ */ -+ list_move(&hc->qh->qh_list_entry, -+ &hcd->periodic_sched_assigned); -+ -+ /* -+ * Make sure the Periodic Tx FIFO Empty interrupt is -+ * enabled so that the periodic schedule will be -+ * processed. -+ */ -+ gintmsk.b.ptxfempty = 1; -+ dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32); -+ } -+ } -+} -+ -+/** -+ * Performs common cleanup for non-periodic transfers after a Transfer -+ * Complete interrupt. This function should be called after any endpoint type -+ * specific handling is finished to release the host channel. -+ */ -+static void complete_non_periodic_xfer(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd, -+ enum dwc_otg_halt_status halt_status) -+{ -+ union hcint_data hcint; -+ -+ qtd->error_count = 0; -+ -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ if (hcint.b.nyet) { -+ /* -+ * Got a NYET on the last transaction of the transfer. This -+ * means that the endpoint should be in the PING state at the -+ * beginning of the next transfer. -+ */ -+ hc->qh->ping_state = 1; -+ clear_hc_int(hc_regs, nyet); -+ } -+ -+ /* -+ * Always halt and release the host channel to make it available for -+ * more transfers. There may still be more phases for a control -+ * transfer or more data packets for a bulk transfer at this point, -+ * but the host channel is still halted. A channel will be reassigned -+ * to the transfer when the non-periodic schedule is processed after -+ * the channel is released. This allows transactions to be queued -+ * properly via dwc_otg_hcd_queue_transactions, which also enables the -+ * Tx FIFO Empty interrupt if necessary. -+ */ -+ if (hc->ep_is_in) { -+ /* -+ * IN transfers in Slave mode require an explicit disable to -+ * halt the channel. (In DMA mode, this call simply releases -+ * the channel.) -+ */ -+ halt_channel(hcd, hc, qtd, halt_status); -+ } else { -+ /* -+ * The channel is automatically disabled by the core for OUT -+ * transfers in Slave mode. -+ */ -+ release_channel(hcd, hc, qtd, halt_status); -+ } -+} -+ -+/** -+ * Performs common cleanup for periodic transfers after a Transfer Complete -+ * interrupt. This function should be called after any endpoint type specific -+ * handling is finished to release the host channel. -+ */ -+static void complete_periodic_xfer(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd, -+ enum dwc_otg_halt_status halt_status) -+{ -+ union hctsiz_data hctsiz; -+ qtd->error_count = 0; -+ -+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz); -+ if (!hc->ep_is_in || hctsiz.b.pktcnt == 0) { -+ /* Core halts channel in these cases. */ -+ release_channel(hcd, hc, qtd, halt_status); -+ } else { -+ /* Flush any outstanding requests from the Tx queue. */ -+ halt_channel(hcd, hc, qtd, halt_status); -+ } -+} -+ -+/** -+ * Handles a host channel Transfer Complete interrupt. This handler may be -+ * called in either DMA mode or Slave mode. -+ */ -+static int32_t handle_hc_xfercomp_intr(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ int urb_xfer_done; -+ enum dwc_otg_halt_status halt_status = DWC_OTG_HC_XFER_COMPLETE; -+ struct urb *urb = qtd->urb; -+ int pipe_type = usb_pipetype(urb->pipe); -+ -+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " -+ "Transfer Complete--\n", hc->hc_num); -+ -+ /* -+ * Handle xfer complete on CSPLIT. -+ */ -+ if (hc->qh->do_split) -+ qtd->complete_split = 0; -+ -+ /* Update the QTD and URB states. */ -+ switch (pipe_type) { -+ case PIPE_CONTROL: -+ switch (qtd->control_phase) { -+ case DWC_OTG_CONTROL_SETUP: -+ if (urb->transfer_buffer_length > 0) -+ qtd->control_phase = DWC_OTG_CONTROL_DATA; -+ else -+ qtd->control_phase = DWC_OTG_CONTROL_STATUS; -+ DWC_DEBUGPL(DBG_HCDV, -+ " Control setup transaction done\n"); -+ halt_status = DWC_OTG_HC_XFER_COMPLETE; -+ break; -+ case DWC_OTG_CONTROL_DATA:{ -+ urb_xfer_done = -+ update_urb_state_xfer_comp(hc, hc_regs, -+ urb, qtd); -+ if (urb_xfer_done) { -+ qtd->control_phase = -+ DWC_OTG_CONTROL_STATUS; -+ DWC_DEBUGPL(DBG_HCDV, -+ " Control data transfer done\n"); -+ } else { -+ save_data_toggle(hc, hc_regs, qtd); -+ } -+ halt_status = DWC_OTG_HC_XFER_COMPLETE; -+ break; -+ } -+ case DWC_OTG_CONTROL_STATUS: -+ DWC_DEBUGPL(DBG_HCDV, " Control transfer complete\n"); -+ if (urb->status == -EINPROGRESS) -+ urb->status = 0; -+ dwc_otg_hcd_complete_urb(hcd, urb, urb->status); -+ qtd->urb = NULL; -+ halt_status = DWC_OTG_HC_XFER_URB_COMPLETE; -+ break; -+ } -+ -+ complete_non_periodic_xfer(hcd, hc, hc_regs, qtd, -+ halt_status); -+ break; -+ case PIPE_BULK: -+ DWC_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n"); -+ urb_xfer_done = -+ update_urb_state_xfer_comp(hc, hc_regs, urb, qtd); -+ if (urb_xfer_done) { -+ dwc_otg_hcd_complete_urb(hcd, urb, urb->status); -+ qtd->urb = NULL; -+ halt_status = DWC_OTG_HC_XFER_URB_COMPLETE; -+ } else { -+ halt_status = DWC_OTG_HC_XFER_COMPLETE; -+ } -+ -+ save_data_toggle(hc, hc_regs, qtd); -+ complete_non_periodic_xfer(hcd, hc, hc_regs, qtd, -+ halt_status); -+ break; -+ case PIPE_INTERRUPT: -+ DWC_DEBUGPL(DBG_HCDV, " Interrupt transfer complete\n"); -+ update_urb_state_xfer_comp(hc, hc_regs, urb, qtd); -+ -+ /* -+ * Interrupt URB is done on the first transfer complete -+ * interrupt. -+ */ -+ dwc_otg_hcd_complete_urb(hcd, urb, urb->status); -+ qtd->urb = NULL; -+ save_data_toggle(hc, hc_regs, qtd); -+ complete_periodic_xfer(hcd, hc, hc_regs, qtd, -+ DWC_OTG_HC_XFER_URB_COMPLETE); -+ break; -+ case PIPE_ISOCHRONOUS: -+ DWC_DEBUGPL(DBG_HCDV, " Isochronous transfer complete\n"); -+ if (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_ALL) { -+ halt_status = -+ update_isoc_urb_state(hcd, hc, hc_regs, qtd, -+ DWC_OTG_HC_XFER_COMPLETE); -+ } -+ complete_periodic_xfer(hcd, hc, hc_regs, qtd, halt_status); -+ break; -+ } -+ -+ disable_hc_int(hc_regs, xfercompl); -+ -+ return 1; -+} -+ -+/** -+ * Handles a host channel STALL interrupt. This handler may be called in -+ * either DMA mode or Slave mode. -+ */ -+static int32_t handle_hc_stall_intr(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ struct urb *urb = qtd->urb; -+ int pipe_type = usb_pipetype(urb->pipe); -+ -+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " -+ "STALL Received--\n", hc->hc_num); -+ -+ if (pipe_type == PIPE_CONTROL) { -+ dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EPIPE); -+ qtd->urb = NULL; -+ } -+ -+ if (pipe_type == PIPE_BULK || pipe_type == PIPE_INTERRUPT) { -+ dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EPIPE); -+ qtd->urb = NULL; -+ /* -+ * USB protocol requires resetting the data toggle for bulk -+ * and interrupt endpoints when a CLEAR_FEATURE(ENDPOINT_HALT) -+ * setup command is issued to the endpoint. Anticipate the -+ * CLEAR_FEATURE command since a STALL has occurred and reset -+ * the data toggle now. -+ */ -+ hc->qh->data_toggle = 0; -+ } -+ -+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_STALL); -+ -+ disable_hc_int(hc_regs, stall); -+ -+ return 1; -+} -+ -+/* -+ * Updates the state of the URB when a transfer has been stopped due to an -+ * abnormal condition before the transfer completes. Modifies the -+ * actual_length field of the URB to reflect the number of bytes that have -+ * actually been transferred via the host channel. -+ */ -+static void update_urb_state_xfer_intr(struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct urb *urb, -+ struct dwc_otg_qtd *qtd, -+ enum dwc_otg_halt_status halt_status) -+{ -+ uint32_t bytes_transferred = get_actual_xfer_length(hc, hc_regs, qtd, -+ halt_status, NULL); -+ urb->actual_length += bytes_transferred; -+ -+#ifdef DEBUG -+ { -+ union hctsiz_data hctsiz; -+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz); -+ DWC_DEBUGPL(DBG_HCDV, "DWC_otg: %s: %s, channel %d\n", -+ __func__, (hc->ep_is_in ? "IN" : "OUT"), -+ hc->hc_num); -+ DWC_DEBUGPL(DBG_HCDV, " hc->start_pkt_count %d\n", -+ hc->start_pkt_count); -+ DWC_DEBUGPL(DBG_HCDV, " hctsiz.pktcnt %d\n", hctsiz.b.pktcnt); -+ DWC_DEBUGPL(DBG_HCDV, " hc->max_packet %d\n", -+ hc->max_packet); -+ DWC_DEBUGPL(DBG_HCDV, " bytes_transferred %d\n", -+ bytes_transferred); -+ DWC_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", -+ urb->actual_length); -+ DWC_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n", -+ urb->transfer_buffer_length); -+ } -+#endif -+} -+ -+/** -+ * Handles a host channel NAK interrupt. This handler may be called in either -+ * DMA mode or Slave mode. -+ */ -+static int32_t handle_hc_nak_intr(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " -+ "NAK Received--\n", hc->hc_num); -+ -+ /* -+ * Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and -+ * interrupt. Re-start the SSPLIT transfer. -+ */ -+ if (hc->do_split) { -+ if (hc->complete_split) -+ qtd->error_count = 0; -+ qtd->complete_split = 0; -+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK); -+ goto handle_nak_done; -+ } -+ -+ switch (usb_pipetype(qtd->urb->pipe)) { -+ case PIPE_CONTROL: -+ case PIPE_BULK: -+ if (hcd->core_if->dma_enable && hc->ep_is_in) { -+ /* -+ * NAK interrupts are enabled on bulk/control IN -+ * transfers in DMA mode for the sole purpose of -+ * resetting the error count after a transaction error -+ * occurs. The core will continue transferring data. -+ */ -+ qtd->error_count = 0; -+ goto handle_nak_done; -+ } -+ -+ /* -+ * NAK interrupts normally occur during OUT transfers in DMA -+ * or Slave mode. For IN transfers, more requests will be -+ * queued as request queue space is available. -+ */ -+ qtd->error_count = 0; -+ -+ if (!hc->qh->ping_state) { -+ update_urb_state_xfer_intr(hc, hc_regs, qtd->urb, -+ qtd, DWC_OTG_HC_XFER_NAK); -+ save_data_toggle(hc, hc_regs, qtd); -+ if (qtd->urb->dev->speed == USB_SPEED_HIGH) -+ hc->qh->ping_state = 1; -+ } -+ -+ /* -+ * Halt the channel so the transfer can be re-started from -+ * the appropriate point or the PING protocol will -+ * start/continue. -+ */ -+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK); -+ break; -+ case PIPE_INTERRUPT: -+ qtd->error_count = 0; -+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK); -+ break; -+ case PIPE_ISOCHRONOUS: -+ /* Should never get called for isochronous transfers. */ -+ BUG(); -+ break; -+ } -+ -+handle_nak_done: -+ disable_hc_int(hc_regs, nak); -+ -+ return 1; -+} -+ -+/** -+ * Handles a host channel ACK interrupt. This interrupt is enabled when -+ * performing the PING protocol in Slave mode, when errors occur during -+ * either Slave mode or DMA mode, and during Start Split transactions. -+ */ -+static int32_t handle_hc_ack_intr(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " -+ "ACK Received--\n", hc->hc_num); -+ -+ if (hc->do_split) { -+ /* -+ * Handle ACK on SSPLIT. -+ * ACK should not occur in CSPLIT. -+ */ -+ if ((!hc->ep_is_in) -+ && (hc->data_pid_start != DWC_OTG_HC_PID_SETUP)) { -+ qtd->ssplit_out_xfer_count = hc->xfer_len; -+ } -+ if (!(hc->ep_type == DWC_OTG_EP_TYPE_ISOC && !hc->ep_is_in)) { -+ /* Don't need complete for isochronous out transfers. */ -+ qtd->complete_split = 1; -+ } -+ -+ /* ISOC OUT */ -+ if ((hc->ep_type == DWC_OTG_EP_TYPE_ISOC) && !hc->ep_is_in) { -+ switch (hc->xact_pos) { -+ case DWC_HCSPLIT_XACTPOS_ALL: -+ break; -+ case DWC_HCSPLIT_XACTPOS_END: -+ qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL; -+ qtd->isoc_split_offset = 0; -+ break; -+ case DWC_HCSPLIT_XACTPOS_BEGIN: -+ case DWC_HCSPLIT_XACTPOS_MID: -+ /* -+ * For BEGIN or MID, calculate the length for -+ * the next microframe to determine the correct -+ * SSPLIT token, either MID or END. -+ */ -+ do { -+ struct usb_iso_packet_descriptor -+ *frame_desc; -+ -+ frame_desc = -+ &qtd->urb->iso_frame_desc[qtd->isoc_frame_index]; -+ qtd->isoc_split_offset += 188; -+ -+ if ((frame_desc->length - -+ qtd->isoc_split_offset) <= 188) { -+ qtd->isoc_split_pos = -+ DWC_HCSPLIT_XACTPOS_END; -+ } else { -+ qtd->isoc_split_pos = -+ DWC_HCSPLIT_XACTPOS_MID; -+ } -+ -+ } while (0); -+ break; -+ } -+ } else { -+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK); -+ } -+ } else { -+ qtd->error_count = 0; -+ -+ if (hc->qh->ping_state) { -+ hc->qh->ping_state = 0; -+ /* -+ * Halt the channel so the transfer can be re-started -+ * from the appropriate point. This only happens in -+ * Slave mode. In DMA mode, the ping_state is cleared -+ * when the transfer is started because the core -+ * automatically executes the PING, then the transfer. -+ */ -+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK); -+ } -+ } -+ -+ /* -+ * If the ACK occurred when _not_ in the PING state, let the channel -+ * continue transferring data after clearing the error count. -+ */ -+ -+ disable_hc_int(hc_regs, ack); -+ -+ return 1; -+} -+ -+/** -+ * Handles a host channel NYET interrupt. This interrupt should only occur on -+ * Bulk and Control OUT endpoints and for complete split transactions. If a -+ * NYET occurs at the same time as a Transfer Complete interrupt, it is -+ * handled in the xfercomp interrupt handler, not here. This handler may be -+ * called in either DMA mode or Slave mode. -+ */ -+static int32_t handle_hc_nyet_intr(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " -+ "NYET Received--\n", hc->hc_num); -+ -+ /* -+ * NYET on CSPLIT -+ * re-do the CSPLIT immediately on non-periodic -+ */ -+ if ((hc->do_split) && (hc->complete_split)) { -+ if ((hc->ep_type == DWC_OTG_EP_TYPE_INTR) || -+ (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)) { -+ int frnum = -+ dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd -+ (hcd)); -+ -+ if (dwc_full_frame_num(frnum) != -+ dwc_full_frame_num(hc->qh->sched_frame)) { -+ /* -+ * No longer in the same full speed frame. -+ * Treat this as a transaction error. -+ */ -+#if 0 -+ /** @todo Fix system performance so this can -+ * be treated as an error. Right now complete -+ * splits cannot be scheduled precisely enough -+ * due to other system activity, so this error -+ * occurs regularly in Slave mode. -+ */ -+ qtd->error_count++; -+#endif -+ qtd->complete_split = 0; -+ halt_channel(hcd, hc, qtd, -+ DWC_OTG_HC_XFER_XACT_ERR); -+ /** @todo add support for isoc release */ -+ goto handle_nyet_done; -+ } -+ } -+ -+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET); -+ goto handle_nyet_done; -+ } -+ -+ hc->qh->ping_state = 1; -+ qtd->error_count = 0; -+ -+ update_urb_state_xfer_intr(hc, hc_regs, qtd->urb, qtd, -+ DWC_OTG_HC_XFER_NYET); -+ save_data_toggle(hc, hc_regs, qtd); -+ -+ /* -+ * Halt the channel and re-start the transfer so the PING -+ * protocol will start. -+ */ -+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NYET); -+ -+handle_nyet_done: -+ disable_hc_int(hc_regs, nyet); -+ return 1; -+} -+ -+/** -+ * Handles a host channel babble interrupt. This handler may be called in -+ * either DMA mode or Slave mode. -+ */ -+static int32_t handle_hc_babble_intr(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " -+ "Babble Error--\n", hc->hc_num); -+ if (hc->ep_type != DWC_OTG_EP_TYPE_ISOC) { -+ dwc_otg_hcd_complete_urb(hcd, qtd->urb, -EOVERFLOW); -+ qtd->urb = NULL; -+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_BABBLE_ERR); -+ } else { -+ enum dwc_otg_halt_status halt_status; -+ halt_status = update_isoc_urb_state(hcd, hc, hc_regs, qtd, -+ DWC_OTG_HC_XFER_BABBLE_ERR); -+ halt_channel(hcd, hc, qtd, halt_status); -+ } -+ disable_hc_int(hc_regs, bblerr); -+ return 1; -+} -+ -+/** -+ * Handles a host channel AHB error interrupt. This handler is only called in -+ * DMA mode. -+ */ -+static int32_t handle_hc_ahberr_intr(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ union hcchar_data hcchar; -+ union hcsplt_data hcsplt; -+ union hctsiz_data hctsiz; -+ uint32_t hcdma; -+ struct urb *urb = qtd->urb; -+ -+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " -+ "AHB Error--\n", hc->hc_num); -+ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt); -+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz); -+ hcdma = dwc_read_reg32(&hc_regs->hcdma); -+ -+ DWC_ERROR("AHB ERROR, Channel %d\n", hc->hc_num); -+ DWC_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32); -+ DWC_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma); -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Enqueue\n"); -+ DWC_ERROR(" Device address: %d\n", usb_pipedevice(urb->pipe)); -+ DWC_ERROR(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe), -+ (usb_pipein(urb->pipe) ? "IN" : "OUT")); -+ DWC_ERROR(" Endpoint type: %s\n", -+ ({ -+ char *pipetype; -+ switch (usb_pipetype(urb->pipe)) { -+ case PIPE_CONTROL: -+ pipetype = "CONTROL"; -+ break; -+ case PIPE_BULK: -+ pipetype = "BULK"; -+ break; -+ case PIPE_INTERRUPT: -+ pipetype = "INTERRUPT"; -+ break; -+ case PIPE_ISOCHRONOUS: -+ pipetype = "ISOCHRONOUS"; -+ break; -+ default: -+ pipetype = "UNKNOWN"; -+ break; -+ } -+ pipetype; -+ })); -+ DWC_ERROR(" Speed: %s\n", -+ ({ -+ char *speed; -+ switch (urb->dev->speed) { -+ case USB_SPEED_HIGH: -+ speed = "HIGH"; -+ break; -+ case USB_SPEED_FULL: -+ speed = "FULL"; -+ break; -+ case USB_SPEED_LOW: -+ speed = "LOW"; -+ break; -+ default: -+ speed = "UNKNOWN"; -+ break; -+ } -+ speed; -+ })); -+ DWC_ERROR(" Max packet size: %d\n", -+ usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))); -+ DWC_ERROR(" Data buffer length: %d\n", urb->transfer_buffer_length); -+ DWC_ERROR(" Transfer buffer: %p, Transfer DMA: 0x%llx\n", -+ urb->transfer_buffer, (unsigned long long)urb->transfer_dma); -+ DWC_ERROR(" Setup buffer: %p, Setup DMA: 0x%llx\n", -+ urb->setup_packet, (unsigned long long)urb->setup_dma); -+ DWC_ERROR(" Interval: %d\n", urb->interval); -+ -+ dwc_otg_hcd_complete_urb(hcd, urb, -EIO); -+ qtd->urb = NULL; -+ -+ /* -+ * Force a channel halt. Don't call halt_channel because that won't -+ * write to the HCCHARn register in DMA mode to force the halt. -+ */ -+ dwc_otg_hc_halt(hcd->core_if, hc, DWC_OTG_HC_XFER_AHB_ERR); -+ -+ disable_hc_int(hc_regs, ahberr); -+ return 1; -+} -+ -+/** -+ * Handles a host channel transaction error interrupt. This handler may be -+ * called in either DMA mode or Slave mode. -+ */ -+static int32_t handle_hc_xacterr_intr(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " -+ "Transaction Error--\n", hc->hc_num); -+ -+ switch (usb_pipetype(qtd->urb->pipe)) { -+ case PIPE_CONTROL: -+ case PIPE_BULK: -+ qtd->error_count++; -+ if (!hc->qh->ping_state) { -+ update_urb_state_xfer_intr(hc, hc_regs, qtd->urb, -+ qtd, -+ DWC_OTG_HC_XFER_XACT_ERR); -+ save_data_toggle(hc, hc_regs, qtd); -+ if (!hc->ep_is_in -+ && qtd->urb->dev->speed == USB_SPEED_HIGH) { -+ hc->qh->ping_state = 1; -+ } -+ } -+ -+ /* -+ * Halt the channel so the transfer can be re-started from -+ * the appropriate point or the PING protocol will start. -+ */ -+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR); -+ break; -+ case PIPE_INTERRUPT: -+ qtd->error_count++; -+ if ((hc->do_split) && (hc->complete_split)) -+ qtd->complete_split = 0; -+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR); -+ break; -+ case PIPE_ISOCHRONOUS: -+ { -+ enum dwc_otg_halt_status halt_status; -+ halt_status = -+ update_isoc_urb_state(hcd, hc, hc_regs, qtd, -+ DWC_OTG_HC_XFER_XACT_ERR); -+ -+ halt_channel(hcd, hc, qtd, halt_status); -+ } -+ break; -+ } -+ -+ disable_hc_int(hc_regs, xacterr); -+ -+ return 1; -+} -+ -+/** -+ * Handles a host channel frame overrun interrupt. This handler may be called -+ * in either DMA mode or Slave mode. -+ */ -+static int32_t handle_hc_frmovrun_intr(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ enum dwc_otg_halt_status halt_status; -+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " -+ "Frame Overrun--\n", hc->hc_num); -+ -+ switch (usb_pipetype(qtd->urb->pipe)) { -+ case PIPE_CONTROL: -+ case PIPE_BULK: -+ break; -+ case PIPE_INTERRUPT: -+ halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_FRAME_OVERRUN); -+ break; -+ case PIPE_ISOCHRONOUS: -+ halt_status = -+ update_isoc_urb_state(hcd, hc, hc_regs, qtd, -+ DWC_OTG_HC_XFER_FRAME_OVERRUN); -+ halt_channel(hcd, hc, qtd, halt_status); -+ break; -+ } -+ -+ disable_hc_int(hc_regs, frmovrun); -+ -+ return 1; -+} -+ -+/** -+ * Handles a host channel data toggle error interrupt. This handler may be -+ * called in either DMA mode or Slave mode. -+ */ -+static int32_t handle_hc_datatglerr_intr(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " -+ "Data Toggle Error--\n", hc->hc_num); -+ -+ if (hc->ep_is_in) { -+ qtd->error_count = 0; -+ } else { -+ DWC_ERROR("Data Toggle Error on OUT transfer," -+ "channel %d\n", hc->hc_num); -+ } -+ -+ disable_hc_int(hc_regs, datatglerr); -+ -+ return 1; -+} -+ -+#ifdef DEBUG -+/** -+ * This function is for debug only. It checks that a valid halt status is set -+ * and that HCCHARn.chdis is clear. If there's a problem, corrective action is -+ * taken and a warning is issued. -+ * Returns 1 if halt status is ok, 0 otherwise. -+ */ -+static inline int halt_status_ok(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ union hcchar_data hcchar; -+ union hctsiz_data hctsiz; -+ union hcint_data hcint; -+ union hcintmsk_data hcintmsk; -+ union hcsplt_data hcsplt; -+ -+ if (hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS) { -+ /* -+ * This code is here only as a check. This condition should -+ * never happen. Ignore the halt if it does occur. -+ */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ hctsiz.d32 = dwc_read_reg32(&hc_regs->hctsiz); -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk); -+ hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt); -+ DWC_WARN -+ ("%s: hc->halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS, " -+ "channel %d, hcchar 0x%08x, hctsiz 0x%08x, " -+ "hcint 0x%08x, hcintmsk 0x%08x, " -+ "hcsplt 0x%08x, qtd->complete_split %d\n", __func__, -+ hc->hc_num, hcchar.d32, hctsiz.d32, hcint.d32, -+ hcintmsk.d32, hcsplt.d32, qtd->complete_split); -+ -+ DWC_WARN("%s: no halt status, channel %d, ignoring interrupt\n", -+ __func__, hc->hc_num); -+ DWC_WARN("\n"); -+ clear_hc_int(hc_regs, chhltd); -+ return 0; -+ } -+ -+ /* -+ * This code is here only as a check. hcchar.chdis should -+ * never be set when the halt interrupt occurs. Halt the -+ * channel again if it does occur. -+ */ -+ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); -+ if (hcchar.b.chdis) { -+ DWC_WARN("%s: hcchar.chdis set unexpectedly, " -+ "hcchar 0x%08x, trying to halt again\n", -+ __func__, hcchar.d32); -+ clear_hc_int(hc_regs, chhltd); -+ hc->halt_pending = 0; -+ halt_channel(hcd, hc, qtd, hc->halt_status); -+ return 0; -+ } -+ -+ return 1; -+} -+#endif -+ -+/** -+ * Handles a host Channel Halted interrupt in DMA mode. This handler -+ * determines the reason the channel halted and proceeds accordingly. -+ */ -+static void handle_hc_chhltd_intr_dma(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ union hcint_data hcint; -+ union hcintmsk_data hcintmsk; -+ -+ if (hc->halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE || -+ hc->halt_status == DWC_OTG_HC_XFER_AHB_ERR) { -+ /* -+ * Just release the channel. A dequeue can happen on a -+ * transfer timeout. In the case of an AHB Error, the channel -+ * was forced to halt because there's no way to gracefully -+ * recover. -+ */ -+ release_channel(hcd, hc, qtd, hc->halt_status); -+ return; -+ } -+ -+ /* Read the HCINTn register to determine the cause for the halt. */ -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk); -+ -+ if (hcint.b.xfercomp) { -+ /* -+ * @todo This is here because of a possible hardware -+ * bug. Spec says that on SPLIT-ISOC OUT transfers in -+ * DMA mode that a HALT interrupt w/ACK bit set should -+ * occur, but I only see the XFERCOMP bit, even with -+ * it masked out. This is a workaround for that -+ * behavior. Should fix this when hardware is fixed. -+ */ -+ if ((hc->ep_type == DWC_OTG_EP_TYPE_ISOC) && (!hc->ep_is_in)) -+ handle_hc_ack_intr(hcd, hc, hc_regs, qtd); -+ handle_hc_xfercomp_intr(hcd, hc, hc_regs, qtd); -+ } else if (hcint.b.stall) { -+ handle_hc_stall_intr(hcd, hc, hc_regs, qtd); -+ } else if (hcint.b.xacterr) { -+ /* -+ * Must handle xacterr before nak or ack. Could get a xacterr -+ * at the same time as either of these on a BULK/CONTROL OUT -+ * that started with a PING. The xacterr takes precedence. -+ */ -+ handle_hc_xacterr_intr(hcd, hc, hc_regs, qtd); -+ } else if (hcint.b.nyet) { -+ /* -+ * Must handle nyet before nak or ack. Could get a nyet at the -+ * same time as either of those on a BULK/CONTROL OUT that -+ * started with a PING. The nyet takes precedence. -+ */ -+ handle_hc_nyet_intr(hcd, hc, hc_regs, qtd); -+ } else if (hcint.b.bblerr) { -+ handle_hc_babble_intr(hcd, hc, hc_regs, qtd); -+ } else if (hcint.b.frmovrun) { -+ handle_hc_frmovrun_intr(hcd, hc, hc_regs, qtd); -+ } else if (hcint.b.nak && !hcintmsk.b.nak) { -+ /* -+ * If nak is not masked, it's because a non-split IN transfer -+ * is in an error state. In that case, the nak is handled by -+ * the nak interrupt handler, not here. Handle nak here for -+ * BULK/CONTROL OUT transfers, which halt on a NAK to allow -+ * rewinding the buffer pointer. -+ */ -+ handle_hc_nak_intr(hcd, hc, hc_regs, qtd); -+ } else if (hcint.b.ack && !hcintmsk.b.ack) { -+ /* -+ * If ack is not masked, it's because a non-split IN transfer -+ * is in an error state. In that case, the ack is handled by -+ * the ack interrupt handler, not here. Handle ack here for -+ * split transfers. Start splits halt on ACK. -+ */ -+ handle_hc_ack_intr(hcd, hc, hc_regs, qtd); -+ } else { -+ if (hc->ep_type == DWC_OTG_EP_TYPE_INTR || -+ hc->ep_type == DWC_OTG_EP_TYPE_ISOC) { -+ /* -+ * A periodic transfer halted with no other channel -+ * interrupts set. Assume it was halted by the core -+ * because it could not be completed in its scheduled -+ * (micro)frame. -+ */ -+#ifdef DEBUG -+ DWC_PRINT("%s: Halt channel %d (assume incomplete " -+ "periodic transfer)\n", -+ __func__, hc->hc_num); -+#endif -+ halt_channel(hcd, hc, qtd, -+ DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE); -+ } else { -+ DWC_ERROR("%s: Channel %d, DMA Mode -- ChHltd set, " -+ "but reason for halting is unknown, hcint " -+ "0x%08x, intsts 0x%08x\n", -+ __func__, hc->hc_num, hcint.d32, -+ dwc_read_reg32(&hcd->core_if->core_global_regs-> -+ gintsts)); -+ } -+ } -+} -+ -+/** -+ * Handles a host channel Channel Halted interrupt. -+ * -+ * In slave mode, this handler is called only when the driver specifically -+ * requests a halt. This occurs during handling other host channel interrupts -+ * (e.g. nak, xacterr, stall, nyet, etc.). -+ * -+ * In DMA mode, this is the interrupt that occurs when the core has finished -+ * processing a transfer on a channel. Other host channel interrupts (except -+ * ahberr) are disabled in DMA mode. -+ */ -+static int32_t handle_hc_chhltd_intr(struct dwc_otg_hcd *hcd, -+ struct dwc_hc *hc, -+ struct dwc_otg_hc_regs *hc_regs, -+ struct dwc_otg_qtd *qtd) -+{ -+ DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: " -+ "Channel Halted--\n", hc->hc_num); -+ -+ if (hcd->core_if->dma_enable) { -+ handle_hc_chhltd_intr_dma(hcd, hc, hc_regs, qtd); -+ } else { -+#ifdef DEBUG -+ if (!halt_status_ok(hcd, hc, hc_regs, qtd)) -+ return 1; -+#endif -+ release_channel(hcd, hc, qtd, hc->halt_status); -+ } -+ -+ return 1; -+} -+ -+/** Handles interrupt for a specific Host Channel */ -+int32_t dwc_otg_hcd_handle_hc_n_intr(struct dwc_otg_hcd *dwc_otg_hcd, -+ uint32_t _num) -+{ -+ int retval = 0; -+ union hcint_data hcint; -+ union hcintmsk_data hcintmsk; -+ struct dwc_hc *hc; -+ struct dwc_otg_hc_regs *hc_regs; -+ struct dwc_otg_qtd *qtd; -+ -+ DWC_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", _num); -+ -+ hc = dwc_otg_hcd->hc_ptr_array[_num]; -+ hc_regs = dwc_otg_hcd->core_if->host_if->hc_regs[_num]; -+ qtd = list_entry(hc->qh->qtd_list.next, struct dwc_otg_qtd, -+ qtd_list_entry); -+ -+ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); -+ hcintmsk.d32 = dwc_read_reg32(&hc_regs->hcintmsk); -+ DWC_DEBUGPL(DBG_HCDV, -+ " hcint 0x%08x, hcintmsk 0x%08x, hcint&hcintmsk 0x%08x\n", -+ hcint.d32, hcintmsk.d32, (hcint.d32 & hcintmsk.d32)); -+ hcint.d32 = hcint.d32 & hcintmsk.d32; -+ -+ if (!dwc_otg_hcd->core_if->dma_enable) { -+ if ((hcint.b.chhltd) && (hcint.d32 != 0x2)) -+ hcint.b.chhltd = 0; -+ } -+ -+ if (hcint.b.xfercomp) { -+ retval |= -+ handle_hc_xfercomp_intr(dwc_otg_hcd, hc, hc_regs, qtd); -+ /* -+ * If NYET occurred at same time as Xfer Complete, the NYET is -+ * handled by the Xfer Complete interrupt handler. Don't want -+ * to call the NYET interrupt handler in this case. -+ */ -+ hcint.b.nyet = 0; -+ } -+ if (hcint.b.chhltd) -+ retval |= handle_hc_chhltd_intr(dwc_otg_hcd, hc, hc_regs, qtd); -+ -+ if (hcint.b.ahberr) -+ retval |= handle_hc_ahberr_intr(dwc_otg_hcd, hc, hc_regs, qtd); -+ -+ if (hcint.b.stall) -+ retval |= handle_hc_stall_intr(dwc_otg_hcd, hc, hc_regs, qtd); -+ -+ if (hcint.b.nak) -+ retval |= handle_hc_nak_intr(dwc_otg_hcd, hc, hc_regs, qtd); -+ -+ if (hcint.b.ack) -+ retval |= handle_hc_ack_intr(dwc_otg_hcd, hc, hc_regs, qtd); -+ -+ if (hcint.b.nyet) -+ retval |= handle_hc_nyet_intr(dwc_otg_hcd, hc, hc_regs, qtd); -+ -+ if (hcint.b.xacterr) -+ retval |= -+ handle_hc_xacterr_intr(dwc_otg_hcd, hc, hc_regs, qtd); -+ -+ if (hcint.b.bblerr) -+ retval |= handle_hc_babble_intr(dwc_otg_hcd, hc, hc_regs, qtd); -+ -+ if (hcint.b.frmovrun) -+ retval |= -+ handle_hc_frmovrun_intr(dwc_otg_hcd, hc, hc_regs, qtd); -+ -+ if (hcint.b.datatglerr) -+ retval |= -+ handle_hc_datatglerr_intr(dwc_otg_hcd, hc, hc_regs, qtd); -+ -+ return retval; -+} -+ -+#endif /* DWC_DEVICE_ONLY */ -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -new file mode 100644 -index 0000000..e4c96f2 ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -@@ -0,0 +1,695 @@ -+/* ========================================================================== -+ * -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+#ifndef DWC_DEVICE_ONLY -+ -+/* -+ * -+ * This file contains the functions to manage Queue Heads and Queue -+ * Transfer Descriptors. -+ */ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/init.h> -+#include <linux/device.h> -+#include <linux/errno.h> -+#include <linux/list.h> -+#include <linux/interrupt.h> -+#include <linux/string.h> -+ -+#include "dwc_otg_driver.h" -+#include "dwc_otg_hcd.h" -+#include "dwc_otg_regs.h" -+ -+/** -+ * This function allocates and initializes a QH. -+ * -+ * @hcd: The HCD state structure for the DWC OTG controller. -+ * @urb: Holds the information about the device/endpoint that we need -+ * to initialize the QH. -+ * -+ * Returns Returns pointer to the newly allocated QH, or NULL on error. */ -+struct dwc_otg_qh *dwc_otg_hcd_qh_create(struct dwc_otg_hcd *hcd, -+ struct urb *urb) -+{ -+ struct dwc_otg_qh *qh; -+ -+ /* Allocate memory */ -+ /** @todo add memflags argument */ -+ qh = dwc_otg_hcd_qh_alloc(); -+ if (qh == NULL) -+ return NULL; -+ -+ dwc_otg_hcd_qh_init(hcd, qh, urb); -+ return qh; -+} -+ -+/** Free each QTD in the QH's QTD-list then free the QH. QH should already be -+ * removed from a list. QTD list should already be empty if called from URB -+ * Dequeue. -+ * -+ * @qh: The QH to free. -+ */ -+void dwc_otg_hcd_qh_free(struct dwc_otg_qh *qh) -+{ -+ struct dwc_otg_qtd *qtd; -+ struct list_head *pos; -+ -+ /* Free each QTD in the QTD list */ -+ for (pos = qh->qtd_list.next; -+ pos != &qh->qtd_list; pos = qh->qtd_list.next) { -+ list_del(pos); -+ qtd = dwc_list_to_qtd(pos); -+ dwc_otg_hcd_qtd_free(qtd); -+ } -+ -+ kfree(qh); -+ return; -+} -+ -+/** Initializes a QH structure. -+ * -+ * @hcd: The HCD state structure for the DWC OTG controller. -+ * @qh: The QH to init. -+ * @urb: Holds the information about the device/endpoint that we need -+ * to initialize the QH. */ -+#define SCHEDULE_SLOP 10 -+void dwc_otg_hcd_qh_init(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh, -+ struct urb *urb) -+{ -+ memset(qh, 0, sizeof(struct dwc_otg_qh)); -+ -+ /* Initialize QH */ -+ switch (usb_pipetype(urb->pipe)) { -+ case PIPE_CONTROL: -+ qh->ep_type = USB_ENDPOINT_XFER_CONTROL; -+ break; -+ case PIPE_BULK: -+ qh->ep_type = USB_ENDPOINT_XFER_BULK; -+ break; -+ case PIPE_ISOCHRONOUS: -+ qh->ep_type = USB_ENDPOINT_XFER_ISOC; -+ break; -+ case PIPE_INTERRUPT: -+ qh->ep_type = USB_ENDPOINT_XFER_INT; -+ break; -+ } -+ -+ qh->ep_is_in = usb_pipein(urb->pipe) ? 1 : 0; -+ -+ qh->data_toggle = DWC_OTG_HC_PID_DATA0; -+ qh->maxp = -+ usb_maxpacket(urb->dev, urb->pipe, !(usb_pipein(urb->pipe))); -+ INIT_LIST_HEAD(&qh->qtd_list); -+ INIT_LIST_HEAD(&qh->qh_list_entry); -+ qh->channel = NULL; -+ -+ /* FS/LS Enpoint on HS Hub -+ * NOT virtual root hub */ -+ qh->do_split = 0; -+ if (((urb->dev->speed == USB_SPEED_LOW) || -+ (urb->dev->speed == USB_SPEED_FULL)) && -+ (urb->dev->tt) && (urb->dev->tt->hub->devnum != 1)) { -+ DWC_DEBUGPL(DBG_HCD, -+ "QH init: EP %d: TT found at hub addr %d, for " -+ "port %d\n", -+ usb_pipeendpoint(urb->pipe), -+ urb->dev->tt->hub->devnum, urb->dev->ttport); -+ qh->do_split = 1; -+ } -+ -+ if (qh->ep_type == USB_ENDPOINT_XFER_INT || -+ qh->ep_type == USB_ENDPOINT_XFER_ISOC) { -+ /* Compute scheduling parameters once and save them. */ -+ union hprt0_data hprt; -+ -+ /* todo Account for split transfers in the bus time. */ -+ int bytecount = -+ dwc_hb_mult(qh->maxp) * dwc_max_packet(qh->maxp); -+ /* -+ * The results from usb_calc_bus_time are in nanosecs, -+ * so divide the result by 1000 to convert to -+ * microsecs expected by this driver -+ */ -+ qh->usecs = usb_calc_bus_time(urb->dev->speed, -+ usb_pipein(urb->pipe), -+ (qh->ep_type == -+ USB_ENDPOINT_XFER_ISOC), -+ bytecount) / 1000; -+ -+ /* Start in a slightly future (micro)frame. */ -+ qh->sched_frame = dwc_frame_num_inc(hcd->frame_number, -+ SCHEDULE_SLOP); -+ qh->interval = urb->interval; -+#if 0 -+ /* Increase interrupt polling rate for debugging. */ -+ if (qh->ep_type == USB_ENDPOINT_XFER_INT) -+ qh->interval = 8; -+#endif -+ hprt.d32 = dwc_read_reg32(hcd->core_if->host_if->hprt0); -+ if ((hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) && -+ ((urb->dev->speed == USB_SPEED_LOW) || -+ (urb->dev->speed == USB_SPEED_FULL))) { -+ qh->interval *= 8; -+ qh->sched_frame |= 0x7; -+ qh->start_split_frame = qh->sched_frame; -+ } -+ -+ } -+ -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD QH Initialized\n"); -+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - qh = %p\n", qh); -+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Device Address = %d\n", -+ urb->dev->devnum); -+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Endpoint %d, %s\n", -+ usb_pipeendpoint(urb->pipe), -+ usb_pipein(urb->pipe) == USB_DIR_IN ? "IN" : "OUT"); -+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Speed = %s\n", -+ ({ -+ char *speed; -+ switch (urb->dev->speed) { -+ case USB_SPEED_LOW: -+ speed = "low"; -+ break; -+ case USB_SPEED_FULL: -+ speed = "full"; -+ break; -+ case USB_SPEED_HIGH: -+ speed = "high"; -+ break; -+ default: -+ speed = "?"; -+ break; -+ } -+ speed; -+ })); -+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Type = %s\n", -+ ({ -+ char *type; -+ switch (qh->ep_type) { -+ case USB_ENDPOINT_XFER_ISOC: -+ type = "isochronous"; -+ break; -+ case USB_ENDPOINT_XFER_INT: -+ type = "interrupt"; -+ break; -+ case USB_ENDPOINT_XFER_CONTROL: -+ type = "control"; -+ break; -+ case USB_ENDPOINT_XFER_BULK: -+ type = "bulk"; -+ break; -+ default: -+ type = "?"; -+ break; -+ } -+ type; -+ })); -+#ifdef DEBUG -+ if (qh->ep_type == USB_ENDPOINT_XFER_INT) { -+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - usecs = %d\n", -+ qh->usecs); -+ DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - interval = %d\n", -+ qh->interval); -+ } -+#endif -+ -+ return; -+} -+ -+/** -+ * Checks that a channel is available for a periodic transfer. -+ * -+ * Returns 0 if successful, negative error code otherise. -+ */ -+static int periodic_channel_available(struct dwc_otg_hcd *hcd) -+{ -+ /* -+ * Currently assuming that there is a dedicated host channnel for each -+ * periodic transaction plus at least one host channel for -+ * non-periodic transactions. -+ */ -+ int status; -+ int num_channels; -+ -+ num_channels = hcd->core_if->core_params->host_channels; -+ if ((hcd->periodic_channels + hcd->non_periodic_channels < -+ num_channels) && (hcd->periodic_channels < num_channels - 1)) { -+ status = 0; -+ } else { -+ DWC_NOTICE -+ ("%s: Total channels: %d, Periodic: %d, Non-periodic: %d\n", -+ __func__, num_channels, hcd->periodic_channels, -+ hcd->non_periodic_channels); -+ status = -ENOSPC; -+ } -+ -+ return status; -+} -+ -+/** -+ * Checks that there is sufficient bandwidth for the specified QH in the -+ * periodic schedule. For simplicity, this calculation assumes that all the -+ * transfers in the periodic schedule may occur in the same (micro)frame. -+ * -+ * @hcd: The HCD state structure for the DWC OTG controller. -+ * @qh: QH containing periodic bandwidth required. -+ * -+ * Returns 0 if successful, negative error code otherwise. -+ */ -+static int check_periodic_bandwidth(struct dwc_otg_hcd *hcd, -+ struct dwc_otg_qh *qh) -+{ -+ int status; -+ uint16_t max_claimed_usecs; -+ -+ status = 0; -+ -+ if (hcd->core_if->core_params->speed == DWC_SPEED_PARAM_HIGH) { -+ /* -+ * High speed mode. -+ * Max periodic usecs is 80% x 125 usec = 100 usec. -+ */ -+ max_claimed_usecs = 100 - qh->usecs; -+ } else { -+ /* -+ * Full speed mode. -+ * Max periodic usecs is 90% x 1000 usec = 900 usec. -+ */ -+ max_claimed_usecs = 900 - qh->usecs; -+ } -+ -+ if (hcd->periodic_usecs > max_claimed_usecs) { -+ DWC_NOTICE("%s: already claimed usecs %d, required usecs %d\n", -+ __func__, hcd->periodic_usecs, qh->usecs); -+ status = -ENOSPC; -+ } -+ -+ return status; -+} -+ -+/** -+ * Checks that the max transfer size allowed in a host channel is large enough -+ * to handle the maximum data transfer in a single (micro)frame for a periodic -+ * transfer. -+ * -+ * @hcd: The HCD state structure for the DWC OTG controller. -+ * @qh: QH for a periodic endpoint. -+ * -+ * Returns 0 if successful, negative error code otherwise. -+ */ -+static int check_max_xfer_size(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh) -+{ -+ int status; -+ uint32_t max_xfer_size; -+ uint32_t max_channel_xfer_size; -+ -+ status = 0; -+ -+ max_xfer_size = dwc_max_packet(qh->maxp) * dwc_hb_mult(qh->maxp); -+ max_channel_xfer_size = hcd->core_if->core_params->max_transfer_size; -+ -+ if (max_xfer_size > max_channel_xfer_size) { -+ DWC_NOTICE("%s: Periodic xfer length %d > " -+ "max xfer length for channel %d\n", -+ __func__, max_xfer_size, max_channel_xfer_size); -+ status = -ENOSPC; -+ } -+ -+ return status; -+} -+ -+/** -+ * Schedules an interrupt or isochronous transfer in the periodic schedule. -+ * -+ * @hcd: The HCD state structure for the DWC OTG controller. -+ * @qh: QH for the periodic transfer. The QH should already contain the -+ * scheduling information. -+ * -+ * Returns 0 if successful, negative error code otherwise. -+ */ -+static int schedule_periodic(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh) -+{ -+ int status = 0; -+ -+ status = periodic_channel_available(hcd); -+ if (status) { -+ DWC_NOTICE("%s: No host channel available for periodic " -+ "transfer.\n", __func__); -+ return status; -+ } -+ -+ status = check_periodic_bandwidth(hcd, qh); -+ if (status) { -+ DWC_NOTICE("%s: Insufficient periodic bandwidth for " -+ "periodic transfer.\n", __func__); -+ return status; -+ } -+ -+ status = check_max_xfer_size(hcd, qh); -+ if (status) { -+ DWC_NOTICE("%s: Channel max transfer size too small " -+ "for periodic transfer.\n", __func__); -+ return status; -+ } -+ -+ /* Always start in the inactive schedule. */ -+ list_add_tail(&qh->qh_list_entry, &hcd->periodic_sched_inactive); -+ -+ /* Reserve the periodic channel. */ -+ hcd->periodic_channels++; -+ -+ /* Update claimed usecs per (micro)frame. */ -+ hcd->periodic_usecs += qh->usecs; -+ -+ /* -+ * Update average periodic bandwidth claimed and # periodic -+ * reqs for usbfs. -+ */ -+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_allocated += -+ qh->usecs / qh->interval; -+ if (qh->ep_type == USB_ENDPOINT_XFER_INT) { -+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_int_reqs++; -+ DWC_DEBUGPL(DBG_HCD, -+ "Scheduled intr: qh %p, usecs %d, period %d\n", qh, -+ qh->usecs, qh->interval); -+ } else { -+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_isoc_reqs++; -+ DWC_DEBUGPL(DBG_HCD, -+ "Scheduled isoc: qh %p, usecs %d, period %d\n", qh, -+ qh->usecs, qh->interval); -+ } -+ -+ return status; -+} -+ -+/** -+ * This function adds a QH to either the non periodic or periodic schedule if -+ * it is not already in the schedule. If the QH is already in the schedule, no -+ * action is taken. -+ * -+ * Returns 0 if successful, negative error code otherwise. -+ */ -+int dwc_otg_hcd_qh_add(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh) -+{ -+ int status = 0; -+ -+ if (!spin_is_locked(&hcd->global_lock)) { -+ pr_err("%s don't have hcd->global_lock", __func__); -+ BUG(); -+ } -+ -+ if (!list_empty(&qh->qh_list_entry)) { -+ /* QH already in a schedule. */ -+ goto done; -+ } -+ -+ /* Add the new QH to the appropriate schedule */ -+ if (dwc_qh_is_non_per(qh)) { -+ /* Always start in the inactive schedule. */ -+ list_add_tail(&qh->qh_list_entry, -+ &hcd->non_periodic_sched_inactive); -+ } else { -+ status = schedule_periodic(hcd, qh); -+ } -+ -+done: -+ return status; -+} -+ -+/** -+ * Removes an interrupt or isochronous transfer from the periodic schedule. -+ * -+ * @hcd: The HCD state structure for the DWC OTG controller. -+ * @qh: QH for the periodic transfer. -+ */ -+static void deschedule_periodic(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh) -+{ -+ list_del_init(&qh->qh_list_entry); -+ -+ /* Release the periodic channel reservation. */ -+ hcd->periodic_channels--; -+ -+ /* Update claimed usecs per (micro)frame. */ -+ hcd->periodic_usecs -= qh->usecs; -+ -+ /* -+ * Update average periodic bandwidth claimed and # periodic -+ * reqs for usbfs. -+ */ -+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_allocated -= -+ qh->usecs / qh->interval; -+ -+ if (qh->ep_type == USB_ENDPOINT_XFER_INT) { -+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_int_reqs--; -+ DWC_DEBUGPL(DBG_HCD, -+ "Descheduled intr: qh %p, usecs %d, period %d\n", -+ qh, qh->usecs, qh->interval); -+ } else { -+ hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_isoc_reqs--; -+ DWC_DEBUGPL(DBG_HCD, -+ "Descheduled isoc: qh %p, usecs %d, period %d\n", -+ qh, qh->usecs, qh->interval); -+ } -+} -+ -+/** -+ * Removes a QH from either the non-periodic or periodic schedule. Memory is -+ * not freed. -+ * -+ * @hcd: The HCD state structure. -+ * @qh: QH to remove from schedule. */ -+void dwc_otg_hcd_qh_remove(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh) -+{ -+ if (!spin_is_locked(&hcd->global_lock)) { -+ pr_err("%s don't have hcd->global_lock", __func__); -+ BUG(); -+ } -+ -+ if (list_empty(&qh->qh_list_entry)) { -+ /* QH is not in a schedule. */ -+ goto done; -+ } -+ -+ if (dwc_qh_is_non_per(qh)) { -+ if (hcd->non_periodic_qh_ptr == &qh->qh_list_entry) { -+ hcd->non_periodic_qh_ptr = -+ hcd->non_periodic_qh_ptr->next; -+ } -+ list_del_init(&qh->qh_list_entry); -+ } else { -+ deschedule_periodic(hcd, qh); -+ } -+ -+done: -+ ; -+} -+ -+/** -+ * Deactivates a QH. For non-periodic QHs, removes the QH from the active -+ * non-periodic schedule. The QH is added to the inactive non-periodic -+ * schedule if any QTDs are still attached to the QH. -+ * -+ * For periodic QHs, the QH is removed from the periodic queued schedule. If -+ * there are any QTDs still attached to the QH, the QH is added to either the -+ * periodic inactive schedule or the periodic ready schedule and its next -+ * scheduled frame is calculated. The QH is placed in the ready schedule if -+ * the scheduled frame has been reached already. Otherwise it's placed in the -+ * inactive schedule. If there are no QTDs attached to the QH, the QH is -+ * completely removed from the periodic schedule. -+ */ -+void dwc_otg_hcd_qh_deactivate(struct dwc_otg_hcd *hcd, struct dwc_otg_qh *qh, -+ int sched_next_periodic_split) -+{ -+ uint16_t frame_number; -+ -+ if (!spin_is_locked(&hcd->global_lock)) { -+ pr_err("%s don't have hcd->global_lock", __func__); -+ BUG(); -+ } -+ -+ if (dwc_qh_is_non_per(qh)) { -+ dwc_otg_hcd_qh_remove(hcd, qh); -+ if (!list_empty(&qh->qtd_list)) -+ /* Add back to inactive non-periodic schedule. */ -+ dwc_otg_hcd_qh_add(hcd, qh); -+ return; -+ } -+ -+ frame_number = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(hcd)); -+ -+ if (qh->do_split) { -+ /* Schedule the next continuing periodic split transfer */ -+ if (sched_next_periodic_split) { -+ -+ qh->sched_frame = frame_number; -+ if (dwc_frame_num_le(frame_number, -+ dwc_frame_num_inc(qh->start_split_frame, -+ 1))) { -+ /* -+ * Allow one frame to elapse after -+ * start split microframe before -+ * scheduling complete split, but DONT -+ * if we are doing the next start -+ * split in the same frame for an ISOC -+ * out. -+ */ -+ if ((qh->ep_type != USB_ENDPOINT_XFER_ISOC) -+ || (qh->ep_is_in != 0)) { -+ qh->sched_frame = -+ dwc_frame_num_inc(qh->sched_frame, -+ 1); -+ } -+ } -+ } else { -+ qh->sched_frame = -+ dwc_frame_num_inc(qh->start_split_frame, -+ qh->interval); -+ if (dwc_frame_num_le(qh->sched_frame, frame_number)) -+ qh->sched_frame = frame_number; -+ -+ qh->sched_frame |= 0x7; -+ qh->start_split_frame = qh->sched_frame; -+ } -+ } else { -+ qh->sched_frame = dwc_frame_num_inc(qh->sched_frame, -+ qh->interval); -+ if (dwc_frame_num_le(qh->sched_frame, frame_number)) -+ qh->sched_frame = frame_number; -+ } -+ -+ if (list_empty(&qh->qtd_list)) { -+ dwc_otg_hcd_qh_remove(hcd, qh); -+ } else { -+ /* -+ * Remove from periodic_sched_queued and move to -+ * appropriate queue. -+ */ -+ if (qh->sched_frame == frame_number) { -+ list_move(&qh->qh_list_entry, -+ &hcd->periodic_sched_ready); -+ } else { -+ list_move(&qh->qh_list_entry, -+ &hcd->periodic_sched_inactive); -+ } -+ } -+} -+ -+/** -+ * This function allocates and initializes a QTD. -+ * -+ * @urb: The URB to create a QTD from. Each URB-QTD pair will end up -+ * pointing to each other so each pair should have a unique correlation. -+ * -+ * Returns Returns pointer to the newly allocated QTD, or NULL on error. */ -+struct dwc_otg_qtd *dwc_otg_hcd_qtd_create(struct urb *urb) -+{ -+ struct dwc_otg_qtd *qtd; -+ -+ qtd = dwc_otg_hcd_qtd_alloc(); -+ if (qtd == NULL) -+ return NULL; -+ -+ dwc_otg_hcd_qtd_init(qtd, urb); -+ return qtd; -+} -+ -+/** -+ * Initializes a QTD structure. -+ * -+ * @qtd: The QTD to initialize. -+ * @urb: The URB to use for initialization. -+ */ -+void dwc_otg_hcd_qtd_init(struct dwc_otg_qtd *qtd, struct urb *urb) -+{ -+ memset(qtd, 0, sizeof(struct dwc_otg_qtd)); -+ qtd->urb = urb; -+ if (usb_pipecontrol(urb->pipe)) { -+ /* -+ * The only time the QTD data toggle is used is on the data -+ * phase of control transfers. This phase always starts with -+ * DATA1. -+ */ -+ qtd->data_toggle = DWC_OTG_HC_PID_DATA1; -+ qtd->control_phase = DWC_OTG_CONTROL_SETUP; -+ } -+ -+ /* start split */ -+ qtd->complete_split = 0; -+ qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL; -+ qtd->isoc_split_offset = 0; -+ -+ /* Store the qtd ptr in the urb to reference what QTD. */ -+ urb->hcpriv = qtd; -+ return; -+} -+ -+/** -+ * This function adds a QTD to the QTD-list of a QH. It will find the correct -+ * QH to place the QTD into. If it does not find a QH, then it will create a -+ * new QH. If the QH to which the QTD is added is not currently scheduled, it -+ * is placed into the proper schedule based on its EP type. -+ * -+ * @qtd: The QTD to add -+ * @dwc_otg_hcd: The DWC HCD structure -+ * -+ * Returns 0 if successful, negative error code otherwise. -+ */ -+int dwc_otg_hcd_qtd_add(struct dwc_otg_qtd *qtd, -+ struct dwc_otg_hcd *dwc_otg_hcd) -+{ -+ struct usb_host_endpoint *ep; -+ struct dwc_otg_qh *qh; -+ int retval = 0; -+ -+ struct urb *urb = qtd->urb; -+ -+ /* -+ * Get the QH which holds the QTD-list to insert to. Create QH if it -+ * doesn't exist. -+ */ -+ ep = dwc_urb_to_endpoint(urb); -+ qh = ep->hcpriv; -+ if (qh == NULL) { -+ qh = dwc_otg_hcd_qh_create(dwc_otg_hcd, urb); -+ if (qh == NULL) { -+ retval = -ENOMEM; -+ goto done; -+ } -+ ep->hcpriv = qh; -+ } -+ qtd->qh = qh; -+ retval = dwc_otg_hcd_qh_add(dwc_otg_hcd, qh); -+ if (retval == 0) -+ list_add_tail(&qtd->qtd_list_entry, &qh->qtd_list); -+done: -+ return retval; -+} -+ -+#endif /* DWC_DEVICE_ONLY */ -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_octeon.c b/drivers/usb/host/dwc_otg/dwc_otg_octeon.c -new file mode 100644 -index 0000000..5e92b3c ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_octeon.c -@@ -0,0 +1,1078 @@ -+/* ========================================================================== -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/init.h> -+#include <linux/device.h> -+#include <linux/errno.h> -+#include <linux/types.h> -+#include <linux/stat.h> /* permission constants */ -+#include <linux/platform_device.h> -+#include <linux/io.h> -+ -+#include "dwc_otg_plat.h" -+#include "dwc_otg_attr.h" -+#include "dwc_otg_driver.h" -+#include "dwc_otg_cil.h" -+#ifndef DWC_HOST_ONLY -+#include "dwc_otg_pcd.h" -+#endif -+#include "dwc_otg_hcd.h" -+ -+#define DWC_DRIVER_VERSION "2.40a 10-APR-2006" -+#define DWC_DRIVER_DESC "HS OTG USB Controller driver" -+ -+static const char dwc_driver_name[] = "dwc_otg"; -+int dwc_errata_write_count; /* See dwc_otg_plat.h, dwc_write_reg32 */ -+ -+/*-------------------------------------------------------------------------*/ -+/* Encapsulate the module parameter settings */ -+ -+static struct dwc_otg_core_params dwc_otg_module_params = { -+ .opt = -1, -+ .otg_cap = -1, -+ .dma_enable = -1, -+ .dma_burst_size = -1, -+ .speed = -1, -+ .host_support_fs_ls_low_power = -1, -+ .host_ls_low_power_phy_clk = -1, -+ .enable_dynamic_fifo = -1, -+ .data_fifo_size = -1, -+ .dev_rx_fifo_size = -1, -+ .dev_nperio_tx_fifo_size = -1, -+ .dev_perio_tx_fifo_size = {-1, /* dev_perio_tx_fifo_size_1 */ -+ -1, -+ -1, -+ -1, -+ -1, -+ -1, -+ -1, -+ -1, -+ -1, -+ -1, -+ -1, -+ -1, -+ -1, -+ -1, -+ -1}, /* 15 */ -+ .host_rx_fifo_size = -1, -+ .host_nperio_tx_fifo_size = -1, -+ .host_perio_tx_fifo_size = -1, -+ .max_transfer_size = -1, -+ .max_packet_count = -1, -+ .host_channels = -1, -+ .dev_endpoints = -1, -+ .phy_type = -1, -+ .phy_utmi_width = -1, -+ .phy_ulpi_ddr = -1, -+ .phy_ulpi_ext_vbus = -1, -+ .i2c_enable = -1, -+ .ulpi_fs_ls = -1, -+ .ts_dline = -1, -+}; -+ -+/** -+ * Global Debug Level Mask. -+ */ -+uint32_t g_dbg_lvl; /* 0 -> OFF */ -+ -+/** -+ * This function shows the Driver Version. -+ */ -+static ssize_t version_show(struct device_driver *dev, char *buf) -+{ -+ return snprintf(buf, sizeof(DWC_DRIVER_VERSION) + 2, "%s\n", -+ DWC_DRIVER_VERSION); -+} -+ -+static DRIVER_ATTR(version, S_IRUGO, version_show, NULL); -+ -+/** -+ * This function is called during module intialization to verify that -+ * the module parameters are in a valid state. -+ */ -+static int check_parameters(struct dwc_otg_core_if *core_if) -+{ -+ int i; -+ int retval = 0; -+ -+/* Checks if the parameter is outside of its valid range of values */ -+#define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \ -+ ((dwc_otg_module_params._param_ < (_low_)) || \ -+ (dwc_otg_module_params._param_ > (_high_))) -+ -+/* If the parameter has been set by the user, check that the parameter value is -+ * within the value range of values. If not, report a module error. */ -+#define DWC_OTG_PARAM_ERR(_param_, _low_, _high_, _string_) \ -+ do { \ -+ if (dwc_otg_module_params._param_ != -1) { \ -+ if (DWC_OTG_PARAM_TEST(_param_, (_low_), (_high_))) { \ -+ DWC_ERROR("`%d' invalid for parameter `%s'\n", \ -+ dwc_otg_module_params._param_, _string_); \ -+ dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \ -+ retval++; \ -+ } \ -+ } \ -+ } while (0) -+ -+ DWC_OTG_PARAM_ERR(opt, 0, 1, "opt"); -+ DWC_OTG_PARAM_ERR(otg_cap, 0, 2, "otg_cap"); -+ DWC_OTG_PARAM_ERR(dma_enable, 0, 1, "dma_enable"); -+ DWC_OTG_PARAM_ERR(speed, 0, 1, "speed"); -+ DWC_OTG_PARAM_ERR(host_support_fs_ls_low_power, 0, 1, -+ "host_support_fs_ls_low_power"); -+ DWC_OTG_PARAM_ERR(host_ls_low_power_phy_clk, 0, 1, -+ "host_ls_low_power_phy_clk"); -+ DWC_OTG_PARAM_ERR(enable_dynamic_fifo, 0, 1, "enable_dynamic_fifo"); -+ DWC_OTG_PARAM_ERR(data_fifo_size, 32, 32768, "data_fifo_size"); -+ DWC_OTG_PARAM_ERR(dev_rx_fifo_size, 16, 32768, "dev_rx_fifo_size"); -+ DWC_OTG_PARAM_ERR(dev_nperio_tx_fifo_size, 16, 32768, -+ "dev_nperio_tx_fifo_size"); -+ DWC_OTG_PARAM_ERR(host_rx_fifo_size, 16, 32768, "host_rx_fifo_size"); -+ DWC_OTG_PARAM_ERR(host_nperio_tx_fifo_size, 16, 32768, -+ "host_nperio_tx_fifo_size"); -+ DWC_OTG_PARAM_ERR(host_perio_tx_fifo_size, 16, 32768, -+ "host_perio_tx_fifo_size"); -+ DWC_OTG_PARAM_ERR(max_transfer_size, 2047, 524288, "max_transfer_size"); -+ DWC_OTG_PARAM_ERR(max_packet_count, 15, 511, "max_packet_count"); -+ DWC_OTG_PARAM_ERR(host_channels, 1, 16, "host_channels"); -+ DWC_OTG_PARAM_ERR(dev_endpoints, 1, 15, "dev_endpoints"); -+ DWC_OTG_PARAM_ERR(phy_type, 0, 2, "phy_type"); -+ DWC_OTG_PARAM_ERR(phy_ulpi_ddr, 0, 1, "phy_ulpi_ddr"); -+ DWC_OTG_PARAM_ERR(phy_ulpi_ext_vbus, 0, 1, "phy_ulpi_ext_vbus"); -+ DWC_OTG_PARAM_ERR(i2c_enable, 0, 1, "i2c_enable"); -+ DWC_OTG_PARAM_ERR(ulpi_fs_ls, 0, 1, "ulpi_fs_ls"); -+ DWC_OTG_PARAM_ERR(ts_dline, 0, 1, "ts_dline"); -+ -+ if (dwc_otg_module_params.dma_burst_size != -1) { -+ if (DWC_OTG_PARAM_TEST(dma_burst_size, 1, 1) && -+ DWC_OTG_PARAM_TEST(dma_burst_size, 4, 4) && -+ DWC_OTG_PARAM_TEST(dma_burst_size, 8, 8) && -+ DWC_OTG_PARAM_TEST(dma_burst_size, 16, 16) && -+ DWC_OTG_PARAM_TEST(dma_burst_size, 32, 32) && -+ DWC_OTG_PARAM_TEST(dma_burst_size, 64, 64) && -+ DWC_OTG_PARAM_TEST(dma_burst_size, 128, 128) && -+ DWC_OTG_PARAM_TEST(dma_burst_size, 256, 256)) { -+ DWC_ERROR -+ ("`%d' invalid for parameter `dma_burst_size'\n", -+ dwc_otg_module_params.dma_burst_size); -+ dwc_otg_module_params.dma_burst_size = 32; -+ retval++; -+ } -+ } -+ -+ if (dwc_otg_module_params.phy_utmi_width != -1) { -+ if (DWC_OTG_PARAM_TEST(phy_utmi_width, 8, 8) && -+ DWC_OTG_PARAM_TEST(phy_utmi_width, 16, 16)) { -+ DWC_ERROR -+ ("`%d' invalid for parameter `phy_utmi_width'\n", -+ dwc_otg_module_params.phy_utmi_width); -+ dwc_otg_module_params.phy_utmi_width = 16; -+ retval++; -+ } -+ } -+ -+ for (i = 0; i < 15; i++) { -+ /* @todo should be like above */ -+ if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] != -+ (unsigned)-1) { -+ if (DWC_OTG_PARAM_TEST -+ (dev_perio_tx_fifo_size[i], 4, 768)) { -+ DWC_ERROR -+ ("`%d' invalid for parameter `%s_%d'\n", -+ dwc_otg_module_params. -+ dev_perio_tx_fifo_size[i], -+ "dev_perio_tx_fifo_size", i); -+ dwc_otg_module_params. -+ dev_perio_tx_fifo_size[i] = -+ dwc_param_dev_perio_tx_fifo_size_default; -+ retval++; -+ } -+ } -+ } -+ -+ /* At this point, all module parameters that have been set by the user -+ * are valid, and those that have not are left unset. Now set their -+ * default values and/or check the parameters against the hardware -+ * configurations of the OTG core. */ -+ -+/* This sets the parameter to the default value if it has not been set by the -+ * user */ -+#define PARAM_SET_DEFAULT(_param_) \ -+ ({ \ -+ int changed = 1; \ -+ if (dwc_otg_module_params._param_ == -1) { \ -+ changed = 0; \ -+ dwc_otg_module_params._param_ = dwc_param_##_param_##_default; \ -+ } \ -+ changed; \ -+ }) -+ -+/* This checks the macro agains the hardware configuration to see if it is -+ * valid. It is possible that the default value could be invalid. In this -+ * case, it will report a module error if the user touched the parameter. -+ * Otherwise it will adjust the value without any error. */ -+#define PARAM_CHECK_VALID(_param_, _str_, _is_valid_, _set_valid_) \ -+ ({ \ -+ int changed = PARAM_SET_DEFAULT(_param_); \ -+ int error = 0; \ -+ if (!(_is_valid_)) { \ -+ if (changed) { \ -+ DWC_ERROR("`%d' invalid for parameter `%s'. Check HW configuration.\n", dwc_otg_module_params._param_, _str_); \ -+ error = 1; \ -+ } \ -+ dwc_otg_module_params._param_ = (_set_valid_); \ -+ } \ -+ error; \ -+ }) -+ -+ /* OTG Cap */ -+ retval += PARAM_CHECK_VALID(otg_cap, "otg_cap", -+ ({ -+ int valid; -+ valid = 1; -+ switch (dwc_otg_module_params.otg_cap) { -+ case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE: -+ if (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) -+ valid = 0; -+ break; -+ case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE: -+ if ((core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) -+ && (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) -+ && (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) -+ && (core_if->hwcfg2.b.op_mode != DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) -+ valid = 0; -+ break; -+ case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE: -+ /* always valid */ -+ break; -+ } -+ valid; -+ }), -+ (((core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) -+ || (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) -+ || (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE) -+ || (core_if->hwcfg2.b.op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) -+ ? -+ DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE : DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE)); -+ -+ retval += PARAM_CHECK_VALID(dma_enable, "dma_enable", -+ ((dwc_otg_module_params. -+ dma_enable == 1) -+ && (core_if->hwcfg2.b. -+ architecture == 0)) ? 0 : 1, -+ 0); -+ -+ retval += PARAM_CHECK_VALID(opt, "opt", 1, 0); -+ -+ PARAM_SET_DEFAULT(dma_burst_size); -+ -+ retval += PARAM_CHECK_VALID(host_support_fs_ls_low_power, -+ "host_support_fs_ls_low_power", -+ 1, 0); -+ -+ retval += PARAM_CHECK_VALID(enable_dynamic_fifo, -+ "enable_dynamic_fifo", -+ ((dwc_otg_module_params.enable_dynamic_fifo == 0) -+ || (core_if->hwcfg2.b.dynamic_fifo == 1)), 0); -+ -+ retval += PARAM_CHECK_VALID(data_fifo_size, -+ "data_fifo_size", -+ dwc_otg_module_params.data_fifo_size <= core_if->hwcfg3.b.dfifo_depth, -+ core_if->hwcfg3.b.dfifo_depth); -+ -+ retval += PARAM_CHECK_VALID(dev_rx_fifo_size, -+ "dev_rx_fifo_size", -+ (dwc_otg_module_params.dev_rx_fifo_size <= -+ dwc_read_reg32(&core_if->core_global_regs->grxfsiz)), -+ dwc_read_reg32(&core_if->core_global_regs->grxfsiz)); -+ -+ retval += PARAM_CHECK_VALID(dev_nperio_tx_fifo_size, -+ "dev_nperio_tx_fifo_size", -+ dwc_otg_module_params.dev_nperio_tx_fifo_size <= -+ (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16), -+ dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16); -+ -+ retval += PARAM_CHECK_VALID(host_rx_fifo_size, -+ "host_rx_fifo_size", -+ dwc_otg_module_params.host_rx_fifo_size <= -+ dwc_read_reg32(&core_if->core_global_regs->grxfsiz), -+ dwc_read_reg32(&core_if->core_global_regs->grxfsiz)); -+ -+ retval += PARAM_CHECK_VALID(host_nperio_tx_fifo_size, -+ "host_nperio_tx_fifo_size", -+ dwc_otg_module_params.host_nperio_tx_fifo_size <= -+ (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16), -+ dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16); -+ -+ retval += PARAM_CHECK_VALID(host_perio_tx_fifo_size, -+ "host_perio_tx_fifo_size", -+ dwc_otg_module_params.host_perio_tx_fifo_size <= -+ (dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16), -+ (dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16)); -+ -+ retval += PARAM_CHECK_VALID(max_transfer_size, -+ "max_transfer_size", -+ dwc_otg_module_params.max_transfer_size < -+ (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11)), -+ (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11)) - 1); -+ -+ retval += PARAM_CHECK_VALID(max_packet_count, -+ "max_packet_count", -+ dwc_otg_module_params.max_packet_count < -+ (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)), -+ (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1); -+ -+ retval += PARAM_CHECK_VALID(host_channels, -+ "host_channels", -+ dwc_otg_module_params.host_channels <= (core_if->hwcfg2.b.num_host_chan + 1), -+ core_if->hwcfg2.b.num_host_chan + 1); -+ -+ retval += PARAM_CHECK_VALID(dev_endpoints, -+ "dev_endpoints", -+ dwc_otg_module_params.dev_endpoints <= core_if->hwcfg2.b.num_dev_ep, -+ core_if->hwcfg2.b.num_dev_ep); -+ -+/* -+ * Define the following to disable the FS PHY Hardware checking. This is for -+ * internal testing only. -+ * -+ * #define NO_FS_PHY_HW_CHECKS -+ */ -+ -+#ifdef NO_FS_PHY_HW_CHECKS -+ retval += PARAM_CHECK_VALID(phy_type, "phy_type", 1, 0); -+#else -+ retval += PARAM_CHECK_VALID(phy_type, "phy_type", -+ ({ -+ int valid = 0; -+ if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_UTMI) && ((core_if->hwcfg2.b.hs_phy_type == 1) || (core_if->hwcfg2.b.hs_phy_type == 3))) -+ valid = 1; -+ else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_ULPI) && ((core_if->hwcfg2.b.hs_phy_type == 2) || (core_if->hwcfg2.b.hs_phy_type == 3))) -+ valid = 1; -+ else if ((dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) && (core_if->hwcfg2.b.fs_phy_type == 1)) -+ valid = 1; -+ valid; -+ }), -+ ({ -+ int set = DWC_PHY_TYPE_PARAM_FS; -+ if (core_if->hwcfg2.b.hs_phy_type) { -+ if ((core_if->hwcfg2.b.hs_phy_type == 3) -+ || (core_if->hwcfg2.b.hs_phy_type == 1)) -+ set = DWC_PHY_TYPE_PARAM_UTMI; -+ else -+ set = DWC_PHY_TYPE_PARAM_ULPI; -+ } -+ set; -+ })); -+#endif -+ -+ retval += PARAM_CHECK_VALID(speed, "speed", -+ dwc_otg_module_params.speed == 0 -+ && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1, -+ dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS ? 1 : 0); -+ -+ retval += PARAM_CHECK_VALID(host_ls_low_power_phy_clk, -+ "host_ls_low_power_phy_clk", -+ dwc_otg_module_params.host_ls_low_power_phy_clk == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ -+ && (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? 0 : 1, -+ (dwc_otg_module_params.phy_type == DWC_PHY_TYPE_PARAM_FS) ? -+ DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ : DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ); -+ -+ PARAM_SET_DEFAULT(phy_ulpi_ddr); -+ PARAM_SET_DEFAULT(phy_ulpi_ext_vbus); -+ PARAM_SET_DEFAULT(phy_utmi_width); -+ PARAM_SET_DEFAULT(ulpi_fs_ls); -+ PARAM_SET_DEFAULT(ts_dline); -+ -+#ifdef NO_FS_PHY_HW_CHECKS -+ retval += PARAM_CHECK_VALID(i2c_enable, "i2c_enable", 1, 0); -+#else -+ retval += PARAM_CHECK_VALID(i2c_enable, "i2c_enable", -+ dwc_otg_module_params.i2c_enable == 1 -+ && (core_if->hwcfg3.b.i2c == 0) ? 0 : 1, 0); -+#endif -+ -+ for (i = 0; i < 15; i++) { -+ -+ int changed = 1; -+ int error = 0; -+ -+ if (dwc_otg_module_params.dev_perio_tx_fifo_size[i] == -1) { -+ changed = 0; -+ dwc_otg_module_params.dev_perio_tx_fifo_size[i] = -+ dwc_param_dev_perio_tx_fifo_size_default; -+ } -+ if (! -+ (dwc_otg_module_params.dev_perio_tx_fifo_size[i] <= -+ (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz[i])))) { -+ if (changed) { -+ DWC_ERROR("`%d' invalid for parameter " -+ "`dev_perio_fifo_size_%d'. " -+ "Check HW configuration.\n", -+ dwc_otg_module_params. -+ dev_perio_tx_fifo_size[i], i); -+ error = 1; -+ } -+ dwc_otg_module_params.dev_perio_tx_fifo_size[i] = -+ dwc_read_reg32(&core_if->core_global_regs-> -+ dptxfsiz[i]); -+ } -+ retval += error; -+ } -+ -+ return retval; -+} -+ -+/** -+ * This function is the top level interrupt handler for the Common -+ * (Device and host modes) interrupts. -+ */ -+static irqreturn_t dwc_otg_common_irq(int _irq, void *_dev) -+{ -+ struct dwc_otg_device *otg_dev = _dev; -+ int32_t retval = IRQ_NONE; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&otg_dev->hcd->global_lock, flags); -+ -+ retval = dwc_otg_handle_common_intr(otg_dev->core_if); -+ -+ spin_unlock_irqrestore(&otg_dev->hcd->global_lock, flags); -+ -+ return IRQ_RETVAL(retval); -+} -+ -+/** -+ * This function is called when a device is unregistered with the -+ * dwc_otg_driver. This happens, for example, when the rmmod command is -+ * executed. The device may or may not be electrically present. If it is -+ * present, the driver stops device processing. Any resources used on behalf -+ * of this device are freed. -+ * -+ * @dev: -+ */ -+static int dwc_otg_driver_remove(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct dwc_otg_device *otg_dev = dev->platform_data; -+ DWC_DEBUGPL(DBG_ANY, "%s(%p)\n", __func__, dev); -+ -+ if (otg_dev == NULL) -+ /* Memory allocation for the dwc_otg_device failed. */ -+ return -ENOMEM; -+ -+ /* -+ * Free the IRQ -+ */ -+ if (otg_dev->common_irq_installed) -+ free_irq(platform_get_irq(to_platform_device(dev), 0), otg_dev); -+ -+#ifndef DWC_DEVICE_ONLY -+ if (otg_dev->hcd != NULL) -+ dwc_otg_hcd_remove(dev); -+#endif -+ -+#ifndef DWC_HOST_ONLY -+ if (otg_dev->pcd != NULL) -+ dwc_otg_pcd_remove(dev); -+#endif -+ if (otg_dev->core_if != NULL) -+ dwc_otg_cil_remove(otg_dev->core_if); -+ -+ /* -+ * Remove the device attributes -+ */ -+ dwc_otg_attr_remove(dev); -+ -+ /* -+ * Clear the platform_data pointer. -+ */ -+ dev->platform_data = 0; -+ return 0; -+} -+ -+/** -+ * This function is called when an device is bound to a -+ * dwc_otg_driver. It creates the driver components required to -+ * control the device (CIL, HCD, and PCD) and it initializes the -+ * device. The driver components are stored in a dwc_otg_device -+ * structure. A reference to the dwc_otg_device is saved in the -+ * device. This allows the driver to access the dwc_otg_device -+ * structure on subsequent calls to driver methods for this device. -+ * -+ * @dev: device definition -+ */ -+static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) -+{ -+ struct resource *res_base; -+ struct device *dev = &pdev->dev; -+ struct dwc_otg_device *dwc_otg_device; -+ int32_t snpsid; -+ unsigned long flags; -+ int irq; -+ int retval; -+ -+ dev_dbg(dev, "dwc_otg_driver_probe(%p)\n", dev); -+ -+ dwc_otg_device = devm_kzalloc(&pdev->dev, -+ sizeof(struct dwc_otg_device), -+ GFP_KERNEL); -+ if (!dwc_otg_device) { -+ dev_err(dev, "kmalloc of dwc_otg_device failed\n"); -+ return -ENOMEM; -+ } -+ dwc_otg_device->reg_offset = 0xFFFFFFFF; -+ -+ /* -+ * Map the DWC_otg Core memory into virtual address space. -+ */ -+ res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res_base) -+ goto err_ports; -+ -+ dwc_otg_device->base = -+ devm_ioremap_nocache(&pdev->dev, -+ res_base->start, -+ res_base->end - res_base->start); -+ -+ if (!dwc_otg_device->base) -+ goto err_ports; -+ -+ dev_dbg(dev, "base=%p\n", dwc_otg_device->base); -+ -+ /* -+ * Attempt to ensure this device is really a DWC_otg Controller. -+ * Read and verify the SNPSID register contents. The value should be -+ * 0x45F42XXX, which corresponds to "OT2", as in "OTG version 2.XX". -+ */ -+ snpsid = -+ dwc_read_reg32((uint32_t *) ((uint8_t *) dwc_otg_device->base + -+ 0x40)); -+ if ((snpsid & 0xFFFFF000) != 0x4F542000) { -+ dev_err(dev, "Bad value for SNPSID: 0x%08x\n", snpsid); -+ goto err_ports; -+ } -+ -+ /* -+ * Initialize driver data to point to the global DWC_otg -+ * Device structure. -+ */ -+ dev->platform_data = dwc_otg_device; -+ dev_dbg(dev, "dwc_otg_device=0x%p\n", dwc_otg_device); -+ -+ dwc_otg_device->core_if = dwc_otg_cil_init(dwc_otg_device->base, -+ &dwc_otg_module_params); -+ if (dwc_otg_device->core_if == 0) { -+ dev_err(dev, "CIL initialization failed!\n"); -+ goto err_ports; -+ } -+ dwc_otg_device->core_if->usb_num = to_platform_device(dev)->id; -+ -+ /* -+ * Validate parameter values. -+ */ -+ if (check_parameters(dwc_otg_device->core_if) != 0) -+ goto err_ports; -+ -+ /* -+ * Create Device Attributes in sysfs -+ */ -+ dwc_otg_attr_create(dev); -+ -+ /* -+ * Disable the global interrupt until all the interrupt -+ * handlers are installed. -+ */ -+ dwc_otg_disable_global_interrupts(dwc_otg_device->core_if); -+ /* -+ * Install the interrupt handler for the common interrupts before -+ * enabling common interrupts in core_init below. -+ */ -+ irq = platform_get_irq(to_platform_device(dev), 0); -+ DWC_DEBUGPL(DBG_CIL, "registering (common) handler for irq%d\n", irq); -+ retval = request_irq(irq, dwc_otg_common_irq, -+ IRQF_SHARED, "dwc_otg", dwc_otg_device); -+ if (retval != 0) { -+ DWC_ERROR("request of irq%d failed\n", irq); -+ goto err_ports; -+ } else { -+ dwc_otg_device->common_irq_installed = 1; -+ } -+ -+ /* -+ * Initialize the DWC_otg core. -+ */ -+ dwc_otg_core_init(dwc_otg_device->core_if); -+ -+#ifndef DWC_HOST_ONLY -+ /* -+ * Initialize the PCD -+ */ -+ retval = dwc_otg_pcd_init(dev); -+ if (retval != 0) { -+ DWC_ERROR("dwc_otg_pcd_init failed\n"); -+ dwc_otg_device->pcd = NULL; -+ goto err_ports; -+ } -+#endif -+#ifndef DWC_DEVICE_ONLY -+ /* -+ * Initialize the HCD -+ */ -+ retval = dwc_otg_hcd_init(dev); -+ if (retval != 0) { -+ DWC_ERROR("dwc_otg_hcd_init failed\n"); -+ dwc_otg_device->hcd = NULL; -+ goto err_ports; -+ } -+#endif -+ -+ /* -+ * Enable the global interrupt after all the interrupt -+ * handlers are installed. -+ */ -+ local_irq_save(flags); -+ dwc_otg_enable_global_interrupts(dwc_otg_device->core_if); -+ local_irq_restore(flags); -+ -+ return 0; -+ -+err_ports: -+ devm_kfree(&pdev->dev, dwc_otg_device); -+ return -ENOENT; -+} -+ -+/** -+ * This structure defines the methods to be called by a bus driver -+ * during the lifecycle of a device on that bus. Both drivers and -+ * devices are registered with a bus driver. The bus driver matches -+ * devices to drivers based on information in the device and driver -+ * structures. -+ * -+ * The probe function is called when the bus driver matches a device -+ * to this driver. The remove function is called when a device is -+ * unregistered with the bus driver. -+ */ -+static struct platform_driver dwc_otg_driver = { -+ .probe = dwc_otg_driver_probe, -+ .remove = dwc_otg_driver_remove, -+ .driver = { -+ .name = dwc_driver_name, -+ .owner = THIS_MODULE}, -+}; -+ -+/** -+ * This function is called when the dwc_otg_driver is installed with the -+ * insmod command. It registers the dwc_otg_driver structure with the -+ * appropriate bus driver. This will cause the dwc_otg_driver_probe function -+ * to be called. In addition, the bus driver will automatically expose -+ * attributes defined for the device and driver in the special sysfs file -+ * system. -+ * -+ * Returns -+ */ -+static int __init dwc_otg_driver_init(void) -+{ -+ int retval; -+ -+ pr_info("%s: version %s\n", dwc_driver_name, DWC_DRIVER_VERSION); -+ -+ /* Though core was configured for external dma override that with slave -+ mode only for CN31XX. DMA is broken in this chip */ -+ if (OCTEON_IS_MODEL(OCTEON_CN31XX)) -+ dwc_otg_module_params.dma_enable = 0; -+ -+ retval = platform_driver_register(&dwc_otg_driver); -+ -+ if (retval < 0) { -+ pr_err("%s retval=%d\n", __func__, retval); -+ return retval; -+ } -+ if (driver_create_file(&dwc_otg_driver.driver, &driver_attr_version)) -+ pr_warning("DWC_OTG: Failed to create driver version file\n"); -+ -+ return retval; -+} -+module_init(dwc_otg_driver_init); -+ -+/** -+ * This function is called when the driver is removed from the kernel -+ * with the rmmod command. The driver unregisters itself with its bus -+ * driver. -+ * -+ */ -+static void __exit dwc_otg_driver_cleanup(void) -+{ -+ printk(KERN_DEBUG "dwc_otg_driver_cleanup()\n"); -+ -+ driver_remove_file(&dwc_otg_driver.driver, &driver_attr_version); -+ -+ platform_driver_unregister(&dwc_otg_driver); -+ -+ printk(KERN_INFO "%s module removed\n", dwc_driver_name); -+} -+module_exit(dwc_otg_driver_cleanup); -+ -+MODULE_DESCRIPTION(DWC_DRIVER_DESC); -+MODULE_AUTHOR("Synopsys Inc."); -+MODULE_LICENSE("GPL"); -+ -+module_param_named(otg_cap, dwc_otg_module_params.otg_cap, int, 0444); -+MODULE_PARM_DESC(otg_cap, "OTG Capabilities 0=HNP&SRP 1=SRP Only 2=None"); -+module_param_named(opt, dwc_otg_module_params.opt, int, 0444); -+MODULE_PARM_DESC(opt, "OPT Mode"); -+module_param_named(dma_enable, dwc_otg_module_params.dma_enable, int, 0444); -+MODULE_PARM_DESC(dma_enable, "DMA Mode 0=Slave 1=DMA enabled"); -+module_param_named(dma_burst_size, dwc_otg_module_params.dma_burst_size, int, -+ 0444); -+MODULE_PARM_DESC(dma_burst_size, -+ "DMA Burst Size 1, 4, 8, 16, 32, 64, 128, 256"); -+module_param_named(speed, dwc_otg_module_params.speed, int, 0444); -+MODULE_PARM_DESC(speed, "Speed 0=High Speed 1=Full Speed"); -+module_param_named(host_support_fs_ls_low_power, -+ dwc_otg_module_params.host_support_fs_ls_low_power, int, -+ 0444); -+MODULE_PARM_DESC(host_support_fs_ls_low_power, -+ "Support Low Power w/FS or LS 0=Support 1=Don't Support"); -+module_param_named(host_ls_low_power_phy_clk, -+ dwc_otg_module_params.host_ls_low_power_phy_clk, int, 0444); -+MODULE_PARM_DESC(host_ls_low_power_phy_clk, -+ "Low Speed Low Power Clock 0=48Mhz 1=6Mhz"); -+module_param_named(enable_dynamic_fifo, -+ dwc_otg_module_params.enable_dynamic_fifo, int, 0444); -+MODULE_PARM_DESC(enable_dynamic_fifo, "0=cC Setting 1=Allow Dynamic Sizing"); -+module_param_named(data_fifo_size, dwc_otg_module_params.data_fifo_size, int, -+ 0444); -+MODULE_PARM_DESC(data_fifo_size, -+ "Total number of words in the data FIFO memory 32-32768"); -+module_param_named(dev_rx_fifo_size, dwc_otg_module_params.dev_rx_fifo_size, -+ int, 0444); -+MODULE_PARM_DESC(dev_rx_fifo_size, "Number of words in the Rx FIFO 16-32768"); -+module_param_named(dev_nperio_tx_fifo_size, -+ dwc_otg_module_params.dev_nperio_tx_fifo_size, int, 0444); -+MODULE_PARM_DESC(dev_nperio_tx_fifo_size, -+ "Number of words in the non-periodic Tx FIFO 16-32768"); -+module_param_named(dev_perio_tx_fifo_size_1, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[0], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_1, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_2, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[1], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_2, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_3, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[2], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_3, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_4, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[3], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_4, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_5, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[4], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_5, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_6, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[5], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_6, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_7, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[6], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_7, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_8, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[7], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_8, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_9, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[8], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_9, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_10, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[9], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_10, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_11, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[10], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_11, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_12, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[11], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_12, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_13, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[12], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_13, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_14, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[13], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_14, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(dev_perio_tx_fifo_size_15, -+ dwc_otg_module_params.dev_perio_tx_fifo_size[14], int, 0444); -+MODULE_PARM_DESC(dev_perio_tx_fifo_size_15, -+ "Number of words in the periodic Tx FIFO 4-768"); -+module_param_named(host_rx_fifo_size, dwc_otg_module_params.host_rx_fifo_size, -+ int, 0444); -+MODULE_PARM_DESC(host_rx_fifo_size, "Number of words in the Rx FIFO 16-32768"); -+module_param_named(host_nperio_tx_fifo_size, -+ dwc_otg_module_params.host_nperio_tx_fifo_size, int, 0444); -+MODULE_PARM_DESC(host_nperio_tx_fifo_size, -+ "Number of words in the non-periodic Tx FIFO 16-32768"); -+module_param_named(host_perio_tx_fifo_size, -+ dwc_otg_module_params.host_perio_tx_fifo_size, int, 0444); -+MODULE_PARM_DESC(host_perio_tx_fifo_size, -+ "Number of words in the host periodic Tx FIFO 16-32768"); -+module_param_named(max_transfer_size, dwc_otg_module_params.max_transfer_size, -+ int, 0444); -+/** @todo Set the max to 512K, modify checks */ -+MODULE_PARM_DESC(max_transfer_size, -+ "The maximum transfer size supported in bytes 2047-65535"); -+module_param_named(max_packet_count, dwc_otg_module_params.max_packet_count, -+ int, 0444); -+MODULE_PARM_DESC(max_packet_count, -+ "The maximum number of packets in a transfer 15-511"); -+module_param_named(host_channels, dwc_otg_module_params.host_channels, int, -+ 0444); -+MODULE_PARM_DESC(host_channels, -+ "The number of host channel registers to use 1-16"); -+module_param_named(dev_endpoints, dwc_otg_module_params.dev_endpoints, int, -+ 0444); -+MODULE_PARM_DESC(dev_endpoints, -+ "The number of endpoints in addition to EP0 available " -+ "for device mode 1-15"); -+module_param_named(phy_type, dwc_otg_module_params.phy_type, int, 0444); -+MODULE_PARM_DESC(phy_type, "0=Reserved 1=UTMI+ 2=ULPI"); -+module_param_named(phy_utmi_width, dwc_otg_module_params.phy_utmi_width, int, -+ 0444); -+MODULE_PARM_DESC(phy_utmi_width, "Specifies the UTMI+ Data Width 8 or 16 bits"); -+module_param_named(phy_ulpi_ddr, dwc_otg_module_params.phy_ulpi_ddr, int, 0444); -+MODULE_PARM_DESC(phy_ulpi_ddr, -+ "ULPI at double or single data rate 0=Single 1=Double"); -+module_param_named(phy_ulpi_ext_vbus, dwc_otg_module_params.phy_ulpi_ext_vbus, -+ int, 0444); -+MODULE_PARM_DESC(phy_ulpi_ext_vbus, -+ "ULPI PHY using internal or external vbus 0=Internal"); -+module_param_named(i2c_enable, dwc_otg_module_params.i2c_enable, int, 0444); -+MODULE_PARM_DESC(i2c_enable, "FS PHY Interface"); -+module_param_named(ulpi_fs_ls, dwc_otg_module_params.ulpi_fs_ls, int, 0444); -+MODULE_PARM_DESC(ulpi_fs_ls, "ULPI PHY FS/LS mode only"); -+module_param_named(ts_dline, dwc_otg_module_params.ts_dline, int, 0444); -+MODULE_PARM_DESC(ts_dline, "Term select Dline pulsing for all PHYs"); -+module_param_named(debug, g_dbg_lvl, int, 0644); -+MODULE_PARM_DESC(debug, ""); -+ -+/** @page "Module Parameters" -+ * -+ * The following parameters may be specified when starting the module. -+ * These parameters define how the DWC_otg controller should be -+ * configured. Parameter values are passed to the CIL initialization -+ * function dwc_otg_cil_init -+ * -+ * Example: <code>modprobe dwc_otg speed=1 otg_cap=1</code> -+ * -+ -+ <table> -+ <tr><td>Parameter Name</td><td>Meaning</td></tr> -+ -+ <tr> -+ <td>otg_cap</td> -+ <td>Specifies the OTG capabilities. The driver will automatically detect the -+ value for this parameter if none is specified. -+ - 0: HNP and SRP capable (default, if available) -+ - 1: SRP Only capable -+ - 2: No HNP/SRP capable -+ </td></tr> -+ -+ <tr> -+ <td>dma_enable</td> -+ <td>Specifies whether to use slave or DMA mode for accessing the data FIFOs. -+ The driver will automatically detect the value for this parameter if none is -+ specified. -+ - 0: Slave -+ - 1: DMA (default, if available) -+ </td></tr> -+ -+ <tr> -+ <td>dma_burst_size</td> -+ <td>The DMA Burst size (applicable only for External DMA Mode). -+ - Values: 1, 4, 8 16, 32, 64, 128, 256 (default 32) -+ </td></tr> -+ -+ <tr> -+ <td>speed</td> -+ <td>Specifies the maximum speed of operation in host and device mode. The -+ actual speed depends on the speed of the attached device and the value of -+ phy_type. -+ - 0: High Speed (default) -+ - 1: Full Speed -+ </td></tr> -+ -+ <tr> -+ <td>host_support_fs_ls_low_power</td> -+ <td>Specifies whether low power mode is supported when attached to a Full -+ Speed or Low Speed device in host mode. -+ - 0: Don't support low power mode (default) -+ - 1: Support low power mode -+ </td></tr> -+ -+ <tr> -+ <td>host_ls_low_power_phy_clk</td> -+ <td>Specifies the PHY clock rate in low power mode when connected to a Low -+ Speed device in host mode. This parameter is applicable only if -+ HOST_SUPPORT_FS_LS_LOW_POWER is enabled. -+ - 0: 48 MHz (default) -+ - 1: 6 MHz -+ </td></tr> -+ -+ <tr> -+ <td>enable_dynamic_fifo</td> -+ <td> Specifies whether FIFOs may be resized by the driver software. -+ - 0: Use cC FIFO size parameters -+ - 1: Allow dynamic FIFO sizing (default) -+ </td></tr> -+ -+ <tr> -+ <td>data_fifo_size</td> -+ <td>Total number of 4-byte words in the data FIFO memory. This memory -+ includes the Rx FIFO, non-periodic Tx FIFO, and periodic Tx FIFOs. -+ - Values: 32 to 32768 (default 8192) -+ -+ Note: The total FIFO memory depth in the FPGA configuration is 8192. -+ </td></tr> -+ -+ <tr> -+ <td>dev_rx_fifo_size</td> -+ <td>Number of 4-byte words in the Rx FIFO in device mode when dynamic -+ FIFO sizing is enabled. -+ - Values: 16 to 32768 (default 1064) -+ </td></tr> -+ -+ <tr> -+ <td>dev_nperio_tx_fifo_size</td> -+ <td>Number of 4-byte words in the non-periodic Tx FIFO in device mode when -+ dynamic FIFO sizing is enabled. -+ - Values: 16 to 32768 (default 1024) -+ </td></tr> -+ -+ <tr> -+ <td>dev_perio_tx_fifo_size_n (n = 1 to 15)</td> -+ <td>Number of 4-byte words in each of the periodic Tx FIFOs in device mode -+ when dynamic FIFO sizing is enabled. -+ - Values: 4 to 768 (default 256) -+ </td></tr> -+ -+ <tr> -+ <td>host_rx_fifo_size</td> -+ <td>Number of 4-byte words in the Rx FIFO in host mode when dynamic FIFO -+ sizing is enabled. -+ - Values: 16 to 32768 (default 1024) -+ </td></tr> -+ -+ <tr> -+ <td>host_nperio_tx_fifo_size</td> -+ <td>Number of 4-byte words in the non-periodic Tx FIFO in host mode when -+ dynamic FIFO sizing is enabled in the core. -+ - Values: 16 to 32768 (default 1024) -+ </td></tr> -+ -+ <tr> -+ <td>host_perio_tx_fifo_size</td> -+ <td>Number of 4-byte words in the host periodic Tx FIFO when dynamic FIFO -+ sizing is enabled. -+ - Values: 16 to 32768 (default 1024) -+ </td></tr> -+ -+ <tr> -+ <td>max_transfer_size</td> -+ <td>The maximum transfer size supported in bytes. -+ - Values: 2047 to 65,535 (default 65,535) -+ </td></tr> -+ -+ <tr> -+ <td>max_packet_count</td> -+ <td>The maximum number of packets in a transfer. -+ - Values: 15 to 511 (default 511) -+ </td></tr> -+ -+ <tr> -+ <td>host_channels</td> -+ <td>The number of host channel registers to use. -+ - Values: 1 to 16 (default 12) -+ -+ Note: The FPGA configuration supports a maximum of 12 host channels. -+ </td></tr> -+ -+ <tr> -+ <td>dev_endpoints</td> -+ <td>The number of endpoints in addition to EP0 available for device mode -+ operations. -+ - Values: 1 to 15 (default 6 IN and OUT) -+ -+ Note: The FPGA configuration supports a maximum of 6 IN and OUT endpoints in -+ addition to EP0. -+ </td></tr> -+ -+ <tr> -+ <td>phy_type</td> -+ <td>Specifies the type of PHY interface to use. By default, the driver will -+ automatically detect the phy_type. -+ - 0: Full Speed -+ - 1: UTMI+ (default, if available) -+ - 2: ULPI -+ </td></tr> -+ -+ <tr> -+ <td>phy_utmi_width</td> -+ <td>Specifies the UTMI+ Data Width. This parameter is applicable for a -+ phy_type of UTMI+. Also, this parameter is applicable only if the -+ OTG_HSPHY_WIDTH cC parameter was set to "8 and 16 bits", meaning that the -+ core has been configured to work at either data path width. -+ - Values: 8 or 16 bits (default 16) -+ </td></tr> -+ -+ <tr> -+ <td>phy_ulpi_ddr</td> -+ <td>Specifies whether the ULPI operates at double or single data rate. This -+ parameter is only applicable if phy_type is ULPI. -+ - 0: single data rate ULPI interface with 8 bit wide data bus (default) -+ - 1: double data rate ULPI interface with 4 bit wide data bus -+ </td></tr> -+ -+ <tr> -+ <td>i2c_enable</td> -+ <td>Specifies whether to use the I2C interface for full speed PHY. This -+ parameter is only applicable if PHY_TYPE is FS. -+ - 0: Disabled (default) -+ - 1: Enabled -+ </td></tr> -+ -+*/ -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_plat.h b/drivers/usb/host/dwc_otg/dwc_otg_plat.h -new file mode 100644 -index 0000000..93ef282 ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_plat.h -@@ -0,0 +1,236 @@ -+/* ========================================================================== -+ * -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+ -+#if !defined(__DWC_OTG_PLAT_H__) -+#define __DWC_OTG_PLAT_H__ -+ -+#include <linux/types.h> -+#include <linux/slab.h> -+#include <linux/list.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <linux/io.h> -+ -+#include <asm/octeon/octeon.h> -+#include <asm/octeon/cvmx-usbnx-defs.h> -+ -+#define SZ_256K 0x00040000 -+#ifndef CONFIG_64BIT -+#define OCTEON_USB_BASE_ADDRESS 0x80016F0010000000ull -+#endif -+ -+/** -+ * @file -+ * -+ * This file contains the Platform Specific constants, interfaces -+ * (functions and macros) for Linux. -+ * -+ */ -+ -+/** -+ * Reads the content of a register. -+ * -+ * @_reg: address of register to read. -+ * Returns contents of the register. -+ * -+ -+ * Usage:<br> -+ * <code>uint32_t dev_ctl = dwc_read_reg32(&dev_regs->dctl);</code> -+ */ -+static inline uint32_t dwc_read_reg32(uint32_t *_reg) -+{ -+ uint32_t result; -+ /* USB device registers on Octeon are 32bit address swapped */ -+#ifdef CONFIG_64BIT -+ uint64_t address = (unsigned long)_reg ^ 4; -+#else -+ uint64_t address = OCTEON_USB_BASE_ADDRESS | ((unsigned long)_reg ^ 4); -+#endif -+ result = cvmx_read64_uint32(address); -+ return result; -+}; -+ -+/** -+ * Writes a register with a 32 bit value. -+ * -+ * @_reg: address of register to read. -+ * @_value: to write to _reg. -+ * -+ * Usage:<br> -+ * <code>dwc_write_reg32(&dev_regs->dctl, 0); </code> -+ */ -+static inline void dwc_write_reg32(uint32_t *_reg, -+ const uint32_t _value) -+{ -+ /* USB device registers on Octeon are 32bit address swapped */ -+#ifdef CONFIG_64BIT -+ uint64_t address = (unsigned long)_reg ^ 4; -+#else -+ uint64_t address = OCTEON_USB_BASE_ADDRESS | ((unsigned long)_reg ^ 4); -+#endif -+ wmb(); -+ cvmx_write64_uint32(address, _value); -+ -+#ifdef CONFIG_CPU_CAVIUM_OCTEON -+ /* O2P/O1P pass 1 bug workaround: A read must occur for at least -+ every 3rd write to insure that the writes do not overrun the -+ USBN. */ -+ if (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX)) { -+ extern int dwc_errata_write_count; -+ if (++dwc_errata_write_count > 2) { -+ cvmx_read_csr(CVMX_USBNX_DMA0_INB_CHN0(0)); -+ dwc_errata_write_count = 0; -+ } -+ } -+#endif -+}; -+ -+/** -+ * This function modifies bit values in a register. Using the -+ * algorithm: (reg_contents & ~clear_mask) | set_mask. -+ * -+ * @_reg: address of register to read. -+ * @_clear_mask: bit mask to be cleared. -+ * @_set_mask: bit mask to be set. -+ * -+ * Usage:<br> -+ * <code> // Clear the SOF Interrupt Mask bit and <br> -+ * // set the OTG Interrupt mask bit, leaving all others as they were. -+ * dwc_modify_reg32(&dev_regs->gintmsk, DWC_SOF_INT, DWC_OTG_INT);</code> -+ */ -+static inline void dwc_modify_reg32(uint32_t *_reg, -+ const uint32_t _clear_mask, -+ const uint32_t _set_mask) -+{ -+ uint32_t value = dwc_read_reg32(_reg); -+ value &= ~_clear_mask; -+ value |= _set_mask; -+ dwc_write_reg32(_reg, value); -+}; -+ -+/* -+ * Debugging support vanishes in non-debug builds. -+ */ -+ -+/** -+ * The Debug Level bit-mask variable. -+ */ -+extern uint32_t g_dbg_lvl; -+/** -+ * Set the Debug Level variable. -+ */ -+static inline uint32_t SET_DEBUG_LEVEL(const uint32_t _new) -+{ -+ uint32_t old = g_dbg_lvl; -+ g_dbg_lvl = _new; -+ return old; -+} -+ -+/** When debug level has the DBG_CIL bit set, display CIL Debug messages. */ -+#define DBG_CIL (0x2) -+/** When debug level has the DBG_CILV bit set, display CIL Verbose debug -+ * messages */ -+#define DBG_CILV (0x20) -+/** When debug level has the DBG_PCD bit set, display PCD (Device) debug -+ * messages */ -+#define DBG_PCD (0x4) -+/** When debug level has the DBG_PCDV set, display PCD (Device) Verbose debug -+ * messages */ -+#define DBG_PCDV (0x40) -+/** When debug level has the DBG_HCD bit set, display Host debug messages */ -+#define DBG_HCD (0x8) -+/** When debug level has the DBG_HCDV bit set, display Verbose Host debug -+ * messages */ -+#define DBG_HCDV (0x80) -+/** When debug level has the DBG_HCD_URB bit set, display enqueued URBs in host -+ * mode. */ -+#define DBG_HCD_URB (0x800) -+ -+/** When debug level has any bit set, display debug messages */ -+#define DBG_ANY (0xFF) -+ -+/** All debug messages off */ -+#define DBG_OFF 0 -+ -+/** Prefix string for DWC_DEBUG print macros. */ -+#define USB_DWC "DWC_otg: " -+ -+/** -+ * Print a debug message when the Global debug level variable contains -+ * the bit defined in <code>lvl</code>. -+ * -+ * @lvl: - Debug level, use one of the DBG_ constants above. -+ * @x: - like printf -+ * -+ * Example:<p> -+ * <code> -+ * DWC_DEBUGPL( DBG_ANY, "%s(%p)\n", __func__, _reg_base_addr); -+ * </code> -+ * <br> -+ * results in:<br> -+ * <code> -+ * usb-DWC_otg: dwc_otg_cil_init(ca867000) -+ * </code> -+ */ -+#ifdef DEBUG -+ -+# define DWC_DEBUGPL(lvl, x...) \ -+ do { \ -+ if ((lvl)&g_dbg_lvl) \ -+ printk(KERN_DEBUG USB_DWC x); \ -+ } while (0) -+# define DWC_DEBUGP(x...) DWC_DEBUGPL(DBG_ANY, x) -+ -+# define CHK_DEBUG_LEVEL(level) ((level) & g_dbg_lvl) -+ -+#else -+ -+# define DWC_DEBUGPL(lvl, x...) do { } while (0) -+# define DWC_DEBUGP(x...) -+ -+# define CHK_DEBUG_LEVEL(level) (0) -+ -+#endif /*DEBUG*/ -+/* -+ * Print an Error message. -+ */ -+#define DWC_ERROR(x...) printk(KERN_ERR USB_DWC x) -+/* -+ * Print a Warning message. -+ */ -+#define DWC_WARN(x...) printk(KERN_WARNING USB_DWC x) -+/* -+ * Print a notice (normal but significant message). -+ */ -+#define DWC_NOTICE(x...) printk(KERN_NOTICE USB_DWC x) -+/* -+ * Basic message printing. -+ */ -+#define DWC_PRINT(x...) printk(KERN_INFO USB_DWC x) -+#endif -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_regs.h b/drivers/usb/host/dwc_otg/dwc_otg_regs.h -new file mode 100644 -index 0000000..34cc4f7 ---- /dev/null -+++ b/drivers/usb/host/dwc_otg/dwc_otg_regs.h -@@ -0,0 +1,2355 @@ -+/* ========================================================================== -+ * -+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, -+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless -+ * otherwise expressly agreed to in writing between Synopsys and you. -+ * -+ * The Software IS NOT an item of Licensed Software or Licensed Product under -+ * any End User Software License Agreement or Agreement for Licensed Product -+ * with Synopsys or any supplement thereto. You are permitted to use and -+ * redistribute this Software in source and binary forms, with or without -+ * modification, provided that redistributions of source code must retain this -+ * notice. You may not view, use, disclose, copy or distribute this file or -+ * any information contained herein except pursuant to this license grant from -+ * Synopsys. If you do not agree with this notice, including the disclaimer -+ * below, then you are not authorized to use the Software. -+ * -+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * ========================================================================== */ -+ -+#ifndef __DWC_OTG_REGS_H__ -+#define __DWC_OTG_REGS_H__ -+ -+/* -+ * -+ * This file contains the data structures for accessing the DWC_otg -+ * core registers. -+ * -+ * The application interfaces with the HS OTG core by reading from and -+ * writing to the Control and Status Register (CSR) space through the -+ * AHB Slave interface. These registers are 32 bits wide, and the -+ * addresses are 32-bit-block aligned. -+ * CSRs are classified as follows: -+ * - Core Global Registers -+ * - Device Mode Registers -+ * - Device Global Registers -+ * - Device Endpoint Specific Registers -+ * - Host Mode Registers -+ * - Host Global Registers -+ * - Host Port CSRs -+ * - Host Channel Specific Registers -+ * -+ * Only the Core Global registers can be accessed in both Device and -+ * Host modes. When the HS OTG core is operating in one mode, either -+ * Device or Host, the application must not access registers from the -+ * other mode. When the core switches from one mode to another, the -+ * registers in the new mode of operation must be reprogrammed as they -+ * would be after a power-on reset. -+ */ -+ -+/****************************************************************************/ -+/* DWC_otg Core registers . -+ * The dwc_otg_core_global_regs structure defines the size -+ * and relative field offsets for the Core Global registers. -+ */ -+struct dwc_otg_core_global_regs { -+ /* OTG Control and Status Register. Offset: 000h */ -+ uint32_t gotgctl; -+ /* OTG Interrupt Register. Offset: 004h */ -+ uint32_t gotgint; -+ /* Core AHB Configuration Register. Offset: 008h */ -+ uint32_t gahbcfg; -+#define DWC_GLBINTRMASK 0x0001 -+#define DWC_DMAENABLE 0x0020 -+#define DWC_NPTXEMPTYLVL_EMPTY 0x0080 -+#define DWC_NPTXEMPTYLVL_HALFEMPTY 0x0000 -+#define DWC_PTXEMPTYLVL_EMPTY 0x0100 -+#define DWC_PTXEMPTYLVL_HALFEMPTY 0x0000 -+ -+ /* Core USB Configuration Register. Offset: 00Ch */ -+ uint32_t gusbcfg; -+ /* Core Reset Register. Offset: 010h */ -+ uint32_t grstctl; -+ /* Core Interrupt Register. Offset: 014h */ -+ uint32_t gintsts; -+ /* Core Interrupt Mask Register. Offset: 018h */ -+ uint32_t gintmsk; -+ /* Receive Status Queue Read Register (Read Only). Offset: 01Ch */ -+ uint32_t grxstsr; -+ /* Receive Status Queue Read & POP Register (Read Only). Offset: 020h*/ -+ uint32_t grxstsp; -+ /* Receive FIFO Size Register. Offset: 024h */ -+ uint32_t grxfsiz; -+ /* Non Periodic Transmit FIFO Size Register. Offset: 028h */ -+ uint32_t gnptxfsiz; -+ /* -+ *Non Periodic Transmit FIFO/Queue Status Register (Read -+ * Only). Offset: 02Ch -+ */ -+ uint32_t gnptxsts; -+ /* I2C Access Register. Offset: 030h */ -+ uint32_t gi2cctl; -+ /* PHY Vendor Control Register. Offset: 034h */ -+ uint32_t gpvndctl; -+ /* General Purpose Input/Output Register. Offset: 038h */ -+ uint32_t ggpio; -+ /* User ID Register. Offset: 03Ch */ -+ uint32_t guid; -+ /* Synopsys ID Register (Read Only). Offset: 040h */ -+ uint32_t gsnpsid; -+ /* User HW Config1 Register (Read Only). Offset: 044h */ -+ uint32_t ghwcfg1; -+ /* User HW Config2 Register (Read Only). Offset: 048h */ -+ uint32_t ghwcfg2; -+#define DWC_SLAVE_ONLY_ARCH 0 -+#define DWC_EXT_DMA_ARCH 1 -+#define DWC_INT_DMA_ARCH 2 -+ -+#define DWC_MODE_HNP_SRP_CAPABLE 0 -+#define DWC_MODE_SRP_ONLY_CAPABLE 1 -+#define DWC_MODE_NO_HNP_SRP_CAPABLE 2 -+#define DWC_MODE_SRP_CAPABLE_DEVICE 3 -+#define DWC_MODE_NO_SRP_CAPABLE_DEVICE 4 -+#define DWC_MODE_SRP_CAPABLE_HOST 5 -+#define DWC_MODE_NO_SRP_CAPABLE_HOST 6 -+ -+ /* User HW Config3 Register (Read Only). Offset: 04Ch */ -+ uint32_t ghwcfg3; -+ /* User HW Config4 Register (Read Only). Offset: 050h*/ -+ uint32_t ghwcfg4; -+ /* Reserved Offset: 054h-0FFh */ -+ uint32_t reserved[43]; -+ /* Host Periodic Transmit FIFO Size Register. Offset: 100h */ -+ uint32_t hptxfsiz; -+ /* -+ * Device Periodic Transmit FIFO#n Register. -+ * Offset: 104h + (FIFO_Number-1)*04h, -+ * 1 <= FIFO Number <= 15 (1<=n<=15). -+ */ -+ uint32_t dptxfsiz[15]; -+}; -+ -+/* -+ * This union represents the bit fields of the Core OTG Control -+ * and Status Register (GOTGCTL). Set the bits using the bit -+ * fields then write the d32 value to the register. -+ */ -+union gotgctl_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved21_31:11; -+ unsigned currmod:1; -+ unsigned bsesvld:1; -+ unsigned asesvld:1; -+ unsigned reserved17:1; -+ unsigned conidsts:1; -+ unsigned reserved12_15:4; -+ unsigned devhnpen:1; -+ unsigned hstsethnpen:1; -+ unsigned hnpreq:1; -+ unsigned hstnegscs:1; -+ unsigned reserved2_7:6; -+ unsigned sesreq:1; -+ unsigned sesreqscs:1; -+#else -+ unsigned sesreqscs:1; -+ unsigned sesreq:1; -+ unsigned reserved2_7:6; -+ unsigned hstnegscs:1; -+ unsigned hnpreq:1; -+ unsigned hstsethnpen:1; -+ unsigned devhnpen:1; -+ unsigned reserved12_15:4; -+ unsigned conidsts:1; -+ unsigned reserved17:1; -+ unsigned asesvld:1; -+ unsigned bsesvld:1; -+ unsigned currmod:1; -+ unsigned reserved21_31:11; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields of the Core OTG Interrupt Register -+ * (GOTGINT). Set/clear the bits using the bit fields then write the d32 -+ * value to the register. -+ */ -+union gotgint_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved31_20:12; -+ unsigned debdone:1; -+ unsigned adevtoutchng:1; -+ unsigned hstnegdet:1; -+ unsigned reserver10_16:7; -+ unsigned hstnegsucstschng:1; -+ unsigned sesreqsucstschng:1; -+ unsigned reserved3_7:5; -+ unsigned sesenddet:1; -+ unsigned reserved0_1:2; -+#else -+ -+ /* Current Mode */ -+ unsigned reserved0_1:2; -+ -+ /* Session End Detected */ -+ unsigned sesenddet:1; -+ -+ unsigned reserved3_7:5; -+ -+ /* Session Request Success Status Change */ -+ unsigned sesreqsucstschng:1; -+ /* Host Negotiation Success Status Change */ -+ unsigned hstnegsucstschng:1; -+ -+ unsigned reserver10_16:7; -+ -+ /* Host Negotiation Detected */ -+ unsigned hstnegdet:1; -+ /* A-Device Timeout Change */ -+ unsigned adevtoutchng:1; -+ /* Debounce Done */ -+ unsigned debdone:1; -+ -+ unsigned reserved31_20:12; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields of the Core AHB Configuration -+ * Register (GAHBCFG). Set/clear the bits using the bit fields then -+ * write the d32 value to the register. -+ */ -+union gahbcfg_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#define DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0 -+#define DWC_GAHBCFG_TXFEMPTYLVL_EMPTY 1 -+#define DWC_GAHBCFG_DMAENABLE 1 -+#define DWC_GAHBCFG_INT_DMA_BURST_INCR16 7 -+#define DWC_GAHBCFG_INT_DMA_BURST_INCR8 5 -+#define DWC_GAHBCFG_INT_DMA_BURST_INCR4 3 -+#define DWC_GAHBCFG_INT_DMA_BURST_INCR 1 -+#define DWC_GAHBCFG_INT_DMA_BURST_SINGLE 0 -+#define DWC_GAHBCFG_GLBINT_ENABLE 1 -+ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved9_31:23; -+ unsigned ptxfemplvl:1; -+ unsigned nptxfemplvl:1; -+ unsigned reserved:1; -+ unsigned dmaenable:1; -+ unsigned hburstlen:4; -+ unsigned glblintrmsk:1; -+#else -+ unsigned glblintrmsk:1; -+ unsigned hburstlen:4; -+ unsigned dmaenable:1; -+ unsigned reserved:1; -+ unsigned nptxfemplvl:1; -+ unsigned ptxfemplvl:1; -+ unsigned reserved9_31:23; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields of the Core USB Configuration -+ * Register (GUSBCFG). Set the bits using the bit fields then write -+ * the d32 value to the register. -+ */ -+union gusbcfg_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:9; -+ unsigned term_sel_dl_pulse:1; -+ unsigned ulpi_int_vbus_indicator:1; -+ unsigned ulpi_ext_vbus_drv:1; -+ unsigned ulpi_clk_sus_m:1; -+ unsigned ulpi_auto_res:1; -+ unsigned ulpi_fsls:1; -+ unsigned otgutmifssel:1; -+ unsigned phylpwrclksel:1; -+ unsigned nptxfrwnden:1; -+ unsigned usbtrdtim:4; -+ unsigned hnpcap:1; -+ unsigned srpcap:1; -+ unsigned ddrsel:1; -+ unsigned physel:1; -+ unsigned fsintf:1; -+ unsigned ulpi_utmi_sel:1; -+ unsigned phyif:1; -+ unsigned toutcal:3; -+#else -+ unsigned toutcal:3; -+ unsigned phyif:1; -+ unsigned ulpi_utmi_sel:1; -+ unsigned fsintf:1; -+ unsigned physel:1; -+ unsigned ddrsel:1; -+ unsigned srpcap:1; -+ unsigned hnpcap:1; -+ unsigned usbtrdtim:4; -+ unsigned nptxfrwnden:1; -+ unsigned phylpwrclksel:1; -+ unsigned otgutmifssel:1; -+ unsigned ulpi_fsls:1; -+ unsigned ulpi_auto_res:1; -+ unsigned ulpi_clk_sus_m:1; -+ unsigned ulpi_ext_vbus_drv:1; -+ unsigned ulpi_int_vbus_indicator:1; -+ unsigned term_sel_dl_pulse:1; -+ unsigned reserved:9; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields of the Core Reset Register -+ * (GRSTCTL). Set/clear the bits using the bit fields then write the -+ * d32 value to the register. -+ */ -+union grstctl_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned ahbidle:1; -+ unsigned dmareq:1; -+ unsigned reserved11_29:19; -+ unsigned txfnum:5; -+ unsigned txfflsh:1; -+ unsigned rxfflsh:1; -+ unsigned intknqflsh:1; -+ unsigned hstfrm:1; -+ unsigned hsftrst:1; -+ unsigned csftrst:1; -+#else -+ -+ /* -+ * Core Soft Reset (CSftRst) (Device and Host) -+ * -+ * The application can flush the control logic in the -+ * entire core using this bit. This bit resets the -+ * pipelines in the AHB Clock domain as well as the -+ * PHY Clock domain. -+ * -+ * The state machines are reset to an IDLE state, the -+ * control bits in the CSRs are cleared, all the -+ * transmit FIFOs and the receive FIFO are flushed. -+ * -+ * The status mask bits that control the generation of -+ * the interrupt, are cleared, to clear the -+ * interrupt. The interrupt status bits are not -+ * cleared, so the application can get the status of -+ * any events that occurred in the core after it has -+ * set this bit. -+ * -+ * Any transactions on the AHB are terminated as soon -+ * as possible following the protocol. Any -+ * transactions on the USB are terminated immediately. -+ * -+ * The configuration settings in the CSRs are -+ * unchanged, so the software doesn't have to -+ * reprogram these registers (Device -+ * Configuration/Host Configuration/Core System -+ * Configuration/Core PHY Configuration). -+ * -+ * The application can write to this bit, any time it -+ * wants to reset the core. This is a self clearing -+ * bit and the core clears this bit after all the -+ * necessary logic is reset in the core, which may -+ * take several clocks, depending on the current state -+ * of the core. -+ */ -+ unsigned csftrst:1; -+ /* -+ * Hclk Soft Reset -+ * -+ * The application uses this bit to reset the control logic in -+ * the AHB clock domain. Only AHB clock domain pipelines are -+ * reset. -+ */ -+ unsigned hsftrst:1; -+ /* -+ * Host Frame Counter Reset (Host Only)<br> -+ * -+ * The application can reset the (micro)frame number -+ * counter inside the core, using this bit. When the -+ * (micro)frame counter is reset, the subsequent SOF -+ * sent out by the core, will have a (micro)frame -+ * number of 0. -+ */ -+ unsigned hstfrm:1; -+ /* -+ * In Token Sequence Learning Queue Flush -+ * (INTknQFlsh) (Device Only) -+ */ -+ unsigned intknqflsh:1; -+ /* -+ * RxFIFO Flush (RxFFlsh) (Device and Host) -+ * -+ * The application can flush the entire Receive FIFO -+ * using this bit. <p>The application must first -+ * ensure that the core is not in the middle of a -+ * transaction. <p>The application should write into -+ * this bit, only after making sure that neither the -+ * DMA engine is reading from the RxFIFO nor the MAC -+ * is writing the data in to the FIFO. <p>The -+ * application should wait until the bit is cleared -+ * before performing any other operations. This bit -+ * will takes 8 clocks (slowest of PHY or AHB clock) -+ * to clear. -+ */ -+ unsigned rxfflsh:1; -+ /* -+ * TxFIFO Flush (TxFFlsh) (Device and Host). -+ * -+ * This bit is used to selectively flush a single or -+ * all transmit FIFOs. The application must first -+ * ensure that the core is not in the middle of a -+ * transaction. <p>The application should write into -+ * this bit, only after making sure that neither the -+ * DMA engine is writing into the TxFIFO nor the MAC -+ * is reading the data out of the FIFO. <p>The -+ * application should wait until the core clears this -+ * bit, before performing any operations. This bit -+ * will takes 8 clocks (slowest of PHY or AHB clock) -+ * to clear. -+ */ -+ unsigned txfflsh:1; -+ -+ /* -+ * TxFIFO Number (TxFNum) (Device and Host). -+ * -+ * This is the FIFO number which needs to be flushed, -+ * using the TxFIFO Flush bit. This field should not -+ * be changed until the TxFIFO Flush bit is cleared by -+ * the core. -+ * - 0x0:Non Periodic TxFIFO Flush -+ * - 0x1:Periodic TxFIFO #1 Flush in device mode -+ * or Periodic TxFIFO in host mode -+ * - 0x2:Periodic TxFIFO #2 Flush in device mode. -+ * - ... -+ * - 0xF:Periodic TxFIFO #15 Flush in device mode -+ * - 0x10: Flush all the Transmit NonPeriodic and -+ * Transmit Periodic FIFOs in the core -+ */ -+ unsigned txfnum:5; -+ /* Reserved */ -+ unsigned reserved11_29:19; -+ /* -+ * DMA Request Signal. Indicated DMA request is in -+ * probress. Used for debug purpose. -+ */ -+ unsigned dmareq:1; -+ /* -+ * AHB Master Idle. Indicates the AHB Master State -+ * Machine is in IDLE condition. -+ */ -+ unsigned ahbidle:1; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields of the Core Interrupt Mask -+ * Register (GINTMSK). Set/clear the bits using the bit fields then -+ * write the d32 value to the register. -+ */ -+union gintmsk_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned wkupintr:1; -+ unsigned sessreqintr:1; -+ unsigned disconnect:1; -+ unsigned conidstschng:1; -+ unsigned reserved27:1; -+ unsigned ptxfempty:1; -+ unsigned hcintr:1; -+ unsigned portintr:1; -+ unsigned reserved22_23:2; -+ unsigned incomplisoout:1; -+ unsigned incomplisoin:1; -+ unsigned outepintr:1; -+ unsigned inepintr:1; -+ unsigned epmismatch:1; -+ unsigned reserved16:1; -+ unsigned eopframe:1; -+ unsigned isooutdrop:1; -+ unsigned enumdone:1; -+ unsigned usbreset:1; -+ unsigned usbsuspend:1; -+ unsigned erlysuspend:1; -+ unsigned i2cintr:1; -+ unsigned reserved8:1; -+ unsigned goutnakeff:1; -+ unsigned ginnakeff:1; -+ unsigned nptxfempty:1; -+ unsigned rxstsqlvl:1; -+ unsigned sofintr:1; -+ unsigned otgintr:1; -+ unsigned modemismatch:1; -+ unsigned reserved0:1; -+#else -+ unsigned reserved0:1; -+ unsigned modemismatch:1; -+ unsigned otgintr:1; -+ unsigned sofintr:1; -+ unsigned rxstsqlvl:1; -+ unsigned nptxfempty:1; -+ unsigned ginnakeff:1; -+ unsigned goutnakeff:1; -+ unsigned reserved8:1; -+ unsigned i2cintr:1; -+ unsigned erlysuspend:1; -+ unsigned usbsuspend:1; -+ unsigned usbreset:1; -+ unsigned enumdone:1; -+ unsigned isooutdrop:1; -+ unsigned eopframe:1; -+ unsigned reserved16:1; -+ unsigned epmismatch:1; -+ unsigned inepintr:1; -+ unsigned outepintr:1; -+ unsigned incomplisoin:1; -+ unsigned incomplisoout:1; -+ unsigned reserved22_23:2; -+ unsigned portintr:1; -+ unsigned hcintr:1; -+ unsigned ptxfempty:1; -+ unsigned reserved27:1; -+ unsigned conidstschng:1; -+ unsigned disconnect:1; -+ unsigned sessreqintr:1; -+ unsigned wkupintr:1; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields of the Core Interrupt Register -+ * (GINTSTS). Set/clear the bits using the bit fields then write the -+ * d32 value to the register. -+ */ -+union gintsts_data { -+ /* raw register data */ -+ uint32_t d32; -+#define DWC_SOF_INTR_MASK 0x0008 -+ -+ /* register bits */ -+ struct { -+#define DWC_HOST_MODE 1 -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned wkupintr:1; -+ unsigned sessreqintr:1; -+ unsigned disconnect:1; -+ unsigned conidstschng:1; -+ unsigned reserved27:1; -+ unsigned ptxfempty:1; -+ unsigned hcintr:1; -+ unsigned portintr:1; -+ unsigned reserved22_23:2; -+ unsigned incomplisoout:1; -+ unsigned incomplisoin:1; -+ unsigned outepintr:1; -+ unsigned inepint:1; -+ unsigned epmismatch:1; -+ unsigned intokenrx:1; -+ unsigned eopframe:1; -+ unsigned isooutdrop:1; -+ unsigned enumdone:1; -+ unsigned usbreset:1; -+ unsigned usbsuspend:1; -+ unsigned erlysuspend:1; -+ unsigned i2cintr:1; -+ unsigned reserved8:1; -+ unsigned goutnakeff:1; -+ unsigned ginnakeff:1; -+ unsigned nptxfempty:1; -+ unsigned rxstsqlvl:1; -+ unsigned sofintr:1; -+ unsigned otgintr:1; -+ unsigned modemismatch:1; -+ unsigned curmode:1; -+#else -+ unsigned curmode:1; -+ unsigned modemismatch:1; -+ unsigned otgintr:1; -+ unsigned sofintr:1; -+ unsigned rxstsqlvl:1; -+ unsigned nptxfempty:1; -+ unsigned ginnakeff:1; -+ unsigned goutnakeff:1; -+ unsigned reserved8:1; -+ unsigned i2cintr:1; -+ unsigned erlysuspend:1; -+ unsigned usbsuspend:1; -+ unsigned usbreset:1; -+ unsigned enumdone:1; -+ unsigned isooutdrop:1; -+ unsigned eopframe:1; -+ unsigned intokenrx:1; -+ unsigned epmismatch:1; -+ unsigned inepint:1; -+ unsigned outepintr:1; -+ unsigned incomplisoin:1; -+ unsigned incomplisoout:1; -+ unsigned reserved22_23:2; -+ unsigned portintr:1; -+ unsigned hcintr:1; -+ unsigned ptxfempty:1; -+ unsigned reserved27:1; -+ unsigned conidstschng:1; -+ unsigned disconnect:1; -+ unsigned sessreqintr:1; -+ unsigned wkupintr:1; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields in the Device Receive Status Read and -+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the d32 -+ * element then read out the bits using the bit elements. -+ */ -+union device_grxsts_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#define DWC_DSTS_SETUP_UPDT 0x6 /* SETUP Packet */ -+#define DWC_DSTS_SETUP_COMP 0x4 /* Setup Phase Complete */ -+#define DWC_DSTS_GOUT_NAK 0x1 /* Global OUT NAK */ -+#define DWC_STS_XFER_COMP 0x3 /* OUT Data Transfer Complete */ -+#define DWC_STS_DATA_UPDT 0x2 /* OUT Data Packet */ -+ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:7; -+ unsigned fn:4; -+ unsigned pktsts:4; -+ unsigned dpid:2; -+ unsigned bcnt:11; -+ unsigned epnum:4; -+#else -+ unsigned epnum:4; -+ unsigned bcnt:11; -+ unsigned dpid:2; -+ unsigned pktsts:4; -+ unsigned fn:4; -+ unsigned reserved:7; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields in the Host Receive Status Read and -+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the d32 -+ * element then read out the bits using the bit elements. -+ */ -+union host_grxsts_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#define DWC_GRXSTS_PKTSTS_CH_HALTED 0x7 -+#define DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR 0x5 -+#define DWC_GRXSTS_PKTSTS_IN_XFER_COMP 0x3 -+#define DWC_GRXSTS_PKTSTS_IN 0x2 -+ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:11; -+ unsigned pktsts:4; -+ unsigned dpid:2; -+ unsigned bcnt:11; -+ unsigned chnum:4; -+#else -+ unsigned chnum:4; -+ unsigned bcnt:11; -+ unsigned dpid:2; -+ unsigned pktsts:4; -+ unsigned reserved:11; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields in the FIFO Size Registers (HPTXFSIZ, -+ * GNPTXFSIZ, DPTXFSIZn). Read the register into the d32 element then -+ * read out the bits using the bit elements. -+ */ -+union fifosize_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned depth:16; -+ unsigned startaddr:16; -+#else -+ unsigned startaddr:16; -+ unsigned depth:16; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields in the Non-Periodic Transmit -+ * FIFO/Queue Status Register (GNPTXSTS). Read the register into the -+ * d32 element then read out the bits using the bit -+ * elements. -+ */ -+union gnptxsts_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:1; -+ unsigned nptxqtop_chnep:4; -+ unsigned nptxqtop_token:2; -+ unsigned nptxqtop_terminate:1; -+ unsigned nptxqspcavail:8; -+ unsigned nptxfspcavail:16; -+#else -+ unsigned nptxfspcavail:16; -+ unsigned nptxqspcavail:8; -+ /* -+ * Top of the Non-Periodic Transmit Request Queue -+ * - bit 24 - Terminate (Last entry for the selected -+ * channel/EP) -+ * - bits 26:25 - Token Type -+ * - 2'b00 - IN/OUT -+ * - 2'b01 - Zero Length OUT -+ * - 2'b10 - PING/Complete Split -+ * - 2'b11 - Channel Halt -+ * - bits 30:27 - Channel/EP Number -+ */ -+ unsigned nptxqtop_terminate:1; -+ unsigned nptxqtop_token:2; -+ unsigned nptxqtop_chnep:4; -+ unsigned reserved:1; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields in the I2C Control Register -+ * (I2CCTL). Read the register into the d32 element then read out the -+ * bits using the bit elements. -+ */ -+union gi2cctl_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned bsydne:1; -+ unsigned rw:1; -+ unsigned reserved:2; -+ unsigned i2cdevaddr:2; -+ unsigned i2csuspctl:1; -+ unsigned ack:1; -+ unsigned i2cen:1; -+ unsigned addr:7; -+ unsigned regaddr:8; -+ unsigned rwdata:8; -+#else -+ unsigned rwdata:8; -+ unsigned regaddr:8; -+ unsigned addr:7; -+ unsigned i2cen:1; -+ unsigned ack:1; -+ unsigned i2csuspctl:1; -+ unsigned i2cdevaddr:2; -+ unsigned reserved:2; -+ unsigned rw:1; -+ unsigned bsydne:1; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields in the User HW Config1 -+ * Register. Read the register into the d32 element then read -+ * out the bits using the bit elements. -+ */ -+union hwcfg1_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned ep_dir15:2; -+ unsigned ep_dir14:2; -+ unsigned ep_dir13:2; -+ unsigned ep_dir12:2; -+ unsigned ep_dir11:2; -+ unsigned ep_dir10:2; -+ unsigned ep_dir9:2; -+ unsigned ep_dir8:2; -+ unsigned ep_dir7:2; -+ unsigned ep_dir6:2; -+ unsigned ep_dir5:2; -+ unsigned ep_dir4:2; -+ unsigned ep_dir3:2; -+ unsigned ep_dir2:2; -+ unsigned ep_dir1:2; -+ unsigned ep_dir0:2; -+#else -+ unsigned ep_dir0:2; -+ unsigned ep_dir1:2; -+ unsigned ep_dir2:2; -+ unsigned ep_dir3:2; -+ unsigned ep_dir4:2; -+ unsigned ep_dir5:2; -+ unsigned ep_dir6:2; -+ unsigned ep_dir7:2; -+ unsigned ep_dir8:2; -+ unsigned ep_dir9:2; -+ unsigned ep_dir10:2; -+ unsigned ep_dir11:2; -+ unsigned ep_dir12:2; -+ unsigned ep_dir13:2; -+ unsigned ep_dir14:2; -+ unsigned ep_dir15:2; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields in the User HW Config2 -+ * Register. Read the register into the d32 element then read -+ * out the bits using the bit elements. -+ */ -+union hwcfg2_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3 -+#define DWC_HWCFG2_HS_PHY_TYPE_ULPI 2 -+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI 1 -+#define DWC_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0 -+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6 -+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5 -+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4 -+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3 -+#define DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2 -+#define DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1 -+#define DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG 0 -+ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved31:1; -+ unsigned dev_token_q_depth:5; -+ unsigned host_perio_tx_q_depth:2; -+ unsigned nonperio_tx_q_depth:2; -+ unsigned rx_status_q_depth:2; -+ unsigned dynamic_fifo:1; -+ unsigned perio_ep_supported:1; -+ unsigned num_host_chan:4; -+ unsigned num_dev_ep:4; -+ unsigned fs_phy_type:2; -+ unsigned hs_phy_type:2; -+ unsigned point2point:1; -+ unsigned architecture:2; -+ unsigned op_mode:3; -+#else -+ unsigned op_mode:3; -+ unsigned architecture:2; -+ unsigned point2point:1; -+ unsigned hs_phy_type:2; -+ unsigned fs_phy_type:2; -+ unsigned num_dev_ep:4; -+ unsigned num_host_chan:4; -+ unsigned perio_ep_supported:1; -+ unsigned dynamic_fifo:1; -+ unsigned rx_status_q_depth:2; -+ unsigned nonperio_tx_q_depth:2; -+ unsigned host_perio_tx_q_depth:2; -+ unsigned dev_token_q_depth:5; -+ unsigned reserved31:1; -+#endif -+ } b; -+}; -+ -+/** -+ * This union represents the bit fields in the User HW Config3 -+ * Register. Read the register into the d32 element then read -+ * out the bits using the bit elements. -+ */ -+union hwcfg3_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+ /* GHWCFG3 */ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned dfifo_depth:16; -+ unsigned reserved15_13:3; -+ unsigned ahb_phy_clock_synch:1; -+ unsigned synch_reset_type:1; -+ unsigned optional_features:1; -+ unsigned vendor_ctrl_if:1; -+ unsigned i2c:1; -+ unsigned otg_func:1; -+ unsigned packet_size_cntr_width:3; -+ unsigned xfer_size_cntr_width:4; -+#else -+ unsigned xfer_size_cntr_width:4; -+ unsigned packet_size_cntr_width:3; -+ unsigned otg_func:1; -+ unsigned i2c:1; -+ unsigned vendor_ctrl_if:1; -+ unsigned optional_features:1; -+ unsigned synch_reset_type:1; -+ unsigned ahb_phy_clock_synch:1; -+ unsigned reserved15_13:3; -+ unsigned dfifo_depth:16; -+#endif -+ } b; -+}; -+ -+/** -+ * This union represents the bit fields in the User HW Config4 -+ * Register. Read the register into the d32 element then read -+ * out the bits using the bit elements. -+ */ -+union hwcfg4_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved31_25:7; -+ unsigned session_end_filt_en:1; -+ unsigned b_valid_filt_en:1; -+ unsigned a_valid_filt_en:1; -+ unsigned vbus_valid_filt_en:1; -+ unsigned iddig_filt_en:1; -+ unsigned num_dev_mode_ctrl_ep:4; -+ unsigned utmi_phy_data_width:2; -+ unsigned min_ahb_freq:9; -+ unsigned power_optimiz:1; -+ unsigned num_dev_perio_in_ep:4; -+#else -+ unsigned num_dev_perio_in_ep:4; -+ unsigned power_optimiz:1; -+ unsigned min_ahb_freq:9; -+ unsigned utmi_phy_data_width:2; -+ unsigned num_dev_mode_ctrl_ep:4; -+ unsigned iddig_filt_en:1; -+ unsigned vbus_valid_filt_en:1; -+ unsigned a_valid_filt_en:1; -+ unsigned b_valid_filt_en:1; -+ unsigned session_end_filt_en:1; -+ unsigned reserved31_25:7; -+#endif -+ } b; -+}; -+ -+ -+/* -+ * Device Global Registers. Offsets 800h-BFFh -+ * -+ * The following structures define the size and relative field offsets -+ * for the Device Mode Registers. -+ * -+ * These registers are visible only in Device mode and must not be -+ * accessed in Host mode, as the results are unknown. -+ */ -+struct dwc_otg_dev_global_regs { -+ /* Device Configuration Register. Offset 800h */ -+ uint32_t dcfg; -+ /* Device Control Register. Offset: 804h */ -+ uint32_t dctl; -+ /* Device Status Register (Read Only). Offset: 808h */ -+ uint32_t dsts; -+ /* Reserved. Offset: 80Ch */ -+ uint32_t unused; -+ /* -+ * Device IN Endpoint Common Interrupt Mask Register. Offset: 810h -+ */ -+ uint32_t diepmsk; -+ /* -+ * Device OUT Endpoint Common Interrupt Mask -+ * Register. Offset: 814h -+ */ -+ uint32_t doepmsk; -+ /* -+ * Device All Endpoints Interrupt Register. Offset: 818h -+ */ -+ uint32_t daint; -+ /* -+ * Device All Endpoints Interrupt Mask Register. Offset: -+ * 81Ch -+ */ -+ uint32_t daintmsk; -+ /* -+ * Device IN Token Queue Read Register-1 (Read Only). -+ * Offset: 820h -+ */ -+ uint32_t dtknqr1; -+ /* -+ * Device IN Token Queue Read Register-2 (Read Only). -+ * Offset: 824h -+ */ -+ uint32_t dtknqr2; -+ /* -+ * Device VBUS discharge Register. Offset: 828h -+ */ -+ uint32_t dvbusdis; -+ /* -+ * Device VBUS Pulse Register. Offset: 82Ch -+ */ -+ uint32_t dvbuspulse; -+ /* -+ * Device IN Token Queue Read Register-3 (Read Only). -+ * Offset: 830h -+ */ -+ uint32_t dtknqr3; -+ /* -+ * Device IN Token Queue Read Register-4 (Read Only). -+ * Offset: 834h -+ */ -+ uint32_t dtknqr4; -+}; -+ -+/* -+ * This union represents the bit fields in the Device Configuration -+ * Register. Read the register into the d32 member then -+ * set/clear the bits using the bit elements. Write the -+ * d32 member to the dcfg register. -+ */ -+union dcfg_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#define DWC_DCFG_FRAME_INTERVAL_95 3 -+#define DWC_DCFG_FRAME_INTERVAL_90 2 -+#define DWC_DCFG_FRAME_INTERVAL_85 1 -+#define DWC_DCFG_FRAME_INTERVAL_80 0 -+#define DWC_DCFG_SEND_STALL 1 -+ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved9:10; -+ unsigned epmscnt:4; -+ unsigned reserved13_17:5; -+ unsigned perfrint:2; -+ unsigned devaddr:7; -+ unsigned reserved3:1; -+ unsigned nzstsouthshk:1; -+ unsigned devspd:2; -+#else -+ -+ /* Device Speed */ -+ unsigned devspd:2; -+ /* Non Zero Length Status OUT Handshake */ -+ unsigned nzstsouthshk:1; -+ unsigned reserved3:1; -+ /* Device Addresses */ -+ unsigned devaddr:7; -+ /* Periodic Frame Interval */ -+ unsigned perfrint:2; -+ unsigned reserved13_17:5; -+ /* In Endpoint Mis-match count */ -+ unsigned epmscnt:4; -+ unsigned reserved9:10; -+#endif -+ } b; -+}; -+ -+/** -+ * This union represents the bit fields in the Device Control -+ * Register. Read the register into the d32 member then -+ * set/clear the bits using the bit elements. -+ */ -+union dctl_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:21; -+ unsigned cgoutnak:1; -+ unsigned sgoutnak:1; -+ unsigned cgnpinnak:1; -+ unsigned sgnpinnak:1; -+ unsigned tstctl:3; -+ unsigned goutnaksts:1; -+ unsigned gnpinnaksts:1; -+ unsigned sftdiscon:1; -+ unsigned rmtwkupsig:1; -+#else -+ -+ /* Remote Wakeup */ -+ unsigned rmtwkupsig:1; -+ /* Soft Disconnect */ -+ unsigned sftdiscon:1; -+ /* Global Non-Periodic IN NAK Status */ -+ unsigned gnpinnaksts:1; -+ /* Global OUT NAK Status */ -+ unsigned goutnaksts:1; -+ /* Test Control */ -+ unsigned tstctl:3; -+ /* Set Global Non-Periodic IN NAK */ -+ unsigned sgnpinnak:1; -+ /* Clear Global Non-Periodic IN NAK */ -+ unsigned cgnpinnak:1; -+ /* Set Global OUT NAK */ -+ unsigned sgoutnak:1; -+ /* Clear Global OUT NAK */ -+ unsigned cgoutnak:1; -+ -+ unsigned reserved:21; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields in the Device Status -+ * Register. Read the register into the d32 member then -+ * set/clear the bits using the bit elements. -+ */ -+union dsts_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#define DWC_DSTS_ENUMSPD_FS_PHY_48MHZ 3 -+#define DWC_DSTS_ENUMSPD_LS_PHY_6MHZ 2 -+#define DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1 -+#define DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0 -+ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved22_31:10; -+ unsigned soffn:14; -+ unsigned reserved4_7:4; -+ unsigned errticerr:1; -+ unsigned enumspd:2; -+ unsigned suspsts:1; -+#else -+ -+ /* Suspend Status */ -+ unsigned suspsts:1; -+ /* Enumerated Speed */ -+ unsigned enumspd:2; -+ /* Erratic Error */ -+ unsigned errticerr:1; -+ unsigned reserved4_7:4; -+ /* Frame or Microframe Number of the received SOF */ -+ unsigned soffn:14; -+ unsigned reserved22_31:10; -+#endif -+ } b; -+}; -+ -+/** -+ * This union represents the bit fields in the Device IN EP Interrupt -+ * Register and the Device IN EP Common Mask Register. -+ * -+ * It also represents the bit fields in the Device IN EP Common -+ * Interrupt Mask Register. -+ -+ * - Read the register into the d32 member then set/clear the -+ * bits using the bit elements. -+ */ -+union diepint_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved07_31:25; -+ unsigned inepnakeff:1; -+ unsigned intknepmis:1; -+ unsigned intktxfemp:1; -+ unsigned timeout:1; -+ unsigned ahberr:1; -+ unsigned epdisabled:1; -+ unsigned xfercompl:1; -+#else -+ -+y /* Transfer complete mask */ -+ unsigned xfercompl:1; -+ /* Endpoint disable mask */ -+ unsigned epdisabled:1; -+ /* AHB Error mask */ -+ unsigned ahberr:1; -+ /* TimeOUT Handshake mask (non-ISOC EPs) */ -+ unsigned timeout:1; -+ /* IN Token received with TxF Empty mask */ -+ unsigned intktxfemp:1; -+ /* IN Token Received with EP mismatch mask */ -+ unsigned intknepmis:1; -+ /* IN Endpoint HAK Effective mask */ -+ unsigned inepnakeff:1; -+ unsigned reserved07_31:25; -+#endif -+ } b; -+}; -+ -+/** -+ * This union represents the bit fields in the Device OUT EP Interrupt -+ * Registerand Device OUT EP Common Interrupt Mask Register. -+ * -+ * It also represents the bit fields in the Device OUT EP Common -+ * Interrupt Mask Register. -+ * -+ * - Read the register into the d32 member then set/clear the -+ * bits using the bit elements. -+ */ -+union doepint_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved04_31:28; -+ unsigned setup:1; -+ unsigned ahberr:1; -+ unsigned epdisabled:1; -+ unsigned xfercompl:1; -+#else -+ -+ /* Transfer complete */ -+ unsigned xfercompl:1; -+ /* Endpoint disable */ -+ unsigned epdisabled:1; -+ /* AHB Error */ -+ unsigned ahberr:1; -+ /* Setup Phase Done (contorl EPs) */ -+ unsigned setup:1; -+ unsigned reserved04_31:28; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields in the Device All EP Interrupt -+ * and Mask Registers. -+ * - Read the register into the d32 member then set/clear the -+ * bits using the bit elements. -+ */ -+union daint_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned out:16; -+ unsigned in:16; -+#else -+ -+ /* IN Endpoint bits */ -+ unsigned in:16; -+ /* OUT Endpoint bits */ -+ unsigned out:16; -+#endif -+ } ep; -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned outep15:1; -+ unsigned outep14:1; -+ unsigned outep13:1; -+ unsigned outep12:1; -+ unsigned outep11:1; -+ unsigned outep10:1; -+ unsigned outep9:1; -+ unsigned outep8:1; -+ unsigned outep7:1; -+ unsigned outep6:1; -+ unsigned outep5:1; -+ unsigned outep4:1; -+ unsigned outep3:1; -+ unsigned outep2:1; -+ unsigned outep1:1; -+ unsigned outep0:1; -+ unsigned inep15:1; -+ unsigned inep14:1; -+ unsigned inep13:1; -+ unsigned inep12:1; -+ unsigned inep11:1; -+ unsigned inep10:1; -+ unsigned inep9:1; -+ unsigned inep8:1; -+ unsigned inep7:1; -+ unsigned inep6:1; -+ unsigned inep5:1; -+ unsigned inep4:1; -+ unsigned inep3:1; -+ unsigned inep2:1; -+ unsigned inep1:1; -+ unsigned inep0:1; -+#else -+ -+ /* IN Endpoint bits */ -+ unsigned inep0:1; -+ unsigned inep1:1; -+ unsigned inep2:1; -+ unsigned inep3:1; -+ unsigned inep4:1; -+ unsigned inep5:1; -+ unsigned inep6:1; -+ unsigned inep7:1; -+ unsigned inep8:1; -+ unsigned inep9:1; -+ unsigned inep10:1; -+ unsigned inep11:1; -+ unsigned inep12:1; -+ unsigned inep13:1; -+ unsigned inep14:1; -+ unsigned inep15:1; -+ /* OUT Endpoint bits */ -+ unsigned outep0:1; -+ unsigned outep1:1; -+ unsigned outep2:1; -+ unsigned outep3:1; -+ unsigned outep4:1; -+ unsigned outep5:1; -+ unsigned outep6:1; -+ unsigned outep7:1; -+ unsigned outep8:1; -+ unsigned outep9:1; -+ unsigned outep10:1; -+ unsigned outep11:1; -+ unsigned outep12:1; -+ unsigned outep13:1; -+ unsigned outep14:1; -+ unsigned outep15:1; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields in the Device IN Token Queue -+ * Read Registers. -+ * - Read the register into the d32 member. -+ * - READ-ONLY Register -+ */ -+union dtknq1_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned epnums0_5:24; -+ unsigned wrap_bit:1; -+ unsigned reserved05_06:2; -+ unsigned intknwptr:5; -+#else -+ -+ /* In Token Queue Write Pointer */ -+ unsigned intknwptr:5; -+ /* Reserved */ -+ unsigned reserved05_06:2; -+ /* write pointer has wrapped. */ -+ unsigned wrap_bit:1; -+ /* EP Numbers of IN Tokens 0 ... 4 */ -+ unsigned epnums0_5:24; -+#endif -+ } b; -+}; -+ -+/* -+ * Device Logical IN Endpoint-Specific Registers. Offsets -+ * 900h-AFCh -+ * -+ * There will be one set of endpoint registers per logical endpoint -+ * implemented. -+ * -+ * These registers are visible only in Device mode and must not be -+ * accessed in Host mode, as the results are unknown. -+ */ -+struct dwc_otg_dev_in_ep_regs { -+ /* -+ * Device IN Endpoint Control Register. Offset:900h + -+ * (ep_num * 20h) + 00h -+ */ -+ uint32_t diepctl; -+ /* Reserved. Offset:900h + (ep_num * 20h) + 04h */ -+ uint32_t reserved04; -+ /* -+ * Device IN Endpoint Interrupt Register. Offset:900h + -+ * (ep_num * 20h) + 08h -+ */ -+ uint32_t diepint; -+ /* Reserved. Offset:900h + (ep_num * 20h) + 0Ch */ -+ uint32_t reserved0C; -+ /* -+ * Device IN Endpoint Transfer Size -+ * Register. Offset:900h + (ep_num * 20h) + 10h -+ */ -+ uint32_t dieptsiz; -+ /* -+ * Device IN Endpoint DMA Address Register. Offset:900h + -+ * (ep_num * 20h) + 14h -+ */ -+ uint32_t diepdma; -+ /* -+ * Reserved. Offset:900h + (ep_num * 20h) + 18h - 900h + -+ * (ep_num * 20h) + 1Ch -+ */ -+ uint32_t reserved18[2]; -+}; -+ -+/** -+ * Device Logical OUT Endpoint-Specific Registers. Offsets: -+ * B00h-CFCh -+ * -+ * There will be one set of endpoint registers per logical endpoint -+ * implemented. -+ * -+ * These registers are visible only in Device mode and must not be -+ * accessed in Host mode, as the results are unknown. -+ */ -+struct dwc_otg_dev_out_ep_regs { -+ /* -+ * Device OUT Endpoint Control Register. Offset:B00h + -+ * (ep_num * 20h) + 00h -+ */ -+ uint32_t doepctl; -+ /* -+ * Device OUT Endpoint Frame number Register. Offset: -+ * B00h + (ep_num * 20h) + 04h -+ */ -+ uint32_t doepfn; -+ /* -+ * Device OUT Endpoint Interrupt Register. Offset:B00h + -+ * (ep_num * 20h) + 08h -+ */ -+ uint32_t doepint; -+ /* -+ * Reserved. Offset:B00h + (ep_num * 20h) + 0Ch */ -+ uint32_t reserved0C; -+ /* -+ * Device OUT Endpoint Transfer Size Register. Offset: -+ * B00h + (ep_num * 20h) + 10h -+ */ -+ uint32_t doeptsiz; -+ /* -+ * Device OUT Endpoint DMA Address Register. Offset:B00h -+ * + (ep_num * 20h) + 14h -+ */ -+ uint32_t doepdma; -+ /* -+ * Reserved. Offset:B00h + (ep_num * 20h) + 18h - B00h + -+ * (ep_num * 20h) + 1Ch -+ */ -+ uint32_t unused[2]; -+}; -+ -+/* -+ * This union represents the bit fields in the Device EP Control -+ * Register. Read the register into the d32 member then -+ * set/clear the bits using the bit elements. -+ */ -+union depctl_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#define DWC_DEP0CTL_MPS_64 0 -+#define DWC_DEP0CTL_MPS_32 1 -+#define DWC_DEP0CTL_MPS_16 2 -+#define DWC_DEP0CTL_MPS_8 3 -+ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned mps:11; -+ unsigned epena:1; -+ unsigned epdis:1; -+ unsigned setd1pid:1; -+ unsigned setd0pid:1; -+ unsigned snak:1; -+ unsigned cnak:1; -+ unsigned txfnum:4; -+ unsigned stall:1; -+ unsigned snp:1; -+ unsigned eptype:2; -+ unsigned naksts:1; -+ unsigned dpid:1; -+ unsigned usbactep:1; -+ unsigned nextep:4; -+#else -+ -+ /* -+ * Maximum Packet Size -+ * IN/OUT EPn -+ * IN/OUT EP0 - 2 bits -+ * 2'b00: 64 Bytes -+ * 2'b01: 32 -+ * 2'b10: 16 -+ * 2'b11: 8 -+ */ -+ unsigned mps:11; -+ /* -+ * Next Endpoint -+ * IN EPn/IN EP0 -+ * OUT EPn/OUT EP0 - reserved -+ */ -+ unsigned nextep:4; -+ -+ /* USB Active Endpoint */ -+ unsigned usbactep:1; -+ -+ /* -+ * Endpoint DPID (INTR/Bulk IN and OUT endpoints) -+ * This field contains the PID of the packet going to -+ * be received or transmitted on this endpoint. The -+ * application should program the PID of the first -+ * packet going to be received or transmitted on this -+ * endpoint , after the endpoint is -+ * activated. Application use the SetD1PID and -+ * SetD0PID fields of this register to program either -+ * D0 or D1 PID. -+ * -+ * The encoding for this field is -+ * - 0: D0 -+ * - 1: D1 -+ */ -+ unsigned dpid:1; -+ -+ /* NAK Status */ -+ unsigned naksts:1; -+ -+ /* -+ * Endpoint Type -+ * 2'b00: Control -+ * 2'b01: Isochronous -+ * 2'b10: Bulk -+ * 2'b11: Interrupt -+ */ -+ unsigned eptype:2; -+ -+ /* -+ * Snoop Mode -+ * OUT EPn/OUT EP0 -+ * IN EPn/IN EP0 - reserved -+ */ -+ unsigned snp:1; -+ -+ /* Stall Handshake */ -+ unsigned stall:1; -+ -+ /* -+ * Tx Fifo Number -+ * IN EPn/IN EP0 -+ * OUT EPn/OUT EP0 - reserved -+ */ -+ unsigned txfnum:4; -+ -+ /* Clear NAK */ -+ unsigned cnak:1; -+ /* Set NAK */ -+ unsigned snak:1; -+ /* -+ * Set DATA0 PID (INTR/Bulk IN and OUT endpoints) -+ * Writing to this field sets the Endpoint DPID (DPID) -+ * field in this register to DATA0. Set Even -+ * (micro)frame (SetEvenFr) (ISO IN and OUT Endpoints) -+ * Writing to this field sets the Even/Odd -+ * (micro)frame (EO_FrNum) field to even (micro) -+ * frame. -+ */ -+ unsigned setd0pid:1; -+ /* -+ * Set DATA1 PID (INTR/Bulk IN and OUT endpoints) -+ * Writing to this field sets the Endpoint DPID (DPID) -+ * field in this register to DATA1 Set Odd -+ * (micro)frame (SetOddFr) (ISO IN and OUT Endpoints) -+ * Writing to this field sets the Even/Odd -+ * (micro)frame (EO_FrNum) field to odd (micro) frame. -+ */ -+ unsigned setd1pid:1; -+ -+ /* Endpoint Disable */ -+ unsigned epdis:1; -+ /* Endpoint Enable */ -+ unsigned epena:1; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields in the Device EP Transfer -+ * Size Register. Read the register into the d32 member then -+ * set/clear the bits using the bit elements. -+ */ -+union deptsiz_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:1; -+ unsigned mc:2; -+ unsigned pktcnt:10; -+ unsigned xfersize:19; -+#else -+ -+ /* Transfer size */ -+ unsigned xfersize:19; -+ /* Packet Count */ -+ unsigned pktcnt:10; -+ /* Multi Count - Periodic IN endpoints */ -+ unsigned mc:2; -+ unsigned reserved:1; -+#endif -+ } b; -+}; -+ -+/* -+ * This union represents the bit fields in the Device EP 0 Transfer -+ * Size Register. Read the register into the d32 member then -+ * set/clear the bits using the bit elements. -+ */ -+union deptsiz0_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved31:1; -+ unsigned supcnt:2; -+ unsigned reserved20_28:9; -+ unsigned pktcnt:1; -+ unsigned reserved7_18:12; -+ unsigned xfersize:7; -+#else -+ -+ /* Transfer size */ -+ unsigned xfersize:7; -+ /* Reserved */ -+ unsigned reserved7_18:12; -+ /* Packet Count */ -+ unsigned pktcnt:1; -+ /* Reserved */ -+ unsigned reserved20_28:9; -+ /* Setup Packet Count (DOEPTSIZ0 Only) */ -+ unsigned supcnt:2; -+ unsigned reserved31:1; -+#endif -+ } b; -+}; -+ -+/** Maximum number of Periodic FIFOs */ -+#define MAX_PERIO_FIFOS 15 -+ -+/** Maximum number of Endpoints/HostChannels */ -+#define MAX_EPS_CHANNELS 16 -+ -+/* -+ * The dwc_otg_dev_if structure contains information needed to manage -+ * the DWC_otg controller acting in device mode. It represents the -+ * programming view of the device-specific aspects of the controller. -+ */ -+struct dwc_otg_dev_if { -+ /* -+ * Pointer to device Global registers. -+ * Device Global Registers starting at offset 800h -+ */ -+ struct dwc_otg_dev_global_regs *dev_global_regs; -+#define DWC_DEV_GLOBAL_REG_OFFSET 0x800 -+ -+ /* -+ * Device Logical IN Endpoint-Specific Registers 900h-AFCh -+ */ -+ struct dwc_otg_dev_in_ep_regs *in_ep_regs[MAX_EPS_CHANNELS]; -+#define DWC_DEV_IN_EP_REG_OFFSET 0x900 -+#define DWC_EP_REG_OFFSET 0x20 -+ -+ /* Device Logical OUT Endpoint-Specific Registers B00h-CFCh */ -+ struct dwc_otg_dev_out_ep_regs *out_ep_regs[MAX_EPS_CHANNELS]; -+#define DWC_DEV_OUT_EP_REG_OFFSET 0xB00 -+ -+ /* Device configuration information */ -+ uint8_t speed; /* Device Speed 0: Unknown, 1: LS, 2:FS, 3: HS */ -+ uint8_t num_eps; /* Number of EPs range: 1-16 (includes EP0) */ -+ uint8_t num_perio_eps; /* # of Periodic EP range: 0-15 */ -+ -+ /* Size of periodic FIFOs (Bytes) */ -+ uint16_t perio_tx_fifo_size[MAX_PERIO_FIFOS]; -+ -+}; -+ -+ -+/* Host Mode Register Structures */ -+ -+/* -+ * The Host Global Registers structure defines the size and relative -+ * field offsets for the Host Mode Global Registers. Host Global -+ * Registers offsets 400h-7FFh. -+ */ -+struct dwc_otg_host_global_regs { -+ /* Host Configuration Register. Offset: 400h */ -+ uint32_t hcfg; -+ /* Host Frame Interval Register. Offset: 404h */ -+ uint32_t hfir; -+ /* Host Frame Number / Frame Remaining Register. Offset: 408h */ -+ uint32_t hfnum; -+ /* Reserved. Offset: 40Ch */ -+ uint32_t reserved40C; -+ /* Host Periodic Transmit FIFO/ Queue Status Register. Offset: 410h */ -+ uint32_t hptxsts; -+ /* Host All Channels Interrupt Register. Offset: 414h */ -+ uint32_t haint; -+ /* Host All Channels Interrupt Mask Register. Offset: 418h */ -+ uint32_t haintmsk; -+}; -+ -+/* -+ * This union represents the bit fields in the Host Configuration Register. -+ * Read the register into the d32 member then set/clear the bits using -+ * the bit elements. Write the d32 member to the hcfg register. -+ */ -+union hcfg_data { -+ /** raw register data */ -+ uint32_t d32; -+ -+ /** register bits */ -+ struct { -+#define DWC_HCFG_6_MHZ 2 -+#define DWC_HCFG_48_MHZ 1 -+#define DWC_HCFG_30_60_MHZ 0 -+ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:29; -+ unsigned fslssupp:1; -+ unsigned fslspclksel:2; -+#else -+ -+ /* FS/LS Phy Clock Select */ -+ unsigned fslspclksel:2; -+ /* FS/LS Only Support */ -+ unsigned fslssupp:1; -+ unsigned reserved:29; -+#endif -+ } b; -+}; -+ -+/** -+ * This union represents the bit fields in the Host Frame Remaing/Number -+ * Register. -+ */ -+union hfir_data { -+ /* raw register data */ -+ uint32_t d32; -+ -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:16; -+ unsigned frint:16; -+#else -+ unsigned frint:16; -+ unsigned reserved:16; -+#endif -+ } b; -+}; -+ -+/** -+ * This union represents the bit fields in the Host Frame Remaing/Number -+ * Register. -+ */ -+union hfnum_data { -+ /* raw register data */ -+ uint32_t d32; -+ -+ /* register bits */ -+ struct { -+#define DWC_HFNUM_MAX_FRNUM 0x3FFF -+ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned frrem:16; -+ unsigned frnum:16; -+#else -+ unsigned frnum:16; -+ unsigned frrem:16; -+#endif -+ } b; -+}; -+ -+union hptxsts_data { -+ /* raw register data */ -+ uint32_t d32; -+ -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned ptxqtop_odd:1; -+ unsigned ptxqtop_chnum:4; -+ unsigned ptxqtop_token:2; -+ unsigned ptxqtop_terminate:1; -+ unsigned ptxqspcavail:8; -+ unsigned ptxfspcavail:16; -+#else -+ unsigned ptxfspcavail:16; -+ unsigned ptxqspcavail:8; -+ /* -+ * Top of the Periodic Transmit Request Queue -+ * - bit 24 - Terminate (last entry for the selected channel) -+ * - bits 26:25 - Token Type -+ * - 2'b00 - Zero length -+ * - 2'b01 - Ping -+ * - 2'b10 - Disable -+ * - bits 30:27 - Channel Number -+ * - bit 31 - Odd/even microframe -+ */ -+ unsigned ptxqtop_terminate:1; -+ unsigned ptxqtop_token:2; -+ unsigned ptxqtop_chnum:4; -+ unsigned ptxqtop_odd:1; -+#endif -+ } b; -+}; -+ -+/** -+ * This union represents the bit fields in the Host Port Control and Status -+ * Register. Read the register into the d32 member then set/clear the -+ * bits using the bit elements. Write the d32 member to the -+ * hprt0 register. -+ */ -+union hprt0_data { -+ /** raw register data */ -+ uint32_t d32; -+ /** register bits */ -+ struct { -+#define DWC_HPRT0_PRTSPD_LOW_SPEED 2 -+#define DWC_HPRT0_PRTSPD_FULL_SPEED 1 -+#define DWC_HPRT0_PRTSPD_HIGH_SPEED 0 -+ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved19_31:13; -+ unsigned prtspd:2; -+ unsigned prttstctl:4; -+ unsigned prtpwr:1; -+ unsigned prtlnsts:2; -+ unsigned reserved9:1; -+ unsigned prtrst:1; -+ unsigned prtsusp:1; -+ unsigned prtres:1; -+ unsigned prtovrcurrchng:1; -+ unsigned prtovrcurract:1; -+ unsigned prtenchng:1; -+ unsigned prtena:1; -+ unsigned prtconndet:1; -+ unsigned prtconnsts:1; -+#else -+ unsigned prtconnsts:1; -+ unsigned prtconndet:1; -+ unsigned prtena:1; -+ unsigned prtenchng:1; -+ unsigned prtovrcurract:1; -+ unsigned prtovrcurrchng:1; -+ unsigned prtres:1; -+ unsigned prtsusp:1; -+ unsigned prtrst:1; -+ unsigned reserved9:1; -+ unsigned prtlnsts:2; -+ unsigned prtpwr:1; -+ unsigned prttstctl:4; -+ unsigned prtspd:2; -+ unsigned reserved19_31:13; -+#endif -+ } b; -+}; -+ -+/** -+ * This union represents the bit fields in the Host All Interrupt -+ * Register. -+ */ -+union haint_data { -+ /** raw register data */ -+ uint32_t d32; -+ /** register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:16; -+ unsigned ch15:1; -+ unsigned ch14:1; -+ unsigned ch13:1; -+ unsigned ch12:1; -+ unsigned ch11:1; -+ unsigned ch10:1; -+ unsigned ch9:1; -+ unsigned ch8:1; -+ unsigned ch7:1; -+ unsigned ch6:1; -+ unsigned ch5:1; -+ unsigned ch4:1; -+ unsigned ch3:1; -+ unsigned ch2:1; -+ unsigned ch1:1; -+ unsigned ch0:1; -+#else -+ unsigned ch0:1; -+ unsigned ch1:1; -+ unsigned ch2:1; -+ unsigned ch3:1; -+ unsigned ch4:1; -+ unsigned ch5:1; -+ unsigned ch6:1; -+ unsigned ch7:1; -+ unsigned ch8:1; -+ unsigned ch9:1; -+ unsigned ch10:1; -+ unsigned ch11:1; -+ unsigned ch12:1; -+ unsigned ch13:1; -+ unsigned ch14:1; -+ unsigned ch15:1; -+ unsigned reserved:16; -+#endif -+ } b; -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:16; -+ unsigned chint:16; -+#else -+ unsigned chint:16; -+ unsigned reserved:16; -+#endif -+ } b2; -+}; -+ -+/** -+ * This union represents the bit fields in the Host All Interrupt -+ * Register. -+ */ -+union haintmsk_data { -+ /** raw register data */ -+ uint32_t d32; -+ /** register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:16; -+ unsigned ch15:1; -+ unsigned ch14:1; -+ unsigned ch13:1; -+ unsigned ch12:1; -+ unsigned ch11:1; -+ unsigned ch10:1; -+ unsigned ch9:1; -+ unsigned ch8:1; -+ unsigned ch7:1; -+ unsigned ch6:1; -+ unsigned ch5:1; -+ unsigned ch4:1; -+ unsigned ch3:1; -+ unsigned ch2:1; -+ unsigned ch1:1; -+ unsigned ch0:1; -+#else -+ unsigned ch0:1; -+ unsigned ch1:1; -+ unsigned ch2:1; -+ unsigned ch3:1; -+ unsigned ch4:1; -+ unsigned ch5:1; -+ unsigned ch6:1; -+ unsigned ch7:1; -+ unsigned ch8:1; -+ unsigned ch9:1; -+ unsigned ch10:1; -+ unsigned ch11:1; -+ unsigned ch12:1; -+ unsigned ch13:1; -+ unsigned ch14:1; -+ unsigned ch15:1; -+ unsigned reserved:16; -+#endif -+ } b; -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:16; -+ unsigned chint:16; -+#else -+ unsigned chint:16; -+ unsigned reserved:16; -+#endif -+ } b2; -+}; -+ -+/* -+ * Host Channel Specific Registers. 500h-5FCh -+ */ -+struct dwc_otg_hc_regs { -+ /* -+ * Host Channel 0 Characteristic Register. -+ * Offset: 500h + (chan_num * 20h) + 00h -+ */ -+ uint32_t hcchar; -+ /* -+ * Host Channel 0 Split Control Register. -+ * Offset: 500h + (chan_num * 20h) + 04h -+ */ -+ uint32_t hcsplt; -+ /* -+ * Host Channel 0 Interrupt Register. -+ * Offset: 500h + (chan_num * 20h) + 08h -+ */ -+ uint32_t hcint; -+ /* -+ * Host Channel 0 Interrupt Mask Register. -+ * Offset: 500h + (chan_num * 20h) + 0Ch -+ */ -+ uint32_t hcintmsk; -+ /* -+ * Host Channel 0 Transfer Size Register. -+ * Offset: 500h + (chan_num * 20h) + 10h -+ */ -+ uint32_t hctsiz; -+ /* -+ * Host Channel 0 DMA Address Register. -+ * Offset: 500h + (chan_num * 20h) + 14h -+ */ -+ uint32_t hcdma; -+ /* -+ * Reserved. -+ * Offset: 500h + (chan_num * 20h) + 18h - -+ * 500h + (chan_num * 20h) + 1Ch -+ */ -+ uint32_t reserved[2]; -+}; -+ -+/** -+ * This union represents the bit fields in the Host Channel Characteristics -+ * Register. Read the register into the d32 member then set/clear the -+ * bits using the bit elements. Write the d32 member to the -+ * hcchar register. -+ */ -+union hcchar_data { -+ /** raw register data */ -+ uint32_t d32; -+ -+ /** register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned chen:1; -+ unsigned chdis:1; -+ unsigned oddfrm:1; -+ unsigned devaddr:7; -+ unsigned multicnt:2; -+ unsigned eptype:2; -+ unsigned lspddev:1; -+ unsigned reserved:1; -+ unsigned epdir:1; -+ unsigned epnum:4; -+ unsigned mps:11; -+#else -+ -+ /* Maximum packet size in bytes */ -+ unsigned mps:11; -+ -+ /* Endpoint number */ -+ unsigned epnum:4; -+ -+ /* 0: OUT, 1: IN */ -+ unsigned epdir:1; -+ -+ unsigned reserved:1; -+ -+ /* 0: Full/high speed device, 1: Low speed device */ -+ unsigned lspddev:1; -+ -+ /* 0: Control, 1: Isoc, 2: Bulk, 3: Intr */ -+ unsigned eptype:2; -+ -+ /* Packets per frame for periodic transfers. 0 is reserved. */ -+ unsigned multicnt:2; -+ -+ /* Device address */ -+ unsigned devaddr:7; -+ -+ /* -+ * Frame to transmit periodic transaction. -+ * 0: even, 1: odd -+ */ -+ unsigned oddfrm:1; -+ -+ /* Channel disable */ -+ unsigned chdis:1; -+ -+ /* Channel enable */ -+ unsigned chen:1; -+#endif -+ } b; -+}; -+ -+union hcsplt_data { -+ /* raw register data */ -+ uint32_t d32; -+ -+ /* register bits */ -+ struct { -+#define DWC_HCSPLIT_XACTPOS_ALL 3 -+#define DWC_HCSPLIT_XACTPOS_BEGIN 2 -+#define DWC_HCSPLIT_XACTPOS_END 1 -+#define DWC_HCSPLIT_XACTPOS_MID 0 -+ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned spltena:1; -+ unsigned reserved:14; -+ unsigned compsplt:1; -+ unsigned xactpos:2; -+ unsigned hubaddr:7; -+ unsigned prtaddr:7; -+#else -+ -+ /* Port Address */ -+ unsigned prtaddr:7; -+ -+ /* Hub Address */ -+ unsigned hubaddr:7; -+ -+ /* Transaction Position */ -+ unsigned xactpos:2; -+ -+ /* Do Complete Split */ -+ unsigned compsplt:1; -+ -+ /* Reserved */ -+ unsigned reserved:14; -+ -+ /* Split Enble */ -+ unsigned spltena:1; -+#endif -+ } b; -+}; -+ -+/** -+ * This union represents the bit fields in the Host All Interrupt -+ * Register. -+ */ -+union hcint_data { -+ /* raw register data */ -+ uint32_t d32; -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:21; -+ unsigned datatglerr:1; -+ unsigned frmovrun:1; -+ unsigned bblerr:1; -+ unsigned xacterr:1; -+ unsigned nyet:1; -+ unsigned ack:1; -+ unsigned nak:1; -+ unsigned stall:1; -+ unsigned ahberr:1; -+ unsigned chhltd:1; -+ unsigned xfercomp:1; -+#else -+ -+ /* Transfer Complete */ -+ unsigned xfercomp:1; -+ /* Channel Halted */ -+ unsigned chhltd:1; -+ /* AHB Error */ -+ unsigned ahberr:1; -+ /* STALL Response Received */ -+ unsigned stall:1; -+ /* NAK Response Received */ -+ unsigned nak:1; -+ /* ACK Response Received */ -+ unsigned ack:1; -+ /* NYET Response Received */ -+ unsigned nyet:1; -+ /* Transaction Err */ -+ unsigned xacterr:1; -+ /* Babble Error */ -+ unsigned bblerr:1; -+ /* Frame Overrun */ -+ unsigned frmovrun:1; -+ /* Data Toggle Error */ -+ unsigned datatglerr:1; -+ /* Reserved */ -+ unsigned reserved:21; -+#endif -+ } b; -+}; -+ -+/** -+ * This union represents the bit fields in the Host Channel Transfer Size -+ * Register. Read the register into the d32 member then set/clear the -+ * bits using the bit elements. Write the d32 member to the -+ * hcchar register. -+ */ -+union hctsiz_data { -+ /* raw register data */ -+ uint32_t d32; -+ -+ /* register bits */ -+ struct { -+#define DWC_HCTSIZ_SETUP 3 -+#define DWC_HCTSIZ_MDATA 3 -+#define DWC_HCTSIZ_DATA2 1 -+#define DWC_HCTSIZ_DATA1 2 -+#define DWC_HCTSIZ_DATA0 0 -+ -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned dopng:1; -+ unsigned pid:2; -+ unsigned pktcnt:10; -+ unsigned xfersize:19; -+#else -+ -+ /* Total transfer size in bytes */ -+ unsigned xfersize:19; -+ -+ /* Data packets to transfer */ -+ unsigned pktcnt:10; -+ -+ /* -+ * Packet ID for next data packet -+ * 0: DATA0 -+ * 1: DATA2 -+ * 2: DATA1 -+ * 3: MDATA (non-Control), SETUP (Control) -+ */ -+ unsigned pid:2; -+ -+ /* Do PING protocol when 1 */ -+ unsigned dopng:1; -+#endif -+ } b; -+}; -+ -+/** -+ * This union represents the bit fields in the Host Channel Interrupt Mask -+ * Register. Read the register into the d32 member then set/clear the -+ * bits using the bit elements. Write the d32 member to the -+ * hcintmsk register. -+ */ -+union hcintmsk_data { -+ /** raw register data */ -+ uint32_t d32; -+ -+ /** register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:21; -+ unsigned datatglerr:1; -+ unsigned frmovrun:1; -+ unsigned bblerr:1; -+ unsigned xacterr:1; -+ unsigned nyet:1; -+ unsigned ack:1; -+ unsigned nak:1; -+ unsigned stall:1; -+ unsigned ahberr:1; -+ unsigned chhltd:1; -+ unsigned xfercompl:1; -+#else -+ unsigned xfercompl:1; -+ unsigned chhltd:1; -+ unsigned ahberr:1; -+ unsigned stall:1; -+ unsigned nak:1; -+ unsigned ack:1; -+ unsigned nyet:1; -+ unsigned xacterr:1; -+ unsigned bblerr:1; -+ unsigned frmovrun:1; -+ unsigned datatglerr:1; -+ unsigned reserved:21; -+#endif -+ } b; -+}; -+ -+/** OTG Host Interface Structure. -+ * -+ * The OTG Host Interface Structure structure contains information -+ * needed to manage the DWC_otg controller acting in host mode. It -+ * represents the programming view of the host-specific aspects of the -+ * controller. -+ */ -+struct dwc_otg_host_if { -+ /* Host Global Registers starting at offset 400h.*/ -+ struct dwc_otg_host_global_regs *host_global_regs; -+#define DWC_OTG_HOST_GLOBAL_REG_OFFSET 0x400 -+ -+ /* Host Port 0 Control and Status Register */ -+ uint32_t *hprt0; -+#define DWC_OTG_HOST_PORT_REGS_OFFSET 0x440 -+ -+ /* Host Channel Specific Registers at offsets 500h-5FCh. */ -+ struct dwc_otg_hc_regs *hc_regs[MAX_EPS_CHANNELS]; -+#define DWC_OTG_HOST_CHAN_REGS_OFFSET 0x500 -+#define DWC_OTG_CHAN_REGS_OFFSET 0x20 -+ -+ /* Host configuration information */ -+ /* Number of Host Channels (range: 1-16) */ -+ uint8_t num_host_channels; -+ /* Periodic EPs supported (0: no, 1: yes) */ -+ uint8_t perio_eps_supported; -+ /* Periodic Tx FIFO Size (Only 1 host periodic Tx FIFO) */ -+ uint16_t perio_tx_fifo_size; -+ -+}; -+ -+/** -+ * This union represents the bit fields in the Power and Clock Gating Control -+ * Register. Read the register into the d32 member then set/clear the -+ * bits using the bit elements. -+ */ -+union pcgcctl_data { -+ /* raw register data */ -+ uint32_t d32; -+ -+ /* register bits */ -+ struct { -+#ifdef __BIG_ENDIAN_BITFIELD -+ unsigned reserved:27; -+ unsigned physuspended:1; -+ unsigned rstpdwnmodule:1; -+ unsigned pwrclmp:1; -+ unsigned gatehclk:1; -+ unsigned stoppclk:1; -+#else -+ -+ /* Stop Pclk */ -+ unsigned stoppclk:1; -+ /* Gate Hclk */ -+ unsigned gatehclk:1; -+ /* Power Clamp */ -+ unsigned pwrclmp:1; -+ /* Reset Power Down Modules */ -+ unsigned rstpdwnmodule:1; -+ /* PHY Suspended */ -+ unsigned physuspended:1; -+ -+ unsigned reserved:27; -+#endif -+ } b; -+}; -+ -+#endif --- -1.6.0.6 - diff --git a/target/linux/octeon/patches-2.6.30/100-wndap330_hacks.patch b/target/linux/octeon/patches-2.6.30/100-wndap330_hacks.patch deleted file mode 100644 index c4ca4217c0..0000000000 --- a/target/linux/octeon/patches-2.6.30/100-wndap330_hacks.patch +++ /dev/null @@ -1,77 +0,0 @@ ---- a/drivers/staging/octeon/cvmx-helper-board.c -+++ b/drivers/staging/octeon/cvmx-helper-board.c -@@ -90,7 +90,7 @@ int cvmx_helper_board_get_mii_address(in - case CVMX_BOARD_TYPE_KODAMA: - case CVMX_BOARD_TYPE_EBH3100: - case CVMX_BOARD_TYPE_HIKARI: -- case CVMX_BOARD_TYPE_CN3010_EVB_HS5: -+ //case CVMX_BOARD_TYPE_CN3010_EVB_HS5: /* hack for the WNDAP330 */ - case CVMX_BOARD_TYPE_CN3005_EVB_HS5: - case CVMX_BOARD_TYPE_CN3020_EVB_HS5: - /* -@@ -103,6 +103,12 @@ int cvmx_helper_board_get_mii_address(in - return 9; - else - return -1; -+ case CVMX_BOARD_TYPE_CN3010_EVB_HS5: /* hack for the WNDAP330 */ -+ /* We have only one port, using GMII */ -+ if (ipd_port == 0) -+ return 9; -+ else -+ return -1; - case CVMX_BOARD_TYPE_NAC38: - /* Board has 8 RGMII ports PHYs are 0-7 */ - if ((ipd_port >= 0) && (ipd_port < 4)) -@@ -205,7 +211,7 @@ cvmx_helper_link_info_t __cvmx_helper_bo - result.s.speed = 1000; - return result; - case CVMX_BOARD_TYPE_EBH3100: -- case CVMX_BOARD_TYPE_CN3010_EVB_HS5: -+ //case CVMX_BOARD_TYPE_CN3010_EVB_HS5: /* hack for the WNDAP330 */ - case CVMX_BOARD_TYPE_CN3005_EVB_HS5: - case CVMX_BOARD_TYPE_CN3020_EVB_HS5: - /* Port 1 on these boards is always Gigabit */ -@@ -217,6 +223,9 @@ cvmx_helper_link_info_t __cvmx_helper_bo - } - /* Fall through to the generic code below */ - break; -+ case CVMX_BOARD_TYPE_CN3010_EVB_HS5: /* hack for the WNDAP330 */ -+ is_broadcom_phy = 1; -+ break; - case CVMX_BOARD_TYPE_CUST_NB5: - /* Port 1 on these boards is always Gigabit */ - if (ipd_port == 1) { ---- a/drivers/staging/octeon/cvmx-helper-rgmii.c -+++ b/drivers/staging/octeon/cvmx-helper-rgmii.c -@@ -66,13 +66,15 @@ int __cvmx_helper_rgmii_probe(int interf - cvmx_dprintf("ERROR: RGMII initialize called in " - "SPI interface\n"); - } else if (OCTEON_IS_MODEL(OCTEON_CN31XX) -- || OCTEON_IS_MODEL(OCTEON_CN30XX) -+ //|| OCTEON_IS_MODEL(OCTEON_CN30XX) - || OCTEON_IS_MODEL(OCTEON_CN50XX)) { - /* - * On these chips "type" says we're in - * GMII/MII mode. This limits us to 2 ports - */ - num_ports = 2; -+ } else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) { -+ num_ports = 1; - } else { - cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n", - __func__); ---- a/arch/mips/cavium-octeon/pci.c -+++ b/arch/mips/cavium-octeon/pci.c -@@ -95,9 +95,11 @@ const char *octeon_get_pci_interrupts(vo - case CVMX_BOARD_TYPE_EBH3000: - return ""; - case CVMX_BOARD_TYPE_EBH3100: -- case CVMX_BOARD_TYPE_CN3010_EVB_HS5: -+ //case CVMX_BOARD_TYPE_CN3010_EVB_HS5: - case CVMX_BOARD_TYPE_CN3005_EVB_HS5: - return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; -+ case CVMX_BOARD_TYPE_CN3010_EVB_HS5: -+ return "AAAAAAAAAAAAAABAAAAAAAAAAAAAAABA"; - case CVMX_BOARD_TYPE_BBGW_REF: - return "AABCD"; - default: diff --git a/target/linux/octeon/patches-2.6.30/105-nb5_fixup.patch b/target/linux/octeon/patches-2.6.30/105-nb5_fixup.patch deleted file mode 100644 index 2165eb0a1b..0000000000 --- a/target/linux/octeon/patches-2.6.30/105-nb5_fixup.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/arch/mips/cavium-octeon/pci.c -+++ b/arch/mips/cavium-octeon/pci.c -@@ -102,6 +102,8 @@ const char *octeon_get_pci_interrupts(vo - return "AAAAAAAAAAAAAABAAAAAAAAAAAAAAABA"; - case CVMX_BOARD_TYPE_BBGW_REF: - return "AABCD"; -+ case CVMX_BOARD_TYPE_CUST_NB5: -+ return "ABDABAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - default: - return ""; - } ---- a/drivers/staging/octeon/cvmx-helper-board.c -+++ b/drivers/staging/octeon/cvmx-helper-board.c -@@ -699,6 +699,7 @@ cvmx_helper_board_usb_clock_types_t __cv - { - switch (cvmx_sysinfo_get()->board_type) { - case CVMX_BOARD_TYPE_BBGW_REF: -+ case CVMX_BOARD_TYPE_CUST_NB5: - return USB_CLOCK_TYPE_CRYSTAL_12; - } - return USB_CLOCK_TYPE_REF_48; diff --git a/target/linux/octeon/patches-2.6.30/106-no_module_reloc.patch b/target/linux/octeon/patches-2.6.30/106-no_module_reloc.patch deleted file mode 100644 index 449bda7567..0000000000 --- a/target/linux/octeon/patches-2.6.30/106-no_module_reloc.patch +++ /dev/null @@ -1,372 +0,0 @@ -diff -urN linux-2.6.30.10/arch/mips/Makefile linux-2.6.30.10.new//arch/mips/Makefile ---- linux-2.6.30.10/arch/mips/Makefile 2010-01-29 16:12:01.000000000 +0100 -+++ linux-2.6.30.10.new//arch/mips/Makefile 2009-12-04 07:00:07.000000000 +0100 -@@ -83,7 +83,7 @@ - cflags-y += -G 0 -mno-abicalls -fno-pic -pipe - cflags-y += -msoft-float - LDFLAGS_vmlinux += -G 0 -static -n -nostdlib --MODFLAGS += -mno-long-calls -+MODFLAGS += -mlong-calls - - cflags-y += -ffreestanding - -diff -urN linux-2.6.30.10/arch/mips/include/asm/module.h linux-2.6.30.10.new//arch/mips/include/asm/module.h ---- linux-2.6.30.10/arch/mips/include/asm/module.h 2010-01-29 16:12:01.000000000 +0100 -+++ linux-2.6.30.10.new//arch/mips/include/asm/module.h 2009-12-04 07:00:07.000000000 +0100 -@@ -9,11 +9,6 @@ - struct list_head dbe_list; - const struct exception_table_entry *dbe_start; - const struct exception_table_entry *dbe_end; -- -- void *phys_plt_tbl; -- void *virt_plt_tbl; -- unsigned int phys_plt_offset; -- unsigned int virt_plt_offset; - }; - - typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ -diff -urN linux-2.6.30.10/arch/mips/kernel/module.c linux-2.6.30.10.new//arch/mips/kernel/module.c ---- linux-2.6.30.10/arch/mips/kernel/module.c 2010-01-29 16:12:01.000000000 +0100 -+++ linux-2.6.30.10.new//arch/mips/kernel/module.c 2009-12-04 07:00:07.000000000 +0100 -@@ -43,116 +43,6 @@ - static LIST_HEAD(dbe_list); - static DEFINE_SPINLOCK(dbe_lock); - --/* -- * Get the potential max trampolines size required of the init and -- * non-init sections. Only used if we cannot find enough contiguous -- * physically mapped memory to put the module into. -- */ --static unsigned int --get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, -- const char *secstrings, unsigned int symindex, bool is_init) --{ -- unsigned long ret = 0; -- unsigned int i, j; -- Elf_Sym *syms; -- -- /* Everything marked ALLOC (this includes the exported symbols) */ -- for (i = 1; i < hdr->e_shnum; ++i) { -- unsigned int info = sechdrs[i].sh_info; -- -- if (sechdrs[i].sh_type != SHT_REL -- && sechdrs[i].sh_type != SHT_RELA) -- continue; -- -- /* Not a valid relocation section? */ -- if (info >= hdr->e_shnum) -- continue; -- -- /* Don't bother with non-allocated sections */ -- if (!(sechdrs[info].sh_flags & SHF_ALLOC)) -- continue; -- -- /* If it's called *.init*, and we're not init, we're -- not interested */ -- if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) -- != is_init) -- continue; -- -- syms = (Elf_Sym *) sechdrs[symindex].sh_addr; -- if (sechdrs[i].sh_type == SHT_REL) { -- Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr; -- unsigned int size = sechdrs[i].sh_size / sizeof(*rel); -- -- for (j = 0; j < size; ++j) { -- Elf_Sym *sym; -- -- if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26) -- continue; -- -- sym = syms + ELF_MIPS_R_SYM(rel[j]); -- if (!is_init && sym->st_shndx != SHN_UNDEF) -- continue; -- -- ret += 4 * sizeof(int); -- } -- } else { -- Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr; -- unsigned int size = sechdrs[i].sh_size / sizeof(*rela); -- -- for (j = 0; j < size; ++j) { -- Elf_Sym *sym; -- -- if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26) -- continue; -- -- sym = syms + ELF_MIPS_R_SYM(rela[j]); -- if (!is_init && sym->st_shndx != SHN_UNDEF) -- continue; -- -- ret += 4 * sizeof(int); -- } -- } -- } -- -- return ret; --} -- --#ifndef MODULE_START --static void *alloc_phys(unsigned long size) --{ -- unsigned order; -- struct page *page; -- struct page *p; -- -- size = PAGE_ALIGN(size); -- order = get_order(size); -- -- page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN | -- __GFP_THISNODE, order); -- if (!page) -- return NULL; -- -- split_page(page, order); -- -- for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p) -- __free_page(p); -- -- return page_address(page); --} --#endif -- --static void free_phys(void *ptr, unsigned long size) --{ -- struct page *page; -- struct page *end; -- -- page = virt_to_page(ptr); -- end = page + (PAGE_ALIGN(size) >> PAGE_SHIFT); -- -- for (; page < end; ++page) -- __free_page(page); --} -- - void *module_alloc(unsigned long size) - { - #ifdef MODULE_START -@@ -168,101 +58,23 @@ - - return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL); - #else -- void *ptr; -- - if (size == 0) - return NULL; -- -- ptr = alloc_phys(size); -- -- /* If we failed to allocate physically contiguous memory, -- * fall back to regular vmalloc. The module loader code will -- * create jump tables to handle long jumps */ -- if (!ptr) -- return vmalloc(size); -- -- return ptr; --#endif --} -- --static inline bool is_phys_addr(void *ptr) --{ --#ifdef CONFIG_64BIT -- return (KSEGX((unsigned long)ptr) == CKSEG0); --#else -- return (KSEGX(ptr) == KSEG0); -+ return vmalloc(size); - #endif - } - - /* Free memory returned from module_alloc */ - void module_free(struct module *mod, void *module_region) - { -- if (is_phys_addr(module_region)) { -- if (mod->module_init == module_region) -- free_phys(module_region, mod->init_size); -- else if (mod->module_core == module_region) -- free_phys(module_region, mod->core_size); -- else -- BUG(); -- } else { -- vfree(module_region); -- } -+ vfree(module_region); - /* FIXME: If module_region == mod->init_region, trim exception - table entries. */ - } - --static void *__module_alloc(int size, bool phys) --{ -- void *ptr; -- -- if (phys) -- ptr = kmalloc(size, GFP_KERNEL); -- else -- ptr = vmalloc(size); -- return ptr; --} -- --static void __module_free(void *ptr) --{ -- if (is_phys_addr(ptr)) -- kfree(ptr); -- else -- vfree(ptr); --} -- - int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, - char *secstrings, struct module *mod) - { -- unsigned int symindex = 0; -- unsigned int core_size, init_size; -- int i; -- -- for (i = 1; i < hdr->e_shnum; i++) -- if (sechdrs[i].sh_type == SHT_SYMTAB) -- symindex = i; -- -- core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false); -- init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true); -- -- mod->arch.phys_plt_offset = 0; -- mod->arch.virt_plt_offset = 0; -- mod->arch.phys_plt_tbl = NULL; -- mod->arch.virt_plt_tbl = NULL; -- -- if ((core_size + init_size) == 0) -- return 0; -- -- mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1); -- if (!mod->arch.phys_plt_tbl) -- return -ENOMEM; -- -- mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0); -- if (!mod->arch.virt_plt_tbl) { -- __module_free(mod->arch.phys_plt_tbl); -- mod->arch.phys_plt_tbl = NULL; -- return -ENOMEM; -- } -- - return 0; - } - -@@ -285,37 +97,27 @@ - return 0; - } - --static Elf_Addr add_plt_entry_to(unsigned *plt_offset, -- void *start, Elf_Addr v) -+static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) - { -- unsigned *tramp = start + *plt_offset; -- -- *plt_offset += 4 * sizeof(int); -- -- /* adjust carry for addiu */ -- if (v & 0x00008000) -- v += 0x10000; -- -- tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */ -- tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */ -- tramp[2] = 0x03200008; /* jr t9 */ -- tramp[3] = 0x00000000; /* nop */ -+ if (v % 4) { -+ printk(KERN_ERR "module %s: dangerous relocation\n", me->name); -+ return -ENOEXEC; -+ } - -- return (Elf_Addr) tramp; --} -+ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { -+ printk(KERN_ERR -+ "module %s: relocation overflow\n", -+ me->name); -+ return -ENOEXEC; -+ } - --static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v) --{ -- if (is_phys_addr(location)) -- return add_plt_entry_to(&me->arch.phys_plt_offset, -- me->arch.phys_plt_tbl, v); -- else -- return add_plt_entry_to(&me->arch.virt_plt_offset, -- me->arch.virt_plt_tbl, v); -+ *location = (*location & ~0x03ffffff) | -+ ((*location + (v >> 2)) & 0x03ffffff); - -+ return 0; - } - --static int set_r_mips_26(struct module *me, u32 *location, u32 ofs, Elf_Addr v) -+static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) - { - if (v % 4) { - printk(KERN_ERR "module %s: dangerous relocation\n", me->name); -@@ -323,31 +125,17 @@ - } - - if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { -- v = add_plt_entry(me, location, v + (ofs << 2)); -- if (!v) { -- printk(KERN_ERR -+ printk(KERN_ERR - "module %s: relocation overflow\n", - me->name); -- return -ENOEXEC; -- } -- ofs = 0; -+ return -ENOEXEC; - } - -- *location = (*location & ~0x03ffffff) | ((ofs + (v >> 2)) & 0x03ffffff); -+ *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff); - - return 0; - } - --static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) --{ -- return set_r_mips_26(me, location, *location & 0x03ffffff, v); --} -- --static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) --{ -- return set_r_mips_26(me, location, 0, v); --} -- - static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v) - { - struct mips_hi16 *n; -@@ -612,32 +400,11 @@ - list_add(&me->arch.dbe_list, &dbe_list); - spin_unlock_irq(&dbe_lock); - } -- -- /* Get rid of the fixup trampoline if we're running the module -- * from physically mapped address space */ -- if (me->arch.phys_plt_offset == 0) { -- __module_free(me->arch.phys_plt_tbl); -- me->arch.phys_plt_tbl = NULL; -- } -- if (me->arch.virt_plt_offset == 0) { -- __module_free(me->arch.virt_plt_tbl); -- me->arch.virt_plt_tbl = NULL; -- } -- - return 0; - } - - void module_arch_cleanup(struct module *mod) - { -- if (mod->arch.phys_plt_tbl) { -- __module_free(mod->arch.phys_plt_tbl); -- mod->arch.phys_plt_tbl = NULL; -- } -- if (mod->arch.virt_plt_tbl) { -- __module_free(mod->arch.virt_plt_tbl); -- mod->arch.virt_plt_tbl = NULL; -- } -- - spin_lock_irq(&dbe_lock); - list_del(&mod->arch.dbe_list); - spin_unlock_irq(&dbe_lock); |