Merge patch series "Use block pr_ops in LIO"
[sfrench/cifs-2.6.git] / drivers / crypto / intel / qat / qat_common / adf_pfvf_vf_proto.c
1 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
2 /* Copyright(c) 2015 - 2021 Intel Corporation */
3 #include <linux/bitfield.h>
4 #include <linux/completion.h>
5 #include <linux/minmax.h>
6 #include <linux/types.h>
7 #include "adf_accel_devices.h"
8 #include "adf_common_drv.h"
9 #include "adf_pfvf_msg.h"
10 #include "adf_pfvf_utils.h"
11 #include "adf_pfvf_vf_msg.h"
12 #include "adf_pfvf_vf_proto.h"
13
14 #define ADF_PFVF_MSG_COLLISION_DETECT_DELAY     10
15 #define ADF_PFVF_MSG_ACK_DELAY                  2
16 #define ADF_PFVF_MSG_ACK_MAX_RETRY              100
17
18 /* How often to retry if there is no response */
19 #define ADF_PFVF_MSG_RESP_RETRIES       5
20 #define ADF_PFVF_MSG_RESP_TIMEOUT       (ADF_PFVF_MSG_ACK_DELAY * \
21                                          ADF_PFVF_MSG_ACK_MAX_RETRY + \
22                                          ADF_PFVF_MSG_COLLISION_DETECT_DELAY)
23
24 /**
25  * adf_send_vf2pf_msg() - send VF to PF message
26  * @accel_dev:  Pointer to acceleration device
27  * @msg:        Message to send
28  *
29  * This function allows the VF to send a message to the PF.
30  *
31  * Return: 0 on success, error code otherwise.
32  */
33 int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, struct pfvf_message msg)
34 {
35         struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
36         u32 pfvf_offset = pfvf_ops->get_vf2pf_offset(0);
37
38         return pfvf_ops->send_msg(accel_dev, msg, pfvf_offset,
39                                   &accel_dev->vf.vf2pf_lock);
40 }
41
42 /**
43  * adf_recv_pf2vf_msg() - receive a PF to VF message
44  * @accel_dev:  Pointer to acceleration device
45  *
46  * This function allows the VF to receive a message from the PF.
47  *
48  * Return: a valid message on success, zero otherwise.
49  */
50 static struct pfvf_message adf_recv_pf2vf_msg(struct adf_accel_dev *accel_dev)
51 {
52         struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
53         u32 pfvf_offset = pfvf_ops->get_pf2vf_offset(0);
54
55         return pfvf_ops->recv_msg(accel_dev, pfvf_offset, accel_dev->vf.pf_compat_ver);
56 }
57
58 /**
59  * adf_send_vf2pf_req() - send VF2PF request message
60  * @accel_dev:  Pointer to acceleration device.
61  * @msg:        Request message to send
62  * @resp:       Returned PF response
63  *
64  * This function sends a message that requires a response from the VF to the PF
65  * and waits for a reply.
66  *
67  * Return: 0 on success, error code otherwise.
68  */
69 int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
70                        struct pfvf_message *resp)
71 {
72         unsigned long timeout = msecs_to_jiffies(ADF_PFVF_MSG_RESP_TIMEOUT);
73         unsigned int retries = ADF_PFVF_MSG_RESP_RETRIES;
74         int ret;
75
76         reinit_completion(&accel_dev->vf.msg_received);
77
78         /* Send request from VF to PF */
79         do {
80                 ret = adf_send_vf2pf_msg(accel_dev, msg);
81                 if (ret) {
82                         dev_err(&GET_DEV(accel_dev),
83                                 "Failed to send request msg to PF\n");
84                         return ret;
85                 }
86
87                 /* Wait for response, if it times out retry */
88                 ret = wait_for_completion_timeout(&accel_dev->vf.msg_received,
89                                                   timeout);
90                 if (ret) {
91                         if (likely(resp))
92                                 *resp = accel_dev->vf.response;
93
94                         /* Once copied, set to an invalid value */
95                         accel_dev->vf.response.type = 0;
96
97                         return 0;
98                 }
99
100                 dev_err(&GET_DEV(accel_dev), "PFVF response message timeout\n");
101         } while (--retries);
102
103         return -EIO;
104 }
105
106 static int adf_vf2pf_blkmsg_data_req(struct adf_accel_dev *accel_dev, bool crc,
107                                      u8 *type, u8 *data)
108 {
109         struct pfvf_message req = { 0 };
110         struct pfvf_message resp = { 0 };
111         u8 blk_type;
112         u8 blk_byte;
113         u8 msg_type;
114         u8 max_data;
115         int err;
116
117         /* Convert the block type to {small, medium, large} size category */
118         if (*type <= ADF_VF2PF_SMALL_BLOCK_TYPE_MAX) {
119                 msg_type = ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ;
120                 blk_type = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK, *type);
121                 blk_byte = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK, *data);
122                 max_data = ADF_VF2PF_SMALL_BLOCK_BYTE_MAX;
123         } else if (*type <= ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX) {
124                 msg_type = ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ;
125                 blk_type = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK,
126                                       *type - ADF_VF2PF_SMALL_BLOCK_TYPE_MAX);
127                 blk_byte = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK, *data);
128                 max_data = ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX;
129         } else if (*type <= ADF_VF2PF_LARGE_BLOCK_TYPE_MAX) {
130                 msg_type = ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ;
131                 blk_type = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK,
132                                       *type - ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX);
133                 blk_byte = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK, *data);
134                 max_data = ADF_VF2PF_LARGE_BLOCK_BYTE_MAX;
135         } else {
136                 dev_err(&GET_DEV(accel_dev), "Invalid message type %u\n", *type);
137                 return -EINVAL;
138         }
139
140         /* Sanity check */
141         if (*data > max_data) {
142                 dev_err(&GET_DEV(accel_dev),
143                         "Invalid byte %s %u for message type %u\n",
144                         crc ? "count" : "index", *data, *type);
145                 return -EINVAL;
146         }
147
148         /* Build the block message */
149         req.type = msg_type;
150         req.data = blk_type | blk_byte | FIELD_PREP(ADF_VF2PF_BLOCK_CRC_REQ_MASK, crc);
151
152         err = adf_send_vf2pf_req(accel_dev, req, &resp);
153         if (err)
154                 return err;
155
156         *type = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_TYPE_MASK, resp.data);
157         *data = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_DATA_MASK, resp.data);
158
159         return 0;
160 }
161
162 static int adf_vf2pf_blkmsg_get_byte(struct adf_accel_dev *accel_dev, u8 type,
163                                      u8 index, u8 *data)
164 {
165         int ret;
166
167         ret = adf_vf2pf_blkmsg_data_req(accel_dev, false, &type, &index);
168         if (ret < 0)
169                 return ret;
170
171         if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_DATA)) {
172                 dev_err(&GET_DEV(accel_dev),
173                         "Unexpected BLKMSG response type %u, byte 0x%x\n",
174                         type, index);
175                 return -EFAULT;
176         }
177
178         *data = index;
179         return 0;
180 }
181
182 static int adf_vf2pf_blkmsg_get_crc(struct adf_accel_dev *accel_dev, u8 type,
183                                     u8 bytes, u8 *crc)
184 {
185         int ret;
186
187         /* The count of bytes refers to a length, however shift it to a 0-based
188          * count to avoid overflows. Thus, a request for 0 bytes is technically
189          * valid.
190          */
191         --bytes;
192
193         ret = adf_vf2pf_blkmsg_data_req(accel_dev, true, &type, &bytes);
194         if (ret < 0)
195                 return ret;
196
197         if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_CRC)) {
198                 dev_err(&GET_DEV(accel_dev),
199                         "Unexpected CRC BLKMSG response type %u, crc 0x%x\n",
200                         type, bytes);
201                 return  -EFAULT;
202         }
203
204         *crc = bytes;
205         return 0;
206 }
207
208 /**
209  * adf_send_vf2pf_blkmsg_req() - retrieve block message
210  * @accel_dev:  Pointer to acceleration VF device.
211  * @type:       The block message type, see adf_pfvf_msg.h for allowed values
212  * @buffer:     input buffer where to place the received data
213  * @buffer_len: buffer length as input, the amount of written bytes on output
214  *
215  * Request a message of type 'type' over the block message transport.
216  * This function will send the required amount block message requests and
217  * return the overall content back to the caller through the provided buffer.
218  * The buffer should be large enough to contain the requested message type,
219  * otherwise the response will be truncated.
220  *
221  * Return: 0 on success, error code otherwise.
222  */
223 int adf_send_vf2pf_blkmsg_req(struct adf_accel_dev *accel_dev, u8 type,
224                               u8 *buffer, unsigned int *buffer_len)
225 {
226         unsigned int index;
227         unsigned int msg_len;
228         int ret;
229         u8 remote_crc;
230         u8 local_crc;
231
232         if (unlikely(type > ADF_VF2PF_LARGE_BLOCK_TYPE_MAX)) {
233                 dev_err(&GET_DEV(accel_dev), "Invalid block message type %d\n",
234                         type);
235                 return -EINVAL;
236         }
237
238         if (unlikely(*buffer_len < ADF_PFVF_BLKMSG_HEADER_SIZE)) {
239                 dev_err(&GET_DEV(accel_dev),
240                         "Buffer size too small for a block message\n");
241                 return -EINVAL;
242         }
243
244         ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type,
245                                         ADF_PFVF_BLKMSG_VER_BYTE,
246                                         &buffer[ADF_PFVF_BLKMSG_VER_BYTE]);
247         if (unlikely(ret))
248                 return ret;
249
250         if (unlikely(!buffer[ADF_PFVF_BLKMSG_VER_BYTE])) {
251                 dev_err(&GET_DEV(accel_dev),
252                         "Invalid version 0 received for block request %u", type);
253                 return -EFAULT;
254         }
255
256         ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type,
257                                         ADF_PFVF_BLKMSG_LEN_BYTE,
258                                         &buffer[ADF_PFVF_BLKMSG_LEN_BYTE]);
259         if (unlikely(ret))
260                 return ret;
261
262         if (unlikely(!buffer[ADF_PFVF_BLKMSG_LEN_BYTE])) {
263                 dev_err(&GET_DEV(accel_dev),
264                         "Invalid size 0 received for block request %u", type);
265                 return -EFAULT;
266         }
267
268         /* We need to pick the minimum since there is no way to request a
269          * specific version. As a consequence any scenario is possible:
270          * - PF has a newer (longer) version which doesn't fit in the buffer
271          * - VF expects a newer (longer) version, so we must not ask for
272          *   bytes in excess
273          * - PF and VF share the same version, no problem
274          */
275         msg_len = ADF_PFVF_BLKMSG_HEADER_SIZE + buffer[ADF_PFVF_BLKMSG_LEN_BYTE];
276         msg_len = min(*buffer_len, msg_len);
277
278         /* Get the payload */
279         for (index = ADF_PFVF_BLKMSG_HEADER_SIZE; index < msg_len; index++) {
280                 ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type, index,
281                                                 &buffer[index]);
282                 if (unlikely(ret))
283                         return ret;
284         }
285
286         ret = adf_vf2pf_blkmsg_get_crc(accel_dev, type, msg_len, &remote_crc);
287         if (unlikely(ret))
288                 return ret;
289
290         local_crc = adf_pfvf_calc_blkmsg_crc(buffer, msg_len);
291         if (unlikely(local_crc != remote_crc)) {
292                 dev_err(&GET_DEV(accel_dev),
293                         "CRC error on msg type %d. Local %02X, remote %02X\n",
294                         type, local_crc, remote_crc);
295                 return -EIO;
296         }
297
298         *buffer_len = msg_len;
299         return 0;
300 }
301
302 static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev,
303                                  struct pfvf_message msg)
304 {
305         switch (msg.type) {
306         case ADF_PF2VF_MSGTYPE_RESTARTING:
307                 dev_dbg(&GET_DEV(accel_dev), "Restarting message received from PF\n");
308
309                 adf_pf2vf_handle_pf_restarting(accel_dev);
310                 return false;
311         case ADF_PF2VF_MSGTYPE_VERSION_RESP:
312         case ADF_PF2VF_MSGTYPE_BLKMSG_RESP:
313         case ADF_PF2VF_MSGTYPE_RP_RESET_RESP:
314                 dev_dbg(&GET_DEV(accel_dev),
315                         "Response Message received from PF (type 0x%.4x, data 0x%.4x)\n",
316                         msg.type, msg.data);
317                 accel_dev->vf.response = msg;
318                 complete(&accel_dev->vf.msg_received);
319                 return true;
320         default:
321                 dev_err(&GET_DEV(accel_dev),
322                         "Unknown message from PF (type 0x%.4x, data: 0x%.4x)\n",
323                         msg.type, msg.data);
324         }
325
326         return false;
327 }
328
329 bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev)
330 {
331         struct pfvf_message msg;
332
333         msg = adf_recv_pf2vf_msg(accel_dev);
334         if (msg.type)  /* Invalid or no message */
335                 return adf_handle_pf2vf_msg(accel_dev, msg);
336
337         /* No replies for PF->VF messages at present */
338
339         return true;
340 }
341
342 /**
343  * adf_enable_vf2pf_comms() - Function enables communication from vf to pf
344  *
345  * @accel_dev:  Pointer to acceleration device virtual function.
346  *
347  * Return: 0 on success, error code otherwise.
348  */
349 int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev)
350 {
351         int ret;
352
353         adf_pfvf_crc_init();
354         adf_enable_pf2vf_interrupts(accel_dev);
355
356         ret = adf_vf2pf_request_version(accel_dev);
357         if (ret)
358                 return ret;
359
360         ret = adf_vf2pf_get_capabilities(accel_dev);
361         if (ret)
362                 return ret;
363
364         ret = adf_vf2pf_get_ring_to_svc(accel_dev);
365
366         return ret;
367 }
368 EXPORT_SYMBOL_GPL(adf_enable_vf2pf_comms);