common/qat: add PF to VF communication
authorArek Kusztal <arkadiuszx.kusztal@intel.com>
Mon, 28 Jun 2021 16:34:29 +0000 (17:34 +0100)
committerAkhil Goyal <gakhil@marvell.com>
Tue, 20 Jul 2021 08:32:05 +0000 (10:32 +0200)
Add communication between physical device and virtual function
in Intel QucikAssist Technology PMD.

Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
Acked-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Akhil Goyal <gakhil@marvell.com>
drivers/common/qat/meson.build
drivers/common/qat/qat_adf/adf_pf2vf_msg.h [new file with mode: 0644]
drivers/common/qat/qat_device.c
drivers/common/qat/qat_device.h
drivers/common/qat/qat_pf2vf.c [new file with mode: 0644]
drivers/common/qat/qat_pf2vf.h [new file with mode: 0644]

index 479a46f..053c219 100644 (file)
@@ -49,6 +49,7 @@ sources += files(
         'qat_qp.c',
         'qat_device.c',
         'qat_logs.c',
+        'qat_pf2vf.c',
 )
 includes += include_directories(
         'qat_adf',
diff --git a/drivers/common/qat/qat_adf/adf_pf2vf_msg.h b/drivers/common/qat/qat_adf/adf_pf2vf_msg.h
new file mode 100644 (file)
index 0000000..4029b1c
--- /dev/null
@@ -0,0 +1,154 @@
+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
+ * Copyright(c) 2021 Intel Corporation
+ */
+#ifndef ADF_PF2VF_MSG_H_
+#define ADF_PF2VF_MSG_H_
+
+/* VF/PF compatibility version. */
+/* ADF_PFVF_COMPATIBILITY_EXT_CAP: Support for extended capabilities */
+#define ADF_PFVF_COMPATIBILITY_CAPABILITIES    2
+/* ADF_PFVF_COMPATIBILITY_FAST_ACK: In-use pattern cleared by receiver */
+#define ADF_PFVF_COMPATIBILITY_FAST_ACK                3
+#define ADF_PFVF_COMPATIBILITY_RING_TO_SVC_MAP 4
+#define ADF_PFVF_COMPATIBILITY_VERSION         4       /* PF<->VF compat */
+
+#define ADF_PFVF_INT                               1
+#define ADF_PFVF_MSGORIGIN_SYSTEM              2
+#define ADF_PFVF_1X_MSGTYPE_SHIFT              2
+#define ADF_PFVF_1X_MSGTYPE_MASK               0xF
+#define ADF_PFVF_1X_MSGDATA_SHIFT              6
+#define ADF_PFVF_1X_MSGDATA_MASK               0x3FF
+#define ADF_PFVF_2X_MSGTYPE_SHIFT              2
+#define ADF_PFVF_2X_MSGTYPE_MASK               0x3F
+#define ADF_PFVF_2X_MSGDATA_SHIFT              8
+#define ADF_PFVF_2X_MSGDATA_MASK               0xFFFFFF
+
+#define ADF_PFVF_IN_USE                                0x6AC2
+#define ADF_PFVF_IN_USE_MASK                   0xFFFE
+#define ADF_PFVF_VF_MSG_SHIFT                  16
+
+/* PF->VF messages */
+#define ADF_PF2VF_MSGTYPE_RESTARTING           0x01
+#define ADF_PF2VF_MSGTYPE_VERSION_RESP         0x02
+#define ADF_PF2VF_MSGTYPE_BLOCK_RESP           0x03
+#define ADF_PF2VF_MSGTYPE_FATAL_ERROR          0x04
+/* Do not use messages which start from 0x10 to 1.x as 1.x only use
+ * 4 bits as message types. Hence they are only applicable to 2.0
+ */
+#define ADF_PF2VF_MSGTYPE_RP_RESET_RESP                0x10
+
+/* PF->VF Version Response - ADF_PF2VF_MSGTYPE_VERSION_RESP */
+#define ADF_PF2VF_VERSION_RESP_VERS_MASK       0xFF
+#define ADF_PF2VF_VERSION_RESP_VERS_SHIFT      0
+#define ADF_PF2VF_VERSION_RESP_RESULT_MASK     0x03
+#define ADF_PF2VF_VERSION_RESP_RESULT_SHIFT    8
+#define ADF_PF2VF_MINORVERSION_SHIFT           0
+#define ADF_PF2VF_MAJORVERSION_SHIFT           4
+#define ADF_PF2VF_VF_COMPATIBLE                        1
+#define ADF_PF2VF_VF_INCOMPATIBLE              2
+#define ADF_PF2VF_VF_COMPAT_UNKNOWN            3
+
+/* PF->VF Block Response Type - ADF_PF2VF_MSGTYPE_BLOCK_RESP */
+#define ADF_PF2VF_BLOCK_RESP_TYPE_DATA         0x0
+#define ADF_PF2VF_BLOCK_RESP_TYPE_CRC          0x1
+#define ADF_PF2VF_BLOCK_RESP_TYPE_ERROR                0x2
+#define ADF_PF2VF_BLOCK_RESP_TYPE_MASK         0x03
+#define ADF_PF2VF_BLOCK_RESP_TYPE_SHIFT                0
+#define ADF_PF2VF_BLOCK_RESP_DATA_MASK         0xFF
+#define ADF_PF2VF_BLOCK_RESP_DATA_SHIFT                2
+
+/*
+ * PF->VF Block Error Code - Returned in data field when the
+ * response type indicates an error
+ */
+#define ADF_PF2VF_INVALID_BLOCK_TYPE           0x0
+#define ADF_PF2VF_INVALID_BYTE_NUM_REQ         0x1
+#define ADF_PF2VF_PAYLOAD_TRUNCATED            0x2
+#define ADF_PF2VF_UNSPECIFIED_ERROR            0x3
+
+/* VF->PF messages */
+#define ADF_VF2PF_MSGTYPE_INIT                 0x3
+#define ADF_VF2PF_MSGTYPE_SHUTDOWN             0x4
+#define ADF_VF2PF_MSGTYPE_VERSION_REQ          0x5
+#define ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ       0x6
+#define ADF_VF2PF_MSGTYPE_GET_LARGE_BLOCK_REQ  0x7
+#define ADF_VF2PF_MSGTYPE_GET_MEDIUM_BLOCK_REQ 0x8
+#define ADF_VF2PF_MSGTYPE_GET_SMALL_BLOCK_REQ  0x9
+/* Do not use messages which start from 0x10 to 1.x as 1.x only use
+ * 4 bits as message types. Hence they are only applicable to 2.0
+ */
+#define ADF_VF2PF_MSGTYPE_RP_RESET             0x10
+
+/* VF->PF Block Request Type - ADF_VF2PF_MSGTYPE_GET_xxx_BLOCK_REQ  */
+#define ADF_VF2PF_MIN_SMALL_MESSAGE_TYPE       0
+#define ADF_VF2PF_MAX_SMALL_MESSAGE_TYPE \
+               (ADF_VF2PF_MIN_SMALL_MESSAGE_TYPE + 15)
+#define ADF_VF2PF_MIN_MEDIUM_MESSAGE_TYPE \
+               (ADF_VF2PF_MAX_SMALL_MESSAGE_TYPE + 1)
+#define ADF_VF2PF_MAX_MEDIUM_MESSAGE_TYPE \
+               (ADF_VF2PF_MIN_MEDIUM_MESSAGE_TYPE + 7)
+#define ADF_VF2PF_MIN_LARGE_MESSAGE_TYPE \
+               (ADF_VF2PF_MAX_MEDIUM_MESSAGE_TYPE + 1)
+#define ADF_VF2PF_MAX_LARGE_MESSAGE_TYPE \
+               (ADF_VF2PF_MIN_LARGE_MESSAGE_TYPE + 3)
+#define ADF_VF2PF_SMALL_PAYLOAD_SIZE           30
+#define ADF_VF2PF_MEDIUM_PAYLOAD_SIZE          62
+#define ADF_VF2PF_LARGE_PAYLOAD_SIZE           126
+
+#define ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT         0
+#define ADF_VF2PF_LARGE_BLOCK_REQ_TYPE_MASK    0x3
+#define ADF_VF2PF_MEDIUM_BLOCK_REQ_TYPE_MASK   0x7
+#define ADF_VF2PF_SMALL_BLOCK_REQ_TYPE_MASK    0xF
+
+#define ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_SHIFT   2
+#define ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_MASK    0x7F
+#define ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_SHIFT  3
+#define ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_MASK   0x3F
+#define ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_SHIFT   4
+#define ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_MASK    0x1F
+#define ADF_VF2PF_BLOCK_REQ_CRC_SHIFT          9
+
+/* PF-VF block message header bytes */
+#define ADF_VF2PF_BLOCK_VERSION_BYTE           0
+#define ADF_VF2PF_BLOCK_LEN_BYTE                1
+#define ADF_VF2PF_BLOCK_DATA                   2
+
+/* Block message types
+ *  0..15 - 32 byte message
+ * 16..23 - 64 byte message
+ * 24..27 - 128 byte message
+ * 2 - Get Capability Request message
+ */
+#define ADF_VF2PF_BLOCK_MSG_CAP_SUMMARY         0x2
+#define ADF_VF2PF_BLOCK_MSG_GET_RING_TO_SVC_REQ 0x3
+
+/* VF->PF Compatible Version Request - ADF_VF2PF_MSGTYPE_VERSION_REQ */
+#define ADF_VF2PF_COMPAT_VER_SHIFT             0
+#define ADF_VF2PF_COMPAT_VER_MASK              0xFF
+
+/* How long to wait for far side to acknowledge receipt */
+#define ADF_IOV_MSG_ACK_DELAY_US               5
+#define ADF_IOV_MSG_ACK_MAX_RETRY      (100 * 1000 / ADF_IOV_MSG_ACK_DELAY_US)
+/* If CSR is busy, how long to delay before retrying */
+#define ADF_IOV_MSG_RETRY_DELAY                        5
+#define ADF_IOV_MSG_MAX_RETRIES                        3
+/* How long to wait for a response from the other side */
+#define ADF_IOV_MSG_RESP_TIMEOUT               100
+/* How often to retry when there is no response */
+#define ADF_IOV_MSG_RESP_RETRIES               5
+
+#define ADF_IOV_RATELIMIT_INTERVAL             8
+#define ADF_IOV_RATELIMIT_BURST                        130
+/* PF VF message byte shift */
+#define ADF_PFVF_DATA_SHIFT                     8
+#define ADF_PFVF_DATA_MASK                      0xFF
+
+/* CRC Calculation */
+#define ADF_CRC8_INIT_VALUE 0xFF
+
+/* Per device register offsets */
+/* GEN 4 */
+#define ADF_4XXXIOV_PF2VM_OFFSET       0x1008
+#define ADF_4XXXIOV_VM2PF_OFFSET       0x100C
+
+#endif /* ADF_IOV_MSG_H */
index 932d711..5ee4411 100644 (file)
 #include "adf_transport_access_macros.h"
 #include "qat_sym_pmd.h"
 #include "qat_comp_pmd.h"
+#include "adf_pf2vf_msg.h"
+
+/* pv2vf data Gen 4*/
+struct qat_pf2vf_dev qat_pf2vf_gen4 = {
+       .pf2vf_offset = ADF_4XXXIOV_PF2VM_OFFSET,
+       .vf2pf_offset = ADF_4XXXIOV_VM2PF_OFFSET,
+       .pf2vf_type_shift = ADF_PFVF_2X_MSGTYPE_SHIFT,
+       .pf2vf_type_mask = ADF_PFVF_2X_MSGTYPE_MASK,
+       .pf2vf_data_shift = ADF_PFVF_2X_MSGDATA_SHIFT,
+       .pf2vf_data_mask = ADF_PFVF_2X_MSGDATA_MASK,
+};
 
 /* Hardware device information per generation */
 __extension__
@@ -33,7 +44,8 @@ struct qat_gen_hw_data qat_gen_config[] =  {
        [QAT_GEN4] = {
                .dev_gen = QAT_GEN4,
                .qp_hw_data = NULL,
-               .comp_num_im_bufs_required = QAT_NUM_INTERM_BUFS_GEN3
+               .comp_num_im_bufs_required = QAT_NUM_INTERM_BUFS_GEN3,
+               .pf2vf_dev = &qat_pf2vf_gen4
        },
 };
 
@@ -249,6 +261,14 @@ qat_pci_device_allocate(struct rte_pci_device *pci_dev,
                return NULL;
        }
 
+       if (qat_dev->qat_dev_gen == QAT_GEN4) {
+               qat_dev->misc_bar_io_addr = pci_dev->mem_resource[2].addr;
+               if (qat_dev->misc_bar_io_addr == NULL) {
+                       QAT_LOG(ERR, "QAT cannot get access to VF misc bar");
+                       return NULL;
+               }
+       }
+
        if (devargs && devargs->drv_str)
                qat_dev_parse_cmd(devargs->drv_str, qat_dev_cmd_param);
 
index f4fecc9..05e164b 100644 (file)
@@ -108,12 +108,24 @@ struct qat_pci_device {
        struct qat_qp_hw_data qp_gen4_data[QAT_GEN4_BUNDLE_NUM]
                [QAT_GEN4_QPS_PER_BUNDLE_NUM];
        /**< Data of ring configuration on gen4 */
+       void *misc_bar_io_addr;
+       /**< Address of misc bar */
 };
 
 struct qat_gen_hw_data {
        enum qat_device_gen dev_gen;
        const struct qat_qp_hw_data (*qp_hw_data)[ADF_MAX_QPS_ON_ANY_SERVICE];
        enum qat_comp_num_im_buffers comp_num_im_bufs_required;
+       struct qat_pf2vf_dev *pf2vf_dev;
+};
+
+struct qat_pf2vf_dev {
+       uint32_t pf2vf_offset;
+       uint32_t vf2pf_offset;
+       int pf2vf_type_shift;
+       uint32_t pf2vf_type_mask;
+       int pf2vf_data_shift;
+       uint32_t pf2vf_data_mask;
 };
 
 extern struct qat_gen_hw_data qat_gen_config[];
diff --git a/drivers/common/qat/qat_pf2vf.c b/drivers/common/qat/qat_pf2vf.c
new file mode 100644 (file)
index 0000000..6327311
--- /dev/null
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Intel Corporation
+ */
+
+#include "qat_pf2vf.h"
+#include "adf_pf2vf_msg.h"
+
+#include <rte_cycles.h>
+
+int qat_pf2vf_exch_msg(struct qat_pci_device *qat_dev,
+               struct qat_pf2vf_msg pf2vf_msg,
+               int len, uint8_t *ret)
+{
+       int i = 0;
+       struct qat_pf2vf_dev *qat_pf2vf =
+       qat_gen_config[qat_dev->qat_dev_gen].pf2vf_dev;
+       void *pmisc_bar_addr = qat_dev->misc_bar_io_addr;
+       uint32_t msg = 0, count = 0, val = 0;
+       uint32_t vf_csr_off = qat_pf2vf->vf2pf_offset;
+       uint32_t pf_csr_off = qat_pf2vf->pf2vf_offset;
+       int type_shift = qat_pf2vf->pf2vf_type_shift;
+       uint32_t type_mask = qat_pf2vf->pf2vf_type_mask;
+       int blck_hdr_shift = qat_pf2vf->pf2vf_data_shift;
+       int data_shift = blck_hdr_shift;
+
+       switch (pf2vf_msg.msg_type) {
+       case ADF_VF2PF_MSGTYPE_GET_SMALL_BLOCK_REQ:
+               data_shift += ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_SHIFT;
+               break;
+       case ADF_VF2PF_MSGTYPE_GET_MEDIUM_BLOCK_REQ:
+               data_shift += ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_SHIFT;
+               break;
+       case ADF_VF2PF_MSGTYPE_GET_LARGE_BLOCK_REQ:
+               data_shift += ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_SHIFT;
+               break;
+       }
+
+       if ((pf2vf_msg.msg_type & type_mask) != pf2vf_msg.msg_type) {
+               QAT_LOG(ERR, "PF2VF message type 0x%X out of range\n",
+                       pf2vf_msg.msg_type);
+               return -EINVAL;
+       }
+
+       for (; i < len; i++) {
+               count = 0;
+               if (len == 1) {
+                       msg = (pf2vf_msg.msg_type << type_shift) |
+                               (pf2vf_msg.msg_data << (data_shift));
+               } else
+                       msg = (pf2vf_msg.msg_type << type_shift) |
+                               ((pf2vf_msg.msg_data + i) << (data_shift));
+               if (pf2vf_msg.block_hdr > 0)
+                       msg |= pf2vf_msg.block_hdr << blck_hdr_shift;
+               msg |= ADF_PFVF_INT | ADF_PFVF_MSGORIGIN_SYSTEM;
+
+               ADF_CSR_WR(pmisc_bar_addr, vf_csr_off, msg);
+               int us = 0;
+               /*
+                * Wait for confirmation from remote that it received
+                * the message
+                */
+               do {
+                       rte_delay_us_sleep(5);
+                       us += 5;
+                       val = ADF_CSR_RD(pmisc_bar_addr, vf_csr_off);
+               } while ((val & ADF_PFVF_INT) &&
+                       (++count < ADF_IOV_MSG_ACK_MAX_RETRY));
+
+               if (val & ADF_PFVF_INT) {
+                       QAT_LOG(ERR, "ACK not received from remote\n");
+                       return -EIO;
+               }
+
+               uint32_t pf_val = ADF_CSR_RD(pmisc_bar_addr, pf_csr_off);
+
+               *(ret + i) = (uint8_t)(pf_val >> (pf2vf_msg.block_hdr > 0 ?
+                               10 : 8) & 0xff);
+       }
+       return 0;
+}
diff --git a/drivers/common/qat/qat_pf2vf.h b/drivers/common/qat/qat_pf2vf.h
new file mode 100644 (file)
index 0000000..df59277
--- /dev/null
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Intel Corporation
+ */
+
+#include "qat_device.h"
+
+#ifndef QAT_PF2VF_H_
+#define QAT_PF2VF_H_
+
+struct qat_pf2vf_msg {
+       uint32_t msg_data;
+       int block_hdr;
+       uint16_t msg_type;
+};
+
+int qat_pf2vf_exch_msg(struct qat_pci_device *qat_dev,
+       struct qat_pf2vf_msg pf2vf_msg, int len, uint8_t *ret);
+
+#endif