Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: qat - introduce support for PFVF block messages

GEN2 devices use a single CSR for PFVF messages, which leaves up to 10 bits
of payload per single message. While such amount is sufficient for the
currently defined messages, the transfer of bigger and more complex data
streams from the PF to the VF requires a new mechanism that extends the
protocol.

This patch adds a new layer on top of the basic PFVF messaging, called
Block Messages, to encapsulate up to 126 bytes of data in a single
logical message across multiple PFVF messages of new types (SMALL,
MEDIUM and LARGE BLOCK), including (sub)types (BLKMSG_TYPE) to carry the
information about the actual Block Message.

Regardless of the size, each Block Message uses a two bytes header,
containing the version and size, to allow for extension while
maintaining compatibility. The size and the types of Block Messages are
defined as follow:

- small block messages: up to 16 BLKMSG types of up to 30 bytes
- medium block messages: up to 8 BLKMSG types of up to 62 bytes
- large block messages: up to 4 BLKMSG types of up to 126 bytes

It effectively works as reading a byte at a time from a block device and
for each of these new Block Messages:
- the requestor (always a VF) can either request a specific byte of the
larger message, in order to retrieve the full message, or request the
value of the CRC calculated for a specific message up to the provided
size (to allow for messages to grow while maintaining forward
compatibility)
- the responder (always the PF) will either return a single data or CRC
byte, along with the indication of response type (or error).

This patch provides the basic infrastructure to perform the above
operations, without defining any new message.

As CRCs are required, this code now depends on the CRC8 module.

Note: as a consequence of the Block Messages design, sending multiple
PFVF messages in bursts, the interrupt rate limiting values on the PF are
increased.

Signed-off-by: Marco Chiappero <marco.chiappero@intel.com>
Co-developed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: Fiona Trahe <fiona.trahe@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Marco Chiappero and committed by
Herbert Xu
673184a2 3a5b2a08

