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