vsec.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Intel Vendor Specific Extended Capabilities auxiliary bus driver
  4. *
  5. * Copyright (c) 2021, Intel Corporation.
  6. * All Rights Reserved.
  7. *
  8. * Author: David E. Box <david.e.box@linux.intel.com>
  9. *
  10. * This driver discovers and creates auxiliary devices for Intel defined PCIe
  11. * "Vendor Specific" and "Designated Vendor Specific" Extended Capabilities,
  12. * VSEC and DVSEC respectively. The driver supports features on specific PCIe
  13. * endpoints that exist primarily to expose them.
  14. */
  15. #include <linux/auxiliary_bus.h>
  16. #include <linux/bits.h>
  17. #include <linux/bitops.h>
  18. #include <linux/bug.h>
  19. #include <linux/cleanup.h>
  20. #include <linux/delay.h>
  21. #include <linux/idr.h>
  22. #include <linux/log2.h>
  23. #include <linux/intel_vsec.h>
  24. #include <linux/kernel.h>
  25. #include <linux/module.h>
  26. #include <linux/pci.h>
  27. #include <linux/types.h>
  28. #define PMT_XA_START 0
  29. #define PMT_XA_MAX INT_MAX
  30. #define PMT_XA_LIMIT XA_LIMIT(PMT_XA_START, PMT_XA_MAX)
  31. static DEFINE_IDA(intel_vsec_ida);
  32. static DEFINE_IDA(intel_vsec_sdsi_ida);
  33. static DEFINE_XARRAY_ALLOC(auxdev_array);
  34. enum vsec_device_state {
  35. STATE_NOT_FOUND,
  36. STATE_REGISTERED,
  37. STATE_SKIP,
  38. };
  39. struct vsec_priv {
  40. struct intel_vsec_platform_info *info;
  41. struct device *suppliers[VSEC_FEATURE_COUNT];
  42. struct oobmsm_plat_info plat_info;
  43. enum vsec_device_state state[VSEC_FEATURE_COUNT];
  44. unsigned long found_caps;
  45. };
  46. static const char *intel_vsec_name(enum intel_vsec_id id)
  47. {
  48. switch (id) {
  49. case VSEC_ID_TELEMETRY:
  50. return "telemetry";
  51. case VSEC_ID_WATCHER:
  52. return "watcher";
  53. case VSEC_ID_CRASHLOG:
  54. return "crashlog";
  55. case VSEC_ID_SDSI:
  56. return "sdsi";
  57. case VSEC_ID_TPMI:
  58. return "tpmi";
  59. case VSEC_ID_DISCOVERY:
  60. return "discovery";
  61. default:
  62. return NULL;
  63. }
  64. }
  65. static bool intel_vsec_supported(u16 id, unsigned long caps)
  66. {
  67. switch (id) {
  68. case VSEC_ID_TELEMETRY:
  69. return !!(caps & VSEC_CAP_TELEMETRY);
  70. case VSEC_ID_WATCHER:
  71. return !!(caps & VSEC_CAP_WATCHER);
  72. case VSEC_ID_CRASHLOG:
  73. return !!(caps & VSEC_CAP_CRASHLOG);
  74. case VSEC_ID_SDSI:
  75. return !!(caps & VSEC_CAP_SDSI);
  76. case VSEC_ID_TPMI:
  77. return !!(caps & VSEC_CAP_TPMI);
  78. case VSEC_ID_DISCOVERY:
  79. return !!(caps & VSEC_CAP_DISCOVERY);
  80. default:
  81. return false;
  82. }
  83. }
  84. static void intel_vsec_remove_aux(void *data)
  85. {
  86. auxiliary_device_delete(data);
  87. auxiliary_device_uninit(data);
  88. }
  89. static void intel_vsec_dev_release(struct device *dev)
  90. {
  91. struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(dev);
  92. xa_erase(&auxdev_array, intel_vsec_dev->id);
  93. ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id);
  94. kfree(intel_vsec_dev->resource);
  95. kfree(intel_vsec_dev);
  96. }
  97. static const struct vsec_feature_dependency *
  98. get_consumer_dependencies(struct vsec_priv *priv, int cap_id)
  99. {
  100. const struct vsec_feature_dependency *deps = priv->info->deps;
  101. int consumer_id = priv->info->num_deps;
  102. if (!deps)
  103. return NULL;
  104. while (consumer_id--)
  105. if (deps[consumer_id].feature == BIT(cap_id))
  106. return &deps[consumer_id];
  107. return NULL;
  108. }
  109. static bool vsec_driver_present(int cap_id)
  110. {
  111. unsigned long bit = BIT(cap_id);
  112. switch (bit) {
  113. case VSEC_CAP_TELEMETRY:
  114. return IS_ENABLED(CONFIG_INTEL_PMT_TELEMETRY);
  115. case VSEC_CAP_WATCHER:
  116. return IS_ENABLED(CONFIG_INTEL_PMT_WATCHER);
  117. case VSEC_CAP_CRASHLOG:
  118. return IS_ENABLED(CONFIG_INTEL_PMT_CRASHLOG);
  119. case VSEC_CAP_SDSI:
  120. return IS_ENABLED(CONFIG_INTEL_SDSI);
  121. case VSEC_CAP_TPMI:
  122. return IS_ENABLED(CONFIG_INTEL_TPMI);
  123. case VSEC_CAP_DISCOVERY:
  124. return IS_ENABLED(CONFIG_INTEL_PMT_DISCOVERY);
  125. default:
  126. return false;
  127. }
  128. }
  129. /*
  130. * Although pci_device_id table is available in the pdev, this prototype is
  131. * necessary because the code using it can be called by an exported API that
  132. * might pass a different pdev.
  133. */
  134. static const struct pci_device_id intel_vsec_pci_ids[];
  135. static int intel_vsec_link_devices(struct pci_dev *pdev, struct device *dev,
  136. int consumer_id)
  137. {
  138. const struct vsec_feature_dependency *deps;
  139. enum vsec_device_state *state;
  140. struct device **suppliers;
  141. struct vsec_priv *priv;
  142. int supplier_id;
  143. if (!consumer_id)
  144. return 0;
  145. if (!pci_match_id(intel_vsec_pci_ids, pdev))
  146. return 0;
  147. priv = pci_get_drvdata(pdev);
  148. state = priv->state;
  149. suppliers = priv->suppliers;
  150. priv->suppliers[consumer_id] = dev;
  151. deps = get_consumer_dependencies(priv, consumer_id);
  152. if (!deps)
  153. return 0;
  154. for_each_set_bit(supplier_id, &deps->supplier_bitmap, VSEC_FEATURE_COUNT) {
  155. struct device_link *link;
  156. if (state[supplier_id] != STATE_REGISTERED ||
  157. !vsec_driver_present(supplier_id))
  158. continue;
  159. if (!suppliers[supplier_id]) {
  160. dev_err(dev, "Bad supplier list\n");
  161. return -EINVAL;
  162. }
  163. link = device_link_add(dev, suppliers[supplier_id],
  164. DL_FLAG_AUTOPROBE_CONSUMER);
  165. if (!link)
  166. return -EINVAL;
  167. }
  168. return 0;
  169. }
  170. int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent,
  171. struct intel_vsec_device *intel_vsec_dev,
  172. const char *name)
  173. {
  174. struct auxiliary_device *auxdev = &intel_vsec_dev->auxdev;
  175. int ret, id;
  176. if (!parent)
  177. return -EINVAL;
  178. ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev,
  179. PMT_XA_LIMIT, GFP_KERNEL);
  180. if (ret < 0) {
  181. kfree(intel_vsec_dev->resource);
  182. kfree(intel_vsec_dev);
  183. return ret;
  184. }
  185. id = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL);
  186. if (id < 0) {
  187. xa_erase(&auxdev_array, intel_vsec_dev->id);
  188. kfree(intel_vsec_dev->resource);
  189. kfree(intel_vsec_dev);
  190. return id;
  191. }
  192. auxdev->id = id;
  193. auxdev->name = name;
  194. auxdev->dev.parent = parent;
  195. auxdev->dev.release = intel_vsec_dev_release;
  196. ret = auxiliary_device_init(auxdev);
  197. if (ret < 0) {
  198. intel_vsec_dev_release(&auxdev->dev);
  199. return ret;
  200. }
  201. /*
  202. * Assign a name now to ensure that the device link doesn't contain
  203. * a null string for the consumer name. This is a problem when a supplier
  204. * supplies more than one consumer and can lead to a duplicate name error
  205. * when the link is created in sysfs.
  206. */
  207. ret = dev_set_name(&auxdev->dev, "%s.%s.%d", KBUILD_MODNAME, auxdev->name,
  208. auxdev->id);
  209. if (ret)
  210. goto cleanup_aux;
  211. ret = intel_vsec_link_devices(pdev, &auxdev->dev, intel_vsec_dev->cap_id);
  212. if (ret)
  213. goto cleanup_aux;
  214. ret = auxiliary_device_add(auxdev);
  215. if (ret)
  216. goto cleanup_aux;
  217. return devm_add_action_or_reset(parent, intel_vsec_remove_aux,
  218. auxdev);
  219. cleanup_aux:
  220. auxiliary_device_uninit(auxdev);
  221. return ret;
  222. }
  223. EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, "INTEL_VSEC");
  224. static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *header,
  225. struct intel_vsec_platform_info *info,
  226. unsigned long cap_id)
  227. {
  228. struct intel_vsec_device __free(kfree) *intel_vsec_dev = NULL;
  229. struct resource __free(kfree) *res = NULL;
  230. struct resource *tmp;
  231. struct device *parent;
  232. unsigned long quirks = info->quirks;
  233. u64 base_addr;
  234. int i;
  235. if (info->parent)
  236. parent = info->parent;
  237. else
  238. parent = &pdev->dev;
  239. if (!intel_vsec_supported(header->id, info->caps))
  240. return -EINVAL;
  241. if (!header->num_entries) {
  242. dev_dbg(&pdev->dev, "Invalid 0 entry count for header id %d\n", header->id);
  243. return -EINVAL;
  244. }
  245. if (!header->entry_size) {
  246. dev_dbg(&pdev->dev, "Invalid 0 entry size for header id %d\n", header->id);
  247. return -EINVAL;
  248. }
  249. intel_vsec_dev = kzalloc_obj(*intel_vsec_dev);
  250. if (!intel_vsec_dev)
  251. return -ENOMEM;
  252. res = kzalloc_objs(*res, header->num_entries);
  253. if (!res)
  254. return -ENOMEM;
  255. if (quirks & VSEC_QUIRK_TABLE_SHIFT)
  256. header->offset >>= TABLE_OFFSET_SHIFT;
  257. if (info->base_addr)
  258. base_addr = info->base_addr;
  259. else
  260. base_addr = pdev->resource[header->tbir].start;
  261. /*
  262. * The DVSEC/VSEC contains the starting offset and count for a block of
  263. * discovery tables. Create a resource array of these tables to the
  264. * auxiliary device driver.
  265. */
  266. for (i = 0, tmp = res; i < header->num_entries; i++, tmp++) {
  267. tmp->start = base_addr + header->offset + i * (header->entry_size * sizeof(u32));
  268. tmp->end = tmp->start + (header->entry_size * sizeof(u32)) - 1;
  269. tmp->flags = IORESOURCE_MEM;
  270. /* Check resource is not in use */
  271. if (!request_mem_region(tmp->start, resource_size(tmp), ""))
  272. return -EBUSY;
  273. release_mem_region(tmp->start, resource_size(tmp));
  274. }
  275. intel_vsec_dev->pcidev = pdev;
  276. intel_vsec_dev->resource = no_free_ptr(res);
  277. intel_vsec_dev->num_resources = header->num_entries;
  278. intel_vsec_dev->quirks = info->quirks;
  279. intel_vsec_dev->base_addr = info->base_addr;
  280. intel_vsec_dev->priv_data = info->priv_data;
  281. intel_vsec_dev->cap_id = cap_id;
  282. if (header->id == VSEC_ID_SDSI)
  283. intel_vsec_dev->ida = &intel_vsec_sdsi_ida;
  284. else
  285. intel_vsec_dev->ida = &intel_vsec_ida;
  286. /*
  287. * Pass the ownership of intel_vsec_dev and resource within it to
  288. * intel_vsec_add_aux()
  289. */
  290. return intel_vsec_add_aux(pdev, parent, no_free_ptr(intel_vsec_dev),
  291. intel_vsec_name(header->id));
  292. }
  293. static bool suppliers_ready(struct vsec_priv *priv,
  294. const struct vsec_feature_dependency *consumer_deps,
  295. int cap_id)
  296. {
  297. enum vsec_device_state *state = priv->state;
  298. int supplier_id;
  299. if (WARN_ON_ONCE(consumer_deps->feature != BIT(cap_id)))
  300. return false;
  301. /*
  302. * Verify that all required suppliers have been found. Return false
  303. * immediately if any are still missing.
  304. */
  305. for_each_set_bit(supplier_id, &consumer_deps->supplier_bitmap, VSEC_FEATURE_COUNT) {
  306. if (state[supplier_id] == STATE_SKIP)
  307. continue;
  308. if (state[supplier_id] == STATE_NOT_FOUND)
  309. return false;
  310. }
  311. /*
  312. * All suppliers have been found and the consumer is ready to be
  313. * registered.
  314. */
  315. return true;
  316. }
  317. static int get_cap_id(u32 header_id, unsigned long *cap_id)
  318. {
  319. switch (header_id) {
  320. case VSEC_ID_TELEMETRY:
  321. *cap_id = ilog2(VSEC_CAP_TELEMETRY);
  322. break;
  323. case VSEC_ID_WATCHER:
  324. *cap_id = ilog2(VSEC_CAP_WATCHER);
  325. break;
  326. case VSEC_ID_CRASHLOG:
  327. *cap_id = ilog2(VSEC_CAP_CRASHLOG);
  328. break;
  329. case VSEC_ID_SDSI:
  330. *cap_id = ilog2(VSEC_CAP_SDSI);
  331. break;
  332. case VSEC_ID_TPMI:
  333. *cap_id = ilog2(VSEC_CAP_TPMI);
  334. break;
  335. case VSEC_ID_DISCOVERY:
  336. *cap_id = ilog2(VSEC_CAP_DISCOVERY);
  337. break;
  338. default:
  339. return -EINVAL;
  340. }
  341. return 0;
  342. }
  343. static int intel_vsec_register_device(struct pci_dev *pdev,
  344. struct intel_vsec_header *header,
  345. struct intel_vsec_platform_info *info)
  346. {
  347. const struct vsec_feature_dependency *consumer_deps;
  348. struct vsec_priv *priv;
  349. unsigned long cap_id;
  350. int ret;
  351. ret = get_cap_id(header->id, &cap_id);
  352. if (ret)
  353. return ret;
  354. /*
  355. * Only track dependencies for devices probed by the VSEC driver.
  356. * For others using the exported APIs, add the device directly.
  357. */
  358. if (!pci_match_id(intel_vsec_pci_ids, pdev))
  359. return intel_vsec_add_dev(pdev, header, info, cap_id);
  360. priv = pci_get_drvdata(pdev);
  361. if (priv->state[cap_id] == STATE_REGISTERED ||
  362. priv->state[cap_id] == STATE_SKIP)
  363. return -EEXIST;
  364. priv->found_caps |= BIT(cap_id);
  365. if (!vsec_driver_present(cap_id)) {
  366. priv->state[cap_id] = STATE_SKIP;
  367. return -ENODEV;
  368. }
  369. consumer_deps = get_consumer_dependencies(priv, cap_id);
  370. if (!consumer_deps || suppliers_ready(priv, consumer_deps, cap_id)) {
  371. ret = intel_vsec_add_dev(pdev, header, info, cap_id);
  372. if (ret)
  373. priv->state[cap_id] = STATE_SKIP;
  374. else
  375. priv->state[cap_id] = STATE_REGISTERED;
  376. return ret;
  377. }
  378. return -EAGAIN;
  379. }
  380. static bool intel_vsec_walk_header(struct pci_dev *pdev,
  381. struct intel_vsec_platform_info *info)
  382. {
  383. struct intel_vsec_header **header = info->headers;
  384. bool have_devices = false;
  385. int ret;
  386. for ( ; *header; header++) {
  387. ret = intel_vsec_register_device(pdev, *header, info);
  388. if (!ret)
  389. have_devices = true;
  390. }
  391. return have_devices;
  392. }
  393. static bool intel_vsec_walk_dvsec(struct pci_dev *pdev,
  394. struct intel_vsec_platform_info *info)
  395. {
  396. bool have_devices = false;
  397. int pos = 0;
  398. do {
  399. struct intel_vsec_header header;
  400. u32 table, hdr;
  401. u16 vid;
  402. int ret;
  403. pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_DVSEC);
  404. if (!pos)
  405. break;
  406. pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER1, &hdr);
  407. vid = PCI_DVSEC_HEADER1_VID(hdr);
  408. if (vid != PCI_VENDOR_ID_INTEL)
  409. continue;
  410. /* Support only revision 1 */
  411. header.rev = PCI_DVSEC_HEADER1_REV(hdr);
  412. if (header.rev != 1) {
  413. dev_info(&pdev->dev, "Unsupported DVSEC revision %d\n", header.rev);
  414. continue;
  415. }
  416. header.length = PCI_DVSEC_HEADER1_LEN(hdr);
  417. pci_read_config_byte(pdev, pos + INTEL_DVSEC_ENTRIES, &header.num_entries);
  418. pci_read_config_byte(pdev, pos + INTEL_DVSEC_SIZE, &header.entry_size);
  419. pci_read_config_dword(pdev, pos + INTEL_DVSEC_TABLE, &table);
  420. header.tbir = INTEL_DVSEC_TABLE_BAR(table);
  421. header.offset = INTEL_DVSEC_TABLE_OFFSET(table);
  422. pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER2, &hdr);
  423. header.id = PCI_DVSEC_HEADER2_ID(hdr);
  424. ret = intel_vsec_register_device(pdev, &header, info);
  425. if (ret)
  426. continue;
  427. have_devices = true;
  428. } while (true);
  429. return have_devices;
  430. }
  431. static bool intel_vsec_walk_vsec(struct pci_dev *pdev,
  432. struct intel_vsec_platform_info *info)
  433. {
  434. bool have_devices = false;
  435. int pos = 0;
  436. do {
  437. struct intel_vsec_header header;
  438. u32 table, hdr;
  439. int ret;
  440. pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_VNDR);
  441. if (!pos)
  442. break;
  443. pci_read_config_dword(pdev, pos + PCI_VNDR_HEADER, &hdr);
  444. /* Support only revision 1 */
  445. header.rev = PCI_VNDR_HEADER_REV(hdr);
  446. if (header.rev != 1) {
  447. dev_info(&pdev->dev, "Unsupported VSEC revision %d\n", header.rev);
  448. continue;
  449. }
  450. header.id = PCI_VNDR_HEADER_ID(hdr);
  451. header.length = PCI_VNDR_HEADER_LEN(hdr);
  452. /* entry, size, and table offset are the same as DVSEC */
  453. pci_read_config_byte(pdev, pos + INTEL_DVSEC_ENTRIES, &header.num_entries);
  454. pci_read_config_byte(pdev, pos + INTEL_DVSEC_SIZE, &header.entry_size);
  455. pci_read_config_dword(pdev, pos + INTEL_DVSEC_TABLE, &table);
  456. header.tbir = INTEL_DVSEC_TABLE_BAR(table);
  457. header.offset = INTEL_DVSEC_TABLE_OFFSET(table);
  458. ret = intel_vsec_register_device(pdev, &header, info);
  459. if (ret)
  460. continue;
  461. have_devices = true;
  462. } while (true);
  463. return have_devices;
  464. }
  465. int intel_vsec_register(struct pci_dev *pdev,
  466. struct intel_vsec_platform_info *info)
  467. {
  468. if (!pdev || !info || !info->headers)
  469. return -EINVAL;
  470. if (!intel_vsec_walk_header(pdev, info))
  471. return -ENODEV;
  472. else
  473. return 0;
  474. }
  475. EXPORT_SYMBOL_NS_GPL(intel_vsec_register, "INTEL_VSEC");
  476. static bool intel_vsec_get_features(struct pci_dev *pdev,
  477. struct intel_vsec_platform_info *info)
  478. {
  479. bool found = false;
  480. /*
  481. * Both DVSEC and VSEC capabilities can exist on the same device,
  482. * so both intel_vsec_walk_dvsec() and intel_vsec_walk_vsec() must be
  483. * called independently. Additionally, intel_vsec_walk_header() is
  484. * needed for devices that do not have VSEC/DVSEC but provide the
  485. * information via device_data.
  486. */
  487. if (intel_vsec_walk_dvsec(pdev, info))
  488. found = true;
  489. if (intel_vsec_walk_vsec(pdev, info))
  490. found = true;
  491. if (info && (info->quirks & VSEC_QUIRK_NO_DVSEC) &&
  492. intel_vsec_walk_header(pdev, info))
  493. found = true;
  494. return found;
  495. }
  496. static void intel_vsec_skip_missing_dependencies(struct pci_dev *pdev)
  497. {
  498. struct vsec_priv *priv = pci_get_drvdata(pdev);
  499. const struct vsec_feature_dependency *deps = priv->info->deps;
  500. int consumer_id = priv->info->num_deps;
  501. while (consumer_id--) {
  502. int supplier_id;
  503. deps = &priv->info->deps[consumer_id];
  504. for_each_set_bit(supplier_id, &deps->supplier_bitmap, VSEC_FEATURE_COUNT) {
  505. if (!(BIT(supplier_id) & priv->found_caps))
  506. priv->state[supplier_id] = STATE_SKIP;
  507. }
  508. }
  509. }
  510. static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
  511. {
  512. struct intel_vsec_platform_info *info;
  513. struct vsec_priv *priv;
  514. int num_caps, ret;
  515. int run_once = 0;
  516. bool found_any = false;
  517. ret = pcim_enable_device(pdev);
  518. if (ret)
  519. return ret;
  520. pci_save_state(pdev);
  521. info = (struct intel_vsec_platform_info *)id->driver_data;
  522. if (!info)
  523. return -EINVAL;
  524. priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  525. if (!priv)
  526. return -ENOMEM;
  527. priv->info = info;
  528. pci_set_drvdata(pdev, priv);
  529. num_caps = hweight_long(info->caps);
  530. while (num_caps--) {
  531. found_any |= intel_vsec_get_features(pdev, info);
  532. if (priv->found_caps == info->caps)
  533. break;
  534. if (!run_once) {
  535. intel_vsec_skip_missing_dependencies(pdev);
  536. run_once = 1;
  537. }
  538. }
  539. if (!found_any)
  540. return -ENODEV;
  541. return 0;
  542. }
  543. int intel_vsec_set_mapping(struct oobmsm_plat_info *plat_info,
  544. struct intel_vsec_device *vsec_dev)
  545. {
  546. struct vsec_priv *priv;
  547. priv = pci_get_drvdata(vsec_dev->pcidev);
  548. if (!priv)
  549. return -EINVAL;
  550. priv->plat_info = *plat_info;
  551. return 0;
  552. }
  553. EXPORT_SYMBOL_NS_GPL(intel_vsec_set_mapping, "INTEL_VSEC");
  554. struct oobmsm_plat_info *intel_vsec_get_mapping(struct pci_dev *pdev)
  555. {
  556. struct vsec_priv *priv;
  557. if (!pci_match_id(intel_vsec_pci_ids, pdev))
  558. return ERR_PTR(-EINVAL);
  559. priv = pci_get_drvdata(pdev);
  560. if (!priv)
  561. return ERR_PTR(-EINVAL);
  562. return &priv->plat_info;
  563. }
  564. EXPORT_SYMBOL_NS_GPL(intel_vsec_get_mapping, "INTEL_VSEC");
  565. /* DG1 info */
  566. static struct intel_vsec_header dg1_header = {
  567. .length = 0x10,
  568. .id = 2,
  569. .num_entries = 1,
  570. .entry_size = 3,
  571. .tbir = 0,
  572. .offset = 0x466000,
  573. };
  574. static struct intel_vsec_header *dg1_headers[] = {
  575. &dg1_header,
  576. NULL
  577. };
  578. static const struct intel_vsec_platform_info dg1_info = {
  579. .caps = VSEC_CAP_TELEMETRY,
  580. .headers = dg1_headers,
  581. .quirks = VSEC_QUIRK_NO_DVSEC | VSEC_QUIRK_EARLY_HW,
  582. };
  583. /* MTL info */
  584. static const struct intel_vsec_platform_info mtl_info = {
  585. .caps = VSEC_CAP_TELEMETRY,
  586. };
  587. static const struct vsec_feature_dependency oobmsm_deps[] = {
  588. {
  589. .feature = VSEC_CAP_TELEMETRY,
  590. .supplier_bitmap = VSEC_CAP_DISCOVERY | VSEC_CAP_TPMI,
  591. },
  592. };
  593. /* OOBMSM info */
  594. static const struct intel_vsec_platform_info oobmsm_info = {
  595. .caps = VSEC_CAP_TELEMETRY | VSEC_CAP_SDSI | VSEC_CAP_TPMI |
  596. VSEC_CAP_DISCOVERY,
  597. .deps = oobmsm_deps,
  598. .num_deps = ARRAY_SIZE(oobmsm_deps),
  599. };
  600. /* DMR OOBMSM info */
  601. static const struct intel_vsec_platform_info dmr_oobmsm_info = {
  602. .caps = VSEC_CAP_TELEMETRY | VSEC_CAP_TPMI | VSEC_CAP_DISCOVERY,
  603. .deps = oobmsm_deps,
  604. .num_deps = ARRAY_SIZE(oobmsm_deps),
  605. };
  606. /* TGL info */
  607. static const struct intel_vsec_platform_info tgl_info = {
  608. .caps = VSEC_CAP_TELEMETRY,
  609. .quirks = VSEC_QUIRK_TABLE_SHIFT | VSEC_QUIRK_EARLY_HW,
  610. };
  611. /* LNL info */
  612. static const struct intel_vsec_platform_info lnl_info = {
  613. .caps = VSEC_CAP_TELEMETRY | VSEC_CAP_WATCHER,
  614. };
  615. #define PCI_DEVICE_ID_INTEL_VSEC_ADL 0x467d
  616. #define PCI_DEVICE_ID_INTEL_VSEC_DG1 0x490e
  617. #define PCI_DEVICE_ID_INTEL_VSEC_MTL_M 0x7d0d
  618. #define PCI_DEVICE_ID_INTEL_VSEC_MTL_S 0xad0d
  619. #define PCI_DEVICE_ID_INTEL_VSEC_OOBMSM 0x09a7
  620. #define PCI_DEVICE_ID_INTEL_VSEC_OOBMSM_DMR 0x09a1
  621. #define PCI_DEVICE_ID_INTEL_VSEC_RPL 0xa77d
  622. #define PCI_DEVICE_ID_INTEL_VSEC_TGL 0x9a0d
  623. #define PCI_DEVICE_ID_INTEL_VSEC_LNL_M 0x647d
  624. #define PCI_DEVICE_ID_INTEL_VSEC_PTL 0xb07d
  625. #define PCI_DEVICE_ID_INTEL_VSEC_WCL 0xfd7d
  626. #define PCI_DEVICE_ID_INTEL_VSEC_NVL 0xd70d
  627. static const struct pci_device_id intel_vsec_pci_ids[] = {
  628. { PCI_DEVICE_DATA(INTEL, VSEC_ADL, &tgl_info) },
  629. { PCI_DEVICE_DATA(INTEL, VSEC_DG1, &dg1_info) },
  630. { PCI_DEVICE_DATA(INTEL, VSEC_MTL_M, &mtl_info) },
  631. { PCI_DEVICE_DATA(INTEL, VSEC_MTL_S, &mtl_info) },
  632. { PCI_DEVICE_DATA(INTEL, VSEC_OOBMSM, &oobmsm_info) },
  633. { PCI_DEVICE_DATA(INTEL, VSEC_OOBMSM_DMR, &dmr_oobmsm_info) },
  634. { PCI_DEVICE_DATA(INTEL, VSEC_RPL, &tgl_info) },
  635. { PCI_DEVICE_DATA(INTEL, VSEC_TGL, &tgl_info) },
  636. { PCI_DEVICE_DATA(INTEL, VSEC_LNL_M, &lnl_info) },
  637. { PCI_DEVICE_DATA(INTEL, VSEC_PTL, &mtl_info) },
  638. { PCI_DEVICE_DATA(INTEL, VSEC_WCL, &mtl_info) },
  639. { PCI_DEVICE_DATA(INTEL, VSEC_NVL, &mtl_info) },
  640. { }
  641. };
  642. MODULE_DEVICE_TABLE(pci, intel_vsec_pci_ids);
  643. static pci_ers_result_t intel_vsec_pci_error_detected(struct pci_dev *pdev,
  644. pci_channel_state_t state)
  645. {
  646. pci_ers_result_t status = PCI_ERS_RESULT_NEED_RESET;
  647. dev_info(&pdev->dev, "PCI error detected, state %d", state);
  648. if (state == pci_channel_io_perm_failure)
  649. status = PCI_ERS_RESULT_DISCONNECT;
  650. else
  651. pci_disable_device(pdev);
  652. return status;
  653. }
  654. static pci_ers_result_t intel_vsec_pci_slot_reset(struct pci_dev *pdev)
  655. {
  656. struct intel_vsec_device *intel_vsec_dev;
  657. pci_ers_result_t status = PCI_ERS_RESULT_DISCONNECT;
  658. const struct pci_device_id *pci_dev_id;
  659. unsigned long index;
  660. dev_info(&pdev->dev, "Resetting PCI slot\n");
  661. msleep(2000);
  662. if (pci_enable_device(pdev)) {
  663. dev_info(&pdev->dev,
  664. "Failed to re-enable PCI device after reset.\n");
  665. goto out;
  666. }
  667. status = PCI_ERS_RESULT_RECOVERED;
  668. xa_for_each(&auxdev_array, index, intel_vsec_dev) {
  669. /* check if pdev doesn't match */
  670. if (pdev != intel_vsec_dev->pcidev)
  671. continue;
  672. devm_release_action(&pdev->dev, intel_vsec_remove_aux,
  673. &intel_vsec_dev->auxdev);
  674. }
  675. pci_disable_device(pdev);
  676. pci_restore_state(pdev);
  677. pci_dev_id = pci_match_id(intel_vsec_pci_ids, pdev);
  678. intel_vsec_pci_probe(pdev, pci_dev_id);
  679. out:
  680. return status;
  681. }
  682. static void intel_vsec_pci_resume(struct pci_dev *pdev)
  683. {
  684. dev_info(&pdev->dev, "Done resuming PCI device\n");
  685. }
  686. static const struct pci_error_handlers intel_vsec_pci_err_handlers = {
  687. .error_detected = intel_vsec_pci_error_detected,
  688. .slot_reset = intel_vsec_pci_slot_reset,
  689. .resume = intel_vsec_pci_resume,
  690. };
  691. static struct pci_driver intel_vsec_pci_driver = {
  692. .name = "intel_vsec",
  693. .id_table = intel_vsec_pci_ids,
  694. .probe = intel_vsec_pci_probe,
  695. .err_handler = &intel_vsec_pci_err_handlers,
  696. };
  697. module_pci_driver(intel_vsec_pci_driver);
  698. MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
  699. MODULE_DESCRIPTION("Intel Extended Capabilities auxiliary bus driver");
  700. MODULE_LICENSE("GPL v2");