ntb_hw_gen3.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. /*
  2. * This file is provided under a dual BSD/GPLv2 license. When using or
  3. * redistributing this file, you may do so under either license.
  4. *
  5. * GPL LICENSE SUMMARY
  6. *
  7. * Copyright(c) 2017 Intel Corporation. All rights reserved.
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of version 2 of the GNU General Public License as
  11. * published by the Free Software Foundation.
  12. *
  13. * BSD LICENSE
  14. *
  15. * Copyright(c) 2017 Intel Corporation. All rights reserved.
  16. *
  17. * Redistribution and use in source and binary forms, with or without
  18. * modification, are permitted provided that the following conditions
  19. * are met:
  20. *
  21. * * Redistributions of source code must retain the above copyright
  22. * notice, this list of conditions and the following disclaimer.
  23. * * Redistributions in binary form must reproduce the above copy
  24. * notice, this list of conditions and the following disclaimer in
  25. * the documentation and/or other materials provided with the
  26. * distribution.
  27. * * Neither the name of Intel Corporation nor the names of its
  28. * contributors may be used to endorse or promote products derived
  29. * from this software without specific prior written permission.
  30. *
  31. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  34. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  36. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  37. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  38. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  39. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  40. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  41. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42. *
  43. * Intel PCIe GEN3 NTB Linux driver
  44. *
  45. */
  46. #include <linux/debugfs.h>
  47. #include <linux/delay.h>
  48. #include <linux/init.h>
  49. #include <linux/interrupt.h>
  50. #include <linux/module.h>
  51. #include <linux/pci.h>
  52. #include <linux/random.h>
  53. #include <linux/slab.h>
  54. #include <linux/ntb.h>
  55. #include "ntb_hw_intel.h"
  56. #include "ntb_hw_gen1.h"
  57. #include "ntb_hw_gen3.h"
  58. static int gen3_poll_link(struct intel_ntb_dev *ndev);
  59. static const struct intel_ntb_reg gen3_reg = {
  60. .poll_link = gen3_poll_link,
  61. .link_is_up = xeon_link_is_up,
  62. .db_ioread = gen3_db_ioread,
  63. .db_iowrite = gen3_db_iowrite,
  64. .db_size = sizeof(u32),
  65. .ntb_ctl = GEN3_NTBCNTL_OFFSET,
  66. .mw_bar = {2, 4},
  67. };
  68. static const struct intel_ntb_alt_reg gen3_pri_reg = {
  69. .db_bell = GEN3_EM_DOORBELL_OFFSET,
  70. .db_clear = GEN3_IM_INT_STATUS_OFFSET,
  71. .db_mask = GEN3_IM_INT_DISABLE_OFFSET,
  72. .spad = GEN3_IM_SPAD_OFFSET,
  73. };
  74. static const struct intel_ntb_alt_reg gen3_b2b_reg = {
  75. .db_bell = GEN3_IM_DOORBELL_OFFSET,
  76. .db_clear = GEN3_EM_INT_STATUS_OFFSET,
  77. .db_mask = GEN3_EM_INT_DISABLE_OFFSET,
  78. .spad = GEN3_B2B_SPAD_OFFSET,
  79. };
  80. static const struct intel_ntb_xlat_reg gen3_sec_xlat = {
  81. /* .bar0_base = GEN3_EMBAR0_OFFSET, */
  82. .bar2_limit = GEN3_IMBAR1XLMT_OFFSET,
  83. .bar2_xlat = GEN3_IMBAR1XBASE_OFFSET,
  84. };
  85. static int gen3_poll_link(struct intel_ntb_dev *ndev)
  86. {
  87. u16 reg_val;
  88. int rc;
  89. ndev->reg->db_iowrite(ndev->db_link_mask,
  90. ndev->self_mmio +
  91. ndev->self_reg->db_clear);
  92. rc = pci_read_config_word(ndev->ntb.pdev,
  93. GEN3_LINK_STATUS_OFFSET, &reg_val);
  94. if (rc)
  95. return 0;
  96. if (reg_val == ndev->lnk_sta)
  97. return 0;
  98. ndev->lnk_sta = reg_val;
  99. return 1;
  100. }
  101. static int gen3_init_isr(struct intel_ntb_dev *ndev)
  102. {
  103. int i;
  104. /*
  105. * The MSIX vectors and the interrupt status bits are not lined up
  106. * on Skylake. By default the link status bit is bit 32, however it
  107. * is by default MSIX vector0. We need to fixup to line them up.
  108. * The vectors at reset is 1-32,0. We need to reprogram to 0-32.
  109. */
  110. for (i = 0; i < GEN3_DB_MSIX_VECTOR_COUNT; i++)
  111. iowrite8(i, ndev->self_mmio + GEN3_INTVEC_OFFSET + i);
  112. /* move link status down one as workaround */
  113. if (ndev->hwerr_flags & NTB_HWERR_MSIX_VECTOR32_BAD) {
  114. iowrite8(GEN3_DB_MSIX_VECTOR_COUNT - 2,
  115. ndev->self_mmio + GEN3_INTVEC_OFFSET +
  116. (GEN3_DB_MSIX_VECTOR_COUNT - 1));
  117. }
  118. return ndev_init_isr(ndev, GEN3_DB_MSIX_VECTOR_COUNT,
  119. GEN3_DB_MSIX_VECTOR_COUNT,
  120. GEN3_DB_MSIX_VECTOR_SHIFT,
  121. GEN3_DB_TOTAL_SHIFT);
  122. }
  123. static int gen3_setup_b2b_mw(struct intel_ntb_dev *ndev,
  124. const struct intel_b2b_addr *addr,
  125. const struct intel_b2b_addr *peer_addr)
  126. {
  127. struct pci_dev *pdev;
  128. void __iomem *mmio;
  129. phys_addr_t bar_addr;
  130. pdev = ndev->ntb.pdev;
  131. mmio = ndev->self_mmio;
  132. /* setup incoming bar limits == base addrs (zero length windows) */
  133. bar_addr = addr->bar2_addr64;
  134. iowrite64(bar_addr, mmio + GEN3_IMBAR1XLMT_OFFSET);
  135. bar_addr = ioread64(mmio + GEN3_IMBAR1XLMT_OFFSET);
  136. dev_dbg(&pdev->dev, "IMBAR1XLMT %#018llx\n", bar_addr);
  137. bar_addr = addr->bar4_addr64;
  138. iowrite64(bar_addr, mmio + GEN3_IMBAR2XLMT_OFFSET);
  139. bar_addr = ioread64(mmio + GEN3_IMBAR2XLMT_OFFSET);
  140. dev_dbg(&pdev->dev, "IMBAR2XLMT %#018llx\n", bar_addr);
  141. /* zero incoming translation addrs */
  142. iowrite64(0, mmio + GEN3_IMBAR1XBASE_OFFSET);
  143. iowrite64(0, mmio + GEN3_IMBAR2XBASE_OFFSET);
  144. ndev->peer_mmio = ndev->self_mmio;
  145. return 0;
  146. }
  147. static int gen3_init_ntb(struct intel_ntb_dev *ndev)
  148. {
  149. int rc;
  150. ndev->mw_count = XEON_MW_COUNT;
  151. ndev->spad_count = GEN3_SPAD_COUNT;
  152. ndev->db_count = GEN3_DB_COUNT;
  153. ndev->db_link_mask = GEN3_DB_LINK_BIT;
  154. /* DB fixup for using 31 right now */
  155. if (ndev->hwerr_flags & NTB_HWERR_MSIX_VECTOR32_BAD)
  156. ndev->db_link_mask |= BIT_ULL(31);
  157. switch (ndev->ntb.topo) {
  158. case NTB_TOPO_B2B_USD:
  159. case NTB_TOPO_B2B_DSD:
  160. ndev->self_reg = &gen3_pri_reg;
  161. ndev->peer_reg = &gen3_b2b_reg;
  162. ndev->xlat_reg = &gen3_sec_xlat;
  163. if (ndev->ntb.topo == NTB_TOPO_B2B_USD) {
  164. rc = gen3_setup_b2b_mw(ndev,
  165. &xeon_b2b_dsd_addr,
  166. &xeon_b2b_usd_addr);
  167. } else {
  168. rc = gen3_setup_b2b_mw(ndev,
  169. &xeon_b2b_usd_addr,
  170. &xeon_b2b_dsd_addr);
  171. }
  172. if (rc)
  173. return rc;
  174. /* Enable Bus Master and Memory Space on the secondary side */
  175. iowrite16(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER,
  176. ndev->self_mmio + GEN3_SPCICMD_OFFSET);
  177. break;
  178. default:
  179. return -EINVAL;
  180. }
  181. ndev->db_valid_mask = BIT_ULL(ndev->db_count) - 1;
  182. /* Make sure we are not using DB's used for link status */
  183. if (ndev->hwerr_flags & NTB_HWERR_MSIX_VECTOR32_BAD)
  184. ndev->db_valid_mask &= ~ndev->db_link_mask;
  185. ndev->reg->db_iowrite(ndev->db_valid_mask,
  186. ndev->self_mmio +
  187. ndev->self_reg->db_mask);
  188. return 0;
  189. }
  190. int gen3_init_dev(struct intel_ntb_dev *ndev)
  191. {
  192. struct pci_dev *pdev;
  193. u8 ppd;
  194. int rc;
  195. pdev = ndev->ntb.pdev;
  196. ndev->reg = &gen3_reg;
  197. rc = pci_read_config_byte(pdev, XEON_PPD_OFFSET, &ppd);
  198. if (rc)
  199. return -EIO;
  200. ndev->ntb.topo = xeon_ppd_topo(ndev, ppd);
  201. dev_dbg(&pdev->dev, "ppd %#x topo %s\n", ppd,
  202. ntb_topo_string(ndev->ntb.topo));
  203. if (ndev->ntb.topo == NTB_TOPO_NONE)
  204. return -EINVAL;
  205. ndev->hwerr_flags |= NTB_HWERR_MSIX_VECTOR32_BAD;
  206. rc = gen3_init_ntb(ndev);
  207. if (rc)
  208. return rc;
  209. return gen3_init_isr(ndev);
  210. }
  211. ssize_t ndev_ntb3_debugfs_read(struct file *filp, char __user *ubuf,
  212. size_t count, loff_t *offp)
  213. {
  214. struct intel_ntb_dev *ndev;
  215. void __iomem *mmio;
  216. char *buf;
  217. size_t buf_size;
  218. ssize_t ret, off;
  219. union { u64 v64; u32 v32; u16 v16; } u;
  220. ndev = filp->private_data;
  221. mmio = ndev->self_mmio;
  222. buf_size = min(count, 0x800ul);
  223. buf = kmalloc(buf_size, GFP_KERNEL);
  224. if (!buf)
  225. return -ENOMEM;
  226. off = 0;
  227. off += scnprintf(buf + off, buf_size - off,
  228. "NTB Device Information:\n");
  229. off += scnprintf(buf + off, buf_size - off,
  230. "Connection Topology -\t%s\n",
  231. ntb_topo_string(ndev->ntb.topo));
  232. off += scnprintf(buf + off, buf_size - off,
  233. "NTB CTL -\t\t%#06x\n", ndev->ntb_ctl);
  234. off += scnprintf(buf + off, buf_size - off,
  235. "LNK STA -\t\t%#06x\n", ndev->lnk_sta);
  236. if (!ndev->reg->link_is_up(ndev))
  237. off += scnprintf(buf + off, buf_size - off,
  238. "Link Status -\t\tDown\n");
  239. else {
  240. off += scnprintf(buf + off, buf_size - off,
  241. "Link Status -\t\tUp\n");
  242. off += scnprintf(buf + off, buf_size - off,
  243. "Link Speed -\t\tPCI-E Gen %u\n",
  244. NTB_LNK_STA_SPEED(ndev->lnk_sta));
  245. off += scnprintf(buf + off, buf_size - off,
  246. "Link Width -\t\tx%u\n",
  247. NTB_LNK_STA_WIDTH(ndev->lnk_sta));
  248. }
  249. off += scnprintf(buf + off, buf_size - off,
  250. "Memory Window Count -\t%u\n", ndev->mw_count);
  251. off += scnprintf(buf + off, buf_size - off,
  252. "Scratchpad Count -\t%u\n", ndev->spad_count);
  253. off += scnprintf(buf + off, buf_size - off,
  254. "Doorbell Count -\t%u\n", ndev->db_count);
  255. off += scnprintf(buf + off, buf_size - off,
  256. "Doorbell Vector Count -\t%u\n", ndev->db_vec_count);
  257. off += scnprintf(buf + off, buf_size - off,
  258. "Doorbell Vector Shift -\t%u\n", ndev->db_vec_shift);
  259. off += scnprintf(buf + off, buf_size - off,
  260. "Doorbell Valid Mask -\t%#llx\n", ndev->db_valid_mask);
  261. off += scnprintf(buf + off, buf_size - off,
  262. "Doorbell Link Mask -\t%#llx\n", ndev->db_link_mask);
  263. off += scnprintf(buf + off, buf_size - off,
  264. "Doorbell Mask Cached -\t%#llx\n", ndev->db_mask);
  265. u.v64 = ndev_db_read(ndev, mmio + ndev->self_reg->db_mask);
  266. off += scnprintf(buf + off, buf_size - off,
  267. "Doorbell Mask -\t\t%#llx\n", u.v64);
  268. u.v64 = ndev_db_read(ndev, mmio + ndev->self_reg->db_bell);
  269. off += scnprintf(buf + off, buf_size - off,
  270. "Doorbell Bell -\t\t%#llx\n", u.v64);
  271. off += scnprintf(buf + off, buf_size - off,
  272. "\nNTB Incoming XLAT:\n");
  273. u.v64 = ioread64(mmio + GEN3_IMBAR1XBASE_OFFSET);
  274. off += scnprintf(buf + off, buf_size - off,
  275. "IMBAR1XBASE -\t\t%#018llx\n", u.v64);
  276. u.v64 = ioread64(mmio + GEN3_IMBAR2XBASE_OFFSET);
  277. off += scnprintf(buf + off, buf_size - off,
  278. "IMBAR2XBASE -\t\t%#018llx\n", u.v64);
  279. u.v64 = ioread64(mmio + GEN3_IMBAR1XLMT_OFFSET);
  280. off += scnprintf(buf + off, buf_size - off,
  281. "IMBAR1XLMT -\t\t\t%#018llx\n", u.v64);
  282. u.v64 = ioread64(mmio + GEN3_IMBAR2XLMT_OFFSET);
  283. off += scnprintf(buf + off, buf_size - off,
  284. "IMBAR2XLMT -\t\t\t%#018llx\n", u.v64);
  285. if (ntb_topo_is_b2b(ndev->ntb.topo)) {
  286. off += scnprintf(buf + off, buf_size - off,
  287. "\nNTB Outgoing B2B XLAT:\n");
  288. u.v64 = ioread64(mmio + GEN3_EMBAR1XBASE_OFFSET);
  289. off += scnprintf(buf + off, buf_size - off,
  290. "EMBAR1XBASE -\t\t%#018llx\n", u.v64);
  291. u.v64 = ioread64(mmio + GEN3_EMBAR2XBASE_OFFSET);
  292. off += scnprintf(buf + off, buf_size - off,
  293. "EMBAR2XBASE -\t\t%#018llx\n", u.v64);
  294. u.v64 = ioread64(mmio + GEN3_EMBAR1XLMT_OFFSET);
  295. off += scnprintf(buf + off, buf_size - off,
  296. "EMBAR1XLMT -\t\t%#018llx\n", u.v64);
  297. u.v64 = ioread64(mmio + GEN3_EMBAR2XLMT_OFFSET);
  298. off += scnprintf(buf + off, buf_size - off,
  299. "EMBAR2XLMT -\t\t%#018llx\n", u.v64);
  300. off += scnprintf(buf + off, buf_size - off,
  301. "\nNTB Secondary BAR:\n");
  302. u.v64 = ioread64(mmio + GEN3_EMBAR0_OFFSET);
  303. off += scnprintf(buf + off, buf_size - off,
  304. "EMBAR0 -\t\t%#018llx\n", u.v64);
  305. u.v64 = ioread64(mmio + GEN3_EMBAR1_OFFSET);
  306. off += scnprintf(buf + off, buf_size - off,
  307. "EMBAR1 -\t\t%#018llx\n", u.v64);
  308. u.v64 = ioread64(mmio + GEN3_EMBAR2_OFFSET);
  309. off += scnprintf(buf + off, buf_size - off,
  310. "EMBAR2 -\t\t%#018llx\n", u.v64);
  311. }
  312. off += scnprintf(buf + off, buf_size - off,
  313. "\nNTB Statistics:\n");
  314. u.v16 = ioread16(mmio + GEN3_USMEMMISS_OFFSET);
  315. off += scnprintf(buf + off, buf_size - off,
  316. "Upstream Memory Miss -\t%u\n", u.v16);
  317. off += scnprintf(buf + off, buf_size - off,
  318. "\nNTB Hardware Errors:\n");
  319. if (!pci_read_config_word(ndev->ntb.pdev,
  320. GEN3_DEVSTS_OFFSET, &u.v16))
  321. off += scnprintf(buf + off, buf_size - off,
  322. "DEVSTS -\t\t%#06x\n", u.v16);
  323. if (!pci_read_config_word(ndev->ntb.pdev,
  324. GEN3_LINK_STATUS_OFFSET, &u.v16))
  325. off += scnprintf(buf + off, buf_size - off,
  326. "LNKSTS -\t\t%#06x\n", u.v16);
  327. if (!pci_read_config_dword(ndev->ntb.pdev,
  328. GEN3_UNCERRSTS_OFFSET, &u.v32))
  329. off += scnprintf(buf + off, buf_size - off,
  330. "UNCERRSTS -\t\t%#06x\n", u.v32);
  331. if (!pci_read_config_dword(ndev->ntb.pdev,
  332. GEN3_CORERRSTS_OFFSET, &u.v32))
  333. off += scnprintf(buf + off, buf_size - off,
  334. "CORERRSTS -\t\t%#06x\n", u.v32);
  335. ret = simple_read_from_buffer(ubuf, count, offp, buf, off);
  336. kfree(buf);
  337. return ret;
  338. }
  339. int intel_ntb3_link_enable(struct ntb_dev *ntb, enum ntb_speed max_speed,
  340. enum ntb_width max_width)
  341. {
  342. struct intel_ntb_dev *ndev;
  343. u32 ntb_ctl;
  344. ndev = container_of(ntb, struct intel_ntb_dev, ntb);
  345. dev_dbg(&ntb->pdev->dev,
  346. "Enabling link with max_speed %d max_width %d\n",
  347. max_speed, max_width);
  348. if (max_speed != NTB_SPEED_AUTO)
  349. dev_dbg(&ntb->pdev->dev, "ignoring max_speed %d\n", max_speed);
  350. if (max_width != NTB_WIDTH_AUTO)
  351. dev_dbg(&ntb->pdev->dev, "ignoring max_width %d\n", max_width);
  352. ntb_ctl = ioread32(ndev->self_mmio + ndev->reg->ntb_ctl);
  353. ntb_ctl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
  354. ntb_ctl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
  355. ntb_ctl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
  356. iowrite32(ntb_ctl, ndev->self_mmio + ndev->reg->ntb_ctl);
  357. return 0;
  358. }
  359. static int intel_ntb3_mw_set_trans(struct ntb_dev *ntb, int pidx, int idx,
  360. dma_addr_t addr, resource_size_t size)
  361. {
  362. struct intel_ntb_dev *ndev = ntb_ndev(ntb);
  363. unsigned long xlat_reg, limit_reg;
  364. resource_size_t bar_size, mw_size;
  365. void __iomem *mmio;
  366. u64 base, limit, reg_val;
  367. int bar;
  368. if (pidx != NTB_DEF_PEER_IDX)
  369. return -EINVAL;
  370. if (idx >= ndev->b2b_idx && !ndev->b2b_off)
  371. idx += 1;
  372. bar = ndev_mw_to_bar(ndev, idx);
  373. if (bar < 0)
  374. return bar;
  375. bar_size = pci_resource_len(ndev->ntb.pdev, bar);
  376. if (idx == ndev->b2b_idx)
  377. mw_size = bar_size - ndev->b2b_off;
  378. else
  379. mw_size = bar_size;
  380. /* hardware requires that addr is aligned to bar size */
  381. if (addr & (bar_size - 1))
  382. return -EINVAL;
  383. /* make sure the range fits in the usable mw size */
  384. if (size > mw_size)
  385. return -EINVAL;
  386. mmio = ndev->self_mmio;
  387. xlat_reg = ndev->xlat_reg->bar2_xlat + (idx * 0x10);
  388. limit_reg = ndev->xlat_reg->bar2_limit + (idx * 0x10);
  389. base = pci_resource_start(ndev->ntb.pdev, bar);
  390. /* Set the limit if supported, if size is not mw_size */
  391. if (limit_reg && size != mw_size)
  392. limit = base + size;
  393. else
  394. limit = base + mw_size;
  395. /* set and verify setting the translation address */
  396. iowrite64(addr, mmio + xlat_reg);
  397. reg_val = ioread64(mmio + xlat_reg);
  398. if (reg_val != addr) {
  399. iowrite64(0, mmio + xlat_reg);
  400. return -EIO;
  401. }
  402. dev_dbg(&ntb->pdev->dev, "BAR %d IMBARXBASE: %#Lx\n", bar, reg_val);
  403. /* set and verify setting the limit */
  404. iowrite64(limit, mmio + limit_reg);
  405. reg_val = ioread64(mmio + limit_reg);
  406. if (reg_val != limit) {
  407. iowrite64(base, mmio + limit_reg);
  408. iowrite64(0, mmio + xlat_reg);
  409. return -EIO;
  410. }
  411. dev_dbg(&ntb->pdev->dev, "BAR %d IMBARXLMT: %#Lx\n", bar, reg_val);
  412. /* setup the EP */
  413. limit_reg = ndev->xlat_reg->bar2_limit + (idx * 0x10) + 0x4000;
  414. base = ioread64(mmio + GEN3_EMBAR1_OFFSET + (8 * idx));
  415. base &= ~0xf;
  416. if (limit_reg && size != mw_size)
  417. limit = base + size;
  418. else
  419. limit = base + mw_size;
  420. /* set and verify setting the limit */
  421. iowrite64(limit, mmio + limit_reg);
  422. reg_val = ioread64(mmio + limit_reg);
  423. if (reg_val != limit) {
  424. iowrite64(base, mmio + limit_reg);
  425. iowrite64(0, mmio + xlat_reg);
  426. return -EIO;
  427. }
  428. dev_dbg(&ntb->pdev->dev, "BAR %d EMBARXLMT: %#Lx\n", bar, reg_val);
  429. return 0;
  430. }
  431. int intel_ntb3_peer_db_addr(struct ntb_dev *ntb, phys_addr_t *db_addr,
  432. resource_size_t *db_size,
  433. u64 *db_data, int db_bit)
  434. {
  435. phys_addr_t db_addr_base;
  436. struct intel_ntb_dev *ndev = ntb_ndev(ntb);
  437. if (unlikely(db_bit >= BITS_PER_LONG_LONG))
  438. return -EINVAL;
  439. if (unlikely(BIT_ULL(db_bit) & ~ntb_ndev(ntb)->db_valid_mask))
  440. return -EINVAL;
  441. ndev_db_addr(ndev, &db_addr_base, db_size, ndev->peer_addr,
  442. ndev->peer_reg->db_bell);
  443. if (db_addr) {
  444. *db_addr = db_addr_base + (db_bit * 4);
  445. dev_dbg(&ndev->ntb.pdev->dev, "Peer db addr %llx db bit %d\n",
  446. *db_addr, db_bit);
  447. }
  448. if (db_data) {
  449. *db_data = 1;
  450. dev_dbg(&ndev->ntb.pdev->dev, "Peer db data %llx db bit %d\n",
  451. *db_data, db_bit);
  452. }
  453. return 0;
  454. }
  455. int intel_ntb3_peer_db_set(struct ntb_dev *ntb, u64 db_bits)
  456. {
  457. struct intel_ntb_dev *ndev = ntb_ndev(ntb);
  458. int bit;
  459. if (db_bits & ~ndev->db_valid_mask)
  460. return -EINVAL;
  461. while (db_bits) {
  462. bit = __ffs(db_bits);
  463. iowrite32(1, ndev->peer_mmio +
  464. ndev->peer_reg->db_bell + (bit * 4));
  465. db_bits &= db_bits - 1;
  466. }
  467. return 0;
  468. }
  469. u64 intel_ntb3_db_read(struct ntb_dev *ntb)
  470. {
  471. struct intel_ntb_dev *ndev = ntb_ndev(ntb);
  472. return ndev_db_read(ndev,
  473. ndev->self_mmio +
  474. ndev->self_reg->db_clear);
  475. }
  476. int intel_ntb3_db_clear(struct ntb_dev *ntb, u64 db_bits)
  477. {
  478. struct intel_ntb_dev *ndev = ntb_ndev(ntb);
  479. return ndev_db_write(ndev, db_bits,
  480. ndev->self_mmio +
  481. ndev->self_reg->db_clear);
  482. }
  483. const struct ntb_dev_ops intel_ntb3_ops = {
  484. .mw_count = intel_ntb_mw_count,
  485. .mw_get_align = intel_ntb_mw_get_align,
  486. .mw_set_trans = intel_ntb3_mw_set_trans,
  487. .peer_mw_count = intel_ntb_peer_mw_count,
  488. .peer_mw_get_addr = intel_ntb_peer_mw_get_addr,
  489. .link_is_up = intel_ntb_link_is_up,
  490. .link_enable = intel_ntb3_link_enable,
  491. .link_disable = intel_ntb_link_disable,
  492. .db_valid_mask = intel_ntb_db_valid_mask,
  493. .db_vector_count = intel_ntb_db_vector_count,
  494. .db_vector_mask = intel_ntb_db_vector_mask,
  495. .db_read = intel_ntb3_db_read,
  496. .db_clear = intel_ntb3_db_clear,
  497. .db_set_mask = intel_ntb_db_set_mask,
  498. .db_clear_mask = intel_ntb_db_clear_mask,
  499. .peer_db_addr = intel_ntb3_peer_db_addr,
  500. .peer_db_set = intel_ntb3_peer_db_set,
  501. .spad_is_unsafe = intel_ntb_spad_is_unsafe,
  502. .spad_count = intel_ntb_spad_count,
  503. .spad_read = intel_ntb_spad_read,
  504. .spad_write = intel_ntb_spad_write,
  505. .peer_spad_addr = intel_ntb_peer_spad_addr,
  506. .peer_spad_read = intel_ntb_peer_spad_read,
  507. .peer_spad_write = intel_ntb_peer_spad_write,
  508. };