Пример #1
0
static int
csio_t5_set_mem_win(struct csio_hw *hw, uint32_t win)
{
	u32 mem_win_base;
	/*
	 * Truncation intentional: we only read the bottom 32-bits of the
	 * 64-bit BAR0/BAR1 ...  We use the hardware backdoor mechanism to
	 * read BAR0 instead of using pci_resource_start() because we could be
	 * operating from within a Virtual Machine which is trapping our
	 * accesses to our Configuration Space and we need to set up the PCI-E
	 * Memory Window decoders with the actual addresses which will be
	 * coming across the PCI-E link.
	 */

	/* For T5, only relative offset inside the PCIe BAR is passed */
	mem_win_base = MEMWIN_BASE;

	/*
	 * Set up memory window for accessing adapter memory ranges.  (Read
	 * back MA register to ensure that changes propagate before we attempt
	 * to use the new values.)
	 */
	csio_wr_reg32(hw, mem_win_base | BIR(0) |
			  WINDOW(ilog2(MEMWIN_APERTURE) - 10),
			  PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));
	csio_rd_reg32(hw,
		      PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));

	return 0;
}
Пример #2
0
static void
t4_dump_tcb(struct adapter *sc, int tid)
{
    uint32_t tcb_base, off, i, j;

    /* Dump TCB for the tid */
    tcb_base = t4_read_reg(sc, A_TP_CMM_TCB_BASE);
    t4_write_reg(sc, PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_OFFSET, 2),
                 tcb_base + tid * TCB_SIZE);
    t4_read_reg(sc, PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_OFFSET, 2));
    off = 0;
    printf("\n");
    for (i = 0; i < 4; i++) {
        uint32_t buf[8];
        for (j = 0; j < 8; j++, off += 4)
            buf[j] = htonl(t4_read_reg(sc, MEMWIN2_BASE + off));

        printf("%08x %08x %08x %08x %08x %08x %08x %08x\n",
               buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
               buf[7]);
    }
}
Пример #3
0
/*
 * csio_t5_memory_rw - read/write EDC 0, EDC 1 or MC via PCIE memory window
 * @hw: the csio_hw
 * @win: PCI-E memory Window to use
 * @mtype: memory type: MEM_EDC0, MEM_EDC1, MEM_MC0 (or MEM_MC) or MEM_MC1
 * @addr: address within indicated memory type
 * @len: amount of memory to transfer
 * @buf: host memory buffer
 * @dir: direction of transfer 1 => read, 0 => write
 *
 * Reads/writes an [almost] arbitrary memory region in the firmware: the
 * firmware memory address, length and host buffer must be aligned on
 * 32-bit boudaries.  The memory is transferred as a raw byte sequence
 * from/to the firmware's memory.  If this memory contains data
 * structures which contain multi-byte integers, it's the callers
 * responsibility to perform appropriate byte order conversions.
 */
static int
csio_t5_memory_rw(struct csio_hw *hw, u32 win, int mtype, u32 addr,
		u32 len, uint32_t *buf, int dir)
{
	u32 pos, start, offset, memoffset;
	u32 edc_size, mc_size, win_pf, mem_reg, mem_aperture, mem_base;

	/*
	 * Argument sanity checks ...
	 */
	if ((addr & 0x3) || (len & 0x3))
		return -EINVAL;

	/* Offset into the region of memory which is being accessed
	 * MEM_EDC0 = 0
	 * MEM_EDC1 = 1
	 * MEM_MC   = 2 -- T4
	 * MEM_MC0  = 2 -- For T5
	 * MEM_MC1  = 3 -- For T5
	 */
	edc_size  = EDRAM_SIZE_GET(csio_rd_reg32(hw, MA_EDRAM0_BAR));
	if (mtype != MEM_MC1)
		memoffset = (mtype * (edc_size * 1024 * 1024));
	else {
		mc_size = EXT_MEM_SIZE_GET(csio_rd_reg32(hw,
							 MA_EXT_MEMORY_BAR));
		memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024;
	}

	/* Determine the PCIE_MEM_ACCESS_OFFSET */
	addr = addr + memoffset;

	/*
	 * Each PCI-E Memory Window is programmed with a window size -- or
	 * "aperture" -- which controls the granularity of its mapping onto
	 * adapter memory.  We need to grab that aperture in order to know
	 * how to use the specified window.  The window is also programmed
	 * with the base address of the Memory Window in BAR0's address
	 * space.  For T4 this is an absolute PCI-E Bus Address.  For T5
	 * the address is relative to BAR0.
	 */
	mem_reg = csio_rd_reg32(hw,
			PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));
	mem_aperture = 1 << (WINDOW(mem_reg) + 10);
	mem_base = GET_PCIEOFST(mem_reg) << 10;

	start = addr & ~(mem_aperture-1);
	offset = addr - start;
	win_pf = V_PFNUM(hw->pfn);

	csio_dbg(hw, "csio_t5_memory_rw: mem_reg: 0x%x, mem_aperture: 0x%x\n",
		 mem_reg, mem_aperture);
	csio_dbg(hw, "csio_t5_memory_rw: mem_base: 0x%x, mem_offset: 0x%x\n",
		 mem_base, memoffset);
	csio_dbg(hw, "csio_t5_memory_rw: start:0x%x, offset:0x%x, win_pf:%d\n",
		 start, offset, win_pf);
	csio_dbg(hw, "csio_t5_memory_rw: mtype: %d, addr: 0x%x, len: %d\n",
		 mtype, addr, len);

	for (pos = start; len > 0; pos += mem_aperture, offset = 0) {
		/*
		 * Move PCI-E Memory Window to our current transfer
		 * position.  Read it back to ensure that changes propagate
		 * before we attempt to use the new value.
		 */
		csio_wr_reg32(hw, pos | win_pf,
			PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, win));
		csio_rd_reg32(hw,
			PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, win));

		while (offset < mem_aperture && len > 0) {
			if (dir)
				*buf++ = csio_rd_reg32(hw, mem_base + offset);
			else
				csio_wr_reg32(hw, *buf++, mem_base + offset);

			offset += sizeof(__be32);
			len -= sizeof(__be32);
		}
	}
	return 0;
}