xref: /openbmc/linux/drivers/fpga/dfl-afu-main.c (revision e72e8bf1)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Driver for FPGA Accelerated Function Unit (AFU)
4  *
5  * Copyright (C) 2017-2018 Intel Corporation, Inc.
6  *
7  * Authors:
8  *   Wu Hao <hao.wu@intel.com>
9  *   Xiao Guangrong <guangrong.xiao@linux.intel.com>
10  *   Joseph Grecco <joe.grecco@intel.com>
11  *   Enno Luebbers <enno.luebbers@intel.com>
12  *   Tim Whisonant <tim.whisonant@intel.com>
13  *   Ananda Ravuri <ananda.ravuri@intel.com>
14  *   Henry Mitchel <henry.mitchel@intel.com>
15  */
16 
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/uaccess.h>
20 #include <linux/fpga-dfl.h>
21 
22 #include "dfl-afu.h"
23 
24 /**
25  * __afu_port_enable - enable a port by clear reset
26  * @pdev: port platform device.
27  *
28  * Enable Port by clear the port soft reset bit, which is set by default.
29  * The AFU is unable to respond to any MMIO access while in reset.
30  * __afu_port_enable function should only be used after __afu_port_disable
31  * function.
32  *
33  * The caller needs to hold lock for protection.
34  */
35 void __afu_port_enable(struct platform_device *pdev)
36 {
37 	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
38 	void __iomem *base;
39 	u64 v;
40 
41 	WARN_ON(!pdata->disable_count);
42 
43 	if (--pdata->disable_count != 0)
44 		return;
45 
46 	base = dfl_get_feature_ioaddr_by_id(&pdev->dev, PORT_FEATURE_ID_HEADER);
47 
48 	/* Clear port soft reset */
49 	v = readq(base + PORT_HDR_CTRL);
50 	v &= ~PORT_CTRL_SFTRST;
51 	writeq(v, base + PORT_HDR_CTRL);
52 }
53 
54 #define RST_POLL_INVL 10 /* us */
55 #define RST_POLL_TIMEOUT 1000 /* us */
56 
57 /**
58  * __afu_port_disable - disable a port by hold reset
59  * @pdev: port platform device.
60  *
61  * Disable Port by setting the port soft reset bit, it puts the port into reset.
62  *
63  * The caller needs to hold lock for protection.
64  */
65 int __afu_port_disable(struct platform_device *pdev)
66 {
67 	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
68 	void __iomem *base;
69 	u64 v;
70 
71 	if (pdata->disable_count++ != 0)
72 		return 0;
73 
74 	base = dfl_get_feature_ioaddr_by_id(&pdev->dev, PORT_FEATURE_ID_HEADER);
75 
76 	/* Set port soft reset */
77 	v = readq(base + PORT_HDR_CTRL);
78 	v |= PORT_CTRL_SFTRST;
79 	writeq(v, base + PORT_HDR_CTRL);
80 
81 	/*
82 	 * HW sets ack bit to 1 when all outstanding requests have been drained
83 	 * on this port and minimum soft reset pulse width has elapsed.
84 	 * Driver polls port_soft_reset_ack to determine if reset done by HW.
85 	 */
86 	if (readq_poll_timeout(base + PORT_HDR_CTRL, v, v & PORT_CTRL_SFTRST,
87 			       RST_POLL_INVL, RST_POLL_TIMEOUT)) {
88 		dev_err(&pdev->dev, "timeout, fail to reset device\n");
89 		return -ETIMEDOUT;
90 	}
91 
92 	return 0;
93 }
94 
95 /*
96  * This function resets the FPGA Port and its accelerator (AFU) by function
97  * __port_disable and __port_enable (set port soft reset bit and then clear
98  * it). Userspace can do Port reset at any time, e.g. during DMA or Partial
99  * Reconfiguration. But it should never cause any system level issue, only
100  * functional failure (e.g. DMA or PR operation failure) and be recoverable
101  * from the failure.
102  *
103  * Note: the accelerator (AFU) is not accessible when its port is in reset
104  * (disabled). Any attempts on MMIO access to AFU while in reset, will
105  * result errors reported via port error reporting sub feature (if present).
106  */
107 static int __port_reset(struct platform_device *pdev)
108 {
109 	int ret;
110 
111 	ret = __afu_port_disable(pdev);
112 	if (!ret)
113 		__afu_port_enable(pdev);
114 
115 	return ret;
116 }
117 
118 static int port_reset(struct platform_device *pdev)
119 {
120 	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
121 	int ret;
122 
123 	mutex_lock(&pdata->lock);
124 	ret = __port_reset(pdev);
125 	mutex_unlock(&pdata->lock);
126 
127 	return ret;
128 }
129 
130 static int port_get_id(struct platform_device *pdev)
131 {
132 	void __iomem *base;
133 
134 	base = dfl_get_feature_ioaddr_by_id(&pdev->dev, PORT_FEATURE_ID_HEADER);
135 
136 	return FIELD_GET(PORT_CAP_PORT_NUM, readq(base + PORT_HDR_CAP));
137 }
138 
139 static ssize_t
140 id_show(struct device *dev, struct device_attribute *attr, char *buf)
141 {
142 	int id = port_get_id(to_platform_device(dev));
143 
144 	return scnprintf(buf, PAGE_SIZE, "%d\n", id);
145 }
146 static DEVICE_ATTR_RO(id);
147 
148 static ssize_t
149 ltr_show(struct device *dev, struct device_attribute *attr, char *buf)
150 {
151 	struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
152 	void __iomem *base;
153 	u64 v;
154 
155 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
156 
157 	mutex_lock(&pdata->lock);
158 	v = readq(base + PORT_HDR_CTRL);
159 	mutex_unlock(&pdata->lock);
160 
161 	return sprintf(buf, "%x\n", (u8)FIELD_GET(PORT_CTRL_LATENCY, v));
162 }
163 
164 static ssize_t
165 ltr_store(struct device *dev, struct device_attribute *attr,
166 	  const char *buf, size_t count)
167 {
168 	struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
169 	void __iomem *base;
170 	bool ltr;
171 	u64 v;
172 
173 	if (kstrtobool(buf, &ltr))
174 		return -EINVAL;
175 
176 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
177 
178 	mutex_lock(&pdata->lock);
179 	v = readq(base + PORT_HDR_CTRL);
180 	v &= ~PORT_CTRL_LATENCY;
181 	v |= FIELD_PREP(PORT_CTRL_LATENCY, ltr ? 1 : 0);
182 	writeq(v, base + PORT_HDR_CTRL);
183 	mutex_unlock(&pdata->lock);
184 
185 	return count;
186 }
187 static DEVICE_ATTR_RW(ltr);
188 
189 static ssize_t
190 ap1_event_show(struct device *dev, struct device_attribute *attr, char *buf)
191 {
192 	struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
193 	void __iomem *base;
194 	u64 v;
195 
196 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
197 
198 	mutex_lock(&pdata->lock);
199 	v = readq(base + PORT_HDR_STS);
200 	mutex_unlock(&pdata->lock);
201 
202 	return sprintf(buf, "%x\n", (u8)FIELD_GET(PORT_STS_AP1_EVT, v));
203 }
204 
205 static ssize_t
206 ap1_event_store(struct device *dev, struct device_attribute *attr,
207 		const char *buf, size_t count)
208 {
209 	struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
210 	void __iomem *base;
211 	bool clear;
212 
213 	if (kstrtobool(buf, &clear) || !clear)
214 		return -EINVAL;
215 
216 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
217 
218 	mutex_lock(&pdata->lock);
219 	writeq(PORT_STS_AP1_EVT, base + PORT_HDR_STS);
220 	mutex_unlock(&pdata->lock);
221 
222 	return count;
223 }
224 static DEVICE_ATTR_RW(ap1_event);
225 
226 static ssize_t
227 ap2_event_show(struct device *dev, struct device_attribute *attr,
228 	       char *buf)
229 {
230 	struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
231 	void __iomem *base;
232 	u64 v;
233 
234 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
235 
236 	mutex_lock(&pdata->lock);
237 	v = readq(base + PORT_HDR_STS);
238 	mutex_unlock(&pdata->lock);
239 
240 	return sprintf(buf, "%x\n", (u8)FIELD_GET(PORT_STS_AP2_EVT, v));
241 }
242 
243 static ssize_t
244 ap2_event_store(struct device *dev, struct device_attribute *attr,
245 		const char *buf, size_t count)
246 {
247 	struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
248 	void __iomem *base;
249 	bool clear;
250 
251 	if (kstrtobool(buf, &clear) || !clear)
252 		return -EINVAL;
253 
254 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
255 
256 	mutex_lock(&pdata->lock);
257 	writeq(PORT_STS_AP2_EVT, base + PORT_HDR_STS);
258 	mutex_unlock(&pdata->lock);
259 
260 	return count;
261 }
262 static DEVICE_ATTR_RW(ap2_event);
263 
264 static ssize_t
265 power_state_show(struct device *dev, struct device_attribute *attr, char *buf)
266 {
267 	struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
268 	void __iomem *base;
269 	u64 v;
270 
271 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
272 
273 	mutex_lock(&pdata->lock);
274 	v = readq(base + PORT_HDR_STS);
275 	mutex_unlock(&pdata->lock);
276 
277 	return sprintf(buf, "0x%x\n", (u8)FIELD_GET(PORT_STS_PWR_STATE, v));
278 }
279 static DEVICE_ATTR_RO(power_state);
280 
281 static ssize_t
282 userclk_freqcmd_store(struct device *dev, struct device_attribute *attr,
283 		      const char *buf, size_t count)
284 {
285 	struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
286 	u64 userclk_freq_cmd;
287 	void __iomem *base;
288 
289 	if (kstrtou64(buf, 0, &userclk_freq_cmd))
290 		return -EINVAL;
291 
292 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
293 
294 	mutex_lock(&pdata->lock);
295 	writeq(userclk_freq_cmd, base + PORT_HDR_USRCLK_CMD0);
296 	mutex_unlock(&pdata->lock);
297 
298 	return count;
299 }
300 static DEVICE_ATTR_WO(userclk_freqcmd);
301 
302 static ssize_t
303 userclk_freqcntrcmd_store(struct device *dev, struct device_attribute *attr,
304 			  const char *buf, size_t count)
305 {
306 	struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
307 	u64 userclk_freqcntr_cmd;
308 	void __iomem *base;
309 
310 	if (kstrtou64(buf, 0, &userclk_freqcntr_cmd))
311 		return -EINVAL;
312 
313 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
314 
315 	mutex_lock(&pdata->lock);
316 	writeq(userclk_freqcntr_cmd, base + PORT_HDR_USRCLK_CMD1);
317 	mutex_unlock(&pdata->lock);
318 
319 	return count;
320 }
321 static DEVICE_ATTR_WO(userclk_freqcntrcmd);
322 
323 static ssize_t
324 userclk_freqsts_show(struct device *dev, struct device_attribute *attr,
325 		     char *buf)
326 {
327 	struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
328 	u64 userclk_freqsts;
329 	void __iomem *base;
330 
331 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
332 
333 	mutex_lock(&pdata->lock);
334 	userclk_freqsts = readq(base + PORT_HDR_USRCLK_STS0);
335 	mutex_unlock(&pdata->lock);
336 
337 	return sprintf(buf, "0x%llx\n", (unsigned long long)userclk_freqsts);
338 }
339 static DEVICE_ATTR_RO(userclk_freqsts);
340 
341 static ssize_t
342 userclk_freqcntrsts_show(struct device *dev, struct device_attribute *attr,
343 			 char *buf)
344 {
345 	struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
346 	u64 userclk_freqcntrsts;
347 	void __iomem *base;
348 
349 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
350 
351 	mutex_lock(&pdata->lock);
352 	userclk_freqcntrsts = readq(base + PORT_HDR_USRCLK_STS1);
353 	mutex_unlock(&pdata->lock);
354 
355 	return sprintf(buf, "0x%llx\n",
356 		       (unsigned long long)userclk_freqcntrsts);
357 }
358 static DEVICE_ATTR_RO(userclk_freqcntrsts);
359 
360 static struct attribute *port_hdr_attrs[] = {
361 	&dev_attr_id.attr,
362 	&dev_attr_ltr.attr,
363 	&dev_attr_ap1_event.attr,
364 	&dev_attr_ap2_event.attr,
365 	&dev_attr_power_state.attr,
366 	&dev_attr_userclk_freqcmd.attr,
367 	&dev_attr_userclk_freqcntrcmd.attr,
368 	&dev_attr_userclk_freqsts.attr,
369 	&dev_attr_userclk_freqcntrsts.attr,
370 	NULL,
371 };
372 
373 static umode_t port_hdr_attrs_visible(struct kobject *kobj,
374 				      struct attribute *attr, int n)
375 {
376 	struct device *dev = kobj_to_dev(kobj);
377 	umode_t mode = attr->mode;
378 	void __iomem *base;
379 
380 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
381 
382 	if (dfl_feature_revision(base) > 0) {
383 		/*
384 		 * userclk sysfs interfaces are only visible in case port
385 		 * revision is 0, as hardware with revision >0 doesn't
386 		 * support this.
387 		 */
388 		if (attr == &dev_attr_userclk_freqcmd.attr ||
389 		    attr == &dev_attr_userclk_freqcntrcmd.attr ||
390 		    attr == &dev_attr_userclk_freqsts.attr ||
391 		    attr == &dev_attr_userclk_freqcntrsts.attr)
392 			mode = 0;
393 	}
394 
395 	return mode;
396 }
397 
398 static const struct attribute_group port_hdr_group = {
399 	.attrs      = port_hdr_attrs,
400 	.is_visible = port_hdr_attrs_visible,
401 };
402 
403 static int port_hdr_init(struct platform_device *pdev,
404 			 struct dfl_feature *feature)
405 {
406 	port_reset(pdev);
407 
408 	return 0;
409 }
410 
411 static long
412 port_hdr_ioctl(struct platform_device *pdev, struct dfl_feature *feature,
413 	       unsigned int cmd, unsigned long arg)
414 {
415 	long ret;
416 
417 	switch (cmd) {
418 	case DFL_FPGA_PORT_RESET:
419 		if (!arg)
420 			ret = port_reset(pdev);
421 		else
422 			ret = -EINVAL;
423 		break;
424 	default:
425 		dev_dbg(&pdev->dev, "%x cmd not handled", cmd);
426 		ret = -ENODEV;
427 	}
428 
429 	return ret;
430 }
431 
432 static const struct dfl_feature_id port_hdr_id_table[] = {
433 	{.id = PORT_FEATURE_ID_HEADER,},
434 	{0,}
435 };
436 
437 static const struct dfl_feature_ops port_hdr_ops = {
438 	.init = port_hdr_init,
439 	.ioctl = port_hdr_ioctl,
440 };
441 
442 static ssize_t
443 afu_id_show(struct device *dev, struct device_attribute *attr, char *buf)
444 {
445 	struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
446 	void __iomem *base;
447 	u64 guidl, guidh;
448 
449 	base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_AFU);
450 
451 	mutex_lock(&pdata->lock);
452 	if (pdata->disable_count) {
453 		mutex_unlock(&pdata->lock);
454 		return -EBUSY;
455 	}
456 
457 	guidl = readq(base + GUID_L);
458 	guidh = readq(base + GUID_H);
459 	mutex_unlock(&pdata->lock);
460 
461 	return scnprintf(buf, PAGE_SIZE, "%016llx%016llx\n", guidh, guidl);
462 }
463 static DEVICE_ATTR_RO(afu_id);
464 
465 static struct attribute *port_afu_attrs[] = {
466 	&dev_attr_afu_id.attr,
467 	NULL
468 };
469 
470 static umode_t port_afu_attrs_visible(struct kobject *kobj,
471 				      struct attribute *attr, int n)
472 {
473 	struct device *dev = kobj_to_dev(kobj);
474 
475 	/*
476 	 * sysfs entries are visible only if related private feature is
477 	 * enumerated.
478 	 */
479 	if (!dfl_get_feature_by_id(dev, PORT_FEATURE_ID_AFU))
480 		return 0;
481 
482 	return attr->mode;
483 }
484 
485 static const struct attribute_group port_afu_group = {
486 	.attrs      = port_afu_attrs,
487 	.is_visible = port_afu_attrs_visible,
488 };
489 
490 static int port_afu_init(struct platform_device *pdev,
491 			 struct dfl_feature *feature)
492 {
493 	struct resource *res = &pdev->resource[feature->resource_index];
494 
495 	return afu_mmio_region_add(dev_get_platdata(&pdev->dev),
496 				   DFL_PORT_REGION_INDEX_AFU,
497 				   resource_size(res), res->start,
498 				   DFL_PORT_REGION_MMAP | DFL_PORT_REGION_READ |
499 				   DFL_PORT_REGION_WRITE);
500 }
501 
502 static const struct dfl_feature_id port_afu_id_table[] = {
503 	{.id = PORT_FEATURE_ID_AFU,},
504 	{0,}
505 };
506 
507 static const struct dfl_feature_ops port_afu_ops = {
508 	.init = port_afu_init,
509 };
510 
511 static int port_stp_init(struct platform_device *pdev,
512 			 struct dfl_feature *feature)
513 {
514 	struct resource *res = &pdev->resource[feature->resource_index];
515 
516 	return afu_mmio_region_add(dev_get_platdata(&pdev->dev),
517 				   DFL_PORT_REGION_INDEX_STP,
518 				   resource_size(res), res->start,
519 				   DFL_PORT_REGION_MMAP | DFL_PORT_REGION_READ |
520 				   DFL_PORT_REGION_WRITE);
521 }
522 
523 static const struct dfl_feature_id port_stp_id_table[] = {
524 	{.id = PORT_FEATURE_ID_STP,},
525 	{0,}
526 };
527 
528 static const struct dfl_feature_ops port_stp_ops = {
529 	.init = port_stp_init,
530 };
531 
532 static struct dfl_feature_driver port_feature_drvs[] = {
533 	{
534 		.id_table = port_hdr_id_table,
535 		.ops = &port_hdr_ops,
536 	},
537 	{
538 		.id_table = port_afu_id_table,
539 		.ops = &port_afu_ops,
540 	},
541 	{
542 		.id_table = port_err_id_table,
543 		.ops = &port_err_ops,
544 	},
545 	{
546 		.id_table = port_stp_id_table,
547 		.ops = &port_stp_ops,
548 	},
549 	{
550 		.ops = NULL,
551 	}
552 };
553 
554 static int afu_open(struct inode *inode, struct file *filp)
555 {
556 	struct platform_device *fdev = dfl_fpga_inode_to_feature_dev(inode);
557 	struct dfl_feature_platform_data *pdata;
558 	int ret;
559 
560 	pdata = dev_get_platdata(&fdev->dev);
561 	if (WARN_ON(!pdata))
562 		return -ENODEV;
563 
564 	ret = dfl_feature_dev_use_begin(pdata);
565 	if (ret)
566 		return ret;
567 
568 	dev_dbg(&fdev->dev, "Device File Open\n");
569 	filp->private_data = fdev;
570 
571 	return 0;
572 }
573 
574 static int afu_release(struct inode *inode, struct file *filp)
575 {
576 	struct platform_device *pdev = filp->private_data;
577 	struct dfl_feature_platform_data *pdata;
578 
579 	dev_dbg(&pdev->dev, "Device File Release\n");
580 
581 	pdata = dev_get_platdata(&pdev->dev);
582 
583 	mutex_lock(&pdata->lock);
584 	__port_reset(pdev);
585 	afu_dma_region_destroy(pdata);
586 	mutex_unlock(&pdata->lock);
587 
588 	dfl_feature_dev_use_end(pdata);
589 
590 	return 0;
591 }
592 
593 static long afu_ioctl_check_extension(struct dfl_feature_platform_data *pdata,
594 				      unsigned long arg)
595 {
596 	/* No extension support for now */
597 	return 0;
598 }
599 
600 static long
601 afu_ioctl_get_info(struct dfl_feature_platform_data *pdata, void __user *arg)
602 {
603 	struct dfl_fpga_port_info info;
604 	struct dfl_afu *afu;
605 	unsigned long minsz;
606 
607 	minsz = offsetofend(struct dfl_fpga_port_info, num_umsgs);
608 
609 	if (copy_from_user(&info, arg, minsz))
610 		return -EFAULT;
611 
612 	if (info.argsz < minsz)
613 		return -EINVAL;
614 
615 	mutex_lock(&pdata->lock);
616 	afu = dfl_fpga_pdata_get_private(pdata);
617 	info.flags = 0;
618 	info.num_regions = afu->num_regions;
619 	info.num_umsgs = afu->num_umsgs;
620 	mutex_unlock(&pdata->lock);
621 
622 	if (copy_to_user(arg, &info, sizeof(info)))
623 		return -EFAULT;
624 
625 	return 0;
626 }
627 
628 static long afu_ioctl_get_region_info(struct dfl_feature_platform_data *pdata,
629 				      void __user *arg)
630 {
631 	struct dfl_fpga_port_region_info rinfo;
632 	struct dfl_afu_mmio_region region;
633 	unsigned long minsz;
634 	long ret;
635 
636 	minsz = offsetofend(struct dfl_fpga_port_region_info, offset);
637 
638 	if (copy_from_user(&rinfo, arg, minsz))
639 		return -EFAULT;
640 
641 	if (rinfo.argsz < minsz || rinfo.padding)
642 		return -EINVAL;
643 
644 	ret = afu_mmio_region_get_by_index(pdata, rinfo.index, &region);
645 	if (ret)
646 		return ret;
647 
648 	rinfo.flags = region.flags;
649 	rinfo.size = region.size;
650 	rinfo.offset = region.offset;
651 
652 	if (copy_to_user(arg, &rinfo, sizeof(rinfo)))
653 		return -EFAULT;
654 
655 	return 0;
656 }
657 
658 static long
659 afu_ioctl_dma_map(struct dfl_feature_platform_data *pdata, void __user *arg)
660 {
661 	struct dfl_fpga_port_dma_map map;
662 	unsigned long minsz;
663 	long ret;
664 
665 	minsz = offsetofend(struct dfl_fpga_port_dma_map, iova);
666 
667 	if (copy_from_user(&map, arg, minsz))
668 		return -EFAULT;
669 
670 	if (map.argsz < minsz || map.flags)
671 		return -EINVAL;
672 
673 	ret = afu_dma_map_region(pdata, map.user_addr, map.length, &map.iova);
674 	if (ret)
675 		return ret;
676 
677 	if (copy_to_user(arg, &map, sizeof(map))) {
678 		afu_dma_unmap_region(pdata, map.iova);
679 		return -EFAULT;
680 	}
681 
682 	dev_dbg(&pdata->dev->dev, "dma map: ua=%llx, len=%llx, iova=%llx\n",
683 		(unsigned long long)map.user_addr,
684 		(unsigned long long)map.length,
685 		(unsigned long long)map.iova);
686 
687 	return 0;
688 }
689 
690 static long
691 afu_ioctl_dma_unmap(struct dfl_feature_platform_data *pdata, void __user *arg)
692 {
693 	struct dfl_fpga_port_dma_unmap unmap;
694 	unsigned long minsz;
695 
696 	minsz = offsetofend(struct dfl_fpga_port_dma_unmap, iova);
697 
698 	if (copy_from_user(&unmap, arg, minsz))
699 		return -EFAULT;
700 
701 	if (unmap.argsz < minsz || unmap.flags)
702 		return -EINVAL;
703 
704 	return afu_dma_unmap_region(pdata, unmap.iova);
705 }
706 
707 static long afu_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
708 {
709 	struct platform_device *pdev = filp->private_data;
710 	struct dfl_feature_platform_data *pdata;
711 	struct dfl_feature *f;
712 	long ret;
713 
714 	dev_dbg(&pdev->dev, "%s cmd 0x%x\n", __func__, cmd);
715 
716 	pdata = dev_get_platdata(&pdev->dev);
717 
718 	switch (cmd) {
719 	case DFL_FPGA_GET_API_VERSION:
720 		return DFL_FPGA_API_VERSION;
721 	case DFL_FPGA_CHECK_EXTENSION:
722 		return afu_ioctl_check_extension(pdata, arg);
723 	case DFL_FPGA_PORT_GET_INFO:
724 		return afu_ioctl_get_info(pdata, (void __user *)arg);
725 	case DFL_FPGA_PORT_GET_REGION_INFO:
726 		return afu_ioctl_get_region_info(pdata, (void __user *)arg);
727 	case DFL_FPGA_PORT_DMA_MAP:
728 		return afu_ioctl_dma_map(pdata, (void __user *)arg);
729 	case DFL_FPGA_PORT_DMA_UNMAP:
730 		return afu_ioctl_dma_unmap(pdata, (void __user *)arg);
731 	default:
732 		/*
733 		 * Let sub-feature's ioctl function to handle the cmd
734 		 * Sub-feature's ioctl returns -ENODEV when cmd is not
735 		 * handled in this sub feature, and returns 0 and other
736 		 * error code if cmd is handled.
737 		 */
738 		dfl_fpga_dev_for_each_feature(pdata, f)
739 			if (f->ops && f->ops->ioctl) {
740 				ret = f->ops->ioctl(pdev, f, cmd, arg);
741 				if (ret != -ENODEV)
742 					return ret;
743 			}
744 	}
745 
746 	return -EINVAL;
747 }
748 
749 static int afu_mmap(struct file *filp, struct vm_area_struct *vma)
750 {
751 	struct platform_device *pdev = filp->private_data;
752 	struct dfl_feature_platform_data *pdata;
753 	u64 size = vma->vm_end - vma->vm_start;
754 	struct dfl_afu_mmio_region region;
755 	u64 offset;
756 	int ret;
757 
758 	if (!(vma->vm_flags & VM_SHARED))
759 		return -EINVAL;
760 
761 	pdata = dev_get_platdata(&pdev->dev);
762 
763 	offset = vma->vm_pgoff << PAGE_SHIFT;
764 	ret = afu_mmio_region_get_by_offset(pdata, offset, size, &region);
765 	if (ret)
766 		return ret;
767 
768 	if (!(region.flags & DFL_PORT_REGION_MMAP))
769 		return -EINVAL;
770 
771 	if ((vma->vm_flags & VM_READ) && !(region.flags & DFL_PORT_REGION_READ))
772 		return -EPERM;
773 
774 	if ((vma->vm_flags & VM_WRITE) &&
775 	    !(region.flags & DFL_PORT_REGION_WRITE))
776 		return -EPERM;
777 
778 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
779 
780 	return remap_pfn_range(vma, vma->vm_start,
781 			(region.phys + (offset - region.offset)) >> PAGE_SHIFT,
782 			size, vma->vm_page_prot);
783 }
784 
785 static const struct file_operations afu_fops = {
786 	.owner = THIS_MODULE,
787 	.open = afu_open,
788 	.release = afu_release,
789 	.unlocked_ioctl = afu_ioctl,
790 	.mmap = afu_mmap,
791 };
792 
793 static int afu_dev_init(struct platform_device *pdev)
794 {
795 	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
796 	struct dfl_afu *afu;
797 
798 	afu = devm_kzalloc(&pdev->dev, sizeof(*afu), GFP_KERNEL);
799 	if (!afu)
800 		return -ENOMEM;
801 
802 	afu->pdata = pdata;
803 
804 	mutex_lock(&pdata->lock);
805 	dfl_fpga_pdata_set_private(pdata, afu);
806 	afu_mmio_region_init(pdata);
807 	afu_dma_region_init(pdata);
808 	mutex_unlock(&pdata->lock);
809 
810 	return 0;
811 }
812 
813 static int afu_dev_destroy(struct platform_device *pdev)
814 {
815 	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
816 
817 	mutex_lock(&pdata->lock);
818 	afu_mmio_region_destroy(pdata);
819 	afu_dma_region_destroy(pdata);
820 	dfl_fpga_pdata_set_private(pdata, NULL);
821 	mutex_unlock(&pdata->lock);
822 
823 	return 0;
824 }
825 
826 static int port_enable_set(struct platform_device *pdev, bool enable)
827 {
828 	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
829 	int ret = 0;
830 
831 	mutex_lock(&pdata->lock);
832 	if (enable)
833 		__afu_port_enable(pdev);
834 	else
835 		ret = __afu_port_disable(pdev);
836 	mutex_unlock(&pdata->lock);
837 
838 	return ret;
839 }
840 
841 static struct dfl_fpga_port_ops afu_port_ops = {
842 	.name = DFL_FPGA_FEATURE_DEV_PORT,
843 	.owner = THIS_MODULE,
844 	.get_id = port_get_id,
845 	.enable_set = port_enable_set,
846 };
847 
848 static int afu_probe(struct platform_device *pdev)
849 {
850 	int ret;
851 
852 	dev_dbg(&pdev->dev, "%s\n", __func__);
853 
854 	ret = afu_dev_init(pdev);
855 	if (ret)
856 		goto exit;
857 
858 	ret = dfl_fpga_dev_feature_init(pdev, port_feature_drvs);
859 	if (ret)
860 		goto dev_destroy;
861 
862 	ret = dfl_fpga_dev_ops_register(pdev, &afu_fops, THIS_MODULE);
863 	if (ret) {
864 		dfl_fpga_dev_feature_uinit(pdev);
865 		goto dev_destroy;
866 	}
867 
868 	return 0;
869 
870 dev_destroy:
871 	afu_dev_destroy(pdev);
872 exit:
873 	return ret;
874 }
875 
876 static int afu_remove(struct platform_device *pdev)
877 {
878 	dev_dbg(&pdev->dev, "%s\n", __func__);
879 
880 	dfl_fpga_dev_ops_unregister(pdev);
881 	dfl_fpga_dev_feature_uinit(pdev);
882 	afu_dev_destroy(pdev);
883 
884 	return 0;
885 }
886 
887 static const struct attribute_group *afu_dev_groups[] = {
888 	&port_hdr_group,
889 	&port_afu_group,
890 	&port_err_group,
891 	NULL
892 };
893 
894 static struct platform_driver afu_driver = {
895 	.driver	= {
896 		.name	    = DFL_FPGA_FEATURE_DEV_PORT,
897 		.dev_groups = afu_dev_groups,
898 	},
899 	.probe   = afu_probe,
900 	.remove  = afu_remove,
901 };
902 
903 static int __init afu_init(void)
904 {
905 	int ret;
906 
907 	dfl_fpga_port_ops_add(&afu_port_ops);
908 
909 	ret = platform_driver_register(&afu_driver);
910 	if (ret)
911 		dfl_fpga_port_ops_del(&afu_port_ops);
912 
913 	return ret;
914 }
915 
916 static void __exit afu_exit(void)
917 {
918 	platform_driver_unregister(&afu_driver);
919 
920 	dfl_fpga_port_ops_del(&afu_port_ops);
921 }
922 
923 module_init(afu_init);
924 module_exit(afu_exit);
925 
926 MODULE_DESCRIPTION("FPGA Accelerated Function Unit driver");
927 MODULE_AUTHOR("Intel Corporation");
928 MODULE_LICENSE("GPL v2");
929 MODULE_ALIAS("platform:dfl-port");
930