+442 -3
+1
drivers/crypto/qat/Kconfig
··· 13 13 select CRYPTO_SHA512 14 14 select CRYPTO_LIB_AES 15 15 select FW_LOADER 16 + select CRC8 16 17 17 18 config CRYPTO_DEV_QAT_DH895xCC 18 19 tristate "Support for Intel(R) DH895xCC"
+74
drivers/crypto/qat/qat_common/adf_pfvf_msg.h
··· 71 71 enum pf2vf_msgtype { 72 72 ADF_PF2VF_MSGTYPE_RESTARTING = 0x01, 73 73 ADF_PF2VF_MSGTYPE_VERSION_RESP = 0x02, 74 + ADF_PF2VF_MSGTYPE_BLKMSG_RESP = 0x03, 74 75 }; 75 76 76 77 /* VF->PF messages */ ··· 80 79 ADF_VF2PF_MSGTYPE_SHUTDOWN = 0x04, 81 80 ADF_VF2PF_MSGTYPE_VERSION_REQ = 0x05, 82 81 ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ = 0x06, 82 + ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ = 0x07, 83 + ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ = 0x08, 84 + ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ = 0x09, 83 85 }; 84 86 85 87 /* VF/PF compatibility version. */ ··· 100 96 ADF_PF2VF_VF_INCOMPATIBLE = 0x02, 101 97 ADF_PF2VF_VF_COMPAT_UNKNOWN = 0x03, 102 98 }; 99 + 100 + /* PF->VF Block Responses */ 101 + #define ADF_PF2VF_BLKMSG_RESP_TYPE_MASK GENMASK(1, 0) 102 + #define ADF_PF2VF_BLKMSG_RESP_DATA_MASK GENMASK(9, 2) 103 + 104 + enum pf2vf_blkmsg_resp_type { 105 + ADF_PF2VF_BLKMSG_RESP_TYPE_DATA = 0x00, 106 + ADF_PF2VF_BLKMSG_RESP_TYPE_CRC = 0x01, 107 + ADF_PF2VF_BLKMSG_RESP_TYPE_ERROR = 0x02, 108 + }; 109 + 110 + /* PF->VF Block Error Code */ 111 + enum pf2vf_blkmsg_error { 112 + ADF_PF2VF_INVALID_BLOCK_TYPE = 0x00, 113 + ADF_PF2VF_INVALID_BYTE_NUM_REQ = 0x01, 114 + ADF_PF2VF_PAYLOAD_TRUNCATED = 0x02, 115 + ADF_PF2VF_UNSPECIFIED_ERROR = 0x03, 116 + }; 117 + 118 + /* VF->PF Block Requests */ 119 + #define ADF_VF2PF_LARGE_BLOCK_TYPE_MASK GENMASK(1, 0) 120 + #define ADF_VF2PF_LARGE_BLOCK_BYTE_MASK GENMASK(8, 2) 121 + #define ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK GENMASK(2, 0) 122 + #define ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK GENMASK(8, 3) 123 + #define ADF_VF2PF_SMALL_BLOCK_TYPE_MASK GENMASK(3, 0) 124 + #define ADF_VF2PF_SMALL_BLOCK_BYTE_MASK GENMASK(8, 4) 125 + #define ADF_VF2PF_BLOCK_CRC_REQ_MASK BIT(9) 126 + 127 + /* PF->VF Block Request Types 128 + * 0..15 - 32 byte message 129 + * 16..23 - 64 byte message 130 + * 24..27 - 128 byte message 131 + */ 132 + /* No block messages as of yet */ 133 + 134 + #define ADF_VF2PF_SMALL_BLOCK_TYPE_MAX \ 135 + (FIELD_MAX(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK)) 136 + 137 + #define ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX \ 138 + (FIELD_MAX(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK) + \ 139 + ADF_VF2PF_SMALL_BLOCK_TYPE_MAX + 1) 140 + 141 + #define ADF_VF2PF_LARGE_BLOCK_TYPE_MAX \ 142 + (FIELD_MAX(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK) + \ 143 + ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX) 144 + 145 + #define ADF_VF2PF_SMALL_BLOCK_BYTE_MAX \ 146 + FIELD_MAX(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK) 147 + 148 + #define ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX \ 149 + FIELD_MAX(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK) 150 + 151 + #define ADF_VF2PF_LARGE_BLOCK_BYTE_MAX \ 152 + FIELD_MAX(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK) 153 + 154 + struct pfvf_blkmsg_header { 155 + u8 version; 156 + u8 payload_size; 157 + } __packed; 158 + 159 + #define ADF_PFVF_BLKMSG_HEADER_SIZE (sizeof(struct pfvf_blkmsg_header)) 160 + #define ADF_PFVF_BLKMSG_PAYLOAD_SIZE(blkmsg) (sizeof(blkmsg) - \ 161 + ADF_PFVF_BLKMSG_HEADER_SIZE) 162 + #define ADF_PFVF_BLKMSG_MSG_SIZE(blkmsg) (ADF_PFVF_BLKMSG_HEADER_SIZE + \ 163 + (blkmsg)->hdr.payload_size) 164 + #define ADF_PFVF_BLKMSG_MSG_MAX_SIZE 128 165 + 166 + /* PF->VF Block message header bytes */ 167 + #define ADF_PFVF_BLKMSG_VER_BYTE 0 168 + #define ADF_PFVF_BLKMSG_LEN_BYTE 1 103 169 104 170 #endif /* ADF_PFVF_MSG_H */
+3
drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
··· 7 7 8 8 void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev); 9 9 10 + typedef int (*adf_pf2vf_blkmsg_provider)(struct adf_accel_dev *accel_dev, 11 + u8 *buffer, u8 compat); 12 + 10 13 #endif /* ADF_PFVF_PF_MSG_H */
+137
drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
··· 6 6 #include "adf_accel_devices.h" 7 7 #include "adf_common_drv.h" 8 8 #include "adf_pfvf_msg.h" 9 + #include "adf_pfvf_pf_msg.h" 9 10 #include "adf_pfvf_pf_proto.h" 11 + #include "adf_pfvf_utils.h" 12 + 13 + typedef u8 (*pf2vf_blkmsg_data_getter_fn)(u8 const *blkmsg, u8 byte); 14 + 15 + static const adf_pf2vf_blkmsg_provider pf2vf_blkmsg_providers[] = { 16 + NULL, /* no message type defined for value 0 */ 17 + NULL, /* no message type defined for value 1 */ 18 + }; 10 19 11 20 /** 12 21 * adf_send_pf2vf_msg() - send PF to VF message ··· 51 42 u32 pfvf_offset = pfvf_ops->get_vf2pf_offset(vf_nr); 52 43 53 44 return pfvf_ops->recv_msg(accel_dev, pfvf_offset); 45 + } 46 + 47 + static adf_pf2vf_blkmsg_provider get_blkmsg_response_provider(u8 type) 48 + { 49 + if (type >= ARRAY_SIZE(pf2vf_blkmsg_providers)) 50 + return NULL; 51 + 52 + return pf2vf_blkmsg_providers[type]; 53 + } 54 + 55 + /* Byte pf2vf_blkmsg_data_getter_fn callback */ 56 + static u8 adf_pf2vf_blkmsg_get_byte(u8 const *blkmsg, u8 index) 57 + { 58 + return blkmsg[index]; 59 + } 60 + 61 + /* CRC pf2vf_blkmsg_data_getter_fn callback */ 62 + static u8 adf_pf2vf_blkmsg_get_crc(u8 const *blkmsg, u8 count) 63 + { 64 + /* count is 0-based, turn it into a length */ 65 + return adf_pfvf_calc_blkmsg_crc(blkmsg, count + 1); 66 + } 67 + 68 + static int adf_pf2vf_blkmsg_get_data(struct adf_accel_vf_info *vf_info, 69 + u8 type, u8 byte, u8 max_size, u8 *data, 70 + pf2vf_blkmsg_data_getter_fn data_getter) 71 + { 72 + u8 blkmsg[ADF_PFVF_BLKMSG_MSG_MAX_SIZE] = { 0 }; 73 + struct adf_accel_dev *accel_dev = vf_info->accel_dev; 74 + adf_pf2vf_blkmsg_provider provider; 75 + u8 msg_size; 76 + 77 + provider = get_blkmsg_response_provider(type); 78 + 79 + if (unlikely(!provider)) { 80 + pr_err("QAT: No registered provider for message %d\n", type); 81 + *data = ADF_PF2VF_INVALID_BLOCK_TYPE; 82 + return -EINVAL; 83 + } 84 + 85 + if (unlikely((*provider)(accel_dev, blkmsg, vf_info->vf_compat_ver))) { 86 + pr_err("QAT: unknown error from provider for message %d\n", type); 87 + *data = ADF_PF2VF_UNSPECIFIED_ERROR; 88 + return -EINVAL; 89 + } 90 + 91 + msg_size = ADF_PFVF_BLKMSG_HEADER_SIZE + blkmsg[ADF_PFVF_BLKMSG_LEN_BYTE]; 92 + 93 + if (unlikely(msg_size >= max_size)) { 94 + pr_err("QAT: Invalid size %d provided for message type %d\n", 95 + msg_size, type); 96 + *data = ADF_PF2VF_PAYLOAD_TRUNCATED; 97 + return -EINVAL; 98 + } 99 + 100 + if (unlikely(byte >= msg_size)) { 101 + pr_err("QAT: Out-of-bound byte number %d (msg size %d)\n", 102 + byte, msg_size); 103 + *data = ADF_PF2VF_INVALID_BYTE_NUM_REQ; 104 + return -EINVAL; 105 + } 106 + 107 + *data = data_getter(blkmsg, byte); 108 + return 0; 109 + } 110 + 111 + static struct pfvf_message handle_blkmsg_req(struct adf_accel_vf_info *vf_info, 112 + struct pfvf_message req) 113 + { 114 + u8 resp_type = ADF_PF2VF_BLKMSG_RESP_TYPE_ERROR; 115 + struct pfvf_message resp = { 0 }; 116 + u8 resp_data = 0; 117 + u8 blk_type; 118 + u8 blk_byte; 119 + u8 byte_max; 120 + 121 + switch (req.type) { 122 + case ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ: 123 + blk_type = FIELD_GET(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK, req.data) 124 + + ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX + 1; 125 + blk_byte = FIELD_GET(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK, req.data); 126 + byte_max = ADF_VF2PF_LARGE_BLOCK_BYTE_MAX; 127 + break; 128 + case ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ: 129 + blk_type = FIELD_GET(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK, req.data) 130 + + ADF_VF2PF_SMALL_BLOCK_TYPE_MAX + 1; 131 + blk_byte = FIELD_GET(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK, req.data); 132 + byte_max = ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX; 133 + break; 134 + case ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ: 135 + blk_type = FIELD_GET(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK, req.data); 136 + blk_byte = FIELD_GET(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK, req.data); 137 + byte_max = ADF_VF2PF_SMALL_BLOCK_BYTE_MAX; 138 + break; 139 + } 140 + 141 + /* Is this a request for CRC or data? */ 142 + if (FIELD_GET(ADF_VF2PF_BLOCK_CRC_REQ_MASK, req.data)) { 143 + dev_dbg(&GET_DEV(vf_info->accel_dev), 144 + "BlockMsg of type %d for CRC over %d bytes received from VF%d\n", 145 + blk_type, blk_byte, vf_info->vf_nr); 146 + 147 + if (!adf_pf2vf_blkmsg_get_data(vf_info, blk_type, blk_byte, 148 + byte_max, &resp_data, 149 + adf_pf2vf_blkmsg_get_crc)) 150 + resp_type = ADF_PF2VF_BLKMSG_RESP_TYPE_CRC; 151 + } else { 152 + dev_dbg(&GET_DEV(vf_info->accel_dev), 153 + "BlockMsg of type %d for data byte %d received from VF%d\n", 154 + blk_type, blk_byte, vf_info->vf_nr); 155 + 156 + if (!adf_pf2vf_blkmsg_get_data(vf_info, blk_type, blk_byte, 157 + byte_max, &resp_data, 158 + adf_pf2vf_blkmsg_get_byte)) 159 + resp_type = ADF_PF2VF_BLKMSG_RESP_TYPE_DATA; 160 + } 161 + 162 + resp.type = ADF_PF2VF_MSGTYPE_BLKMSG_RESP; 163 + resp.data = FIELD_PREP(ADF_PF2VF_BLKMSG_RESP_TYPE_MASK, resp_type) | 164 + FIELD_PREP(ADF_PF2VF_BLKMSG_RESP_DATA_MASK, resp_data); 165 + 166 + return resp; 54 167 } 55 168 56 169 static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr, ··· 237 106 vf_info->init = false; 238 107 } 239 108 break; 109 + case ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ: 110 + case ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ: 111 + case ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ: 112 + *resp = handle_blkmsg_req(vf_info, msg); 113 + break; 240 114 default: 241 115 dev_dbg(&GET_DEV(accel_dev), 242 116 "Unknown message from VF%d (type 0x%.4x, data: 0x%.4x)\n", ··· 283 147 */ 284 148 int adf_enable_pf2vf_comms(struct adf_accel_dev *accel_dev) 285 149 { 150 + adf_pfvf_crc_init(); 286 151 spin_lock_init(&accel_dev->pf.vf2pf_ints_lock); 287 152 288 153 return 0;
+15
drivers/crypto/qat/qat_common/adf_pfvf_utils.c
··· 1 1 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) 2 2 /* Copyright(c) 2021 Intel Corporation */ 3 + #include <linux/crc8.h> 3 4 #include <linux/pci.h> 4 5 #include <linux/types.h> 5 6 #include "adf_accel_devices.h" 6 7 #include "adf_pfvf_msg.h" 7 8 #include "adf_pfvf_utils.h" 9 + 10 + /* CRC Calculation */ 11 + DECLARE_CRC8_TABLE(pfvf_crc8_table); 12 + #define ADF_PFVF_CRC8_POLYNOMIAL 0x97 13 + 14 + void adf_pfvf_crc_init(void) 15 + { 16 + crc8_populate_msb(pfvf_crc8_table, ADF_PFVF_CRC8_POLYNOMIAL); 17 + } 18 + 19 + u8 adf_pfvf_calc_blkmsg_crc(u8 const *buf, u8 buf_len) 20 + { 21 + return crc8(pfvf_crc8_table, buf, buf_len, CRC8_INIT_VALUE); 22 + } 8 23 9 24 static bool set_value_on_csr_msg(struct adf_accel_dev *accel_dev, u32 *csr_msg, 10 25 u32 value, const struct pfvf_field_format *fmt)
+3
drivers/crypto/qat/qat_common/adf_pfvf_utils.h
··· 10 10 #define ADF_PFVF_MSG_ACK_DELAY_US 4 11 11 #define ADF_PFVF_MSG_ACK_MAX_DELAY_US (1 * USEC_PER_SEC) 12 12 13 + u8 adf_pfvf_calc_blkmsg_crc(u8 const *buf, u8 buf_len); 14 + void adf_pfvf_crc_init(void); 15 + 13 16 struct pfvf_field_format { 14 17 u8 offset; 15 18 u32 mask;
+202 -1
drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
··· 1 1 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) 2 2 /* Copyright(c) 2015 - 2021 Intel Corporation */ 3 + #include <linux/bitfield.h> 3 4 #include <linux/completion.h> 5 + #include <linux/minmax.h> 4 6 #include <linux/types.h> 5 7 #include "adf_accel_devices.h" 6 8 #include "adf_common_drv.h" 7 9 #include "adf_pfvf_msg.h" 10 + #include "adf_pfvf_utils.h" 8 11 #include "adf_pfvf_vf_msg.h" 9 12 #include "adf_pfvf_vf_proto.h" 10 13 ··· 97 94 return 0; 98 95 } 99 96 97 + static int adf_vf2pf_blkmsg_data_req(struct adf_accel_dev *accel_dev, bool crc, 98 + u8 *type, u8 *data) 99 + { 100 + struct pfvf_message req = { 0 }; 101 + struct pfvf_message resp = { 0 }; 102 + u8 blk_type; 103 + u8 blk_byte; 104 + u8 msg_type; 105 + u8 max_data; 106 + int err; 107 + 108 + /* Convert the block type to {small, medium, large} size category */ 109 + if (*type <= ADF_VF2PF_SMALL_BLOCK_TYPE_MAX) { 110 + msg_type = ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ; 111 + blk_type = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK, *type); 112 + blk_byte = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK, *data); 113 + max_data = ADF_VF2PF_SMALL_BLOCK_BYTE_MAX; 114 + } else if (*type <= ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX) { 115 + msg_type = ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ; 116 + blk_type = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK, 117 + *type - ADF_VF2PF_SMALL_BLOCK_TYPE_MAX); 118 + blk_byte = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK, *data); 119 + max_data = ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX; 120 + } else if (*type <= ADF_VF2PF_LARGE_BLOCK_TYPE_MAX) { 121 + msg_type = ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ; 122 + blk_type = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK, 123 + *type - ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX); 124 + blk_byte = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK, *data); 125 + max_data = ADF_VF2PF_LARGE_BLOCK_BYTE_MAX; 126 + } else { 127 + dev_err(&GET_DEV(accel_dev), "Invalid message type %u\n", *type); 128 + return -EINVAL; 129 + } 130 + 131 + /* Sanity check */ 132 + if (*data > max_data) { 133 + dev_err(&GET_DEV(accel_dev), 134 + "Invalid byte %s %u for message type %u\n", 135 + crc ? "count" : "index", *data, *type); 136 + return -EINVAL; 137 + } 138 + 139 + /* Build the block message */ 140 + req.type = msg_type; 141 + req.data = blk_type | blk_byte | FIELD_PREP(ADF_VF2PF_BLOCK_CRC_REQ_MASK, crc); 142 + 143 + err = adf_send_vf2pf_req(accel_dev, req, &resp); 144 + if (err) 145 + return err; 146 + 147 + *type = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_TYPE_MASK, resp.data); 148 + *data = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_DATA_MASK, resp.data); 149 + 150 + return 0; 151 + } 152 + 153 + static int adf_vf2pf_blkmsg_get_byte(struct adf_accel_dev *accel_dev, u8 type, 154 + u8 index, u8 *data) 155 + { 156 + int ret; 157 + 158 + ret = adf_vf2pf_blkmsg_data_req(accel_dev, false, &type, &index); 159 + if (ret < 0) 160 + return ret; 161 + 162 + if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_DATA)) { 163 + dev_err(&GET_DEV(accel_dev), 164 + "Unexpected BLKMSG response type %u, byte 0x%x\n", 165 + type, index); 166 + return -EFAULT; 167 + } 168 + 169 + *data = index; 170 + return 0; 171 + } 172 + 173 + static int adf_vf2pf_blkmsg_get_crc(struct adf_accel_dev *accel_dev, u8 type, 174 + u8 bytes, u8 *crc) 175 + { 176 + int ret; 177 + 178 + /* The count of bytes refers to a length, however shift it to a 0-based 179 + * count to avoid overflows. Thus, a request for 0 bytes is technically 180 + * valid. 181 + */ 182 + --bytes; 183 + 184 + ret = adf_vf2pf_blkmsg_data_req(accel_dev, true, &type, &bytes); 185 + if (ret < 0) 186 + return ret; 187 + 188 + if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_CRC)) { 189 + dev_err(&GET_DEV(accel_dev), 190 + "Unexpected CRC BLKMSG response type %u, crc 0x%x\n", 191 + type, bytes); 192 + return -EFAULT; 193 + } 194 + 195 + *crc = bytes; 196 + return 0; 197 + } 198 + 199 + /** 200 + * adf_send_vf2pf_blkmsg_req() - retrieve block message 201 + * @accel_dev: Pointer to acceleration VF device. 202 + * @type: The block message type, see adf_pfvf_msg.h for allowed values 203 + * @buffer: input buffer where to place the received data 204 + * @buffer_len: buffer length as input, the amount of written bytes on output 205 + * 206 + * Request a message of type 'type' over the block message transport. 207 + * This function will send the required amount block message requests and 208 + * return the overall content back to the caller through the provided buffer. 209 + * The buffer should be large enough to contain the requested message type, 210 + * otherwise the response will be truncated. 211 + * 212 + * Return: 0 on success, error code otherwise. 213 + */ 214 + int adf_send_vf2pf_blkmsg_req(struct adf_accel_dev *accel_dev, u8 type, 215 + u8 *buffer, unsigned int *buffer_len) 216 + { 217 + unsigned int index; 218 + unsigned int msg_len; 219 + int ret; 220 + u8 remote_crc; 221 + u8 local_crc; 222 + 223 + if (unlikely(type > ADF_VF2PF_LARGE_BLOCK_TYPE_MAX)) { 224 + dev_err(&GET_DEV(accel_dev), "Invalid block message type %d\n", 225 + type); 226 + return -EINVAL; 227 + } 228 + 229 + if (unlikely(*buffer_len < ADF_PFVF_BLKMSG_HEADER_SIZE)) { 230 + dev_err(&GET_DEV(accel_dev), 231 + "Buffer size too small for a block message\n"); 232 + return -EINVAL; 233 + } 234 + 235 + ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type, 236 + ADF_PFVF_BLKMSG_VER_BYTE, 237 + &buffer[ADF_PFVF_BLKMSG_VER_BYTE]); 238 + if (unlikely(ret)) 239 + return ret; 240 + 241 + if (unlikely(!buffer[ADF_PFVF_BLKMSG_VER_BYTE])) { 242 + dev_err(&GET_DEV(accel_dev), 243 + "Invalid version 0 received for block request %u", type); 244 + return -EFAULT; 245 + } 246 + 247 + ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type, 248 + ADF_PFVF_BLKMSG_LEN_BYTE, 249 + &buffer[ADF_PFVF_BLKMSG_LEN_BYTE]); 250 + if (unlikely(ret)) 251 + return ret; 252 + 253 + if (unlikely(!buffer[ADF_PFVF_BLKMSG_LEN_BYTE])) { 254 + dev_err(&GET_DEV(accel_dev), 255 + "Invalid size 0 received for block request %u", type); 256 + return -EFAULT; 257 + } 258 + 259 + /* We need to pick the minimum since there is no way to request a 260 + * specific version. As a consequence any scenario is possible: 261 + * - PF has a newer (longer) version which doesn't fit in the buffer 262 + * - VF expects a newer (longer) version, so we must not ask for 263 + * bytes in excess 264 + * - PF and VF share the same version, no problem 265 + */ 266 + msg_len = ADF_PFVF_BLKMSG_HEADER_SIZE + buffer[ADF_PFVF_BLKMSG_LEN_BYTE]; 267 + msg_len = min(*buffer_len, msg_len); 268 + 269 + /* Get the payload */ 270 + for (index = ADF_PFVF_BLKMSG_HEADER_SIZE; index < msg_len; index++) { 271 + ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type, index, 272 + &buffer[index]); 273 + if (unlikely(ret)) 274 + return ret; 275 + } 276 + 277 + ret = adf_vf2pf_blkmsg_get_crc(accel_dev, type, msg_len, &remote_crc); 278 + if (unlikely(ret)) 279 + return ret; 280 + 281 + local_crc = adf_pfvf_calc_blkmsg_crc(buffer, msg_len); 282 + if (unlikely(local_crc != remote_crc)) { 283 + dev_err(&GET_DEV(accel_dev), 284 + "CRC error on msg type %d. Local %02X, remote %02X\n", 285 + type, local_crc, remote_crc); 286 + return -EIO; 287 + } 288 + 289 + *buffer_len = msg_len; 290 + return 0; 291 + } 292 + 100 293 static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev, 101 294 struct pfvf_message msg) 102 295 { ··· 303 104 adf_pf2vf_handle_pf_restarting(accel_dev); 304 105 return false; 305 106 case ADF_PF2VF_MSGTYPE_VERSION_RESP: 107 + case ADF_PF2VF_MSGTYPE_BLKMSG_RESP: 306 108 dev_dbg(&GET_DEV(accel_dev), 307 109 "Response Message received from PF (type 0x%.4x, data 0x%.4x)\n", 308 110 msg.type, msg.data); ··· 335 135 /** 336 136 * adf_enable_vf2pf_comms() - Function enables communication from vf to pf 337 137 * 338 - * @accel_dev: Pointer to acceleration device virtual function. 138 + * @accel_dev: Pointer to acceleration device virtual function. 339 139 * 340 140 * Return: 0 on success, error code otherwise. 341 141 */ 342 142 int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev) 343 143 { 144 + adf_pfvf_crc_init(); 344 145 adf_enable_pf2vf_interrupts(accel_dev); 345 146 return adf_vf2pf_request_version(accel_dev); 346 147 }
+2
drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h
··· 9 9 int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, struct pfvf_message msg); 10 10 int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, struct pfvf_message msg, 11 11 struct pfvf_message *resp); 12 + int adf_send_vf2pf_blkmsg_req(struct adf_accel_dev *accel_dev, u8 type, 13 + u8 *buffer, unsigned int *buffer_len); 12 14 13 15 int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev); 14 16
+5 -2
drivers/crypto/qat/qat_common/adf_sriov.c
··· 8 8 #include "adf_cfg.h" 9 9 #include "adf_pfvf_pf_msg.h" 10 10 11 + #define ADF_VF2PF_RATELIMIT_INTERVAL 8 12 + #define ADF_VF2PF_RATELIMIT_BURST 130 13 + 11 14 static struct workqueue_struct *pf2vf_resp_wq; 12 15 13 16 struct adf_pf2vf_resp { ··· 65 62 66 63 mutex_init(&vf_info->pf2vf_lock); 67 64 ratelimit_state_init(&vf_info->vf2pf_ratelimit, 68 - DEFAULT_RATELIMIT_INTERVAL, 69 - DEFAULT_RATELIMIT_BURST); 65 + ADF_VF2PF_RATELIMIT_INTERVAL, 66 + ADF_VF2PF_RATELIMIT_BURST); 70 67 } 71 68 72 69 /* Set Valid bits in AE Thread to PCIe Function Mapping */