14a22edb5SArvind Bhushan /* 24a22edb5SArvind Bhushan * This file is part of the Chelsio FCoE driver for Linux. 34a22edb5SArvind Bhushan * 44a22edb5SArvind Bhushan * Copyright (c) 2008-2013 Chelsio Communications, Inc. All rights reserved. 54a22edb5SArvind Bhushan * 64a22edb5SArvind Bhushan * This software is available to you under a choice of one of two 74a22edb5SArvind Bhushan * licenses. You may choose to be licensed under the terms of the GNU 84a22edb5SArvind Bhushan * General Public License (GPL) Version 2, available from the file 94a22edb5SArvind Bhushan * OpenIB.org BSD license below: 104a22edb5SArvind Bhushan * 114a22edb5SArvind Bhushan * Redistribution and use in source and binary forms, with or 124a22edb5SArvind Bhushan * without modification, are permitted provided that the following 134a22edb5SArvind Bhushan * conditions are met: 144a22edb5SArvind Bhushan * 154a22edb5SArvind Bhushan * - Redistributions of source code must retain the above 164a22edb5SArvind Bhushan * copyright notice, this list of conditions and the following 174a22edb5SArvind Bhushan * disclaimer. 184a22edb5SArvind Bhushan * 194a22edb5SArvind Bhushan * - Redistributions in binary form must reproduce the above 204a22edb5SArvind Bhushan * copyright notice, this list of conditions and the following 214a22edb5SArvind Bhushan * disclaimer in the documentation and/or other materials 224a22edb5SArvind Bhushan * provided with the distribution. 234a22edb5SArvind Bhushan * 244a22edb5SArvind Bhushan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 254a22edb5SArvind Bhushan * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 264a22edb5SArvind Bhushan * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 274a22edb5SArvind Bhushan * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 284a22edb5SArvind Bhushan * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 294a22edb5SArvind Bhushan * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 304a22edb5SArvind Bhushan * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 314a22edb5SArvind Bhushan * SOFTWARE. 324a22edb5SArvind Bhushan */ 334a22edb5SArvind Bhushan 344a22edb5SArvind Bhushan #include "csio_hw.h" 354a22edb5SArvind Bhushan #include "csio_init.h" 364a22edb5SArvind Bhushan 374a22edb5SArvind Bhushan static int 384a22edb5SArvind Bhushan csio_t5_set_mem_win(struct csio_hw *hw, uint32_t win) 394a22edb5SArvind Bhushan { 404a22edb5SArvind Bhushan u32 mem_win_base; 414a22edb5SArvind Bhushan /* 424a22edb5SArvind Bhushan * Truncation intentional: we only read the bottom 32-bits of the 434a22edb5SArvind Bhushan * 64-bit BAR0/BAR1 ... We use the hardware backdoor mechanism to 444a22edb5SArvind Bhushan * read BAR0 instead of using pci_resource_start() because we could be 454a22edb5SArvind Bhushan * operating from within a Virtual Machine which is trapping our 464a22edb5SArvind Bhushan * accesses to our Configuration Space and we need to set up the PCI-E 474a22edb5SArvind Bhushan * Memory Window decoders with the actual addresses which will be 484a22edb5SArvind Bhushan * coming across the PCI-E link. 494a22edb5SArvind Bhushan */ 504a22edb5SArvind Bhushan 514a22edb5SArvind Bhushan /* For T5, only relative offset inside the PCIe BAR is passed */ 524a22edb5SArvind Bhushan mem_win_base = MEMWIN_BASE; 534a22edb5SArvind Bhushan 544a22edb5SArvind Bhushan /* 554a22edb5SArvind Bhushan * Set up memory window for accessing adapter memory ranges. (Read 564a22edb5SArvind Bhushan * back MA register to ensure that changes propagate before we attempt 574a22edb5SArvind Bhushan * to use the new values.) 584a22edb5SArvind Bhushan */ 59f061de42SHariprasad Shenai csio_wr_reg32(hw, mem_win_base | BIR_V(0) | 60f061de42SHariprasad Shenai WINDOW_V(ilog2(MEMWIN_APERTURE) - 10), 61f061de42SHariprasad Shenai PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, win)); 624a22edb5SArvind Bhushan csio_rd_reg32(hw, 63f061de42SHariprasad Shenai PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, win)); 644a22edb5SArvind Bhushan 654a22edb5SArvind Bhushan return 0; 664a22edb5SArvind Bhushan } 674a22edb5SArvind Bhushan 684a22edb5SArvind Bhushan /* 694a22edb5SArvind Bhushan * Interrupt handler for the PCIE module. 704a22edb5SArvind Bhushan */ 714a22edb5SArvind Bhushan static void 724a22edb5SArvind Bhushan csio_t5_pcie_intr_handler(struct csio_hw *hw) 734a22edb5SArvind Bhushan { 744a22edb5SArvind Bhushan static struct intr_info pcie_intr_info[] = { 75f061de42SHariprasad Shenai { MSTGRPPERR_F, "Master Response Read Queue parity error", 764a22edb5SArvind Bhushan -1, 1 }, 77f061de42SHariprasad Shenai { MSTTIMEOUTPERR_F, "Master Timeout FIFO parity error", -1, 1 }, 78f061de42SHariprasad Shenai { MSIXSTIPERR_F, "MSI-X STI SRAM parity error", -1, 1 }, 79f061de42SHariprasad Shenai { MSIXADDRLPERR_F, "MSI-X AddrL parity error", -1, 1 }, 80f061de42SHariprasad Shenai { MSIXADDRHPERR_F, "MSI-X AddrH parity error", -1, 1 }, 81f061de42SHariprasad Shenai { MSIXDATAPERR_F, "MSI-X data parity error", -1, 1 }, 82f061de42SHariprasad Shenai { MSIXDIPERR_F, "MSI-X DI parity error", -1, 1 }, 83f061de42SHariprasad Shenai { PIOCPLGRPPERR_F, "PCI PIO completion Group FIFO parity error", 844a22edb5SArvind Bhushan -1, 1 }, 85f061de42SHariprasad Shenai { PIOREQGRPPERR_F, "PCI PIO request Group FIFO parity error", 864a22edb5SArvind Bhushan -1, 1 }, 87f061de42SHariprasad Shenai { TARTAGPERR_F, "PCI PCI target tag FIFO parity error", -1, 1 }, 88f061de42SHariprasad Shenai { MSTTAGQPERR_F, "PCI master tag queue parity error", -1, 1 }, 89f061de42SHariprasad Shenai { CREQPERR_F, "PCI CMD channel request parity error", -1, 1 }, 90f061de42SHariprasad Shenai { CRSPPERR_F, "PCI CMD channel response parity error", -1, 1 }, 91f061de42SHariprasad Shenai { DREQWRPERR_F, "PCI DMA channel write request parity error", 924a22edb5SArvind Bhushan -1, 1 }, 93f061de42SHariprasad Shenai { DREQPERR_F, "PCI DMA channel request parity error", -1, 1 }, 94f061de42SHariprasad Shenai { DRSPPERR_F, "PCI DMA channel response parity error", -1, 1 }, 95f061de42SHariprasad Shenai { HREQWRPERR_F, "PCI HMA channel count parity error", -1, 1 }, 96f061de42SHariprasad Shenai { HREQPERR_F, "PCI HMA channel request parity error", -1, 1 }, 97f061de42SHariprasad Shenai { HRSPPERR_F, "PCI HMA channel response parity error", -1, 1 }, 98f061de42SHariprasad Shenai { CFGSNPPERR_F, "PCI config snoop FIFO parity error", -1, 1 }, 99f061de42SHariprasad Shenai { FIDPERR_F, "PCI FID parity error", -1, 1 }, 100f061de42SHariprasad Shenai { VFIDPERR_F, "PCI INTx clear parity error", -1, 1 }, 101f061de42SHariprasad Shenai { MAGRPPERR_F, "PCI MA group FIFO parity error", -1, 1 }, 102f061de42SHariprasad Shenai { PIOTAGPERR_F, "PCI PIO tag parity error", -1, 1 }, 103f061de42SHariprasad Shenai { IPRXHDRGRPPERR_F, "PCI IP Rx header group parity error", 1044a22edb5SArvind Bhushan -1, 1 }, 105f061de42SHariprasad Shenai { IPRXDATAGRPPERR_F, "PCI IP Rx data group parity error", 1064a22edb5SArvind Bhushan -1, 1 }, 107f061de42SHariprasad Shenai { RPLPERR_F, "PCI IP replay buffer parity error", -1, 1 }, 108f061de42SHariprasad Shenai { IPSOTPERR_F, "PCI IP SOT buffer parity error", -1, 1 }, 109f061de42SHariprasad Shenai { TRGT1GRPPERR_F, "PCI TRGT1 group FIFOs parity error", -1, 1 }, 110f061de42SHariprasad Shenai { READRSPERR_F, "Outbound read error", -1, 0 }, 1114a22edb5SArvind Bhushan { 0, NULL, 0, 0 } 1124a22edb5SArvind Bhushan }; 1134a22edb5SArvind Bhushan 1144a22edb5SArvind Bhushan int fat; 1154bbd458eSVarun Prakash fat = csio_handle_intr_status(hw, PCIE_INT_CAUSE_A, pcie_intr_info); 1164a22edb5SArvind Bhushan if (fat) 1174a22edb5SArvind Bhushan csio_hw_fatal_err(hw); 1184a22edb5SArvind Bhushan } 1194a22edb5SArvind Bhushan 1204a22edb5SArvind Bhushan /* 1214a22edb5SArvind Bhushan * csio_t5_flash_cfg_addr - return the address of the flash configuration file 1224a22edb5SArvind Bhushan * @hw: the HW module 1234a22edb5SArvind Bhushan * 1244a22edb5SArvind Bhushan * Return the address within the flash where the Firmware Configuration 1254a22edb5SArvind Bhushan * File is stored. 1264a22edb5SArvind Bhushan */ 1274a22edb5SArvind Bhushan static unsigned int 1284a22edb5SArvind Bhushan csio_t5_flash_cfg_addr(struct csio_hw *hw) 1294a22edb5SArvind Bhushan { 1304a22edb5SArvind Bhushan return FLASH_CFG_START; 1314a22edb5SArvind Bhushan } 1324a22edb5SArvind Bhushan 1334a22edb5SArvind Bhushan /* 1344a22edb5SArvind Bhushan * csio_t5_mc_read - read from MC through backdoor accesses 1354a22edb5SArvind Bhushan * @hw: the hw module 1364a22edb5SArvind Bhushan * @idx: index to the register 1374a22edb5SArvind Bhushan * @addr: address of first byte requested 1384a22edb5SArvind Bhushan * @data: 64 bytes of data containing the requested address 1394a22edb5SArvind Bhushan * @ecc: where to store the corresponding 64-bit ECC word 1404a22edb5SArvind Bhushan * 1414a22edb5SArvind Bhushan * Read 64 bytes of data from MC starting at a 64-byte-aligned address 1424a22edb5SArvind Bhushan * that covers the requested address @addr. If @parity is not %NULL it 1434a22edb5SArvind Bhushan * is assigned the 64-bit ECC word for the read data. 1444a22edb5SArvind Bhushan */ 1454a22edb5SArvind Bhushan static int 1464a22edb5SArvind Bhushan csio_t5_mc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data, 1474a22edb5SArvind Bhushan uint64_t *ecc) 1484a22edb5SArvind Bhushan { 1494a22edb5SArvind Bhushan int i; 1504a22edb5SArvind Bhushan uint32_t mc_bist_cmd_reg, mc_bist_cmd_addr_reg, mc_bist_cmd_len_reg; 151f11106c9SLee Jones uint32_t mc_bist_data_pattern_reg; 1524a22edb5SArvind Bhushan 15389c3a86cSHariprasad Shenai mc_bist_cmd_reg = MC_REG(MC_P_BIST_CMD_A, idx); 15489c3a86cSHariprasad Shenai mc_bist_cmd_addr_reg = MC_REG(MC_P_BIST_CMD_ADDR_A, idx); 15589c3a86cSHariprasad Shenai mc_bist_cmd_len_reg = MC_REG(MC_P_BIST_CMD_LEN_A, idx); 15689c3a86cSHariprasad Shenai mc_bist_data_pattern_reg = MC_REG(MC_P_BIST_DATA_PATTERN_A, idx); 1574a22edb5SArvind Bhushan 15889c3a86cSHariprasad Shenai if (csio_rd_reg32(hw, mc_bist_cmd_reg) & START_BIST_F) 1594a22edb5SArvind Bhushan return -EBUSY; 1604a22edb5SArvind Bhushan csio_wr_reg32(hw, addr & ~0x3fU, mc_bist_cmd_addr_reg); 1614a22edb5SArvind Bhushan csio_wr_reg32(hw, 64, mc_bist_cmd_len_reg); 1624a22edb5SArvind Bhushan csio_wr_reg32(hw, 0xc, mc_bist_data_pattern_reg); 16389c3a86cSHariprasad Shenai csio_wr_reg32(hw, BIST_OPCODE_V(1) | START_BIST_F | BIST_CMD_GAP_V(1), 1644a22edb5SArvind Bhushan mc_bist_cmd_reg); 16589c3a86cSHariprasad Shenai i = csio_hw_wait_op_done_val(hw, mc_bist_cmd_reg, START_BIST_F, 1664a22edb5SArvind Bhushan 0, 10, 1, NULL); 1674a22edb5SArvind Bhushan if (i) 1684a22edb5SArvind Bhushan return i; 1694a22edb5SArvind Bhushan 17089c3a86cSHariprasad Shenai #define MC_DATA(i) MC_BIST_STATUS_REG(MC_BIST_STATUS_RDATA_A, i) 1714a22edb5SArvind Bhushan 1724a22edb5SArvind Bhushan for (i = 15; i >= 0; i--) 1734a22edb5SArvind Bhushan *data++ = htonl(csio_rd_reg32(hw, MC_DATA(i))); 1744a22edb5SArvind Bhushan if (ecc) 1754a22edb5SArvind Bhushan *ecc = csio_rd_reg64(hw, MC_DATA(16)); 1764a22edb5SArvind Bhushan #undef MC_DATA 1774a22edb5SArvind Bhushan return 0; 1784a22edb5SArvind Bhushan } 1794a22edb5SArvind Bhushan 1804a22edb5SArvind Bhushan /* 1814a22edb5SArvind Bhushan * csio_t5_edc_read - read from EDC through backdoor accesses 1824a22edb5SArvind Bhushan * @hw: the hw module 1834a22edb5SArvind Bhushan * @idx: which EDC to access 1844a22edb5SArvind Bhushan * @addr: address of first byte requested 1854a22edb5SArvind Bhushan * @data: 64 bytes of data containing the requested address 1864a22edb5SArvind Bhushan * @ecc: where to store the corresponding 64-bit ECC word 1874a22edb5SArvind Bhushan * 1884a22edb5SArvind Bhushan * Read 64 bytes of data from EDC starting at a 64-byte-aligned address 1894a22edb5SArvind Bhushan * that covers the requested address @addr. If @parity is not %NULL it 1904a22edb5SArvind Bhushan * is assigned the 64-bit ECC word for the read data. 1914a22edb5SArvind Bhushan */ 1924a22edb5SArvind Bhushan static int 1934a22edb5SArvind Bhushan csio_t5_edc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data, 1944a22edb5SArvind Bhushan uint64_t *ecc) 1954a22edb5SArvind Bhushan { 1964a22edb5SArvind Bhushan int i; 1974a22edb5SArvind Bhushan uint32_t edc_bist_cmd_reg, edc_bist_cmd_addr_reg, edc_bist_cmd_len_reg; 198f11106c9SLee Jones uint32_t edc_bist_cmd_data_pattern; 1994a22edb5SArvind Bhushan 2004a22edb5SArvind Bhushan /* 2014a22edb5SArvind Bhushan * These macro are missing in t4_regs.h file. 2024a22edb5SArvind Bhushan */ 2034a22edb5SArvind Bhushan #define EDC_STRIDE_T5 (EDC_T51_BASE_ADDR - EDC_T50_BASE_ADDR) 2044a22edb5SArvind Bhushan #define EDC_REG_T5(reg, idx) (reg + EDC_STRIDE_T5 * idx) 2054a22edb5SArvind Bhushan 20689c3a86cSHariprasad Shenai edc_bist_cmd_reg = EDC_REG_T5(EDC_H_BIST_CMD_A, idx); 20789c3a86cSHariprasad Shenai edc_bist_cmd_addr_reg = EDC_REG_T5(EDC_H_BIST_CMD_ADDR_A, idx); 20889c3a86cSHariprasad Shenai edc_bist_cmd_len_reg = EDC_REG_T5(EDC_H_BIST_CMD_LEN_A, idx); 20989c3a86cSHariprasad Shenai edc_bist_cmd_data_pattern = EDC_REG_T5(EDC_H_BIST_DATA_PATTERN_A, idx); 2104a22edb5SArvind Bhushan #undef EDC_REG_T5 2114a22edb5SArvind Bhushan #undef EDC_STRIDE_T5 2124a22edb5SArvind Bhushan 21389c3a86cSHariprasad Shenai if (csio_rd_reg32(hw, edc_bist_cmd_reg) & START_BIST_F) 2144a22edb5SArvind Bhushan return -EBUSY; 2154a22edb5SArvind Bhushan csio_wr_reg32(hw, addr & ~0x3fU, edc_bist_cmd_addr_reg); 2164a22edb5SArvind Bhushan csio_wr_reg32(hw, 64, edc_bist_cmd_len_reg); 2174a22edb5SArvind Bhushan csio_wr_reg32(hw, 0xc, edc_bist_cmd_data_pattern); 21889c3a86cSHariprasad Shenai csio_wr_reg32(hw, BIST_OPCODE_V(1) | START_BIST_F | BIST_CMD_GAP_V(1), 2194a22edb5SArvind Bhushan edc_bist_cmd_reg); 22089c3a86cSHariprasad Shenai i = csio_hw_wait_op_done_val(hw, edc_bist_cmd_reg, START_BIST_F, 2214a22edb5SArvind Bhushan 0, 10, 1, NULL); 2224a22edb5SArvind Bhushan if (i) 2234a22edb5SArvind Bhushan return i; 2244a22edb5SArvind Bhushan 22589c3a86cSHariprasad Shenai #define EDC_DATA(i) (EDC_BIST_STATUS_REG(EDC_BIST_STATUS_RDATA_A, i) + idx) 2264a22edb5SArvind Bhushan 2274a22edb5SArvind Bhushan for (i = 15; i >= 0; i--) 2284a22edb5SArvind Bhushan *data++ = htonl(csio_rd_reg32(hw, EDC_DATA(i))); 2294a22edb5SArvind Bhushan if (ecc) 2304a22edb5SArvind Bhushan *ecc = csio_rd_reg64(hw, EDC_DATA(16)); 2314a22edb5SArvind Bhushan #undef EDC_DATA 2324a22edb5SArvind Bhushan return 0; 2334a22edb5SArvind Bhushan } 2344a22edb5SArvind Bhushan 2354a22edb5SArvind Bhushan /* 2364a22edb5SArvind Bhushan * csio_t5_memory_rw - read/write EDC 0, EDC 1 or MC via PCIE memory window 2374a22edb5SArvind Bhushan * @hw: the csio_hw 2384a22edb5SArvind Bhushan * @win: PCI-E memory Window to use 2394a22edb5SArvind Bhushan * @mtype: memory type: MEM_EDC0, MEM_EDC1, MEM_MC0 (or MEM_MC) or MEM_MC1 2404a22edb5SArvind Bhushan * @addr: address within indicated memory type 2414a22edb5SArvind Bhushan * @len: amount of memory to transfer 2424a22edb5SArvind Bhushan * @buf: host memory buffer 2434a22edb5SArvind Bhushan * @dir: direction of transfer 1 => read, 0 => write 2444a22edb5SArvind Bhushan * 2454a22edb5SArvind Bhushan * Reads/writes an [almost] arbitrary memory region in the firmware: the 2464a22edb5SArvind Bhushan * firmware memory address, length and host buffer must be aligned on 247*a89562e3SBhaskar Chowdhury * 32-bit boundaries. The memory is transferred as a raw byte sequence 2484a22edb5SArvind Bhushan * from/to the firmware's memory. If this memory contains data 2494a22edb5SArvind Bhushan * structures which contain multi-byte integers, it's the callers 2504a22edb5SArvind Bhushan * responsibility to perform appropriate byte order conversions. 2514a22edb5SArvind Bhushan */ 2524a22edb5SArvind Bhushan static int 2534a22edb5SArvind Bhushan csio_t5_memory_rw(struct csio_hw *hw, u32 win, int mtype, u32 addr, 2544a22edb5SArvind Bhushan u32 len, uint32_t *buf, int dir) 2554a22edb5SArvind Bhushan { 2564a22edb5SArvind Bhushan u32 pos, start, offset, memoffset; 2574a22edb5SArvind Bhushan u32 edc_size, mc_size, win_pf, mem_reg, mem_aperture, mem_base; 2584a22edb5SArvind Bhushan 2594a22edb5SArvind Bhushan /* 2604a22edb5SArvind Bhushan * Argument sanity checks ... 2614a22edb5SArvind Bhushan */ 2624a22edb5SArvind Bhushan if ((addr & 0x3) || (len & 0x3)) 2634a22edb5SArvind Bhushan return -EINVAL; 2644a22edb5SArvind Bhushan 2654a22edb5SArvind Bhushan /* Offset into the region of memory which is being accessed 2664a22edb5SArvind Bhushan * MEM_EDC0 = 0 2674a22edb5SArvind Bhushan * MEM_EDC1 = 1 2684a22edb5SArvind Bhushan * MEM_MC = 2 -- T4 2694a22edb5SArvind Bhushan * MEM_MC0 = 2 -- For T5 2704a22edb5SArvind Bhushan * MEM_MC1 = 3 -- For T5 2714a22edb5SArvind Bhushan */ 2726559a7e8SHariprasad Shenai edc_size = EDRAM0_SIZE_G(csio_rd_reg32(hw, MA_EDRAM0_BAR_A)); 2734a22edb5SArvind Bhushan if (mtype != MEM_MC1) 2744a22edb5SArvind Bhushan memoffset = (mtype * (edc_size * 1024 * 1024)); 2754a22edb5SArvind Bhushan else { 2766559a7e8SHariprasad Shenai mc_size = EXT_MEM_SIZE_G(csio_rd_reg32(hw, 2776559a7e8SHariprasad Shenai MA_EXT_MEMORY_BAR_A)); 2784a22edb5SArvind Bhushan memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024; 2794a22edb5SArvind Bhushan } 2804a22edb5SArvind Bhushan 2814a22edb5SArvind Bhushan /* Determine the PCIE_MEM_ACCESS_OFFSET */ 2824a22edb5SArvind Bhushan addr = addr + memoffset; 2834a22edb5SArvind Bhushan 2844a22edb5SArvind Bhushan /* 2854a22edb5SArvind Bhushan * Each PCI-E Memory Window is programmed with a window size -- or 2864a22edb5SArvind Bhushan * "aperture" -- which controls the granularity of its mapping onto 2874a22edb5SArvind Bhushan * adapter memory. We need to grab that aperture in order to know 2884a22edb5SArvind Bhushan * how to use the specified window. The window is also programmed 2894a22edb5SArvind Bhushan * with the base address of the Memory Window in BAR0's address 2904a22edb5SArvind Bhushan * space. For T4 this is an absolute PCI-E Bus Address. For T5 2914a22edb5SArvind Bhushan * the address is relative to BAR0. 2924a22edb5SArvind Bhushan */ 2934a22edb5SArvind Bhushan mem_reg = csio_rd_reg32(hw, 294f061de42SHariprasad Shenai PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, win)); 295f061de42SHariprasad Shenai mem_aperture = 1 << (WINDOW_V(mem_reg) + 10); 296f061de42SHariprasad Shenai mem_base = PCIEOFST_G(mem_reg) << 10; 2974a22edb5SArvind Bhushan 2984a22edb5SArvind Bhushan start = addr & ~(mem_aperture-1); 2994a22edb5SArvind Bhushan offset = addr - start; 300f061de42SHariprasad Shenai win_pf = PFNUM_V(hw->pfn); 3014a22edb5SArvind Bhushan 3024a22edb5SArvind Bhushan csio_dbg(hw, "csio_t5_memory_rw: mem_reg: 0x%x, mem_aperture: 0x%x\n", 3034a22edb5SArvind Bhushan mem_reg, mem_aperture); 3044a22edb5SArvind Bhushan csio_dbg(hw, "csio_t5_memory_rw: mem_base: 0x%x, mem_offset: 0x%x\n", 3054a22edb5SArvind Bhushan mem_base, memoffset); 3064a22edb5SArvind Bhushan csio_dbg(hw, "csio_t5_memory_rw: start:0x%x, offset:0x%x, win_pf:%d\n", 3074a22edb5SArvind Bhushan start, offset, win_pf); 3084a22edb5SArvind Bhushan csio_dbg(hw, "csio_t5_memory_rw: mtype: %d, addr: 0x%x, len: %d\n", 3094a22edb5SArvind Bhushan mtype, addr, len); 3104a22edb5SArvind Bhushan 3114a22edb5SArvind Bhushan for (pos = start; len > 0; pos += mem_aperture, offset = 0) { 3124a22edb5SArvind Bhushan /* 3134a22edb5SArvind Bhushan * Move PCI-E Memory Window to our current transfer 3144a22edb5SArvind Bhushan * position. Read it back to ensure that changes propagate 3154a22edb5SArvind Bhushan * before we attempt to use the new value. 3164a22edb5SArvind Bhushan */ 3174a22edb5SArvind Bhushan csio_wr_reg32(hw, pos | win_pf, 318f061de42SHariprasad Shenai PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win)); 3194a22edb5SArvind Bhushan csio_rd_reg32(hw, 320f061de42SHariprasad Shenai PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win)); 3214a22edb5SArvind Bhushan 3224a22edb5SArvind Bhushan while (offset < mem_aperture && len > 0) { 3234a22edb5SArvind Bhushan if (dir) 3244a22edb5SArvind Bhushan *buf++ = csio_rd_reg32(hw, mem_base + offset); 3254a22edb5SArvind Bhushan else 3264a22edb5SArvind Bhushan csio_wr_reg32(hw, *buf++, mem_base + offset); 3274a22edb5SArvind Bhushan 3284a22edb5SArvind Bhushan offset += sizeof(__be32); 3294a22edb5SArvind Bhushan len -= sizeof(__be32); 3304a22edb5SArvind Bhushan } 3314a22edb5SArvind Bhushan } 3324a22edb5SArvind Bhushan return 0; 3334a22edb5SArvind Bhushan } 3344a22edb5SArvind Bhushan 3354a22edb5SArvind Bhushan /* 3364a22edb5SArvind Bhushan * csio_t5_dfs_create_ext_mem - setup debugfs for MC0 or MC1 to read the values 3374a22edb5SArvind Bhushan * @hw: the csio_hw 3384a22edb5SArvind Bhushan * 3394a22edb5SArvind Bhushan * This function creates files in the debugfs with external memory region 3404a22edb5SArvind Bhushan * MC0 & MC1. 3414a22edb5SArvind Bhushan */ 3424a22edb5SArvind Bhushan static void 3434a22edb5SArvind Bhushan csio_t5_dfs_create_ext_mem(struct csio_hw *hw) 3444a22edb5SArvind Bhushan { 3454a22edb5SArvind Bhushan u32 size; 3466559a7e8SHariprasad Shenai int i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE_A); 3476559a7e8SHariprasad Shenai 3486559a7e8SHariprasad Shenai if (i & EXT_MEM_ENABLE_F) { 3496559a7e8SHariprasad Shenai size = csio_rd_reg32(hw, MA_EXT_MEMORY_BAR_A); 3504a22edb5SArvind Bhushan csio_add_debugfs_mem(hw, "mc0", MEM_MC0, 3516559a7e8SHariprasad Shenai EXT_MEM_SIZE_G(size)); 3524a22edb5SArvind Bhushan } 3536559a7e8SHariprasad Shenai if (i & EXT_MEM1_ENABLE_F) { 3546559a7e8SHariprasad Shenai size = csio_rd_reg32(hw, MA_EXT_MEMORY1_BAR_A); 3554a22edb5SArvind Bhushan csio_add_debugfs_mem(hw, "mc1", MEM_MC1, 3566559a7e8SHariprasad Shenai EXT_MEM_SIZE_G(size)); 3574a22edb5SArvind Bhushan } 3584a22edb5SArvind Bhushan } 3594a22edb5SArvind Bhushan 3604a22edb5SArvind Bhushan /* T5 adapter specific function */ 3614a22edb5SArvind Bhushan struct csio_hw_chip_ops t5_ops = { 3624a22edb5SArvind Bhushan .chip_set_mem_win = csio_t5_set_mem_win, 3634a22edb5SArvind Bhushan .chip_pcie_intr_handler = csio_t5_pcie_intr_handler, 3644a22edb5SArvind Bhushan .chip_flash_cfg_addr = csio_t5_flash_cfg_addr, 3654a22edb5SArvind Bhushan .chip_mc_read = csio_t5_mc_read, 3664a22edb5SArvind Bhushan .chip_edc_read = csio_t5_edc_read, 3674a22edb5SArvind Bhushan .chip_memory_rw = csio_t5_memory_rw, 3684a22edb5SArvind Bhushan .chip_dfs_create_ext_mem = csio_t5_dfs_create_ext_mem, 3694a22edb5SArvind Bhushan }; 370