config.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  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_byte(dev,
  244. fn->dvsec_afu_info_pos + OCXL_DVSEC_AFU_INFO_AFU_IDX,
  245. afu_idx);
  246. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_VERSION, &val);
  247. if (rc)
  248. return rc;
  249. /* AFU index map can have holes */
  250. if (!val)
  251. return 0;
  252. templ_major = EXTRACT_BITS(val, 8, 15);
  253. templ_minor = EXTRACT_BITS(val, 0, 7);
  254. dev_dbg(&dev->dev, "AFU descriptor template version %d.%d\n",
  255. templ_major, templ_minor);
  256. len = EXTRACT_BITS(val, 16, 31);
  257. if (len != OCXL_TEMPL_LEN) {
  258. dev_warn(&dev->dev,
  259. "Unexpected template length in AFU information (%#x)\n",
  260. len);
  261. }
  262. return 1;
  263. }
  264. EXPORT_SYMBOL_GPL(ocxl_config_check_afu_index);
  265. static int read_afu_name(struct pci_dev *dev, struct ocxl_fn_config *fn,
  266. struct ocxl_afu_config *afu)
  267. {
  268. int i, rc;
  269. u32 val, *ptr;
  270. BUILD_BUG_ON(OCXL_AFU_NAME_SZ < OCXL_TEMPL_NAME_LEN);
  271. for (i = 0; i < OCXL_TEMPL_NAME_LEN; i += 4) {
  272. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_NAME + i, &val);
  273. if (rc)
  274. return rc;
  275. ptr = (u32 *) &afu->name[i];
  276. *ptr = val;
  277. }
  278. afu->name[OCXL_AFU_NAME_SZ - 1] = '\0'; /* play safe */
  279. return 0;
  280. }
  281. static int read_afu_mmio(struct pci_dev *dev, struct ocxl_fn_config *fn,
  282. struct ocxl_afu_config *afu)
  283. {
  284. int rc;
  285. u32 val;
  286. /*
  287. * Global MMIO
  288. */
  289. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_GLOBAL, &val);
  290. if (rc)
  291. return rc;
  292. afu->global_mmio_bar = EXTRACT_BITS(val, 0, 2);
  293. afu->global_mmio_offset = EXTRACT_BITS(val, 16, 31) << 16;
  294. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_GLOBAL + 4, &val);
  295. if (rc)
  296. return rc;
  297. afu->global_mmio_offset += (u64) val << 32;
  298. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_GLOBAL_SZ, &val);
  299. if (rc)
  300. return rc;
  301. afu->global_mmio_size = val;
  302. /*
  303. * Per-process MMIO
  304. */
  305. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_PP, &val);
  306. if (rc)
  307. return rc;
  308. afu->pp_mmio_bar = EXTRACT_BITS(val, 0, 2);
  309. afu->pp_mmio_offset = EXTRACT_BITS(val, 16, 31) << 16;
  310. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_PP + 4, &val);
  311. if (rc)
  312. return rc;
  313. afu->pp_mmio_offset += (u64) val << 32;
  314. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MMIO_PP_SZ, &val);
  315. if (rc)
  316. return rc;
  317. afu->pp_mmio_stride = val;
  318. return 0;
  319. }
  320. static int read_afu_control(struct pci_dev *dev, struct ocxl_afu_config *afu)
  321. {
  322. int pos;
  323. u8 val8;
  324. u16 val16;
  325. pos = find_dvsec_afu_ctrl(dev, afu->idx);
  326. if (!pos) {
  327. dev_err(&dev->dev, "Can't find AFU control DVSEC for AFU %d\n",
  328. afu->idx);
  329. return -ENODEV;
  330. }
  331. afu->dvsec_afu_control_pos = pos;
  332. pci_read_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_SUP, &val8);
  333. afu->pasid_supported_log = EXTRACT_BITS(val8, 0, 4);
  334. pci_read_config_word(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_SUP, &val16);
  335. afu->actag_supported = EXTRACT_BITS(val16, 0, 11);
  336. return 0;
  337. }
  338. static bool char_allowed(int c)
  339. {
  340. /*
  341. * Permitted Characters : Alphanumeric, hyphen, underscore, comma
  342. */
  343. if ((c >= 0x30 && c <= 0x39) /* digits */ ||
  344. (c >= 0x41 && c <= 0x5A) /* upper case */ ||
  345. (c >= 0x61 && c <= 0x7A) /* lower case */ ||
  346. c == 0 /* NULL */ ||
  347. c == 0x2D /* - */ ||
  348. c == 0x5F /* _ */ ||
  349. c == 0x2C /* , */)
  350. return true;
  351. return false;
  352. }
  353. static int validate_afu(struct pci_dev *dev, struct ocxl_afu_config *afu)
  354. {
  355. int i;
  356. if (!afu->name[0]) {
  357. dev_err(&dev->dev, "Empty AFU name\n");
  358. return -EINVAL;
  359. }
  360. for (i = 0; i < OCXL_TEMPL_NAME_LEN; i++) {
  361. if (!char_allowed(afu->name[i])) {
  362. dev_err(&dev->dev,
  363. "Invalid character in AFU name\n");
  364. return -EINVAL;
  365. }
  366. }
  367. if (afu->global_mmio_bar != 0 &&
  368. afu->global_mmio_bar != 2 &&
  369. afu->global_mmio_bar != 4) {
  370. dev_err(&dev->dev, "Invalid global MMIO bar number\n");
  371. return -EINVAL;
  372. }
  373. if (afu->pp_mmio_bar != 0 &&
  374. afu->pp_mmio_bar != 2 &&
  375. afu->pp_mmio_bar != 4) {
  376. dev_err(&dev->dev, "Invalid per-process MMIO bar number\n");
  377. return -EINVAL;
  378. }
  379. return 0;
  380. }
  381. int ocxl_config_read_afu(struct pci_dev *dev, struct ocxl_fn_config *fn,
  382. struct ocxl_afu_config *afu, u8 afu_idx)
  383. {
  384. int rc;
  385. u32 val32;
  386. /*
  387. * First, we need to write the AFU idx for the AFU we want to
  388. * access.
  389. */
  390. WARN_ON((afu_idx & OCXL_DVSEC_AFU_IDX_MASK) != afu_idx);
  391. afu->idx = afu_idx;
  392. pci_write_config_byte(dev,
  393. fn->dvsec_afu_info_pos + OCXL_DVSEC_AFU_INFO_AFU_IDX,
  394. afu->idx);
  395. rc = read_afu_name(dev, fn, afu);
  396. if (rc)
  397. return rc;
  398. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_AFU_VERSION, &val32);
  399. if (rc)
  400. return rc;
  401. afu->version_major = EXTRACT_BITS(val32, 24, 31);
  402. afu->version_minor = EXTRACT_BITS(val32, 16, 23);
  403. afu->afuc_type = EXTRACT_BITS(val32, 14, 15);
  404. afu->afum_type = EXTRACT_BITS(val32, 12, 13);
  405. afu->profile = EXTRACT_BITS(val32, 0, 7);
  406. rc = read_afu_mmio(dev, fn, afu);
  407. if (rc)
  408. return rc;
  409. rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MEM_SZ, &val32);
  410. if (rc)
  411. return rc;
  412. afu->log_mem_size = EXTRACT_BITS(val32, 0, 7);
  413. rc = read_afu_control(dev, afu);
  414. if (rc)
  415. return rc;
  416. dev_dbg(&dev->dev, "AFU configuration:\n");
  417. dev_dbg(&dev->dev, " name = %s\n", afu->name);
  418. dev_dbg(&dev->dev, " version = %d.%d\n", afu->version_major,
  419. afu->version_minor);
  420. dev_dbg(&dev->dev, " global mmio bar = %hhu\n", afu->global_mmio_bar);
  421. dev_dbg(&dev->dev, " global mmio offset = %#llx\n",
  422. afu->global_mmio_offset);
  423. dev_dbg(&dev->dev, " global mmio size = %#x\n", afu->global_mmio_size);
  424. dev_dbg(&dev->dev, " pp mmio bar = %hhu\n", afu->pp_mmio_bar);
  425. dev_dbg(&dev->dev, " pp mmio offset = %#llx\n", afu->pp_mmio_offset);
  426. dev_dbg(&dev->dev, " pp mmio stride = %#x\n", afu->pp_mmio_stride);
  427. dev_dbg(&dev->dev, " mem size (log) = %hhu\n", afu->log_mem_size);
  428. dev_dbg(&dev->dev, " pasid supported (log) = %u\n",
  429. afu->pasid_supported_log);
  430. dev_dbg(&dev->dev, " actag supported = %u\n",
  431. afu->actag_supported);
  432. rc = validate_afu(dev, afu);
  433. return rc;
  434. }
  435. EXPORT_SYMBOL_GPL(ocxl_config_read_afu);
  436. int ocxl_config_get_actag_info(struct pci_dev *dev, u16 *base, u16 *enabled,
  437. u16 *supported)
  438. {
  439. int rc;
  440. /*
  441. * This is really a simple wrapper for the kernel API, to
  442. * avoid an external driver using ocxl as a library to call
  443. * platform-dependent code
  444. */
  445. rc = pnv_ocxl_get_actag(dev, base, enabled, supported);
  446. if (rc) {
  447. dev_err(&dev->dev, "Can't get actag for device: %d\n", rc);
  448. return rc;
  449. }
  450. return 0;
  451. }
  452. EXPORT_SYMBOL_GPL(ocxl_config_get_actag_info);
  453. void ocxl_config_set_afu_actag(struct pci_dev *dev, int pos, int actag_base,
  454. int actag_count)
  455. {
  456. u16 val;
  457. val = actag_count & OCXL_DVSEC_ACTAG_MASK;
  458. pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_EN, val);
  459. val = actag_base & OCXL_DVSEC_ACTAG_MASK;
  460. pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_BASE, val);
  461. }
  462. EXPORT_SYMBOL_GPL(ocxl_config_set_afu_actag);
  463. int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count)
  464. {
  465. return pnv_ocxl_get_pasid_count(dev, count);
  466. }
  467. EXPORT_SYMBOL_GPL(ocxl_config_get_pasid_info);
  468. void ocxl_config_set_afu_pasid(struct pci_dev *dev, int pos, int pasid_base,
  469. u32 pasid_count_log)
  470. {
  471. u8 val8;
  472. u32 val32;
  473. val8 = pasid_count_log & OCXL_DVSEC_PASID_LOG_MASK;
  474. pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_EN, val8);
  475. pci_read_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_BASE,
  476. &val32);
  477. val32 &= ~OCXL_DVSEC_PASID_MASK;
  478. val32 |= pasid_base & OCXL_DVSEC_PASID_MASK;
  479. pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_BASE,
  480. val32);
  481. }
  482. EXPORT_SYMBOL_GPL(ocxl_config_set_afu_pasid);
  483. void ocxl_config_set_afu_state(struct pci_dev *dev, int pos, int enable)
  484. {
  485. u8 val;
  486. pci_read_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ENABLE, &val);
  487. if (enable)
  488. val |= 1;
  489. else
  490. val &= 0xFE;
  491. pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ENABLE, val);
  492. }
  493. EXPORT_SYMBOL_GPL(ocxl_config_set_afu_state);
  494. int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec)
  495. {
  496. u32 val;
  497. __be32 *be32ptr;
  498. u8 timers;
  499. int i, rc;
  500. long recv_cap;
  501. char *recv_rate;
  502. /*
  503. * Skip on function != 0, as the TL can only be defined on 0
  504. */
  505. if (PCI_FUNC(dev->devfn) != 0)
  506. return 0;
  507. recv_rate = kzalloc(PNV_OCXL_TL_RATE_BUF_SIZE, GFP_KERNEL);
  508. if (!recv_rate)
  509. return -ENOMEM;
  510. /*
  511. * The spec defines 64 templates for messages in the
  512. * Transaction Layer (TL).
  513. *
  514. * The host and device each support a subset, so we need to
  515. * configure the transmitters on each side to send only
  516. * templates the receiver understands, at a rate the receiver
  517. * can process. Per the spec, template 0 must be supported by
  518. * everybody. That's the template which has been used by the
  519. * host and device so far.
  520. *
  521. * The sending rate limit must be set before the template is
  522. * enabled.
  523. */
  524. /*
  525. * Device -> host
  526. */
  527. rc = pnv_ocxl_get_tl_cap(dev, &recv_cap, recv_rate,
  528. PNV_OCXL_TL_RATE_BUF_SIZE);
  529. if (rc)
  530. goto out;
  531. for (i = 0; i < PNV_OCXL_TL_RATE_BUF_SIZE; i += 4) {
  532. be32ptr = (__be32 *) &recv_rate[i];
  533. pci_write_config_dword(dev,
  534. tl_dvsec + OCXL_DVSEC_TL_SEND_RATE + i,
  535. be32_to_cpu(*be32ptr));
  536. }
  537. val = recv_cap >> 32;
  538. pci_write_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_SEND_CAP, val);
  539. val = recv_cap & GENMASK(31, 0);
  540. pci_write_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_SEND_CAP + 4, val);
  541. /*
  542. * Host -> device
  543. */
  544. for (i = 0; i < PNV_OCXL_TL_RATE_BUF_SIZE; i += 4) {
  545. pci_read_config_dword(dev,
  546. tl_dvsec + OCXL_DVSEC_TL_RECV_RATE + i,
  547. &val);
  548. be32ptr = (__be32 *) &recv_rate[i];
  549. *be32ptr = cpu_to_be32(val);
  550. }
  551. pci_read_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_RECV_CAP, &val);
  552. recv_cap = (long) val << 32;
  553. pci_read_config_dword(dev, tl_dvsec + OCXL_DVSEC_TL_RECV_CAP + 4, &val);
  554. recv_cap |= val;
  555. rc = pnv_ocxl_set_tl_conf(dev, recv_cap, __pa(recv_rate),
  556. PNV_OCXL_TL_RATE_BUF_SIZE);
  557. if (rc)
  558. goto out;
  559. /*
  560. * Opencapi commands needing to be retried are classified per
  561. * the TL in 2 groups: short and long commands.
  562. *
  563. * The short back off timer it not used for now. It will be
  564. * for opencapi 4.0.
  565. *
  566. * The long back off timer is typically used when an AFU hits
  567. * a page fault but the NPU is already processing one. So the
  568. * AFU needs to wait before it can resubmit. Having a value
  569. * too low doesn't break anything, but can generate extra
  570. * traffic on the link.
  571. * We set it to 1.6 us for now. It's shorter than, but in the
  572. * same order of magnitude as the time spent to process a page
  573. * fault.
  574. */
  575. timers = 0x2 << 4; /* long timer = 1.6 us */
  576. pci_write_config_byte(dev, tl_dvsec + OCXL_DVSEC_TL_BACKOFF_TIMERS,
  577. timers);
  578. rc = 0;
  579. out:
  580. kfree(recv_rate);
  581. return rc;
  582. }
  583. EXPORT_SYMBOL_GPL(ocxl_config_set_TL);
  584. int ocxl_config_terminate_pasid(struct pci_dev *dev, int afu_control, int pasid)
  585. {
  586. u32 val;
  587. unsigned long timeout;
  588. pci_read_config_dword(dev, afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
  589. &val);
  590. if (EXTRACT_BIT(val, 20)) {
  591. dev_err(&dev->dev,
  592. "Can't terminate PASID %#x, previous termination didn't complete\n",
  593. pasid);
  594. return -EBUSY;
  595. }
  596. val &= ~OCXL_DVSEC_PASID_MASK;
  597. val |= pasid & OCXL_DVSEC_PASID_MASK;
  598. val |= BIT(20);
  599. pci_write_config_dword(dev,
  600. afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
  601. val);
  602. timeout = jiffies + (HZ * OCXL_CFG_TIMEOUT);
  603. pci_read_config_dword(dev, afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
  604. &val);
  605. while (EXTRACT_BIT(val, 20)) {
  606. if (time_after_eq(jiffies, timeout)) {
  607. dev_err(&dev->dev,
  608. "Timeout while waiting for AFU to terminate PASID %#x\n",
  609. pasid);
  610. return -EBUSY;
  611. }
  612. cpu_relax();
  613. pci_read_config_dword(dev,
  614. afu_control + OCXL_DVSEC_AFU_CTRL_TERM_PASID,
  615. &val);
  616. }
  617. return 0;
  618. }
  619. EXPORT_SYMBOL_GPL(ocxl_config_terminate_pasid);
  620. void ocxl_config_set_actag(struct pci_dev *dev, int func_dvsec, u32 tag_first,
  621. u32 tag_count)
  622. {
  623. u32 val;
  624. val = (tag_first & OCXL_DVSEC_ACTAG_MASK) << 16;
  625. val |= tag_count & OCXL_DVSEC_ACTAG_MASK;
  626. pci_write_config_dword(dev, func_dvsec + OCXL_DVSEC_FUNC_OFF_ACTAG,
  627. val);
  628. }
  629. EXPORT_SYMBOL_GPL(ocxl_config_set_actag);