diff options
Diffstat (limited to 'drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c')
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c | 368 |
1 files changed, 0 insertions, 368 deletions
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c deleted file mode 100644 index 1015155b6374..000000000000 --- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c +++ /dev/null @@ -1,368 +0,0 @@ -// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) -/* Copyright(c) 2015 - 2021 Intel Corporation */ -#include <linux/bitfield.h> -#include <linux/completion.h> -#include <linux/minmax.h> -#include <linux/types.h> -#include "adf_accel_devices.h" -#include "adf_common_drv.h" -#include "adf_pfvf_msg.h" -#include "adf_pfvf_utils.h" -#include "adf_pfvf_vf_msg.h" -#include "adf_pfvf_vf_proto.h" - -#define ADF_PFVF_MSG_COLLISION_DETECT_DELAY 10 -#define ADF_PFVF_MSG_ACK_DELAY 2 -#define ADF_PFVF_MSG_ACK_MAX_RETRY 100 - -/* How often to retry if there is no response */ -#define ADF_PFVF_MSG_RESP_RETRIES 5 -#define ADF_PFVF_MSG_RESP_TIMEOUT (ADF_PFVF_MSG_ACK_DELAY * \ - ADF_PFVF_MSG_ACK_MAX_RETRY + \ - ADF_PFVF_MSG_COLLISION_DETECT_DELAY) - -/** - * adf_send_vf2pf_msg() - send VF to PF message - * @accel_dev: Pointer to acceleration device - * @msg: Message to send - * - * This function allows the VF to send a message to the PF. - * - * Return: 0 on success, error code otherwise. - */ -int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, struct pfvf_message msg) -{ - struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev); - u32 pfvf_offset = pfvf_ops->get_vf2pf_offset(0); - - return pfvf_ops->send_msg(accel_dev, msg, pfvf_offset, - &accel_dev->vf.vf2pf_lock); -} - -/** - * adf_recv_pf2vf_msg() - receive a PF to VF message - * @accel_dev: Pointer to acceleration device - * - * This function allows the VF to receive a message from the PF. - * - * Return: a valid message on success, zero otherwise. - */ -static struct pfvf_message adf_recv_pf2vf_msg(struct adf_accel_dev *accel_dev) -{ - struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev); - u32 pfvf_offset = pfvf_ops->get_pf2vf_offset(0); - - return pfvf_ops->recv_msg(accel_dev, pfvf_offset, accel_dev->vf.pf_compat_ver); -} - -/** - * adf_send_vf2pf_req() - send VF2PF request message - * @accel_dev: Pointer to acceleration device. - * @msg: Request message to send - * @resp: Returned PF response - * - * This function sends a message that requires a response from the VF to the PF - * and waits for a reply. - * - * Return: 0 on success, error code otherwise. - */ -int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, struct pfvf_message msg, - struct pfvf_message *resp) -{ - unsigned long timeout = msecs_to_jiffies(ADF_PFVF_MSG_RESP_TIMEOUT); - unsigned int retries = ADF_PFVF_MSG_RESP_RETRIES; - int ret; - - reinit_completion(&accel_dev->vf.msg_received); - - /* Send request from VF to PF */ - do { - ret = adf_send_vf2pf_msg(accel_dev, msg); - if (ret) { - dev_err(&GET_DEV(accel_dev), - "Failed to send request msg to PF\n"); - return ret; - } - - /* Wait for response, if it times out retry */ - ret = wait_for_completion_timeout(&accel_dev->vf.msg_received, - timeout); - if (ret) { - if (likely(resp)) - *resp = accel_dev->vf.response; - - /* Once copied, set to an invalid value */ - accel_dev->vf.response.type = 0; - - return 0; - } - - dev_err(&GET_DEV(accel_dev), "PFVF response message timeout\n"); - } while (--retries); - - return -EIO; -} - -static int adf_vf2pf_blkmsg_data_req(struct adf_accel_dev *accel_dev, bool crc, - u8 *type, u8 *data) -{ - struct pfvf_message req = { 0 }; - struct pfvf_message resp = { 0 }; - u8 blk_type; - u8 blk_byte; - u8 msg_type; - u8 max_data; - int err; - - /* Convert the block type to {small, medium, large} size category */ - if (*type <= ADF_VF2PF_SMALL_BLOCK_TYPE_MAX) { - msg_type = ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ; - blk_type = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK, *type); - blk_byte = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK, *data); - max_data = ADF_VF2PF_SMALL_BLOCK_BYTE_MAX; - } else if (*type <= ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX) { - msg_type = ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ; - blk_type = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK, - *type - ADF_VF2PF_SMALL_BLOCK_TYPE_MAX); - blk_byte = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK, *data); - max_data = ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX; - } else if (*type <= ADF_VF2PF_LARGE_BLOCK_TYPE_MAX) { - msg_type = ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ; - blk_type = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK, - *type - ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX); - blk_byte = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK, *data); - max_data = ADF_VF2PF_LARGE_BLOCK_BYTE_MAX; - } else { - dev_err(&GET_DEV(accel_dev), "Invalid message type %u\n", *type); - return -EINVAL; - } - - /* Sanity check */ - if (*data > max_data) { - dev_err(&GET_DEV(accel_dev), - "Invalid byte %s %u for message type %u\n", - crc ? "count" : "index", *data, *type); - return -EINVAL; - } - - /* Build the block message */ - req.type = msg_type; - req.data = blk_type | blk_byte | FIELD_PREP(ADF_VF2PF_BLOCK_CRC_REQ_MASK, crc); - - err = adf_send_vf2pf_req(accel_dev, req, &resp); - if (err) - return err; - - *type = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_TYPE_MASK, resp.data); - *data = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_DATA_MASK, resp.data); - - return 0; -} - -static int adf_vf2pf_blkmsg_get_byte(struct adf_accel_dev *accel_dev, u8 type, - u8 index, u8 *data) -{ - int ret; - - ret = adf_vf2pf_blkmsg_data_req(accel_dev, false, &type, &index); - if (ret < 0) - return ret; - - if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_DATA)) { - dev_err(&GET_DEV(accel_dev), - "Unexpected BLKMSG response type %u, byte 0x%x\n", - type, index); - return -EFAULT; - } - - *data = index; - return 0; -} - -static int adf_vf2pf_blkmsg_get_crc(struct adf_accel_dev *accel_dev, u8 type, - u8 bytes, u8 *crc) -{ - int ret; - - /* The count of bytes refers to a length, however shift it to a 0-based - * count to avoid overflows. Thus, a request for 0 bytes is technically - * valid. - */ - --bytes; - - ret = adf_vf2pf_blkmsg_data_req(accel_dev, true, &type, &bytes); - if (ret < 0) - return ret; - - if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_CRC)) { - dev_err(&GET_DEV(accel_dev), - "Unexpected CRC BLKMSG response type %u, crc 0x%x\n", - type, bytes); - return -EFAULT; - } - - *crc = bytes; - return 0; -} - -/** - * adf_send_vf2pf_blkmsg_req() - retrieve block message - * @accel_dev: Pointer to acceleration VF device. - * @type: The block message type, see adf_pfvf_msg.h for allowed values - * @buffer: input buffer where to place the received data - * @buffer_len: buffer length as input, the amount of written bytes on output - * - * Request a message of type 'type' over the block message transport. - * This function will send the required amount block message requests and - * return the overall content back to the caller through the provided buffer. - * The buffer should be large enough to contain the requested message type, - * otherwise the response will be truncated. - * - * Return: 0 on success, error code otherwise. - */ -int adf_send_vf2pf_blkmsg_req(struct adf_accel_dev *accel_dev, u8 type, - u8 *buffer, unsigned int *buffer_len) -{ - unsigned int index; - unsigned int msg_len; - int ret; - u8 remote_crc; - u8 local_crc; - - if (unlikely(type > ADF_VF2PF_LARGE_BLOCK_TYPE_MAX)) { - dev_err(&GET_DEV(accel_dev), "Invalid block message type %d\n", - type); - return -EINVAL; - } - - if (unlikely(*buffer_len < ADF_PFVF_BLKMSG_HEADER_SIZE)) { - dev_err(&GET_DEV(accel_dev), - "Buffer size too small for a block message\n"); - return -EINVAL; - } - - ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type, - ADF_PFVF_BLKMSG_VER_BYTE, - &buffer[ADF_PFVF_BLKMSG_VER_BYTE]); - if (unlikely(ret)) - return ret; - - if (unlikely(!buffer[ADF_PFVF_BLKMSG_VER_BYTE])) { - dev_err(&GET_DEV(accel_dev), - "Invalid version 0 received for block request %u", type); - return -EFAULT; - } - - ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type, - ADF_PFVF_BLKMSG_LEN_BYTE, - &buffer[ADF_PFVF_BLKMSG_LEN_BYTE]); - if (unlikely(ret)) - return ret; - - if (unlikely(!buffer[ADF_PFVF_BLKMSG_LEN_BYTE])) { - dev_err(&GET_DEV(accel_dev), - "Invalid size 0 received for block request %u", type); - return -EFAULT; - } - - /* We need to pick the minimum since there is no way to request a - * specific version. As a consequence any scenario is possible: - * - PF has a newer (longer) version which doesn't fit in the buffer - * - VF expects a newer (longer) version, so we must not ask for - * bytes in excess - * - PF and VF share the same version, no problem - */ - msg_len = ADF_PFVF_BLKMSG_HEADER_SIZE + buffer[ADF_PFVF_BLKMSG_LEN_BYTE]; - msg_len = min(*buffer_len, msg_len); - - /* Get the payload */ - for (index = ADF_PFVF_BLKMSG_HEADER_SIZE; index < msg_len; index++) { - ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type, index, - &buffer[index]); - if (unlikely(ret)) - return ret; - } - - ret = adf_vf2pf_blkmsg_get_crc(accel_dev, type, msg_len, &remote_crc); - if (unlikely(ret)) - return ret; - - local_crc = adf_pfvf_calc_blkmsg_crc(buffer, msg_len); - if (unlikely(local_crc != remote_crc)) { - dev_err(&GET_DEV(accel_dev), - "CRC error on msg type %d. Local %02X, remote %02X\n", - type, local_crc, remote_crc); - return -EIO; - } - - *buffer_len = msg_len; - return 0; -} - -static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev, - struct pfvf_message msg) -{ - switch (msg.type) { - case ADF_PF2VF_MSGTYPE_RESTARTING: - dev_dbg(&GET_DEV(accel_dev), "Restarting message received from PF\n"); - - adf_pf2vf_handle_pf_restarting(accel_dev); - return false; - case ADF_PF2VF_MSGTYPE_VERSION_RESP: - case ADF_PF2VF_MSGTYPE_BLKMSG_RESP: - case ADF_PF2VF_MSGTYPE_RP_RESET_RESP: - dev_dbg(&GET_DEV(accel_dev), - "Response Message received from PF (type 0x%.4x, data 0x%.4x)\n", - msg.type, msg.data); - accel_dev->vf.response = msg; - complete(&accel_dev->vf.msg_received); - return true; - default: - dev_err(&GET_DEV(accel_dev), - "Unknown message from PF (type 0x%.4x, data: 0x%.4x)\n", - msg.type, msg.data); - } - - return false; -} - -bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev) -{ - struct pfvf_message msg; - - msg = adf_recv_pf2vf_msg(accel_dev); - if (msg.type) /* Invalid or no message */ - return adf_handle_pf2vf_msg(accel_dev, msg); - - /* No replies for PF->VF messages at present */ - - return true; -} - -/** - * adf_enable_vf2pf_comms() - Function enables communication from vf to pf - * - * @accel_dev: Pointer to acceleration device virtual function. - * - * Return: 0 on success, error code otherwise. - */ -int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev) -{ - int ret; - - adf_pfvf_crc_init(); - adf_enable_pf2vf_interrupts(accel_dev); - - ret = adf_vf2pf_request_version(accel_dev); - if (ret) - return ret; - - ret = adf_vf2pf_get_capabilities(accel_dev); - if (ret) - return ret; - - ret = adf_vf2pf_get_ring_to_svc(accel_dev); - - return ret; -} -EXPORT_SYMBOL_GPL(adf_enable_vf2pf_comms); |