aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c
blob: 23db562b801d7911ec771a1a771a35b9ba719d28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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,
};