dfl.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Driver for FPGA Device Feature List (DFL) Support
  4. *
  5. * Copyright (C) 2017-2018 Intel Corporation, Inc.
  6. *
  7. * Authors:
  8. * Kang Luwei <luwei.kang@intel.com>
  9. * Zhang Yi <yi.z.zhang@intel.com>
  10. * Wu Hao <hao.wu@intel.com>
  11. * Xiao Guangrong <guangrong.xiao@linux.intel.com>
  12. */
  13. #include <linux/module.h>
  14. #include "dfl.h"
  15. static DEFINE_MUTEX(dfl_id_mutex);
  16. /*
  17. * when adding a new feature dev support in DFL framework, it's required to
  18. * add a new item in enum dfl_id_type and provide related information in below
  19. * dfl_devs table which is indexed by dfl_id_type, e.g. name string used for
  20. * platform device creation (define name strings in dfl.h, as they could be
  21. * reused by platform device drivers).
  22. *
  23. * if the new feature dev needs chardev support, then it's required to add
  24. * a new item in dfl_chardevs table and configure dfl_devs[i].devt_type as
  25. * index to dfl_chardevs table. If no chardev support just set devt_type
  26. * as one invalid index (DFL_FPGA_DEVT_MAX).
  27. */
  28. enum dfl_id_type {
  29. FME_ID, /* fme id allocation and mapping */
  30. PORT_ID, /* port id allocation and mapping */
  31. DFL_ID_MAX,
  32. };
  33. enum dfl_fpga_devt_type {
  34. DFL_FPGA_DEVT_FME,
  35. DFL_FPGA_DEVT_PORT,
  36. DFL_FPGA_DEVT_MAX,
  37. };
  38. static struct lock_class_key dfl_pdata_keys[DFL_ID_MAX];
  39. static const char *dfl_pdata_key_strings[DFL_ID_MAX] = {
  40. "dfl-fme-pdata",
  41. "dfl-port-pdata",
  42. };
  43. /**
  44. * dfl_dev_info - dfl feature device information.
  45. * @name: name string of the feature platform device.
  46. * @dfh_id: id value in Device Feature Header (DFH) register by DFL spec.
  47. * @id: idr id of the feature dev.
  48. * @devt_type: index to dfl_chrdevs[].
  49. */
  50. struct dfl_dev_info {
  51. const char *name;
  52. u32 dfh_id;
  53. struct idr id;
  54. enum dfl_fpga_devt_type devt_type;
  55. };
  56. /* it is indexed by dfl_id_type */
  57. static struct dfl_dev_info dfl_devs[] = {
  58. {.name = DFL_FPGA_FEATURE_DEV_FME, .dfh_id = DFH_ID_FIU_FME,
  59. .devt_type = DFL_FPGA_DEVT_FME},
  60. {.name = DFL_FPGA_FEATURE_DEV_PORT, .dfh_id = DFH_ID_FIU_PORT,
  61. .devt_type = DFL_FPGA_DEVT_PORT},
  62. };
  63. /**
  64. * dfl_chardev_info - chardev information of dfl feature device
  65. * @name: nmae string of the char device.
  66. * @devt: devt of the char device.
  67. */
  68. struct dfl_chardev_info {
  69. const char *name;
  70. dev_t devt;
  71. };
  72. /* indexed by enum dfl_fpga_devt_type */
  73. static struct dfl_chardev_info dfl_chrdevs[] = {
  74. {.name = DFL_FPGA_FEATURE_DEV_FME},
  75. {.name = DFL_FPGA_FEATURE_DEV_PORT},
  76. };
  77. static void dfl_ids_init(void)
  78. {
  79. int i;
  80. for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
  81. idr_init(&dfl_devs[i].id);
  82. }
  83. static void dfl_ids_destroy(void)
  84. {
  85. int i;
  86. for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
  87. idr_destroy(&dfl_devs[i].id);
  88. }
  89. static int dfl_id_alloc(enum dfl_id_type type, struct device *dev)
  90. {
  91. int id;
  92. WARN_ON(type >= DFL_ID_MAX);
  93. mutex_lock(&dfl_id_mutex);
  94. id = idr_alloc(&dfl_devs[type].id, dev, 0, 0, GFP_KERNEL);
  95. mutex_unlock(&dfl_id_mutex);
  96. return id;
  97. }
  98. static void dfl_id_free(enum dfl_id_type type, int id)
  99. {
  100. WARN_ON(type >= DFL_ID_MAX);
  101. mutex_lock(&dfl_id_mutex);
  102. idr_remove(&dfl_devs[type].id, id);
  103. mutex_unlock(&dfl_id_mutex);
  104. }
  105. static enum dfl_id_type feature_dev_id_type(struct platform_device *pdev)
  106. {
  107. int i;
  108. for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
  109. if (!strcmp(dfl_devs[i].name, pdev->name))
  110. return i;
  111. return DFL_ID_MAX;
  112. }
  113. static enum dfl_id_type dfh_id_to_type(u32 id)
  114. {
  115. int i;
  116. for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
  117. if (dfl_devs[i].dfh_id == id)
  118. return i;
  119. return DFL_ID_MAX;
  120. }
  121. /*
  122. * introduce a global port_ops list, it allows port drivers to register ops
  123. * in such list, then other feature devices (e.g. FME), could use the port
  124. * functions even related port platform device is hidden. Below is one example,
  125. * in virtualization case of PCIe-based FPGA DFL device, when SRIOV is
  126. * enabled, port (and it's AFU) is turned into VF and port platform device
  127. * is hidden from system but it's still required to access port to finish FPGA
  128. * reconfiguration function in FME.
  129. */
  130. static DEFINE_MUTEX(dfl_port_ops_mutex);
  131. static LIST_HEAD(dfl_port_ops_list);
  132. /**
  133. * dfl_fpga_port_ops_get - get matched port ops from the global list
  134. * @pdev: platform device to match with associated port ops.
  135. * Return: matched port ops on success, NULL otherwise.
  136. *
  137. * Please note that must dfl_fpga_port_ops_put after use the port_ops.
  138. */
  139. struct dfl_fpga_port_ops *dfl_fpga_port_ops_get(struct platform_device *pdev)
  140. {
  141. struct dfl_fpga_port_ops *ops = NULL;
  142. mutex_lock(&dfl_port_ops_mutex);
  143. if (list_empty(&dfl_port_ops_list))
  144. goto done;
  145. list_for_each_entry(ops, &dfl_port_ops_list, node) {
  146. /* match port_ops using the name of platform device */
  147. if (!strcmp(pdev->name, ops->name)) {
  148. if (!try_module_get(ops->owner))
  149. ops = NULL;
  150. goto done;
  151. }
  152. }
  153. ops = NULL;
  154. done:
  155. mutex_unlock(&dfl_port_ops_mutex);
  156. return ops;
  157. }
  158. EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_get);
  159. /**
  160. * dfl_fpga_port_ops_put - put port ops
  161. * @ops: port ops.
  162. */
  163. void dfl_fpga_port_ops_put(struct dfl_fpga_port_ops *ops)
  164. {
  165. if (ops && ops->owner)
  166. module_put(ops->owner);
  167. }
  168. EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_put);
  169. /**
  170. * dfl_fpga_port_ops_add - add port_ops to global list
  171. * @ops: port ops to add.
  172. */
  173. void dfl_fpga_port_ops_add(struct dfl_fpga_port_ops *ops)
  174. {
  175. mutex_lock(&dfl_port_ops_mutex);
  176. list_add_tail(&ops->node, &dfl_port_ops_list);
  177. mutex_unlock(&dfl_port_ops_mutex);
  178. }
  179. EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_add);
  180. /**
  181. * dfl_fpga_port_ops_del - remove port_ops from global list
  182. * @ops: port ops to del.
  183. */
  184. void dfl_fpga_port_ops_del(struct dfl_fpga_port_ops *ops)
  185. {
  186. mutex_lock(&dfl_port_ops_mutex);
  187. list_del(&ops->node);
  188. mutex_unlock(&dfl_port_ops_mutex);
  189. }
  190. EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_del);
  191. /**
  192. * dfl_fpga_check_port_id - check the port id
  193. * @pdev: port platform device.
  194. * @pport_id: port id to compare.
  195. *
  196. * Return: 1 if port device matches with given port id, otherwise 0.
  197. */
  198. int dfl_fpga_check_port_id(struct platform_device *pdev, void *pport_id)
  199. {
  200. struct dfl_fpga_port_ops *port_ops = dfl_fpga_port_ops_get(pdev);
  201. int port_id;
  202. if (!port_ops || !port_ops->get_id)
  203. return 0;
  204. port_id = port_ops->get_id(pdev);
  205. dfl_fpga_port_ops_put(port_ops);
  206. return port_id == *(int *)pport_id;
  207. }
  208. EXPORT_SYMBOL_GPL(dfl_fpga_check_port_id);
  209. /**
  210. * dfl_fpga_dev_feature_uinit - uinit for sub features of dfl feature device
  211. * @pdev: feature device.
  212. */
  213. void dfl_fpga_dev_feature_uinit(struct platform_device *pdev)
  214. {
  215. struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
  216. struct dfl_feature *feature;
  217. dfl_fpga_dev_for_each_feature(pdata, feature)
  218. if (feature->ops) {
  219. feature->ops->uinit(pdev, feature);
  220. feature->ops = NULL;
  221. }
  222. }
  223. EXPORT_SYMBOL_GPL(dfl_fpga_dev_feature_uinit);
  224. static int dfl_feature_instance_init(struct platform_device *pdev,
  225. struct dfl_feature_platform_data *pdata,
  226. struct dfl_feature *feature,
  227. struct dfl_feature_driver *drv)
  228. {
  229. int ret;
  230. ret = drv->ops->init(pdev, feature);
  231. if (ret)
  232. return ret;
  233. feature->ops = drv->ops;
  234. return ret;
  235. }
  236. /**
  237. * dfl_fpga_dev_feature_init - init for sub features of dfl feature device
  238. * @pdev: feature device.
  239. * @feature_drvs: drvs for sub features.
  240. *
  241. * This function will match sub features with given feature drvs list and
  242. * use matched drv to init related sub feature.
  243. *
  244. * Return: 0 on success, negative error code otherwise.
  245. */
  246. int dfl_fpga_dev_feature_init(struct platform_device *pdev,
  247. struct dfl_feature_driver *feature_drvs)
  248. {
  249. struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
  250. struct dfl_feature_driver *drv = feature_drvs;
  251. struct dfl_feature *feature;
  252. int ret;
  253. while (drv->ops) {
  254. dfl_fpga_dev_for_each_feature(pdata, feature) {
  255. /* match feature and drv using id */
  256. if (feature->id == drv->id) {
  257. ret = dfl_feature_instance_init(pdev, pdata,
  258. feature, drv);
  259. if (ret)
  260. goto exit;
  261. }
  262. }
  263. drv++;
  264. }
  265. return 0;
  266. exit:
  267. dfl_fpga_dev_feature_uinit(pdev);
  268. return ret;
  269. }
  270. EXPORT_SYMBOL_GPL(dfl_fpga_dev_feature_init);
  271. static void dfl_chardev_uinit(void)
  272. {
  273. int i;
  274. for (i = 0; i < DFL_FPGA_DEVT_MAX; i++)
  275. if (MAJOR(dfl_chrdevs[i].devt)) {
  276. unregister_chrdev_region(dfl_chrdevs[i].devt,
  277. MINORMASK);
  278. dfl_chrdevs[i].devt = MKDEV(0, 0);
  279. }
  280. }
  281. static int dfl_chardev_init(void)
  282. {
  283. int i, ret;
  284. for (i = 0; i < DFL_FPGA_DEVT_MAX; i++) {
  285. ret = alloc_chrdev_region(&dfl_chrdevs[i].devt, 0, MINORMASK,
  286. dfl_chrdevs[i].name);
  287. if (ret)
  288. goto exit;
  289. }
  290. return 0;
  291. exit:
  292. dfl_chardev_uinit();
  293. return ret;
  294. }
  295. static dev_t dfl_get_devt(enum dfl_fpga_devt_type type, int id)
  296. {
  297. if (type >= DFL_FPGA_DEVT_MAX)
  298. return 0;
  299. return MKDEV(MAJOR(dfl_chrdevs[type].devt), id);
  300. }
  301. /**
  302. * dfl_fpga_dev_ops_register - register cdev ops for feature dev
  303. *
  304. * @pdev: feature dev.
  305. * @fops: file operations for feature dev's cdev.
  306. * @owner: owning module/driver.
  307. *
  308. * Return: 0 on success, negative error code otherwise.
  309. */
  310. int dfl_fpga_dev_ops_register(struct platform_device *pdev,
  311. const struct file_operations *fops,
  312. struct module *owner)
  313. {
  314. struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
  315. cdev_init(&pdata->cdev, fops);
  316. pdata->cdev.owner = owner;
  317. /*
  318. * set parent to the feature device so that its refcount is
  319. * decreased after the last refcount of cdev is gone, that
  320. * makes sure the feature device is valid during device
  321. * file's life-cycle.
  322. */
  323. pdata->cdev.kobj.parent = &pdev->dev.kobj;
  324. return cdev_add(&pdata->cdev, pdev->dev.devt, 1);
  325. }
  326. EXPORT_SYMBOL_GPL(dfl_fpga_dev_ops_register);
  327. /**
  328. * dfl_fpga_dev_ops_unregister - unregister cdev ops for feature dev
  329. * @pdev: feature dev.
  330. */
  331. void dfl_fpga_dev_ops_unregister(struct platform_device *pdev)
  332. {
  333. struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
  334. cdev_del(&pdata->cdev);
  335. }
  336. EXPORT_SYMBOL_GPL(dfl_fpga_dev_ops_unregister);
  337. /**
  338. * struct build_feature_devs_info - info collected during feature dev build.
  339. *
  340. * @dev: device to enumerate.
  341. * @cdev: the container device for all feature devices.
  342. * @feature_dev: current feature device.
  343. * @ioaddr: header register region address of feature device in enumeration.
  344. * @sub_features: a sub features linked list for feature device in enumeration.
  345. * @feature_num: number of sub features for feature device in enumeration.
  346. */
  347. struct build_feature_devs_info {
  348. struct device *dev;
  349. struct dfl_fpga_cdev *cdev;
  350. struct platform_device *feature_dev;
  351. void __iomem *ioaddr;
  352. struct list_head sub_features;
  353. int feature_num;
  354. };
  355. /**
  356. * struct dfl_feature_info - sub feature info collected during feature dev build
  357. *
  358. * @fid: id of this sub feature.
  359. * @mmio_res: mmio resource of this sub feature.
  360. * @ioaddr: mapped base address of mmio resource.
  361. * @node: node in sub_features linked list.
  362. */
  363. struct dfl_feature_info {
  364. u64 fid;
  365. struct resource mmio_res;
  366. void __iomem *ioaddr;
  367. struct list_head node;
  368. };
  369. static void dfl_fpga_cdev_add_port_dev(struct dfl_fpga_cdev *cdev,
  370. struct platform_device *port)
  371. {
  372. struct dfl_feature_platform_data *pdata = dev_get_platdata(&port->dev);
  373. mutex_lock(&cdev->lock);
  374. list_add(&pdata->node, &cdev->port_dev_list);
  375. get_device(&pdata->dev->dev);
  376. mutex_unlock(&cdev->lock);
  377. }
  378. /*
  379. * register current feature device, it is called when we need to switch to
  380. * another feature parsing or we have parsed all features on given device
  381. * feature list.
  382. */
  383. static int build_info_commit_dev(struct build_feature_devs_info *binfo)
  384. {
  385. struct platform_device *fdev = binfo->feature_dev;
  386. struct dfl_feature_platform_data *pdata;
  387. struct dfl_feature_info *finfo, *p;
  388. enum dfl_id_type type;
  389. int ret, index = 0;
  390. if (!fdev)
  391. return 0;
  392. type = feature_dev_id_type(fdev);
  393. if (WARN_ON_ONCE(type >= DFL_ID_MAX))
  394. return -EINVAL;
  395. /*
  396. * we do not need to care for the memory which is associated with
  397. * the platform device. After calling platform_device_unregister(),
  398. * it will be automatically freed by device's release() callback,
  399. * platform_device_release().
  400. */
  401. pdata = kzalloc(dfl_feature_platform_data_size(binfo->feature_num),
  402. GFP_KERNEL);
  403. if (!pdata)
  404. return -ENOMEM;
  405. pdata->dev = fdev;
  406. pdata->num = binfo->feature_num;
  407. pdata->dfl_cdev = binfo->cdev;
  408. mutex_init(&pdata->lock);
  409. lockdep_set_class_and_name(&pdata->lock, &dfl_pdata_keys[type],
  410. dfl_pdata_key_strings[type]);
  411. /*
  412. * the count should be initialized to 0 to make sure
  413. *__fpga_port_enable() following __fpga_port_disable()
  414. * works properly for port device.
  415. * and it should always be 0 for fme device.
  416. */
  417. WARN_ON(pdata->disable_count);
  418. fdev->dev.platform_data = pdata;
  419. /* each sub feature has one MMIO resource */
  420. fdev->num_resources = binfo->feature_num;
  421. fdev->resource = kcalloc(binfo->feature_num, sizeof(*fdev->resource),
  422. GFP_KERNEL);
  423. if (!fdev->resource)
  424. return -ENOMEM;
  425. /* fill features and resource information for feature dev */
  426. list_for_each_entry_safe(finfo, p, &binfo->sub_features, node) {
  427. struct dfl_feature *feature = &pdata->features[index];
  428. /* save resource information for each feature */
  429. feature->id = finfo->fid;
  430. feature->resource_index = index;
  431. feature->ioaddr = finfo->ioaddr;
  432. fdev->resource[index++] = finfo->mmio_res;
  433. list_del(&finfo->node);
  434. kfree(finfo);
  435. }
  436. ret = platform_device_add(binfo->feature_dev);
  437. if (!ret) {
  438. if (type == PORT_ID)
  439. dfl_fpga_cdev_add_port_dev(binfo->cdev,
  440. binfo->feature_dev);
  441. else
  442. binfo->cdev->fme_dev =
  443. get_device(&binfo->feature_dev->dev);
  444. /*
  445. * reset it to avoid build_info_free() freeing their resource.
  446. *
  447. * The resource of successfully registered feature devices
  448. * will be freed by platform_device_unregister(). See the
  449. * comments in build_info_create_dev().
  450. */
  451. binfo->feature_dev = NULL;
  452. }
  453. return ret;
  454. }
  455. static int
  456. build_info_create_dev(struct build_feature_devs_info *binfo,
  457. enum dfl_id_type type, void __iomem *ioaddr)
  458. {
  459. struct platform_device *fdev;
  460. int ret;
  461. if (type >= DFL_ID_MAX)
  462. return -EINVAL;
  463. /* we will create a new device, commit current device first */
  464. ret = build_info_commit_dev(binfo);
  465. if (ret)
  466. return ret;
  467. /*
  468. * we use -ENODEV as the initialization indicator which indicates
  469. * whether the id need to be reclaimed
  470. */
  471. fdev = platform_device_alloc(dfl_devs[type].name, -ENODEV);
  472. if (!fdev)
  473. return -ENOMEM;
  474. binfo->feature_dev = fdev;
  475. binfo->feature_num = 0;
  476. binfo->ioaddr = ioaddr;
  477. INIT_LIST_HEAD(&binfo->sub_features);
  478. fdev->id = dfl_id_alloc(type, &fdev->dev);
  479. if (fdev->id < 0)
  480. return fdev->id;
  481. fdev->dev.parent = &binfo->cdev->region->dev;
  482. fdev->dev.devt = dfl_get_devt(dfl_devs[type].devt_type, fdev->id);
  483. return 0;
  484. }
  485. static void build_info_free(struct build_feature_devs_info *binfo)
  486. {
  487. struct dfl_feature_info *finfo, *p;
  488. /*
  489. * it is a valid id, free it. See comments in
  490. * build_info_create_dev()
  491. */
  492. if (binfo->feature_dev && binfo->feature_dev->id >= 0) {
  493. dfl_id_free(feature_dev_id_type(binfo->feature_dev),
  494. binfo->feature_dev->id);
  495. list_for_each_entry_safe(finfo, p, &binfo->sub_features, node) {
  496. list_del(&finfo->node);
  497. kfree(finfo);
  498. }
  499. }
  500. platform_device_put(binfo->feature_dev);
  501. devm_kfree(binfo->dev, binfo);
  502. }
  503. static inline u32 feature_size(void __iomem *start)
  504. {
  505. u64 v = readq(start + DFH);
  506. u32 ofst = FIELD_GET(DFH_NEXT_HDR_OFST, v);
  507. /* workaround for private features with invalid size, use 4K instead */
  508. return ofst ? ofst : 4096;
  509. }
  510. static u64 feature_id(void __iomem *start)
  511. {
  512. u64 v = readq(start + DFH);
  513. u16 id = FIELD_GET(DFH_ID, v);
  514. u8 type = FIELD_GET(DFH_TYPE, v);
  515. if (type == DFH_TYPE_FIU)
  516. return FEATURE_ID_FIU_HEADER;
  517. else if (type == DFH_TYPE_PRIVATE)
  518. return id;
  519. else if (type == DFH_TYPE_AFU)
  520. return FEATURE_ID_AFU;
  521. WARN_ON(1);
  522. return 0;
  523. }
  524. /*
  525. * when create sub feature instances, for private features, it doesn't need
  526. * to provide resource size and feature id as they could be read from DFH
  527. * register. For afu sub feature, its register region only contains user
  528. * defined registers, so never trust any information from it, just use the
  529. * resource size information provided by its parent FIU.
  530. */
  531. static int
  532. create_feature_instance(struct build_feature_devs_info *binfo,
  533. struct dfl_fpga_enum_dfl *dfl, resource_size_t ofst,
  534. resource_size_t size, u64 fid)
  535. {
  536. struct dfl_feature_info *finfo;
  537. /* read feature size and id if inputs are invalid */
  538. size = size ? size : feature_size(dfl->ioaddr + ofst);
  539. fid = fid ? fid : feature_id(dfl->ioaddr + ofst);
  540. if (dfl->len - ofst < size)
  541. return -EINVAL;
  542. finfo = kzalloc(sizeof(*finfo), GFP_KERNEL);
  543. if (!finfo)
  544. return -ENOMEM;
  545. finfo->fid = fid;
  546. finfo->mmio_res.start = dfl->start + ofst;
  547. finfo->mmio_res.end = finfo->mmio_res.start + size - 1;
  548. finfo->mmio_res.flags = IORESOURCE_MEM;
  549. finfo->ioaddr = dfl->ioaddr + ofst;
  550. list_add_tail(&finfo->node, &binfo->sub_features);
  551. binfo->feature_num++;
  552. return 0;
  553. }
  554. static int parse_feature_port_afu(struct build_feature_devs_info *binfo,
  555. struct dfl_fpga_enum_dfl *dfl,
  556. resource_size_t ofst)
  557. {
  558. u64 v = readq(binfo->ioaddr + PORT_HDR_CAP);
  559. u32 size = FIELD_GET(PORT_CAP_MMIO_SIZE, v) << 10;
  560. WARN_ON(!size);
  561. return create_feature_instance(binfo, dfl, ofst, size, FEATURE_ID_AFU);
  562. }
  563. static int parse_feature_afu(struct build_feature_devs_info *binfo,
  564. struct dfl_fpga_enum_dfl *dfl,
  565. resource_size_t ofst)
  566. {
  567. if (!binfo->feature_dev) {
  568. dev_err(binfo->dev, "this AFU does not belong to any FIU.\n");
  569. return -EINVAL;
  570. }
  571. switch (feature_dev_id_type(binfo->feature_dev)) {
  572. case PORT_ID:
  573. return parse_feature_port_afu(binfo, dfl, ofst);
  574. default:
  575. dev_info(binfo->dev, "AFU belonging to FIU %s is not supported yet.\n",
  576. binfo->feature_dev->name);
  577. }
  578. return 0;
  579. }
  580. static int parse_feature_fiu(struct build_feature_devs_info *binfo,
  581. struct dfl_fpga_enum_dfl *dfl,
  582. resource_size_t ofst)
  583. {
  584. u32 id, offset;
  585. u64 v;
  586. int ret = 0;
  587. v = readq(dfl->ioaddr + ofst + DFH);
  588. id = FIELD_GET(DFH_ID, v);
  589. /* create platform device for dfl feature dev */
  590. ret = build_info_create_dev(binfo, dfh_id_to_type(id),
  591. dfl->ioaddr + ofst);
  592. if (ret)
  593. return ret;
  594. ret = create_feature_instance(binfo, dfl, ofst, 0, 0);
  595. if (ret)
  596. return ret;
  597. /*
  598. * find and parse FIU's child AFU via its NEXT_AFU register.
  599. * please note that only Port has valid NEXT_AFU pointer per spec.
  600. */
  601. v = readq(dfl->ioaddr + ofst + NEXT_AFU);
  602. offset = FIELD_GET(NEXT_AFU_NEXT_DFH_OFST, v);
  603. if (offset)
  604. return parse_feature_afu(binfo, dfl, ofst + offset);
  605. dev_dbg(binfo->dev, "No AFUs detected on FIU %d\n", id);
  606. return ret;
  607. }
  608. static int parse_feature_private(struct build_feature_devs_info *binfo,
  609. struct dfl_fpga_enum_dfl *dfl,
  610. resource_size_t ofst)
  611. {
  612. if (!binfo->feature_dev) {
  613. dev_err(binfo->dev, "the private feature %llx does not belong to any AFU.\n",
  614. (unsigned long long)feature_id(dfl->ioaddr + ofst));
  615. return -EINVAL;
  616. }
  617. return create_feature_instance(binfo, dfl, ofst, 0, 0);
  618. }
  619. /**
  620. * parse_feature - parse a feature on given device feature list
  621. *
  622. * @binfo: build feature devices information.
  623. * @dfl: device feature list to parse
  624. * @ofst: offset to feature header on this device feature list
  625. */
  626. static int parse_feature(struct build_feature_devs_info *binfo,
  627. struct dfl_fpga_enum_dfl *dfl, resource_size_t ofst)
  628. {
  629. u64 v;
  630. u32 type;
  631. v = readq(dfl->ioaddr + ofst + DFH);
  632. type = FIELD_GET(DFH_TYPE, v);
  633. switch (type) {
  634. case DFH_TYPE_AFU:
  635. return parse_feature_afu(binfo, dfl, ofst);
  636. case DFH_TYPE_PRIVATE:
  637. return parse_feature_private(binfo, dfl, ofst);
  638. case DFH_TYPE_FIU:
  639. return parse_feature_fiu(binfo, dfl, ofst);
  640. default:
  641. dev_info(binfo->dev,
  642. "Feature Type %x is not supported.\n", type);
  643. }
  644. return 0;
  645. }
  646. static int parse_feature_list(struct build_feature_devs_info *binfo,
  647. struct dfl_fpga_enum_dfl *dfl)
  648. {
  649. void __iomem *start = dfl->ioaddr;
  650. void __iomem *end = dfl->ioaddr + dfl->len;
  651. int ret = 0;
  652. u32 ofst = 0;
  653. u64 v;
  654. /* walk through the device feature list via DFH's next DFH pointer. */
  655. for (; start < end; start += ofst) {
  656. if (end - start < DFH_SIZE) {
  657. dev_err(binfo->dev, "The region is too small to contain a feature.\n");
  658. return -EINVAL;
  659. }
  660. ret = parse_feature(binfo, dfl, start - dfl->ioaddr);
  661. if (ret)
  662. return ret;
  663. v = readq(start + DFH);
  664. ofst = FIELD_GET(DFH_NEXT_HDR_OFST, v);
  665. /* stop parsing if EOL(End of List) is set or offset is 0 */
  666. if ((v & DFH_EOL) || !ofst)
  667. break;
  668. }
  669. /* commit current feature device when reach the end of list */
  670. return build_info_commit_dev(binfo);
  671. }
  672. struct dfl_fpga_enum_info *dfl_fpga_enum_info_alloc(struct device *dev)
  673. {
  674. struct dfl_fpga_enum_info *info;
  675. get_device(dev);
  676. info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
  677. if (!info) {
  678. put_device(dev);
  679. return NULL;
  680. }
  681. info->dev = dev;
  682. INIT_LIST_HEAD(&info->dfls);
  683. return info;
  684. }
  685. EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_alloc);
  686. void dfl_fpga_enum_info_free(struct dfl_fpga_enum_info *info)
  687. {
  688. struct dfl_fpga_enum_dfl *tmp, *dfl;
  689. struct device *dev;
  690. if (!info)
  691. return;
  692. dev = info->dev;
  693. /* remove all device feature lists in the list. */
  694. list_for_each_entry_safe(dfl, tmp, &info->dfls, node) {
  695. list_del(&dfl->node);
  696. devm_kfree(dev, dfl);
  697. }
  698. devm_kfree(dev, info);
  699. put_device(dev);
  700. }
  701. EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_free);
  702. /**
  703. * dfl_fpga_enum_info_add_dfl - add info of a device feature list to enum info
  704. *
  705. * @info: ptr to dfl_fpga_enum_info
  706. * @start: mmio resource address of the device feature list.
  707. * @len: mmio resource length of the device feature list.
  708. * @ioaddr: mapped mmio resource address of the device feature list.
  709. *
  710. * One FPGA device may have one or more Device Feature Lists (DFLs), use this
  711. * function to add information of each DFL to common data structure for next
  712. * step enumeration.
  713. *
  714. * Return: 0 on success, negative error code otherwise.
  715. */
  716. int dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info *info,
  717. resource_size_t start, resource_size_t len,
  718. void __iomem *ioaddr)
  719. {
  720. struct dfl_fpga_enum_dfl *dfl;
  721. dfl = devm_kzalloc(info->dev, sizeof(*dfl), GFP_KERNEL);
  722. if (!dfl)
  723. return -ENOMEM;
  724. dfl->start = start;
  725. dfl->len = len;
  726. dfl->ioaddr = ioaddr;
  727. list_add_tail(&dfl->node, &info->dfls);
  728. return 0;
  729. }
  730. EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_add_dfl);
  731. static int remove_feature_dev(struct device *dev, void *data)
  732. {
  733. struct platform_device *pdev = to_platform_device(dev);
  734. enum dfl_id_type type = feature_dev_id_type(pdev);
  735. int id = pdev->id;
  736. platform_device_unregister(pdev);
  737. dfl_id_free(type, id);
  738. return 0;
  739. }
  740. static void remove_feature_devs(struct dfl_fpga_cdev *cdev)
  741. {
  742. device_for_each_child(&cdev->region->dev, NULL, remove_feature_dev);
  743. }
  744. /**
  745. * dfl_fpga_feature_devs_enumerate - enumerate feature devices
  746. * @info: information for enumeration.
  747. *
  748. * This function creates a container device (base FPGA region), enumerates
  749. * feature devices based on the enumeration info and creates platform devices
  750. * under the container device.
  751. *
  752. * Return: dfl_fpga_cdev struct on success, -errno on failure
  753. */
  754. struct dfl_fpga_cdev *
  755. dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info)
  756. {
  757. struct build_feature_devs_info *binfo;
  758. struct dfl_fpga_enum_dfl *dfl;
  759. struct dfl_fpga_cdev *cdev;
  760. int ret = 0;
  761. if (!info->dev)
  762. return ERR_PTR(-ENODEV);
  763. cdev = devm_kzalloc(info->dev, sizeof(*cdev), GFP_KERNEL);
  764. if (!cdev)
  765. return ERR_PTR(-ENOMEM);
  766. cdev->region = fpga_region_create(info->dev, NULL, NULL);
  767. if (!cdev->region) {
  768. ret = -ENOMEM;
  769. goto free_cdev_exit;
  770. }
  771. cdev->parent = info->dev;
  772. mutex_init(&cdev->lock);
  773. INIT_LIST_HEAD(&cdev->port_dev_list);
  774. ret = fpga_region_register(cdev->region);
  775. if (ret)
  776. goto free_region_exit;
  777. /* create and init build info for enumeration */
  778. binfo = devm_kzalloc(info->dev, sizeof(*binfo), GFP_KERNEL);
  779. if (!binfo) {
  780. ret = -ENOMEM;
  781. goto unregister_region_exit;
  782. }
  783. binfo->dev = info->dev;
  784. binfo->cdev = cdev;
  785. /*
  786. * start enumeration for all feature devices based on Device Feature
  787. * Lists.
  788. */
  789. list_for_each_entry(dfl, &info->dfls, node) {
  790. ret = parse_feature_list(binfo, dfl);
  791. if (ret) {
  792. remove_feature_devs(cdev);
  793. build_info_free(binfo);
  794. goto unregister_region_exit;
  795. }
  796. }
  797. build_info_free(binfo);
  798. return cdev;
  799. unregister_region_exit:
  800. fpga_region_unregister(cdev->region);
  801. free_region_exit:
  802. fpga_region_free(cdev->region);
  803. free_cdev_exit:
  804. devm_kfree(info->dev, cdev);
  805. return ERR_PTR(ret);
  806. }
  807. EXPORT_SYMBOL_GPL(dfl_fpga_feature_devs_enumerate);
  808. /**
  809. * dfl_fpga_feature_devs_remove - remove all feature devices
  810. * @cdev: fpga container device.
  811. *
  812. * Remove the container device and all feature devices under given container
  813. * devices.
  814. */
  815. void dfl_fpga_feature_devs_remove(struct dfl_fpga_cdev *cdev)
  816. {
  817. struct dfl_feature_platform_data *pdata, *ptmp;
  818. remove_feature_devs(cdev);
  819. mutex_lock(&cdev->lock);
  820. if (cdev->fme_dev) {
  821. /* the fme should be unregistered. */
  822. WARN_ON(device_is_registered(cdev->fme_dev));
  823. put_device(cdev->fme_dev);
  824. }
  825. list_for_each_entry_safe(pdata, ptmp, &cdev->port_dev_list, node) {
  826. struct platform_device *port_dev = pdata->dev;
  827. /* the port should be unregistered. */
  828. WARN_ON(device_is_registered(&port_dev->dev));
  829. list_del(&pdata->node);
  830. put_device(&port_dev->dev);
  831. }
  832. mutex_unlock(&cdev->lock);
  833. fpga_region_unregister(cdev->region);
  834. devm_kfree(cdev->parent, cdev);
  835. }
  836. EXPORT_SYMBOL_GPL(dfl_fpga_feature_devs_remove);
  837. /**
  838. * __dfl_fpga_cdev_find_port - find a port under given container device
  839. *
  840. * @cdev: container device
  841. * @data: data passed to match function
  842. * @match: match function used to find specific port from the port device list
  843. *
  844. * Find a port device under container device. This function needs to be
  845. * invoked with lock held.
  846. *
  847. * Return: pointer to port's platform device if successful, NULL otherwise.
  848. *
  849. * NOTE: you will need to drop the device reference with put_device() after use.
  850. */
  851. struct platform_device *
  852. __dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data,
  853. int (*match)(struct platform_device *, void *))
  854. {
  855. struct dfl_feature_platform_data *pdata;
  856. struct platform_device *port_dev;
  857. list_for_each_entry(pdata, &cdev->port_dev_list, node) {
  858. port_dev = pdata->dev;
  859. if (match(port_dev, data) && get_device(&port_dev->dev))
  860. return port_dev;
  861. }
  862. return NULL;
  863. }
  864. EXPORT_SYMBOL_GPL(__dfl_fpga_cdev_find_port);
  865. static int __init dfl_fpga_init(void)
  866. {
  867. int ret;
  868. dfl_ids_init();
  869. ret = dfl_chardev_init();
  870. if (ret)
  871. dfl_ids_destroy();
  872. return ret;
  873. }
  874. static void __exit dfl_fpga_exit(void)
  875. {
  876. dfl_chardev_uinit();
  877. dfl_ids_destroy();
  878. }
  879. module_init(dfl_fpga_init);
  880. module_exit(dfl_fpga_exit);
  881. MODULE_DESCRIPTION("FPGA Device Feature List (DFL) Support");
  882. MODULE_AUTHOR("Intel Corporation");
  883. MODULE_LICENSE("GPL v2");