From patchwork Mon Mar 15 13:58:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 89125 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id F371FA054F; Mon, 15 Mar 2021 14:59:59 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 03E16242671; Mon, 15 Mar 2021 14:59:56 +0100 (CET) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 6473124266F for ; Mon, 15 Mar 2021 14:59:55 +0100 (CET) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 360CA7F5D5; Mon, 15 Mar 2021 16:59:55 +0300 (MSK) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on shelob.oktetlabs.ru X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=ALL_TRUSTED, DKIM_ADSP_DISCARD, URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from aros.oktetlabs.ru (aros.oktetlabs.ru [192.168.38.17]) by shelob.oktetlabs.ru (Postfix) with ESMTP id B55C77F53D; Mon, 15 Mar 2021 16:59:47 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru B55C77F53D Authentication-Results: shelob.oktetlabs.ru/B55C77F53D; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: Ferruh Yigit Cc: dev@dpdk.org, Vijay Srivastava Date: Mon, 15 Mar 2021 16:58:17 +0300 Message-Id: <20210315135823.605774-3-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210315135823.605774-1-andrew.rybchenko@oktetlabs.ru> References: <20210311110325.3291203-1-andrew.rybchenko@oktetlabs.ru> <20210315135823.605774-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 2/8] common/sfc_efx/base: add API to get VirtQ doorbell offset X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Vijay Srivastava Add an API to query the virtqueue doorbell offset in the BAR for a VI. For vDPA, the virtio net driver notifies the device directly by writing doorbell. This API would be invoked from vDPA client driver. Signed-off-by: Vijay Srivastava Signed-off-by: Andrew Rybchenko --- drivers/common/sfc_efx/base/efx.h | 12 +++ drivers/common/sfc_efx/base/efx_impl.h | 2 + drivers/common/sfc_efx/base/efx_virtio.c | 41 ++++++++++ drivers/common/sfc_efx/base/rhead_impl.h | 6 ++ drivers/common/sfc_efx/base/rhead_virtio.c | 93 ++++++++++++++++++++++ 5 files changed, 154 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index c2c73bd382..d4b7d7f47e 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -4475,6 +4475,18 @@ extern void efx_virtio_qdestroy( __in efx_virtio_vq_t *evvp); +/* + * Get the offset in the BAR of the doorbells for a VI. + * net device : doorbell offset of RX & TX queues + * block device : request doorbell offset in the BAR. + * For further details refer section of 4 of SF-119689 + */ +LIBEFX_API +extern __checkReturn efx_rc_t +efx_virtio_get_doorbell_offset( + __in efx_virtio_vq_t *evvp, + __out uint32_t *offsetp); + #endif /* EFSYS_OPT_VIRTIO */ #ifdef __cplusplus diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h index f27d9fa82c..d6742f4a8c 100644 --- a/drivers/common/sfc_efx/base/efx_impl.h +++ b/drivers/common/sfc_efx/base/efx_impl.h @@ -316,6 +316,8 @@ typedef struct efx_virtio_ops_s { efx_virtio_vq_dyncfg_t *); efx_rc_t (*evo_virtio_qstop)(efx_virtio_vq_t *, efx_virtio_vq_dyncfg_t *); + efx_rc_t (*evo_get_doorbell_offset)(efx_virtio_vq_t *, + uint32_t *); } efx_virtio_ops_t; #endif /* EFSYS_OPT_VIRTIO */ diff --git a/drivers/common/sfc_efx/base/efx_virtio.c b/drivers/common/sfc_efx/base/efx_virtio.c index 1b7b01556e..de998fcad9 100644 --- a/drivers/common/sfc_efx/base/efx_virtio.c +++ b/drivers/common/sfc_efx/base/efx_virtio.c @@ -12,6 +12,7 @@ static const efx_virtio_ops_t __efx_virtio_rhead_ops = { rhead_virtio_qstart, /* evo_virtio_qstart */ rhead_virtio_qstop, /* evo_virtio_qstop */ + rhead_virtio_get_doorbell_offset, /* evo_get_doorbell_offset */ }; #endif /* EFSYS_OPT_RIVERHEAD */ @@ -213,4 +214,44 @@ efx_virtio_qdestroy( } } + __checkReturn efx_rc_t +efx_virtio_get_doorbell_offset( + __in efx_virtio_vq_t *evvp, + __out uint32_t *offsetp) +{ + efx_nic_t *enp; + const efx_virtio_ops_t *evop; + efx_rc_t rc; + + if ((evvp == NULL) || (offsetp == NULL)) { + rc = EINVAL; + goto fail1; + } + + enp = evvp->evv_enp; + evop = enp->en_evop; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_VIRTIO); + + if (evop == NULL) { + rc = ENOTSUP; + goto fail2; + } + + if ((rc = evop->evo_get_doorbell_offset(evvp, offsetp)) != 0) + goto fail3; + + return (0); + +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + #endif /* EFSYS_OPT_VIRTIO */ diff --git a/drivers/common/sfc_efx/base/rhead_impl.h b/drivers/common/sfc_efx/base/rhead_impl.h index a15ac52a58..4304f63f4c 100644 --- a/drivers/common/sfc_efx/base/rhead_impl.h +++ b/drivers/common/sfc_efx/base/rhead_impl.h @@ -492,6 +492,12 @@ rhead_virtio_qstop( __in efx_virtio_vq_t *evvp, __out_opt efx_virtio_vq_dyncfg_t *evvdp); +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +rhead_virtio_get_doorbell_offset( + __in efx_virtio_vq_t *evvp, + __out uint32_t *offsetp); + #endif /* EFSYS_OPT_VIRTIO */ #ifdef __cplusplus diff --git a/drivers/common/sfc_efx/base/rhead_virtio.c b/drivers/common/sfc_efx/base/rhead_virtio.c index d1719f834e..147460c95c 100644 --- a/drivers/common/sfc_efx/base/rhead_virtio.c +++ b/drivers/common/sfc_efx/base/rhead_virtio.c @@ -187,4 +187,97 @@ rhead_virtio_qstop( return (rc); } + __checkReturn efx_rc_t +rhead_virtio_get_doorbell_offset( + __in efx_virtio_vq_t *evvp, + __out uint32_t *offsetp) +{ + efx_nic_t *enp = evvp->evv_enp; + efx_mcdi_req_t req; + uint32_t type; + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_LEN, + MC_CMD_VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_LEN); + efx_rc_t rc; + + req.emr_cmd = MC_CMD_VIRTIO_GET_DOORBELL_OFFSET; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_VIRTIO_GET_DOORBELL_OFFSET_REQ_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_LEN; + + switch (evvp->evv_type) { + case EFX_VIRTIO_VQ_TYPE_NET_RXQ: + case EFX_VIRTIO_VQ_TYPE_NET_TXQ: + type = MC_CMD_VIRTIO_GET_FEATURES_IN_NET; + break; + case EFX_VIRTIO_VQ_TYPE_BLOCK: + type = MC_CMD_VIRTIO_GET_FEATURES_IN_BLOCK; + break; + default: + rc = EINVAL; + goto fail1; + } + + MCDI_IN_SET_BYTE(req, VIRTIO_GET_DOORBELL_OFFSET_REQ_DEVICE_ID, + type); + MCDI_IN_SET_WORD(req, VIRTIO_GET_DOORBELL_OFFSET_REQ_TARGET_VF, + evvp->evv_target_vf); + MCDI_IN_SET_DWORD(req, VIRTIO_GET_DOORBELL_OFFSET_REQ_INSTANCE, + evvp->evv_vi_index); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail2; + } + + switch (type) { + case MC_CMD_VIRTIO_GET_FEATURES_IN_NET: + if (req.emr_out_length_used < + MC_CMD_VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_LEN) { + rc = EMSGSIZE; + goto fail3; + } + + if (evvp->evv_type == EFX_VIRTIO_VQ_TYPE_NET_RXQ) { + *offsetp = MCDI_OUT_DWORD(req, + VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_RX_DBL_OFFSET); + } else if (evvp->evv_type == EFX_VIRTIO_VQ_TYPE_NET_TXQ) { + *offsetp = MCDI_OUT_DWORD(req, + VIRTIO_GET_NET_DOORBELL_OFFSET_RESP_TX_DBL_OFFSET); + } + break; + case MC_CMD_VIRTIO_GET_FEATURES_IN_BLOCK: + if (req.emr_out_length_used < + MC_CMD_VIRTIO_GET_BLOCK_DOORBELL_OFFSET_RESP_LEN) { + rc = EMSGSIZE; + goto fail4; + } + + *offsetp = MCDI_OUT_DWORD(req, + VIRTIO_GET_BLOCK_DOORBELL_OFFSET_RESP_DBL_OFFSET); + break; + default: + EFSYS_ASSERT(0); + rc = EINVAL; + goto fail5; + } + + return (0); + +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + #endif /* EFSYS_OPT_RIVERHEAD && EFSYS_OPT_VIRTIO */