config.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. // SPDX-License-Identifier: GPL-2.0+
  2. // Copyright 2017 IBM Corp.
  3. #include <linux/pci.h>
  4. #include <asm/pnv-ocxl.h>
  5. #include <misc/ocxl.h>
  6. #include <misc/ocxl-config.h>
  7. #define EXTRACT_BIT(val, bit) (!!(val & BIT(bit)))
  8. #define EXTRACT_BITS(val, s, e) ((val & GENMASK(e, s)) >> s)
  9. #define OCXL_DVSEC_AFU_IDX_MASK GENMASK(5, 0)
  10. #define OCXL_DVSEC_ACTAG_MASK GENMASK(11, 0)
  11. #define OCXL_DVSEC_PASID_MASK GENMASK(19, 0)
  12. #define OCXL_DVSEC_PASID_LOG_MASK GENMASK(4, 0)
  13. #define OCXL_DVSEC_TEMPL_VERSION 0x0
  14. #define OCXL_DVSEC_TEMPL_NAME 0x4
  15. #define OCXL_DVSEC_TEMPL_AFU_VERSION 0x1C
  16. #define OCXL_DVSEC_TEMPL_MMIO_GLOBAL 0x20
  17. #define OCXL_DVSEC_TEMPL_MMIO_GLOBAL_SZ 0x28
  18. #define OCXL_DVSEC_TEMPL_MMIO_PP 0x30
  19. #define OCXL_DVSEC_TEMPL_MMIO_PP_SZ 0x38
  20. #define OCXL_DVSEC_TEMPL_MEM_SZ 0x3C
  21. #define OCXL_DVSEC_TEMPL_WWID 0x40
  22. #define OCXL_MAX_AFU_PER_FUNCTION 64
  23. #define OCXL_TEMPL_LEN 0x58
  24. #define OCXL_TEMPL_NAME_LEN 24
  25. #define OCXL_CFG_TIMEOUT 3
  26. static int find_dvsec(struct pci_dev *dev, int dvsec_id)
  27. {
  28. int vsec = 0;
  29. u16 vendor, id;
  30. while ((vsec = pci_find_next_ext_capability(dev, vsec,
  31. OCXL_EXT_CAP_ID_DVSEC))) {
  32. pci_read_config_word(dev, vsec + OCXL_DVSEC_VENDOR_OFFSET,
  33. &vendor);
  34. pci_read_config_word(dev, vsec + OCXL_DVSEC_ID_OFFSET, &id);
  35. if (vendor == PCI_VENDOR_ID_IBM && id == dvsec_id)
  36. return vsec;
  37. }
  38. return 0;
  39. }
  40. static int find_dvsec_afu_ctrl(struct pci_dev *dev, u8 afu_idx)
  41. {
  42. int vsec = 0;
  43. u16 vendor, id;
  44. u8 idx;
  45. while ((vsec = pci_find_next_ext_capability(dev, vsec,
  46. OCXL_EXT_CAP_ID_DVSEC))) {
  47. pci_read_config_word(dev, vsec + OCXL_DVSEC_VENDOR_OFFSET,
  48. &vendor);
  49. pci_read_config_word(dev, vsec + OCXL_DVSEC_ID_OFFSET, &id);
  50. if (vendor == PCI_VENDOR_ID_IBM &&
  51. id == OCXL_DVSEC_AFU_CTRL_ID) {
  52. pci_read_config_byte(dev,
  53. vsec + OCXL_DVSEC_AFU_CTRL_AFU_IDX,
  54. &idx);
  55. if (idx == afu_idx)
  56. return vsec;
  57. }
  58. }
  59. return 0;
  60. }
  61. static int read_pasid(struct pci_dev *dev, struct ocxl_fn_config *fn)
  62. {
  63. u16 val;
  64. int pos;
  65. pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PASID);
  66. if (!pos) {
  67. /*
  68. * PASID capability is not mandatory, but there
  69. * shouldn't be any AFU
  70. */
  71. dev_dbg(&dev->dev, "Function doesn't require any PASID\n");
  72. fn->max_pasid_log = -1;
  73. goto out;
  74. }
  75. pci_read_config_word(dev, pos + PCI_PASID_CAP, &val);
  76. fn->max_pasid_log = EXTRACT_BITS(val, 8, 12);
  77. out:
  78. dev_dbg(&dev->dev, "PASID capability:\n");
  79. dev_dbg(&dev->dev, " Max PASID log = %d\n", fn->max_pasid_log);
  80. return 0;
  81. }
  82. static int read_dvsec_tl(struct pci_dev *dev, struct ocxl_fn_config *fn)
  83. {
  84. int pos;
  85. pos = find_dvsec(dev, OCXL_DVSEC_TL_ID);
  86. if (!pos && PCI_FUNC(dev->devfn) == 0) {
  87. dev_err(&dev->dev, "Can't find TL DVSEC\n");
  88. return -ENODEV;
  89. }
  90. if (pos && PCI_FUNC(dev->devfn) != 0) {
  91. dev_err(&dev->dev, "TL DVSEC is only allowed on function 0\n");
  92. return -ENODEV;
  93. }
  94. fn->dvsec_tl_pos = pos;
  95. return 0;
  96. }
  97. static int read_dvsec_function(struct pci_dev *dev, struct ocxl_fn_config *fn)
  98. {
  99. int pos, afu_present;
  100. u32 val;
  101. pos = find_dvsec(dev, OCXL_DVSEC_FUNC_ID);
  102. if (!pos) {
  103. dev_err(&dev->dev, "Can't find function DVSEC\n");
  104. return -ENODEV;
  105. }
  106. fn->dvsec_function_pos = pos;
  107. pci_read_config_dword(dev, pos + OCXL_DVSEC_FUNC_OFF_INDEX, &val);
  108. afu_present = EXTRACT_BIT(val, 31);
  109. if (!afu_present) {
  110. fn->max_afu_index = -1;
  111. dev_dbg(&dev->dev, "Function doesn't define any AFU\n");
  112. goto out;
  113. }
  114. fn->max_afu_index = EXTRACT_BITS(val, 24, 29);
  115. out:
  116. dev_dbg(&dev->dev, "Function DVSEC:\n");
  117. dev_dbg(&dev->dev, " Max AFU index = %d\n", fn->max_afu_index);
  118. return 0;
  119. }
  120. static int read_dvsec_afu_info(struct pci_dev *dev, struct ocxl_fn_config *fn)
  121. {
  122. int pos;
  123. if (fn->max_afu_index < 0) {
  124. fn->dvsec_afu_info_pos = -1;
  125. return 0;
  126. }
  127. pos = find_dvsec(dev, OCXL_DVSEC_AFU_INFO_ID);
  128. if (!pos) {
  129. dev_err(&dev->dev, "Can't find AFU information DVSEC\n");
  130. return -ENODEV;
  131. }
  132. fn->dvsec_afu_info_pos = pos;
  133. return 0;
  134. }
  135. static int read_dvsec_vendor(struct pci_dev *dev)
  136. {
  137. int pos;
  138. u32 cfg, tlx, dlx;
  139. /*
  140. * vendor specific DVSEC is optional
  141. *
  142. * It's currently only used on function 0 to specify the
  143. * version of some logic blocks. Some older images may not
  144. * even have it so we ignore any errors
  145. */
  146. if (PCI_FUNC(dev->devfn) != 0)
  147. return 0;
  148. pos = find_dvsec(dev, OCXL_DVSEC_VENDOR_ID);
  149. if (!pos)
  150. return 0;
  151. pci_read_config_dword(dev, pos + OCXL_DVSEC_VENDOR_CFG_VERS, &cfg);
  152. pci_read_config_dword(dev, pos + OCXL_DVSEC_VENDOR_TLX_VERS, &tlx);
  153. pci_read_config_dword(dev, pos + OCXL_DVSEC_VENDOR_DLX_VERS, &dlx);
  154. dev_dbg(&dev->dev, "Vendor specific DVSEC:\n");
  155. dev_dbg(&dev->dev, " CFG version = 0x%x\n", cfg);
  156. dev_dbg(&dev->dev, " TLX version = 0x%x\n", tlx);
  157. dev_dbg(&dev->dev, " DLX version = 0x%x\n", dlx);
  158. return 0;
  159. }
  160. static int validate_function(struct pci_dev *dev, struct ocxl_fn_config *fn)
  161. {
  162. if (fn->max_pasid_log == -1 && fn->max_afu_index >= 0) {
  163. dev_err(&dev->dev,
  164. "AFUs are defined but no PASIDs are requested\n");
  165. return -EINVAL;
  166. }
  167. if (fn->max_afu_index > OCXL_MAX_AFU_PER_FUNCTION) {
  168. dev_err(&dev->dev,
  169. "Max AFU index out of architectural limit (%d vs %d)\n",
  170. fn->max_afu_index, OCXL_MAX_AFU_PER_FUNCTION);
  171. return -EINVAL;
  172. }
  173. return 0;
  174. }
  175. int ocxl_config_read_function(struct pci_dev *dev, struct ocxl_fn_config *fn)
  176. {
  177. int rc;
  178. rc = read_pasid(dev, fn);
  179. if (rc) {
  180. dev_err(&dev->dev, "Invalid PASID configuration: %d\n", rc);
  181. return -ENODEV;
  182. }
  183. rc = read_dvsec_tl(dev, fn);
  184. if (rc) {
  185. dev_err(&dev->dev,
  186. "Invalid Transaction Layer DVSEC configuration: %d\n",
  187. rc);
  188. return -ENODEV;
  189. }
  190. rc = read_dvsec_function(dev, fn);
  191. if (rc) {
  192. dev_err(&dev->dev,
  193. "Invalid Function DVSEC configuration: %d\n", rc);
  194. return -ENODEV;
  195. }
  196. rc = read_dvsec_afu_info(dev, fn);
  197. if (rc) {
  198. dev_err(&dev->dev, "Invalid AFU configuration: %d\n", rc);
  199. return -ENODEV;
  200. }
  201. rc = read_dvsec_vendor(dev);
  202. if (rc) {
  203. dev_err(&dev->dev,
  204. "Invalid vendor specific DVSEC configuration: %d\n",
  205. rc);
  206. return -ENODEV;
  207. }
  208. rc = validate_function(dev, fn);
  209. return rc;
  210. }
  211. EXPORT_SYMBOL_GPL(ocxl_config_read_function);
  212. static int read_afu_info(struct pci_dev *dev, struct ocxl_fn_config *fn,
  213. int offset, u32 *data)
  214. {
  215. u32 val;
  216. unsigned long timeout = jiffies + (HZ * OCXL_CFG_TIMEOUT);
  217. int pos = fn->dvsec_afu_info_pos;
  218. /* Protect 'data valid' bit */
  219. if (EXTRACT_BIT(offset, 31)) {
  220. dev_err(&dev->dev, "Invalid offset in AFU info DVSEC\n");
  221. return -EINVAL;
  222. }
  223. pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_INFO_OFF, offset);
  224. pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_INFO_OFF, &val);
  225. while (!EXTRACT_BIT(val, 31)) {
  226. if (time_after_eq(jiffies, timeout)) {
  227. dev_err(&dev->dev,
  228. "Timeout while reading AFU info DVSEC (offset=%d)\n",
  229. offset);
  230. return -EBUSY;
  231. }
  232. cpu_relax();
  233. pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_INFO_OFF, &val);
  234. }
  235. pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_INFO_DATA, data);
  236. return 0;
  237. }
  238. int ocxl_config_check_afu_index(struct pci_dev *dev,
  239. struct ocxl_fn_config *fn, int afu_idx)
  240. {
  241. u32 val;
  242. int rc, templ_major, templ_minor, len;
  243. pci_write_config_word(dev, fn->dvsec_afu_info_pos, afu_idx);
  244. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_VERSION, &val);
  245. if (rc)
  246. return rc;
  247. /* AFU index map can have holes */
  248. if (!val)
  249. return 0;
  250. templ_major = EXTRACT_BITS(val, 8, 15);
  251. templ_minor = EXTRACT_BITS(val, 0, 7);
  252. dev_dbg(&dev->dev, "AFU descriptor template version %d.%d\n",
  253. templ_major, templ_minor);
  254. len = EXTRACT_BITS(val, 16, 31);
  255. if (len != OCXL_TEMPL_LEN) {
  256. dev_warn(&dev->dev,
  257. "Unexpected template length in AFU information (%#x)\n",
  258. len);
  259. }
  260. return 1;
  261. }
  262. EXPORT_SYMBOL_GPL(ocxl_config_check_afu_index);
  263. static int read_afu_name(struct pci_dev *dev, struct ocxl_fn_config *fn,
  264. struct ocxl_afu_config *afu)
  265. {
  266. int i, rc;
  267. u32 val, *ptr;
  268. BUILD_BUG_ON(OCXL_AFU_NAME_SZ < OCXL_TEMPL_NAME_LEN);
  269. for (i = 0; i < OCXL_TEMPL_NAME_LEN; i += 4) {
  270. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_NAME + i, &val);
  271. if (rc)
  272. return rc;
  273. ptr = (u32 *) &afu->name[i];
  274. *ptr = val;
  275. }
  276. afu->name[OCXL_AFU_NAME_SZ - 1] = '\0'; /* play safe */
  277. return 0;
  278. }
  279. static int read_afu_mmio(struct pci_dev *dev, struct ocxl_fn_config *fn,
  280. struct ocxl_afu_config *afu)
  281. {
  282. int rc;
  283. u32 val;
  284. /*
  285. * Global MMIO
  286. */
  287. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_GLOBAL, &val);
  288. if (rc)
  289. return rc;
  290. afu->global_mmio_bar = EXTRACT_BITS(val, 0, 2);
  291. afu->global_mmio_offset = EXTRACT_BITS(val, 16, 31) << 16;
  292. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_GLOBAL + 4, &val);
  293. if (rc)
  294. return rc;
  295. afu->global_mmio_offset += (u64) val << 32;
  296. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_GLOBAL_SZ, &val);
  297. if (rc)
  298. return rc;
  299. afu->global_mmio_size = val;
  300. /*
  301. * Per-process MMIO
  302. */
  303. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_PP, &val);
  304. if (rc)
  305. return rc;
  306. afu->pp_mmio_bar = EXTRACT_BITS(val, 0, 2);
  307. afu->pp_mmio_offset = EXTRACT_BITS(val, 16, 31) << 16;
  308. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_PP + 4, &val);
  309. if (rc)
  310. return rc;
  311. afu->pp_mmio_offset += (u64) val << 32;
  312. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_PP_SZ, &val);
  313. if (rc)
  314. return rc;
  315. afu->pp_mmio_stride = val;
  316. return 0;
  317. }
  318. static int read_afu_control(struct pci_dev *dev, struct ocxl_afu_config *afu)
  319. {
  320. int pos;
  321. u8 val8;
  322. u16 val16;
  323. pos = find_dvsec_afu_ctrl(dev, afu->idx);
  324. if (!pos) {
  325. dev_err(&dev->dev, "Can't find AFU control DVSEC for AFU %d\n",
  326. afu->idx);
  327. return -ENODEV;
  328. }
  329. afu->dvsec_afu_control_pos = pos;
  330. pci_read_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_SUP, &val8);
  331. afu->pasid_supported_log = EXTRACT_BITS(val8, 0, 4);
  332. pci_read_config_word(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_SUP, &val16);
  333. afu->actag_supported = EXTRACT_BITS(val16, 0, 11);
  334. return 0;
  335. }
  336. static bool char_allowed(int c)
  337. {
  338. /*
  339. * Permitted Characters : Alphanumeric, hyphen, underscore, comma
  340. */
  341. if ((c >= 0x30 && c <= 0x39) /* digits */ ||
  342. (c >= 0x41 && c <= 0x5A) /* upper case */ ||
  343. (c >= 0x61 && c <= 0x7A) /* lower case */ ||
  344. c == 0 /* NULL */ ||
  345. c == 0x2D /* - */ ||
  346. c == 0x5F /* _ */ ||
  347. c == 0x2C /* , */)
  348. return true;
  349. return false;
  350. }
  351. static int validate_afu(struct pci_dev *dev, struct ocxl_afu_config *afu)
  352. {
  353. int i;
  354. if (!afu->name[0]) {
  355. dev_err(&dev->dev, "Empty AFU name\n");
  356. return -EINVAL;
  357. }
  358. for (i = 0; i < OCXL_TEMPL_NAME_LEN; i++) {
  359. if (!char_allowed(afu->name[i])) {
  360. dev_err(&dev->dev,
  361. "Invalid character in AFU name\n");
  362. return -EINVAL;
  363. }
  364. }
  365. if (afu->global_mmio_bar != 0 &&
  366. afu->global_mmio_bar != 2 &&
  367. afu->global_mmio_bar != 4) {
  368. dev_err(&dev->dev, "Invalid global MMIO bar number\n");
  369. return -EINVAL;
  370. }
  371. if (afu->pp_mmio_bar != 0 &&
  372. afu->pp_mmio_bar != 2 &&
  373. afu->pp_mmio_bar != 4) {
  374. dev_err(&dev->dev, "Invalid per-process MMIO bar number\n");
  375. return -EINVAL;
  376. }
  377. return 0;
  378. }
  379. int ocxl_config_read_afu(struct pci_dev *dev, struct ocxl_fn_config *fn,
  380. struct ocxl_afu_config *afu, u8 afu_idx)
  381. {
  382. int rc;
  383. u32 val32;
  384. /*
  385. * First, we need to write the AFU idx for the AFU we want to
  386. * access.
  387. */
  388. WARN_ON((afu_idx & OCXL_DVSEC_AFU_IDX_MASK) != afu_idx);
  389. afu->idx = afu_idx;
  390. pci_write_config_byte(dev,
  391. fn->dvsec_afu_info_pos + OCXL_DVSEC_AFU_INFO_AFU_IDX,
  392. afu->idx);
  393. rc = read_afu_name(dev, fn, afu);
  394. if (rc)
  395. return rc;
  396. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_AFU_VERSION, &val32);
  397. if (rc)
  398. return rc;
  399. afu->version_major = EXTRACT_BITS(val32, 24, 31);
  400. afu->version_minor = EXTRACT_BITS(val32, 16, 23);
  401. afu->afuc_type = EXTRACT_BITS(val32, 14, 15);
  402. afu->afum_type = EXTRACT_BITS(val32, 12, 13);
  403. afu->profile = EXTRACT_BITS(val32, 0, 7);
  404. rc = read_afu_mmio(dev, fn, afu);
  405. if (rc)
  406. return rc;
  407. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MEM_SZ, &val32);
  408. if (rc)
  409. return rc;
  410. afu->log_mem_size = EXTRACT_BITS(val32, 0, 7);
  411. rc = read_afu_control(dev, afu);
  412. if (rc)
  413. return rc;
  414. dev_dbg(&dev->dev, "AFU configuration:\n");
  415. dev_dbg(&dev->dev, " name = %s\n", afu->name);
  416. dev_dbg(&dev->dev, " version = %d.%d\n", afu->version_major,
  417. afu->version_minor);
  418. dev_dbg(&dev->dev, " global mmio bar = %hhu\n", afu->global_mmio_bar);
  419. dev_dbg(&dev->dev, " global mmio offset = %#llx\n",
  420. afu->global_mmio_offset);
  421. dev_dbg(&dev->dev, " global mmio size = %#x\n", afu->global_mmio_size);
  422. dev_dbg(&dev->dev, " pp mmio bar = %hhu\n", afu->pp_mmio_bar);
  423. dev_dbg(&dev->dev, " pp mmio offset = %#llx\n", afu->pp_mmio_offset);
  424. dev_dbg(&dev->dev, " pp mmio stride = %#x\n", afu->pp_mmio_stride);
  425. dev_dbg(&dev->dev, " mem size (log) = %hhu\n", afu->log_mem_size);
  426. dev_dbg(&dev->dev, " pasid supported (log) = %u\n",
  427. afu->pasid_supported_log);
  428. dev_dbg(&dev->dev, " actag supported = %u\n",
  429. afu->actag_supported);
  430. rc = validate_afu(dev, afu);
  431. return rc;
  432. }
  433. EXPORT_SYMBOL_GPL(ocxl_config_read_afu);
  434. int ocxl_config_get_actag_info(struct pci_dev *dev, u16 *base, u16 *enabled,
  435. u16 *supported)
  436. {
  437. int rc;
  438. /*
  439. * This is really a simple wrapper for the kernel API, to
  440. * avoid an external driver using ocxl as a library to call
  441. * platform-dependent code
  442. */
  443. rc = pnv_ocxl_get_actag(dev, base, enabled, supported);
  444. if (rc) {
  445. dev_err(&dev->dev, "Can't get actag for device: %d\n", rc);
  446. return rc;
  447. }
  448. return 0;
  449. }
  450. EXPORT_SYMBOL_GPL(ocxl_config_get_actag_info);
  451. void ocxl_config_set_afu_actag(struct pci_dev *dev, int pos, int actag_base,
  452. int actag_count)
  453. {
  454. u16 val;
  455. val = actag_count & OCXL_DVSEC_ACTAG_MASK;
  456. pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_EN, val);
  457. val = actag_base & OCXL_DVSEC_ACTAG_MASK;
  458. pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_BASE, val);
  459. }
  460. EXPORT_SYMBOL_GPL(ocxl_config_set_afu_actag);
  461. int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count)
  462. {
  463. return pnv_ocxl_get_pasid_count(dev, count);
  464. }
  465. EXPORT_SYMBOL_GPL(ocxl_config_get_pasid_info);
  466. void ocxl_config_set_afu_pasid(struct pci_dev *dev, int pos, int pasid_base,
  467. u32 pasid_count_log)
  468. {
  469. u8 val8;
  470. u32 val32;
  471. val8 = pasid_count_log & OCXL_DVSEC_PASID_LOG_MASK;
  472. pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_EN, val8);
  473. pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_BASE,
  474. &val32);
  475. val32 &= ~OCXL_DVSEC_PASID_MASK;
  476. val32 |= pasid_base & OCXL_DVSEC_PASID_MASK;
  477. pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_BASE,
  478. val32);
  479. }
  480. EXPORT_SYMBOL_GPL(ocxl_config_set_afu_pasid);
  481. void ocxl_config_set_afu_state(struct pci_dev *dev, int pos, int enable)
  482. {
  483. u8 val;
  484. pci_read_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ENABLE, &val);
  485. if (enable)
  486. val |= 1;
  487. else
  488. val &= 0xFE;
  489. pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ENABLE, val);
  490. }
  491. EXPORT_SYMBOL_GPL(ocxl_config_set_afu_state);
  492. int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec)
  493. {
  494. u32 val;
  495. __be32 *be32ptr;
  496. u8 timers;
  497. int i, rc;
  498. long recv_cap;
  499. char *recv_rate;
  500. /*
  501. * Skip on function != 0, as the TL can only be defined on 0
  502. */
  503. if (PCI_FUNC(dev->devfn) != 0)
  504. return 0;
  505. recv_rate = kzalloc(PNV_OCXL_TL_RATE_BUF_SIZE, GFP_KERNEL);
  506. if (!recv_rate)
  507. return -ENOMEM;
  508. /*
  509. * The spec defines 64 templates for messages in the
  510. * Transaction Layer (TL).
  511. *
  512. * The host and device each support a subset, so we need to
  513. * configure the transmitters on each side to send only
  514. * templates the receiver understands, at a rate the receiver
  515. * can process. Per the spec, template 0 must be supported by
  516. * everybody. That's the template which has been used by the
  517. * host and device so far.
  518. *
  519. * The sending rate limit must be set before the template is
  520. * enabled.
  521. */
  522. /*
  523. * Device -> host
  524. */
  525. rc = pnv_ocxl_get_tl_cap(dev, &recv_cap, recv_rate,
  526. PNV_OCXL_TL_RATE_BUF_SIZE);
  527. if (rc)
  528. goto out;
  529. for (i = 0; i < PNV_OCXL_TL_RATE_BUF_SIZE; i += 4) {
  530. be32ptr = (__be32 *) &recv_rate[i];
  531. pci_write_config_dword(dev,
  532. tl_dvsec + OCXL_DVSEC_TL_SEND_RATE + i,
  533. be32_to_cpu(*be32ptr));
  534. }
  535. val = recv_cap >> 32;
  536. pci_write_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_SEND_CAP, val);
  537. val = recv_cap & GENMASK(31, 0);
  538. pci_write_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_SEND_CAP + 4, val);
  539. /*
  540. * Host -> device
  541. */
  542. for (i = 0; i < PNV_OCXL_TL_RATE_BUF_SIZE; i += 4) {
  543. pci_read_config_dword(dev,
  544. tl_dvsec + OCXL_DVSEC_TL_RECV_RATE + i,
  545. &val);
  546. be32ptr = (__be32 *) &recv_rate[i];
  547. *be32ptr = cpu_to_be32(val);
  548. }
  549. pci_read_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_RECV_CAP, &val);
  550. recv_cap = (long) val << 32;
  551. pci_read_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_RECV_CAP + 4, &val);
  552. recv_cap |= val;
  553. rc = pnv_ocxl_set_tl_conf(dev, recv_cap, __pa(recv_rate),
  554. PNV_OCXL_TL_RATE_BUF_SIZE);
  555. if (rc)
  556. goto out;
  557. /*
  558. * Opencapi commands needing to be retried are classified per
  559. * the TL in 2 groups: short and long commands.
  560. *
  561. * The short back off timer it not used for now. It will be
  562. * for opencapi 4.0.
  563. *
  564. * The long back off timer is typically used when an AFU hits
  565. * a page fault but the NPU is already processing one. So the
  566. * AFU needs to wait before it can resubmit. Having a value
  567. * too low doesn't break anything, but can generate extra
  568. * traffic on the link.
  569. * We set it to 1.6 us for now. It's shorter than, but in the
  570. * same order of magnitude as the time spent to process a page
  571. * fault.
  572. */
  573. timers = 0x2 << 4; /* long timer = 1.6 us */
  574. pci_write_config_byte(dev, tl_dvsec + OCXL_DVSEC_TL_BACKOFF_TIMERS,
  575. timers);
  576. rc = 0;
  577. out:
  578. kfree(recv_rate);
  579. return rc;
  580. }
  581. EXPORT_SYMBOL_GPL(ocxl_config_set_TL);
  582. int ocxl_config_terminate_pasid(struct pci_dev *dev, int afu_control, int pasid)
  583. {
  584. u32 val;
  585. unsigned long timeout;
  586. pci_read_config_dword(dev, afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
  587. &val);
  588. if (EXTRACT_BIT(val, 20)) {
  589. dev_err(&dev->dev,
  590. "Can't terminate PASID %#x, previous termination didn't complete\n",
  591. pasid);
  592. return -EBUSY;
  593. }
  594. val &= ~OCXL_DVSEC_PASID_MASK;
  595. val |= pasid & OCXL_DVSEC_PASID_MASK;
  596. val |= BIT(20);
  597. pci_write_config_dword(dev,
  598. afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
  599. val);
  600. timeout = jiffies + (HZ * OCXL_CFG_TIMEOUT);
  601. pci_read_config_dword(dev, afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
  602. &val);
  603. while (EXTRACT_BIT(val, 20)) {
  604. if (time_after_eq(jiffies, timeout)) {
  605. dev_err(&dev->dev,
  606. "Timeout while waiting for AFU to terminate PASID %#x\n",
  607. pasid);
  608. return -EBUSY;
  609. }
  610. cpu_relax();
  611. pci_read_config_dword(dev,
  612. afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
  613. &val);
  614. }
  615. return 0;
  616. }
  617. EXPORT_SYMBOL_GPL(ocxl_config_terminate_pasid);
  618. void ocxl_config_set_actag(struct pci_dev *dev, int func_dvsec, u32 tag_first,
  619. u32 tag_count)
  620. {
  621. u32 val;
  622. val = (tag_first & OCXL_DVSEC_ACTAG_MASK) << 16;
  623. val |= tag_count & OCXL_DVSEC_ACTAG_MASK;
  624. pci_write_config_dword(dev, func_dvsec + OCXL_DVSEC_FUNC_OFF_ACTAG,
  625. val);
  626. }
  627. EXPORT_SYMBOL_GPL(ocxl_config_set_actag);