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