1*a4b16dadSTom Zanussi // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
2*a4b16dadSTom Zanussi /* Copyright(c) 2021 Intel Corporation */
3*a4b16dadSTom Zanussi #include <linux/delay.h>
4*a4b16dadSTom Zanussi #include <linux/iopoll.h>
5*a4b16dadSTom Zanussi #include <linux/mutex.h>
6*a4b16dadSTom Zanussi #include <linux/types.h>
7*a4b16dadSTom Zanussi #include "adf_accel_devices.h"
8*a4b16dadSTom Zanussi #include "adf_common_drv.h"
9*a4b16dadSTom Zanussi #include "adf_gen2_pfvf.h"
10*a4b16dadSTom Zanussi #include "adf_pfvf_msg.h"
11*a4b16dadSTom Zanussi #include "adf_pfvf_pf_proto.h"
12*a4b16dadSTom Zanussi #include "adf_pfvf_vf_proto.h"
13*a4b16dadSTom Zanussi #include "adf_pfvf_utils.h"
14*a4b16dadSTom Zanussi
15*a4b16dadSTom Zanussi /* VF2PF interrupts */
16*a4b16dadSTom Zanussi #define ADF_GEN2_VF_MSK 0xFFFF
17*a4b16dadSTom Zanussi #define ADF_GEN2_ERR_REG_VF2PF(vf_src) (((vf_src) & 0x01FFFE00) >> 9)
18*a4b16dadSTom Zanussi #define ADF_GEN2_ERR_MSK_VF2PF(vf_mask) (((vf_mask) & ADF_GEN2_VF_MSK) << 9)
19*a4b16dadSTom Zanussi
20*a4b16dadSTom Zanussi #define ADF_GEN2_PF_PF2VF_OFFSET(i) (0x3A000 + 0x280 + ((i) * 0x04))
21*a4b16dadSTom Zanussi #define ADF_GEN2_VF_PF2VF_OFFSET 0x200
22*a4b16dadSTom Zanussi
23*a4b16dadSTom Zanussi #define ADF_GEN2_CSR_IN_USE 0x6AC2
24*a4b16dadSTom Zanussi #define ADF_GEN2_CSR_IN_USE_MASK 0xFFFE
25*a4b16dadSTom Zanussi
26*a4b16dadSTom Zanussi enum gen2_csr_pos {
27*a4b16dadSTom Zanussi ADF_GEN2_CSR_PF2VF_OFFSET = 0,
28*a4b16dadSTom Zanussi ADF_GEN2_CSR_VF2PF_OFFSET = 16,
29*a4b16dadSTom Zanussi };
30*a4b16dadSTom Zanussi
31*a4b16dadSTom Zanussi #define ADF_PFVF_GEN2_MSGTYPE_SHIFT 2
32*a4b16dadSTom Zanussi #define ADF_PFVF_GEN2_MSGTYPE_MASK 0x0F
33*a4b16dadSTom Zanussi #define ADF_PFVF_GEN2_MSGDATA_SHIFT 6
34*a4b16dadSTom Zanussi #define ADF_PFVF_GEN2_MSGDATA_MASK 0x3FF
35*a4b16dadSTom Zanussi
36*a4b16dadSTom Zanussi static const struct pfvf_csr_format csr_gen2_fmt = {
37*a4b16dadSTom Zanussi { ADF_PFVF_GEN2_MSGTYPE_SHIFT, ADF_PFVF_GEN2_MSGTYPE_MASK },
38*a4b16dadSTom Zanussi { ADF_PFVF_GEN2_MSGDATA_SHIFT, ADF_PFVF_GEN2_MSGDATA_MASK },
39*a4b16dadSTom Zanussi };
40*a4b16dadSTom Zanussi
41*a4b16dadSTom Zanussi #define ADF_PFVF_MSG_RETRY_DELAY 5
42*a4b16dadSTom Zanussi #define ADF_PFVF_MSG_MAX_RETRIES 3
43*a4b16dadSTom Zanussi
adf_gen2_pf_get_pfvf_offset(u32 i)44*a4b16dadSTom Zanussi static u32 adf_gen2_pf_get_pfvf_offset(u32 i)
45*a4b16dadSTom Zanussi {
46*a4b16dadSTom Zanussi return ADF_GEN2_PF_PF2VF_OFFSET(i);
47*a4b16dadSTom Zanussi }
48*a4b16dadSTom Zanussi
adf_gen2_vf_get_pfvf_offset(u32 i)49*a4b16dadSTom Zanussi static u32 adf_gen2_vf_get_pfvf_offset(u32 i)
50*a4b16dadSTom Zanussi {
51*a4b16dadSTom Zanussi return ADF_GEN2_VF_PF2VF_OFFSET;
52*a4b16dadSTom Zanussi }
53*a4b16dadSTom Zanussi
adf_gen2_enable_vf2pf_interrupts(void __iomem * pmisc_addr,u32 vf_mask)54*a4b16dadSTom Zanussi static void adf_gen2_enable_vf2pf_interrupts(void __iomem *pmisc_addr, u32 vf_mask)
55*a4b16dadSTom Zanussi {
56*a4b16dadSTom Zanussi /* Enable VF2PF Messaging Ints - VFs 0 through 15 per vf_mask[15:0] */
57*a4b16dadSTom Zanussi if (vf_mask & ADF_GEN2_VF_MSK) {
58*a4b16dadSTom Zanussi u32 val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK3)
59*a4b16dadSTom Zanussi & ~ADF_GEN2_ERR_MSK_VF2PF(vf_mask);
60*a4b16dadSTom Zanussi ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, val);
61*a4b16dadSTom Zanussi }
62*a4b16dadSTom Zanussi }
63*a4b16dadSTom Zanussi
adf_gen2_disable_all_vf2pf_interrupts(void __iomem * pmisc_addr)64*a4b16dadSTom Zanussi static void adf_gen2_disable_all_vf2pf_interrupts(void __iomem *pmisc_addr)
65*a4b16dadSTom Zanussi {
66*a4b16dadSTom Zanussi /* Disable VF2PF interrupts for VFs 0 through 15 per vf_mask[15:0] */
67*a4b16dadSTom Zanussi u32 val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK3)
68*a4b16dadSTom Zanussi | ADF_GEN2_ERR_MSK_VF2PF(ADF_GEN2_VF_MSK);
69*a4b16dadSTom Zanussi ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, val);
70*a4b16dadSTom Zanussi }
71*a4b16dadSTom Zanussi
adf_gen2_disable_pending_vf2pf_interrupts(void __iomem * pmisc_addr)72*a4b16dadSTom Zanussi static u32 adf_gen2_disable_pending_vf2pf_interrupts(void __iomem *pmisc_addr)
73*a4b16dadSTom Zanussi {
74*a4b16dadSTom Zanussi u32 sources, disabled, pending;
75*a4b16dadSTom Zanussi u32 errsou3, errmsk3;
76*a4b16dadSTom Zanussi
77*a4b16dadSTom Zanussi /* Get the interrupt sources triggered by VFs */
78*a4b16dadSTom Zanussi errsou3 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRSOU3);
79*a4b16dadSTom Zanussi sources = ADF_GEN2_ERR_REG_VF2PF(errsou3);
80*a4b16dadSTom Zanussi
81*a4b16dadSTom Zanussi if (!sources)
82*a4b16dadSTom Zanussi return 0;
83*a4b16dadSTom Zanussi
84*a4b16dadSTom Zanussi /* Get the already disabled interrupts */
85*a4b16dadSTom Zanussi errmsk3 = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK3);
86*a4b16dadSTom Zanussi disabled = ADF_GEN2_ERR_REG_VF2PF(errmsk3);
87*a4b16dadSTom Zanussi
88*a4b16dadSTom Zanussi pending = sources & ~disabled;
89*a4b16dadSTom Zanussi if (!pending)
90*a4b16dadSTom Zanussi return 0;
91*a4b16dadSTom Zanussi
92*a4b16dadSTom Zanussi /* Due to HW limitations, when disabling the interrupts, we can't
93*a4b16dadSTom Zanussi * just disable the requested sources, as this would lead to missed
94*a4b16dadSTom Zanussi * interrupts if ERRSOU3 changes just before writing to ERRMSK3.
95*a4b16dadSTom Zanussi * To work around it, disable all and re-enable only the sources that
96*a4b16dadSTom Zanussi * are not in vf_mask and were not already disabled. Re-enabling will
97*a4b16dadSTom Zanussi * trigger a new interrupt for the sources that have changed in the
98*a4b16dadSTom Zanussi * meantime, if any.
99*a4b16dadSTom Zanussi */
100*a4b16dadSTom Zanussi errmsk3 |= ADF_GEN2_ERR_MSK_VF2PF(ADF_GEN2_VF_MSK);
101*a4b16dadSTom Zanussi ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3);
102*a4b16dadSTom Zanussi
103*a4b16dadSTom Zanussi errmsk3 &= ADF_GEN2_ERR_MSK_VF2PF(sources | disabled);
104*a4b16dadSTom Zanussi ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3);
105*a4b16dadSTom Zanussi
106*a4b16dadSTom Zanussi /* Return the sources of the (new) interrupt(s) */
107*a4b16dadSTom Zanussi return pending;
108*a4b16dadSTom Zanussi }
109*a4b16dadSTom Zanussi
gen2_csr_get_int_bit(enum gen2_csr_pos offset)110*a4b16dadSTom Zanussi static u32 gen2_csr_get_int_bit(enum gen2_csr_pos offset)
111*a4b16dadSTom Zanussi {
112*a4b16dadSTom Zanussi return ADF_PFVF_INT << offset;
113*a4b16dadSTom Zanussi }
114*a4b16dadSTom Zanussi
gen2_csr_msg_to_position(u32 csr_msg,enum gen2_csr_pos offset)115*a4b16dadSTom Zanussi static u32 gen2_csr_msg_to_position(u32 csr_msg, enum gen2_csr_pos offset)
116*a4b16dadSTom Zanussi {
117*a4b16dadSTom Zanussi return (csr_msg & 0xFFFF) << offset;
118*a4b16dadSTom Zanussi }
119*a4b16dadSTom Zanussi
gen2_csr_msg_from_position(u32 csr_val,enum gen2_csr_pos offset)120*a4b16dadSTom Zanussi static u32 gen2_csr_msg_from_position(u32 csr_val, enum gen2_csr_pos offset)
121*a4b16dadSTom Zanussi {
122*a4b16dadSTom Zanussi return (csr_val >> offset) & 0xFFFF;
123*a4b16dadSTom Zanussi }
124*a4b16dadSTom Zanussi
gen2_csr_is_in_use(u32 msg,enum gen2_csr_pos offset)125*a4b16dadSTom Zanussi static bool gen2_csr_is_in_use(u32 msg, enum gen2_csr_pos offset)
126*a4b16dadSTom Zanussi {
127*a4b16dadSTom Zanussi return ((msg >> offset) & ADF_GEN2_CSR_IN_USE_MASK) == ADF_GEN2_CSR_IN_USE;
128*a4b16dadSTom Zanussi }
129*a4b16dadSTom Zanussi
gen2_csr_clear_in_use(u32 * msg,enum gen2_csr_pos offset)130*a4b16dadSTom Zanussi static void gen2_csr_clear_in_use(u32 *msg, enum gen2_csr_pos offset)
131*a4b16dadSTom Zanussi {
132*a4b16dadSTom Zanussi *msg &= ~(ADF_GEN2_CSR_IN_USE_MASK << offset);
133*a4b16dadSTom Zanussi }
134*a4b16dadSTom Zanussi
gen2_csr_set_in_use(u32 * msg,enum gen2_csr_pos offset)135*a4b16dadSTom Zanussi static void gen2_csr_set_in_use(u32 *msg, enum gen2_csr_pos offset)
136*a4b16dadSTom Zanussi {
137*a4b16dadSTom Zanussi *msg |= (ADF_GEN2_CSR_IN_USE << offset);
138*a4b16dadSTom Zanussi }
139*a4b16dadSTom Zanussi
is_legacy_user_pfvf_message(u32 msg)140*a4b16dadSTom Zanussi static bool is_legacy_user_pfvf_message(u32 msg)
141*a4b16dadSTom Zanussi {
142*a4b16dadSTom Zanussi return !(msg & ADF_PFVF_MSGORIGIN_SYSTEM);
143*a4b16dadSTom Zanussi }
144*a4b16dadSTom Zanussi
is_pf2vf_notification(u8 msg_type)145*a4b16dadSTom Zanussi static bool is_pf2vf_notification(u8 msg_type)
146*a4b16dadSTom Zanussi {
147*a4b16dadSTom Zanussi switch (msg_type) {
148*a4b16dadSTom Zanussi case ADF_PF2VF_MSGTYPE_RESTARTING:
149*a4b16dadSTom Zanussi return true;
150*a4b16dadSTom Zanussi default:
151*a4b16dadSTom Zanussi return false;
152*a4b16dadSTom Zanussi }
153*a4b16dadSTom Zanussi }
154*a4b16dadSTom Zanussi
is_vf2pf_notification(u8 msg_type)155*a4b16dadSTom Zanussi static bool is_vf2pf_notification(u8 msg_type)
156*a4b16dadSTom Zanussi {
157*a4b16dadSTom Zanussi switch (msg_type) {
158*a4b16dadSTom Zanussi case ADF_VF2PF_MSGTYPE_INIT:
159*a4b16dadSTom Zanussi case ADF_VF2PF_MSGTYPE_SHUTDOWN:
160*a4b16dadSTom Zanussi return true;
161*a4b16dadSTom Zanussi default:
162*a4b16dadSTom Zanussi return false;
163*a4b16dadSTom Zanussi }
164*a4b16dadSTom Zanussi }
165*a4b16dadSTom Zanussi
166*a4b16dadSTom Zanussi struct pfvf_gen2_params {
167*a4b16dadSTom Zanussi u32 pfvf_offset;
168*a4b16dadSTom Zanussi struct mutex *csr_lock; /* lock preventing concurrent access of CSR */
169*a4b16dadSTom Zanussi enum gen2_csr_pos local_offset;
170*a4b16dadSTom Zanussi enum gen2_csr_pos remote_offset;
171*a4b16dadSTom Zanussi bool (*is_notification_message)(u8 msg_type);
172*a4b16dadSTom Zanussi u8 compat_ver;
173*a4b16dadSTom Zanussi };
174*a4b16dadSTom Zanussi
adf_gen2_pfvf_send(struct adf_accel_dev * accel_dev,struct pfvf_message msg,struct pfvf_gen2_params * params)175*a4b16dadSTom Zanussi static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev,
176*a4b16dadSTom Zanussi struct pfvf_message msg,
177*a4b16dadSTom Zanussi struct pfvf_gen2_params *params)
178*a4b16dadSTom Zanussi {
179*a4b16dadSTom Zanussi void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
180*a4b16dadSTom Zanussi enum gen2_csr_pos remote_offset = params->remote_offset;
181*a4b16dadSTom Zanussi enum gen2_csr_pos local_offset = params->local_offset;
182*a4b16dadSTom Zanussi unsigned int retries = ADF_PFVF_MSG_MAX_RETRIES;
183*a4b16dadSTom Zanussi struct mutex *lock = params->csr_lock;
184*a4b16dadSTom Zanussi u32 pfvf_offset = params->pfvf_offset;
185*a4b16dadSTom Zanussi u32 int_bit;
186*a4b16dadSTom Zanussi u32 csr_val;
187*a4b16dadSTom Zanussi u32 csr_msg;
188*a4b16dadSTom Zanussi int ret;
189*a4b16dadSTom Zanussi
190*a4b16dadSTom Zanussi /* Gen2 messages, both PF->VF and VF->PF, are all 16 bits long. This
191*a4b16dadSTom Zanussi * allows us to build and read messages as if they where all 0 based.
192*a4b16dadSTom Zanussi * However, send and receive are in a single shared 32 bits register,
193*a4b16dadSTom Zanussi * so we need to shift and/or mask the message half before decoding
194*a4b16dadSTom Zanussi * it and after encoding it. Which one to shift depends on the
195*a4b16dadSTom Zanussi * direction.
196*a4b16dadSTom Zanussi */
197*a4b16dadSTom Zanussi
198*a4b16dadSTom Zanussi int_bit = gen2_csr_get_int_bit(local_offset);
199*a4b16dadSTom Zanussi
200*a4b16dadSTom Zanussi csr_msg = adf_pfvf_csr_msg_of(accel_dev, msg, &csr_gen2_fmt);
201*a4b16dadSTom Zanussi if (unlikely(!csr_msg))
202*a4b16dadSTom Zanussi return -EINVAL;
203*a4b16dadSTom Zanussi
204*a4b16dadSTom Zanussi /* Prepare for CSR format, shifting the wire message in place and
205*a4b16dadSTom Zanussi * setting the in use pattern
206*a4b16dadSTom Zanussi */
207*a4b16dadSTom Zanussi csr_msg = gen2_csr_msg_to_position(csr_msg, local_offset);
208*a4b16dadSTom Zanussi gen2_csr_set_in_use(&csr_msg, remote_offset);
209*a4b16dadSTom Zanussi
210*a4b16dadSTom Zanussi mutex_lock(lock);
211*a4b16dadSTom Zanussi
212*a4b16dadSTom Zanussi start:
213*a4b16dadSTom Zanussi /* Check if the PFVF CSR is in use by remote function */
214*a4b16dadSTom Zanussi csr_val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
215*a4b16dadSTom Zanussi if (gen2_csr_is_in_use(csr_val, local_offset)) {
216*a4b16dadSTom Zanussi dev_dbg(&GET_DEV(accel_dev),
217*a4b16dadSTom Zanussi "PFVF CSR in use by remote function\n");
218*a4b16dadSTom Zanussi goto retry;
219*a4b16dadSTom Zanussi }
220*a4b16dadSTom Zanussi
221*a4b16dadSTom Zanussi /* Attempt to get ownership of the PFVF CSR */
222*a4b16dadSTom Zanussi ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_msg | int_bit);
223*a4b16dadSTom Zanussi
224*a4b16dadSTom Zanussi /* Wait for confirmation from remote func it received the message */
225*a4b16dadSTom Zanussi ret = read_poll_timeout(ADF_CSR_RD, csr_val, !(csr_val & int_bit),
226*a4b16dadSTom Zanussi ADF_PFVF_MSG_ACK_DELAY_US,
227*a4b16dadSTom Zanussi ADF_PFVF_MSG_ACK_MAX_DELAY_US,
228*a4b16dadSTom Zanussi true, pmisc_addr, pfvf_offset);
229*a4b16dadSTom Zanussi if (unlikely(ret < 0)) {
230*a4b16dadSTom Zanussi dev_dbg(&GET_DEV(accel_dev), "ACK not received from remote\n");
231*a4b16dadSTom Zanussi csr_val &= ~int_bit;
232*a4b16dadSTom Zanussi }
233*a4b16dadSTom Zanussi
234*a4b16dadSTom Zanussi /* For fire-and-forget notifications, the receiver does not clear
235*a4b16dadSTom Zanussi * the in-use pattern. This is used to detect collisions.
236*a4b16dadSTom Zanussi */
237*a4b16dadSTom Zanussi if (params->is_notification_message(msg.type) && csr_val != csr_msg) {
238*a4b16dadSTom Zanussi /* Collision must have overwritten the message */
239*a4b16dadSTom Zanussi dev_err(&GET_DEV(accel_dev),
240*a4b16dadSTom Zanussi "Collision on notification - PFVF CSR overwritten by remote function\n");
241*a4b16dadSTom Zanussi goto retry;
242*a4b16dadSTom Zanussi }
243*a4b16dadSTom Zanussi
244*a4b16dadSTom Zanussi /* If the far side did not clear the in-use pattern it is either
245*a4b16dadSTom Zanussi * 1) Notification - message left intact to detect collision
246*a4b16dadSTom Zanussi * 2) Older protocol (compatibility version < 3) on the far side
247*a4b16dadSTom Zanussi * where the sender is responsible for clearing the in-use
248*a4b16dadSTom Zanussi * pattern after the received has acknowledged receipt.
249*a4b16dadSTom Zanussi * In either case, clear the in-use pattern now.
250*a4b16dadSTom Zanussi */
251*a4b16dadSTom Zanussi if (gen2_csr_is_in_use(csr_val, remote_offset)) {
252*a4b16dadSTom Zanussi gen2_csr_clear_in_use(&csr_val, remote_offset);
253*a4b16dadSTom Zanussi ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val);
254*a4b16dadSTom Zanussi }
255*a4b16dadSTom Zanussi
256*a4b16dadSTom Zanussi out:
257*a4b16dadSTom Zanussi mutex_unlock(lock);
258*a4b16dadSTom Zanussi return ret;
259*a4b16dadSTom Zanussi
260*a4b16dadSTom Zanussi retry:
261*a4b16dadSTom Zanussi if (--retries) {
262*a4b16dadSTom Zanussi msleep(ADF_PFVF_MSG_RETRY_DELAY);
263*a4b16dadSTom Zanussi goto start;
264*a4b16dadSTom Zanussi } else {
265*a4b16dadSTom Zanussi ret = -EBUSY;
266*a4b16dadSTom Zanussi goto out;
267*a4b16dadSTom Zanussi }
268*a4b16dadSTom Zanussi }
269*a4b16dadSTom Zanussi
adf_gen2_pfvf_recv(struct adf_accel_dev * accel_dev,struct pfvf_gen2_params * params)270*a4b16dadSTom Zanussi static struct pfvf_message adf_gen2_pfvf_recv(struct adf_accel_dev *accel_dev,
271*a4b16dadSTom Zanussi struct pfvf_gen2_params *params)
272*a4b16dadSTom Zanussi {
273*a4b16dadSTom Zanussi void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
274*a4b16dadSTom Zanussi enum gen2_csr_pos remote_offset = params->remote_offset;
275*a4b16dadSTom Zanussi enum gen2_csr_pos local_offset = params->local_offset;
276*a4b16dadSTom Zanussi u32 pfvf_offset = params->pfvf_offset;
277*a4b16dadSTom Zanussi struct pfvf_message msg = { 0 };
278*a4b16dadSTom Zanussi u32 int_bit;
279*a4b16dadSTom Zanussi u32 csr_val;
280*a4b16dadSTom Zanussi u16 csr_msg;
281*a4b16dadSTom Zanussi
282*a4b16dadSTom Zanussi int_bit = gen2_csr_get_int_bit(local_offset);
283*a4b16dadSTom Zanussi
284*a4b16dadSTom Zanussi /* Read message */
285*a4b16dadSTom Zanussi csr_val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
286*a4b16dadSTom Zanussi if (!(csr_val & int_bit)) {
287*a4b16dadSTom Zanussi dev_info(&GET_DEV(accel_dev),
288*a4b16dadSTom Zanussi "Spurious PFVF interrupt, msg 0x%.8x. Ignored\n", csr_val);
289*a4b16dadSTom Zanussi return msg;
290*a4b16dadSTom Zanussi }
291*a4b16dadSTom Zanussi
292*a4b16dadSTom Zanussi /* Extract the message from the CSR */
293*a4b16dadSTom Zanussi csr_msg = gen2_csr_msg_from_position(csr_val, local_offset);
294*a4b16dadSTom Zanussi
295*a4b16dadSTom Zanussi /* Ignore legacy non-system (non-kernel) messages */
296*a4b16dadSTom Zanussi if (unlikely(is_legacy_user_pfvf_message(csr_msg))) {
297*a4b16dadSTom Zanussi dev_dbg(&GET_DEV(accel_dev),
298*a4b16dadSTom Zanussi "Ignored non-system message (0x%.8x);\n", csr_val);
299*a4b16dadSTom Zanussi /* Because this must be a legacy message, the far side
300*a4b16dadSTom Zanussi * must clear the in-use pattern, so don't do it.
301*a4b16dadSTom Zanussi */
302*a4b16dadSTom Zanussi return msg;
303*a4b16dadSTom Zanussi }
304*a4b16dadSTom Zanussi
305*a4b16dadSTom Zanussi /* Return the pfvf_message format */
306*a4b16dadSTom Zanussi msg = adf_pfvf_message_of(accel_dev, csr_msg, &csr_gen2_fmt);
307*a4b16dadSTom Zanussi
308*a4b16dadSTom Zanussi /* The in-use pattern is not cleared for notifications (so that
309*a4b16dadSTom Zanussi * it can be used for collision detection) or older implementations
310*a4b16dadSTom Zanussi */
311*a4b16dadSTom Zanussi if (params->compat_ver >= ADF_PFVF_COMPAT_FAST_ACK &&
312*a4b16dadSTom Zanussi !params->is_notification_message(msg.type))
313*a4b16dadSTom Zanussi gen2_csr_clear_in_use(&csr_val, remote_offset);
314*a4b16dadSTom Zanussi
315*a4b16dadSTom Zanussi /* To ACK, clear the INT bit */
316*a4b16dadSTom Zanussi csr_val &= ~int_bit;
317*a4b16dadSTom Zanussi ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val);
318*a4b16dadSTom Zanussi
319*a4b16dadSTom Zanussi return msg;
320*a4b16dadSTom Zanussi }
321*a4b16dadSTom Zanussi
adf_gen2_pf2vf_send(struct adf_accel_dev * accel_dev,struct pfvf_message msg,u32 pfvf_offset,struct mutex * csr_lock)322*a4b16dadSTom Zanussi static int adf_gen2_pf2vf_send(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
323*a4b16dadSTom Zanussi u32 pfvf_offset, struct mutex *csr_lock)
324*a4b16dadSTom Zanussi {
325*a4b16dadSTom Zanussi struct pfvf_gen2_params params = {
326*a4b16dadSTom Zanussi .csr_lock = csr_lock,
327*a4b16dadSTom Zanussi .pfvf_offset = pfvf_offset,
328*a4b16dadSTom Zanussi .local_offset = ADF_GEN2_CSR_PF2VF_OFFSET,
329*a4b16dadSTom Zanussi .remote_offset = ADF_GEN2_CSR_VF2PF_OFFSET,
330*a4b16dadSTom Zanussi .is_notification_message = is_pf2vf_notification,
331*a4b16dadSTom Zanussi };
332*a4b16dadSTom Zanussi
333*a4b16dadSTom Zanussi return adf_gen2_pfvf_send(accel_dev, msg, ¶ms);
334*a4b16dadSTom Zanussi }
335*a4b16dadSTom Zanussi
adf_gen2_vf2pf_send(struct adf_accel_dev * accel_dev,struct pfvf_message msg,u32 pfvf_offset,struct mutex * csr_lock)336*a4b16dadSTom Zanussi static int adf_gen2_vf2pf_send(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
337*a4b16dadSTom Zanussi u32 pfvf_offset, struct mutex *csr_lock)
338*a4b16dadSTom Zanussi {
339*a4b16dadSTom Zanussi struct pfvf_gen2_params params = {
340*a4b16dadSTom Zanussi .csr_lock = csr_lock,
341*a4b16dadSTom Zanussi .pfvf_offset = pfvf_offset,
342*a4b16dadSTom Zanussi .local_offset = ADF_GEN2_CSR_VF2PF_OFFSET,
343*a4b16dadSTom Zanussi .remote_offset = ADF_GEN2_CSR_PF2VF_OFFSET,
344*a4b16dadSTom Zanussi .is_notification_message = is_vf2pf_notification,
345*a4b16dadSTom Zanussi };
346*a4b16dadSTom Zanussi
347*a4b16dadSTom Zanussi return adf_gen2_pfvf_send(accel_dev, msg, ¶ms);
348*a4b16dadSTom Zanussi }
349*a4b16dadSTom Zanussi
adf_gen2_pf2vf_recv(struct adf_accel_dev * accel_dev,u32 pfvf_offset,u8 compat_ver)350*a4b16dadSTom Zanussi static struct pfvf_message adf_gen2_pf2vf_recv(struct adf_accel_dev *accel_dev,
351*a4b16dadSTom Zanussi u32 pfvf_offset, u8 compat_ver)
352*a4b16dadSTom Zanussi {
353*a4b16dadSTom Zanussi struct pfvf_gen2_params params = {
354*a4b16dadSTom Zanussi .pfvf_offset = pfvf_offset,
355*a4b16dadSTom Zanussi .local_offset = ADF_GEN2_CSR_PF2VF_OFFSET,
356*a4b16dadSTom Zanussi .remote_offset = ADF_GEN2_CSR_VF2PF_OFFSET,
357*a4b16dadSTom Zanussi .is_notification_message = is_pf2vf_notification,
358*a4b16dadSTom Zanussi .compat_ver = compat_ver,
359*a4b16dadSTom Zanussi };
360*a4b16dadSTom Zanussi
361*a4b16dadSTom Zanussi return adf_gen2_pfvf_recv(accel_dev, ¶ms);
362*a4b16dadSTom Zanussi }
363*a4b16dadSTom Zanussi
adf_gen2_vf2pf_recv(struct adf_accel_dev * accel_dev,u32 pfvf_offset,u8 compat_ver)364*a4b16dadSTom Zanussi static struct pfvf_message adf_gen2_vf2pf_recv(struct adf_accel_dev *accel_dev,
365*a4b16dadSTom Zanussi u32 pfvf_offset, u8 compat_ver)
366*a4b16dadSTom Zanussi {
367*a4b16dadSTom Zanussi struct pfvf_gen2_params params = {
368*a4b16dadSTom Zanussi .pfvf_offset = pfvf_offset,
369*a4b16dadSTom Zanussi .local_offset = ADF_GEN2_CSR_VF2PF_OFFSET,
370*a4b16dadSTom Zanussi .remote_offset = ADF_GEN2_CSR_PF2VF_OFFSET,
371*a4b16dadSTom Zanussi .is_notification_message = is_vf2pf_notification,
372*a4b16dadSTom Zanussi .compat_ver = compat_ver,
373*a4b16dadSTom Zanussi };
374*a4b16dadSTom Zanussi
375*a4b16dadSTom Zanussi return adf_gen2_pfvf_recv(accel_dev, ¶ms);
376*a4b16dadSTom Zanussi }
377*a4b16dadSTom Zanussi
adf_gen2_init_pf_pfvf_ops(struct adf_pfvf_ops * pfvf_ops)378*a4b16dadSTom Zanussi void adf_gen2_init_pf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops)
379*a4b16dadSTom Zanussi {
380*a4b16dadSTom Zanussi pfvf_ops->enable_comms = adf_enable_pf2vf_comms;
381*a4b16dadSTom Zanussi pfvf_ops->get_pf2vf_offset = adf_gen2_pf_get_pfvf_offset;
382*a4b16dadSTom Zanussi pfvf_ops->get_vf2pf_offset = adf_gen2_pf_get_pfvf_offset;
383*a4b16dadSTom Zanussi pfvf_ops->enable_vf2pf_interrupts = adf_gen2_enable_vf2pf_interrupts;
384*a4b16dadSTom Zanussi pfvf_ops->disable_all_vf2pf_interrupts = adf_gen2_disable_all_vf2pf_interrupts;
385*a4b16dadSTom Zanussi pfvf_ops->disable_pending_vf2pf_interrupts = adf_gen2_disable_pending_vf2pf_interrupts;
386*a4b16dadSTom Zanussi pfvf_ops->send_msg = adf_gen2_pf2vf_send;
387*a4b16dadSTom Zanussi pfvf_ops->recv_msg = adf_gen2_vf2pf_recv;
388*a4b16dadSTom Zanussi }
389*a4b16dadSTom Zanussi EXPORT_SYMBOL_GPL(adf_gen2_init_pf_pfvf_ops);
390*a4b16dadSTom Zanussi
adf_gen2_init_vf_pfvf_ops(struct adf_pfvf_ops * pfvf_ops)391*a4b16dadSTom Zanussi void adf_gen2_init_vf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops)
392*a4b16dadSTom Zanussi {
393*a4b16dadSTom Zanussi pfvf_ops->enable_comms = adf_enable_vf2pf_comms;
394*a4b16dadSTom Zanussi pfvf_ops->get_pf2vf_offset = adf_gen2_vf_get_pfvf_offset;
395*a4b16dadSTom Zanussi pfvf_ops->get_vf2pf_offset = adf_gen2_vf_get_pfvf_offset;
396*a4b16dadSTom Zanussi pfvf_ops->send_msg = adf_gen2_vf2pf_send;
397*a4b16dadSTom Zanussi pfvf_ops->recv_msg = adf_gen2_pf2vf_recv;
398*a4b16dadSTom Zanussi }
399*a4b16dadSTom Zanussi EXPORT_SYMBOL_GPL(adf_gen2_init_vf_pfvf_ops);
400