From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id A9080A04B1; Thu, 24 Sep 2020 14:17:11 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A01C51DE65; Thu, 24 Sep 2020 14:13:41 +0200 (CEST) Received: from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com [148.163.129.52]) by dpdk.org (Postfix) with ESMTP id 78C3A1DE0D for ; Thu, 24 Sep 2020 14:12:58 +0200 (CEST) Received: from mx1-us1.ppe-hosted.com (unknown [10.7.65.60]) by dispatch1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTP id 05F8D60080 for ; Thu, 24 Sep 2020 12:12:58 +0000 (UTC) Received: from us4-mdac16-48.ut7.mdlocal (unknown [10.7.66.15]) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTP id 04E3D2009A for ; Thu, 24 Sep 2020 12:12:58 +0000 (UTC) X-Virus-Scanned: Proofpoint Essentials engine Received: from mx1-us1.ppe-hosted.com (unknown [10.7.65.174]) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id 6FBFB1C0059 for ; Thu, 24 Sep 2020 12:12:57 +0000 (UTC) Received: from webmail.solarflare.com (uk.solarflare.com [193.34.186.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id 26C601C0064 for ; Thu, 24 Sep 2020 12:12:57 +0000 (UTC) Received: from ukex01.SolarFlarecom.com (10.17.10.4) by ukex01.SolarFlarecom.com (10.17.10.4) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 24 Sep 2020 13:12:47 +0100 Received: from opal.uk.solarflarecom.com (10.17.10.1) by ukex01.SolarFlarecom.com (10.17.10.4) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 24 Sep 2020 13:12:46 +0100 Received: from ukv-loginhost.uk.solarflarecom.com (ukv-loginhost.uk.solarflarecom.com [10.17.10.39]) by opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id 08OCCkxM025951 for ; Thu, 24 Sep 2020 13:12:46 +0100 Received: from ukv-loginhost.uk.solarflarecom.com (localhost [127.0.0.1]) by ukv-loginhost.uk.solarflarecom.com (Postfix) with ESMTP id CF88E1613AB for ; Thu, 24 Sep 2020 13:12:46 +0100 (BST) From: Andrew Rybchenko To: Date: Thu, 24 Sep 2020 13:11:57 +0100 Message-ID: <1600949555-28043-23-git-send-email-arybchenko@solarflare.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1600949555-28043-1-git-send-email-arybchenko@solarflare.com> References: <1600764594-14752-1-git-send-email-arybchenko@solarflare.com> <1600949555-28043-1-git-send-email-arybchenko@solarflare.com> MIME-Version: 1.0 Content-Type: text/plain X-TM-AS-Product-Ver: SMEX-12.5.0.1300-8.6.1012-25674.003 X-TM-AS-Result: No-9.884500-8.000000-10 X-TMASE-MatchedRID: mxPm4/rFDPQ40FQTvb+HBi8s/ULwMh463V4UShoTXadtw+n+iKWyyEeO 32NJTaee5KHYnTLjqLl8d8ZLFoVsqNpsFVyqUNwXbBMSu4v05tM/pOSL72dTfwdkFovAReUoLPJ tWpbJjY34tChzbbBKvF+bnK6VdutFKerAqZTShjM+NrfDUTEXxPG6GRFYrbYYQW6eCaGxKwKOJ3 eQSEJmKs4M0wnt7LoDssHw+J0qGMkop8ZOkjgdUXL1TJ3FgoWZ1JP9NndNOkWEWB8iuyGqCfLwF Hrs2PUr1OYlw6XumHi35qHKWj7a5i7J3GddaS//HC7hAz/oKnJcaNB/u5yQqx53XUX0iwoUwv9A ibJlKnD5st7EvPbtNXqZ7YfJvYp/z5ey3IkHnU7bbgI4AuYpVzQAl7cHmp8GwzktBYXAF0rbWkH MATUzun2dcFgFzv71EtRm78gcrDGSsyjfsjrH/os/uwyVPuwc9/x+2nQH35JXiLrvhpKLfJ8eTN fYszv08a9FfTFXt2nHEfUJ5TpSVhID8IiUPlK/ngIgpj8eDcAZ1CdBJOsoY8RB0bsfrpPIqxB32 o9eGck2pvMU9bFHY2Qz0gWJZun4JUAZABQE7mkYTBdVS3PYE7BLMjppLAcuVlxr1FJij9s= X-TM-AS-User-Approved-Sender: Yes X-TM-AS-User-Blocked-Sender: No X-TMASE-Result: 10--9.884500-8.000000 X-TMASE-Version: SMEX-12.5.0.1300-8.6.1012-25674.003 X-MDID: 1600949577-Lp3VMEKGOBhd Subject: [dpdk-dev] [PATCH v3 22/60] common/sfc_efx/base: merge versions of init EvQ wrappers X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 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" The decision on which version of the INIT_EVQ command to use may be done inside the function itself. Caller should just provide enough information sufficient in both cases. It avoids code duplication and simplifies maintenance. If v2 is not supported, keep decision about low-latency hint outside the MCDI helper function since it will differ on Riverhead (there is no EVB yet, but still want merging for better throughput). Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/ef10_ev.c | 54 +++--- drivers/common/sfc_efx/base/efx_impl.h | 11 -- drivers/common/sfc_efx/base/efx_mcdi.c | 228 ++++++++----------------- 3 files changed, 95 insertions(+), 198 deletions(-) diff --git a/drivers/common/sfc_efx/base/ef10_ev.c b/drivers/common/sfc_efx/base/ef10_ev.c index 18f19e816d..e2b5c62d5d 100644 --- a/drivers/common/sfc_efx/base/ef10_ev.c +++ b/drivers/common/sfc_efx/base/ef10_ev.c @@ -130,6 +130,7 @@ ef10_ev_qcreate( efx_nic_cfg_t *encp = &(enp->en_nic_cfg); uint32_t irq; efx_rc_t rc; + boolean_t low_latency; _NOTE(ARGUNUSED(id)) /* buftbl id managed by MC */ @@ -175,42 +176,29 @@ ef10_ev_qcreate( * created. See bug58606. */ - if (encp->enc_init_evq_v2_supported) { - /* - * On Medford the low latency license is required to enable RX - * and event cut through and to disable RX batching. If event - * queue type in flags is auto, we let the firmware decide the - * settings to use. If the adapter has a low latency license, - * it will choose the best settings for low latency, otherwise - * it will choose the best settings for throughput. - */ - rc = efx_mcdi_init_evq_v2(enp, index, esmp, ndescs, irq, us, - flags); - if (rc != 0) - goto fail2; - } else { - /* - * On Huntington we need to specify the settings to use. - * If event queue type in flags is auto, we favour throughput - * if the adapter is running virtualization supporting firmware - * (i.e. the full featured firmware variant) - * and latency otherwise. The Ethernet Virtual Bridging - * capability is used to make this decision. (Note though that - * the low latency firmware variant is also best for - * throughput and corresponding type should be specified - * to choose it.) - */ - boolean_t low_latency = encp->enc_datapath_cap_evb ? 0 : 1; - rc = efx_mcdi_init_evq(enp, index, esmp, ndescs, irq, us, flags, - low_latency); - if (rc != 0) - goto fail3; - } + /* + * On Huntington we need to specify the settings to use. + * If event queue type in flags is auto, we favour throughput + * if the adapter is running virtualization supporting firmware + * (i.e. the full featured firmware variant) + * and latency otherwise. The Ethernet Virtual Bridging + * capability is used to make this decision. (Note though that + * the low latency firmware variant is also best for + * throughput and corresponding type should be specified + * to choose it.) + * + * If FW supports EvQ types (e.g. on Medford and Medford2) the + * type which is specified in flags is passed to FW to make the + * decision and low_latency hint is ignored. + */ + low_latency = encp->enc_datapath_cap_evb ? 0 : 1; + rc = efx_mcdi_init_evq(enp, index, esmp, ndescs, irq, us, flags, + low_latency); + if (rc != 0) + goto fail2; return (0); -fail3: - EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h index bf1cfc49ca..47e4dcb01f 100644 --- a/drivers/common/sfc_efx/base/efx_impl.h +++ b/drivers/common/sfc_efx/base/efx_impl.h @@ -1422,17 +1422,6 @@ efx_mcdi_init_evq( __in uint32_t flags, __in boolean_t low_latency); -LIBEFX_INTERNAL -extern __checkReturn efx_rc_t -efx_mcdi_init_evq_v2( - __in efx_nic_t *enp, - __in unsigned int instance, - __in efsys_mem_t *esmp, - __in size_t nevs, - __in uint32_t irq, - __in uint32_t us, - __in uint32_t flags); - LIBEFX_INTERNAL extern __checkReturn efx_rc_t efx_mcdi_fini_evq( diff --git a/drivers/common/sfc_efx/base/efx_mcdi.c b/drivers/common/sfc_efx/base/efx_mcdi.c index 50d723ecb4..69d2327839 100644 --- a/drivers/common/sfc_efx/base/efx_mcdi.c +++ b/drivers/common/sfc_efx/base/efx_mcdi.c @@ -2456,146 +2456,14 @@ efx_mcdi_init_evq( __in uint32_t flags, __in boolean_t low_latency) { + const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); efx_mcdi_req_t req; EFX_MCDI_DECLARE_BUF(payload, MC_CMD_INIT_EVQ_V2_IN_LEN(EF10_EVQ_MAXNBUFS), MC_CMD_INIT_EVQ_V2_OUT_LEN); - efx_qword_t *dma_addr; - uint64_t addr; - int npages; - int i; boolean_t interrupting; int ev_cut_through; - efx_rc_t rc; - - npages = efx_evq_nbufs(enp, nevs); - if (npages > EF10_EVQ_MAXNBUFS) { - rc = EINVAL; - goto fail1; - } - - req.emr_cmd = MC_CMD_INIT_EVQ; - req.emr_in_buf = payload; - req.emr_in_length = MC_CMD_INIT_EVQ_V2_IN_LEN(npages); - req.emr_out_buf = payload; - req.emr_out_length = MC_CMD_INIT_EVQ_V2_OUT_LEN; - - MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_SIZE, nevs); - MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_INSTANCE, instance); - MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_IRQ_NUM, irq); - - interrupting = ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) == - EFX_EVQ_FLAGS_NOTIFY_INTERRUPT); - - /* - * On Huntington RX and TX event batching can only be requested together - * (even if the datapath firmware doesn't actually support RX - * batching). If event cut through is enabled no RX batching will occur. - * - * So always enable RX and TX event batching, and enable event cut - * through if we want low latency operation. - */ - switch (flags & EFX_EVQ_FLAGS_TYPE_MASK) { - case EFX_EVQ_FLAGS_TYPE_AUTO: - ev_cut_through = low_latency ? 1 : 0; - break; - case EFX_EVQ_FLAGS_TYPE_THROUGHPUT: - ev_cut_through = 0; - break; - case EFX_EVQ_FLAGS_TYPE_LOW_LATENCY: - ev_cut_through = 1; - break; - default: - rc = EINVAL; - goto fail2; - } - MCDI_IN_POPULATE_DWORD_6(req, INIT_EVQ_V2_IN_FLAGS, - INIT_EVQ_V2_IN_FLAG_INTERRUPTING, interrupting, - INIT_EVQ_V2_IN_FLAG_RPTR_DOS, 0, - INIT_EVQ_V2_IN_FLAG_INT_ARMD, 0, - INIT_EVQ_V2_IN_FLAG_CUT_THRU, ev_cut_through, - INIT_EVQ_V2_IN_FLAG_RX_MERGE, 1, - INIT_EVQ_V2_IN_FLAG_TX_MERGE, 1); - - /* If the value is zero then disable the timer */ - if (us == 0) { - MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_MODE, - MC_CMD_INIT_EVQ_V2_IN_TMR_MODE_DIS); - MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_LOAD, 0); - MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_RELOAD, 0); - } else { - unsigned int ticks; - - if ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0) - goto fail3; - - MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_MODE, - MC_CMD_INIT_EVQ_V2_IN_TMR_INT_HLDOFF); - MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_LOAD, ticks); - MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_TMR_RELOAD, ticks); - } - - MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_COUNT_MODE, - MC_CMD_INIT_EVQ_V2_IN_COUNT_MODE_DIS); - MCDI_IN_SET_DWORD(req, INIT_EVQ_V2_IN_COUNT_THRSHLD, 0); - - dma_addr = MCDI_IN2(req, efx_qword_t, INIT_EVQ_V2_IN_DMA_ADDR); - addr = EFSYS_MEM_ADDR(esmp); - - for (i = 0; i < npages; i++) { - EFX_POPULATE_QWORD_2(*dma_addr, - EFX_DWORD_1, (uint32_t)(addr >> 32), - EFX_DWORD_0, (uint32_t)(addr & 0xffffffff)); - - dma_addr++; - addr += EFX_BUF_SIZE; - } - - efx_mcdi_execute(enp, &req); - - if (req.emr_rc != 0) { - rc = req.emr_rc; - goto fail4; - } - - if (req.emr_out_length_used < MC_CMD_INIT_EVQ_OUT_LEN) { - rc = EMSGSIZE; - goto fail5; - } - - /* NOTE: ignore the returned IRQ param as firmware does not set it. */ - - 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); -} - - __checkReturn efx_rc_t -efx_mcdi_init_evq_v2( - __in efx_nic_t *enp, - __in unsigned int instance, - __in efsys_mem_t *esmp, - __in size_t nevs, - __in uint32_t irq, - __in uint32_t us, - __in uint32_t flags) -{ - efx_mcdi_req_t req; - EFX_MCDI_DECLARE_BUF(payload, - MC_CMD_INIT_EVQ_V2_IN_LEN(EF10_EVQ_MAXNBUFS), - MC_CMD_INIT_EVQ_V2_OUT_LEN); - boolean_t interrupting; + int ev_merge; unsigned int evq_type; efx_qword_t *dma_addr; uint64_t addr; @@ -2622,24 +2490,68 @@ efx_mcdi_init_evq_v2( interrupting = ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) == EFX_EVQ_FLAGS_NOTIFY_INTERRUPT); - switch (flags & EFX_EVQ_FLAGS_TYPE_MASK) { - case EFX_EVQ_FLAGS_TYPE_AUTO: - evq_type = MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_AUTO; - break; - case EFX_EVQ_FLAGS_TYPE_THROUGHPUT: - evq_type = MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_THROUGHPUT; - break; - case EFX_EVQ_FLAGS_TYPE_LOW_LATENCY: - evq_type = MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_LOW_LATENCY; - break; - default: - rc = EINVAL; - goto fail2; + if (encp->enc_init_evq_v2_supported) { + /* + * On Medford the low latency license is required to enable RX + * and event cut through and to disable RX batching. If event + * queue type in flags is auto, we let the firmware decide the + * settings to use. If the adapter has a low latency license, + * it will choose the best settings for low latency, otherwise + * it will choose the best settings for throughput. + */ + switch (flags & EFX_EVQ_FLAGS_TYPE_MASK) { + case EFX_EVQ_FLAGS_TYPE_AUTO: + evq_type = MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_AUTO; + break; + case EFX_EVQ_FLAGS_TYPE_THROUGHPUT: + evq_type = MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_THROUGHPUT; + break; + case EFX_EVQ_FLAGS_TYPE_LOW_LATENCY: + evq_type = MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_LOW_LATENCY; + break; + default: + rc = EINVAL; + goto fail2; + } + /* EvQ type controls merging, no manual settings */ + ev_merge = 0; + ev_cut_through = 0; + } else { + /* EvQ types other than manual are not supported */ + evq_type = MC_CMD_INIT_EVQ_V2_IN_FLAG_TYPE_MANUAL; + /* + * On Huntington RX and TX event batching can only be requested + * together (even if the datapath firmware doesn't actually + * support RX batching). If event cut through is enabled no RX + * batching will occur. + * + * So always enable RX and TX event batching, and enable event + * cut through if we want low latency operation. + */ + ev_merge = 1; + switch (flags & EFX_EVQ_FLAGS_TYPE_MASK) { + case EFX_EVQ_FLAGS_TYPE_AUTO: + ev_cut_through = low_latency ? 1 : 0; + break; + case EFX_EVQ_FLAGS_TYPE_THROUGHPUT: + ev_cut_through = 0; + break; + case EFX_EVQ_FLAGS_TYPE_LOW_LATENCY: + ev_cut_through = 1; + break; + default: + rc = EINVAL; + goto fail2; + } } - MCDI_IN_POPULATE_DWORD_4(req, INIT_EVQ_V2_IN_FLAGS, + + MCDI_IN_POPULATE_DWORD_7(req, INIT_EVQ_V2_IN_FLAGS, INIT_EVQ_V2_IN_FLAG_INTERRUPTING, interrupting, INIT_EVQ_V2_IN_FLAG_RPTR_DOS, 0, INIT_EVQ_V2_IN_FLAG_INT_ARMD, 0, + INIT_EVQ_V2_IN_FLAG_CUT_THRU, ev_cut_through, + INIT_EVQ_V2_IN_FLAG_RX_MERGE, ev_merge, + INIT_EVQ_V2_IN_FLAG_TX_MERGE, ev_merge, INIT_EVQ_V2_IN_FLAG_TYPE, evq_type); /* If the value is zero then disable the timer */ @@ -2683,18 +2595,26 @@ efx_mcdi_init_evq_v2( goto fail4; } - if (req.emr_out_length_used < MC_CMD_INIT_EVQ_V2_OUT_LEN) { - rc = EMSGSIZE; - goto fail5; + if (encp->enc_init_evq_v2_supported) { + if (req.emr_out_length_used < MC_CMD_INIT_EVQ_V2_OUT_LEN) { + rc = EMSGSIZE; + goto fail5; + } + EFSYS_PROBE1(mcdi_evq_flags, uint32_t, + MCDI_OUT_DWORD(req, INIT_EVQ_V2_OUT_FLAGS)); + } else { + if (req.emr_out_length_used < MC_CMD_INIT_EVQ_OUT_LEN) { + rc = EMSGSIZE; + goto fail6; + } } /* NOTE: ignore the returned IRQ param as firmware does not set it. */ - EFSYS_PROBE1(mcdi_evq_flags, uint32_t, - MCDI_OUT_DWORD(req, INIT_EVQ_V2_OUT_FLAGS)); - return (0); +fail6: + EFSYS_PROBE(fail6); fail5: EFSYS_PROBE(fail5); fail4: -- 2.17.1