New upstream version 18.05
[deb_dpdk.git] / drivers / raw / ifpga_rawdev / base / ifpga_port_error.c
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c
new file mode 100644 (file)
index 0000000..23db562
--- /dev/null
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#include "ifpga_feature_dev.h"
+
+static int port_err_get_revision(struct ifpga_port_hw *port, u64 *val)
+{
+       struct feature_port_error *port_err;
+       struct feature_header header;
+
+       port_err = get_port_feature_ioaddr_by_index(port,
+                                                   PORT_FEATURE_ID_ERROR);
+       header.csr = readq(&port_err->header);
+       *val = header.revision;
+
+       return 0;
+}
+
+static int port_err_get_errors(struct ifpga_port_hw *port, u64 *val)
+{
+       struct feature_port_error *port_err;
+       struct feature_port_err_key error;
+
+       port_err = get_port_feature_ioaddr_by_index(port,
+                                                   PORT_FEATURE_ID_ERROR);
+       error.csr = readq(&port_err->port_error);
+       *val = error.csr;
+
+       return 0;
+}
+
+static int port_err_get_first_error(struct ifpga_port_hw *port, u64 *val)
+{
+       struct feature_port_error *port_err;
+       struct feature_port_first_err_key first_error;
+
+       port_err = get_port_feature_ioaddr_by_index(port,
+                                                   PORT_FEATURE_ID_ERROR);
+       first_error.csr = readq(&port_err->port_first_error);
+       *val = first_error.csr;
+
+       return 0;
+}
+
+static int port_err_get_first_malformed_req_lsb(struct ifpga_port_hw *port,
+                                               u64 *val)
+{
+       struct feature_port_error *port_err;
+       struct feature_port_malformed_req0 malreq0;
+
+       port_err = get_port_feature_ioaddr_by_index(port,
+                                                   PORT_FEATURE_ID_ERROR);
+
+       malreq0.header_lsb = readq(&port_err->malreq0);
+       *val = malreq0.header_lsb;
+
+       return 0;
+}
+
+static int port_err_get_first_malformed_req_msb(struct ifpga_port_hw *port,
+                                               u64 *val)
+{
+       struct feature_port_error *port_err;
+       struct feature_port_malformed_req1 malreq1;
+
+       port_err = get_port_feature_ioaddr_by_index(port,
+                                                   PORT_FEATURE_ID_ERROR);
+
+       malreq1.header_msb = readq(&port_err->malreq1);
+       *val = malreq1.header_msb;
+
+       return 0;
+}
+
+static int port_err_set_clear(struct ifpga_port_hw *port, u64 val)
+{
+       int ret;
+
+       spinlock_lock(&port->lock);
+       ret = port_err_clear(port, val);
+       spinlock_unlock(&port->lock);
+
+       return ret;
+}
+
+static int port_error_init(struct feature *feature)
+{
+       struct ifpga_port_hw *port = feature->parent;
+
+       dev_info(NULL, "port error Init.\n");
+
+       spinlock_lock(&port->lock);
+       port_err_mask(port, false);
+       if (feature->ctx_num)
+               port->capability |= FPGA_PORT_CAP_ERR_IRQ;
+       spinlock_unlock(&port->lock);
+
+       return 0;
+}
+
+static void port_error_uinit(struct feature *feature)
+{
+       UNUSED(feature);
+}
+
+static int port_error_get_prop(struct feature *feature,
+                              struct feature_prop *prop)
+{
+       struct ifpga_port_hw *port = feature->parent;
+
+       switch (prop->prop_id) {
+       case PORT_ERR_PROP_REVISION:
+               return port_err_get_revision(port, &prop->data);
+       case PORT_ERR_PROP_ERRORS:
+               return port_err_get_errors(port, &prop->data);
+       case PORT_ERR_PROP_FIRST_ERROR:
+               return port_err_get_first_error(port, &prop->data);
+       case PORT_ERR_PROP_FIRST_MALFORMED_REQ_LSB:
+               return port_err_get_first_malformed_req_lsb(port, &prop->data);
+       case PORT_ERR_PROP_FIRST_MALFORMED_REQ_MSB:
+               return port_err_get_first_malformed_req_msb(port, &prop->data);
+       }
+
+       return -ENOENT;
+}
+
+static int port_error_set_prop(struct feature *feature,
+                              struct feature_prop *prop)
+{
+       struct ifpga_port_hw *port = feature->parent;
+
+       if (prop->prop_id == PORT_ERR_PROP_CLEAR)
+               return port_err_set_clear(port, prop->data);
+
+       return -ENOENT;
+}
+
+struct feature_ops port_error_ops = {
+       .init = port_error_init,
+       .uinit = port_error_uinit,
+       .get_prop = port_error_get_prop,
+       .set_prop = port_error_set_prop,
+};