1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2018 Intel Corporation 3 */ 4 5 #include "ifpga_feature_dev.h" 6 7 static int port_err_get_revision(struct ifpga_port_hw *port, u64 *val) 8 { 9 struct feature_port_error *port_err; 10 struct feature_header header; 11 12 port_err = get_port_feature_ioaddr_by_index(port, 13 PORT_FEATURE_ID_ERROR); 14 header.csr = readq(&port_err->header); 15 *val = header.revision; 16 17 return 0; 18 } 19 20 static int port_err_get_errors(struct ifpga_port_hw *port, u64 *val) 21 { 22 struct feature_port_error *port_err; 23 struct feature_port_err_key error; 24 25 port_err = get_port_feature_ioaddr_by_index(port, 26 PORT_FEATURE_ID_ERROR); 27 error.csr = readq(&port_err->port_error); 28 *val = error.csr; 29 30 return 0; 31 } 32 33 static int port_err_get_first_error(struct ifpga_port_hw *port, u64 *val) 34 { 35 struct feature_port_error *port_err; 36 struct feature_port_first_err_key first_error; 37 38 port_err = get_port_feature_ioaddr_by_index(port, 39 PORT_FEATURE_ID_ERROR); 40 first_error.csr = readq(&port_err->port_first_error); 41 *val = first_error.csr; 42 43 return 0; 44 } 45 46 static int port_err_get_first_malformed_req_lsb(struct ifpga_port_hw *port, 47 u64 *val) 48 { 49 struct feature_port_error *port_err; 50 struct feature_port_malformed_req0 malreq0; 51 52 port_err = get_port_feature_ioaddr_by_index(port, 53 PORT_FEATURE_ID_ERROR); 54 55 malreq0.header_lsb = readq(&port_err->malreq0); 56 *val = malreq0.header_lsb; 57 58 return 0; 59 } 60 61 static int port_err_get_first_malformed_req_msb(struct ifpga_port_hw *port, 62 u64 *val) 63 { 64 struct feature_port_error *port_err; 65 struct feature_port_malformed_req1 malreq1; 66 67 port_err = get_port_feature_ioaddr_by_index(port, 68 PORT_FEATURE_ID_ERROR); 69 70 malreq1.header_msb = readq(&port_err->malreq1); 71 *val = malreq1.header_msb; 72 73 return 0; 74 } 75 76 static int port_err_set_clear(struct ifpga_port_hw *port, u64 val) 77 { 78 int ret; 79 80 spinlock_lock(&port->lock); 81 ret = port_err_clear(port, val); 82 spinlock_unlock(&port->lock); 83 84 return ret; 85 } 86 87 static int port_error_init(struct ifpga_feature *feature) 88 { 89 struct ifpga_port_hw *port = feature->parent; 90 91 dev_info(NULL, "port error Init.\n"); 92 93 spinlock_lock(&port->lock); 94 port_err_mask(port, false); 95 if (feature->ctx_num) 96 port->capability |= FPGA_PORT_CAP_ERR_IRQ; 97 spinlock_unlock(&port->lock); 98 99 return 0; 100 } 101 102 static void port_error_uinit(struct ifpga_feature *feature) 103 { 104 UNUSED(feature); 105 } 106 107 static int port_error_get_prop(struct ifpga_feature *feature, 108 struct feature_prop *prop) 109 { 110 struct ifpga_port_hw *port = feature->parent; 111 112 switch (prop->prop_id) { 113 case PORT_ERR_PROP_REVISION: 114 return port_err_get_revision(port, &prop->data); 115 case PORT_ERR_PROP_ERRORS: 116 return port_err_get_errors(port, &prop->data); 117 case PORT_ERR_PROP_FIRST_ERROR: 118 return port_err_get_first_error(port, &prop->data); 119 case PORT_ERR_PROP_FIRST_MALFORMED_REQ_LSB: 120 return port_err_get_first_malformed_req_lsb(port, &prop->data); 121 case PORT_ERR_PROP_FIRST_MALFORMED_REQ_MSB: 122 return port_err_get_first_malformed_req_msb(port, &prop->data); 123 } 124 125 return -ENOENT; 126 } 127 128 static int port_error_set_prop(struct ifpga_feature *feature, 129 struct feature_prop *prop) 130 { 131 struct ifpga_port_hw *port = feature->parent; 132 133 if (prop->prop_id == PORT_ERR_PROP_CLEAR) 134 return port_err_set_clear(port, prop->data); 135 136 return -ENOENT; 137 } 138 139 struct ifpga_feature_ops ifpga_rawdev_port_error_ops = { 140 .init = port_error_init, 141 .uinit = port_error_uinit, 142 .get_prop = port_error_get_prop, 143 .set_prop = port_error_set_prop, 144 }; 145