lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20161103212728.9908-1-moritz.fischer@ettus.com>
Date:   Thu,  3 Nov 2016 15:27:28 -0600
From:   Moritz Fischer <moritz.fischer@...us.com>
To:     atull@...nsource.altera.com
Cc:     delicious.quinoa@...il.com, moritz.fischer.private@...il.com,
        Moritz Fischer <moritz.fischer@...us.com>,
        Michal Simek <michal.simek@...inx.com>,
        Sören Brinkmann <soren.brinkmann@...inx.com>,
        linux-kernel@...r.kernel.org, linux-arm-kernel@...ts.infradead.org
Subject: [RFC] fpga mgr: Introduce FPGA capabilities

Add FPGA capabilities as a way to express the capabilities
of a given FPGA manager.

Removes code duplication by comparing the low-level driver's
capabilities at the framework level rather than having each driver
check for supported operations in the write_init() callback.

This allows for extending with additional capabilities, similar
to the the dmaengine framework's implementation.

Signed-off-by: Moritz Fischer <moritz.fischer@...us.com>
Cc: Alan Tull <atull@...nsource.altera.com>
Cc: Michal Simek <michal.simek@...inx.com>
Cc: Sören Brinkmann <soren.brinkmann@...inx.com>
Cc: linux-kernel@...r.kernel.org
Cc: linux-arm-kernel@...ts.infradead.org
---
Hi all,

this is another RFC (this one is against mainline) implementing
fpga capabilities to centralize the checks for different operations.

If we agree this is the way forward, I'll rebase it on top of Alan's
series once that went in (and add potential drivers we added by then.

Cheers,

Moritz

PS: I'm not sure if the checkpatch warning is a false positive ...
---
 drivers/fpga/fpga-mgr.c       | 14 +++++++++++++
 drivers/fpga/socfpga.c        | 10 +++++-----
 drivers/fpga/zynq-fpga.c      |  7 ++++++-
 include/linux/fpga/fpga-mgr.h | 46 ++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index 953dc91..21c508a 100644
--- a/drivers/fpga/fpga-mgr.c
+++ b/drivers/fpga/fpga-mgr.c
@@ -49,6 +49,18 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf,
 	struct device *dev = &mgr->dev;
 	int ret;
 
+	if (flags & FPGA_MGR_PARTIAL_RECONFIG &&
+	    !fpga_mgr_has_cap(FPGA_MGR_CAP_PARTIAL_RECONF, mgr->caps)) {
+		dev_err(dev, "Partial reconfiguration not supported\n");
+		return -ENOTSUPP;
+	}
+
+	if (flags & FPGA_MGR_FULL_RECONFIG &&
+	    !fpga_mgr_has_cap(FPGA_MGR_CAP_FULL_RECONF, mgr->caps)) {
+		dev_err(dev, "Full reconfiguration not supported\n");
+		return -ENOTSUPP;
+	}
+
 	/*
 	 * Call the low level driver's write_init function.  This will do the
 	 * device-specific things to get the FPGA into the state where it is
@@ -245,12 +257,14 @@ EXPORT_SYMBOL_GPL(fpga_mgr_put);
  * @dev:	fpga manager device from pdev
  * @name:	fpga manager name
  * @mops:	pointer to structure of fpga manager ops
+ * @caps:	fpga manager capabilites
  * @priv:	fpga manager private data
  *
  * Return: 0 on success, negative error code otherwise.
  */
 int fpga_mgr_register(struct device *dev, const char *name,
 		      const struct fpga_manager_ops *mops,
+		      fpga_mgr_cap_mask_t caps,
 		      void *priv)
 {
 	struct fpga_manager *mgr;
diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c
index 27d2ff2..fd9760c 100644
--- a/drivers/fpga/socfpga.c
+++ b/drivers/fpga/socfpga.c
@@ -413,10 +413,6 @@ static int socfpga_fpga_ops_configure_init(struct fpga_manager *mgr, u32 flags,
 	struct socfpga_fpga_priv *priv = mgr->priv;
 	int ret;
 
-	if (flags & FPGA_MGR_PARTIAL_RECONFIG) {
-		dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
-		return -EINVAL;
-	}
 	/* Steps 1 - 5: Reset the FPGA */
 	ret = socfpga_fpga_reset(mgr);
 	if (ret)
@@ -555,6 +551,7 @@ static int socfpga_fpga_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct socfpga_fpga_priv *priv;
 	struct resource *res;
+	fpga_mgr_cap_mask_t caps;
 	int ret;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -580,8 +577,11 @@ static int socfpga_fpga_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	fpga_mgr_cap_zero(&caps);
+	fpga_mgr_cap_set(FPGA_MGR_CAP_FULL_RECONF, caps);
+
 	return fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
-				 &socfpga_fpga_ops, priv);
+				 &socfpga_fpga_ops, caps, priv);
 }
 
 static int socfpga_fpga_remove(struct platform_device *pdev)
diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
index c2fb412..1d37ff0 100644
--- a/drivers/fpga/zynq-fpga.c
+++ b/drivers/fpga/zynq-fpga.c
@@ -410,6 +410,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct zynq_fpga_priv *priv;
 	struct resource *res;
+	fpga_mgr_cap_mask_t caps;
 	int err;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -461,9 +462,13 @@ static int zynq_fpga_probe(struct platform_device *pdev)
 	zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK);
 
 	clk_disable(priv->clk);
+	fpga_mgr_cap_zero(&caps);
+	fpga_mgr_cap_set(FPGA_MGR_CAP_FULL_RECONF, caps);
+	fpga_mgr_cap_set(FPGA_MGR_CAP_PARTIAL_RECONF, caps);
+
 
 	err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
-				&zynq_fpga_ops, priv);
+				&zynq_fpga_ops, caps, priv);
 	if (err) {
 		dev_err(dev, "unable to register FPGA manager");
 		clk_unprepare(priv->clk);
diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
index 0940bf4..a0bf750 100644
--- a/include/linux/fpga/fpga-mgr.h
+++ b/include/linux/fpga/fpga-mgr.h
@@ -67,6 +67,47 @@ enum fpga_mgr_states {
  * FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported
  */
 #define FPGA_MGR_PARTIAL_RECONFIG	BIT(0)
+#define FPGA_MGR_FULL_RECONFIG		BIT(1)
+
+enum fpga_manager_capability {
+	FPGA_MGR_CAP_PARTIAL_RECONF,
+	FPGA_MGR_CAP_FULL_RECONF,
+
+/* last capability type for creation of the capabilities mask */
+	FPGA_MGR_CAP_END,
+};
+
+typedef struct { DECLARE_BITMAP(bits, FPGA_MGR_CAP_END); } fpga_mgr_cap_mask_t;
+
+#define fpga_mgr_has_cap(cap, mask) __fpga_mgr_has_cap((cap), &(mask))
+static inline int __fpga_mgr_has_cap(enum fpga_manager_capability cap,
+				     fpga_mgr_cap_mask_t *mask)
+{
+	return test_bit(cap, mask->bits);
+}
+
+#define fpga_mgr_cap_zero(mask) __fpga_mgr_cap_zero(mask)
+static inline void __fpga_mgr_cap_zero(fpga_mgr_cap_mask_t *mask)
+{
+	bitmap_zero(mask->bits, FPGA_MGR_CAP_END);
+}
+
+#define fpga_mgr_cap_clear(cap, mask) __fpga_mgr_cap_clear((cap), &(mask))
+static inline void __fpga_mgr_cap_clear(enum fpga_manager_capability cap,
+				       fpga_mgr_cap_mask_t *mask)
+
+{
+	clear_bit(cap, mask->bits);
+}
+
+#define fpga_mgr_cap_set(cap, mask) __fpga_mgr_cap_set((cap), &(mask))
+static inline void __fpga_mgr_cap_set(enum fpga_manager_capability cap,
+				      fpga_mgr_cap_mask_t *mask)
+
+{
+	set_bit(cap, mask->bits);
+}
+
 
 /**
  * struct fpga_manager_ops - ops for low level fpga manager drivers
@@ -105,6 +146,7 @@ struct fpga_manager {
 	enum fpga_mgr_states state;
 	const struct fpga_manager_ops *mops;
 	void *priv;
+	fpga_mgr_cap_mask_t caps;
 };
 
 #define to_fpga_manager(d) container_of(d, struct fpga_manager, dev)
@@ -120,7 +162,9 @@ struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
 void fpga_mgr_put(struct fpga_manager *mgr);
 
 int fpga_mgr_register(struct device *dev, const char *name,
-		      const struct fpga_manager_ops *mops, void *priv);
+		      const struct fpga_manager_ops *mops,
+		      fpga_mgr_cap_mask_t caps,
+		      void *priv);
 
 void fpga_mgr_unregister(struct device *dev);
 
-- 
2.10.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