csio_hw_t4.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /*
  2. * This file is part of the Chelsio FCoE driver for Linux.
  3. *
  4. * Copyright (c) 2008-2013 Chelsio Communications, Inc. All rights reserved.
  5. *
  6. * This software is available to you under a choice of one of two
  7. * licenses. You may choose to be licensed under the terms of the GNU
  8. * General Public License (GPL) Version 2, available from the file
  9. * OpenIB.org BSD license below:
  10. *
  11. * Redistribution and use in source and binary forms, with or
  12. * without modification, are permitted provided that the following
  13. * conditions are met:
  14. *
  15. * - Redistributions of source code must retain the above
  16. * copyright notice, this list of conditions and the following
  17. * - Redistributions in binary form must reproduce the above
  18. * copyright notice, this list of conditions and the following
  19. * disclaimer in the documentation and/or other materials
  20. * provided with the distribution.
  21. *
  22. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  26. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  27. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  28. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  29. * SOFTWARE.
  30. */
  31. #include "csio_hw.h"
  32. #include "csio_init.h"
  33. /*
  34. * Return the specified PCI-E Configuration Space register from our Physical
  35. * Function. We try first via a Firmware LDST Command since we prefer to let
  36. * the firmware own all of these registers, but if that fails we go for it
  37. * directly ourselves.
  38. */
  39. static uint32_t
  40. csio_t4_read_pcie_cfg4(struct csio_hw *hw, int reg)
  41. {
  42. u32 val = 0;
  43. struct csio_mb *mbp;
  44. int rv;
  45. struct fw_ldst_cmd *ldst_cmd;
  46. mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
  47. if (!mbp) {
  48. CSIO_INC_STATS(hw, n_err_nomem);
  49. pci_read_config_dword(hw->pdev, reg, &val);
  50. return val;
  51. }
  52. csio_mb_ldst(hw, mbp, CSIO_MB_DEFAULT_TMO, reg);
  53. rv = csio_mb_issue(hw, mbp);
  54. /*
  55. * If the LDST Command suucceeded, exctract the returned register
  56. * value. Otherwise read it directly ourself.
  57. */
  58. if (rv == 0) {
  59. ldst_cmd = (struct fw_ldst_cmd *)(mbp->mb);
  60. val = ntohl(ldst_cmd->u.pcie.data[0]);
  61. } else
  62. pci_read_config_dword(hw->pdev, reg, &val);
  63. mempool_free(mbp, hw->mb_mempool);
  64. return val;
  65. }
  66. static int
  67. csio_t4_set_mem_win(struct csio_hw *hw, uint32_t win)
  68. {
  69. u32 bar0;
  70. u32 mem_win_base;
  71. /*
  72. * Truncation intentional: we only read the bottom 32-bits of the
  73. * 64-bit BAR0/BAR1 ... We use the hardware backdoor mechanism to
  74. * read BAR0 instead of using pci_resource_start() because we could be
  75. * operating from within a Virtual Machine which is trapping our
  76. * accesses to our Configuration Space and we need to set up the PCI-E
  77. * Memory Window decoders with the actual addresses which will be
  78. * coming across the PCI-E link.
  79. */
  80. bar0 = csio_t4_read_pcie_cfg4(hw, PCI_BASE_ADDRESS_0);
  81. bar0 &= PCI_BASE_ADDRESS_MEM_MASK;
  82. mem_win_base = bar0 + MEMWIN_BASE;
  83. /*
  84. * Set up memory window for accessing adapter memory ranges. (Read
  85. * back MA register to ensure that changes propagate before we attempt
  86. * to use the new values.)
  87. */
  88. csio_wr_reg32(hw, mem_win_base | BIR(0) |
  89. WINDOW(ilog2(MEMWIN_APERTURE) - 10),
  90. PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));
  91. csio_rd_reg32(hw,
  92. PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));
  93. return 0;
  94. }
  95. /*
  96. * Interrupt handler for the PCIE module.
  97. */
  98. static void
  99. csio_t4_pcie_intr_handler(struct csio_hw *hw)
  100. {
  101. static struct intr_info sysbus_intr_info[] = {
  102. { RNPP, "RXNP array parity error", -1, 1 },
  103. { RPCP, "RXPC array parity error", -1, 1 },
  104. { RCIP, "RXCIF array parity error", -1, 1 },
  105. { RCCP, "Rx completions control array parity error", -1, 1 },
  106. { RFTP, "RXFT array parity error", -1, 1 },
  107. { 0, NULL, 0, 0 }
  108. };
  109. static struct intr_info pcie_port_intr_info[] = {
  110. { TPCP, "TXPC array parity error", -1, 1 },
  111. { TNPP, "TXNP array parity error", -1, 1 },
  112. { TFTP, "TXFT array parity error", -1, 1 },
  113. { TCAP, "TXCA array parity error", -1, 1 },
  114. { TCIP, "TXCIF array parity error", -1, 1 },
  115. { RCAP, "RXCA array parity error", -1, 1 },
  116. { OTDD, "outbound request TLP discarded", -1, 1 },
  117. { RDPE, "Rx data parity error", -1, 1 },
  118. { TDUE, "Tx uncorrectable data error", -1, 1 },
  119. { 0, NULL, 0, 0 }
  120. };
  121. static struct intr_info pcie_intr_info[] = {
  122. { MSIADDRLPERR, "MSI AddrL parity error", -1, 1 },
  123. { MSIADDRHPERR, "MSI AddrH parity error", -1, 1 },
  124. { MSIDATAPERR, "MSI data parity error", -1, 1 },
  125. { MSIXADDRLPERR, "MSI-X AddrL parity error", -1, 1 },
  126. { MSIXADDRHPERR, "MSI-X AddrH parity error", -1, 1 },
  127. { MSIXDATAPERR, "MSI-X data parity error", -1, 1 },
  128. { MSIXDIPERR, "MSI-X DI parity error", -1, 1 },
  129. { PIOCPLPERR, "PCI PIO completion FIFO parity error", -1, 1 },
  130. { PIOREQPERR, "PCI PIO request FIFO parity error", -1, 1 },
  131. { TARTAGPERR, "PCI PCI target tag FIFO parity error", -1, 1 },
  132. { CCNTPERR, "PCI CMD channel count parity error", -1, 1 },
  133. { CREQPERR, "PCI CMD channel request parity error", -1, 1 },
  134. { CRSPPERR, "PCI CMD channel response parity error", -1, 1 },
  135. { DCNTPERR, "PCI DMA channel count parity error", -1, 1 },
  136. { DREQPERR, "PCI DMA channel request parity error", -1, 1 },
  137. { DRSPPERR, "PCI DMA channel response parity error", -1, 1 },
  138. { HCNTPERR, "PCI HMA channel count parity error", -1, 1 },
  139. { HREQPERR, "PCI HMA channel request parity error", -1, 1 },
  140. { HRSPPERR, "PCI HMA channel response parity error", -1, 1 },
  141. { CFGSNPPERR, "PCI config snoop FIFO parity error", -1, 1 },
  142. { FIDPERR, "PCI FID parity error", -1, 1 },
  143. { INTXCLRPERR, "PCI INTx clear parity error", -1, 1 },
  144. { MATAGPERR, "PCI MA tag parity error", -1, 1 },
  145. { PIOTAGPERR, "PCI PIO tag parity error", -1, 1 },
  146. { RXCPLPERR, "PCI Rx completion parity error", -1, 1 },
  147. { RXWRPERR, "PCI Rx write parity error", -1, 1 },
  148. { RPLPERR, "PCI replay buffer parity error", -1, 1 },
  149. { PCIESINT, "PCI core secondary fault", -1, 1 },
  150. { PCIEPINT, "PCI core primary fault", -1, 1 },
  151. { UNXSPLCPLERR, "PCI unexpected split completion error", -1,
  152. 0 },
  153. { 0, NULL, 0, 0 }
  154. };
  155. int fat;
  156. fat = csio_handle_intr_status(hw,
  157. PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS,
  158. sysbus_intr_info) +
  159. csio_handle_intr_status(hw,
  160. PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS,
  161. pcie_port_intr_info) +
  162. csio_handle_intr_status(hw, PCIE_INT_CAUSE, pcie_intr_info);
  163. if (fat)
  164. csio_hw_fatal_err(hw);
  165. }
  166. /*
  167. * csio_t4_flash_cfg_addr - return the address of the flash configuration file
  168. * @hw: the HW module
  169. *
  170. * Return the address within the flash where the Firmware Configuration
  171. * File is stored.
  172. */
  173. static unsigned int
  174. csio_t4_flash_cfg_addr(struct csio_hw *hw)
  175. {
  176. return FLASH_CFG_OFFSET;
  177. }
  178. /*
  179. * csio_t4_mc_read - read from MC through backdoor accesses
  180. * @hw: the hw module
  181. * @idx: not used for T4 adapter
  182. * @addr: address of first byte requested
  183. * @data: 64 bytes of data containing the requested address
  184. * @ecc: where to store the corresponding 64-bit ECC word
  185. *
  186. * Read 64 bytes of data from MC starting at a 64-byte-aligned address
  187. * that covers the requested address @addr. If @parity is not %NULL it
  188. * is assigned the 64-bit ECC word for the read data.
  189. */
  190. static int
  191. csio_t4_mc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data,
  192. uint64_t *ecc)
  193. {
  194. int i;
  195. if (csio_rd_reg32(hw, MC_BIST_CMD) & START_BIST)
  196. return -EBUSY;
  197. csio_wr_reg32(hw, addr & ~0x3fU, MC_BIST_CMD_ADDR);
  198. csio_wr_reg32(hw, 64, MC_BIST_CMD_LEN);
  199. csio_wr_reg32(hw, 0xc, MC_BIST_DATA_PATTERN);
  200. csio_wr_reg32(hw, BIST_OPCODE(1) | START_BIST | BIST_CMD_GAP(1),
  201. MC_BIST_CMD);
  202. i = csio_hw_wait_op_done_val(hw, MC_BIST_CMD, START_BIST,
  203. 0, 10, 1, NULL);
  204. if (i)
  205. return i;
  206. #define MC_DATA(i) MC_BIST_STATUS_REG(MC_BIST_STATUS_RDATA, i)
  207. for (i = 15; i >= 0; i--)
  208. *data++ = htonl(csio_rd_reg32(hw, MC_DATA(i)));
  209. if (ecc)
  210. *ecc = csio_rd_reg64(hw, MC_DATA(16));
  211. #undef MC_DATA
  212. return 0;
  213. }
  214. /*
  215. * csio_t4_edc_read - read from EDC through backdoor accesses
  216. * @hw: the hw module
  217. * @idx: which EDC to access
  218. * @addr: address of first byte requested
  219. * @data: 64 bytes of data containing the requested address
  220. * @ecc: where to store the corresponding 64-bit ECC word
  221. *
  222. * Read 64 bytes of data from EDC starting at a 64-byte-aligned address
  223. * that covers the requested address @addr. If @parity is not %NULL it
  224. * is assigned the 64-bit ECC word for the read data.
  225. */
  226. static int
  227. csio_t4_edc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data,
  228. uint64_t *ecc)
  229. {
  230. int i;
  231. idx *= EDC_STRIDE;
  232. if (csio_rd_reg32(hw, EDC_BIST_CMD + idx) & START_BIST)
  233. return -EBUSY;
  234. csio_wr_reg32(hw, addr & ~0x3fU, EDC_BIST_CMD_ADDR + idx);
  235. csio_wr_reg32(hw, 64, EDC_BIST_CMD_LEN + idx);
  236. csio_wr_reg32(hw, 0xc, EDC_BIST_DATA_PATTERN + idx);
  237. csio_wr_reg32(hw, BIST_OPCODE(1) | BIST_CMD_GAP(1) | START_BIST,
  238. EDC_BIST_CMD + idx);
  239. i = csio_hw_wait_op_done_val(hw, EDC_BIST_CMD + idx, START_BIST,
  240. 0, 10, 1, NULL);
  241. if (i)
  242. return i;
  243. #define EDC_DATA(i) (EDC_BIST_STATUS_REG(EDC_BIST_STATUS_RDATA, i) + idx)
  244. for (i = 15; i >= 0; i--)
  245. *data++ = htonl(csio_rd_reg32(hw, EDC_DATA(i)));
  246. if (ecc)
  247. *ecc = csio_rd_reg64(hw, EDC_DATA(16));
  248. #undef EDC_DATA
  249. return 0;
  250. }
  251. /*
  252. * csio_t4_memory_rw - read/write EDC 0, EDC 1 or MC via PCIE memory window
  253. * @hw: the csio_hw
  254. * @win: PCI-E memory Window to use
  255. * @mtype: memory type: MEM_EDC0, MEM_EDC1, MEM_MC0 (or MEM_MC) or MEM_MC1
  256. * @addr: address within indicated memory type
  257. * @len: amount of memory to transfer
  258. * @buf: host memory buffer
  259. * @dir: direction of transfer 1 => read, 0 => write
  260. *
  261. * Reads/writes an [almost] arbitrary memory region in the firmware: the
  262. * firmware memory address, length and host buffer must be aligned on
  263. * 32-bit boudaries. The memory is transferred as a raw byte sequence
  264. * from/to the firmware's memory. If this memory contains data
  265. * structures which contain multi-byte integers, it's the callers
  266. * responsibility to perform appropriate byte order conversions.
  267. */
  268. static int
  269. csio_t4_memory_rw(struct csio_hw *hw, u32 win, int mtype, u32 addr,
  270. u32 len, uint32_t *buf, int dir)
  271. {
  272. u32 pos, start, offset, memoffset, bar0;
  273. u32 edc_size, mc_size, mem_reg, mem_aperture, mem_base;
  274. /*
  275. * Argument sanity checks ...
  276. */
  277. if ((addr & 0x3) || (len & 0x3))
  278. return -EINVAL;
  279. /* Offset into the region of memory which is being accessed
  280. * MEM_EDC0 = 0
  281. * MEM_EDC1 = 1
  282. * MEM_MC = 2 -- T4
  283. */
  284. edc_size = EDRAM_SIZE_GET(csio_rd_reg32(hw, MA_EDRAM0_BAR));
  285. if (mtype != MEM_MC1)
  286. memoffset = (mtype * (edc_size * 1024 * 1024));
  287. else {
  288. mc_size = EXT_MEM_SIZE_GET(csio_rd_reg32(hw,
  289. MA_EXT_MEMORY_BAR));
  290. memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024;
  291. }
  292. /* Determine the PCIE_MEM_ACCESS_OFFSET */
  293. addr = addr + memoffset;
  294. /*
  295. * Each PCI-E Memory Window is programmed with a window size -- or
  296. * "aperture" -- which controls the granularity of its mapping onto
  297. * adapter memory. We need to grab that aperture in order to know
  298. * how to use the specified window. The window is also programmed
  299. * with the base address of the Memory Window in BAR0's address
  300. * space. For T4 this is an absolute PCI-E Bus Address. For T5
  301. * the address is relative to BAR0.
  302. */
  303. mem_reg = csio_rd_reg32(hw,
  304. PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));
  305. mem_aperture = 1 << (WINDOW(mem_reg) + 10);
  306. mem_base = GET_PCIEOFST(mem_reg) << 10;
  307. bar0 = csio_t4_read_pcie_cfg4(hw, PCI_BASE_ADDRESS_0);
  308. bar0 &= PCI_BASE_ADDRESS_MEM_MASK;
  309. mem_base -= bar0;
  310. start = addr & ~(mem_aperture-1);
  311. offset = addr - start;
  312. csio_dbg(hw, "csio_t4_memory_rw: mem_reg: 0x%x, mem_aperture: 0x%x\n",
  313. mem_reg, mem_aperture);
  314. csio_dbg(hw, "csio_t4_memory_rw: mem_base: 0x%x, mem_offset: 0x%x\n",
  315. mem_base, memoffset);
  316. csio_dbg(hw, "csio_t4_memory_rw: bar0: 0x%x, start:0x%x, offset:0x%x\n",
  317. bar0, start, offset);
  318. csio_dbg(hw, "csio_t4_memory_rw: mtype: %d, addr: 0x%x, len: %d\n",
  319. mtype, addr, len);
  320. for (pos = start; len > 0; pos += mem_aperture, offset = 0) {
  321. /*
  322. * Move PCI-E Memory Window to our current transfer
  323. * position. Read it back to ensure that changes propagate
  324. * before we attempt to use the new value.
  325. */
  326. csio_wr_reg32(hw, pos,
  327. PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, win));
  328. csio_rd_reg32(hw,
  329. PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, win));
  330. while (offset < mem_aperture && len > 0) {
  331. if (dir)
  332. *buf++ = csio_rd_reg32(hw, mem_base + offset);
  333. else
  334. csio_wr_reg32(hw, *buf++, mem_base + offset);
  335. offset += sizeof(__be32);
  336. len -= sizeof(__be32);
  337. }
  338. }
  339. return 0;
  340. }
  341. /*
  342. * csio_t4_dfs_create_ext_mem - setup debugfs for MC to read the values
  343. * @hw: the csio_hw
  344. *
  345. * This function creates files in the debugfs with external memory region MC.
  346. */
  347. static void
  348. csio_t4_dfs_create_ext_mem(struct csio_hw *hw)
  349. {
  350. u32 size;
  351. int i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE);
  352. if (i & EXT_MEM_ENABLE) {
  353. size = csio_rd_reg32(hw, MA_EXT_MEMORY_BAR);
  354. csio_add_debugfs_mem(hw, "mc", MEM_MC,
  355. EXT_MEM_SIZE_GET(size));
  356. }
  357. }
  358. /* T4 adapter specific function */
  359. struct csio_hw_chip_ops t4_ops = {
  360. .chip_set_mem_win = csio_t4_set_mem_win,
  361. .chip_pcie_intr_handler = csio_t4_pcie_intr_handler,
  362. .chip_flash_cfg_addr = csio_t4_flash_cfg_addr,
  363. .chip_mc_read = csio_t4_mc_read,
  364. .chip_edc_read = csio_t4_edc_read,
  365. .chip_memory_rw = csio_t4_memory_rw,
  366. .chip_dfs_create_ext_mem = csio_t4_dfs_create_ext_mem,
  367. };