1*473c88f9SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2*473c88f9SBruce Richardson * Copyright(c) 2010-2018 Intel Corporation
3*473c88f9SBruce Richardson */
4*473c88f9SBruce Richardson
5*473c88f9SBruce Richardson #include "ifpga_feature_dev.h"
6*473c88f9SBruce Richardson
7*473c88f9SBruce Richardson #define PERF_OBJ_ROOT_ID 0xff
8*473c88f9SBruce Richardson
fme_iperf_get_clock(struct ifpga_fme_hw * fme,u64 * clock)9*473c88f9SBruce Richardson static int fme_iperf_get_clock(struct ifpga_fme_hw *fme, u64 *clock)
10*473c88f9SBruce Richardson {
11*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
12*473c88f9SBruce Richardson struct feature_fme_ifpmon_clk_ctr clk;
13*473c88f9SBruce Richardson
14*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
15*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
16*473c88f9SBruce Richardson clk.afu_interf_clock = readq(&iperf->clk);
17*473c88f9SBruce Richardson
18*473c88f9SBruce Richardson *clock = clk.afu_interf_clock;
19*473c88f9SBruce Richardson return 0;
20*473c88f9SBruce Richardson }
21*473c88f9SBruce Richardson
fme_iperf_get_revision(struct ifpga_fme_hw * fme,u64 * revision)22*473c88f9SBruce Richardson static int fme_iperf_get_revision(struct ifpga_fme_hw *fme, u64 *revision)
23*473c88f9SBruce Richardson {
24*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
25*473c88f9SBruce Richardson struct feature_header header;
26*473c88f9SBruce Richardson
27*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
28*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
29*473c88f9SBruce Richardson header.csr = readq(&iperf->header);
30*473c88f9SBruce Richardson *revision = header.revision;
31*473c88f9SBruce Richardson
32*473c88f9SBruce Richardson return 0;
33*473c88f9SBruce Richardson }
34*473c88f9SBruce Richardson
fme_iperf_get_cache_freeze(struct ifpga_fme_hw * fme,u64 * freeze)35*473c88f9SBruce Richardson static int fme_iperf_get_cache_freeze(struct ifpga_fme_hw *fme, u64 *freeze)
36*473c88f9SBruce Richardson {
37*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
38*473c88f9SBruce Richardson struct feature_fme_ifpmon_ch_ctl ctl;
39*473c88f9SBruce Richardson
40*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
41*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
42*473c88f9SBruce Richardson ctl.csr = readq(&iperf->ch_ctl);
43*473c88f9SBruce Richardson *freeze = (u64)ctl.freeze;
44*473c88f9SBruce Richardson return 0;
45*473c88f9SBruce Richardson }
46*473c88f9SBruce Richardson
fme_iperf_set_cache_freeze(struct ifpga_fme_hw * fme,u64 freeze)47*473c88f9SBruce Richardson static int fme_iperf_set_cache_freeze(struct ifpga_fme_hw *fme, u64 freeze)
48*473c88f9SBruce Richardson {
49*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
50*473c88f9SBruce Richardson struct feature_fme_ifpmon_ch_ctl ctl;
51*473c88f9SBruce Richardson bool state;
52*473c88f9SBruce Richardson
53*473c88f9SBruce Richardson state = !!freeze;
54*473c88f9SBruce Richardson
55*473c88f9SBruce Richardson spinlock_lock(&fme->lock);
56*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
57*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
58*473c88f9SBruce Richardson ctl.csr = readq(&iperf->ch_ctl);
59*473c88f9SBruce Richardson ctl.freeze = state;
60*473c88f9SBruce Richardson writeq(ctl.csr, &iperf->ch_ctl);
61*473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
62*473c88f9SBruce Richardson
63*473c88f9SBruce Richardson return 0;
64*473c88f9SBruce Richardson }
65*473c88f9SBruce Richardson
66*473c88f9SBruce Richardson #define IPERF_TIMEOUT 30
67*473c88f9SBruce Richardson
read_cache_counter(struct ifpga_fme_hw * fme,u8 channel,enum iperf_cache_events event)68*473c88f9SBruce Richardson static u64 read_cache_counter(struct ifpga_fme_hw *fme,
69*473c88f9SBruce Richardson u8 channel, enum iperf_cache_events event)
70*473c88f9SBruce Richardson {
71*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
72*473c88f9SBruce Richardson struct feature_fme_ifpmon_ch_ctl ctl;
73*473c88f9SBruce Richardson struct feature_fme_ifpmon_ch_ctr ctr0, ctr1;
74*473c88f9SBruce Richardson u64 counter;
75*473c88f9SBruce Richardson
76*473c88f9SBruce Richardson spinlock_lock(&fme->lock);
77*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
78*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
79*473c88f9SBruce Richardson
80*473c88f9SBruce Richardson /* set channel access type and cache event code. */
81*473c88f9SBruce Richardson ctl.csr = readq(&iperf->ch_ctl);
82*473c88f9SBruce Richardson ctl.cci_chsel = channel;
83*473c88f9SBruce Richardson ctl.cache_event = event;
84*473c88f9SBruce Richardson writeq(ctl.csr, &iperf->ch_ctl);
85*473c88f9SBruce Richardson
86*473c88f9SBruce Richardson /* check the event type in the counter registers */
87*473c88f9SBruce Richardson ctr0.event_code = event;
88*473c88f9SBruce Richardson
89*473c88f9SBruce Richardson if (fpga_wait_register_field(event_code, ctr0,
90*473c88f9SBruce Richardson &iperf->ch_ctr0, IPERF_TIMEOUT, 1)) {
91*473c88f9SBruce Richardson dev_err(fme, "timeout, unmatched cache event type in counter registers.\n");
92*473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
93*473c88f9SBruce Richardson return -ETIMEDOUT;
94*473c88f9SBruce Richardson }
95*473c88f9SBruce Richardson
96*473c88f9SBruce Richardson ctr0.csr = readq(&iperf->ch_ctr0);
97*473c88f9SBruce Richardson ctr1.csr = readq(&iperf->ch_ctr1);
98*473c88f9SBruce Richardson counter = ctr0.cache_counter + ctr1.cache_counter;
99*473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
100*473c88f9SBruce Richardson
101*473c88f9SBruce Richardson return counter;
102*473c88f9SBruce Richardson }
103*473c88f9SBruce Richardson
104*473c88f9SBruce Richardson #define CACHE_SHOW(name, type, event) \
105*473c88f9SBruce Richardson static int fme_iperf_get_cache_##name(struct ifpga_fme_hw *fme, \
106*473c88f9SBruce Richardson u64 *counter) \
107*473c88f9SBruce Richardson { \
108*473c88f9SBruce Richardson *counter = read_cache_counter(fme, type, event); \
109*473c88f9SBruce Richardson return 0; \
110*473c88f9SBruce Richardson }
111*473c88f9SBruce Richardson
112*473c88f9SBruce Richardson CACHE_SHOW(read_hit, CACHE_CHANNEL_RD, IPERF_CACHE_RD_HIT);
113*473c88f9SBruce Richardson CACHE_SHOW(read_miss, CACHE_CHANNEL_RD, IPERF_CACHE_RD_MISS);
114*473c88f9SBruce Richardson CACHE_SHOW(write_hit, CACHE_CHANNEL_WR, IPERF_CACHE_WR_HIT);
115*473c88f9SBruce Richardson CACHE_SHOW(write_miss, CACHE_CHANNEL_WR, IPERF_CACHE_WR_MISS);
116*473c88f9SBruce Richardson CACHE_SHOW(hold_request, CACHE_CHANNEL_RD, IPERF_CACHE_HOLD_REQ);
117*473c88f9SBruce Richardson CACHE_SHOW(tx_req_stall, CACHE_CHANNEL_RD, IPERF_CACHE_TX_REQ_STALL);
118*473c88f9SBruce Richardson CACHE_SHOW(rx_req_stall, CACHE_CHANNEL_RD, IPERF_CACHE_RX_REQ_STALL);
119*473c88f9SBruce Richardson CACHE_SHOW(rx_eviction, CACHE_CHANNEL_RD, IPERF_CACHE_EVICTIONS);
120*473c88f9SBruce Richardson CACHE_SHOW(data_write_port_contention, CACHE_CHANNEL_WR,
121*473c88f9SBruce Richardson IPERF_CACHE_DATA_WR_PORT_CONTEN);
122*473c88f9SBruce Richardson CACHE_SHOW(tag_write_port_contention, CACHE_CHANNEL_WR,
123*473c88f9SBruce Richardson IPERF_CACHE_TAG_WR_PORT_CONTEN);
124*473c88f9SBruce Richardson
fme_iperf_get_vtd_freeze(struct ifpga_fme_hw * fme,u64 * freeze)125*473c88f9SBruce Richardson static int fme_iperf_get_vtd_freeze(struct ifpga_fme_hw *fme, u64 *freeze)
126*473c88f9SBruce Richardson {
127*473c88f9SBruce Richardson struct feature_fme_ifpmon_vtd_ctl ctl;
128*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
129*473c88f9SBruce Richardson
130*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
131*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
132*473c88f9SBruce Richardson ctl.csr = readq(&iperf->vtd_ctl);
133*473c88f9SBruce Richardson *freeze = (u64)ctl.freeze;
134*473c88f9SBruce Richardson
135*473c88f9SBruce Richardson return 0;
136*473c88f9SBruce Richardson }
137*473c88f9SBruce Richardson
fme_iperf_set_vtd_freeze(struct ifpga_fme_hw * fme,u64 freeze)138*473c88f9SBruce Richardson static int fme_iperf_set_vtd_freeze(struct ifpga_fme_hw *fme, u64 freeze)
139*473c88f9SBruce Richardson {
140*473c88f9SBruce Richardson struct feature_fme_ifpmon_vtd_ctl ctl;
141*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
142*473c88f9SBruce Richardson bool state;
143*473c88f9SBruce Richardson
144*473c88f9SBruce Richardson state = !!freeze;
145*473c88f9SBruce Richardson
146*473c88f9SBruce Richardson spinlock_lock(&fme->lock);
147*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
148*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
149*473c88f9SBruce Richardson ctl.csr = readq(&iperf->vtd_ctl);
150*473c88f9SBruce Richardson ctl.freeze = state;
151*473c88f9SBruce Richardson writeq(ctl.csr, &iperf->vtd_ctl);
152*473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
153*473c88f9SBruce Richardson
154*473c88f9SBruce Richardson return 0;
155*473c88f9SBruce Richardson }
156*473c88f9SBruce Richardson
read_iommu_sip_counter(struct ifpga_fme_hw * fme,enum iperf_vtd_sip_events event)157*473c88f9SBruce Richardson static u64 read_iommu_sip_counter(struct ifpga_fme_hw *fme,
158*473c88f9SBruce Richardson enum iperf_vtd_sip_events event)
159*473c88f9SBruce Richardson {
160*473c88f9SBruce Richardson struct feature_fme_ifpmon_vtd_sip_ctl sip_ctl;
161*473c88f9SBruce Richardson struct feature_fme_ifpmon_vtd_sip_ctr sip_ctr;
162*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
163*473c88f9SBruce Richardson u64 counter;
164*473c88f9SBruce Richardson
165*473c88f9SBruce Richardson spinlock_lock(&fme->lock);
166*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
167*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
168*473c88f9SBruce Richardson sip_ctl.csr = readq(&iperf->vtd_sip_ctl);
169*473c88f9SBruce Richardson sip_ctl.vtd_evtcode = event;
170*473c88f9SBruce Richardson writeq(sip_ctl.csr, &iperf->vtd_sip_ctl);
171*473c88f9SBruce Richardson
172*473c88f9SBruce Richardson sip_ctr.event_code = event;
173*473c88f9SBruce Richardson
174*473c88f9SBruce Richardson if (fpga_wait_register_field(event_code, sip_ctr,
175*473c88f9SBruce Richardson &iperf->vtd_sip_ctr, IPERF_TIMEOUT, 1)) {
176*473c88f9SBruce Richardson dev_err(fme, "timeout, unmatched VTd SIP event type in counter registers\n");
177*473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
178*473c88f9SBruce Richardson return -ETIMEDOUT;
179*473c88f9SBruce Richardson }
180*473c88f9SBruce Richardson
181*473c88f9SBruce Richardson sip_ctr.csr = readq(&iperf->vtd_sip_ctr);
182*473c88f9SBruce Richardson counter = sip_ctr.vtd_counter;
183*473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
184*473c88f9SBruce Richardson
185*473c88f9SBruce Richardson return counter;
186*473c88f9SBruce Richardson }
187*473c88f9SBruce Richardson
188*473c88f9SBruce Richardson #define VTD_SIP_SHOW(name, event) \
189*473c88f9SBruce Richardson static int fme_iperf_get_vtd_sip_##name(struct ifpga_fme_hw *fme, \
190*473c88f9SBruce Richardson u64 *counter) \
191*473c88f9SBruce Richardson { \
192*473c88f9SBruce Richardson *counter = read_iommu_sip_counter(fme, event); \
193*473c88f9SBruce Richardson return 0; \
194*473c88f9SBruce Richardson }
195*473c88f9SBruce Richardson
196*473c88f9SBruce Richardson VTD_SIP_SHOW(iotlb_4k_hit, IPERF_VTD_SIP_IOTLB_4K_HIT);
197*473c88f9SBruce Richardson VTD_SIP_SHOW(iotlb_2m_hit, IPERF_VTD_SIP_IOTLB_2M_HIT);
198*473c88f9SBruce Richardson VTD_SIP_SHOW(iotlb_1g_hit, IPERF_VTD_SIP_IOTLB_1G_HIT);
199*473c88f9SBruce Richardson VTD_SIP_SHOW(slpwc_l3_hit, IPERF_VTD_SIP_SLPWC_L3_HIT);
200*473c88f9SBruce Richardson VTD_SIP_SHOW(slpwc_l4_hit, IPERF_VTD_SIP_SLPWC_L4_HIT);
201*473c88f9SBruce Richardson VTD_SIP_SHOW(rcc_hit, IPERF_VTD_SIP_RCC_HIT);
202*473c88f9SBruce Richardson VTD_SIP_SHOW(iotlb_4k_miss, IPERF_VTD_SIP_IOTLB_4K_MISS);
203*473c88f9SBruce Richardson VTD_SIP_SHOW(iotlb_2m_miss, IPERF_VTD_SIP_IOTLB_2M_MISS);
204*473c88f9SBruce Richardson VTD_SIP_SHOW(iotlb_1g_miss, IPERF_VTD_SIP_IOTLB_1G_MISS);
205*473c88f9SBruce Richardson VTD_SIP_SHOW(slpwc_l3_miss, IPERF_VTD_SIP_SLPWC_L3_MISS);
206*473c88f9SBruce Richardson VTD_SIP_SHOW(slpwc_l4_miss, IPERF_VTD_SIP_SLPWC_L4_MISS);
207*473c88f9SBruce Richardson VTD_SIP_SHOW(rcc_miss, IPERF_VTD_SIP_RCC_MISS);
208*473c88f9SBruce Richardson
read_iommu_counter(struct ifpga_fme_hw * fme,u8 port_id,enum iperf_vtd_events base_event)209*473c88f9SBruce Richardson static u64 read_iommu_counter(struct ifpga_fme_hw *fme, u8 port_id,
210*473c88f9SBruce Richardson enum iperf_vtd_events base_event)
211*473c88f9SBruce Richardson {
212*473c88f9SBruce Richardson struct feature_fme_ifpmon_vtd_ctl ctl;
213*473c88f9SBruce Richardson struct feature_fme_ifpmon_vtd_ctr ctr;
214*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
215*473c88f9SBruce Richardson enum iperf_vtd_events event = base_event + port_id;
216*473c88f9SBruce Richardson u64 counter;
217*473c88f9SBruce Richardson
218*473c88f9SBruce Richardson spinlock_lock(&fme->lock);
219*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
220*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
221*473c88f9SBruce Richardson ctl.csr = readq(&iperf->vtd_ctl);
222*473c88f9SBruce Richardson ctl.vtd_evtcode = event;
223*473c88f9SBruce Richardson writeq(ctl.csr, &iperf->vtd_ctl);
224*473c88f9SBruce Richardson
225*473c88f9SBruce Richardson ctr.event_code = event;
226*473c88f9SBruce Richardson
227*473c88f9SBruce Richardson if (fpga_wait_register_field(event_code, ctr,
228*473c88f9SBruce Richardson &iperf->vtd_ctr, IPERF_TIMEOUT, 1)) {
229*473c88f9SBruce Richardson dev_err(fme, "timeout, unmatched VTd event type in counter registers.\n");
230*473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
231*473c88f9SBruce Richardson return -ETIMEDOUT;
232*473c88f9SBruce Richardson }
233*473c88f9SBruce Richardson
234*473c88f9SBruce Richardson ctr.csr = readq(&iperf->vtd_ctr);
235*473c88f9SBruce Richardson counter = ctr.vtd_counter;
236*473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
237*473c88f9SBruce Richardson
238*473c88f9SBruce Richardson return counter;
239*473c88f9SBruce Richardson }
240*473c88f9SBruce Richardson
241*473c88f9SBruce Richardson #define VTD_PORT_SHOW(name, base_event) \
242*473c88f9SBruce Richardson static int fme_iperf_get_vtd_port_##name(struct ifpga_fme_hw *fme, \
243*473c88f9SBruce Richardson u8 port_id, u64 *counter) \
244*473c88f9SBruce Richardson { \
245*473c88f9SBruce Richardson *counter = read_iommu_counter(fme, port_id, base_event); \
246*473c88f9SBruce Richardson return 0; \
247*473c88f9SBruce Richardson }
248*473c88f9SBruce Richardson
249*473c88f9SBruce Richardson VTD_PORT_SHOW(read_transaction, IPERF_VTD_AFU_MEM_RD_TRANS);
250*473c88f9SBruce Richardson VTD_PORT_SHOW(write_transaction, IPERF_VTD_AFU_MEM_WR_TRANS);
251*473c88f9SBruce Richardson VTD_PORT_SHOW(devtlb_read_hit, IPERF_VTD_AFU_DEVTLB_RD_HIT);
252*473c88f9SBruce Richardson VTD_PORT_SHOW(devtlb_write_hit, IPERF_VTD_AFU_DEVTLB_WR_HIT);
253*473c88f9SBruce Richardson VTD_PORT_SHOW(devtlb_4k_fill, IPERF_VTD_DEVTLB_4K_FILL);
254*473c88f9SBruce Richardson VTD_PORT_SHOW(devtlb_2m_fill, IPERF_VTD_DEVTLB_2M_FILL);
255*473c88f9SBruce Richardson VTD_PORT_SHOW(devtlb_1g_fill, IPERF_VTD_DEVTLB_1G_FILL);
256*473c88f9SBruce Richardson
fabric_pobj_is_enabled(u8 port_id,struct feature_fme_iperf * iperf)257*473c88f9SBruce Richardson static bool fabric_pobj_is_enabled(u8 port_id, struct feature_fme_iperf *iperf)
258*473c88f9SBruce Richardson {
259*473c88f9SBruce Richardson struct feature_fme_ifpmon_fab_ctl ctl;
260*473c88f9SBruce Richardson
261*473c88f9SBruce Richardson ctl.csr = readq(&iperf->fab_ctl);
262*473c88f9SBruce Richardson
263*473c88f9SBruce Richardson if (ctl.port_filter == FAB_DISABLE_FILTER)
264*473c88f9SBruce Richardson return port_id == PERF_OBJ_ROOT_ID;
265*473c88f9SBruce Richardson
266*473c88f9SBruce Richardson return port_id == ctl.port_id;
267*473c88f9SBruce Richardson }
268*473c88f9SBruce Richardson
read_fabric_counter(struct ifpga_fme_hw * fme,u8 port_id,enum iperf_fab_events fab_event)269*473c88f9SBruce Richardson static u64 read_fabric_counter(struct ifpga_fme_hw *fme, u8 port_id,
270*473c88f9SBruce Richardson enum iperf_fab_events fab_event)
271*473c88f9SBruce Richardson {
272*473c88f9SBruce Richardson struct feature_fme_ifpmon_fab_ctl ctl;
273*473c88f9SBruce Richardson struct feature_fme_ifpmon_fab_ctr ctr;
274*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
275*473c88f9SBruce Richardson u64 counter = 0;
276*473c88f9SBruce Richardson
277*473c88f9SBruce Richardson spinlock_lock(&fme->lock);
278*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
279*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
280*473c88f9SBruce Richardson
281*473c88f9SBruce Richardson /* if it is disabled, force the counter to return zero. */
282*473c88f9SBruce Richardson if (!fabric_pobj_is_enabled(port_id, iperf))
283*473c88f9SBruce Richardson goto exit;
284*473c88f9SBruce Richardson
285*473c88f9SBruce Richardson ctl.csr = readq(&iperf->fab_ctl);
286*473c88f9SBruce Richardson ctl.fab_evtcode = fab_event;
287*473c88f9SBruce Richardson writeq(ctl.csr, &iperf->fab_ctl);
288*473c88f9SBruce Richardson
289*473c88f9SBruce Richardson ctr.event_code = fab_event;
290*473c88f9SBruce Richardson
291*473c88f9SBruce Richardson if (fpga_wait_register_field(event_code, ctr,
292*473c88f9SBruce Richardson &iperf->fab_ctr, IPERF_TIMEOUT, 1)) {
293*473c88f9SBruce Richardson dev_err(fme, "timeout, unmatched VTd event type in counter registers.\n");
294*473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
295*473c88f9SBruce Richardson return -ETIMEDOUT;
296*473c88f9SBruce Richardson }
297*473c88f9SBruce Richardson
298*473c88f9SBruce Richardson ctr.csr = readq(&iperf->fab_ctr);
299*473c88f9SBruce Richardson counter = ctr.fab_cnt;
300*473c88f9SBruce Richardson exit:
301*473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
302*473c88f9SBruce Richardson return counter;
303*473c88f9SBruce Richardson }
304*473c88f9SBruce Richardson
305*473c88f9SBruce Richardson #define FAB_PORT_SHOW(name, event) \
306*473c88f9SBruce Richardson static int fme_iperf_get_fab_port_##name(struct ifpga_fme_hw *fme, \
307*473c88f9SBruce Richardson u8 port_id, u64 *counter) \
308*473c88f9SBruce Richardson { \
309*473c88f9SBruce Richardson *counter = read_fabric_counter(fme, port_id, event); \
310*473c88f9SBruce Richardson return 0; \
311*473c88f9SBruce Richardson }
312*473c88f9SBruce Richardson
313*473c88f9SBruce Richardson FAB_PORT_SHOW(pcie0_read, IPERF_FAB_PCIE0_RD);
314*473c88f9SBruce Richardson FAB_PORT_SHOW(pcie0_write, IPERF_FAB_PCIE0_WR);
315*473c88f9SBruce Richardson FAB_PORT_SHOW(pcie1_read, IPERF_FAB_PCIE1_RD);
316*473c88f9SBruce Richardson FAB_PORT_SHOW(pcie1_write, IPERF_FAB_PCIE1_WR);
317*473c88f9SBruce Richardson FAB_PORT_SHOW(upi_read, IPERF_FAB_UPI_RD);
318*473c88f9SBruce Richardson FAB_PORT_SHOW(upi_write, IPERF_FAB_UPI_WR);
319*473c88f9SBruce Richardson FAB_PORT_SHOW(mmio_read, IPERF_FAB_MMIO_RD);
320*473c88f9SBruce Richardson FAB_PORT_SHOW(mmio_write, IPERF_FAB_MMIO_WR);
321*473c88f9SBruce Richardson
fme_iperf_get_fab_port_enable(struct ifpga_fme_hw * fme,u8 port_id,u64 * enable)322*473c88f9SBruce Richardson static int fme_iperf_get_fab_port_enable(struct ifpga_fme_hw *fme,
323*473c88f9SBruce Richardson u8 port_id, u64 *enable)
324*473c88f9SBruce Richardson {
325*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
326*473c88f9SBruce Richardson int status;
327*473c88f9SBruce Richardson
328*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
329*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
330*473c88f9SBruce Richardson
331*473c88f9SBruce Richardson status = fabric_pobj_is_enabled(port_id, iperf);
332*473c88f9SBruce Richardson *enable = (u64)status;
333*473c88f9SBruce Richardson
334*473c88f9SBruce Richardson return 0;
335*473c88f9SBruce Richardson }
336*473c88f9SBruce Richardson
337*473c88f9SBruce Richardson /*
338*473c88f9SBruce Richardson * If enable one port or all port event counter in fabric, other
339*473c88f9SBruce Richardson * fabric event counter originally enabled will be disable automatically.
340*473c88f9SBruce Richardson */
fme_iperf_set_fab_port_enable(struct ifpga_fme_hw * fme,u8 port_id,u64 enable)341*473c88f9SBruce Richardson static int fme_iperf_set_fab_port_enable(struct ifpga_fme_hw *fme,
342*473c88f9SBruce Richardson u8 port_id, u64 enable)
343*473c88f9SBruce Richardson {
344*473c88f9SBruce Richardson struct feature_fme_ifpmon_fab_ctl ctl;
345*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
346*473c88f9SBruce Richardson bool state;
347*473c88f9SBruce Richardson
348*473c88f9SBruce Richardson state = !!enable;
349*473c88f9SBruce Richardson
350*473c88f9SBruce Richardson if (!state)
351*473c88f9SBruce Richardson return -EINVAL;
352*473c88f9SBruce Richardson
353*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
354*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
355*473c88f9SBruce Richardson
356*473c88f9SBruce Richardson /* if it is already enabled. */
357*473c88f9SBruce Richardson if (fabric_pobj_is_enabled(port_id, iperf))
358*473c88f9SBruce Richardson return 0;
359*473c88f9SBruce Richardson
360*473c88f9SBruce Richardson spinlock_lock(&fme->lock);
361*473c88f9SBruce Richardson ctl.csr = readq(&iperf->fab_ctl);
362*473c88f9SBruce Richardson if (port_id == PERF_OBJ_ROOT_ID) {
363*473c88f9SBruce Richardson ctl.port_filter = FAB_DISABLE_FILTER;
364*473c88f9SBruce Richardson } else {
365*473c88f9SBruce Richardson ctl.port_filter = FAB_ENABLE_FILTER;
366*473c88f9SBruce Richardson ctl.port_id = port_id;
367*473c88f9SBruce Richardson }
368*473c88f9SBruce Richardson
369*473c88f9SBruce Richardson writeq(ctl.csr, &iperf->fab_ctl);
370*473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
371*473c88f9SBruce Richardson
372*473c88f9SBruce Richardson return 0;
373*473c88f9SBruce Richardson }
374*473c88f9SBruce Richardson
fme_iperf_get_fab_freeze(struct ifpga_fme_hw * fme,u64 * freeze)375*473c88f9SBruce Richardson static int fme_iperf_get_fab_freeze(struct ifpga_fme_hw *fme, u64 *freeze)
376*473c88f9SBruce Richardson {
377*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
378*473c88f9SBruce Richardson struct feature_fme_ifpmon_fab_ctl ctl;
379*473c88f9SBruce Richardson
380*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
381*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
382*473c88f9SBruce Richardson ctl.csr = readq(&iperf->fab_ctl);
383*473c88f9SBruce Richardson *freeze = (u64)ctl.freeze;
384*473c88f9SBruce Richardson
385*473c88f9SBruce Richardson return 0;
386*473c88f9SBruce Richardson }
387*473c88f9SBruce Richardson
fme_iperf_set_fab_freeze(struct ifpga_fme_hw * fme,u64 freeze)388*473c88f9SBruce Richardson static int fme_iperf_set_fab_freeze(struct ifpga_fme_hw *fme, u64 freeze)
389*473c88f9SBruce Richardson {
390*473c88f9SBruce Richardson struct feature_fme_iperf *iperf;
391*473c88f9SBruce Richardson struct feature_fme_ifpmon_fab_ctl ctl;
392*473c88f9SBruce Richardson bool state;
393*473c88f9SBruce Richardson
394*473c88f9SBruce Richardson state = !!freeze;
395*473c88f9SBruce Richardson
396*473c88f9SBruce Richardson spinlock_lock(&fme->lock);
397*473c88f9SBruce Richardson iperf = get_fme_feature_ioaddr_by_index(fme,
398*473c88f9SBruce Richardson FME_FEATURE_ID_GLOBAL_IPERF);
399*473c88f9SBruce Richardson ctl.csr = readq(&iperf->fab_ctl);
400*473c88f9SBruce Richardson ctl.freeze = state;
401*473c88f9SBruce Richardson writeq(ctl.csr, &iperf->fab_ctl);
402*473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
403*473c88f9SBruce Richardson
404*473c88f9SBruce Richardson return 0;
405*473c88f9SBruce Richardson }
406*473c88f9SBruce Richardson
407*473c88f9SBruce Richardson #define PERF_MAX_PORT_NUM 1
408*473c88f9SBruce Richardson #define FME_IPERF_CAP_IOMMU 0x1
409*473c88f9SBruce Richardson
fme_global_iperf_init(struct ifpga_feature * feature)410*473c88f9SBruce Richardson static int fme_global_iperf_init(struct ifpga_feature *feature)
411*473c88f9SBruce Richardson {
412*473c88f9SBruce Richardson struct ifpga_fme_hw *fme;
413*473c88f9SBruce Richardson struct feature_fme_header *fme_hdr;
414*473c88f9SBruce Richardson struct feature_fme_capability fme_capability;
415*473c88f9SBruce Richardson
416*473c88f9SBruce Richardson dev_info(NULL, "FME global_iperf Init.\n");
417*473c88f9SBruce Richardson
418*473c88f9SBruce Richardson fme = (struct ifpga_fme_hw *)feature->parent;
419*473c88f9SBruce Richardson fme_hdr = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
420*473c88f9SBruce Richardson
421*473c88f9SBruce Richardson /* check if iommu is not supported on this device. */
422*473c88f9SBruce Richardson fme_capability.csr = readq(&fme_hdr->capability);
423*473c88f9SBruce Richardson dev_info(NULL, "FME HEAD fme_capability %llx.\n",
424*473c88f9SBruce Richardson (unsigned long long)fme_hdr->capability.csr);
425*473c88f9SBruce Richardson
426*473c88f9SBruce Richardson if (fme_capability.iommu_support)
427*473c88f9SBruce Richardson feature->cap |= FME_IPERF_CAP_IOMMU;
428*473c88f9SBruce Richardson
429*473c88f9SBruce Richardson return 0;
430*473c88f9SBruce Richardson }
431*473c88f9SBruce Richardson
fme_global_iperf_uinit(struct ifpga_feature * feature)432*473c88f9SBruce Richardson static void fme_global_iperf_uinit(struct ifpga_feature *feature)
433*473c88f9SBruce Richardson {
434*473c88f9SBruce Richardson UNUSED(feature);
435*473c88f9SBruce Richardson
436*473c88f9SBruce Richardson dev_info(NULL, "FME global_iperf UInit.\n");
437*473c88f9SBruce Richardson }
438*473c88f9SBruce Richardson
fme_iperf_root_get_prop(struct ifpga_feature * feature,struct feature_prop * prop)439*473c88f9SBruce Richardson static int fme_iperf_root_get_prop(struct ifpga_feature *feature,
440*473c88f9SBruce Richardson struct feature_prop *prop)
441*473c88f9SBruce Richardson {
442*473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
443*473c88f9SBruce Richardson u8 sub = GET_FIELD(PROP_SUB, prop->prop_id);
444*473c88f9SBruce Richardson u16 id = GET_FIELD(PROP_ID, prop->prop_id);
445*473c88f9SBruce Richardson
446*473c88f9SBruce Richardson if (sub != PERF_PROP_SUB_UNUSED)
447*473c88f9SBruce Richardson return -ENOENT;
448*473c88f9SBruce Richardson
449*473c88f9SBruce Richardson switch (id) {
450*473c88f9SBruce Richardson case 0x1: /* CLOCK */
451*473c88f9SBruce Richardson return fme_iperf_get_clock(fme, &prop->data);
452*473c88f9SBruce Richardson case 0x2: /* REVISION */
453*473c88f9SBruce Richardson return fme_iperf_get_revision(fme, &prop->data);
454*473c88f9SBruce Richardson }
455*473c88f9SBruce Richardson
456*473c88f9SBruce Richardson return -ENOENT;
457*473c88f9SBruce Richardson }
458*473c88f9SBruce Richardson
fme_iperf_cache_get_prop(struct ifpga_feature * feature,struct feature_prop * prop)459*473c88f9SBruce Richardson static int fme_iperf_cache_get_prop(struct ifpga_feature *feature,
460*473c88f9SBruce Richardson struct feature_prop *prop)
461*473c88f9SBruce Richardson {
462*473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
463*473c88f9SBruce Richardson u8 sub = GET_FIELD(PROP_SUB, prop->prop_id);
464*473c88f9SBruce Richardson u16 id = GET_FIELD(PROP_ID, prop->prop_id);
465*473c88f9SBruce Richardson
466*473c88f9SBruce Richardson if (sub != PERF_PROP_SUB_UNUSED)
467*473c88f9SBruce Richardson return -ENOENT;
468*473c88f9SBruce Richardson
469*473c88f9SBruce Richardson switch (id) {
470*473c88f9SBruce Richardson case 0x1: /* FREEZE */
471*473c88f9SBruce Richardson return fme_iperf_get_cache_freeze(fme, &prop->data);
472*473c88f9SBruce Richardson case 0x2: /* READ_HIT */
473*473c88f9SBruce Richardson return fme_iperf_get_cache_read_hit(fme, &prop->data);
474*473c88f9SBruce Richardson case 0x3: /* READ_MISS */
475*473c88f9SBruce Richardson return fme_iperf_get_cache_read_miss(fme, &prop->data);
476*473c88f9SBruce Richardson case 0x4: /* WRITE_HIT */
477*473c88f9SBruce Richardson return fme_iperf_get_cache_write_hit(fme, &prop->data);
478*473c88f9SBruce Richardson case 0x5: /* WRITE_MISS */
479*473c88f9SBruce Richardson return fme_iperf_get_cache_write_miss(fme, &prop->data);
480*473c88f9SBruce Richardson case 0x6: /* HOLD_REQUEST */
481*473c88f9SBruce Richardson return fme_iperf_get_cache_hold_request(fme, &prop->data);
482*473c88f9SBruce Richardson case 0x7: /* TX_REQ_STALL */
483*473c88f9SBruce Richardson return fme_iperf_get_cache_tx_req_stall(fme, &prop->data);
484*473c88f9SBruce Richardson case 0x8: /* RX_REQ_STALL */
485*473c88f9SBruce Richardson return fme_iperf_get_cache_rx_req_stall(fme, &prop->data);
486*473c88f9SBruce Richardson case 0x9: /* RX_EVICTION */
487*473c88f9SBruce Richardson return fme_iperf_get_cache_rx_eviction(fme, &prop->data);
488*473c88f9SBruce Richardson case 0xa: /* DATA_WRITE_PORT_CONTENTION */
489*473c88f9SBruce Richardson return fme_iperf_get_cache_data_write_port_contention(fme,
490*473c88f9SBruce Richardson &prop->data);
491*473c88f9SBruce Richardson case 0xb: /* TAG_WRITE_PORT_CONTENTION */
492*473c88f9SBruce Richardson return fme_iperf_get_cache_tag_write_port_contention(fme,
493*473c88f9SBruce Richardson &prop->data);
494*473c88f9SBruce Richardson }
495*473c88f9SBruce Richardson
496*473c88f9SBruce Richardson return -ENOENT;
497*473c88f9SBruce Richardson }
498*473c88f9SBruce Richardson
fme_iperf_vtd_root_get_prop(struct ifpga_feature * feature,struct feature_prop * prop)499*473c88f9SBruce Richardson static int fme_iperf_vtd_root_get_prop(struct ifpga_feature *feature,
500*473c88f9SBruce Richardson struct feature_prop *prop)
501*473c88f9SBruce Richardson {
502*473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
503*473c88f9SBruce Richardson u16 id = GET_FIELD(PROP_ID, prop->prop_id);
504*473c88f9SBruce Richardson
505*473c88f9SBruce Richardson switch (id) {
506*473c88f9SBruce Richardson case 0x1: /* FREEZE */
507*473c88f9SBruce Richardson return fme_iperf_get_vtd_freeze(fme, &prop->data);
508*473c88f9SBruce Richardson case 0x2: /* IOTLB_4K_HIT */
509*473c88f9SBruce Richardson return fme_iperf_get_vtd_sip_iotlb_4k_hit(fme, &prop->data);
510*473c88f9SBruce Richardson case 0x3: /* IOTLB_2M_HIT */
511*473c88f9SBruce Richardson return fme_iperf_get_vtd_sip_iotlb_2m_hit(fme, &prop->data);
512*473c88f9SBruce Richardson case 0x4: /* IOTLB_1G_HIT */
513*473c88f9SBruce Richardson return fme_iperf_get_vtd_sip_iotlb_1g_hit(fme, &prop->data);
514*473c88f9SBruce Richardson case 0x5: /* SLPWC_L3_HIT */
515*473c88f9SBruce Richardson return fme_iperf_get_vtd_sip_slpwc_l3_hit(fme, &prop->data);
516*473c88f9SBruce Richardson case 0x6: /* SLPWC_L4_HIT */
517*473c88f9SBruce Richardson return fme_iperf_get_vtd_sip_slpwc_l4_hit(fme, &prop->data);
518*473c88f9SBruce Richardson case 0x7: /* RCC_HIT */
519*473c88f9SBruce Richardson return fme_iperf_get_vtd_sip_rcc_hit(fme, &prop->data);
520*473c88f9SBruce Richardson case 0x8: /* IOTLB_4K_MISS */
521*473c88f9SBruce Richardson return fme_iperf_get_vtd_sip_iotlb_4k_miss(fme, &prop->data);
522*473c88f9SBruce Richardson case 0x9: /* IOTLB_2M_MISS */
523*473c88f9SBruce Richardson return fme_iperf_get_vtd_sip_iotlb_2m_miss(fme, &prop->data);
524*473c88f9SBruce Richardson case 0xa: /* IOTLB_1G_MISS */
525*473c88f9SBruce Richardson return fme_iperf_get_vtd_sip_iotlb_1g_miss(fme, &prop->data);
526*473c88f9SBruce Richardson case 0xb: /* SLPWC_L3_MISS */
527*473c88f9SBruce Richardson return fme_iperf_get_vtd_sip_slpwc_l3_miss(fme, &prop->data);
528*473c88f9SBruce Richardson case 0xc: /* SLPWC_L4_MISS */
529*473c88f9SBruce Richardson return fme_iperf_get_vtd_sip_slpwc_l4_miss(fme, &prop->data);
530*473c88f9SBruce Richardson case 0xd: /* RCC_MISS */
531*473c88f9SBruce Richardson return fme_iperf_get_vtd_sip_rcc_miss(fme, &prop->data);
532*473c88f9SBruce Richardson }
533*473c88f9SBruce Richardson
534*473c88f9SBruce Richardson return -ENOENT;
535*473c88f9SBruce Richardson }
536*473c88f9SBruce Richardson
fme_iperf_vtd_sub_get_prop(struct ifpga_feature * feature,struct feature_prop * prop)537*473c88f9SBruce Richardson static int fme_iperf_vtd_sub_get_prop(struct ifpga_feature *feature,
538*473c88f9SBruce Richardson struct feature_prop *prop)
539*473c88f9SBruce Richardson {
540*473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
541*473c88f9SBruce Richardson u16 id = GET_FIELD(PROP_ID, prop->prop_id);
542*473c88f9SBruce Richardson u8 sub = GET_FIELD(PROP_SUB, prop->prop_id);
543*473c88f9SBruce Richardson
544*473c88f9SBruce Richardson if (sub > PERF_MAX_PORT_NUM)
545*473c88f9SBruce Richardson return -ENOENT;
546*473c88f9SBruce Richardson
547*473c88f9SBruce Richardson switch (id) {
548*473c88f9SBruce Richardson case 0xe: /* READ_TRANSACTION */
549*473c88f9SBruce Richardson return fme_iperf_get_vtd_port_read_transaction(fme, sub,
550*473c88f9SBruce Richardson &prop->data);
551*473c88f9SBruce Richardson case 0xf: /* WRITE_TRANSACTION */
552*473c88f9SBruce Richardson return fme_iperf_get_vtd_port_write_transaction(fme, sub,
553*473c88f9SBruce Richardson &prop->data);
554*473c88f9SBruce Richardson case 0x10: /* DEVTLB_READ_HIT */
555*473c88f9SBruce Richardson return fme_iperf_get_vtd_port_devtlb_read_hit(fme, sub,
556*473c88f9SBruce Richardson &prop->data);
557*473c88f9SBruce Richardson case 0x11: /* DEVTLB_WRITE_HIT */
558*473c88f9SBruce Richardson return fme_iperf_get_vtd_port_devtlb_write_hit(fme, sub,
559*473c88f9SBruce Richardson &prop->data);
560*473c88f9SBruce Richardson case 0x12: /* DEVTLB_4K_FILL */
561*473c88f9SBruce Richardson return fme_iperf_get_vtd_port_devtlb_4k_fill(fme, sub,
562*473c88f9SBruce Richardson &prop->data);
563*473c88f9SBruce Richardson case 0x13: /* DEVTLB_2M_FILL */
564*473c88f9SBruce Richardson return fme_iperf_get_vtd_port_devtlb_2m_fill(fme, sub,
565*473c88f9SBruce Richardson &prop->data);
566*473c88f9SBruce Richardson case 0x14: /* DEVTLB_1G_FILL */
567*473c88f9SBruce Richardson return fme_iperf_get_vtd_port_devtlb_1g_fill(fme, sub,
568*473c88f9SBruce Richardson &prop->data);
569*473c88f9SBruce Richardson }
570*473c88f9SBruce Richardson
571*473c88f9SBruce Richardson return -ENOENT;
572*473c88f9SBruce Richardson }
573*473c88f9SBruce Richardson
fme_iperf_vtd_get_prop(struct ifpga_feature * feature,struct feature_prop * prop)574*473c88f9SBruce Richardson static int fme_iperf_vtd_get_prop(struct ifpga_feature *feature,
575*473c88f9SBruce Richardson struct feature_prop *prop)
576*473c88f9SBruce Richardson {
577*473c88f9SBruce Richardson u8 sub = GET_FIELD(PROP_SUB, prop->prop_id);
578*473c88f9SBruce Richardson
579*473c88f9SBruce Richardson if (sub == PERF_PROP_SUB_UNUSED)
580*473c88f9SBruce Richardson return fme_iperf_vtd_root_get_prop(feature, prop);
581*473c88f9SBruce Richardson
582*473c88f9SBruce Richardson return fme_iperf_vtd_sub_get_prop(feature, prop);
583*473c88f9SBruce Richardson }
584*473c88f9SBruce Richardson
fme_iperf_fab_get_prop(struct ifpga_feature * feature,struct feature_prop * prop)585*473c88f9SBruce Richardson static int fme_iperf_fab_get_prop(struct ifpga_feature *feature,
586*473c88f9SBruce Richardson struct feature_prop *prop)
587*473c88f9SBruce Richardson {
588*473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
589*473c88f9SBruce Richardson u8 sub = GET_FIELD(PROP_SUB, prop->prop_id);
590*473c88f9SBruce Richardson u16 id = GET_FIELD(PROP_ID, prop->prop_id);
591*473c88f9SBruce Richardson
592*473c88f9SBruce Richardson /* Other properties are present for both top and sub levels */
593*473c88f9SBruce Richardson switch (id) {
594*473c88f9SBruce Richardson case 0x1: /* FREEZE */
595*473c88f9SBruce Richardson if (sub != PERF_PROP_SUB_UNUSED)
596*473c88f9SBruce Richardson return -ENOENT;
597*473c88f9SBruce Richardson return fme_iperf_get_fab_freeze(fme, &prop->data);
598*473c88f9SBruce Richardson case 0x2: /* PCIE0_READ */
599*473c88f9SBruce Richardson return fme_iperf_get_fab_port_pcie0_read(fme, sub,
600*473c88f9SBruce Richardson &prop->data);
601*473c88f9SBruce Richardson case 0x3: /* PCIE0_WRITE */
602*473c88f9SBruce Richardson return fme_iperf_get_fab_port_pcie0_write(fme, sub,
603*473c88f9SBruce Richardson &prop->data);
604*473c88f9SBruce Richardson case 0x4: /* PCIE1_READ */
605*473c88f9SBruce Richardson return fme_iperf_get_fab_port_pcie1_read(fme, sub,
606*473c88f9SBruce Richardson &prop->data);
607*473c88f9SBruce Richardson case 0x5: /* PCIE1_WRITE */
608*473c88f9SBruce Richardson return fme_iperf_get_fab_port_pcie1_write(fme, sub,
609*473c88f9SBruce Richardson &prop->data);
610*473c88f9SBruce Richardson case 0x6: /* UPI_READ */
611*473c88f9SBruce Richardson return fme_iperf_get_fab_port_upi_read(fme, sub,
612*473c88f9SBruce Richardson &prop->data);
613*473c88f9SBruce Richardson case 0x7: /* UPI_WRITE */
614*473c88f9SBruce Richardson return fme_iperf_get_fab_port_upi_write(fme, sub,
615*473c88f9SBruce Richardson &prop->data);
616*473c88f9SBruce Richardson case 0x8: /* MMIO_READ */
617*473c88f9SBruce Richardson return fme_iperf_get_fab_port_mmio_read(fme, sub,
618*473c88f9SBruce Richardson &prop->data);
619*473c88f9SBruce Richardson case 0x9: /* MMIO_WRITE */
620*473c88f9SBruce Richardson return fme_iperf_get_fab_port_mmio_write(fme, sub,
621*473c88f9SBruce Richardson &prop->data);
622*473c88f9SBruce Richardson case 0xa: /* ENABLE */
623*473c88f9SBruce Richardson return fme_iperf_get_fab_port_enable(fme, sub, &prop->data);
624*473c88f9SBruce Richardson }
625*473c88f9SBruce Richardson
626*473c88f9SBruce Richardson return -ENOENT;
627*473c88f9SBruce Richardson }
628*473c88f9SBruce Richardson
fme_global_iperf_get_prop(struct ifpga_feature * feature,struct feature_prop * prop)629*473c88f9SBruce Richardson static int fme_global_iperf_get_prop(struct ifpga_feature *feature,
630*473c88f9SBruce Richardson struct feature_prop *prop)
631*473c88f9SBruce Richardson {
632*473c88f9SBruce Richardson u8 top = GET_FIELD(PROP_TOP, prop->prop_id);
633*473c88f9SBruce Richardson
634*473c88f9SBruce Richardson switch (top) {
635*473c88f9SBruce Richardson case PERF_PROP_TOP_CACHE:
636*473c88f9SBruce Richardson return fme_iperf_cache_get_prop(feature, prop);
637*473c88f9SBruce Richardson case PERF_PROP_TOP_VTD:
638*473c88f9SBruce Richardson return fme_iperf_vtd_get_prop(feature, prop);
639*473c88f9SBruce Richardson case PERF_PROP_TOP_FAB:
640*473c88f9SBruce Richardson return fme_iperf_fab_get_prop(feature, prop);
641*473c88f9SBruce Richardson case PERF_PROP_TOP_UNUSED:
642*473c88f9SBruce Richardson return fme_iperf_root_get_prop(feature, prop);
643*473c88f9SBruce Richardson }
644*473c88f9SBruce Richardson
645*473c88f9SBruce Richardson return -ENOENT;
646*473c88f9SBruce Richardson }
647*473c88f9SBruce Richardson
fme_iperf_cache_set_prop(struct ifpga_feature * feature,struct feature_prop * prop)648*473c88f9SBruce Richardson static int fme_iperf_cache_set_prop(struct ifpga_feature *feature,
649*473c88f9SBruce Richardson struct feature_prop *prop)
650*473c88f9SBruce Richardson {
651*473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
652*473c88f9SBruce Richardson u8 sub = GET_FIELD(PROP_SUB, prop->prop_id);
653*473c88f9SBruce Richardson u16 id = GET_FIELD(PROP_ID, prop->prop_id);
654*473c88f9SBruce Richardson
655*473c88f9SBruce Richardson if (sub == PERF_PROP_SUB_UNUSED && id == 0x1) /* FREEZE */
656*473c88f9SBruce Richardson return fme_iperf_set_cache_freeze(fme, prop->data);
657*473c88f9SBruce Richardson
658*473c88f9SBruce Richardson return -ENOENT;
659*473c88f9SBruce Richardson }
660*473c88f9SBruce Richardson
fme_iperf_vtd_set_prop(struct ifpga_feature * feature,struct feature_prop * prop)661*473c88f9SBruce Richardson static int fme_iperf_vtd_set_prop(struct ifpga_feature *feature,
662*473c88f9SBruce Richardson struct feature_prop *prop)
663*473c88f9SBruce Richardson {
664*473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
665*473c88f9SBruce Richardson u8 sub = GET_FIELD(PROP_SUB, prop->prop_id);
666*473c88f9SBruce Richardson u16 id = GET_FIELD(PROP_ID, prop->prop_id);
667*473c88f9SBruce Richardson
668*473c88f9SBruce Richardson if (sub == PERF_PROP_SUB_UNUSED && id == 0x1) /* FREEZE */
669*473c88f9SBruce Richardson return fme_iperf_set_vtd_freeze(fme, prop->data);
670*473c88f9SBruce Richardson
671*473c88f9SBruce Richardson return -ENOENT;
672*473c88f9SBruce Richardson }
673*473c88f9SBruce Richardson
fme_iperf_fab_set_prop(struct ifpga_feature * feature,struct feature_prop * prop)674*473c88f9SBruce Richardson static int fme_iperf_fab_set_prop(struct ifpga_feature *feature,
675*473c88f9SBruce Richardson struct feature_prop *prop)
676*473c88f9SBruce Richardson {
677*473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
678*473c88f9SBruce Richardson u8 sub = GET_FIELD(PROP_SUB, prop->prop_id);
679*473c88f9SBruce Richardson u16 id = GET_FIELD(PROP_ID, prop->prop_id);
680*473c88f9SBruce Richardson
681*473c88f9SBruce Richardson switch (id) {
682*473c88f9SBruce Richardson case 0x1: /* FREEZE */
683*473c88f9SBruce Richardson if (sub != PERF_PROP_SUB_UNUSED)
684*473c88f9SBruce Richardson return -ENOENT;
685*473c88f9SBruce Richardson return fme_iperf_set_fab_freeze(fme, prop->data);
686*473c88f9SBruce Richardson case 0xa: /* ENABLE */
687*473c88f9SBruce Richardson return fme_iperf_set_fab_port_enable(fme, sub, prop->data);
688*473c88f9SBruce Richardson }
689*473c88f9SBruce Richardson
690*473c88f9SBruce Richardson return -ENOENT;
691*473c88f9SBruce Richardson }
692*473c88f9SBruce Richardson
fme_global_iperf_set_prop(struct ifpga_feature * feature,struct feature_prop * prop)693*473c88f9SBruce Richardson static int fme_global_iperf_set_prop(struct ifpga_feature *feature,
694*473c88f9SBruce Richardson struct feature_prop *prop)
695*473c88f9SBruce Richardson {
696*473c88f9SBruce Richardson u8 top = GET_FIELD(PROP_TOP, prop->prop_id);
697*473c88f9SBruce Richardson
698*473c88f9SBruce Richardson switch (top) {
699*473c88f9SBruce Richardson case PERF_PROP_TOP_CACHE:
700*473c88f9SBruce Richardson return fme_iperf_cache_set_prop(feature, prop);
701*473c88f9SBruce Richardson case PERF_PROP_TOP_VTD:
702*473c88f9SBruce Richardson return fme_iperf_vtd_set_prop(feature, prop);
703*473c88f9SBruce Richardson case PERF_PROP_TOP_FAB:
704*473c88f9SBruce Richardson return fme_iperf_fab_set_prop(feature, prop);
705*473c88f9SBruce Richardson }
706*473c88f9SBruce Richardson
707*473c88f9SBruce Richardson return -ENOENT;
708*473c88f9SBruce Richardson }
709*473c88f9SBruce Richardson
710*473c88f9SBruce Richardson struct ifpga_feature_ops fme_global_iperf_ops = {
711*473c88f9SBruce Richardson .init = fme_global_iperf_init,
712*473c88f9SBruce Richardson .uinit = fme_global_iperf_uinit,
713*473c88f9SBruce Richardson .get_prop = fme_global_iperf_get_prop,
714*473c88f9SBruce Richardson .set_prop = fme_global_iperf_set_prop,
715*473c88f9SBruce Richardson };
716