crypto: qat - add PFVF support to enable the reset of ring pairs
authorMarco Chiappero <marco.chiappero@intel.com>
Thu, 16 Dec 2021 09:13:32 +0000 (09:13 +0000)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 24 Dec 2021 03:18:27 +0000 (14:18 +1100)
Extend support for resetting ring pairs on the device to VFs. Such
reset happens by sending a request to the PF over the PFVF protocol.

This patch defines two new PFVF messages and adds the PFVF logic for
handling the request on PF, triggering the reset, and VFs, accepting the
'success'/'error' response.

This feature is GEN4 specific.

This patch is based on earlier work done by Zelin Deng.

Signed-off-by: Marco Chiappero <marco.chiappero@intel.com>
Reviewed-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>
drivers/crypto/qat/qat_common/adf_pfvf_msg.h
drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c

index f00e9e2..86b0e7b 100644 (file)
@@ -99,6 +99,8 @@ enum pf2vf_msgtype {
        ADF_PF2VF_MSGTYPE_RESTARTING            = 0x01,
        ADF_PF2VF_MSGTYPE_VERSION_RESP          = 0x02,
        ADF_PF2VF_MSGTYPE_BLKMSG_RESP           = 0x03,
+/* Values from 0x10 are Gen4 specific, message type is only 4 bits in Gen2 devices. */
+       ADF_PF2VF_MSGTYPE_RP_RESET_RESP         = 0x10,
 };
 
 /* VF->PF messages */
@@ -110,6 +112,8 @@ enum vf2pf_msgtype {
        ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ       = 0x07,
        ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ      = 0x08,
        ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ       = 0x09,
+/* Values from 0x10 are Gen4 specific, message type is only 4 bits in Gen2 devices. */
+       ADF_VF2PF_MSGTYPE_RP_RESET              = 0x10,
 };
 
 /* VF/PF compatibility version. */
@@ -134,6 +138,16 @@ enum pf2vf_compat_response {
        ADF_PF2VF_VF_COMPAT_UNKNOWN             = 0x03,
 };
 
+enum ring_reset_result {
+       RPRESET_SUCCESS                         = 0x01,
+       RPRESET_NOT_SUPPORTED                   = 0x02,
+       RPRESET_INVAL_BANK                      = 0x03,
+       RPRESET_TIMEOUT                         = 0x04,
+};
+
+#define ADF_VF2PF_RNG_RESET_RP_MASK            GENMASK(1, 0)
+#define ADF_VF2PF_RNG_RESET_RSVD_MASK          GENMASK(25, 2)
+
 /* PF->VF Block Responses */
 #define ADF_PF2VF_BLKMSG_RESP_TYPE_MASK                GENMASK(1, 0)
 #define ADF_PF2VF_BLKMSG_RESP_DATA_MASK                GENMASK(9, 2)
index 84230aa..588352d 100644 (file)
@@ -178,6 +178,55 @@ static struct pfvf_message handle_blkmsg_req(struct adf_accel_vf_info *vf_info,
        return resp;
 }
 
+static struct pfvf_message handle_rp_reset_req(struct adf_accel_dev *accel_dev, u8 vf_nr,
+                                              struct pfvf_message req)
+{
+       struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+       struct pfvf_message resp = {
+               .type = ADF_PF2VF_MSGTYPE_RP_RESET_RESP,
+               .data = RPRESET_SUCCESS
+       };
+       u32 bank_number;
+       u32 rsvd_field;
+
+       bank_number = FIELD_GET(ADF_VF2PF_RNG_RESET_RP_MASK, req.data);
+       rsvd_field = FIELD_GET(ADF_VF2PF_RNG_RESET_RSVD_MASK, req.data);
+
+       dev_dbg(&GET_DEV(accel_dev),
+               "Ring Pair Reset Message received from VF%d for bank 0x%x\n",
+               vf_nr, bank_number);
+
+       if (!hw_data->ring_pair_reset || rsvd_field) {
+               dev_dbg(&GET_DEV(accel_dev),
+                       "Ring Pair Reset for VF%d is not supported\n", vf_nr);
+               resp.data = RPRESET_NOT_SUPPORTED;
+               goto out;
+       }
+
+       if (bank_number >= hw_data->num_banks_per_vf) {
+               dev_err(&GET_DEV(accel_dev),
+                       "Invalid bank number (0x%x) from VF%d for Ring Reset\n",
+                       bank_number, vf_nr);
+               resp.data = RPRESET_INVAL_BANK;
+               goto out;
+       }
+
+       /* Convert the VF provided value to PF bank number */
+       bank_number = vf_nr * hw_data->num_banks_per_vf + bank_number;
+       if (hw_data->ring_pair_reset(accel_dev, bank_number)) {
+               dev_dbg(&GET_DEV(accel_dev),
+                       "Ring pair reset for VF%d failure\n", vf_nr);
+               resp.data = RPRESET_TIMEOUT;
+               goto out;
+       }
+
+       dev_dbg(&GET_DEV(accel_dev),
+               "Ring pair reset for VF%d successfully\n", vf_nr);
+
+out:
+       return resp;
+}
+
 static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
                                struct pfvf_message msg, struct pfvf_message *resp)
 {
@@ -245,6 +294,9 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
        case ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ:
                *resp = handle_blkmsg_req(vf_info, msg);
                break;
+       case ADF_VF2PF_MSGTYPE_RP_RESET:
+               *resp = handle_rp_reset_req(accel_dev, vf_nr, msg);
+               break;
        default:
                dev_dbg(&GET_DEV(accel_dev),
                        "Unknown message from VF%d (type 0x%.4x, data: 0x%.4x)\n",
index 0e4b839..1015155 100644 (file)
@@ -310,6 +310,7 @@ static bool adf_handle_pf2vf_msg(struct adf_accel_dev *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);