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

crypto: qat - enable legacy VFs

We need to support legacy VFs as well as VFs running on different OSes.
To do so the compatibility check need needs to be relaxed.
This patch moves the logic responsible for VF to PF version and
compatibility checking from adfsriov.c to adf_pf2vf_msg.c,
where it belongs, and changes the logic enable legacy VFs.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Tadeusz Struk and committed by
Herbert Xu
df9e21e1 0f74fbf7

+118 -106
+1
drivers/crypto/qat/qat_common/adf_common_drv.h
··· 111 111 int adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr); 112 112 void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev); 113 113 int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev); 114 + void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info); 114 115 void adf_devmgr_update_class_index(struct adf_hw_device_data *hw_data); 115 116 void adf_clean_vf_map(bool); 116 117
+102
drivers/crypto/qat/qat_common/adf_pf2vf_msg.c
··· 256 256 } 257 257 EXPORT_SYMBOL_GPL(adf_iov_putmsg); 258 258 259 + void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info) 260 + { 261 + struct adf_accel_dev *accel_dev = vf_info->accel_dev; 262 + struct adf_hw_device_data *hw_data = accel_dev->hw_device; 263 + int bar_id = hw_data->get_misc_bar_id(hw_data); 264 + struct adf_bar *pmisc = &GET_BARS(accel_dev)[bar_id]; 265 + void __iomem *pmisc_addr = pmisc->virt_addr; 266 + u32 msg, resp = 0, vf_nr = vf_info->vf_nr; 267 + 268 + /* Read message from the VF */ 269 + msg = ADF_CSR_RD(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr)); 270 + 271 + /* To ACK, clear the VF2PFINT bit */ 272 + msg &= ~ADF_VF2PF_INT; 273 + ADF_CSR_WR(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr), msg); 274 + 275 + if (!(msg & ADF_VF2PF_MSGORIGIN_SYSTEM)) 276 + /* Ignore legacy non-system (non-kernel) VF2PF messages */ 277 + goto err; 278 + 279 + switch ((msg & ADF_VF2PF_MSGTYPE_MASK) >> ADF_VF2PF_MSGTYPE_SHIFT) { 280 + case ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ: 281 + { 282 + u8 vf_compat_ver = msg >> ADF_VF2PF_COMPAT_VER_REQ_SHIFT; 283 + 284 + resp = (ADF_PF2VF_MSGORIGIN_SYSTEM | 285 + (ADF_PF2VF_MSGTYPE_VERSION_RESP << 286 + ADF_PF2VF_MSGTYPE_SHIFT) | 287 + (ADF_PFVF_COMPATIBILITY_VERSION << 288 + ADF_PF2VF_VERSION_RESP_VERS_SHIFT)); 289 + 290 + dev_dbg(&GET_DEV(accel_dev), 291 + "Compatibility Version Request from VF%d vers=%u\n", 292 + vf_nr + 1, vf_compat_ver); 293 + 294 + if (vf_compat_ver < hw_data->min_iov_compat_ver) { 295 + dev_err(&GET_DEV(accel_dev), 296 + "VF (vers %d) incompatible with PF (vers %d)\n", 297 + vf_compat_ver, ADF_PFVF_COMPATIBILITY_VERSION); 298 + resp |= ADF_PF2VF_VF_INCOMPATIBLE << 299 + ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; 300 + } else if (vf_compat_ver > ADF_PFVF_COMPATIBILITY_VERSION) { 301 + dev_err(&GET_DEV(accel_dev), 302 + "VF (vers %d) compat with PF (vers %d) unkn.\n", 303 + vf_compat_ver, ADF_PFVF_COMPATIBILITY_VERSION); 304 + resp |= ADF_PF2VF_VF_COMPAT_UNKNOWN << 305 + ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; 306 + } else { 307 + dev_dbg(&GET_DEV(accel_dev), 308 + "VF (vers %d) compatible with PF (vers %d)\n", 309 + vf_compat_ver, ADF_PFVF_COMPATIBILITY_VERSION); 310 + resp |= ADF_PF2VF_VF_COMPATIBLE << 311 + ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; 312 + } 313 + } 314 + break; 315 + case ADF_VF2PF_MSGTYPE_VERSION_REQ: 316 + dev_dbg(&GET_DEV(accel_dev), 317 + "Legacy VersionRequest received from VF%d 0x%x\n", 318 + vf_nr + 1, msg); 319 + resp = (ADF_PF2VF_MSGORIGIN_SYSTEM | 320 + (ADF_PF2VF_MSGTYPE_VERSION_RESP << 321 + ADF_PF2VF_MSGTYPE_SHIFT) | 322 + (ADF_PFVF_COMPATIBILITY_VERSION << 323 + ADF_PF2VF_VERSION_RESP_VERS_SHIFT)); 324 + resp |= ADF_PF2VF_VF_COMPATIBLE << 325 + ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; 326 + /* Set legacy major and minor version num */ 327 + resp |= 1 << ADF_PF2VF_MAJORVERSION_SHIFT | 328 + 1 << ADF_PF2VF_MINORVERSION_SHIFT; 329 + break; 330 + case ADF_VF2PF_MSGTYPE_INIT: 331 + { 332 + dev_dbg(&GET_DEV(accel_dev), 333 + "Init message received from VF%d 0x%x\n", 334 + vf_nr + 1, msg); 335 + vf_info->init = true; 336 + } 337 + break; 338 + case ADF_VF2PF_MSGTYPE_SHUTDOWN: 339 + { 340 + dev_dbg(&GET_DEV(accel_dev), 341 + "Shutdown message received from VF%d 0x%x\n", 342 + vf_nr + 1, msg); 343 + vf_info->init = false; 344 + } 345 + break; 346 + default: 347 + goto err; 348 + } 349 + 350 + if (resp && adf_iov_putmsg(accel_dev, resp, vf_nr)) 351 + dev_err(&GET_DEV(accel_dev), "Failed to send response to VF\n"); 352 + 353 + /* re-enable interrupt on PF from this VF */ 354 + adf_enable_vf2pf_interrupts(accel_dev, (1 << vf_nr)); 355 + return; 356 + err: 357 + dev_dbg(&GET_DEV(accel_dev), "Unknown message from VF%d (0x%x);\n", 358 + vf_nr + 1, msg); 359 + } 360 + 259 361 void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev) 260 362 { 261 363 struct adf_accel_vf_info *vf;
+2
drivers/crypto/qat/qat_common/adf_pf2vf_msg.h
··· 113 113 #define ADF_PF2VF_VERSION_RESP_VERS_SHIFT 6 114 114 #define ADF_PF2VF_VERSION_RESP_RESULT_MASK 0x0000C000 115 115 #define ADF_PF2VF_VERSION_RESP_RESULT_SHIFT 14 116 + #define ADF_PF2VF_MINORVERSION_SHIFT 6 117 + #define ADF_PF2VF_MAJORVERSION_SHIFT 10 116 118 #define ADF_PF2VF_VF_COMPATIBLE 1 117 119 #define ADF_PF2VF_VF_INCOMPATIBLE 2 118 120 #define ADF_PF2VF_VF_COMPAT_UNKNOWN 3
+13 -106
drivers/crypto/qat/qat_common/adf_sriov.c
··· 79 79 ADF_CSR_WR(pmisc_bar_addr, ME2FUNCTION_MAP_B_OFFSET + \ 80 80 ME2FUNCTION_MAP_REG_SIZE * index, value) 81 81 82 - struct adf_pf2vf_resp_data { 82 + struct adf_pf2vf_resp { 83 83 struct work_struct pf2vf_resp_work; 84 - struct adf_accel_dev *accel_dev; 85 - u32 resp; 86 - u8 vf_nr; 84 + struct adf_accel_vf_info *vf_info; 87 85 }; 88 86 89 87 static void adf_iov_send_resp(struct work_struct *work) 90 88 { 91 - struct adf_pf2vf_resp_data *pf2vf_resp_data = 92 - container_of(work, struct adf_pf2vf_resp_data, pf2vf_resp_work); 89 + struct adf_pf2vf_resp *pf2vf_resp = 90 + container_of(work, struct adf_pf2vf_resp, pf2vf_resp_work); 93 91 94 - if (adf_iov_putmsg(pf2vf_resp_data->accel_dev, pf2vf_resp_data->resp, 95 - pf2vf_resp_data->vf_nr)) { 96 - dev_err(&GET_DEV(pf2vf_resp_data->accel_dev), 97 - "Failed to send response\n"); 98 - } 99 - 100 - kfree(pf2vf_resp_data); 92 + adf_vf2pf_req_hndl(pf2vf_resp->vf_info); 93 + kfree(pf2vf_resp); 101 94 } 102 95 103 96 static void adf_vf2pf_bh_handler(void *data) 104 97 { 105 98 struct adf_accel_vf_info *vf_info = (struct adf_accel_vf_info *)data; 106 - struct adf_accel_dev *accel_dev = vf_info->accel_dev; 107 - struct adf_hw_device_data *hw_data = accel_dev->hw_device; 108 - struct adf_bar *pmisc = 109 - &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; 110 - void __iomem *pmisc_addr = pmisc->virt_addr; 111 - u32 msg; 99 + struct adf_pf2vf_resp *pf2vf_resp; 112 100 113 - /* Read message from the VF */ 114 - msg = ADF_CSR_RD(pmisc_addr, hw_data->get_pf2vf_offset(vf_info->vf_nr)); 101 + pf2vf_resp = kzalloc(sizeof(*pf2vf_resp), GFP_ATOMIC); 102 + if (!pf2vf_resp) 103 + return; 115 104 116 - if (!(msg & ADF_VF2PF_MSGORIGIN_SYSTEM)) 117 - /* Ignore legacy non-system (non-kernel) VF2PF messages */ 118 - goto err; 119 - 120 - switch ((msg & ADF_VF2PF_MSGTYPE_MASK) >> ADF_VF2PF_MSGTYPE_SHIFT) { 121 - case ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ: 122 - { 123 - u8 vf_compat_ver = msg >> ADF_VF2PF_COMPAT_VER_REQ_SHIFT; 124 - struct adf_pf2vf_resp_data *pf2vf_resp_data; 125 - u32 resp = (ADF_PF2VF_MSGORIGIN_SYSTEM | 126 - (ADF_PF2VF_MSGTYPE_VERSION_RESP << 127 - ADF_PF2VF_MSGTYPE_SHIFT) | 128 - (ADF_PFVF_COMPATIBILITY_VERSION << 129 - ADF_PF2VF_VERSION_RESP_VERS_SHIFT)); 130 - 131 - dev_dbg(&GET_DEV(accel_dev), 132 - "Compatibility Version Request from VF%d vers=%u\n", 133 - vf_info->vf_nr + 1, vf_compat_ver); 134 - 135 - if (vf_compat_ver < hw_data->min_iov_compat_ver) { 136 - dev_err(&GET_DEV(accel_dev), 137 - "VF (vers %d) incompatible with PF (vers %d)\n", 138 - vf_compat_ver, ADF_PFVF_COMPATIBILITY_VERSION); 139 - resp |= ADF_PF2VF_VF_INCOMPATIBLE << 140 - ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; 141 - } else if (vf_compat_ver > ADF_PFVF_COMPATIBILITY_VERSION) { 142 - dev_err(&GET_DEV(accel_dev), 143 - "VF (vers %d) compat with PF (vers %d) unkn.\n", 144 - vf_compat_ver, ADF_PFVF_COMPATIBILITY_VERSION); 145 - resp |= ADF_PF2VF_VF_COMPAT_UNKNOWN << 146 - ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; 147 - } else { 148 - dev_dbg(&GET_DEV(accel_dev), 149 - "VF (vers %d) compatible with PF (vers %d)\n", 150 - vf_compat_ver, ADF_PFVF_COMPATIBILITY_VERSION); 151 - resp |= ADF_PF2VF_VF_COMPATIBLE << 152 - ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; 153 - } 154 - 155 - pf2vf_resp_data = kzalloc(sizeof(*pf2vf_resp_data), GFP_ATOMIC); 156 - if (!pf2vf_resp_data) 157 - return; 158 - 159 - pf2vf_resp_data->accel_dev = accel_dev; 160 - pf2vf_resp_data->vf_nr = vf_info->vf_nr; 161 - pf2vf_resp_data->resp = resp; 162 - INIT_WORK(&pf2vf_resp_data->pf2vf_resp_work, adf_iov_send_resp); 163 - queue_work(pf2vf_resp_wq, &pf2vf_resp_data->pf2vf_resp_work); 164 - } 165 - break; 166 - case ADF_VF2PF_MSGTYPE_INIT: 167 - { 168 - dev_dbg(&GET_DEV(accel_dev), 169 - "Init message received from VF%d 0x%x\n", 170 - vf_info->vf_nr + 1, msg); 171 - vf_info->init = true; 172 - } 173 - break; 174 - case ADF_VF2PF_MSGTYPE_SHUTDOWN: 175 - { 176 - dev_dbg(&GET_DEV(accel_dev), 177 - "Shutdown message received from VF%d 0x%x\n", 178 - vf_info->vf_nr + 1, msg); 179 - vf_info->init = false; 180 - } 181 - break; 182 - case ADF_VF2PF_MSGTYPE_VERSION_REQ: 183 - dev_err(&GET_DEV(accel_dev), 184 - "Incompatible VersionRequest received from VF%d 0x%x\n", 185 - vf_info->vf_nr + 1, msg); 186 - break; 187 - default: 188 - goto err; 189 - } 190 - 191 - /* To ACK, clear the VF2PFINT bit */ 192 - msg &= ~ADF_VF2PF_INT; 193 - ADF_CSR_WR(pmisc_addr, hw_data->get_pf2vf_offset(vf_info->vf_nr), msg); 194 - 195 - /* re-enable interrupt on PF from this VF */ 196 - adf_enable_vf2pf_interrupts(accel_dev, (1 << vf_info->vf_nr)); 197 - return; 198 - err: 199 - dev_err(&GET_DEV(accel_dev), "Unknown message from VF%d (0x%x);\n", 200 - vf_info->vf_nr + 1, msg); 105 + pf2vf_resp->vf_info = vf_info; 106 + INIT_WORK(&pf2vf_resp->pf2vf_resp_work, adf_iov_send_resp); 107 + queue_work(pf2vf_resp_wq, &pf2vf_resp->pf2vf_resp_work); 201 108 } 202 109 203 110 static int adf_enable_sriov(struct adf_accel_dev *accel_dev)