From patchwork Fri Aug 27 06:56:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97419 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 ACE28A0C43; Fri, 27 Aug 2021 08:57:46 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B2B1C411D3; Fri, 27 Aug 2021 08:57:42 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id EAD65410E9 for ; Fri, 27 Aug 2021 08:57:40 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id AD35A7F6FC; Fri, 27 Aug 2021 09:57:40 +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=1.6 required=5.0 tests=ALL_TRUSTED, DKIM_ADSP_DISCARD, UPPERCASE_50_75,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 C70417F6C9 for ; Fri, 27 Aug 2021 09:57:32 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru C70417F6C9 Authentication-Results: shelob.oktetlabs.ru/C70417F6C9; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Date: Fri, 27 Aug 2021 09:56:40 +0300 Message-Id: <20210827065717.1838258-2-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 01/38] common/sfc_efx/base: update MCDI headers 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" Pickup new FW interface definitions. Signed-off-by: Andrew Rybchenko --- drivers/common/sfc_efx/base/efx_regs_mcdi.h | 1211 ++++++++++++++++++- 1 file changed, 1176 insertions(+), 35 deletions(-) diff --git a/drivers/common/sfc_efx/base/efx_regs_mcdi.h b/drivers/common/sfc_efx/base/efx_regs_mcdi.h index a3c9f076ec..2daf825a36 100644 --- a/drivers/common/sfc_efx/base/efx_regs_mcdi.h +++ b/drivers/common/sfc_efx/base/efx_regs_mcdi.h @@ -492,6 +492,24 @@ */ #define MAE_FIELD_SUPPORTED_MATCH_MASK 0x5 +/* MAE_CT_VNI_MODE enum: Controls the layout of the VNI input to the conntrack + * lookup. (Values are not arbitrary - constrained by table access ABI.) + */ +/* enum: The VNI input to the conntrack lookup will be zero. */ +#define MAE_CT_VNI_MODE_ZERO 0x0 +/* enum: The VNI input to the conntrack lookup will be the VNI (VXLAN/Geneve) + * or VSID (NVGRE) field from the packet. + */ +#define MAE_CT_VNI_MODE_VNI 0x1 +/* enum: The VNI input to the conntrack lookup will be the VLAN ID from the + * outermost VLAN tag (in bottom 12 bits; top 12 bits zero). + */ +#define MAE_CT_VNI_MODE_1VLAN 0x2 +/* enum: The VNI input to the conntrack lookup will be the VLAN IDs from both + * VLAN tags (outermost in bottom 12 bits, innermost in top 12 bits). + */ +#define MAE_CT_VNI_MODE_2VLAN 0x3 + /* MAE_FIELD enum: NB: this enum shares namespace with the support status enum. */ /* enum: Source mport upon entering the MAE. */ @@ -617,7 +635,8 @@ /* MAE_MCDI_ENCAP_TYPE enum: Encapsulation type. Defines how the payload will * be parsed to an inner frame. Other values are reserved. Unknown values - * should be treated same as NONE. + * should be treated same as NONE. (Values are not arbitrary - constrained by + * table access ABI.) */ #define MAE_MCDI_ENCAP_TYPE_NONE 0x0 /* enum */ /* enum: Don't assume enum aligns with support bitmask... */ @@ -634,6 +653,18 @@ /* enum: Selects the virtual NIC plugged into the MAE switch */ #define MAE_MPORT_END_VNIC 0x2 +/* MAE_COUNTER_TYPE enum: The datapath maintains several sets of counters, each + * being associated with a different table. Note that the same counter ID may + * be allocated by different counter blocks, so e.g. AR counter 42 is different + * from CT counter 42. Generation counts are also type-specific. This value is + * also present in the header of streaming counter packets, in the IDENTIFIER + * field (see packetiser packet format definitions). + */ +/* enum: Action Rule counters - can be referenced in AR response. */ +#define MAE_COUNTER_TYPE_AR 0x0 +/* enum: Conntrack counters - can be referenced in CT response. */ +#define MAE_COUNTER_TYPE_CT 0x1 + /* MCDI_EVENT structuredef: The structure of an MCDI_EVENT on Siena/EF10/EF100 * platforms */ @@ -4547,6 +4578,8 @@ #define MC_CMD_MEDIA_BASE_T 0x6 /* enum: QSFP+. */ #define MC_CMD_MEDIA_QSFP_PLUS 0x7 +/* enum: DSFP. */ +#define MC_CMD_MEDIA_DSFP 0x8 #define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48 #define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_LEN 4 /* enum: Native clause 22 */ @@ -7823,11 +7856,16 @@ /***********************************/ /* MC_CMD_GET_PHY_MEDIA_INFO * Read media-specific data from PHY (e.g. SFP/SFP+ module ID information for - * SFP+ PHYs). The 'media type' can be found via GET_PHY_CFG - * (GET_PHY_CFG_OUT_MEDIA_TYPE); the valid 'page number' input values, and the - * output data, are interpreted on a per-type basis. For SFP+: PAGE=0 or 1 + * SFP+ PHYs). The "media type" can be found via GET_PHY_CFG + * (GET_PHY_CFG_OUT_MEDIA_TYPE); the valid "page number" input values, and the + * output data, are interpreted on a per-type basis. For SFP+, PAGE=0 or 1 * returns a 128-byte block read from module I2C address 0xA0 offset 0 or 0x80. - * Anything else: currently undefined. Locks required: None. Return code: 0. + * For QSFP, PAGE=-1 is the lower (unbanked) page. PAGE=2 is the EEPROM and + * PAGE=3 is the module limits. For DSFP, module addressing requires a + * "BANK:PAGE". Not every bank has the same number of pages. See the Common + * Management Interface Specification (CMIS) for further details. A BANK:PAGE + * of "0xffff:0xffff" retrieves the lower (unbanked) page. Locks required - + * None. Return code - 0. */ #define MC_CMD_GET_PHY_MEDIA_INFO 0x4b #define MC_CMD_GET_PHY_MEDIA_INFO_MSGSET 0x4b @@ -7839,6 +7877,12 @@ #define MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN 4 #define MC_CMD_GET_PHY_MEDIA_INFO_IN_PAGE_OFST 0 #define MC_CMD_GET_PHY_MEDIA_INFO_IN_PAGE_LEN 4 +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_DSFP_PAGE_OFST 0 +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_DSFP_PAGE_LBN 0 +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_DSFP_PAGE_WIDTH 16 +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_DSFP_BANK_OFST 0 +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_DSFP_BANK_LBN 16 +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_DSFP_BANK_WIDTH 16 /* MC_CMD_GET_PHY_MEDIA_INFO_OUT msgresponse */ #define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMIN 5 @@ -9350,6 +9394,8 @@ #define NVRAM_PARTITION_TYPE_FPGA_JUMP 0xb08 /* enum: FPGA Validate XCLBIN */ #define NVRAM_PARTITION_TYPE_FPGA_XCLBIN_VALIDATE 0xb09 +/* enum: FPGA XOCL Configuration information */ +#define NVRAM_PARTITION_TYPE_FPGA_XOCL_CONFIG 0xb0a /* enum: MUM firmware partition */ #define NVRAM_PARTITION_TYPE_MUM_FIRMWARE 0xc00 /* enum: SUC firmware partition (this is intentionally an alias of @@ -9427,6 +9473,8 @@ #define NVRAM_PARTITION_TYPE_BUNDLE_LOG 0x1e02 /* enum: Partition for Solarflare gPXE bootrom installed via Bundle update. */ #define NVRAM_PARTITION_TYPE_EXPANSION_ROM_INTERNAL 0x1e03 +/* enum: Partition to store ASN.1 format Bundle Signature for checking. */ +#define NVRAM_PARTITION_TYPE_BUNDLE_SIGNATURE 0x1e04 /* enum: Test partition on SmartNIC system microcontroller (SUC) */ #define NVRAM_PARTITION_TYPE_SUC_TEST 0x1f00 /* enum: System microcontroller access to primary FPGA flash. */ @@ -10051,6 +10099,158 @@ #define MC_CMD_INIT_EVQ_V2_OUT_FLAG_RXQ_FORCE_EV_MERGING_LBN 3 #define MC_CMD_INIT_EVQ_V2_OUT_FLAG_RXQ_FORCE_EV_MERGING_WIDTH 1 +/* MC_CMD_INIT_EVQ_V3_IN msgrequest: Extended request to specify per-queue + * event merge timeouts. + */ +#define MC_CMD_INIT_EVQ_V3_IN_LEN 556 +/* Size, in entries */ +#define MC_CMD_INIT_EVQ_V3_IN_SIZE_OFST 0 +#define MC_CMD_INIT_EVQ_V3_IN_SIZE_LEN 4 +/* Desired instance. Must be set to a specific instance, which is a function + * local queue index. The calling client must be the currently-assigned user of + * this VI (see MC_CMD_SET_VI_USER). + */ +#define MC_CMD_INIT_EVQ_V3_IN_INSTANCE_OFST 4 +#define MC_CMD_INIT_EVQ_V3_IN_INSTANCE_LEN 4 +/* The initial timer value. The load value is ignored if the timer mode is DIS. + */ +#define MC_CMD_INIT_EVQ_V3_IN_TMR_LOAD_OFST 8 +#define MC_CMD_INIT_EVQ_V3_IN_TMR_LOAD_LEN 4 +/* The reload value is ignored in one-shot modes */ +#define MC_CMD_INIT_EVQ_V3_IN_TMR_RELOAD_OFST 12 +#define MC_CMD_INIT_EVQ_V3_IN_TMR_RELOAD_LEN 4 +/* tbd */ +#define MC_CMD_INIT_EVQ_V3_IN_FLAGS_OFST 16 +#define MC_CMD_INIT_EVQ_V3_IN_FLAGS_LEN 4 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_INTERRUPTING_OFST 16 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_INTERRUPTING_LBN 0 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_INTERRUPTING_WIDTH 1 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_RPTR_DOS_OFST 16 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_RPTR_DOS_LBN 1 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_RPTR_DOS_WIDTH 1 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_INT_ARMD_OFST 16 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_INT_ARMD_LBN 2 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_INT_ARMD_WIDTH 1 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_CUT_THRU_OFST 16 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_CUT_THRU_LBN 3 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_CUT_THRU_WIDTH 1 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_RX_MERGE_OFST 16 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_RX_MERGE_LBN 4 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_RX_MERGE_WIDTH 1 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_TX_MERGE_OFST 16 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_TX_MERGE_LBN 5 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_TX_MERGE_WIDTH 1 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_USE_TIMER_OFST 16 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_USE_TIMER_LBN 6 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_USE_TIMER_WIDTH 1 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_TYPE_OFST 16 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_TYPE_LBN 7 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_TYPE_WIDTH 4 +/* enum: All initialisation flags specified by host. */ +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_TYPE_MANUAL 0x0 +/* enum: MEDFORD only. Certain initialisation flags specified by host may be + * over-ridden by firmware based on licenses and firmware variant in order to + * provide the lowest latency achievable. See + * MC_CMD_INIT_EVQ_V2/MC_CMD_INIT_EVQ_V2_OUT/FLAGS for list of affected flags. + */ +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_TYPE_LOW_LATENCY 0x1 +/* enum: MEDFORD only. Certain initialisation flags specified by host may be + * over-ridden by firmware based on licenses and firmware variant in order to + * provide the best throughput achievable. See + * MC_CMD_INIT_EVQ_V2/MC_CMD_INIT_EVQ_V2_OUT/FLAGS for list of affected flags. + */ +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_TYPE_THROUGHPUT 0x2 +/* enum: MEDFORD only. Certain initialisation flags may be over-ridden by + * firmware based on licenses and firmware variant. See + * MC_CMD_INIT_EVQ_V2/MC_CMD_INIT_EVQ_V2_OUT/FLAGS for list of affected flags. + */ +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_TYPE_AUTO 0x3 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_EXT_WIDTH_OFST 16 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_EXT_WIDTH_LBN 11 +#define MC_CMD_INIT_EVQ_V3_IN_FLAG_EXT_WIDTH_WIDTH 1 +#define MC_CMD_INIT_EVQ_V3_IN_TMR_MODE_OFST 20 +#define MC_CMD_INIT_EVQ_V3_IN_TMR_MODE_LEN 4 +/* enum: Disabled */ +#define MC_CMD_INIT_EVQ_V3_IN_TMR_MODE_DIS 0x0 +/* enum: Immediate */ +#define MC_CMD_INIT_EVQ_V3_IN_TMR_IMMED_START 0x1 +/* enum: Triggered */ +#define MC_CMD_INIT_EVQ_V3_IN_TMR_TRIG_START 0x2 +/* enum: Hold-off */ +#define MC_CMD_INIT_EVQ_V3_IN_TMR_INT_HLDOFF 0x3 +/* Target EVQ for wakeups if in wakeup mode. */ +#define MC_CMD_INIT_EVQ_V3_IN_TARGET_EVQ_OFST 24 +#define MC_CMD_INIT_EVQ_V3_IN_TARGET_EVQ_LEN 4 +/* Target interrupt if in interrupting mode (note union with target EVQ). Use + * MC_CMD_RESOURCE_INSTANCE_ANY unless a specific one required for test + * purposes. + */ +#define MC_CMD_INIT_EVQ_V3_IN_IRQ_NUM_OFST 24 +#define MC_CMD_INIT_EVQ_V3_IN_IRQ_NUM_LEN 4 +/* Event Counter Mode. */ +#define MC_CMD_INIT_EVQ_V3_IN_COUNT_MODE_OFST 28 +#define MC_CMD_INIT_EVQ_V3_IN_COUNT_MODE_LEN 4 +/* enum: Disabled */ +#define MC_CMD_INIT_EVQ_V3_IN_COUNT_MODE_DIS 0x0 +/* enum: Disabled */ +#define MC_CMD_INIT_EVQ_V3_IN_COUNT_MODE_RX 0x1 +/* enum: Disabled */ +#define MC_CMD_INIT_EVQ_V3_IN_COUNT_MODE_TX 0x2 +/* enum: Disabled */ +#define MC_CMD_INIT_EVQ_V3_IN_COUNT_MODE_RXTX 0x3 +/* Event queue packet count threshold. */ +#define MC_CMD_INIT_EVQ_V3_IN_COUNT_THRSHLD_OFST 32 +#define MC_CMD_INIT_EVQ_V3_IN_COUNT_THRSHLD_LEN 4 +/* 64-bit address of 4k of 4k-aligned host memory buffer */ +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_OFST 36 +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_LEN 8 +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_LO_OFST 36 +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_LO_LEN 4 +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_LO_LBN 288 +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_LO_WIDTH 32 +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_HI_OFST 40 +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_HI_LEN 4 +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_HI_LBN 320 +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_HI_WIDTH 32 +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_MINNUM 1 +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_MAXNUM 64 +#define MC_CMD_INIT_EVQ_V3_IN_DMA_ADDR_MAXNUM_MCDI2 64 +/* Receive event merge timeout to configure, in nanoseconds. The valid range + * and granularity are device specific. Specify 0 to use the firmware's default + * value. This field is ignored and per-queue merging is disabled if + * MC_CMD_INIT_EVQ/MC_CMD_INIT_EVQ_IN/FLAG_RX_MERGE is not set. + */ +#define MC_CMD_INIT_EVQ_V3_IN_RX_MERGE_TIMEOUT_NS_OFST 548 +#define MC_CMD_INIT_EVQ_V3_IN_RX_MERGE_TIMEOUT_NS_LEN 4 +/* Transmit event merge timeout to configure, in nanoseconds. The valid range + * and granularity are device specific. Specify 0 to use the firmware's default + * value. This field is ignored and per-queue merging is disabled if + * MC_CMD_INIT_EVQ/MC_CMD_INIT_EVQ_IN/FLAG_TX_MERGE is not set. + */ +#define MC_CMD_INIT_EVQ_V3_IN_TX_MERGE_TIMEOUT_NS_OFST 552 +#define MC_CMD_INIT_EVQ_V3_IN_TX_MERGE_TIMEOUT_NS_LEN 4 + +/* MC_CMD_INIT_EVQ_V3_OUT msgresponse */ +#define MC_CMD_INIT_EVQ_V3_OUT_LEN 8 +/* Only valid if INTRFLAG was true */ +#define MC_CMD_INIT_EVQ_V3_OUT_IRQ_OFST 0 +#define MC_CMD_INIT_EVQ_V3_OUT_IRQ_LEN 4 +/* Actual configuration applied on the card */ +#define MC_CMD_INIT_EVQ_V3_OUT_FLAGS_OFST 4 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAGS_LEN 4 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAG_CUT_THRU_OFST 4 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAG_CUT_THRU_LBN 0 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAG_CUT_THRU_WIDTH 1 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAG_RX_MERGE_OFST 4 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAG_RX_MERGE_LBN 1 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAG_RX_MERGE_WIDTH 1 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAG_TX_MERGE_OFST 4 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAG_TX_MERGE_LBN 2 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAG_TX_MERGE_WIDTH 1 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAG_RXQ_FORCE_EV_MERGING_OFST 4 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAG_RXQ_FORCE_EV_MERGING_LBN 3 +#define MC_CMD_INIT_EVQ_V3_OUT_FLAG_RXQ_FORCE_EV_MERGING_WIDTH 1 + /* QUEUE_CRC_MODE structuredef */ #define QUEUE_CRC_MODE_LEN 1 #define QUEUE_CRC_MODE_MODE_LBN 0 @@ -10256,7 +10456,9 @@ #define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_HI_LEN 4 #define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_HI_LBN 256 #define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_HI_WIDTH 32 -#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_NUM 64 +#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_MINNUM 0 +#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_MAXNUM 64 +#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_MAXNUM_MCDI2 64 /* Maximum length of packet to receive, if SNAPSHOT_MODE flag is set */ #define MC_CMD_INIT_RXQ_EXT_IN_SNAPSHOT_LENGTH_OFST 540 #define MC_CMD_INIT_RXQ_EXT_IN_SNAPSHOT_LENGTH_LEN 4 @@ -10360,7 +10562,9 @@ #define MC_CMD_INIT_RXQ_V3_IN_DMA_ADDR_HI_LEN 4 #define MC_CMD_INIT_RXQ_V3_IN_DMA_ADDR_HI_LBN 256 #define MC_CMD_INIT_RXQ_V3_IN_DMA_ADDR_HI_WIDTH 32 -#define MC_CMD_INIT_RXQ_V3_IN_DMA_ADDR_NUM 64 +#define MC_CMD_INIT_RXQ_V3_IN_DMA_ADDR_MINNUM 0 +#define MC_CMD_INIT_RXQ_V3_IN_DMA_ADDR_MAXNUM 64 +#define MC_CMD_INIT_RXQ_V3_IN_DMA_ADDR_MAXNUM_MCDI2 64 /* Maximum length of packet to receive, if SNAPSHOT_MODE flag is set */ #define MC_CMD_INIT_RXQ_V3_IN_SNAPSHOT_LENGTH_OFST 540 #define MC_CMD_INIT_RXQ_V3_IN_SNAPSHOT_LENGTH_LEN 4 @@ -10493,7 +10697,9 @@ #define MC_CMD_INIT_RXQ_V4_IN_DMA_ADDR_HI_LEN 4 #define MC_CMD_INIT_RXQ_V4_IN_DMA_ADDR_HI_LBN 256 #define MC_CMD_INIT_RXQ_V4_IN_DMA_ADDR_HI_WIDTH 32 -#define MC_CMD_INIT_RXQ_V4_IN_DMA_ADDR_NUM 64 +#define MC_CMD_INIT_RXQ_V4_IN_DMA_ADDR_MINNUM 0 +#define MC_CMD_INIT_RXQ_V4_IN_DMA_ADDR_MAXNUM 64 +#define MC_CMD_INIT_RXQ_V4_IN_DMA_ADDR_MAXNUM_MCDI2 64 /* Maximum length of packet to receive, if SNAPSHOT_MODE flag is set */ #define MC_CMD_INIT_RXQ_V4_IN_SNAPSHOT_LENGTH_OFST 540 #define MC_CMD_INIT_RXQ_V4_IN_SNAPSHOT_LENGTH_LEN 4 @@ -10639,7 +10845,9 @@ #define MC_CMD_INIT_RXQ_V5_IN_DMA_ADDR_HI_LEN 4 #define MC_CMD_INIT_RXQ_V5_IN_DMA_ADDR_HI_LBN 256 #define MC_CMD_INIT_RXQ_V5_IN_DMA_ADDR_HI_WIDTH 32 -#define MC_CMD_INIT_RXQ_V5_IN_DMA_ADDR_NUM 64 +#define MC_CMD_INIT_RXQ_V5_IN_DMA_ADDR_MINNUM 0 +#define MC_CMD_INIT_RXQ_V5_IN_DMA_ADDR_MAXNUM 64 +#define MC_CMD_INIT_RXQ_V5_IN_DMA_ADDR_MAXNUM_MCDI2 64 /* Maximum length of packet to receive, if SNAPSHOT_MODE flag is set */ #define MC_CMD_INIT_RXQ_V5_IN_SNAPSHOT_LENGTH_OFST 540 #define MC_CMD_INIT_RXQ_V5_IN_SNAPSHOT_LENGTH_LEN 4 @@ -10878,7 +11086,7 @@ #define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_HI_LEN 4 #define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_HI_LBN 256 #define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_HI_WIDTH 32 -#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_MINNUM 1 +#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_MINNUM 0 #define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_MAXNUM 64 #define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_MAXNUM_MCDI2 64 /* Flags related to Qbb flow control mode. */ @@ -12228,6 +12436,8 @@ * rules inserted by MC_CMD_VNIC_ENCAP_RULE_ADD. (ef100 and later) */ #define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_VNIC_ENCAP_MATCHES 0x5 +/* enum: read the supported encapsulation types for the VNIC */ +#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_VNIC_ENCAP_TYPES 0x6 /* MC_CMD_GET_PARSER_DISP_INFO_OUT msgresponse */ #define MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMIN 8 @@ -12336,6 +12546,30 @@ #define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_SUPPORTED_MATCHES_MAXNUM 61 #define MC_CMD_GET_PARSER_DISP_VNIC_ENCAP_MATCHES_OUT_SUPPORTED_MATCHES_MAXNUM_MCDI2 253 +/* MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT msgresponse: Returns + * the supported encapsulation types for the VNIC + */ +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_LEN 8 +/* The op code OP_GET_SUPPORTED_VNIC_ENCAP_TYPES is returned */ +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_OP_OFST 0 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_OP_LEN 4 +/* Enum values, see field(s): */ +/* MC_CMD_GET_PARSER_DISP_INFO_IN/OP */ +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPES_SUPPORTED_OFST 4 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPES_SUPPORTED_LEN 4 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPE_VXLAN_OFST 4 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPE_VXLAN_LBN 0 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPE_VXLAN_WIDTH 1 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPE_NVGRE_OFST 4 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPE_NVGRE_LBN 1 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPE_NVGRE_WIDTH 1 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPE_GENEVE_OFST 4 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPE_GENEVE_LBN 2 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPE_GENEVE_WIDTH 1 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPE_L2GRE_OFST 4 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPE_L2GRE_LBN 3 +#define MC_CMD_GET_PARSER_DISP_SUPPORTED_VNIC_ENCAP_TYPES_OUT_ENCAP_TYPE_L2GRE_WIDTH 1 + /***********************************/ /* MC_CMD_PARSER_DISP_RW @@ -16236,6 +16470,9 @@ #define MC_CMD_GET_CAPABILITIES_V7_OUT_MAE_ACTION_SET_ALLOC_V2_SUPPORTED_OFST 148 #define MC_CMD_GET_CAPABILITIES_V7_OUT_MAE_ACTION_SET_ALLOC_V2_SUPPORTED_LBN 11 #define MC_CMD_GET_CAPABILITIES_V7_OUT_MAE_ACTION_SET_ALLOC_V2_SUPPORTED_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V7_OUT_RSS_STEER_ON_OUTER_SUPPORTED_OFST 148 +#define MC_CMD_GET_CAPABILITIES_V7_OUT_RSS_STEER_ON_OUTER_SUPPORTED_LBN 12 +#define MC_CMD_GET_CAPABILITIES_V7_OUT_RSS_STEER_ON_OUTER_SUPPORTED_WIDTH 1 /* MC_CMD_GET_CAPABILITIES_V8_OUT msgresponse */ #define MC_CMD_GET_CAPABILITIES_V8_OUT_LEN 160 @@ -16734,6 +16971,9 @@ #define MC_CMD_GET_CAPABILITIES_V8_OUT_MAE_ACTION_SET_ALLOC_V2_SUPPORTED_OFST 148 #define MC_CMD_GET_CAPABILITIES_V8_OUT_MAE_ACTION_SET_ALLOC_V2_SUPPORTED_LBN 11 #define MC_CMD_GET_CAPABILITIES_V8_OUT_MAE_ACTION_SET_ALLOC_V2_SUPPORTED_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V8_OUT_RSS_STEER_ON_OUTER_SUPPORTED_OFST 148 +#define MC_CMD_GET_CAPABILITIES_V8_OUT_RSS_STEER_ON_OUTER_SUPPORTED_LBN 12 +#define MC_CMD_GET_CAPABILITIES_V8_OUT_RSS_STEER_ON_OUTER_SUPPORTED_WIDTH 1 /* These bits are reserved for communicating test-specific capabilities to * host-side test software. All production drivers should treat this field as * opaque. @@ -17246,6 +17486,9 @@ #define MC_CMD_GET_CAPABILITIES_V9_OUT_MAE_ACTION_SET_ALLOC_V2_SUPPORTED_OFST 148 #define MC_CMD_GET_CAPABILITIES_V9_OUT_MAE_ACTION_SET_ALLOC_V2_SUPPORTED_LBN 11 #define MC_CMD_GET_CAPABILITIES_V9_OUT_MAE_ACTION_SET_ALLOC_V2_SUPPORTED_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_STEER_ON_OUTER_SUPPORTED_OFST 148 +#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_STEER_ON_OUTER_SUPPORTED_LBN 12 +#define MC_CMD_GET_CAPABILITIES_V9_OUT_RSS_STEER_ON_OUTER_SUPPORTED_WIDTH 1 /* These bits are reserved for communicating test-specific capabilities to * host-side test software. All production drivers should treat this field as * opaque. @@ -17793,6 +18036,9 @@ #define MC_CMD_GET_CAPABILITIES_V10_OUT_MAE_ACTION_SET_ALLOC_V2_SUPPORTED_OFST 148 #define MC_CMD_GET_CAPABILITIES_V10_OUT_MAE_ACTION_SET_ALLOC_V2_SUPPORTED_LBN 11 #define MC_CMD_GET_CAPABILITIES_V10_OUT_MAE_ACTION_SET_ALLOC_V2_SUPPORTED_WIDTH 1 +#define MC_CMD_GET_CAPABILITIES_V10_OUT_RSS_STEER_ON_OUTER_SUPPORTED_OFST 148 +#define MC_CMD_GET_CAPABILITIES_V10_OUT_RSS_STEER_ON_OUTER_SUPPORTED_LBN 12 +#define MC_CMD_GET_CAPABILITIES_V10_OUT_RSS_STEER_ON_OUTER_SUPPORTED_WIDTH 1 /* These bits are reserved for communicating test-specific capabilities to * host-side test software. All production drivers should treat this field as * opaque. @@ -19900,6 +20146,18 @@ #define MC_CMD_GET_FUNCTION_INFO_OUT_VF_OFST 4 #define MC_CMD_GET_FUNCTION_INFO_OUT_VF_LEN 4 +/* MC_CMD_GET_FUNCTION_INFO_OUT_V2 msgresponse */ +#define MC_CMD_GET_FUNCTION_INFO_OUT_V2_LEN 12 +#define MC_CMD_GET_FUNCTION_INFO_OUT_V2_PF_OFST 0 +#define MC_CMD_GET_FUNCTION_INFO_OUT_V2_PF_LEN 4 +#define MC_CMD_GET_FUNCTION_INFO_OUT_V2_VF_OFST 4 +#define MC_CMD_GET_FUNCTION_INFO_OUT_V2_VF_LEN 4 +/* Values from PCIE_INTERFACE enumeration. For NICs with a single interface, or + * in the case of a V1 response, this should be HOST_PRIMARY. + */ +#define MC_CMD_GET_FUNCTION_INFO_OUT_V2_INTF_OFST 8 +#define MC_CMD_GET_FUNCTION_INFO_OUT_V2_INTF_LEN 4 + /***********************************/ /* MC_CMD_ENABLE_OFFLINE_BIST @@ -25682,6 +25940,9 @@ #define MC_CMD_GET_RX_PREFIX_ID_IN_USER_MARK_OFST 0 #define MC_CMD_GET_RX_PREFIX_ID_IN_USER_MARK_LBN 6 #define MC_CMD_GET_RX_PREFIX_ID_IN_USER_MARK_WIDTH 1 +#define MC_CMD_GET_RX_PREFIX_ID_IN_INGRESS_MPORT_OFST 0 +#define MC_CMD_GET_RX_PREFIX_ID_IN_INGRESS_MPORT_LBN 7 +#define MC_CMD_GET_RX_PREFIX_ID_IN_INGRESS_MPORT_WIDTH 1 #define MC_CMD_GET_RX_PREFIX_ID_IN_INGRESS_VPORT_OFST 0 #define MC_CMD_GET_RX_PREFIX_ID_IN_INGRESS_VPORT_LBN 7 #define MC_CMD_GET_RX_PREFIX_ID_IN_INGRESS_VPORT_WIDTH 1 @@ -25691,6 +25952,12 @@ #define MC_CMD_GET_RX_PREFIX_ID_IN_VLAN_STRIP_TCI_OFST 0 #define MC_CMD_GET_RX_PREFIX_ID_IN_VLAN_STRIP_TCI_LBN 9 #define MC_CMD_GET_RX_PREFIX_ID_IN_VLAN_STRIP_TCI_WIDTH 1 +#define MC_CMD_GET_RX_PREFIX_ID_IN_VLAN_STRIPPED_OFST 0 +#define MC_CMD_GET_RX_PREFIX_ID_IN_VLAN_STRIPPED_LBN 10 +#define MC_CMD_GET_RX_PREFIX_ID_IN_VLAN_STRIPPED_WIDTH 1 +#define MC_CMD_GET_RX_PREFIX_ID_IN_VSWITCH_STATUS_OFST 0 +#define MC_CMD_GET_RX_PREFIX_ID_IN_VSWITCH_STATUS_LBN 11 +#define MC_CMD_GET_RX_PREFIX_ID_IN_VSWITCH_STATUS_WIDTH 1 /* MC_CMD_GET_RX_PREFIX_ID_OUT msgresponse */ #define MC_CMD_GET_RX_PREFIX_ID_OUT_LENMIN 8 @@ -25736,9 +26003,12 @@ #define RX_PREFIX_FIELD_INFO_PARTIAL_TSTAMP 0x4 /* enum */ #define RX_PREFIX_FIELD_INFO_RSS_HASH 0x5 /* enum */ #define RX_PREFIX_FIELD_INFO_USER_MARK 0x6 /* enum */ +#define RX_PREFIX_FIELD_INFO_INGRESS_MPORT 0x7 /* enum */ #define RX_PREFIX_FIELD_INFO_INGRESS_VPORT 0x7 /* enum */ #define RX_PREFIX_FIELD_INFO_CSUM_FRAME 0x8 /* enum */ #define RX_PREFIX_FIELD_INFO_VLAN_STRIP_TCI 0x9 /* enum */ +#define RX_PREFIX_FIELD_INFO_VLAN_STRIPPED 0xa /* enum */ +#define RX_PREFIX_FIELD_INFO_VSWITCH_STATUS 0xb /* enum */ #define RX_PREFIX_FIELD_INFO_TYPE_LBN 24 #define RX_PREFIX_FIELD_INFO_TYPE_WIDTH 8 @@ -26063,6 +26333,10 @@ #define MC_CMD_FPGA_IN_OP_SET_INTERNAL_LINK 0x5 /* enum: Read internal link configuration. */ #define MC_CMD_FPGA_IN_OP_GET_INTERNAL_LINK 0x6 +/* enum: Get MAC statistics of FPGA external port. */ +#define MC_CMD_FPGA_IN_OP_GET_MAC_STATS 0x7 +/* enum: Set configuration on internal FPGA MAC. */ +#define MC_CMD_FPGA_IN_OP_SET_INTERNAL_MAC 0x8 /* MC_CMD_FPGA_OP_GET_VERSION_IN msgrequest: Get the FPGA version string. A * free-format string is returned in response to this command. Any checks on @@ -26206,6 +26480,87 @@ #define MC_CMD_FPGA_OP_GET_INTERNAL_LINK_OUT_SPEED_OFST 4 #define MC_CMD_FPGA_OP_GET_INTERNAL_LINK_OUT_SPEED_LEN 4 +/* MC_CMD_FPGA_OP_GET_MAC_STATS_IN msgrequest: Get FPGA external port MAC + * statistics. + */ +#define MC_CMD_FPGA_OP_GET_MAC_STATS_IN_LEN 4 +/* Sub-command code. Must be OP_GET_MAC_STATS. */ +#define MC_CMD_FPGA_OP_GET_MAC_STATS_IN_OP_OFST 0 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_IN_OP_LEN 4 + +/* MC_CMD_FPGA_OP_GET_MAC_STATS_OUT msgresponse */ +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_LENMIN 4 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_LENMAX 252 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_LENMAX_MCDI2 1020 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_LEN(num) (4+8*(num)) +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_NUM(len) (((len)-4)/8) +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_NUM_STATS_OFST 0 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_NUM_STATS_LEN 4 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_OFST 4 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_LEN 8 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_LO_OFST 4 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_LO_LEN 4 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_LO_LBN 32 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_LO_WIDTH 32 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_HI_OFST 8 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_HI_LEN 4 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_HI_LBN 64 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_HI_WIDTH 32 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_MINNUM 0 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_MAXNUM 31 +#define MC_CMD_FPGA_OP_GET_MAC_STATS_OUT_STATISTICS_MAXNUM_MCDI2 127 +#define MC_CMD_FPGA_MAC_TX_TOTAL_PACKETS 0x0 /* enum */ +#define MC_CMD_FPGA_MAC_TX_TOTAL_BYTES 0x1 /* enum */ +#define MC_CMD_FPGA_MAC_TX_TOTAL_GOOD_PACKETS 0x2 /* enum */ +#define MC_CMD_FPGA_MAC_TX_TOTAL_GOOD_BYTES 0x3 /* enum */ +#define MC_CMD_FPGA_MAC_TX_BAD_FCS 0x4 /* enum */ +#define MC_CMD_FPGA_MAC_TX_PAUSE 0x5 /* enum */ +#define MC_CMD_FPGA_MAC_TX_USER_PAUSE 0x6 /* enum */ +#define MC_CMD_FPGA_MAC_RX_TOTAL_PACKETS 0x7 /* enum */ +#define MC_CMD_FPGA_MAC_RX_TOTAL_BYTES 0x8 /* enum */ +#define MC_CMD_FPGA_MAC_RX_TOTAL_GOOD_PACKETS 0x9 /* enum */ +#define MC_CMD_FPGA_MAC_RX_TOTAL_GOOD_BYTES 0xa /* enum */ +#define MC_CMD_FPGA_MAC_RX_BAD_FCS 0xb /* enum */ +#define MC_CMD_FPGA_MAC_RX_PAUSE 0xc /* enum */ +#define MC_CMD_FPGA_MAC_RX_USER_PAUSE 0xd /* enum */ +#define MC_CMD_FPGA_MAC_RX_UNDERSIZE 0xe /* enum */ +#define MC_CMD_FPGA_MAC_RX_OVERSIZE 0xf /* enum */ +#define MC_CMD_FPGA_MAC_RX_FRAMING_ERR 0x10 /* enum */ +#define MC_CMD_FPGA_MAC_FEC_UNCORRECTED_ERRORS 0x11 /* enum */ +#define MC_CMD_FPGA_MAC_FEC_CORRECTED_ERRORS 0x12 /* enum */ + +/* MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN msgrequest: Configures the internal port + * MAC on the FPGA. + */ +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_LEN 20 +/* Sub-command code. Must be OP_SET_INTERNAL_MAC. */ +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_OP_OFST 0 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_OP_LEN 4 +/* Select which parameters to configure. */ +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_CONTROL_OFST 4 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_CONTROL_LEN 4 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_CFG_MTU_OFST 4 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_CFG_MTU_LBN 0 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_CFG_MTU_WIDTH 1 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_CFG_DRAIN_OFST 4 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_CFG_DRAIN_LBN 1 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_CFG_DRAIN_WIDTH 1 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_CFG_FCNTL_OFST 4 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_CFG_FCNTL_LBN 2 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_CFG_FCNTL_WIDTH 1 +/* The MTU to be programmed into the MAC. */ +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_MTU_OFST 8 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_MTU_LEN 4 +/* Drain Tx FIFO */ +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_DRAIN_OFST 12 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_DRAIN_LEN 4 +/* flow control configuration. See MC_CMD_SET_MAC/MC_CMD_SET_MAC_IN/FCNTL. */ +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_FCNTL_OFST 16 +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_IN_FCNTL_LEN 4 + +/* MC_CMD_FPGA_OP_SET_INTERNAL_MAC_OUT msgresponse */ +#define MC_CMD_FPGA_OP_SET_INTERNAL_MAC_OUT_LEN 0 + /***********************************/ /* MC_CMD_EXTERNAL_MAE_GET_LINK_MODE @@ -26483,6 +26838,12 @@ #define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_STRIP_OUTER_VLAN_OFST 29 #define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_STRIP_OUTER_VLAN_LBN 0 #define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_STRIP_OUTER_VLAN_WIDTH 1 +#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_RSS_ON_OUTER_OFST 29 +#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_RSS_ON_OUTER_LBN 1 +#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_RSS_ON_OUTER_WIDTH 1 +#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_STEER_ON_OUTER_OFST 29 +#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_STEER_ON_OUTER_LBN 2 +#define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_STEER_ON_OUTER_WIDTH 1 /* Only if MATCH_DST_PORT is set. Port number as bytes in network order. */ #define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_DST_PORT_OFST 30 #define MC_CMD_VNIC_ENCAP_RULE_ADD_IN_DST_PORT_LEN 2 @@ -26544,6 +26905,257 @@ #define UUID_NODE_LBN 80 #define UUID_NODE_WIDTH 48 + +/***********************************/ +/* MC_CMD_PLUGIN_ALLOC + * Create a handle to a datapath plugin's extension. This involves finding a + * currently-loaded plugin offering the given functionality (as identified by + * the UUID) and allocating a handle to track the usage of it. Plugin + * functionality is identified by 'extension' rather than any other identifier + * so that a single plugin bitfile may offer more than one piece of independent + * functionality. If two bitfiles are loaded which both offer the same + * extension, then the metadata is interrogated further to determine which is + * the newest and that is the one opened. See SF-123625-SW for architectural + * detail on datapath plugins. + */ +#define MC_CMD_PLUGIN_ALLOC 0x1ad +#define MC_CMD_PLUGIN_ALLOC_MSGSET 0x1ad +#undef MC_CMD_0x1ad_PRIVILEGE_CTG + +#define MC_CMD_0x1ad_PRIVILEGE_CTG SRIOV_CTG_GENERAL + +/* MC_CMD_PLUGIN_ALLOC_IN msgrequest */ +#define MC_CMD_PLUGIN_ALLOC_IN_LEN 24 +/* The functionality requested of the plugin, as a UUID structure */ +#define MC_CMD_PLUGIN_ALLOC_IN_UUID_OFST 0 +#define MC_CMD_PLUGIN_ALLOC_IN_UUID_LEN 16 +/* Additional options for opening the handle */ +#define MC_CMD_PLUGIN_ALLOC_IN_FLAGS_OFST 16 +#define MC_CMD_PLUGIN_ALLOC_IN_FLAGS_LEN 4 +#define MC_CMD_PLUGIN_ALLOC_IN_FLAG_INFO_ONLY_OFST 16 +#define MC_CMD_PLUGIN_ALLOC_IN_FLAG_INFO_ONLY_LBN 0 +#define MC_CMD_PLUGIN_ALLOC_IN_FLAG_INFO_ONLY_WIDTH 1 +#define MC_CMD_PLUGIN_ALLOC_IN_FLAG_ALLOW_DISABLED_OFST 16 +#define MC_CMD_PLUGIN_ALLOC_IN_FLAG_ALLOW_DISABLED_LBN 1 +#define MC_CMD_PLUGIN_ALLOC_IN_FLAG_ALLOW_DISABLED_WIDTH 1 +/* Load the extension only if it is in the specified administrative group. + * Specify ANY to load the extension wherever it is found (if there are + * multiple choices then the extension with the highest MINOR_VER/PATCH_VER + * will be loaded). See MC_CMD_PLUGIN_GET_META_GLOBAL for a description of + * administrative groups. + */ +#define MC_CMD_PLUGIN_ALLOC_IN_ADMIN_GROUP_OFST 20 +#define MC_CMD_PLUGIN_ALLOC_IN_ADMIN_GROUP_LEN 2 +/* enum: Load the extension from any ADMIN_GROUP. */ +#define MC_CMD_PLUGIN_ALLOC_IN_ANY 0xffff +/* Reserved */ +#define MC_CMD_PLUGIN_ALLOC_IN_RESERVED_OFST 22 +#define MC_CMD_PLUGIN_ALLOC_IN_RESERVED_LEN 2 + +/* MC_CMD_PLUGIN_ALLOC_OUT msgresponse */ +#define MC_CMD_PLUGIN_ALLOC_OUT_LEN 4 +/* Unique identifier of this usage */ +#define MC_CMD_PLUGIN_ALLOC_OUT_HANDLE_OFST 0 +#define MC_CMD_PLUGIN_ALLOC_OUT_HANDLE_LEN 4 + + +/***********************************/ +/* MC_CMD_PLUGIN_FREE + * Delete a handle to a plugin's extension. + */ +#define MC_CMD_PLUGIN_FREE 0x1ae +#define MC_CMD_PLUGIN_FREE_MSGSET 0x1ae +#undef MC_CMD_0x1ae_PRIVILEGE_CTG + +#define MC_CMD_0x1ae_PRIVILEGE_CTG SRIOV_CTG_GENERAL + +/* MC_CMD_PLUGIN_FREE_IN msgrequest */ +#define MC_CMD_PLUGIN_FREE_IN_LEN 4 +/* Handle returned by MC_CMD_PLUGIN_ALLOC_OUT */ +#define MC_CMD_PLUGIN_FREE_IN_HANDLE_OFST 0 +#define MC_CMD_PLUGIN_FREE_IN_HANDLE_LEN 4 + +/* MC_CMD_PLUGIN_FREE_OUT msgresponse */ +#define MC_CMD_PLUGIN_FREE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_PLUGIN_GET_META_GLOBAL + * Returns the global metadata applying to the whole plugin extension. See the + * other metadata calls for subtypes of data. + */ +#define MC_CMD_PLUGIN_GET_META_GLOBAL 0x1af +#define MC_CMD_PLUGIN_GET_META_GLOBAL_MSGSET 0x1af +#undef MC_CMD_0x1af_PRIVILEGE_CTG + +#define MC_CMD_0x1af_PRIVILEGE_CTG SRIOV_CTG_GENERAL + +/* MC_CMD_PLUGIN_GET_META_GLOBAL_IN msgrequest */ +#define MC_CMD_PLUGIN_GET_META_GLOBAL_IN_LEN 4 +/* Handle returned by MC_CMD_PLUGIN_ALLOC_OUT */ +#define MC_CMD_PLUGIN_GET_META_GLOBAL_IN_HANDLE_OFST 0 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_IN_HANDLE_LEN 4 + +/* MC_CMD_PLUGIN_GET_META_GLOBAL_OUT msgresponse */ +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_LEN 36 +/* Unique identifier of this plugin extension. This is identical to the value + * which was requested when the handle was allocated. + */ +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_UUID_OFST 0 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_UUID_LEN 16 +/* semver sub-version of this plugin extension */ +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MINOR_VER_OFST 16 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MINOR_VER_LEN 2 +/* semver micro-version of this plugin extension */ +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_PATCH_VER_OFST 18 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_PATCH_VER_LEN 2 +/* Number of different messages which can be sent to this extension */ +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_NUM_MSGS_OFST 20 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_NUM_MSGS_LEN 4 +/* Byte offset within the VI window of the plugin's mapped CSR window. */ +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MAPPED_CSR_OFFSET_OFST 24 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MAPPED_CSR_OFFSET_LEN 2 +/* Number of bytes mapped through to the plugin's CSRs. 0 if that feature was + * not requested by the plugin (in which case MAPPED_CSR_OFFSET and + * MAPPED_CSR_FLAGS are ignored). + */ +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MAPPED_CSR_SIZE_OFST 26 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MAPPED_CSR_SIZE_LEN 2 +/* Flags indicating how to perform the CSR window mapping. */ +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MAPPED_CSR_FLAGS_OFST 28 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MAPPED_CSR_FLAGS_LEN 4 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MAPPED_CSR_FLAG_READ_OFST 28 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MAPPED_CSR_FLAG_READ_LBN 0 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MAPPED_CSR_FLAG_READ_WIDTH 1 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MAPPED_CSR_FLAG_WRITE_OFST 28 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MAPPED_CSR_FLAG_WRITE_LBN 1 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_MAPPED_CSR_FLAG_WRITE_WIDTH 1 +/* Identifier of the set of extensions which all change state together. + * Extensions having the same ADMIN_GROUP will always load and unload at the + * same time. ADMIN_GROUP values themselves are arbitrary (but they contain a + * generation number as an implementation detail to ensure that they're not + * reused rapidly). + */ +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_ADMIN_GROUP_OFST 32 +#define MC_CMD_PLUGIN_GET_META_GLOBAL_OUT_ADMIN_GROUP_LEN 1 +/* Bitshift in MC_CMD_DEVEL_CLIENT_PRIVILEGE_MODIFY's MASK parameters + * corresponding to this extension, i.e. set the bit 1<= ACTION_PRIOS. + */ +#define MC_CMD_MAE_GET_CAPS_V2_OUT_ACTION_PRIOS_OFST 40 +#define MC_CMD_MAE_GET_CAPS_V2_OUT_ACTION_PRIOS_LEN 4 +/* The number of priorities available for OUTER_RULE filters. It is invalid to + * install an OUTER_RULE filter with a priority number >= OUTER_PRIOS. + */ +#define MC_CMD_MAE_GET_CAPS_V2_OUT_OUTER_PRIOS_OFST 44 +#define MC_CMD_MAE_GET_CAPS_V2_OUT_OUTER_PRIOS_LEN 4 +/* MAE API major version. Currently 1. If this field is not present in the + * response (i.e. response shorter than 384 bits), then its value is zero. If + * the value does not match the client's expectations, the client should raise + * a fatal error. + */ +#define MC_CMD_MAE_GET_CAPS_V2_OUT_API_VER_OFST 48 +#define MC_CMD_MAE_GET_CAPS_V2_OUT_API_VER_LEN 4 +/* Mask of supported counter types. Each bit position corresponds to a value of + * the MAE_COUNTER_TYPE enum. If this field is missing (i.e. V1 response), + * clients must assume that only AR counters are supported (i.e. + * COUNTER_TYPES_SUPPORTED==0x1). See also + * MC_CMD_MAE_COUNTERS_STREAM_START/COUNTER_TYPES_MASK. + */ +#define MC_CMD_MAE_GET_CAPS_V2_OUT_COUNTER_TYPES_SUPPORTED_OFST 52 +#define MC_CMD_MAE_GET_CAPS_V2_OUT_COUNTER_TYPES_SUPPORTED_LEN 4 +/* The total number of conntrack counters available to allocate. */ +#define MC_CMD_MAE_GET_CAPS_V2_OUT_CT_COUNTERS_OFST 56 +#define MC_CMD_MAE_GET_CAPS_V2_OUT_CT_COUNTERS_LEN 4 + /***********************************/ /* MC_CMD_MAE_GET_AR_CAPS @@ -29495,8 +30447,8 @@ /***********************************/ /* MC_CMD_MAE_COUNTER_ALLOC - * Allocate match-action-engine counters, which can be referenced in Action - * Rules. + * Allocate match-action-engine counters, which can be referenced in various + * tables. */ #define MC_CMD_MAE_COUNTER_ALLOC 0x143 #define MC_CMD_MAE_COUNTER_ALLOC_MSGSET 0x143 @@ -29504,12 +30456,25 @@ #define MC_CMD_0x143_PRIVILEGE_CTG SRIOV_CTG_MAE -/* MC_CMD_MAE_COUNTER_ALLOC_IN msgrequest */ +/* MC_CMD_MAE_COUNTER_ALLOC_IN msgrequest: Using this is equivalent to using V2 + * with COUNTER_TYPE=AR. + */ #define MC_CMD_MAE_COUNTER_ALLOC_IN_LEN 4 /* The number of counters that the driver would like allocated */ #define MC_CMD_MAE_COUNTER_ALLOC_IN_REQUESTED_COUNT_OFST 0 #define MC_CMD_MAE_COUNTER_ALLOC_IN_REQUESTED_COUNT_LEN 4 +/* MC_CMD_MAE_COUNTER_ALLOC_V2_IN msgrequest */ +#define MC_CMD_MAE_COUNTER_ALLOC_V2_IN_LEN 8 +/* The number of counters that the driver would like allocated */ +#define MC_CMD_MAE_COUNTER_ALLOC_V2_IN_REQUESTED_COUNT_OFST 0 +#define MC_CMD_MAE_COUNTER_ALLOC_V2_IN_REQUESTED_COUNT_LEN 4 +/* Which type of counter to allocate. */ +#define MC_CMD_MAE_COUNTER_ALLOC_V2_IN_COUNTER_TYPE_OFST 4 +#define MC_CMD_MAE_COUNTER_ALLOC_V2_IN_COUNTER_TYPE_LEN 4 +/* Enum values, see field(s): */ +/* MAE_COUNTER_TYPE */ + /* MC_CMD_MAE_COUNTER_ALLOC_OUT msgresponse */ #define MC_CMD_MAE_COUNTER_ALLOC_OUT_LENMIN 12 #define MC_CMD_MAE_COUNTER_ALLOC_OUT_LENMAX 252 @@ -29518,7 +30483,8 @@ #define MC_CMD_MAE_COUNTER_ALLOC_OUT_COUNTER_ID_NUM(len) (((len)-8)/4) /* Generation count. Packets with generation count >= GENERATION_COUNT will * contain valid counter values for counter IDs allocated in this call, unless - * the counter values are zero and zero squash is enabled. + * the counter values are zero and zero squash is enabled. Note that there is + * an independent GENERATION_COUNT object per counter type. */ #define MC_CMD_MAE_COUNTER_ALLOC_OUT_GENERATION_COUNT_OFST 0 #define MC_CMD_MAE_COUNTER_ALLOC_OUT_GENERATION_COUNT_LEN 4 @@ -29548,7 +30514,9 @@ #define MC_CMD_0x144_PRIVILEGE_CTG SRIOV_CTG_MAE -/* MC_CMD_MAE_COUNTER_FREE_IN msgrequest */ +/* MC_CMD_MAE_COUNTER_FREE_IN msgrequest: Using this is equivalent to using V2 + * with COUNTER_TYPE=AR. + */ #define MC_CMD_MAE_COUNTER_FREE_IN_LENMIN 8 #define MC_CMD_MAE_COUNTER_FREE_IN_LENMAX 132 #define MC_CMD_MAE_COUNTER_FREE_IN_LENMAX_MCDI2 132 @@ -29564,6 +30532,23 @@ #define MC_CMD_MAE_COUNTER_FREE_IN_FREE_COUNTER_ID_MAXNUM 32 #define MC_CMD_MAE_COUNTER_FREE_IN_FREE_COUNTER_ID_MAXNUM_MCDI2 32 +/* MC_CMD_MAE_COUNTER_FREE_V2_IN msgrequest */ +#define MC_CMD_MAE_COUNTER_FREE_V2_IN_LEN 136 +/* The number of counter IDs to be freed. */ +#define MC_CMD_MAE_COUNTER_FREE_V2_IN_COUNTER_ID_COUNT_OFST 0 +#define MC_CMD_MAE_COUNTER_FREE_V2_IN_COUNTER_ID_COUNT_LEN 4 +/* An array containing the counter IDs to be freed. */ +#define MC_CMD_MAE_COUNTER_FREE_V2_IN_FREE_COUNTER_ID_OFST 4 +#define MC_CMD_MAE_COUNTER_FREE_V2_IN_FREE_COUNTER_ID_LEN 4 +#define MC_CMD_MAE_COUNTER_FREE_V2_IN_FREE_COUNTER_ID_MINNUM 1 +#define MC_CMD_MAE_COUNTER_FREE_V2_IN_FREE_COUNTER_ID_MAXNUM 32 +#define MC_CMD_MAE_COUNTER_FREE_V2_IN_FREE_COUNTER_ID_MAXNUM_MCDI2 32 +/* Which type of counter to free. */ +#define MC_CMD_MAE_COUNTER_FREE_V2_IN_COUNTER_TYPE_OFST 132 +#define MC_CMD_MAE_COUNTER_FREE_V2_IN_COUNTER_TYPE_LEN 4 +/* Enum values, see field(s): */ +/* MAE_COUNTER_TYPE */ + /* MC_CMD_MAE_COUNTER_FREE_OUT msgresponse */ #define MC_CMD_MAE_COUNTER_FREE_OUT_LENMIN 12 #define MC_CMD_MAE_COUNTER_FREE_OUT_LENMAX 136 @@ -29572,11 +30557,13 @@ #define MC_CMD_MAE_COUNTER_FREE_OUT_FREED_COUNTER_ID_NUM(len) (((len)-8)/4) /* Generation count. A packet with generation count == GENERATION_COUNT will * contain the final values for these counter IDs, unless the counter values - * are zero and zero squash is enabled. Receiving a packet with generation - * count > GENERATION_COUNT guarantees that no more values will be written for - * these counters. If values for these counter IDs are present, the counter ID - * has been reallocated. A counter ID will not be reallocated within a single - * read cycle as this would merge increments from the 'old' and 'new' counters. + * are zero and zero squash is enabled. Note that the GENERATION_COUNT value is + * specific to the COUNTER_TYPE (IDENTIFIER field in packet header). Receiving + * a packet with generation count > GENERATION_COUNT guarantees that no more + * values will be written for these counters. If values for these counter IDs + * are present, the counter ID has been reallocated. A counter ID will not be + * reallocated within a single read cycle as this would merge increments from + * the 'old' and 'new' counters. */ #define MC_CMD_MAE_COUNTER_FREE_OUT_GENERATION_COUNT_OFST 0 #define MC_CMD_MAE_COUNTER_FREE_OUT_GENERATION_COUNT_LEN 4 @@ -29616,7 +30603,9 @@ #define MC_CMD_0x151_PRIVILEGE_CTG SRIOV_CTG_MAE -/* MC_CMD_MAE_COUNTERS_STREAM_START_IN msgrequest */ +/* MC_CMD_MAE_COUNTERS_STREAM_START_IN msgrequest: Using V1 is equivalent to V2 + * with COUNTER_TYPES_MASK=0x1 (i.e. AR counters only). + */ #define MC_CMD_MAE_COUNTERS_STREAM_START_IN_LEN 8 /* The RxQ to write packets to. */ #define MC_CMD_MAE_COUNTERS_STREAM_START_IN_QID_OFST 0 @@ -29634,6 +30623,35 @@ #define MC_CMD_MAE_COUNTERS_STREAM_START_IN_COUNTER_STALL_EN_LBN 1 #define MC_CMD_MAE_COUNTERS_STREAM_START_IN_COUNTER_STALL_EN_WIDTH 1 +/* MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN msgrequest */ +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_LEN 12 +/* The RxQ to write packets to. */ +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_QID_OFST 0 +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_QID_LEN 2 +/* Maximum size in bytes of packets that may be written to the RxQ. */ +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_PACKET_SIZE_OFST 2 +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_PACKET_SIZE_LEN 2 +/* Optional flags. */ +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_FLAGS_OFST 4 +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_FLAGS_LEN 4 +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_ZERO_SQUASH_DISABLE_OFST 4 +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_ZERO_SQUASH_DISABLE_LBN 0 +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_ZERO_SQUASH_DISABLE_WIDTH 1 +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_COUNTER_STALL_EN_OFST 4 +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_COUNTER_STALL_EN_LBN 1 +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_COUNTER_STALL_EN_WIDTH 1 +/* Mask of which counter types should be reported. Each bit position + * corresponds to a value of the MAE_COUNTER_TYPE enum. For example a value of + * 0x3 requests both AR and CT counters. A value of zero is invalid. Counter + * types not selected by the mask value won't be included in the stream. If a + * client wishes to change which counter types are reported, it must first call + * MAE_COUNTERS_STREAM_STOP, then restart it with the new mask value. + * Requesting a counter type which isn't supported by firmware (reported in + * MC_CMD_MAE_GET_CAPS/COUNTER_TYPES_SUPPORTED) will result in ENOTSUP. + */ +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_COUNTER_TYPES_MASK_OFST 8 +#define MC_CMD_MAE_COUNTERS_STREAM_START_V2_IN_COUNTER_TYPES_MASK_LEN 4 + /* MC_CMD_MAE_COUNTERS_STREAM_START_OUT msgresponse */ #define MC_CMD_MAE_COUNTERS_STREAM_START_OUT_LEN 4 #define MC_CMD_MAE_COUNTERS_STREAM_START_OUT_FLAGS_OFST 0 @@ -29661,14 +30679,32 @@ /* MC_CMD_MAE_COUNTERS_STREAM_STOP_OUT msgresponse */ #define MC_CMD_MAE_COUNTERS_STREAM_STOP_OUT_LEN 4 -/* Generation count. The final set of counter values will be written out in - * packets with count == GENERATION_COUNT. An empty packet with count > - * GENERATION_COUNT indicates that no more counter values will be written to - * this stream. +/* Generation count for AR counters. The final set of AR counter values will be + * written out in packets with count == GENERATION_COUNT. An empty packet with + * count > GENERATION_COUNT indicates that no more counter values of this type + * will be written to this stream. */ #define MC_CMD_MAE_COUNTERS_STREAM_STOP_OUT_GENERATION_COUNT_OFST 0 #define MC_CMD_MAE_COUNTERS_STREAM_STOP_OUT_GENERATION_COUNT_LEN 4 +/* MC_CMD_MAE_COUNTERS_STREAM_STOP_V2_OUT msgresponse */ +#define MC_CMD_MAE_COUNTERS_STREAM_STOP_V2_OUT_LENMIN 4 +#define MC_CMD_MAE_COUNTERS_STREAM_STOP_V2_OUT_LENMAX 32 +#define MC_CMD_MAE_COUNTERS_STREAM_STOP_V2_OUT_LENMAX_MCDI2 32 +#define MC_CMD_MAE_COUNTERS_STREAM_STOP_V2_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_MAE_COUNTERS_STREAM_STOP_V2_OUT_GENERATION_COUNT_NUM(len) (((len)-0)/4) +/* Array of generation counts, indexed by MAE_COUNTER_TYPE. Note that since + * MAE_COUNTER_TYPE_AR==0, this response is backwards-compatible with V1. The + * final set of counter values will be written out in packets with count == + * GENERATION_COUNT. An empty packet with count > GENERATION_COUNT indicates + * that no more counter values of this type will be written to this stream. + */ +#define MC_CMD_MAE_COUNTERS_STREAM_STOP_V2_OUT_GENERATION_COUNT_OFST 0 +#define MC_CMD_MAE_COUNTERS_STREAM_STOP_V2_OUT_GENERATION_COUNT_LEN 4 +#define MC_CMD_MAE_COUNTERS_STREAM_STOP_V2_OUT_GENERATION_COUNT_MINNUM 1 +#define MC_CMD_MAE_COUNTERS_STREAM_STOP_V2_OUT_GENERATION_COUNT_MAXNUM 8 +#define MC_CMD_MAE_COUNTERS_STREAM_STOP_V2_OUT_GENERATION_COUNT_MAXNUM_MCDI2 8 + /***********************************/ /* MC_CMD_MAE_COUNTERS_STREAM_GIVE_CREDITS @@ -29941,9 +30977,10 @@ #define MC_CMD_MAE_ACTION_SET_ALLOC_IN_COUNTER_LIST_ID_LEN 4 /* If a driver only wished to update one counter within this action set, then * it can supply a COUNTER_ID instead of allocating a single-element counter - * list. This field should be set to COUNTER_ID_NULL if this behaviour is not - * required. It is not valid to supply a non-NULL value for both - * COUNTER_LIST_ID and COUNTER_ID. + * list. The ID must have been allocated with COUNTER_TYPE=AR. This field + * should be set to COUNTER_ID_NULL if this behaviour is not required. It is + * not valid to supply a non-NULL value for both COUNTER_LIST_ID and + * COUNTER_ID. */ #define MC_CMD_MAE_ACTION_SET_ALLOC_IN_COUNTER_ID_OFST 28 #define MC_CMD_MAE_ACTION_SET_ALLOC_IN_COUNTER_ID_LEN 4 @@ -30021,9 +31058,10 @@ #define MC_CMD_MAE_ACTION_SET_ALLOC_V2_IN_COUNTER_LIST_ID_LEN 4 /* If a driver only wished to update one counter within this action set, then * it can supply a COUNTER_ID instead of allocating a single-element counter - * list. This field should be set to COUNTER_ID_NULL if this behaviour is not - * required. It is not valid to supply a non-NULL value for both - * COUNTER_LIST_ID and COUNTER_ID. + * list. The ID must have been allocated with COUNTER_TYPE=AR. This field + * should be set to COUNTER_ID_NULL if this behaviour is not required. It is + * not valid to supply a non-NULL value for both COUNTER_LIST_ID and + * COUNTER_ID. */ #define MC_CMD_MAE_ACTION_SET_ALLOC_V2_IN_COUNTER_ID_OFST 28 #define MC_CMD_MAE_ACTION_SET_ALLOC_V2_IN_COUNTER_ID_LEN 4 @@ -30352,7 +31390,8 @@ #define MAE_ACTION_RULE_RESPONSE_LOOKUP_CONTROL_LBN 64 #define MAE_ACTION_RULE_RESPONSE_LOOKUP_CONTROL_WIDTH 32 /* Counter ID to increment if DO_CT or DO_RECIRC is set. Must be set to - * COUNTER_ID_NULL otherwise. + * COUNTER_ID_NULL otherwise. Counter ID must have been allocated with + * COUNTER_TYPE=AR. */ #define MAE_ACTION_RULE_RESPONSE_COUNTER_ID_OFST 12 #define MAE_ACTION_RULE_RESPONSE_COUNTER_ID_LEN 4 @@ -30710,6 +31749,108 @@ #define MAE_MPORT_DESC_VNIC_PLUGIN_TBD_LBN 352 #define MAE_MPORT_DESC_VNIC_PLUGIN_TBD_WIDTH 32 +/* MAE_MPORT_DESC_V2 structuredef */ +#define MAE_MPORT_DESC_V2_LEN 56 +#define MAE_MPORT_DESC_V2_MPORT_ID_OFST 0 +#define MAE_MPORT_DESC_V2_MPORT_ID_LEN 4 +#define MAE_MPORT_DESC_V2_MPORT_ID_LBN 0 +#define MAE_MPORT_DESC_V2_MPORT_ID_WIDTH 32 +/* Reserved for future purposes, contains information independent of caller */ +#define MAE_MPORT_DESC_V2_FLAGS_OFST 4 +#define MAE_MPORT_DESC_V2_FLAGS_LEN 4 +#define MAE_MPORT_DESC_V2_FLAGS_LBN 32 +#define MAE_MPORT_DESC_V2_FLAGS_WIDTH 32 +#define MAE_MPORT_DESC_V2_CALLER_FLAGS_OFST 8 +#define MAE_MPORT_DESC_V2_CALLER_FLAGS_LEN 4 +#define MAE_MPORT_DESC_V2_CAN_RECEIVE_ON_OFST 8 +#define MAE_MPORT_DESC_V2_CAN_RECEIVE_ON_LBN 0 +#define MAE_MPORT_DESC_V2_CAN_RECEIVE_ON_WIDTH 1 +#define MAE_MPORT_DESC_V2_CAN_DELIVER_TO_OFST 8 +#define MAE_MPORT_DESC_V2_CAN_DELIVER_TO_LBN 1 +#define MAE_MPORT_DESC_V2_CAN_DELIVER_TO_WIDTH 1 +#define MAE_MPORT_DESC_V2_CAN_DELETE_OFST 8 +#define MAE_MPORT_DESC_V2_CAN_DELETE_LBN 2 +#define MAE_MPORT_DESC_V2_CAN_DELETE_WIDTH 1 +#define MAE_MPORT_DESC_V2_IS_ZOMBIE_OFST 8 +#define MAE_MPORT_DESC_V2_IS_ZOMBIE_LBN 3 +#define MAE_MPORT_DESC_V2_IS_ZOMBIE_WIDTH 1 +#define MAE_MPORT_DESC_V2_CALLER_FLAGS_LBN 64 +#define MAE_MPORT_DESC_V2_CALLER_FLAGS_WIDTH 32 +/* Not the ideal name; it's really the type of thing connected to the m-port */ +#define MAE_MPORT_DESC_V2_MPORT_TYPE_OFST 12 +#define MAE_MPORT_DESC_V2_MPORT_TYPE_LEN 4 +/* enum: Connected to a MAC... */ +#define MAE_MPORT_DESC_V2_MPORT_TYPE_NET_PORT 0x0 +/* enum: Adds metadata and delivers to another m-port */ +#define MAE_MPORT_DESC_V2_MPORT_TYPE_ALIAS 0x1 +/* enum: Connected to a VNIC. */ +#define MAE_MPORT_DESC_V2_MPORT_TYPE_VNIC 0x2 +#define MAE_MPORT_DESC_V2_MPORT_TYPE_LBN 96 +#define MAE_MPORT_DESC_V2_MPORT_TYPE_WIDTH 32 +/* 128-bit value available to drivers for m-port identification. */ +#define MAE_MPORT_DESC_V2_UUID_OFST 16 +#define MAE_MPORT_DESC_V2_UUID_LEN 16 +#define MAE_MPORT_DESC_V2_UUID_LBN 128 +#define MAE_MPORT_DESC_V2_UUID_WIDTH 128 +/* Big wadge of space reserved for other common properties */ +#define MAE_MPORT_DESC_V2_RESERVED_OFST 32 +#define MAE_MPORT_DESC_V2_RESERVED_LEN 8 +#define MAE_MPORT_DESC_V2_RESERVED_LO_OFST 32 +#define MAE_MPORT_DESC_V2_RESERVED_LO_LEN 4 +#define MAE_MPORT_DESC_V2_RESERVED_LO_LBN 256 +#define MAE_MPORT_DESC_V2_RESERVED_LO_WIDTH 32 +#define MAE_MPORT_DESC_V2_RESERVED_HI_OFST 36 +#define MAE_MPORT_DESC_V2_RESERVED_HI_LEN 4 +#define MAE_MPORT_DESC_V2_RESERVED_HI_LBN 288 +#define MAE_MPORT_DESC_V2_RESERVED_HI_WIDTH 32 +#define MAE_MPORT_DESC_V2_RESERVED_LBN 256 +#define MAE_MPORT_DESC_V2_RESERVED_WIDTH 64 +/* Logical port index. Only valid when type NET Port. */ +#define MAE_MPORT_DESC_V2_NET_PORT_IDX_OFST 40 +#define MAE_MPORT_DESC_V2_NET_PORT_IDX_LEN 4 +#define MAE_MPORT_DESC_V2_NET_PORT_IDX_LBN 320 +#define MAE_MPORT_DESC_V2_NET_PORT_IDX_WIDTH 32 +/* The m-port delivered to */ +#define MAE_MPORT_DESC_V2_ALIAS_DELIVER_MPORT_ID_OFST 40 +#define MAE_MPORT_DESC_V2_ALIAS_DELIVER_MPORT_ID_LEN 4 +#define MAE_MPORT_DESC_V2_ALIAS_DELIVER_MPORT_ID_LBN 320 +#define MAE_MPORT_DESC_V2_ALIAS_DELIVER_MPORT_ID_WIDTH 32 +/* The type of thing that owns the VNIC */ +#define MAE_MPORT_DESC_V2_VNIC_CLIENT_TYPE_OFST 40 +#define MAE_MPORT_DESC_V2_VNIC_CLIENT_TYPE_LEN 4 +#define MAE_MPORT_DESC_V2_VNIC_CLIENT_TYPE_FUNCTION 0x1 /* enum */ +#define MAE_MPORT_DESC_V2_VNIC_CLIENT_TYPE_PLUGIN 0x2 /* enum */ +#define MAE_MPORT_DESC_V2_VNIC_CLIENT_TYPE_LBN 320 +#define MAE_MPORT_DESC_V2_VNIC_CLIENT_TYPE_WIDTH 32 +/* The PCIe interface on which the function lives. CJK: We need an enumeration + * of interfaces that we extend as new interface (types) appear. This belongs + * elsewhere and should be referenced from here + */ +#define MAE_MPORT_DESC_V2_VNIC_FUNCTION_INTERFACE_OFST 44 +#define MAE_MPORT_DESC_V2_VNIC_FUNCTION_INTERFACE_LEN 4 +#define MAE_MPORT_DESC_V2_VNIC_FUNCTION_INTERFACE_LBN 352 +#define MAE_MPORT_DESC_V2_VNIC_FUNCTION_INTERFACE_WIDTH 32 +#define MAE_MPORT_DESC_V2_VNIC_FUNCTION_PF_IDX_OFST 48 +#define MAE_MPORT_DESC_V2_VNIC_FUNCTION_PF_IDX_LEN 2 +#define MAE_MPORT_DESC_V2_VNIC_FUNCTION_PF_IDX_LBN 384 +#define MAE_MPORT_DESC_V2_VNIC_FUNCTION_PF_IDX_WIDTH 16 +#define MAE_MPORT_DESC_V2_VNIC_FUNCTION_VF_IDX_OFST 50 +#define MAE_MPORT_DESC_V2_VNIC_FUNCTION_VF_IDX_LEN 2 +/* enum: Indicates that the function is a PF */ +#define MAE_MPORT_DESC_V2_VF_IDX_NULL 0xffff +#define MAE_MPORT_DESC_V2_VNIC_FUNCTION_VF_IDX_LBN 400 +#define MAE_MPORT_DESC_V2_VNIC_FUNCTION_VF_IDX_WIDTH 16 +/* Reserved. Should be ignored for now. */ +#define MAE_MPORT_DESC_V2_VNIC_PLUGIN_TBD_OFST 44 +#define MAE_MPORT_DESC_V2_VNIC_PLUGIN_TBD_LEN 4 +#define MAE_MPORT_DESC_V2_VNIC_PLUGIN_TBD_LBN 352 +#define MAE_MPORT_DESC_V2_VNIC_PLUGIN_TBD_WIDTH 32 +/* A client handle for the VNIC's owner. Only valid for type VNIC. */ +#define MAE_MPORT_DESC_V2_VNIC_CLIENT_HANDLE_OFST 52 +#define MAE_MPORT_DESC_V2_VNIC_CLIENT_HANDLE_LEN 4 +#define MAE_MPORT_DESC_V2_VNIC_CLIENT_HANDLE_LBN 416 +#define MAE_MPORT_DESC_V2_VNIC_CLIENT_HANDLE_WIDTH 32 + /***********************************/ /* MC_CMD_MAE_MPORT_ENUMERATE From patchwork Fri Aug 27 06:56:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97420 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 78C61A0C43; Fri, 27 Aug 2021 08:57:55 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 434CA41251; Fri, 27 Aug 2021 08:57:45 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id AB3EB41250 for ; Fri, 27 Aug 2021 08:57:44 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 755787F6FE; Fri, 27 Aug 2021 09:57:44 +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=1.6 required=5.0 tests=ALL_TRUSTED, DKIM_ADSP_DISCARD, UPPERCASE_50_75,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 E5C707F6CB for ; Fri, 27 Aug 2021 09:57:32 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru E5C707F6CB Authentication-Results: shelob.oktetlabs.ru/E5C707F6CB; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Date: Fri, 27 Aug 2021 09:56:41 +0300 Message-Id: <20210827065717.1838258-3-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 02/38] common/sfc_efx/base: update EF100 registers definitions 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" Pick up all changes and extra definitions. Signed-off-by: Andrew Rybchenko --- drivers/common/sfc_efx/base/efx_regs_ef100.h | 106 +++++++++++++++---- drivers/common/sfc_efx/base/rhead_rx.c | 2 +- 2 files changed, 85 insertions(+), 23 deletions(-) diff --git a/drivers/common/sfc_efx/base/efx_regs_ef100.h b/drivers/common/sfc_efx/base/efx_regs_ef100.h index 2b766aabdd..0446377f64 100644 --- a/drivers/common/sfc_efx/base/efx_regs_ef100.h +++ b/drivers/common/sfc_efx/base/efx_regs_ef100.h @@ -323,12 +323,6 @@ extern "C" { /* ES_RHEAD_BASE_EVENT */ #define ESF_GZ_E_TYPE_LBN 60 #define ESF_GZ_E_TYPE_WIDTH 4 -#define ESE_GZ_EF100_EV_DRIVER 5 -#define ESE_GZ_EF100_EV_MCDI 4 -#define ESE_GZ_EF100_EV_CONTROL 3 -#define ESE_GZ_EF100_EV_TX_TIMESTAMP 2 -#define ESE_GZ_EF100_EV_TX_COMPLETION 1 -#define ESE_GZ_EF100_EV_RX_PKTS 0 #define ESF_GZ_EV_EVQ_PHASE_LBN 59 #define ESF_GZ_EV_EVQ_PHASE_WIDTH 1 #define ESE_GZ_RHEAD_BASE_EVENT_STRUCT_SIZE 64 @@ -467,6 +461,23 @@ extern "C" { #define ESE_GZ_XIL_CFGBAR_VSEC_STRUCT_SIZE 96 +/* ES_addr_spc */ +#define ESF_GZ_ADDR_SPC_FORMAT_1_FUNCTION_LBN 28 +#define ESF_GZ_ADDR_SPC_FORMAT_1_FUNCTION_WIDTH 8 +#define ESF_GZ_ADDR_SPC_FORMAT_2_FUNCTION_LBN 24 +#define ESF_GZ_ADDR_SPC_FORMAT_2_FUNCTION_WIDTH 12 +#define ESF_GZ_ADDR_SPC_FORMAT_1_PROFILE_ID_LBN 24 +#define ESF_GZ_ADDR_SPC_FORMAT_1_PROFILE_ID_WIDTH 4 +#define ESF_GZ_ADDR_SPC_PASID_LBN 2 +#define ESF_GZ_ADDR_SPC_PASID_WIDTH 22 +#define ESF_GZ_ADDR_SPC_FORMAT_LBN 0 +#define ESF_GZ_ADDR_SPC_FORMAT_WIDTH 2 +#define ESE_GZ_ADDR_SPC_FORMAT_1 3 +#define ESF_GZ_ADDR_SPC_FORMAT_2_PROFILE_ID_IDX_LBN 0 +#define ESF_GZ_ADDR_SPC_FORMAT_2_PROFILE_ID_IDX_WIDTH 2 +#define ESE_GZ_ADDR_SPC_STRUCT_SIZE 36 + + /* ES_rh_egres_hclass */ #define ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L4_CSUM_LBN 15 #define ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L4_CSUM_WIDTH 1 @@ -560,14 +571,18 @@ extern "C" { #define ESF_GZ_RX_PREFIX_VLAN_STRIP_TCI_WIDTH 16 #define ESF_GZ_RX_PREFIX_CSUM_FRAME_LBN 144 #define ESF_GZ_RX_PREFIX_CSUM_FRAME_WIDTH 16 -#define ESF_GZ_RX_PREFIX_INGRESS_VPORT_LBN 128 -#define ESF_GZ_RX_PREFIX_INGRESS_VPORT_WIDTH 16 +#define ESF_GZ_RX_PREFIX_INGRESS_MPORT_LBN 128 +#define ESF_GZ_RX_PREFIX_INGRESS_MPORT_WIDTH 16 #define ESF_GZ_RX_PREFIX_USER_MARK_LBN 96 #define ESF_GZ_RX_PREFIX_USER_MARK_WIDTH 32 #define ESF_GZ_RX_PREFIX_RSS_HASH_LBN 64 #define ESF_GZ_RX_PREFIX_RSS_HASH_WIDTH 32 -#define ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN 32 -#define ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_WIDTH 32 +#define ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN 34 +#define ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_WIDTH 30 +#define ESF_GZ_RX_PREFIX_VSWITCH_STATUS_LBN 33 +#define ESF_GZ_RX_PREFIX_VSWITCH_STATUS_WIDTH 1 +#define ESF_GZ_RX_PREFIX_VLAN_STRIPPED_LBN 32 +#define ESF_GZ_RX_PREFIX_VLAN_STRIPPED_WIDTH 1 #define ESF_GZ_RX_PREFIX_CLASS_LBN 16 #define ESF_GZ_RX_PREFIX_CLASS_WIDTH 16 #define ESF_GZ_RX_PREFIX_USER_FLAG_LBN 15 @@ -674,12 +689,12 @@ extern "C" { #define ESF_GZ_M2M_TRANSLATE_ADDR_WIDTH 1 #define ESF_GZ_M2M_RSVD_LBN 120 #define ESF_GZ_M2M_RSVD_WIDTH 2 -#define ESF_GZ_M2M_ADDR_SPC_LBN 108 -#define ESF_GZ_M2M_ADDR_SPC_WIDTH 12 -#define ESF_GZ_M2M_ADDR_SPC_PASID_LBN 86 -#define ESF_GZ_M2M_ADDR_SPC_PASID_WIDTH 22 -#define ESF_GZ_M2M_ADDR_SPC_MODE_LBN 84 -#define ESF_GZ_M2M_ADDR_SPC_MODE_WIDTH 2 +#define ESF_GZ_M2M_ADDR_SPC_ID_DW0_LBN 84 +#define ESF_GZ_M2M_ADDR_SPC_ID_DW0_WIDTH 32 +#define ESF_GZ_M2M_ADDR_SPC_ID_DW1_LBN 116 +#define ESF_GZ_M2M_ADDR_SPC_ID_DW1_WIDTH 4 +#define ESF_GZ_M2M_ADDR_SPC_ID_LBN 84 +#define ESF_GZ_M2M_ADDR_SPC_ID_WIDTH 36 #define ESF_GZ_M2M_LEN_MINUS_1_LBN 64 #define ESF_GZ_M2M_LEN_MINUS_1_WIDTH 20 #define ESF_GZ_M2M_ADDR_DW0_LBN 0 @@ -722,12 +737,12 @@ extern "C" { #define ESF_GZ_TX_SEG_TRANSLATE_ADDR_WIDTH 1 #define ESF_GZ_TX_SEG_RSVD2_LBN 120 #define ESF_GZ_TX_SEG_RSVD2_WIDTH 2 -#define ESF_GZ_TX_SEG_ADDR_SPC_LBN 108 -#define ESF_GZ_TX_SEG_ADDR_SPC_WIDTH 12 -#define ESF_GZ_TX_SEG_ADDR_SPC_PASID_LBN 86 -#define ESF_GZ_TX_SEG_ADDR_SPC_PASID_WIDTH 22 -#define ESF_GZ_TX_SEG_ADDR_SPC_MODE_LBN 84 -#define ESF_GZ_TX_SEG_ADDR_SPC_MODE_WIDTH 2 +#define ESF_GZ_TX_SEG_ADDR_SPC_ID_DW0_LBN 84 +#define ESF_GZ_TX_SEG_ADDR_SPC_ID_DW0_WIDTH 32 +#define ESF_GZ_TX_SEG_ADDR_SPC_ID_DW1_LBN 116 +#define ESF_GZ_TX_SEG_ADDR_SPC_ID_DW1_WIDTH 4 +#define ESF_GZ_TX_SEG_ADDR_SPC_ID_LBN 84 +#define ESF_GZ_TX_SEG_ADDR_SPC_ID_WIDTH 36 #define ESF_GZ_TX_SEG_RSVD_LBN 80 #define ESF_GZ_TX_SEG_RSVD_WIDTH 4 #define ESF_GZ_TX_SEG_LEN_LBN 64 @@ -824,6 +839,12 @@ extern "C" { +/* Enum D2VIO_MSG_OP */ +#define ESE_GZ_QUE_JBDNE 3 +#define ESE_GZ_QUE_EVICT 2 +#define ESE_GZ_QUE_EMPTY 1 +#define ESE_GZ_NOP 0 + /* Enum DESIGN_PARAMS */ #define ESE_EF100_DP_GZ_RX_MAX_RUNT 17 #define ESE_EF100_DP_GZ_VI_STRIDES 16 @@ -871,6 +892,19 @@ extern "C" { #define ESE_GZ_PCI_BASE_CONFIG_SPACE_SIZE 256 #define ESE_GZ_PCI_EXPRESS_XCAP_HDR_SIZE 4 +/* Enum RH_DSC_TYPE */ +#define ESE_GZ_TX_TOMB 0xF +#define ESE_GZ_TX_VIO 0xE +#define ESE_GZ_TX_TSO_OVRRD 0x8 +#define ESE_GZ_TX_D2CMP 0x7 +#define ESE_GZ_TX_DATA 0x6 +#define ESE_GZ_TX_D2M 0x5 +#define ESE_GZ_TX_M2M 0x4 +#define ESE_GZ_TX_SEG 0x3 +#define ESE_GZ_TX_TSO 0x2 +#define ESE_GZ_TX_OVRRD 0x1 +#define ESE_GZ_TX_SEND 0x0 + /* Enum RH_HCLASS_L2_CLASS */ #define ESE_GZ_RH_HCLASS_L2_CLASS_E2_0123VLAN 1 #define ESE_GZ_RH_HCLASS_L2_CLASS_OTHER 0 @@ -907,6 +941,25 @@ extern "C" { #define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_VXLAN 1 #define ESE_GZ_RH_HCLASS_TUNNEL_CLASS_NONE 0 +/* Enum SF_CTL_EVENT_SUBTYPE */ +#define ESE_GZ_EF100_CTL_EV_EVQ_TIMEOUT 0x3 +#define ESE_GZ_EF100_CTL_EV_FLUSH 0x2 +#define ESE_GZ_EF100_CTL_EV_TIME_SYNC 0x1 +#define ESE_GZ_EF100_CTL_EV_UNSOL_OVERFLOW 0x0 + +/* Enum SF_EVENT_TYPE */ +#define ESE_GZ_EF100_EV_DRIVER 0x5 +#define ESE_GZ_EF100_EV_MCDI 0x4 +#define ESE_GZ_EF100_EV_CONTROL 0x3 +#define ESE_GZ_EF100_EV_TX_TIMESTAMP 0x2 +#define ESE_GZ_EF100_EV_TX_COMPLETION 0x1 +#define ESE_GZ_EF100_EV_RX_PKTS 0x0 + +/* Enum SF_EW_EVENT_TYPE */ +#define ESE_GZ_EF100_EWEV_VIRTQ_DESC 0x2 +#define ESE_GZ_EF100_EWEV_TXQ_DESC 0x1 +#define ESE_GZ_EF100_EWEV_64BIT 0x0 + /* Enum TX_DESC_CSO_PARTIAL_EN */ #define ESE_GZ_TX_DESC_CSO_PARTIAL_EN_TCP 2 #define ESE_GZ_TX_DESC_CSO_PARTIAL_EN_UDP 1 @@ -922,6 +975,15 @@ extern "C" { #define ESE_GZ_TX_DESC_IP4_ID_INC_MOD16 2 #define ESE_GZ_TX_DESC_IP4_ID_INC_MOD15 1 #define ESE_GZ_TX_DESC_IP4_ID_NO_OP 0 + +/* Enum VIRTIO_NET_HDR_F */ +#define ESE_GZ_NEEDS_CSUM 0x1 + +/* Enum VIRTIO_NET_HDR_GSO */ +#define ESE_GZ_TCPV6 0x4 +#define ESE_GZ_UDP 0x3 +#define ESE_GZ_TCPV4 0x1 +#define ESE_GZ_NONE 0x0 /************************************************************************* * NOTE: the comment line above marks the end of the autogenerated section */ diff --git a/drivers/common/sfc_efx/base/rhead_rx.c b/drivers/common/sfc_efx/base/rhead_rx.c index 76b8ce302a..692c3e1d49 100644 --- a/drivers/common/sfc_efx/base/rhead_rx.c +++ b/drivers/common/sfc_efx/base/rhead_rx.c @@ -37,7 +37,7 @@ static const efx_rx_prefix_layout_t rhead_default_rx_prefix_layout = { RHEAD_RX_PREFIX_FIELD(PARTIAL_TSTAMP, B_FALSE), RHEAD_RX_PREFIX_FIELD(RSS_HASH, B_FALSE), RHEAD_RX_PREFIX_FIELD(USER_MARK, B_FALSE), - RHEAD_RX_PREFIX_FIELD(INGRESS_VPORT, B_FALSE), + RHEAD_RX_PREFIX_FIELD(INGRESS_MPORT, B_FALSE), RHEAD_RX_PREFIX_FIELD(CSUM_FRAME, B_TRUE), RHEAD_RX_PREFIX_FIELD(VLAN_STRIP_TCI, B_TRUE), From patchwork Fri Aug 27 06:56:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97421 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 CC9F7A0C43; Fri, 27 Aug 2021 08:58:01 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6365D4125D; Fri, 27 Aug 2021 08:57:46 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id BDB3341251 for ; Fri, 27 Aug 2021 08:57:44 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 7C0147F6CB; Fri, 27 Aug 2021 09:57:44 +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 0C9617F6D0; Fri, 27 Aug 2021 09:57:33 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 0C9617F6D0 Authentication-Results: shelob.oktetlabs.ru/0C9617F6D0; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:42 +0300 Message-Id: <20210827065717.1838258-4-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 03/38] net/sfc: add switch mode device argument 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: Igor Romanov Add the argument that allows user to choose either switchdev or legacy mode. Legacy mode enables switching by using Ethernet virtual bridging (EVB) API. In switchdev mode, VF traffic goes via port representor (if any) on PF, and software virtual switch (for example, Open vSwitch) steers the traffic. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- doc/guides/nics/sfc_efx.rst | 13 +++++++++ drivers/net/sfc/sfc.h | 2 ++ drivers/net/sfc/sfc_ethdev.c | 54 ++++++++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_kvargs.c | 1 + drivers/net/sfc/sfc_kvargs.h | 8 ++++++ drivers/net/sfc/sfc_sriov.c | 9 ++++-- 6 files changed, 85 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst index 163bc2533f..d66cb76dab 100644 --- a/doc/guides/nics/sfc_efx.rst +++ b/doc/guides/nics/sfc_efx.rst @@ -371,6 +371,19 @@ boolean parameters value. If this parameter is not specified then ef100 device will operate as network device. +- ``switch_mode`` [legacy|switchdev] (see below for default) + + In legacy mode, NIC firmware provides Ethernet virtual bridging (EVB) API + to configure switching inside NIC to deliver traffic to physical (PF) and + virtual (VF) PCI functions. PF driver is responsible to build the + infrastructure for VFs, and traffic goes to/from VF by default in accordance + with MAC address assigned, permissions and filters installed by VF drivers. + In switchdev mode VF traffic goes via port representor (if any) on PF, and + software virtual switch (for example, Open vSwitch) makes the decision. + Software virtual switch may install MAE rules to pass established traffic + flows via hardware and offload software datapath as the result. + Default is legacy. + - ``rx_datapath`` [auto|efx|ef10|ef10_essb] (default **auto**) Choose receive datapath implementation. diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 331e06bac6..b045baca9e 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -313,6 +313,8 @@ struct sfc_adapter { boolean_t tso_encap; uint32_t rxd_wait_timeout_ns; + + bool switchdev; }; static inline struct sfc_adapter_shared * diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 2db0d000c3..41add341a0 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -2188,6 +2188,44 @@ sfc_register_dp(void) } } +static int +sfc_parse_switch_mode(struct sfc_adapter *sa) +{ + const char *switch_mode = NULL; + int rc; + + sfc_log_init(sa, "entry"); + + rc = sfc_kvargs_process(sa, SFC_KVARG_SWITCH_MODE, + sfc_kvarg_string_handler, &switch_mode); + if (rc != 0) + goto fail_kvargs; + + /* Check representors when supported */ + if (switch_mode == NULL || + strcasecmp(switch_mode, SFC_KVARG_SWITCH_MODE_LEGACY) == 0) { + sa->switchdev = false; + } else if (strcasecmp(switch_mode, + SFC_KVARG_SWITCH_MODE_SWITCHDEV) == 0) { + sa->switchdev = true; + } else { + sfc_err(sa, "invalid switch mode device argument '%s'", + switch_mode); + rc = EINVAL; + goto fail_mode; + } + + sfc_log_init(sa, "done"); + + return 0; + +fail_mode: +fail_kvargs: + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + + return rc; +} + static int sfc_eth_dev_init(struct rte_eth_dev *dev) { @@ -2270,6 +2308,10 @@ sfc_eth_dev_init(struct rte_eth_dev *dev) sfc_adapter_lock_init(sa); sfc_adapter_lock(sa); + rc = sfc_parse_switch_mode(sa); + if (rc != 0) + goto fail_switch_mode; + sfc_log_init(sa, "probing"); rc = sfc_probe(sa); if (rc != 0) @@ -2285,6 +2327,13 @@ sfc_eth_dev_init(struct rte_eth_dev *dev) if (rc != 0) goto fail_attach; + if (sa->switchdev && sa->mae.status != SFC_MAE_STATUS_SUPPORTED) { + sfc_err(sa, + "failed to enable switchdev mode without MAE support"); + rc = ENOTSUP; + goto fail_switchdev_no_mae; + } + encp = efx_nic_cfg_get(sa->nic); /* @@ -2299,6 +2348,9 @@ sfc_eth_dev_init(struct rte_eth_dev *dev) sfc_log_init(sa, "done"); return 0; +fail_switchdev_no_mae: + sfc_detach(sa); + fail_attach: sfc_eth_dev_clear_ops(dev); @@ -2306,6 +2358,7 @@ sfc_eth_dev_init(struct rte_eth_dev *dev) sfc_unprobe(sa); fail_probe: +fail_switch_mode: sfc_adapter_unlock(sa); sfc_adapter_lock_fini(sa); rte_free(dev->data->mac_addrs); @@ -2370,6 +2423,7 @@ RTE_PMD_REGISTER_PCI(net_sfc_efx, sfc_efx_pmd); RTE_PMD_REGISTER_PCI_TABLE(net_sfc_efx, pci_id_sfc_efx_map); RTE_PMD_REGISTER_KMOD_DEP(net_sfc_efx, "* igb_uio | uio_pci_generic | vfio-pci"); RTE_PMD_REGISTER_PARAM_STRING(net_sfc_efx, + SFC_KVARG_SWITCH_MODE "=" SFC_KVARG_VALUES_SWITCH_MODE " " SFC_KVARG_RX_DATAPATH "=" SFC_KVARG_VALUES_RX_DATAPATH " " SFC_KVARG_TX_DATAPATH "=" SFC_KVARG_VALUES_TX_DATAPATH " " SFC_KVARG_PERF_PROFILE "=" SFC_KVARG_VALUES_PERF_PROFILE " " diff --git a/drivers/net/sfc/sfc_kvargs.c b/drivers/net/sfc/sfc_kvargs.c index 974c05e68e..cd16213637 100644 --- a/drivers/net/sfc/sfc_kvargs.c +++ b/drivers/net/sfc/sfc_kvargs.c @@ -22,6 +22,7 @@ sfc_kvargs_parse(struct sfc_adapter *sa) struct rte_eth_dev *eth_dev = (sa)->eth_dev; struct rte_devargs *devargs = eth_dev->device->devargs; const char **params = (const char *[]){ + SFC_KVARG_SWITCH_MODE, SFC_KVARG_STATS_UPDATE_PERIOD_MS, SFC_KVARG_PERF_PROFILE, SFC_KVARG_RX_DATAPATH, diff --git a/drivers/net/sfc/sfc_kvargs.h b/drivers/net/sfc/sfc_kvargs.h index ff76e7d9fc..8e34ec92a2 100644 --- a/drivers/net/sfc/sfc_kvargs.h +++ b/drivers/net/sfc/sfc_kvargs.h @@ -18,6 +18,14 @@ extern "C" { #define SFC_KVARG_VALUES_BOOL "[1|y|yes|on|0|n|no|off]" +#define SFC_KVARG_SWITCH_MODE_LEGACY "legacy" +#define SFC_KVARG_SWITCH_MODE_SWITCHDEV "switchdev" + +#define SFC_KVARG_SWITCH_MODE "switch_mode" +#define SFC_KVARG_VALUES_SWITCH_MODE \ + "[" SFC_KVARG_SWITCH_MODE_LEGACY "|" \ + SFC_KVARG_SWITCH_MODE_SWITCHDEV "]" + #define SFC_KVARG_PERF_PROFILE "perf_profile" #define SFC_KVARG_PERF_PROFILE_AUTO "auto" diff --git a/drivers/net/sfc/sfc_sriov.c b/drivers/net/sfc/sfc_sriov.c index baa0242433..385b172e2e 100644 --- a/drivers/net/sfc/sfc_sriov.c +++ b/drivers/net/sfc/sfc_sriov.c @@ -53,7 +53,7 @@ sfc_sriov_attach(struct sfc_adapter *sa) sfc_log_init(sa, "entry"); sriov->num_vfs = pci_dev->max_vfs; - if (sriov->num_vfs == 0) + if (sa->switchdev || sriov->num_vfs == 0) goto done; vport_config = calloc(sriov->num_vfs + 1, sizeof(*vport_config)); @@ -110,6 +110,11 @@ sfc_sriov_vswitch_create(struct sfc_adapter *sa) sfc_log_init(sa, "entry"); + if (sa->switchdev) { + sfc_log_init(sa, "don't create vswitch in switchdev mode"); + goto done; + } + if (sriov->num_vfs == 0) { sfc_log_init(sa, "no VFs enabled"); goto done; @@ -152,7 +157,7 @@ sfc_sriov_vswitch_destroy(struct sfc_adapter *sa) sfc_log_init(sa, "entry"); - if (sriov->num_vfs == 0) + if (sa->switchdev || sriov->num_vfs == 0) goto done; rc = efx_evb_vswitch_destroy(sa->nic, sriov->vswitch); From patchwork Fri Aug 27 06:56:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97422 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 CB260A0C43; Fri, 27 Aug 2021 08:58:07 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9FCBF41258; Fri, 27 Aug 2021 08:57:47 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 3B9B541258 for ; Fri, 27 Aug 2021 08:57:46 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 1324B7F6CB; Fri, 27 Aug 2021 09:57:46 +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 30F8E7F6D3; Fri, 27 Aug 2021 09:57:33 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 30F8E7F6D3 Authentication-Results: shelob.oktetlabs.ru/30F8E7F6D3; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:43 +0300 Message-Id: <20210827065717.1838258-5-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 04/38] net/sfc: insert switchdev mode MAE rules 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: Igor Romanov By default, the firmware is in EVB mode, but insertion of the first MAE rule resets it to switchdev mode automatically and removes all automatic MAE rules added by EVB support. On initialisation, insert MAE rules that forward traffic between PHY and PF. Add an API for creation and insertion of driver-internal MAE rules(flows). Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc.c | 8 ++ drivers/net/sfc/sfc_mae.c | 211 ++++++++++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_mae.h | 49 +++++++++ 3 files changed, 268 insertions(+) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 274a98e228..cd2c97f3b2 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -895,6 +895,10 @@ sfc_attach(struct sfc_adapter *sa) if (rc != 0) goto fail_mae_attach; + rc = sfc_mae_switchdev_init(sa); + if (rc != 0) + goto fail_mae_switchdev_init; + sfc_log_init(sa, "fini nic"); efx_nic_fini(enp); @@ -923,6 +927,9 @@ sfc_attach(struct sfc_adapter *sa) fail_sw_xstats_init: sfc_flow_fini(sa); + sfc_mae_switchdev_fini(sa); + +fail_mae_switchdev_init: sfc_mae_detach(sa); fail_mae_attach: @@ -969,6 +976,7 @@ sfc_detach(struct sfc_adapter *sa) sfc_flow_fini(sa); + sfc_mae_switchdev_fini(sa); sfc_mae_detach(sa); sfc_mae_counter_rxq_detach(sa); sfc_filter_detach(sa); diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index 4b520bc619..b3607a178b 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -44,6 +44,139 @@ sfc_mae_counter_registry_fini(struct sfc_mae_counter_registry *registry) sfc_mae_counters_fini(®istry->counters); } +static int +sfc_mae_internal_rule_find_empty_slot(struct sfc_adapter *sa, + struct sfc_mae_rule **rule) +{ + struct sfc_mae *mae = &sa->mae; + struct sfc_mae_internal_rules *internal_rules = &mae->internal_rules; + unsigned int entry; + int rc; + + for (entry = 0; entry < SFC_MAE_NB_RULES_MAX; entry++) { + if (internal_rules->rules[entry].spec == NULL) + break; + } + + if (entry == SFC_MAE_NB_RULES_MAX) { + rc = ENOSPC; + sfc_err(sa, "failed too many rules (%u rules used)", entry); + goto fail_too_many_rules; + } + + *rule = &internal_rules->rules[entry]; + + return 0; + +fail_too_many_rules: + return rc; +} + +int +sfc_mae_rule_add_mport_match_deliver(struct sfc_adapter *sa, + const efx_mport_sel_t *mport_match, + const efx_mport_sel_t *mport_deliver, + int prio, struct sfc_mae_rule **rulep) +{ + struct sfc_mae *mae = &sa->mae; + struct sfc_mae_rule *rule; + int rc; + + sfc_log_init(sa, "entry"); + + if (prio > 0 && (unsigned int)prio >= mae->nb_action_rule_prios_max) { + rc = EINVAL; + sfc_err(sa, "failed: invalid priority %d (max %u)", prio, + mae->nb_action_rule_prios_max); + goto fail_invalid_prio; + } + if (prio < 0) + prio = mae->nb_action_rule_prios_max - 1; + + rc = sfc_mae_internal_rule_find_empty_slot(sa, &rule); + if (rc != 0) + goto fail_find_empty_slot; + + sfc_log_init(sa, "init MAE match spec"); + rc = efx_mae_match_spec_init(sa->nic, EFX_MAE_RULE_ACTION, + (uint32_t)prio, &rule->spec); + if (rc != 0) { + sfc_err(sa, "failed to init MAE match spec"); + goto fail_match_init; + } + + rc = efx_mae_match_spec_mport_set(rule->spec, mport_match, NULL); + if (rc != 0) { + sfc_err(sa, "failed to get MAE match mport selector"); + goto fail_mport_set; + } + + rc = efx_mae_action_set_spec_init(sa->nic, &rule->actions); + if (rc != 0) { + sfc_err(sa, "failed to init MAE action set"); + goto fail_action_init; + } + + rc = efx_mae_action_set_populate_deliver(rule->actions, + mport_deliver); + if (rc != 0) { + sfc_err(sa, "failed to populate deliver action"); + goto fail_populate_deliver; + } + + rc = efx_mae_action_set_alloc(sa->nic, rule->actions, + &rule->action_set); + if (rc != 0) { + sfc_err(sa, "failed to allocate action set"); + goto fail_action_set_alloc; + } + + rc = efx_mae_action_rule_insert(sa->nic, rule->spec, NULL, + &rule->action_set, + &rule->rule_id); + if (rc != 0) { + sfc_err(sa, "failed to insert action rule"); + goto fail_rule_insert; + } + + *rulep = rule; + + sfc_log_init(sa, "done"); + + return 0; + +fail_rule_insert: + efx_mae_action_set_free(sa->nic, &rule->action_set); + +fail_action_set_alloc: +fail_populate_deliver: + efx_mae_action_set_spec_fini(sa->nic, rule->actions); + +fail_action_init: +fail_mport_set: + efx_mae_match_spec_fini(sa->nic, rule->spec); + +fail_match_init: +fail_find_empty_slot: +fail_invalid_prio: + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + return rc; +} + +void +sfc_mae_rule_del(struct sfc_adapter *sa, struct sfc_mae_rule *rule) +{ + if (rule == NULL || rule->spec == NULL) + return; + + efx_mae_action_rule_remove(sa->nic, &rule->rule_id); + efx_mae_action_set_free(sa->nic, &rule->action_set); + efx_mae_action_set_spec_fini(sa->nic, rule->actions); + efx_mae_match_spec_fini(sa->nic, rule->spec); + + rule->spec = NULL; +} + int sfc_mae_attach(struct sfc_adapter *sa) { @@ -3443,3 +3576,81 @@ sfc_mae_flow_query(struct rte_eth_dev *dev, "Query for action of this type is not supported"); } } + +int +sfc_mae_switchdev_init(struct sfc_adapter *sa) +{ + const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + struct sfc_mae *mae = &sa->mae; + efx_mport_sel_t pf; + efx_mport_sel_t phy; + int rc; + + sfc_log_init(sa, "entry"); + + if (!sa->switchdev) { + sfc_log_init(sa, "switchdev is not enabled - skip"); + return 0; + } + + if (mae->status != SFC_MAE_STATUS_SUPPORTED) { + rc = ENOTSUP; + sfc_err(sa, "failed to init switchdev - no MAE support"); + goto fail_no_mae; + } + + rc = efx_mae_mport_by_pcie_function(encp->enc_pf, EFX_PCI_VF_INVALID, + &pf); + if (rc != 0) { + sfc_err(sa, "failed get PF mport"); + goto fail_pf_get; + } + + rc = efx_mae_mport_by_phy_port(encp->enc_assigned_port, &phy); + if (rc != 0) { + sfc_err(sa, "failed get PHY mport"); + goto fail_phy_get; + } + + rc = sfc_mae_rule_add_mport_match_deliver(sa, &pf, &phy, + SFC_MAE_RULE_PRIO_LOWEST, + &mae->switchdev_rule_pf_to_ext); + if (rc != 0) { + sfc_err(sa, "failed add MAE rule to forward from PF to PHY"); + goto fail_pf_add; + } + + rc = sfc_mae_rule_add_mport_match_deliver(sa, &phy, &pf, + SFC_MAE_RULE_PRIO_LOWEST, + &mae->switchdev_rule_ext_to_pf); + if (rc != 0) { + sfc_err(sa, "failed add MAE rule to forward from PHY to PF"); + goto fail_phy_add; + } + + sfc_log_init(sa, "done"); + + return 0; + +fail_phy_add: + sfc_mae_rule_del(sa, mae->switchdev_rule_pf_to_ext); + +fail_pf_add: +fail_phy_get: +fail_pf_get: +fail_no_mae: + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + return rc; +} + +void +sfc_mae_switchdev_fini(struct sfc_adapter *sa) +{ + struct sfc_mae *mae = &sa->mae; + + if (!sa->switchdev) + return; + + sfc_mae_rule_del(sa, mae->switchdev_rule_pf_to_ext); + sfc_mae_rule_del(sa, mae->switchdev_rule_ext_to_pf); +} diff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h index 7e3b6a7a97..684f0daf7a 100644 --- a/drivers/net/sfc/sfc_mae.h +++ b/drivers/net/sfc/sfc_mae.h @@ -139,6 +139,26 @@ struct sfc_mae_counter_registry { uint32_t service_id; }; +/** Rules to forward traffic from PHY port to PF and from PF to PHY port */ +#define SFC_MAE_NB_SWITCHDEV_RULES (2) +/** Maximum required internal MAE rules */ +#define SFC_MAE_NB_RULES_MAX (SFC_MAE_NB_SWITCHDEV_RULES) + +struct sfc_mae_rule { + efx_mae_match_spec_t *spec; + efx_mae_actions_t *actions; + efx_mae_aset_id_t action_set; + efx_mae_rule_id_t rule_id; +}; + +struct sfc_mae_internal_rules { + /* + * Rules required to sustain switchdev mode or to provide + * port representor functionality. + */ + struct sfc_mae_rule rules[SFC_MAE_NB_RULES_MAX]; +}; + struct sfc_mae { /** Assigned switch domain identifier */ uint16_t switch_domain_id; @@ -164,6 +184,14 @@ struct sfc_mae { bool counter_rxq_running; /** Counter registry */ struct sfc_mae_counter_registry counter_registry; + /** Driver-internal flow rules */ + struct sfc_mae_internal_rules internal_rules; + /** + * Switchdev default rules. They forward traffic from PHY port + * to PF and vice versa. + */ + struct sfc_mae_rule *switchdev_rule_pf_to_ext; + struct sfc_mae_rule *switchdev_rule_ext_to_pf; }; struct sfc_adapter; @@ -306,6 +334,27 @@ sfc_flow_insert_cb_t sfc_mae_flow_insert; sfc_flow_remove_cb_t sfc_mae_flow_remove; sfc_flow_query_cb_t sfc_mae_flow_query; +/** + * The value used to represent the lowest priority. + * Used in MAE rule API. + */ +#define SFC_MAE_RULE_PRIO_LOWEST (-1) + +/** + * Insert a driver-internal flow rule that matches traffic originating from + * some m-port selector and redirects it to another one + * (eg. PF --> PHY, PHY --> PF). + * + * If requested priority is negative, use the lowest priority. + */ +int sfc_mae_rule_add_mport_match_deliver(struct sfc_adapter *sa, + const efx_mport_sel_t *mport_match, + const efx_mport_sel_t *mport_deliver, + int prio, struct sfc_mae_rule **rulep); +void sfc_mae_rule_del(struct sfc_adapter *sa, struct sfc_mae_rule *rule); +int sfc_mae_switchdev_init(struct sfc_adapter *sa); +void sfc_mae_switchdev_fini(struct sfc_adapter *sa); + #ifdef __cplusplus } #endif From patchwork Fri Aug 27 06:56:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97423 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 46FFAA0C43; Fri, 27 Aug 2021 08:58:14 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D29C841250; Fri, 27 Aug 2021 08:57:57 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 3A9B5410E9 for ; Fri, 27 Aug 2021 08:57:56 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 015337F563; Fri, 27 Aug 2021 09:57: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 4DB127F6D5; Fri, 27 Aug 2021 09:57:33 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 4DB127F6D5 Authentication-Results: shelob.oktetlabs.ru/4DB127F6D5; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:44 +0300 Message-Id: <20210827065717.1838258-6-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 05/38] common/sfc_efx/base: add an API to get mport ID by selector 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: Igor Romanov The mport ID is required to set appropriate egress mport ID in Tx prefix for port representor TxQ. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/common/sfc_efx/base/efx.h | 21 +++++++++ drivers/common/sfc_efx/base/efx_mae.c | 64 +++++++++++++++++++++++++++ drivers/common/sfc_efx/version.map | 1 + 3 files changed, 86 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 24e1314cc3..94803815ac 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -4181,6 +4181,19 @@ typedef struct efx_mport_sel_s { uint32_t sel; } efx_mport_sel_t; +/* + * MPORT ID. Used to refer dynamically to a specific MPORT. + * The difference between MPORT selector and MPORT ID is that + * selector can specify an exact MPORT ID or it can specify a + * pattern by which an exact MPORT ID can be selected. For example, + * static MPORT selector can specify MPORT of a current PF, which + * will be translated to the dynamic MPORT ID based on which PF is + * using that MPORT selector. + */ +typedef struct efx_mport_id_s { + uint32_t id; +} efx_mport_id_t; + #define EFX_MPORT_NULL (0U) /* @@ -4210,6 +4223,14 @@ efx_mae_mport_by_pcie_function( __in uint32_t vf, __out efx_mport_sel_t *mportp); +/* Get MPORT ID by an MPORT selector */ +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_mport_id_by_selector( + __in efx_nic_t *enp, + __in const efx_mport_sel_t *mport_selectorp, + __out efx_mport_id_t *mport_idp); + /* * Fields which have BE postfix in their named constants are expected * to be passed by callers in big-endian byte order. They will appear diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index c22206e227..b38b1143d6 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -731,6 +731,70 @@ efx_mae_mport_by_pcie_function( return (0); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + +static __checkReturn efx_rc_t +efx_mcdi_mae_mport_lookup( + __in efx_nic_t *enp, + __in const efx_mport_sel_t *mport_selectorp, + __out efx_mport_id_t *mport_idp) +{ + efx_mcdi_req_t req; + EFX_MCDI_DECLARE_BUF(payload, + MC_CMD_MAE_MPORT_LOOKUP_IN_LEN, + MC_CMD_MAE_MPORT_LOOKUP_OUT_LEN); + efx_rc_t rc; + + req.emr_cmd = MC_CMD_MAE_MPORT_LOOKUP; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_MAE_MPORT_LOOKUP_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_MAE_MPORT_LOOKUP_OUT_LEN; + + MCDI_IN_SET_DWORD(req, MAE_MPORT_LOOKUP_IN_MPORT_SELECTOR, + mport_selectorp->sel); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail1; + } + + mport_idp->id = MCDI_OUT_DWORD(req, MAE_MPORT_LOOKUP_OUT_MPORT_ID); + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mae_mport_id_by_selector( + __in efx_nic_t *enp, + __in const efx_mport_sel_t *mport_selectorp, + __out efx_mport_id_t *mport_idp) +{ + const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); + efx_rc_t rc; + + if (encp->enc_mae_supported == B_FALSE) { + rc = ENOTSUP; + goto fail1; + } + + rc = efx_mcdi_mae_mport_lookup(enp, mport_selectorp, mport_idp); + if (rc != 0) + goto fail2; + + return (0); + fail2: EFSYS_PROBE(fail2); fail1: diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 0c5bcdfa84..3dc21878c0 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -126,6 +126,7 @@ INTERNAL { efx_mae_match_specs_equal; efx_mae_mport_by_pcie_function; efx_mae_mport_by_phy_port; + efx_mae_mport_id_by_selector; efx_mae_outer_rule_insert; efx_mae_outer_rule_remove; From patchwork Fri Aug 27 06:56:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97424 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 4EB8CA0C43; Fri, 27 Aug 2021 08:58:22 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5B04941271; Fri, 27 Aug 2021 08:58:00 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 1E59D410E9 for ; Fri, 27 Aug 2021 08:57:57 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id DE1DA7F6FC; Fri, 27 Aug 2021 09:57:56 +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 6B2887F6D6; Fri, 27 Aug 2021 09:57:33 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 6B2887F6D6 Authentication-Results: shelob.oktetlabs.ru/6B2887F6D6; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:45 +0300 Message-Id: <20210827065717.1838258-7-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 06/38] net/sfc: support EF100 Tx override prefix 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: Igor Romanov Add internal mbuf dynamic flag and field to request EF100 native Tx datapath to use Tx prefix descriptor to override egress m-port. Overriding egress m-port is necessary on representor Tx burst so that the packet will reach corresponding VF. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_dp.c | 46 ++++++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_dp.h | 25 ++++++++++++++++++ drivers/net/sfc/sfc_ef100_tx.c | 25 ++++++++++++++++++ drivers/net/sfc/sfc_ethdev.c | 4 +++ 4 files changed, 100 insertions(+) diff --git a/drivers/net/sfc/sfc_dp.c b/drivers/net/sfc/sfc_dp.c index 24ed0898c8..66a84c99c8 100644 --- a/drivers/net/sfc/sfc_dp.c +++ b/drivers/net/sfc/sfc_dp.c @@ -12,6 +12,9 @@ #include #include +#include + +#include "efx.h" #include "sfc_dp.h" #include "sfc_log.h" @@ -77,3 +80,46 @@ sfc_dp_register(struct sfc_dp_list *head, struct sfc_dp *entry) return 0; } + +uint64_t sfc_dp_mport_override; +int sfc_dp_mport_offset = -1; + +int +sfc_dp_mport_register(void) +{ + static const struct rte_mbuf_dynfield mport = { + .name = "rte_net_sfc_dynfield_mport", + .size = sizeof(efx_mport_id_t), + .align = __alignof__(efx_mport_id_t), + }; + static const struct rte_mbuf_dynflag mport_override = { + .name = "rte_net_sfc_dynflag_mport_override", + }; + + int field_offset; + int flag; + + if (sfc_dp_mport_override != 0) { + SFC_GENERIC_LOG(INFO, "%s() already registered", __func__); + return 0; + } + + field_offset = rte_mbuf_dynfield_register(&mport); + if (field_offset < 0) { + SFC_GENERIC_LOG(ERR, "%s() failed to register mport dynfield", + __func__); + return -1; + } + + flag = rte_mbuf_dynflag_register(&mport_override); + if (flag < 0) { + SFC_GENERIC_LOG(ERR, "%s() failed to register mport dynflag", + __func__); + return -1; + } + + sfc_dp_mport_offset = field_offset; + sfc_dp_mport_override = UINT64_C(1) << flag; + + return 0; +} diff --git a/drivers/net/sfc/sfc_dp.h b/drivers/net/sfc/sfc_dp.h index 7fd8f34b0f..f3c6892426 100644 --- a/drivers/net/sfc/sfc_dp.h +++ b/drivers/net/sfc/sfc_dp.h @@ -126,6 +126,31 @@ struct sfc_dp *sfc_dp_find_by_caps(struct sfc_dp_list *head, unsigned int avail_caps); int sfc_dp_register(struct sfc_dp_list *head, struct sfc_dp *entry); +/** + * Dynamically registered mbuf flag "mport_override" (as a bitmask). + * + * If this flag is set in an mbuf then the dynamically registered + * mbuf field "mport" holds a valid value. This is used to direct + * port representor transmit traffic to the correct target port. + */ +extern uint64_t sfc_dp_mport_override; + +/** + * Dynamically registered mbuf field "mport" (mbuf byte offset). + * + * If the dynamically registered "mport_override" flag is set in + * an mbuf then the mbuf "mport" field holds a valid value. This + * is used to direct port representor transmit traffic to the + * correct target port. + */ +extern int sfc_dp_mport_offset; + +/** + * Register dynamic mbuf flag and field which can be used to require Tx override + * prefix descriptor with egress mport set. + */ +int sfc_dp_mport_register(void); + #ifdef __cplusplus } #endif diff --git a/drivers/net/sfc/sfc_ef100_tx.c b/drivers/net/sfc/sfc_ef100_tx.c index 522e9a0d34..51eecbe832 100644 --- a/drivers/net/sfc/sfc_ef100_tx.c +++ b/drivers/net/sfc/sfc_ef100_tx.c @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -309,6 +310,19 @@ sfc_ef100_tx_reap(struct sfc_ef100_txq *txq) sfc_ef100_tx_reap_num_descs(txq, sfc_ef100_tx_process_events(txq)); } +static void +sfc_ef100_tx_qdesc_prefix_create(const struct rte_mbuf *m, efx_oword_t *tx_desc) +{ + efx_mport_id_t *mport_id = + RTE_MBUF_DYNFIELD(m, sfc_dp_mport_offset, efx_mport_id_t *); + + EFX_POPULATE_OWORD_3(*tx_desc, + ESF_GZ_TX_PREFIX_EGRESS_MPORT, + mport_id->id, + ESF_GZ_TX_PREFIX_EGRESS_MPORT_EN, 1, + ESF_GZ_TX_DESC_TYPE, ESE_GZ_TX_DESC_TYPE_PREFIX); +} + static uint8_t sfc_ef100_tx_qdesc_cso_inner_l3(uint64_t tx_tunnel) { @@ -525,6 +539,11 @@ sfc_ef100_tx_pkt_descs_max(const struct rte_mbuf *m) SFC_MBUF_SEG_LEN_MAX)); } + if (m->ol_flags & sfc_dp_mport_override) { + /* Tx override prefix descriptor will be used */ + extra_descs++; + } + /* * Any segment of scattered packet cannot be bigger than maximum * segment length. Make sure that subsequent segments do not need @@ -671,6 +690,12 @@ sfc_ef100_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) break; } + if (m_seg->ol_flags & sfc_dp_mport_override) { + id = added++ & txq->ptr_mask; + sfc_ef100_tx_qdesc_prefix_create(m_seg, + &txq->txq_hw_ring[id]); + } + if (m_seg->ol_flags & PKT_TX_TCP_SEG) { m_seg = sfc_ef100_xmit_tso_pkt(txq, m_seg, &added); } else { diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 41add341a0..8e17189875 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -2245,6 +2245,10 @@ sfc_eth_dev_init(struct rte_eth_dev *dev) return 1; } + rc = sfc_dp_mport_register(); + if (rc != 0) + return rc; + sfc_register_dp(); logtype_main = sfc_register_logtype(&pci_dev->addr, From patchwork Fri Aug 27 06:56:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97427 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 517AEA0C43; Fri, 27 Aug 2021 08:58:40 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0101C4127F; Fri, 27 Aug 2021 08:58:06 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 2330E4126B for ; Fri, 27 Aug 2021 08:58:02 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id CF00D7F6CB; Fri, 27 Aug 2021 09:58:01 +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 888F87F6D7; Fri, 27 Aug 2021 09:57:33 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 888F87F6D7 Authentication-Results: shelob.oktetlabs.ru/888F87F6D7; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:46 +0300 Message-Id: <20210827065717.1838258-8-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 07/38] net/sfc: add representors proxy infrastructure 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: Igor Romanov Representor proxy is a mediator between virtual functions and port representors. It forwards traffic between virtual functions and port representors performing base PF ethdev + VF's representor traffic (de-)multiplexing. The implementation will be provided by later patches. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/meson.build | 1 + drivers/net/sfc/sfc.c | 35 ++++++ drivers/net/sfc/sfc.h | 5 + drivers/net/sfc/sfc_repr_proxy.c | 210 +++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_repr_proxy.h | 34 +++++ 5 files changed, 285 insertions(+) create mode 100644 drivers/net/sfc/sfc_repr_proxy.c create mode 100644 drivers/net/sfc/sfc_repr_proxy.h diff --git a/drivers/net/sfc/meson.build b/drivers/net/sfc/meson.build index 948c65968a..4fc2063f7a 100644 --- a/drivers/net/sfc/meson.build +++ b/drivers/net/sfc/meson.build @@ -97,4 +97,5 @@ sources = files( 'sfc_ef100_rx.c', 'sfc_ef100_tx.c', 'sfc_service.c', + 'sfc_repr_proxy.c', ) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index cd2c97f3b2..591b8971b3 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -27,6 +27,25 @@ #include "sfc_sw_stats.h" +bool +sfc_repr_supported(const struct sfc_adapter *sa) +{ + if (!sa->switchdev) + return false; + + /* + * Representor proxy should use service lcore on PF's socket + * (sa->socket_id) to be efficient. But the proxy will fall back + * to any socket if it is not possible to get the service core + * on the same socket. Check that at least service core on any + * socket is available. + */ + if (sfc_get_service_lcore(SOCKET_ID_ANY) == RTE_MAX_LCORE) + return false; + + return true; +} + int sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id, size_t len, int socket_id, efsys_mem_t *esmp) @@ -434,9 +453,16 @@ sfc_try_start(struct sfc_adapter *sa) if (rc != 0) goto fail_flows_insert; + rc = sfc_repr_proxy_start(sa); + if (rc != 0) + goto fail_repr_proxy_start; + sfc_log_init(sa, "done"); return 0; +fail_repr_proxy_start: + sfc_flow_stop(sa); + fail_flows_insert: sfc_tx_stop(sa); @@ -540,6 +566,7 @@ sfc_stop(struct sfc_adapter *sa) sa->state = SFC_ADAPTER_STOPPING; + sfc_repr_proxy_stop(sa); sfc_flow_stop(sa); sfc_tx_stop(sa); sfc_rx_stop(sa); @@ -899,6 +926,10 @@ sfc_attach(struct sfc_adapter *sa) if (rc != 0) goto fail_mae_switchdev_init; + rc = sfc_repr_proxy_attach(sa); + if (rc != 0) + goto fail_repr_proxy_attach; + sfc_log_init(sa, "fini nic"); efx_nic_fini(enp); @@ -927,6 +958,9 @@ sfc_attach(struct sfc_adapter *sa) fail_sw_xstats_init: sfc_flow_fini(sa); + sfc_repr_proxy_detach(sa); + +fail_repr_proxy_attach: sfc_mae_switchdev_fini(sa); fail_mae_switchdev_init: @@ -976,6 +1010,7 @@ sfc_detach(struct sfc_adapter *sa) sfc_flow_fini(sa); + sfc_repr_proxy_detach(sa); sfc_mae_switchdev_fini(sa); sfc_mae_detach(sa); sfc_mae_counter_rxq_detach(sa); diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index b045baca9e..8f65857f65 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -30,6 +30,8 @@ #include "sfc_sriov.h" #include "sfc_mae.h" #include "sfc_dp.h" +#include "sfc_repr_proxy.h" +#include "sfc_service.h" #ifdef __cplusplus extern "C" { @@ -260,6 +262,7 @@ struct sfc_adapter { struct sfc_sw_xstats sw_xstats; struct sfc_filter filter; struct sfc_mae mae; + struct sfc_repr_proxy repr_proxy; struct sfc_flow_list flow_list; @@ -388,6 +391,8 @@ sfc_nb_counter_rxq(const struct sfc_adapter_shared *sas) return sas->counters_rxq_allocated ? 1 : 0; } +bool sfc_repr_supported(const struct sfc_adapter *sa); + /** Get the number of milliseconds since boot from the default timer */ static inline uint64_t sfc_get_system_msecs(void) diff --git a/drivers/net/sfc/sfc_repr_proxy.c b/drivers/net/sfc/sfc_repr_proxy.c new file mode 100644 index 0000000000..eb29376988 --- /dev/null +++ b/drivers/net/sfc/sfc_repr_proxy.c @@ -0,0 +1,210 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019-2021 Xilinx, Inc. + * Copyright(c) 2019 Solarflare Communications Inc. + * + * This software was jointly developed between OKTET Labs (under contract + * for Solarflare) and Solarflare Communications, Inc. + */ + +#include +#include + +#include "sfc_log.h" +#include "sfc_service.h" +#include "sfc_repr_proxy.h" +#include "sfc.h" + +static int32_t +sfc_repr_proxy_routine(void *arg) +{ + struct sfc_repr_proxy *rp = arg; + + /* Representor proxy boilerplate will be here */ + RTE_SET_USED(rp); + + return 0; +} + +int +sfc_repr_proxy_attach(struct sfc_adapter *sa) +{ + struct sfc_repr_proxy *rp = &sa->repr_proxy; + struct rte_service_spec service; + uint32_t cid; + uint32_t sid; + int rc; + + sfc_log_init(sa, "entry"); + + if (!sfc_repr_supported(sa)) { + sfc_log_init(sa, "representors not supported - skip"); + return 0; + } + + cid = sfc_get_service_lcore(sa->socket_id); + if (cid == RTE_MAX_LCORE && sa->socket_id != SOCKET_ID_ANY) { + /* Warn and try to allocate on any NUMA node */ + sfc_warn(sa, + "repr proxy: unable to get service lcore at socket %d", + sa->socket_id); + + cid = sfc_get_service_lcore(SOCKET_ID_ANY); + } + if (cid == RTE_MAX_LCORE) { + rc = ENOTSUP; + sfc_err(sa, "repr proxy: failed to get service lcore"); + goto fail_get_service_lcore; + } + + memset(&service, 0, sizeof(service)); + snprintf(service.name, sizeof(service.name), + "net_sfc_%hu_repr_proxy", sfc_sa2shared(sa)->port_id); + service.socket_id = rte_lcore_to_socket_id(cid); + service.callback = sfc_repr_proxy_routine; + service.callback_userdata = rp; + + rc = rte_service_component_register(&service, &sid); + if (rc != 0) { + rc = ENOEXEC; + sfc_err(sa, "repr proxy: failed to register service component"); + goto fail_register; + } + + rc = rte_service_map_lcore_set(sid, cid, 1); + if (rc != 0) { + rc = -rc; + sfc_err(sa, "repr proxy: failed to map lcore"); + goto fail_map_lcore; + } + + rp->service_core_id = cid; + rp->service_id = sid; + + sfc_log_init(sa, "done"); + + return 0; + +fail_map_lcore: + rte_service_component_unregister(sid); + +fail_register: + /* + * No need to rollback service lcore get since + * it just makes socket_id based search and remembers it. + */ + +fail_get_service_lcore: + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + return rc; +} + +void +sfc_repr_proxy_detach(struct sfc_adapter *sa) +{ + struct sfc_repr_proxy *rp = &sa->repr_proxy; + + sfc_log_init(sa, "entry"); + + if (!sfc_repr_supported(sa)) { + sfc_log_init(sa, "representors not supported - skip"); + return; + } + + rte_service_map_lcore_set(rp->service_id, rp->service_core_id, 0); + rte_service_component_unregister(rp->service_id); + + sfc_log_init(sa, "done"); +} + +int +sfc_repr_proxy_start(struct sfc_adapter *sa) +{ + struct sfc_repr_proxy *rp = &sa->repr_proxy; + int rc; + + sfc_log_init(sa, "entry"); + + /* + * The condition to start the proxy is insufficient. It will be + * complemented with representor port start/stop support. + */ + if (!sfc_repr_supported(sa)) { + sfc_log_init(sa, "representors not supported - skip"); + return 0; + } + + /* Service core may be in "stopped" state, start it */ + rc = rte_service_lcore_start(rp->service_core_id); + if (rc != 0 && rc != -EALREADY) { + rc = -rc; + sfc_err(sa, "failed to start service core for %s: %s", + rte_service_get_name(rp->service_id), + rte_strerror(rc)); + goto fail_start_core; + } + + /* Run the service */ + rc = rte_service_component_runstate_set(rp->service_id, 1); + if (rc < 0) { + rc = -rc; + sfc_err(sa, "failed to run %s component: %s", + rte_service_get_name(rp->service_id), + rte_strerror(rc)); + goto fail_component_runstate_set; + } + rc = rte_service_runstate_set(rp->service_id, 1); + if (rc < 0) { + rc = -rc; + sfc_err(sa, "failed to run %s: %s", + rte_service_get_name(rp->service_id), + rte_strerror(rc)); + goto fail_runstate_set; + } + + sfc_log_init(sa, "done"); + + return 0; + +fail_runstate_set: + rte_service_component_runstate_set(rp->service_id, 0); + +fail_component_runstate_set: + /* Service lcore may be shared and we never stop it */ + +fail_start_core: + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + return rc; +} + +void +sfc_repr_proxy_stop(struct sfc_adapter *sa) +{ + struct sfc_repr_proxy *rp = &sa->repr_proxy; + int rc; + + sfc_log_init(sa, "entry"); + + if (!sfc_repr_supported(sa)) { + sfc_log_init(sa, "representors not supported - skip"); + return; + } + + rc = rte_service_runstate_set(rp->service_id, 0); + if (rc < 0) { + sfc_err(sa, "failed to stop %s: %s", + rte_service_get_name(rp->service_id), + rte_strerror(-rc)); + } + + rc = rte_service_component_runstate_set(rp->service_id, 0); + if (rc < 0) { + sfc_err(sa, "failed to stop %s component: %s", + rte_service_get_name(rp->service_id), + rte_strerror(-rc)); + } + + /* Service lcore may be shared and we never stop it */ + + sfc_log_init(sa, "done"); +} diff --git a/drivers/net/sfc/sfc_repr_proxy.h b/drivers/net/sfc/sfc_repr_proxy.h new file mode 100644 index 0000000000..40ce352335 --- /dev/null +++ b/drivers/net/sfc/sfc_repr_proxy.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019-2021 Xilinx, Inc. + * Copyright(c) 2019 Solarflare Communications Inc. + * + * This software was jointly developed between OKTET Labs (under contract + * for Solarflare) and Solarflare Communications, Inc. + */ + +#ifndef _SFC_REPR_PROXY_H +#define _SFC_REPR_PROXY_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct sfc_repr_proxy { + uint32_t service_core_id; + uint32_t service_id; +}; + +struct sfc_adapter; + +int sfc_repr_proxy_attach(struct sfc_adapter *sa); +void sfc_repr_proxy_detach(struct sfc_adapter *sa); +int sfc_repr_proxy_start(struct sfc_adapter *sa); +void sfc_repr_proxy_stop(struct sfc_adapter *sa); + +#ifdef __cplusplus +} +#endif +#endif /* _SFC_REPR_PROXY_H */ From patchwork Fri Aug 27 06:56:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97425 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 EE2E7A0C43; Fri, 27 Aug 2021 08:58:27 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8E6D04126C; Fri, 27 Aug 2021 08:58:03 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id F059040DF4 for ; Fri, 27 Aug 2021 08:58:01 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id C7FD67F6FC; Fri, 27 Aug 2021 09:58:01 +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 A1D577F6D8; Fri, 27 Aug 2021 09:57:33 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru A1D577F6D8 Authentication-Results: shelob.oktetlabs.ru/A1D577F6D8; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:47 +0300 Message-Id: <20210827065717.1838258-9-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 08/38] net/sfc: reserve TxQ and RxQ for port representors 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: Igor Romanov A Tx/Rx queue pair is required to forward traffic between port representors and virtual functions. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc.c | 51 ++++++++++++++++++++++++++++++-- drivers/net/sfc/sfc.h | 15 ++++++++++ drivers/net/sfc/sfc_ev.h | 40 ++++++++++++++++++------- drivers/net/sfc/sfc_repr_proxy.c | 12 +++++--- drivers/net/sfc/sfc_repr_proxy.h | 8 +++++ drivers/net/sfc/sfc_tx.c | 29 ++++++++++-------- 6 files changed, 124 insertions(+), 31 deletions(-) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 591b8971b3..9abd6d600b 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -46,6 +46,12 @@ sfc_repr_supported(const struct sfc_adapter *sa) return true; } +bool +sfc_repr_available(const struct sfc_adapter_shared *sas) +{ + return sas->nb_repr_rxq > 0 && sas->nb_repr_txq > 0; +} + int sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id, size_t len, int socket_id, efsys_mem_t *esmp) @@ -296,6 +302,41 @@ sfc_estimate_resource_limits(struct sfc_adapter *sa) sas->counters_rxq_allocated = false; } + if (sfc_repr_supported(sa) && + evq_allocated >= SFC_REPR_PROXY_NB_RXQ_MIN + + SFC_REPR_PROXY_NB_TXQ_MIN && + rxq_allocated >= SFC_REPR_PROXY_NB_RXQ_MIN && + txq_allocated >= SFC_REPR_PROXY_NB_TXQ_MIN) { + unsigned int extra; + + txq_allocated -= SFC_REPR_PROXY_NB_TXQ_MIN; + rxq_allocated -= SFC_REPR_PROXY_NB_RXQ_MIN; + evq_allocated -= SFC_REPR_PROXY_NB_RXQ_MIN + + SFC_REPR_PROXY_NB_TXQ_MIN; + + sas->nb_repr_rxq = SFC_REPR_PROXY_NB_RXQ_MIN; + sas->nb_repr_txq = SFC_REPR_PROXY_NB_TXQ_MIN; + + /* Allocate extra representor RxQs up to the maximum */ + extra = MIN(evq_allocated, rxq_allocated); + extra = MIN(extra, + SFC_REPR_PROXY_NB_RXQ_MAX - sas->nb_repr_rxq); + evq_allocated -= extra; + rxq_allocated -= extra; + sas->nb_repr_rxq += extra; + + /* Allocate extra representor TxQs up to the maximum */ + extra = MIN(evq_allocated, txq_allocated); + extra = MIN(extra, + SFC_REPR_PROXY_NB_TXQ_MAX - sas->nb_repr_txq); + evq_allocated -= extra; + txq_allocated -= extra; + sas->nb_repr_txq += extra; + } else { + sas->nb_repr_rxq = 0; + sas->nb_repr_txq = 0; + } + /* Add remaining allocated queues */ sa->rxq_max += MIN(rxq_allocated, evq_allocated / 2); sa->txq_max += MIN(txq_allocated, evq_allocated - sa->rxq_max); @@ -313,8 +354,10 @@ sfc_estimate_resource_limits(struct sfc_adapter *sa) static int sfc_set_drv_limits(struct sfc_adapter *sa) { + struct sfc_adapter_shared *sas = sfc_sa2shared(sa); const struct rte_eth_dev_data *data = sa->eth_dev->data; - uint32_t rxq_reserved = sfc_nb_reserved_rxq(sfc_sa2shared(sa)); + uint32_t rxq_reserved = sfc_nb_reserved_rxq(sas); + uint32_t txq_reserved = sfc_nb_txq_reserved(sas); efx_drv_limits_t lim; memset(&lim, 0, sizeof(lim)); @@ -325,10 +368,12 @@ sfc_set_drv_limits(struct sfc_adapter *sa) * sfc_estimate_resource_limits(). */ lim.edl_min_evq_count = lim.edl_max_evq_count = - 1 + data->nb_rx_queues + data->nb_tx_queues + rxq_reserved; + 1 + data->nb_rx_queues + data->nb_tx_queues + + rxq_reserved + txq_reserved; lim.edl_min_rxq_count = lim.edl_max_rxq_count = data->nb_rx_queues + rxq_reserved; - lim.edl_min_txq_count = lim.edl_max_txq_count = data->nb_tx_queues; + lim.edl_min_txq_count = lim.edl_max_txq_count = + data->nb_tx_queues + txq_reserved; return efx_nic_set_drv_limits(sa->nic, &lim); } diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 8f65857f65..79f9d7979e 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -191,6 +191,8 @@ struct sfc_adapter_shared { char *dp_tx_name; bool counters_rxq_allocated; + unsigned int nb_repr_rxq; + unsigned int nb_repr_txq; }; /* Adapter process private data */ @@ -392,6 +394,19 @@ sfc_nb_counter_rxq(const struct sfc_adapter_shared *sas) } bool sfc_repr_supported(const struct sfc_adapter *sa); +bool sfc_repr_available(const struct sfc_adapter_shared *sas); + +static inline unsigned int +sfc_repr_nb_rxq(const struct sfc_adapter_shared *sas) +{ + return sas->nb_repr_rxq; +} + +static inline unsigned int +sfc_repr_nb_txq(const struct sfc_adapter_shared *sas) +{ + return sas->nb_repr_txq; +} /** Get the number of milliseconds since boot from the default timer */ static inline uint64_t diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h index b2a0380205..590cfb1694 100644 --- a/drivers/net/sfc/sfc_ev.h +++ b/drivers/net/sfc/sfc_ev.h @@ -70,14 +70,21 @@ sfc_mgmt_evq_sw_index(__rte_unused const struct sfc_adapter_shared *sas) static inline unsigned int sfc_nb_reserved_rxq(const struct sfc_adapter_shared *sas) { - return sfc_nb_counter_rxq(sas); + return sfc_nb_counter_rxq(sas) + sfc_repr_nb_rxq(sas); +} + +/* Return the number of Tx queues reserved for driver's internal use */ +static inline unsigned int +sfc_nb_txq_reserved(const struct sfc_adapter_shared *sas) +{ + return sfc_repr_nb_txq(sas); } static inline unsigned int sfc_nb_reserved_evq(const struct sfc_adapter_shared *sas) { - /* An EvQ is required for each reserved RxQ */ - return 1 + sfc_nb_reserved_rxq(sas); + /* An EvQ is required for each reserved Rx/Tx queue */ + return 1 + sfc_nb_reserved_rxq(sas) + sfc_nb_txq_reserved(sas); } /* @@ -112,6 +119,7 @@ sfc_counters_rxq_sw_index(const struct sfc_adapter_shared *sas) * Own event queue is allocated for management, each Rx and each Tx queue. * Zero event queue is used for management events. * When counters are supported, one Rx event queue is reserved. + * When representors are supported, Rx and Tx event queues are reserved. * Rx event queues follow reserved event queues. * Tx event queues follow Rx event queues. */ @@ -150,27 +158,37 @@ sfc_evq_sw_index_by_rxq_sw_index(struct sfc_adapter *sa, } static inline sfc_ethdev_qid_t -sfc_ethdev_tx_qid_by_txq_sw_index(__rte_unused struct sfc_adapter_shared *sas, +sfc_ethdev_tx_qid_by_txq_sw_index(struct sfc_adapter_shared *sas, sfc_sw_index_t txq_sw_index) { - /* Only ethdev queues are present for now */ - return txq_sw_index; + if (txq_sw_index < sfc_nb_txq_reserved(sas)) + return SFC_ETHDEV_QID_INVALID; + + return txq_sw_index - sfc_nb_txq_reserved(sas); } static inline sfc_sw_index_t -sfc_txq_sw_index_by_ethdev_tx_qid(__rte_unused struct sfc_adapter_shared *sas, +sfc_txq_sw_index_by_ethdev_tx_qid(struct sfc_adapter_shared *sas, sfc_ethdev_qid_t ethdev_qid) { - /* Only ethdev queues are present for now */ - return ethdev_qid; + return sfc_nb_txq_reserved(sas) + ethdev_qid; } static inline sfc_sw_index_t sfc_evq_sw_index_by_txq_sw_index(struct sfc_adapter *sa, sfc_sw_index_t txq_sw_index) { - return sfc_nb_reserved_evq(sfc_sa2shared(sa)) + - sa->eth_dev->data->nb_rx_queues + txq_sw_index; + struct sfc_adapter_shared *sas = sfc_sa2shared(sa); + sfc_ethdev_qid_t ethdev_qid; + + ethdev_qid = sfc_ethdev_tx_qid_by_txq_sw_index(sas, txq_sw_index); + if (ethdev_qid == SFC_ETHDEV_QID_INVALID) { + return sfc_nb_reserved_evq(sas) - sfc_nb_txq_reserved(sas) + + txq_sw_index; + } + + return sfc_nb_reserved_evq(sas) + sa->eth_dev->data->nb_rx_queues + + ethdev_qid; } int sfc_ev_attach(struct sfc_adapter *sa); diff --git a/drivers/net/sfc/sfc_repr_proxy.c b/drivers/net/sfc/sfc_repr_proxy.c index eb29376988..6d3962304f 100644 --- a/drivers/net/sfc/sfc_repr_proxy.c +++ b/drivers/net/sfc/sfc_repr_proxy.c @@ -29,6 +29,7 @@ sfc_repr_proxy_routine(void *arg) int sfc_repr_proxy_attach(struct sfc_adapter *sa) { + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); struct sfc_repr_proxy *rp = &sa->repr_proxy; struct rte_service_spec service; uint32_t cid; @@ -37,7 +38,7 @@ sfc_repr_proxy_attach(struct sfc_adapter *sa) sfc_log_init(sa, "entry"); - if (!sfc_repr_supported(sa)) { + if (!sfc_repr_available(sas)) { sfc_log_init(sa, "representors not supported - skip"); return 0; } @@ -102,11 +103,12 @@ sfc_repr_proxy_attach(struct sfc_adapter *sa) void sfc_repr_proxy_detach(struct sfc_adapter *sa) { + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); struct sfc_repr_proxy *rp = &sa->repr_proxy; sfc_log_init(sa, "entry"); - if (!sfc_repr_supported(sa)) { + if (!sfc_repr_available(sas)) { sfc_log_init(sa, "representors not supported - skip"); return; } @@ -120,6 +122,7 @@ sfc_repr_proxy_detach(struct sfc_adapter *sa) int sfc_repr_proxy_start(struct sfc_adapter *sa) { + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); struct sfc_repr_proxy *rp = &sa->repr_proxy; int rc; @@ -129,7 +132,7 @@ sfc_repr_proxy_start(struct sfc_adapter *sa) * The condition to start the proxy is insufficient. It will be * complemented with representor port start/stop support. */ - if (!sfc_repr_supported(sa)) { + if (!sfc_repr_available(sas)) { sfc_log_init(sa, "representors not supported - skip"); return 0; } @@ -180,12 +183,13 @@ sfc_repr_proxy_start(struct sfc_adapter *sa) void sfc_repr_proxy_stop(struct sfc_adapter *sa) { + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); struct sfc_repr_proxy *rp = &sa->repr_proxy; int rc; sfc_log_init(sa, "entry"); - if (!sfc_repr_supported(sa)) { + if (!sfc_repr_available(sas)) { sfc_log_init(sa, "representors not supported - skip"); return; } diff --git a/drivers/net/sfc/sfc_repr_proxy.h b/drivers/net/sfc/sfc_repr_proxy.h index 40ce352335..953b9922c8 100644 --- a/drivers/net/sfc/sfc_repr_proxy.h +++ b/drivers/net/sfc/sfc_repr_proxy.h @@ -16,6 +16,14 @@ extern "C" { #endif +/* Number of supported RxQs with different mbuf memory pools */ +#define SFC_REPR_PROXY_NB_RXQ_MIN (1) +#define SFC_REPR_PROXY_NB_RXQ_MAX (1) + +/* One TxQ is required and sufficient for port representors support */ +#define SFC_REPR_PROXY_NB_TXQ_MIN (1) +#define SFC_REPR_PROXY_NB_TXQ_MAX (1) + struct sfc_repr_proxy { uint32_t service_core_id; uint32_t service_id; diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c index 49b239f4d2..c1b2e964f8 100644 --- a/drivers/net/sfc/sfc_tx.c +++ b/drivers/net/sfc/sfc_tx.c @@ -376,6 +376,8 @@ sfc_tx_configure(struct sfc_adapter *sa) const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); const struct rte_eth_conf *dev_conf = &sa->eth_dev->data->dev_conf; const unsigned int nb_tx_queues = sa->eth_dev->data->nb_tx_queues; + const unsigned int nb_rsvd_tx_queues = sfc_nb_txq_reserved(sas); + const unsigned int nb_txq_total = nb_tx_queues + nb_rsvd_tx_queues; int rc = 0; sfc_log_init(sa, "nb_tx_queues=%u (old %u)", @@ -395,11 +397,11 @@ sfc_tx_configure(struct sfc_adapter *sa) if (rc != 0) goto fail_check_mode; - if (nb_tx_queues == sas->txq_count) + if (nb_txq_total == sas->txq_count) goto done; if (sas->txq_info == NULL) { - sas->txq_info = rte_calloc_socket("sfc-txqs", nb_tx_queues, + sas->txq_info = rte_calloc_socket("sfc-txqs", nb_txq_total, sizeof(sas->txq_info[0]), 0, sa->socket_id); if (sas->txq_info == NULL) @@ -410,7 +412,7 @@ sfc_tx_configure(struct sfc_adapter *sa) * since it should not be shared. */ rc = ENOMEM; - sa->txq_ctrl = calloc(nb_tx_queues, sizeof(sa->txq_ctrl[0])); + sa->txq_ctrl = calloc(nb_txq_total, sizeof(sa->txq_ctrl[0])); if (sa->txq_ctrl == NULL) goto fail_txqs_ctrl_alloc; } else { @@ -422,23 +424,23 @@ sfc_tx_configure(struct sfc_adapter *sa) new_txq_info = rte_realloc(sas->txq_info, - nb_tx_queues * sizeof(sas->txq_info[0]), 0); - if (new_txq_info == NULL && nb_tx_queues > 0) + nb_txq_total * sizeof(sas->txq_info[0]), 0); + if (new_txq_info == NULL && nb_txq_total > 0) goto fail_txqs_realloc; new_txq_ctrl = realloc(sa->txq_ctrl, - nb_tx_queues * sizeof(sa->txq_ctrl[0])); - if (new_txq_ctrl == NULL && nb_tx_queues > 0) + nb_txq_total * sizeof(sa->txq_ctrl[0])); + if (new_txq_ctrl == NULL && nb_txq_total > 0) goto fail_txqs_ctrl_realloc; sas->txq_info = new_txq_info; sa->txq_ctrl = new_txq_ctrl; - if (nb_tx_queues > sas->ethdev_txq_count) { - memset(&sas->txq_info[sas->ethdev_txq_count], 0, - (nb_tx_queues - sas->ethdev_txq_count) * + if (nb_txq_total > sas->txq_count) { + memset(&sas->txq_info[sas->txq_count], 0, + (nb_txq_total - sas->txq_count) * sizeof(sas->txq_info[0])); - memset(&sa->txq_ctrl[sas->ethdev_txq_count], 0, - (nb_tx_queues - sas->ethdev_txq_count) * + memset(&sa->txq_ctrl[sas->txq_count], 0, + (nb_txq_total - sas->txq_count) * sizeof(sa->txq_ctrl[0])); } } @@ -455,7 +457,8 @@ sfc_tx_configure(struct sfc_adapter *sa) sas->ethdev_txq_count++; } - sas->txq_count = sas->ethdev_txq_count; + /* TODO: initialize reserved queues when supported. */ + sas->txq_count = sas->ethdev_txq_count + nb_rsvd_tx_queues; done: return 0; From patchwork Fri Aug 27 06:56:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97426 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 BD985A0C43; Fri, 27 Aug 2021 08:58:33 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B267341279; Fri, 27 Aug 2021 08:58:04 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 0C4BC411E9 for ; Fri, 27 Aug 2021 08:58:02 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id CB4DC7F6D6; Fri, 27 Aug 2021 09:58:01 +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 BB83F7F6D9; Fri, 27 Aug 2021 09:57:33 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru BB83F7F6D9 Authentication-Results: shelob.oktetlabs.ru/BB83F7F6D9; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:48 +0300 Message-Id: <20210827065717.1838258-10-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 09/38] net/sfc: move adapter state enum to separate header 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: Igor Romanov Adapter state will be reused by representors, that will have a separate adapter. Rename adapter state to ethdev state so that the meaning of it is clearer. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc.c | 47 ++++++++++--------- drivers/net/sfc/sfc.h | 54 +--------------------- drivers/net/sfc/sfc_ethdev.c | 40 ++++++++--------- drivers/net/sfc/sfc_ethdev_state.h | 72 ++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_flow.c | 10 ++--- drivers/net/sfc/sfc_intr.c | 12 ++--- drivers/net/sfc/sfc_mae.c | 2 +- drivers/net/sfc/sfc_port.c | 2 +- 8 files changed, 130 insertions(+), 109 deletions(-) create mode 100644 drivers/net/sfc/sfc_ethdev_state.h diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 9abd6d600b..152234cb61 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -26,7 +26,6 @@ #include "sfc_tweak.h" #include "sfc_sw_stats.h" - bool sfc_repr_supported(const struct sfc_adapter *sa) { @@ -440,7 +439,7 @@ sfc_try_start(struct sfc_adapter *sa) sfc_log_init(sa, "entry"); SFC_ASSERT(sfc_adapter_is_locked(sa)); - SFC_ASSERT(sa->state == SFC_ADAPTER_STARTING); + SFC_ASSERT(sa->state == SFC_ETHDEV_STARTING); sfc_log_init(sa, "set FW subvariant"); rc = sfc_set_fw_subvariant(sa); @@ -545,9 +544,9 @@ sfc_start(struct sfc_adapter *sa) SFC_ASSERT(sfc_adapter_is_locked(sa)); switch (sa->state) { - case SFC_ADAPTER_CONFIGURED: + case SFC_ETHDEV_CONFIGURED: break; - case SFC_ADAPTER_STARTED: + case SFC_ETHDEV_STARTED: sfc_notice(sa, "already started"); return 0; default: @@ -555,7 +554,7 @@ sfc_start(struct sfc_adapter *sa) goto fail_bad_state; } - sa->state = SFC_ADAPTER_STARTING; + sa->state = SFC_ETHDEV_STARTING; rc = 0; do { @@ -578,13 +577,13 @@ sfc_start(struct sfc_adapter *sa) if (rc != 0) goto fail_try_start; - sa->state = SFC_ADAPTER_STARTED; + sa->state = SFC_ETHDEV_STARTED; sfc_log_init(sa, "done"); return 0; fail_try_start: fail_sriov_vswitch_create: - sa->state = SFC_ADAPTER_CONFIGURED; + sa->state = SFC_ETHDEV_CONFIGURED; fail_bad_state: sfc_log_init(sa, "failed %d", rc); return rc; @@ -598,9 +597,9 @@ sfc_stop(struct sfc_adapter *sa) SFC_ASSERT(sfc_adapter_is_locked(sa)); switch (sa->state) { - case SFC_ADAPTER_STARTED: + case SFC_ETHDEV_STARTED: break; - case SFC_ADAPTER_CONFIGURED: + case SFC_ETHDEV_CONFIGURED: sfc_notice(sa, "already stopped"); return; default: @@ -609,7 +608,7 @@ sfc_stop(struct sfc_adapter *sa) return; } - sa->state = SFC_ADAPTER_STOPPING; + sa->state = SFC_ETHDEV_STOPPING; sfc_repr_proxy_stop(sa); sfc_flow_stop(sa); @@ -620,7 +619,7 @@ sfc_stop(struct sfc_adapter *sa) sfc_intr_stop(sa); efx_nic_fini(sa->nic); - sa->state = SFC_ADAPTER_CONFIGURED; + sa->state = SFC_ETHDEV_CONFIGURED; sfc_log_init(sa, "done"); } @@ -631,7 +630,7 @@ sfc_restart(struct sfc_adapter *sa) SFC_ASSERT(sfc_adapter_is_locked(sa)); - if (sa->state != SFC_ADAPTER_STARTED) + if (sa->state != SFC_ETHDEV_STARTED) return EINVAL; sfc_stop(sa); @@ -652,7 +651,7 @@ sfc_restart_if_required(void *arg) if (rte_atomic32_cmpset((volatile uint32_t *)&sa->restart_required, 1, 0)) { sfc_adapter_lock(sa); - if (sa->state == SFC_ADAPTER_STARTED) + if (sa->state == SFC_ETHDEV_STARTED) (void)sfc_restart(sa); sfc_adapter_unlock(sa); } @@ -685,9 +684,9 @@ sfc_configure(struct sfc_adapter *sa) SFC_ASSERT(sfc_adapter_is_locked(sa)); - SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED || - sa->state == SFC_ADAPTER_CONFIGURED); - sa->state = SFC_ADAPTER_CONFIGURING; + SFC_ASSERT(sa->state == SFC_ETHDEV_INITIALIZED || + sa->state == SFC_ETHDEV_CONFIGURED); + sa->state = SFC_ETHDEV_CONFIGURING; rc = sfc_check_conf(sa); if (rc != 0) @@ -713,7 +712,7 @@ sfc_configure(struct sfc_adapter *sa) if (rc != 0) goto fail_sw_xstats_configure; - sa->state = SFC_ADAPTER_CONFIGURED; + sa->state = SFC_ETHDEV_CONFIGURED; sfc_log_init(sa, "done"); return 0; @@ -731,7 +730,7 @@ sfc_configure(struct sfc_adapter *sa) fail_intr_configure: fail_check_conf: - sa->state = SFC_ADAPTER_INITIALIZED; + sa->state = SFC_ETHDEV_INITIALIZED; sfc_log_init(sa, "failed %d", rc); return rc; } @@ -743,8 +742,8 @@ sfc_close(struct sfc_adapter *sa) SFC_ASSERT(sfc_adapter_is_locked(sa)); - SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED); - sa->state = SFC_ADAPTER_CLOSING; + SFC_ASSERT(sa->state == SFC_ETHDEV_CONFIGURED); + sa->state = SFC_ETHDEV_CLOSING; sfc_sw_xstats_close(sa); sfc_tx_close(sa); @@ -752,7 +751,7 @@ sfc_close(struct sfc_adapter *sa) sfc_port_close(sa); sfc_intr_close(sa); - sa->state = SFC_ADAPTER_INITIALIZED; + sa->state = SFC_ETHDEV_INITIALIZED; sfc_log_init(sa, "done"); } @@ -993,7 +992,7 @@ sfc_attach(struct sfc_adapter *sa) if (rc != 0) goto fail_sriov_vswitch_create; - sa->state = SFC_ADAPTER_INITIALIZED; + sa->state = SFC_ETHDEV_INITIALIZED; sfc_log_init(sa, "done"); return 0; @@ -1067,7 +1066,7 @@ sfc_detach(struct sfc_adapter *sa) efx_tunnel_fini(sa->nic); sfc_sriov_detach(sa); - sa->state = SFC_ADAPTER_UNINITIALIZED; + sa->state = SFC_ETHDEV_UNINITIALIZED; } static int @@ -1325,7 +1324,7 @@ sfc_unprobe(struct sfc_adapter *sa) sfc_mem_bar_fini(sa); sfc_flow_fini(sa); - sa->state = SFC_ADAPTER_UNINITIALIZED; + sa->state = SFC_ETHDEV_UNINITIALIZED; } uint32_t diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 79f9d7979e..628f32c13f 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -32,62 +32,12 @@ #include "sfc_dp.h" #include "sfc_repr_proxy.h" #include "sfc_service.h" +#include "sfc_ethdev_state.h" #ifdef __cplusplus extern "C" { #endif -/* - * +---------------+ - * | UNINITIALIZED |<-----------+ - * +---------------+ | - * |.eth_dev_init |.eth_dev_uninit - * V | - * +---------------+------------+ - * | INITIALIZED | - * +---------------+<-----------<---------------+ - * |.dev_configure | | - * V |failed | - * +---------------+------------+ | - * | CONFIGURING | | - * +---------------+----+ | - * |success | | - * | | +---------------+ - * | | | CLOSING | - * | | +---------------+ - * | | ^ - * V |.dev_configure | - * +---------------+----+ |.dev_close - * | CONFIGURED |----------------------------+ - * +---------------+<-----------+ - * |.dev_start | - * V | - * +---------------+ | - * | STARTING |------------^ - * +---------------+ failed | - * |success | - * | +---------------+ - * | | STOPPING | - * | +---------------+ - * | ^ - * V |.dev_stop - * +---------------+------------+ - * | STARTED | - * +---------------+ - */ -enum sfc_adapter_state { - SFC_ADAPTER_UNINITIALIZED = 0, - SFC_ADAPTER_INITIALIZED, - SFC_ADAPTER_CONFIGURING, - SFC_ADAPTER_CONFIGURED, - SFC_ADAPTER_CLOSING, - SFC_ADAPTER_STARTING, - SFC_ADAPTER_STARTED, - SFC_ADAPTER_STOPPING, - - SFC_ADAPTER_NSTATES -}; - enum sfc_dev_filter_mode { SFC_DEV_FILTER_MODE_PROMISC = 0, SFC_DEV_FILTER_MODE_ALLMULTI, @@ -245,7 +195,7 @@ struct sfc_adapter { * change its state should acquire the lock. */ rte_spinlock_t lock; - enum sfc_adapter_state state; + enum sfc_ethdev_state state; struct rte_eth_dev *eth_dev; struct rte_kvargs *kvargs; int socket_id; diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 8e17189875..ff762bb90b 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -213,9 +213,9 @@ sfc_dev_configure(struct rte_eth_dev *dev) sfc_adapter_lock(sa); switch (sa->state) { - case SFC_ADAPTER_CONFIGURED: + case SFC_ETHDEV_CONFIGURED: /* FALLTHROUGH */ - case SFC_ADAPTER_INITIALIZED: + case SFC_ETHDEV_INITIALIZED: rc = sfc_configure(sa); break; default: @@ -257,7 +257,7 @@ sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete) sfc_log_init(sa, "entry"); - if (sa->state != SFC_ADAPTER_STARTED) { + if (sa->state != SFC_ETHDEV_STARTED) { sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, ¤t_link); } else if (wait_to_complete) { efx_link_mode_t link_mode; @@ -346,15 +346,15 @@ sfc_dev_close(struct rte_eth_dev *dev) sfc_adapter_lock(sa); switch (sa->state) { - case SFC_ADAPTER_STARTED: + case SFC_ETHDEV_STARTED: sfc_stop(sa); - SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED); + SFC_ASSERT(sa->state == SFC_ETHDEV_CONFIGURED); /* FALLTHROUGH */ - case SFC_ADAPTER_CONFIGURED: + case SFC_ETHDEV_CONFIGURED: sfc_close(sa); - SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED); + SFC_ASSERT(sa->state == SFC_ETHDEV_INITIALIZED); /* FALLTHROUGH */ - case SFC_ADAPTER_INITIALIZED: + case SFC_ETHDEV_INITIALIZED: break; default: sfc_err(sa, "unexpected adapter state %u on close", sa->state); @@ -410,7 +410,7 @@ sfc_dev_filter_set(struct rte_eth_dev *dev, enum sfc_dev_filter_mode mode, sfc_warn(sa, "the change is to be applied on the next " "start provided that isolated mode is " "disabled prior the next start"); - } else if ((sa->state == SFC_ADAPTER_STARTED) && + } else if ((sa->state == SFC_ETHDEV_STARTED) && ((rc = sfc_set_rx_mode(sa)) != 0)) { *toggle = !(enabled); sfc_warn(sa, "Failed to %s %s mode, rc = %d", @@ -704,7 +704,7 @@ sfc_stats_reset(struct rte_eth_dev *dev) sfc_adapter_lock(sa); - if (sa->state != SFC_ADAPTER_STARTED) { + if (sa->state != SFC_ETHDEV_STARTED) { /* * The operation cannot be done if port is not started; it * will be scheduled to be done during the next port start @@ -905,7 +905,7 @@ sfc_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) sfc_adapter_lock(sa); - if (sa->state == SFC_ADAPTER_STARTED) + if (sa->state == SFC_ETHDEV_STARTED) efx_mac_fcntl_get(sa->nic, &wanted_fc, &link_fc); else link_fc = sa->port.flow_ctrl; @@ -971,7 +971,7 @@ sfc_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) sfc_adapter_lock(sa); - if (sa->state == SFC_ADAPTER_STARTED) { + if (sa->state == SFC_ETHDEV_STARTED) { rc = efx_mac_fcntl_set(sa->nic, fcntl, fc_conf->autoneg); if (rc != 0) goto fail_mac_fcntl_set; @@ -1051,7 +1051,7 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) goto fail_check_scatter; if (pdu != sa->port.pdu) { - if (sa->state == SFC_ADAPTER_STARTED) { + if (sa->state == SFC_ETHDEV_STARTED) { sfc_stop(sa); old_pdu = sa->port.pdu; @@ -1128,7 +1128,7 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) goto unlock; } - if (sa->state != SFC_ADAPTER_STARTED) { + if (sa->state != SFC_ETHDEV_STARTED) { sfc_notice(sa, "the port is not started"); sfc_notice(sa, "the new MAC address will be set on port start"); @@ -1215,7 +1215,7 @@ sfc_set_mc_addr_list(struct rte_eth_dev *dev, port->nb_mcast_addrs = nb_mc_addr; - if (sa->state != SFC_ADAPTER_STARTED) + if (sa->state != SFC_ETHDEV_STARTED) return 0; rc = efx_mac_multicast_list_set(sa->nic, port->mcast_addrs, @@ -1356,7 +1356,7 @@ sfc_rx_queue_start(struct rte_eth_dev *dev, uint16_t ethdev_qid) sfc_adapter_lock(sa); rc = EINVAL; - if (sa->state != SFC_ADAPTER_STARTED) + if (sa->state != SFC_ETHDEV_STARTED) goto fail_not_started; rxq_info = sfc_rxq_info_by_ethdev_qid(sas, sfc_ethdev_qid); @@ -1420,7 +1420,7 @@ sfc_tx_queue_start(struct rte_eth_dev *dev, uint16_t ethdev_qid) sfc_adapter_lock(sa); rc = EINVAL; - if (sa->state != SFC_ADAPTER_STARTED) + if (sa->state != SFC_ETHDEV_STARTED) goto fail_not_started; txq_info = sfc_txq_info_by_ethdev_qid(sas, ethdev_qid); @@ -1528,7 +1528,7 @@ sfc_dev_udp_tunnel_op(struct rte_eth_dev *dev, if (rc != 0) goto fail_op; - if (sa->state == SFC_ADAPTER_STARTED) { + if (sa->state == SFC_ETHDEV_STARTED) { rc = efx_tunnel_reconfigure(sa->nic); if (rc == EAGAIN) { /* @@ -1664,7 +1664,7 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, } if (rss_conf->rss_key != NULL) { - if (sa->state == SFC_ADAPTER_STARTED) { + if (sa->state == SFC_ETHDEV_STARTED) { for (key_i = 0; key_i < n_contexts; key_i++) { rc = efx_rx_scale_key_set(sa->nic, contexts[key_i], @@ -1791,7 +1791,7 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, } } - if (sa->state == SFC_ADAPTER_STARTED) { + if (sa->state == SFC_ETHDEV_STARTED) { rc = efx_rx_scale_tbl_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, rss_tbl_new, EFX_RSS_TBL_SIZE); if (rc != 0) diff --git a/drivers/net/sfc/sfc_ethdev_state.h b/drivers/net/sfc/sfc_ethdev_state.h new file mode 100644 index 0000000000..51fb51e20e --- /dev/null +++ b/drivers/net/sfc/sfc_ethdev_state.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019-2021 Xilinx, Inc. + * Copyright(c) 2019 Solarflare Communications Inc. + * + * This software was jointly developed between OKTET Labs (under contract + * for Solarflare) and Solarflare Communications, Inc. + */ + +#ifndef _SFC_ETHDEV_STATE_H +#define _SFC_ETHDEV_STATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * +---------------+ + * | UNINITIALIZED |<-----------+ + * +---------------+ | + * |.eth_dev_init |.eth_dev_uninit + * V | + * +---------------+------------+ + * | INITIALIZED | + * +---------------+<-----------<---------------+ + * |.dev_configure | | + * V |failed | + * +---------------+------------+ | + * | CONFIGURING | | + * +---------------+----+ | + * |success | | + * | | +---------------+ + * | | | CLOSING | + * | | +---------------+ + * | | ^ + * V |.dev_configure | + * +---------------+----+ |.dev_close + * | CONFIGURED |----------------------------+ + * +---------------+<-----------+ + * |.dev_start | + * V | + * +---------------+ | + * | STARTING |------------^ + * +---------------+ failed | + * |success | + * | +---------------+ + * | | STOPPING | + * | +---------------+ + * | ^ + * V |.dev_stop + * +---------------+------------+ + * | STARTED | + * +---------------+ + */ +enum sfc_ethdev_state { + SFC_ETHDEV_UNINITIALIZED = 0, + SFC_ETHDEV_INITIALIZED, + SFC_ETHDEV_CONFIGURING, + SFC_ETHDEV_CONFIGURED, + SFC_ETHDEV_CLOSING, + SFC_ETHDEV_STARTING, + SFC_ETHDEV_STARTED, + SFC_ETHDEV_STOPPING, + + SFC_ETHDEV_NSTATES +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _SFC_ETHDEV_STATE_H */ diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 4f5993a68d..36ee79f331 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -2724,7 +2724,7 @@ sfc_flow_create(struct rte_eth_dev *dev, TAILQ_INSERT_TAIL(&sa->flow_list, flow, entries); - if (sa->state == SFC_ADAPTER_STARTED) { + if (sa->state == SFC_ETHDEV_STARTED) { rc = sfc_flow_insert(sa, flow, error); if (rc != 0) goto fail_flow_insert; @@ -2767,7 +2767,7 @@ sfc_flow_destroy(struct rte_eth_dev *dev, goto fail_bad_value; } - if (sa->state == SFC_ADAPTER_STARTED) + if (sa->state == SFC_ETHDEV_STARTED) rc = sfc_flow_remove(sa, flow, error); TAILQ_REMOVE(&sa->flow_list, flow, entries); @@ -2790,7 +2790,7 @@ sfc_flow_flush(struct rte_eth_dev *dev, sfc_adapter_lock(sa); while ((flow = TAILQ_FIRST(&sa->flow_list)) != NULL) { - if (sa->state == SFC_ADAPTER_STARTED) { + if (sa->state == SFC_ETHDEV_STARTED) { int rc; rc = sfc_flow_remove(sa, flow, error); @@ -2828,7 +2828,7 @@ sfc_flow_query(struct rte_eth_dev *dev, goto fail_no_backend; } - if (sa->state != SFC_ADAPTER_STARTED) { + if (sa->state != SFC_ETHDEV_STARTED) { ret = rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "Can't query the flow: the adapter is not started"); @@ -2858,7 +2858,7 @@ sfc_flow_isolate(struct rte_eth_dev *dev, int enable, int ret = 0; sfc_adapter_lock(sa); - if (sa->state != SFC_ADAPTER_INITIALIZED) { + if (sa->state != SFC_ETHDEV_INITIALIZED) { rte_flow_error_set(error, EBUSY, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "please close the port first"); diff --git a/drivers/net/sfc/sfc_intr.c b/drivers/net/sfc/sfc_intr.c index c2298ed23c..69414fd839 100644 --- a/drivers/net/sfc/sfc_intr.c +++ b/drivers/net/sfc/sfc_intr.c @@ -60,9 +60,9 @@ sfc_intr_line_handler(void *cb_arg) sfc_log_init(sa, "entry"); - if (sa->state != SFC_ADAPTER_STARTED && - sa->state != SFC_ADAPTER_STARTING && - sa->state != SFC_ADAPTER_STOPPING) { + if (sa->state != SFC_ETHDEV_STARTED && + sa->state != SFC_ETHDEV_STARTING && + sa->state != SFC_ETHDEV_STOPPING) { sfc_log_init(sa, "interrupt on stopped adapter, don't reenable"); goto exit; @@ -106,9 +106,9 @@ sfc_intr_message_handler(void *cb_arg) sfc_log_init(sa, "entry"); - if (sa->state != SFC_ADAPTER_STARTED && - sa->state != SFC_ADAPTER_STARTING && - sa->state != SFC_ADAPTER_STOPPING) { + if (sa->state != SFC_ETHDEV_STARTED && + sa->state != SFC_ETHDEV_STARTING && + sa->state != SFC_ETHDEV_STOPPING) { sfc_log_init(sa, "adapter not-started, don't reenable"); goto exit; } diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index b3607a178b..7be77054ab 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -3414,7 +3414,7 @@ sfc_mae_flow_verify(struct sfc_adapter *sa, SFC_ASSERT(sfc_adapter_is_locked(sa)); - if (sa->state != SFC_ADAPTER_STARTED) + if (sa->state != SFC_ETHDEV_STARTED) return EAGAIN; if (outer_rule != NULL) { diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c index adb2b2cb81..7a3f59a112 100644 --- a/drivers/net/sfc/sfc_port.c +++ b/drivers/net/sfc/sfc_port.c @@ -48,7 +48,7 @@ sfc_port_update_mac_stats(struct sfc_adapter *sa, boolean_t force_upload) SFC_ASSERT(sfc_adapter_is_locked(sa)); - if (sa->state != SFC_ADAPTER_STARTED) + if (sa->state != SFC_ETHDEV_STARTED) return 0; /* From patchwork Fri Aug 27 06:56:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97428 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 307E5A0C43; Fri, 27 Aug 2021 08:58:48 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9AD6641270; Fri, 27 Aug 2021 08:58:08 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id C0E2341288 for ; Fri, 27 Aug 2021 08:58:07 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 863F07F6D7; Fri, 27 Aug 2021 09:58:07 +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 D68447F6DA; Fri, 27 Aug 2021 09:57:33 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru D68447F6DA Authentication-Results: shelob.oktetlabs.ru/D68447F6DA; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , Andy Moreton Date: Fri, 27 Aug 2021 09:56:49 +0300 Message-Id: <20210827065717.1838258-11-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 10/38] common/sfc_efx/base: allow creating invalid mport selectors 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: Viacheslav Galaktionov There isn't always a valid mport that can be used. For these cases, special invalid selectors can be generated. Requests that use such selectors in any way will be rejected. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx.h | 11 +++++++++++ drivers/common/sfc_efx/base/efx_mae.c | 25 +++++++++++++++++++++++++ drivers/common/sfc_efx/version.map | 1 + 3 files changed, 37 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 94803815ac..c0d1535017 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -4196,6 +4196,17 @@ typedef struct efx_mport_id_s { #define EFX_MPORT_NULL (0U) +/* + * Generate an invalid MPORT selector. + * + * The resulting MPORT selector is opaque to the caller. Requests + * that attempt to use it will be rejected. + */ +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_mport_invalid( + __out efx_mport_sel_t *mportp); + /* * Get MPORT selector of a physical port. * diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index b38b1143d6..b7afe8fdc8 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -660,6 +660,31 @@ static const efx_mae_mv_bit_desc_t __efx_mae_action_rule_mv_bit_desc_set[] = { #undef EFX_MAE_MV_BIT_DESC }; + __checkReturn efx_rc_t +efx_mae_mport_invalid( + __out efx_mport_sel_t *mportp) +{ + efx_dword_t dword; + efx_rc_t rc; + + if (mportp == NULL) { + rc = EINVAL; + goto fail1; + } + + EFX_POPULATE_DWORD_1(dword, + MAE_MPORT_SELECTOR_TYPE, MAE_MPORT_SELECTOR_TYPE_INVALID); + + memset(mportp, 0, sizeof (*mportp)); + mportp->sel = dword.ed_u32[0]; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + __checkReturn efx_rc_t efx_mae_mport_by_phy_port( __in uint32_t phy_port, diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 3dc21878c0..611757ccde 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -127,6 +127,7 @@ INTERNAL { efx_mae_mport_by_pcie_function; efx_mae_mport_by_phy_port; efx_mae_mport_id_by_selector; + efx_mae_mport_invalid; efx_mae_outer_rule_insert; efx_mae_outer_rule_remove; From patchwork Fri Aug 27 06:56:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97429 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 81A2CA0C43; Fri, 27 Aug 2021 08:58:54 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D92404128B; Fri, 27 Aug 2021 08:58:09 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id C150641289 for ; Fri, 27 Aug 2021 08:58:07 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 8FAC47F6D3; Fri, 27 Aug 2021 09:58:07 +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 F13707F6DB; Fri, 27 Aug 2021 09:57:33 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru F13707F6DB Authentication-Results: shelob.oktetlabs.ru/F13707F6DB; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:50 +0300 Message-Id: <20210827065717.1838258-12-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 11/38] net/sfc: add port representors infrastructure 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: Igor Romanov Provide minimal implementation for port representors that only can be configured and can provide device information. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- doc/guides/nics/sfc_efx.rst | 13 +- drivers/net/sfc/meson.build | 1 + drivers/net/sfc/sfc_ethdev.c | 156 +++++++++++- drivers/net/sfc/sfc_kvargs.c | 1 + drivers/net/sfc/sfc_kvargs.h | 2 + drivers/net/sfc/sfc_repr.c | 458 +++++++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_repr.h | 36 +++ drivers/net/sfc/sfc_switch.h | 5 + 8 files changed, 663 insertions(+), 9 deletions(-) create mode 100644 drivers/net/sfc/sfc_repr.c create mode 100644 drivers/net/sfc/sfc_repr.h diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst index d66cb76dab..4719031508 100644 --- a/doc/guides/nics/sfc_efx.rst +++ b/doc/guides/nics/sfc_efx.rst @@ -74,6 +74,8 @@ SFC EFX PMD has support for: - SR-IOV PF +- Port representors (see :ref: switch_representation) + Non-supported Features ---------------------- @@ -382,7 +384,16 @@ boolean parameters value. software virtual switch (for example, Open vSwitch) makes the decision. Software virtual switch may install MAE rules to pass established traffic flows via hardware and offload software datapath as the result. - Default is legacy. + Default is legacy, unless representors are specified, in which case switchdev + is chosen. + +- ``representor`` parameter [list] + + Instantiate port representor Ethernet devices for specified Virtual + Functions list. + + It is a standard parameter whose format is described in + :ref:`ethernet_device_standard_device_arguments`. - ``rx_datapath`` [auto|efx|ef10|ef10_essb] (default **auto**) diff --git a/drivers/net/sfc/meson.build b/drivers/net/sfc/meson.build index 4fc2063f7a..98365e9e73 100644 --- a/drivers/net/sfc/meson.build +++ b/drivers/net/sfc/meson.build @@ -98,4 +98,5 @@ sources = files( 'sfc_ef100_tx.c', 'sfc_service.c', 'sfc_repr_proxy.c', + 'sfc_repr.c', ) diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index ff762bb90b..8308cbdfef 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -28,6 +28,7 @@ #include "sfc_flow.h" #include "sfc_dp.h" #include "sfc_dp_rx.h" +#include "sfc_repr.h" #include "sfc_sw_stats.h" #define SFC_XSTAT_ID_INVALID_VAL UINT64_MAX @@ -1908,6 +1909,10 @@ static const struct eth_dev_ops sfc_eth_dev_ops = { .pool_ops_supported = sfc_pool_ops_supported, }; +struct sfc_ethdev_init_data { + uint16_t nb_representors; +}; + /** * Duplicate a string in potentially shared memory required for * multi-process support. @@ -2189,7 +2194,7 @@ sfc_register_dp(void) } static int -sfc_parse_switch_mode(struct sfc_adapter *sa) +sfc_parse_switch_mode(struct sfc_adapter *sa, bool has_representors) { const char *switch_mode = NULL; int rc; @@ -2201,9 +2206,9 @@ sfc_parse_switch_mode(struct sfc_adapter *sa) if (rc != 0) goto fail_kvargs; - /* Check representors when supported */ - if (switch_mode == NULL || - strcasecmp(switch_mode, SFC_KVARG_SWITCH_MODE_LEGACY) == 0) { + if (switch_mode == NULL) { + sa->switchdev = has_representors; + } else if (strcasecmp(switch_mode, SFC_KVARG_SWITCH_MODE_LEGACY) == 0) { sa->switchdev = false; } else if (strcasecmp(switch_mode, SFC_KVARG_SWITCH_MODE_SWITCHDEV) == 0) { @@ -2227,10 +2232,11 @@ sfc_parse_switch_mode(struct sfc_adapter *sa) } static int -sfc_eth_dev_init(struct rte_eth_dev *dev) +sfc_eth_dev_init(struct rte_eth_dev *dev, void *init_params) { struct sfc_adapter_shared *sas = sfc_adapter_shared_by_eth_dev(dev); struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct sfc_ethdev_init_data *init_data = init_params; uint32_t logtype_main; struct sfc_adapter *sa; int rc; @@ -2312,7 +2318,7 @@ sfc_eth_dev_init(struct rte_eth_dev *dev) sfc_adapter_lock_init(sa); sfc_adapter_lock(sa); - rc = sfc_parse_switch_mode(sa); + rc = sfc_parse_switch_mode(sa, init_data->nb_representors > 0); if (rc != 0) goto fail_switch_mode; @@ -2402,11 +2408,145 @@ static const struct rte_pci_id pci_id_sfc_efx_map[] = { { .vendor_id = 0 /* sentinel */ } }; +static int +sfc_parse_rte_devargs(const char *args, struct rte_eth_devargs *devargs) +{ + struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 }; + int rc; + + if (args != NULL) { + rc = rte_eth_devargs_parse(args, ð_da); + if (rc != 0) { + SFC_GENERIC_LOG(ERR, + "Failed to parse generic devargs '%s'", + args); + return rc; + } + } + + *devargs = eth_da; + + return 0; +} + +static int +sfc_eth_dev_create(struct rte_pci_device *pci_dev, + struct sfc_ethdev_init_data *init_data, + struct rte_eth_dev **devp) +{ + struct rte_eth_dev *dev; + int rc; + + rc = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name, + sizeof(struct sfc_adapter_shared), + eth_dev_pci_specific_init, pci_dev, + sfc_eth_dev_init, init_data); + if (rc != 0) { + SFC_GENERIC_LOG(ERR, "Failed to create sfc ethdev '%s'", + pci_dev->device.name); + return rc; + } + + dev = rte_eth_dev_allocated(pci_dev->device.name); + if (dev == NULL) { + SFC_GENERIC_LOG(ERR, "Failed to find allocated sfc ethdev '%s'", + pci_dev->device.name); + return -ENODEV; + } + + *devp = dev; + + return 0; +} + +static int +sfc_eth_dev_create_representors(struct rte_eth_dev *dev, + const struct rte_eth_devargs *eth_da) +{ + struct sfc_adapter *sa; + unsigned int i; + int rc; + + if (eth_da->nb_representor_ports == 0) + return 0; + + sa = sfc_adapter_by_eth_dev(dev); + + if (!sa->switchdev) { + sfc_err(sa, "cannot create representors in non-switchdev mode"); + return -EINVAL; + } + + if (!sfc_repr_available(sfc_sa2shared(sa))) { + sfc_err(sa, "cannot create representors: unsupported"); + + return -ENOTSUP; + } + + for (i = 0; i < eth_da->nb_representor_ports; ++i) { + const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + efx_mport_sel_t mport_sel; + + rc = efx_mae_mport_by_pcie_function(encp->enc_pf, + eth_da->representor_ports[i], &mport_sel); + if (rc != 0) { + sfc_err(sa, + "failed to get representor %u m-port: %s - ignore", + eth_da->representor_ports[i], + rte_strerror(-rc)); + continue; + } + + rc = sfc_repr_create(dev, eth_da->representor_ports[i], + sa->mae.switch_domain_id, &mport_sel); + if (rc != 0) { + sfc_err(sa, "cannot create representor %u: %s - ignore", + eth_da->representor_ports[i], + rte_strerror(-rc)); + } + } + + return 0; +} + static int sfc_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct rte_pci_device *pci_dev) { - return rte_eth_dev_pci_generic_probe(pci_dev, - sizeof(struct sfc_adapter_shared), sfc_eth_dev_init); + struct sfc_ethdev_init_data init_data; + struct rte_eth_devargs eth_da; + struct rte_eth_dev *dev; + int rc; + + if (pci_dev->device.devargs != NULL) { + rc = sfc_parse_rte_devargs(pci_dev->device.devargs->args, + ð_da); + if (rc != 0) + return rc; + } else { + memset(ð_da, 0, sizeof(eth_da)); + } + + init_data.nb_representors = eth_da.nb_representor_ports; + + if (eth_da.nb_representor_ports > 0 && + rte_eal_process_type() != RTE_PROC_PRIMARY) { + SFC_GENERIC_LOG(ERR, + "Create representors from secondary process not supported, dev '%s'", + pci_dev->device.name); + return -ENOTSUP; + } + + rc = sfc_eth_dev_create(pci_dev, &init_data, &dev); + if (rc != 0) + return rc; + + rc = sfc_eth_dev_create_representors(dev, ð_da); + if (rc != 0) { + (void)rte_eth_dev_destroy(dev, sfc_eth_dev_uninit); + return rc; + } + + return 0; } static int sfc_eth_dev_pci_remove(struct rte_pci_device *pci_dev) diff --git a/drivers/net/sfc/sfc_kvargs.c b/drivers/net/sfc/sfc_kvargs.c index cd16213637..783cb43ae6 100644 --- a/drivers/net/sfc/sfc_kvargs.c +++ b/drivers/net/sfc/sfc_kvargs.c @@ -23,6 +23,7 @@ sfc_kvargs_parse(struct sfc_adapter *sa) struct rte_devargs *devargs = eth_dev->device->devargs; const char **params = (const char *[]){ SFC_KVARG_SWITCH_MODE, + SFC_KVARG_REPRESENTOR, SFC_KVARG_STATS_UPDATE_PERIOD_MS, SFC_KVARG_PERF_PROFILE, SFC_KVARG_RX_DATAPATH, diff --git a/drivers/net/sfc/sfc_kvargs.h b/drivers/net/sfc/sfc_kvargs.h index 8e34ec92a2..2226f2b3d9 100644 --- a/drivers/net/sfc/sfc_kvargs.h +++ b/drivers/net/sfc/sfc_kvargs.h @@ -26,6 +26,8 @@ extern "C" { "[" SFC_KVARG_SWITCH_MODE_LEGACY "|" \ SFC_KVARG_SWITCH_MODE_SWITCHDEV "]" +#define SFC_KVARG_REPRESENTOR "representor" + #define SFC_KVARG_PERF_PROFILE "perf_profile" #define SFC_KVARG_PERF_PROFILE_AUTO "auto" diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c new file mode 100644 index 0000000000..603a613ec6 --- /dev/null +++ b/drivers/net/sfc/sfc_repr.c @@ -0,0 +1,458 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019-2021 Xilinx, Inc. + * Copyright(c) 2019 Solarflare Communications Inc. + * + * This software was jointly developed between OKTET Labs (under contract + * for Solarflare) and Solarflare Communications, Inc. + */ + +#include + +#include +#include +#include + +#include "efx.h" + +#include "sfc_log.h" +#include "sfc_debug.h" +#include "sfc_repr.h" +#include "sfc_ethdev_state.h" +#include "sfc_switch.h" + +/** Multi-process shared representor private data */ +struct sfc_repr_shared { + uint16_t pf_port_id; + uint16_t repr_id; + uint16_t switch_domain_id; + uint16_t switch_port_id; +}; + +/** Primary process representor private data */ +struct sfc_repr { + /** + * PMD setup and configuration is not thread safe. Since it is not + * performance sensitive, it is better to guarantee thread-safety + * and add device level lock. Adapter control operations which + * change its state should acquire the lock. + */ + rte_spinlock_t lock; + enum sfc_ethdev_state state; +}; + +#define sfcr_err(sr, ...) \ + do { \ + const struct sfc_repr *_sr = (sr); \ + \ + (void)_sr; \ + SFC_GENERIC_LOG(ERR, __VA_ARGS__); \ + } while (0) + +#define sfcr_info(sr, ...) \ + do { \ + const struct sfc_repr *_sr = (sr); \ + \ + (void)_sr; \ + SFC_GENERIC_LOG(INFO, \ + RTE_FMT("%s() " \ + RTE_FMT_HEAD(__VA_ARGS__ ,), \ + __func__, \ + RTE_FMT_TAIL(__VA_ARGS__ ,))); \ + } while (0) + +static inline struct sfc_repr_shared * +sfc_repr_shared_by_eth_dev(struct rte_eth_dev *eth_dev) +{ + struct sfc_repr_shared *srs = eth_dev->data->dev_private; + + return srs; +} + +static inline struct sfc_repr * +sfc_repr_by_eth_dev(struct rte_eth_dev *eth_dev) +{ + struct sfc_repr *sr = eth_dev->process_private; + + return sr; +} + +/* + * Add wrapper functions to acquire/release lock to be able to remove or + * change the lock in one place. + */ + +static inline void +sfc_repr_lock_init(struct sfc_repr *sr) +{ + rte_spinlock_init(&sr->lock); +} + +#ifdef RTE_LIBRTE_SFC_EFX_DEBUG + +static inline int +sfc_repr_lock_is_locked(struct sfc_repr *sr) +{ + return rte_spinlock_is_locked(&sr->lock); +} + +#endif + +static inline void +sfc_repr_lock(struct sfc_repr *sr) +{ + rte_spinlock_lock(&sr->lock); +} + +static inline void +sfc_repr_unlock(struct sfc_repr *sr) +{ + rte_spinlock_unlock(&sr->lock); +} + +static inline void +sfc_repr_lock_fini(__rte_unused struct sfc_repr *sr) +{ + /* Just for symmetry of the API */ +} + +static int +sfc_repr_check_conf(struct sfc_repr *sr, uint16_t nb_rx_queues, + const struct rte_eth_conf *conf) +{ + const struct rte_eth_rss_conf *rss_conf; + int ret = 0; + + sfcr_info(sr, "entry"); + + if (conf->link_speeds != 0) { + sfcr_err(sr, "specific link speeds not supported"); + ret = -EINVAL; + } + + switch (conf->rxmode.mq_mode) { + case ETH_MQ_RX_RSS: + if (nb_rx_queues != 1) { + sfcr_err(sr, "Rx RSS is not supported with %u queues", + nb_rx_queues); + ret = -EINVAL; + break; + } + + rss_conf = &conf->rx_adv_conf.rss_conf; + if (rss_conf->rss_key != NULL || rss_conf->rss_key_len != 0 || + rss_conf->rss_hf != 0) { + sfcr_err(sr, "Rx RSS configuration is not supported"); + ret = -EINVAL; + } + break; + case ETH_MQ_RX_NONE: + break; + default: + sfcr_err(sr, "Rx mode MQ modes other than RSS not supported"); + ret = -EINVAL; + break; + } + + if (conf->txmode.mq_mode != ETH_MQ_TX_NONE) { + sfcr_err(sr, "Tx mode MQ modes not supported"); + ret = -EINVAL; + } + + if (conf->lpbk_mode != 0) { + sfcr_err(sr, "loopback not supported"); + ret = -EINVAL; + } + + if (conf->dcb_capability_en != 0) { + sfcr_err(sr, "priority-based flow control not supported"); + ret = -EINVAL; + } + + if (conf->fdir_conf.mode != RTE_FDIR_MODE_NONE) { + sfcr_err(sr, "Flow Director not supported"); + ret = -EINVAL; + } + + if (conf->intr_conf.lsc != 0) { + sfcr_err(sr, "link status change interrupt not supported"); + ret = -EINVAL; + } + + if (conf->intr_conf.rxq != 0) { + sfcr_err(sr, "receive queue interrupt not supported"); + ret = -EINVAL; + } + + if (conf->intr_conf.rmv != 0) { + sfcr_err(sr, "remove interrupt not supported"); + ret = -EINVAL; + } + + sfcr_info(sr, "done %d", ret); + + return ret; +} + + +static int +sfc_repr_configure(struct sfc_repr *sr, uint16_t nb_rx_queues, + const struct rte_eth_conf *conf) +{ + int ret; + + sfcr_info(sr, "entry"); + + SFC_ASSERT(sfc_repr_lock_is_locked(sr)); + + ret = sfc_repr_check_conf(sr, nb_rx_queues, conf); + if (ret != 0) + goto fail_check_conf; + + sr->state = SFC_ETHDEV_CONFIGURED; + + sfcr_info(sr, "done"); + + return 0; + +fail_check_conf: + sfcr_info(sr, "failed %s", rte_strerror(-ret)); + return ret; +} + +static int +sfc_repr_dev_configure(struct rte_eth_dev *dev) +{ + struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); + struct rte_eth_dev_data *dev_data = dev->data; + int ret; + + sfcr_info(sr, "entry n_rxq=%u n_txq=%u", + dev_data->nb_rx_queues, dev_data->nb_tx_queues); + + sfc_repr_lock(sr); + switch (sr->state) { + case SFC_ETHDEV_CONFIGURED: + /* FALLTHROUGH */ + case SFC_ETHDEV_INITIALIZED: + ret = sfc_repr_configure(sr, dev_data->nb_rx_queues, + &dev_data->dev_conf); + break; + default: + sfcr_err(sr, "unexpected adapter state %u to configure", + sr->state); + ret = -EINVAL; + break; + } + sfc_repr_unlock(sr); + + sfcr_info(sr, "done %s", rte_strerror(-ret)); + + return ret; +} + +static int +sfc_repr_dev_infos_get(struct rte_eth_dev *dev, + struct rte_eth_dev_info *dev_info) +{ + struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); + + dev_info->device = dev->device; + + dev_info->max_rx_queues = SFC_REPR_RXQ_MAX; + dev_info->max_tx_queues = SFC_REPR_TXQ_MAX; + dev_info->default_rxconf.rx_drop_en = 1; + dev_info->switch_info.domain_id = srs->switch_domain_id; + dev_info->switch_info.port_id = srs->switch_port_id; + + return 0; +} + +static void +sfc_repr_close(struct sfc_repr *sr) +{ + SFC_ASSERT(sfc_repr_lock_is_locked(sr)); + + SFC_ASSERT(sr->state == SFC_ETHDEV_CONFIGURED); + sr->state = SFC_ETHDEV_CLOSING; + + /* Put representor close actions here */ + + sr->state = SFC_ETHDEV_INITIALIZED; +} + +static int +sfc_repr_dev_close(struct rte_eth_dev *dev) +{ + struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); + + sfcr_info(sr, "entry"); + + sfc_repr_lock(sr); + switch (sr->state) { + case SFC_ETHDEV_CONFIGURED: + sfc_repr_close(sr); + SFC_ASSERT(sr->state == SFC_ETHDEV_INITIALIZED); + /* FALLTHROUGH */ + case SFC_ETHDEV_INITIALIZED: + break; + default: + sfcr_err(sr, "unexpected adapter state %u on close", sr->state); + break; + } + + /* + * Cleanup all resources. + * Rollback primary process sfc_repr_eth_dev_init() below. + */ + + dev->dev_ops = NULL; + + sfc_repr_unlock(sr); + sfc_repr_lock_fini(sr); + + sfcr_info(sr, "done"); + + free(sr); + + return 0; +} + +static const struct eth_dev_ops sfc_repr_dev_ops = { + .dev_configure = sfc_repr_dev_configure, + .dev_close = sfc_repr_dev_close, + .dev_infos_get = sfc_repr_dev_infos_get, +}; + + +struct sfc_repr_init_data { + uint16_t pf_port_id; + uint16_t repr_id; + uint16_t switch_domain_id; + efx_mport_sel_t mport_sel; +}; + +static int +sfc_repr_assign_mae_switch_port(uint16_t switch_domain_id, + const struct sfc_mae_switch_port_request *req, + uint16_t *switch_port_id) +{ + int rc; + + rc = sfc_mae_assign_switch_port(switch_domain_id, req, switch_port_id); + + SFC_ASSERT(rc >= 0); + return -rc; +} + +static int +sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) +{ + const struct sfc_repr_init_data *repr_data = init_params; + struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); + struct sfc_mae_switch_port_request switch_port_request; + efx_mport_sel_t ethdev_mport_sel; + struct sfc_repr *sr; + int ret; + + /* + * Currently there is no mport we can use for representor's + * ethdev. Use an invalid one for now. This way representors + * can be instantiated. + */ + efx_mae_mport_invalid(ðdev_mport_sel); + + memset(&switch_port_request, 0, sizeof(switch_port_request)); + switch_port_request.type = SFC_MAE_SWITCH_PORT_REPRESENTOR; + switch_port_request.ethdev_mportp = ðdev_mport_sel; + switch_port_request.entity_mportp = &repr_data->mport_sel; + switch_port_request.ethdev_port_id = dev->data->port_id; + + ret = sfc_repr_assign_mae_switch_port(repr_data->switch_domain_id, + &switch_port_request, + &srs->switch_port_id); + if (ret != 0) { + SFC_GENERIC_LOG(ERR, + "%s() failed to assign MAE switch port (domain id %u)", + __func__, repr_data->switch_domain_id); + goto fail_mae_assign_switch_port; + } + + /* + * Allocate process private data from heap, since it should not + * be located in shared memory allocated using rte_malloc() API. + */ + sr = calloc(1, sizeof(*sr)); + if (sr == NULL) { + ret = -ENOMEM; + goto fail_alloc_sr; + } + + sfc_repr_lock_init(sr); + sfc_repr_lock(sr); + + dev->process_private = sr; + + srs->pf_port_id = repr_data->pf_port_id; + srs->repr_id = repr_data->repr_id; + srs->switch_domain_id = repr_data->switch_domain_id; + + dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR; + dev->data->representor_id = srs->repr_id; + dev->data->parent_port_id = srs->pf_port_id; + + dev->data->mac_addrs = rte_zmalloc("sfcr", RTE_ETHER_ADDR_LEN, 0); + if (dev->data->mac_addrs == NULL) { + ret = -ENOMEM; + goto fail_mac_addrs; + } + + dev->dev_ops = &sfc_repr_dev_ops; + + sr->state = SFC_ETHDEV_INITIALIZED; + sfc_repr_unlock(sr); + + return 0; + +fail_mac_addrs: + sfc_repr_unlock(sr); + free(sr); + +fail_alloc_sr: +fail_mae_assign_switch_port: + SFC_GENERIC_LOG(ERR, "%s() failed: %s", __func__, rte_strerror(-ret)); + return ret; +} + +int +sfc_repr_create(struct rte_eth_dev *parent, uint16_t representor_id, + uint16_t switch_domain_id, const efx_mport_sel_t *mport_sel) +{ + struct sfc_repr_init_data repr_data; + char name[RTE_ETH_NAME_MAX_LEN]; + int ret; + + if (snprintf(name, sizeof(name), "net_%s_representor_%u", + parent->device->name, representor_id) >= + (int)sizeof(name)) { + SFC_GENERIC_LOG(ERR, "%s() failed name too long", __func__); + return -ENAMETOOLONG; + } + + memset(&repr_data, 0, sizeof(repr_data)); + repr_data.pf_port_id = parent->data->port_id; + repr_data.repr_id = representor_id; + repr_data.switch_domain_id = switch_domain_id; + repr_data.mport_sel = *mport_sel; + + ret = rte_eth_dev_create(parent->device, name, + sizeof(struct sfc_repr_shared), + NULL, NULL, + sfc_repr_eth_dev_init, &repr_data); + if (ret != 0) + SFC_GENERIC_LOG(ERR, "%s() failed to create device", __func__); + + SFC_GENERIC_LOG(INFO, "%s() done: %s", __func__, rte_strerror(-ret)); + + return ret; +} diff --git a/drivers/net/sfc/sfc_repr.h b/drivers/net/sfc/sfc_repr.h new file mode 100644 index 0000000000..1347206006 --- /dev/null +++ b/drivers/net/sfc/sfc_repr.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019-2021 Xilinx, Inc. + * Copyright(c) 2019 Solarflare Communications Inc. + * + * This software was jointly developed between OKTET Labs (under contract + * for Solarflare) and Solarflare Communications, Inc. + */ + +#ifndef _SFC_REPR_H +#define _SFC_REPR_H + +#include + +#include + +#include "efx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Max count of the representor Rx queues */ +#define SFC_REPR_RXQ_MAX 1 + +/** Max count of the representor Tx queues */ +#define SFC_REPR_TXQ_MAX 1 + +int sfc_repr_create(struct rte_eth_dev *parent, uint16_t representor_id, + uint16_t switch_domain_id, + const efx_mport_sel_t *mport_sel); + +#ifdef __cplusplus +} +#endif +#endif /* _SFC_REPR_H */ diff --git a/drivers/net/sfc/sfc_switch.h b/drivers/net/sfc/sfc_switch.h index 84a02a61f8..a1a2ab9848 100644 --- a/drivers/net/sfc/sfc_switch.h +++ b/drivers/net/sfc/sfc_switch.h @@ -27,6 +27,11 @@ enum sfc_mae_switch_port_type { * and thus refers to its underlying PCIe function */ SFC_MAE_SWITCH_PORT_INDEPENDENT = 0, + /** + * The switch port is operated by a representor RTE ethdev + * and thus refers to the represented PCIe function + */ + SFC_MAE_SWITCH_PORT_REPRESENTOR, }; struct sfc_mae_switch_port_request { From patchwork Fri Aug 27 06:56:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97430 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 16293A0C43; Fri, 27 Aug 2021 08:59:01 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 15E1D4128F; Fri, 27 Aug 2021 08:58:11 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id EDFE34128A for ; Fri, 27 Aug 2021 08:58:07 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id B88BF7F6D6; Fri, 27 Aug 2021 09:58:07 +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 188C07F6DD; Fri, 27 Aug 2021 09:57:34 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 188C07F6DD Authentication-Results: shelob.oktetlabs.ru/188C07F6DD; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:51 +0300 Message-Id: <20210827065717.1838258-13-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 12/38] common/sfc_efx/base: add filter ingress mport matching field 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: Igor Romanov The field changes the mport for which the filter is created. It is required to filter traffic from VF on an alias mport. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/common/sfc_efx/base/ef10_filter.c | 11 +++++++++-- drivers/common/sfc_efx/base/efx.h | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/common/sfc_efx/base/ef10_filter.c b/drivers/common/sfc_efx/base/ef10_filter.c index ac6006c9b4..6d19797d16 100644 --- a/drivers/common/sfc_efx/base/ef10_filter.c +++ b/drivers/common/sfc_efx/base/ef10_filter.c @@ -171,6 +171,7 @@ efx_mcdi_filter_op_add( EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FILTER_OP_V3_IN_LEN, MC_CMD_FILTER_OP_EXT_OUT_LEN); efx_filter_match_flags_t match_flags; + uint32_t port_id; efx_rc_t rc; req.emr_cmd = MC_CMD_FILTER_OP; @@ -180,10 +181,11 @@ efx_mcdi_filter_op_add( req.emr_out_length = MC_CMD_FILTER_OP_EXT_OUT_LEN; /* - * Remove match flag for encapsulated filters that does not correspond + * Remove EFX match flags that do not correspond * to the MCDI match flags */ match_flags = spec->efs_match_flags & ~EFX_FILTER_MATCH_ENCAP_TYPE; + match_flags &= ~EFX_FILTER_MATCH_MPORT; switch (filter_op) { case MC_CMD_FILTER_OP_IN_OP_REPLACE: @@ -202,7 +204,12 @@ efx_mcdi_filter_op_add( goto fail1; } - MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_PORT_ID, enp->en_vport_id); + if (spec->efs_match_flags & EFX_FILTER_MATCH_MPORT) + port_id = spec->efs_ingress_mport; + else + port_id = enp->en_vport_id; + + MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_PORT_ID, port_id); MCDI_IN_SET_DWORD(req, FILTER_OP_EXT_IN_MATCH_FIELDS, match_flags); if (spec->efs_dmaq_id == EFX_FILTER_SPEC_RX_DMAQ_ID_DROP) { diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index c0d1535017..7f04b42bae 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -3389,6 +3389,8 @@ typedef uint8_t efx_filter_flags_t; #define EFX_FILTER_MATCH_OUTER_VID 0x00000100 /* Match by IP transport protocol */ #define EFX_FILTER_MATCH_IP_PROTO 0x00000200 +/* Match by ingress MPORT */ +#define EFX_FILTER_MATCH_MPORT 0x00000400 /* Match by VNI or VSID */ #define EFX_FILTER_MATCH_VNI_OR_VSID 0x00000800 /* For encapsulated packets, match by inner frame local MAC address */ @@ -3451,6 +3453,7 @@ typedef struct efx_filter_spec_s { efx_oword_t efs_loc_host; uint8_t efs_vni_or_vsid[EFX_VNI_OR_VSID_LEN]; uint8_t efs_ifrm_loc_mac[EFX_MAC_ADDR_LEN]; + uint32_t efs_ingress_mport; } efx_filter_spec_t; From patchwork Fri Aug 27 06:56:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97432 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 B0B76A0C43; Fri, 27 Aug 2021 08:59:13 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C70DE4129A; Fri, 27 Aug 2021 08:58:15 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 8F3F741294 for ; Fri, 27 Aug 2021 08:58:13 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 58B1D7F6D6; Fri, 27 Aug 2021 09:58:13 +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 34B987F6DE; Fri, 27 Aug 2021 09:57:34 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 34B987F6DE Authentication-Results: shelob.oktetlabs.ru/34B987F6DE; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:52 +0300 Message-Id: <20210827065717.1838258-14-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 13/38] common/sfc_efx/base: add API to get mport selector by ID 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: Igor Romanov The conversion is required when mport ID is received via mport allocation and mport selector is required for filter creation. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/common/sfc_efx/base/efx.h | 13 +++++++++++++ drivers/common/sfc_efx/base/efx_mae.c | 17 +++++++++++++++++ drivers/common/sfc_efx/version.map | 1 + 3 files changed, 31 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 7f04b42bae..a59c2e47ef 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -4237,6 +4237,19 @@ efx_mae_mport_by_pcie_function( __in uint32_t vf, __out efx_mport_sel_t *mportp); +/* + * Get MPORT selector by an MPORT ID + * + * The resulting MPORT selector is opaque to the caller and can be + * passed as an argument to efx_mae_match_spec_mport_set() + * and efx_mae_action_set_populate_deliver(). + */ +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_mport_by_id( + __in const efx_mport_id_t *mport_idp, + __out efx_mport_sel_t *mportp); + /* Get MPORT ID by an MPORT selector */ LIBEFX_API extern __checkReturn efx_rc_t diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index b7afe8fdc8..f5d981f973 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -827,6 +827,23 @@ efx_mae_mport_id_by_selector( return (rc); } + __checkReturn efx_rc_t +efx_mae_mport_by_id( + __in const efx_mport_id_t *mport_idp, + __out efx_mport_sel_t *mportp) +{ + efx_dword_t dword; + + EFX_POPULATE_DWORD_2(dword, + MAE_MPORT_SELECTOR_TYPE, MAE_MPORT_SELECTOR_TYPE_MPORT_ID, + MAE_MPORT_SELECTOR_MPORT_ID, mport_idp->id); + + memset(mportp, 0, sizeof (*mportp)); + mportp->sel = __LE_TO_CPU_32(dword.ed_u32[0]); + + return (0); +} + __checkReturn efx_rc_t efx_mae_match_spec_field_set( __in efx_mae_match_spec_t *spec, diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 611757ccde..8c5d813c19 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -126,6 +126,7 @@ INTERNAL { efx_mae_match_specs_equal; efx_mae_mport_by_pcie_function; efx_mae_mport_by_phy_port; + efx_mae_mport_by_id; efx_mae_mport_id_by_selector; efx_mae_mport_invalid; efx_mae_outer_rule_insert; From patchwork Fri Aug 27 06:56:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97431 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 24195A0C43; Fri, 27 Aug 2021 08:59:08 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9E11E41278; Fri, 27 Aug 2021 08:58:14 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 8497241292 for ; Fri, 27 Aug 2021 08:58:13 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 540837F6D8; Fri, 27 Aug 2021 09:58:13 +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 4E7A97F6DF; Fri, 27 Aug 2021 09:57:34 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 4E7A97F6DF Authentication-Results: shelob.oktetlabs.ru/4E7A97F6DF; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:53 +0300 Message-Id: <20210827065717.1838258-15-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 14/38] common/sfc_efx/base: add mport alias MCDI wrappers 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: Igor Romanov The APIs allow creation of mports for port representor traffic filtering. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/common/sfc_efx/base/efx.h | 13 ++++ drivers/common/sfc_efx/base/efx_mae.c | 90 +++++++++++++++++++++++++++ drivers/common/sfc_efx/version.map | 2 + 3 files changed, 105 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index a59c2e47ef..0a178128ba 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -4599,6 +4599,19 @@ efx_mae_action_rule_remove( __in efx_nic_t *enp, __in const efx_mae_rule_id_t *ar_idp); +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mcdi_mport_alloc_alias( + __in efx_nic_t *enp, + __out efx_mport_id_t *mportp, + __out_opt uint32_t *labelp); + +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_mport_free( + __in efx_nic_t *enp, + __in const efx_mport_id_t *mportp); + #endif /* EFSYS_OPT_MAE */ #if EFSYS_OPT_VIRTIO diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index f5d981f973..3f498fe189 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -3142,4 +3142,94 @@ efx_mae_action_rule_remove( return (rc); } + __checkReturn efx_rc_t +efx_mcdi_mport_alloc_alias( + __in efx_nic_t *enp, + __out efx_mport_id_t *mportp, + __out_opt uint32_t *labelp) +{ + const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); + efx_mcdi_req_t req; + EFX_MCDI_DECLARE_BUF(payload, + MC_CMD_MAE_MPORT_ALLOC_ALIAS_IN_LEN, + MC_CMD_MAE_MPORT_ALLOC_ALIAS_OUT_LEN); + efx_rc_t rc; + + if (encp->enc_mae_supported == B_FALSE) { + rc = ENOTSUP; + goto fail1; + } + + req.emr_cmd = MC_CMD_MAE_MPORT_ALLOC; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_MAE_MPORT_ALLOC_ALIAS_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_MAE_MPORT_ALLOC_ALIAS_OUT_LEN; + + MCDI_IN_SET_DWORD(req, MAE_MPORT_ALLOC_IN_TYPE, + MC_CMD_MAE_MPORT_ALLOC_IN_MPORT_TYPE_ALIAS); + MCDI_IN_SET_DWORD(req, MAE_MPORT_ALLOC_ALIAS_IN_DELIVER_MPORT, + MAE_MPORT_SELECTOR_ASSIGNED); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail2; + } + + mportp->id = MCDI_OUT_DWORD(req, MAE_MPORT_ALLOC_OUT_MPORT_ID); + if (labelp != NULL) + *labelp = MCDI_OUT_DWORD(req, MAE_MPORT_ALLOC_ALIAS_OUT_LABEL); + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mae_mport_free( + __in efx_nic_t *enp, + __in const efx_mport_id_t *mportp) +{ + const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); + efx_mcdi_req_t req; + EFX_MCDI_DECLARE_BUF(payload, + MC_CMD_MAE_MPORT_FREE_IN_LEN, + MC_CMD_MAE_MPORT_FREE_OUT_LEN); + efx_rc_t rc; + + if (encp->enc_mae_supported == B_FALSE) { + rc = ENOTSUP; + goto fail1; + } + + req.emr_cmd = MC_CMD_MAE_MPORT_FREE; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_MAE_MPORT_FREE_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_MAE_MPORT_FREE_OUT_LEN; + + MCDI_IN_SET_DWORD(req, MAE_MPORT_FREE_IN_MPORT_ID, mportp->id); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail2; + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + #endif /* EFSYS_OPT_MAE */ diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 8c5d813c19..3488367f68 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -127,6 +127,7 @@ INTERNAL { efx_mae_mport_by_pcie_function; efx_mae_mport_by_phy_port; efx_mae_mport_by_id; + efx_mae_mport_free; efx_mae_mport_id_by_selector; efx_mae_mport_invalid; efx_mae_outer_rule_insert; @@ -136,6 +137,7 @@ INTERNAL { efx_mcdi_get_proxy_handle; efx_mcdi_get_timeout; efx_mcdi_init; + efx_mcdi_mport_alloc_alias; efx_mcdi_new_epoch; efx_mcdi_reboot; efx_mcdi_request_abort; From patchwork Fri Aug 27 06:56:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97433 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 D84A9A0C43; Fri, 27 Aug 2021 08:59:19 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3E4D24124D; Fri, 27 Aug 2021 08:58:33 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id C662F411D3 for ; Fri, 27 Aug 2021 08:58:30 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 9C4F57F6DE; Fri, 27 Aug 2021 09:58:30 +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 6A3BC7F6E0; Fri, 27 Aug 2021 09:57:34 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 6A3BC7F6E0 Authentication-Results: shelob.oktetlabs.ru/6A3BC7F6E0; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:54 +0300 Message-Id: <20210827065717.1838258-16-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 15/38] net/sfc: add representor proxy port API 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: Igor Romanov The API is required to create and destroy representor proxy port assigned to representor. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc.c | 12 + drivers/net/sfc/sfc.h | 1 + drivers/net/sfc/sfc_ethdev.c | 2 + drivers/net/sfc/sfc_repr.c | 20 ++ drivers/net/sfc/sfc_repr_proxy.c | 320 ++++++++++++++++++++++++++- drivers/net/sfc/sfc_repr_proxy.h | 30 +++ drivers/net/sfc/sfc_repr_proxy_api.h | 29 +++ 7 files changed, 412 insertions(+), 2 deletions(-) create mode 100644 drivers/net/sfc/sfc_repr_proxy_api.h diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 152234cb61..f79f4d5ffc 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -1043,6 +1043,18 @@ sfc_attach(struct sfc_adapter *sa) return rc; } +void +sfc_pre_detach(struct sfc_adapter *sa) +{ + sfc_log_init(sa, "entry"); + + SFC_ASSERT(!sfc_adapter_is_locked(sa)); + + sfc_repr_proxy_pre_detach(sa); + + sfc_log_init(sa, "done"); +} + void sfc_detach(struct sfc_adapter *sa) { diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 628f32c13f..c3e92f3ab6 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -376,6 +376,7 @@ uint32_t sfc_register_logtype(const struct rte_pci_addr *pci_addr, int sfc_probe(struct sfc_adapter *sa); void sfc_unprobe(struct sfc_adapter *sa); int sfc_attach(struct sfc_adapter *sa); +void sfc_pre_detach(struct sfc_adapter *sa); void sfc_detach(struct sfc_adapter *sa); int sfc_start(struct sfc_adapter *sa); void sfc_stop(struct sfc_adapter *sa); diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 8308cbdfef..8578ba0765 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -345,6 +345,8 @@ sfc_dev_close(struct rte_eth_dev *dev) return 0; } + sfc_pre_detach(sa); + sfc_adapter_lock(sa); switch (sa->state) { case SFC_ETHDEV_STARTED: diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index 603a613ec6..f684b1d7ef 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -19,6 +19,7 @@ #include "sfc_debug.h" #include "sfc_repr.h" #include "sfc_ethdev_state.h" +#include "sfc_repr_proxy_api.h" #include "sfc_switch.h" /** Multi-process shared representor private data */ @@ -285,6 +286,7 @@ static int sfc_repr_dev_close(struct rte_eth_dev *dev) { struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); + struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); sfcr_info(sr, "entry"); @@ -306,6 +308,8 @@ sfc_repr_dev_close(struct rte_eth_dev *dev) * Rollback primary process sfc_repr_eth_dev_init() below. */ + (void)sfc_repr_proxy_del_port(srs->pf_port_id, srs->repr_id); + dev->dev_ops = NULL; sfc_repr_unlock(sr); @@ -378,6 +382,18 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) goto fail_mae_assign_switch_port; } + ret = sfc_repr_proxy_add_port(repr_data->pf_port_id, + repr_data->repr_id, + dev->data->port_id, + &repr_data->mport_sel); + if (ret != 0) { + SFC_GENERIC_LOG(ERR, "%s() failed to add repr proxy port", + __func__); + SFC_ASSERT(ret > 0); + ret = -ret; + goto fail_create_port; + } + /* * Allocate process private data from heap, since it should not * be located in shared memory allocated using rte_malloc() API. @@ -419,6 +435,10 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) free(sr); fail_alloc_sr: + (void)sfc_repr_proxy_del_port(repr_data->pf_port_id, + repr_data->repr_id); + +fail_create_port: fail_mae_assign_switch_port: SFC_GENERIC_LOG(ERR, "%s() failed: %s", __func__, rte_strerror(-ret)); return ret; diff --git a/drivers/net/sfc/sfc_repr_proxy.c b/drivers/net/sfc/sfc_repr_proxy.c index 6d3962304f..f64fa2efc7 100644 --- a/drivers/net/sfc/sfc_repr_proxy.c +++ b/drivers/net/sfc/sfc_repr_proxy.c @@ -13,17 +13,191 @@ #include "sfc_log.h" #include "sfc_service.h" #include "sfc_repr_proxy.h" +#include "sfc_repr_proxy_api.h" #include "sfc.h" +/** + * Amount of time to wait for the representor proxy routine (which is + * running on a service core) to handle a request sent via mbox. + */ +#define SFC_REPR_PROXY_MBOX_POLL_TIMEOUT_MS 1000 + +static struct sfc_repr_proxy * +sfc_repr_proxy_by_adapter(struct sfc_adapter *sa) +{ + return &sa->repr_proxy; +} + +static struct sfc_adapter * +sfc_get_adapter_by_pf_port_id(uint16_t pf_port_id) +{ + struct rte_eth_dev *dev; + struct sfc_adapter *sa; + + SFC_ASSERT(pf_port_id < RTE_MAX_ETHPORTS); + + dev = &rte_eth_devices[pf_port_id]; + sa = sfc_adapter_by_eth_dev(dev); + + sfc_adapter_lock(sa); + + return sa; +} + +static void +sfc_put_adapter(struct sfc_adapter *sa) +{ + sfc_adapter_unlock(sa); +} + +static int +sfc_repr_proxy_mbox_send(struct sfc_repr_proxy_mbox *mbox, + struct sfc_repr_proxy_port *port, + enum sfc_repr_proxy_mbox_op op) +{ + const unsigned int wait_ms = SFC_REPR_PROXY_MBOX_POLL_TIMEOUT_MS; + unsigned int i; + + mbox->op = op; + mbox->port = port; + mbox->ack = false; + + /* + * Release ordering enforces marker set after data is populated. + * Paired with acquire ordering in sfc_repr_proxy_mbox_handle(). + */ + __atomic_store_n(&mbox->write_marker, true, __ATOMIC_RELEASE); + + /* + * Wait for the representor routine to process the request. + * Give up on timeout. + */ + for (i = 0; i < wait_ms; i++) { + /* + * Paired with release ordering in sfc_repr_proxy_mbox_handle() + * on acknowledge write. + */ + if (__atomic_load_n(&mbox->ack, __ATOMIC_ACQUIRE)) + break; + + rte_delay_ms(1); + } + + if (i == wait_ms) { + SFC_GENERIC_LOG(ERR, + "%s() failed to wait for representor proxy routine ack", + __func__); + return ETIMEDOUT; + } + + return 0; +} + +static void +sfc_repr_proxy_mbox_handle(struct sfc_repr_proxy *rp) +{ + struct sfc_repr_proxy_mbox *mbox = &rp->mbox; + + /* + * Paired with release ordering in sfc_repr_proxy_mbox_send() + * on marker set. + */ + if (!__atomic_load_n(&mbox->write_marker, __ATOMIC_ACQUIRE)) + return; + + mbox->write_marker = false; + + switch (mbox->op) { + case SFC_REPR_PROXY_MBOX_ADD_PORT: + TAILQ_INSERT_TAIL(&rp->ports, mbox->port, entries); + break; + case SFC_REPR_PROXY_MBOX_DEL_PORT: + TAILQ_REMOVE(&rp->ports, mbox->port, entries); + break; + default: + SFC_ASSERT(0); + return; + } + + /* + * Paired with acquire ordering in sfc_repr_proxy_mbox_send() + * on acknowledge read. + */ + __atomic_store_n(&mbox->ack, true, __ATOMIC_RELEASE); +} + static int32_t sfc_repr_proxy_routine(void *arg) { struct sfc_repr_proxy *rp = arg; - /* Representor proxy boilerplate will be here */ - RTE_SET_USED(rp); + sfc_repr_proxy_mbox_handle(rp); + + return 0; +} + +static int +sfc_repr_proxy_ports_init(struct sfc_adapter *sa) +{ + struct sfc_repr_proxy *rp = &sa->repr_proxy; + int rc; + + sfc_log_init(sa, "entry"); + + rc = efx_mcdi_mport_alloc_alias(sa->nic, &rp->mport_alias, NULL); + if (rc != 0) { + sfc_err(sa, "failed to alloc mport alias: %s", + rte_strerror(rc)); + goto fail_alloc_mport_alias; + } + + TAILQ_INIT(&rp->ports); + + sfc_log_init(sa, "done"); return 0; + +fail_alloc_mport_alias: + + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + return rc; +} + +void +sfc_repr_proxy_pre_detach(struct sfc_adapter *sa) +{ + struct sfc_repr_proxy *rp = &sa->repr_proxy; + bool close_ports[RTE_MAX_ETHPORTS] = {0}; + struct sfc_repr_proxy_port *port; + unsigned int i; + + SFC_ASSERT(!sfc_adapter_is_locked(sa)); + + sfc_adapter_lock(sa); + + if (sfc_repr_available(sfc_sa2shared(sa))) { + TAILQ_FOREACH(port, &rp->ports, entries) + close_ports[port->rte_port_id] = true; + } else { + sfc_log_init(sa, "representors not supported - skip"); + } + + sfc_adapter_unlock(sa); + + for (i = 0; i < RTE_DIM(close_ports); i++) { + if (close_ports[i]) { + rte_eth_dev_stop(i); + rte_eth_dev_close(i); + } + } +} + +static void +sfc_repr_proxy_ports_fini(struct sfc_adapter *sa) +{ + struct sfc_repr_proxy *rp = &sa->repr_proxy; + + efx_mae_mport_free(sa->nic, &rp->mport_alias); } int @@ -43,6 +217,10 @@ sfc_repr_proxy_attach(struct sfc_adapter *sa) return 0; } + rc = sfc_repr_proxy_ports_init(sa); + if (rc != 0) + goto fail_ports_init; + cid = sfc_get_service_lcore(sa->socket_id); if (cid == RTE_MAX_LCORE && sa->socket_id != SOCKET_ID_ANY) { /* Warn and try to allocate on any NUMA node */ @@ -96,6 +274,9 @@ sfc_repr_proxy_attach(struct sfc_adapter *sa) */ fail_get_service_lcore: + sfc_repr_proxy_ports_fini(sa); + +fail_ports_init: sfc_log_init(sa, "failed: %s", rte_strerror(rc)); return rc; } @@ -115,6 +296,7 @@ sfc_repr_proxy_detach(struct sfc_adapter *sa) rte_service_map_lcore_set(rp->service_id, rp->service_core_id, 0); rte_service_component_unregister(rp->service_id); + sfc_repr_proxy_ports_fini(sa); sfc_log_init(sa, "done"); } @@ -165,6 +347,8 @@ sfc_repr_proxy_start(struct sfc_adapter *sa) goto fail_runstate_set; } + rp->started = true; + sfc_log_init(sa, "done"); return 0; @@ -210,5 +394,137 @@ sfc_repr_proxy_stop(struct sfc_adapter *sa) /* Service lcore may be shared and we never stop it */ + rp->started = false; + + sfc_log_init(sa, "done"); +} + +static struct sfc_repr_proxy_port * +sfc_repr_proxy_find_port(struct sfc_repr_proxy *rp, uint16_t repr_id) +{ + struct sfc_repr_proxy_port *port; + + TAILQ_FOREACH(port, &rp->ports, entries) { + if (port->repr_id == repr_id) + return port; + } + + return NULL; +} + +int +sfc_repr_proxy_add_port(uint16_t pf_port_id, uint16_t repr_id, + uint16_t rte_port_id, const efx_mport_sel_t *mport_sel) +{ + struct sfc_repr_proxy_port *port; + struct sfc_repr_proxy *rp; + struct sfc_adapter *sa; + int rc; + + sa = sfc_get_adapter_by_pf_port_id(pf_port_id); + rp = sfc_repr_proxy_by_adapter(sa); + + sfc_log_init(sa, "entry"); + TAILQ_FOREACH(port, &rp->ports, entries) { + if (port->rte_port_id == rte_port_id) { + rc = EEXIST; + sfc_err(sa, "%s() failed: port exists", __func__); + goto fail_port_exists; + } + } + + port = rte_zmalloc("sfc-repr-proxy-port", sizeof(*port), + sa->socket_id); + if (port == NULL) { + rc = ENOMEM; + sfc_err(sa, "failed to alloc memory for proxy port"); + goto fail_alloc_port; + } + + rc = efx_mae_mport_id_by_selector(sa->nic, mport_sel, + &port->egress_mport); + if (rc != 0) { + sfc_err(sa, + "failed get MAE mport id by selector (repr_id %u): %s", + repr_id, rte_strerror(rc)); + goto fail_mport_id; + } + + port->rte_port_id = rte_port_id; + port->repr_id = repr_id; + + if (rp->started) { + rc = sfc_repr_proxy_mbox_send(&rp->mbox, port, + SFC_REPR_PROXY_MBOX_ADD_PORT); + if (rc != 0) { + sfc_err(sa, "failed to add proxy port %u", + port->repr_id); + goto fail_port_add; + } + } else { + TAILQ_INSERT_TAIL(&rp->ports, port, entries); + } + + sfc_log_init(sa, "done"); + sfc_put_adapter(sa); + + return 0; + +fail_port_add: +fail_mport_id: + rte_free(port); +fail_alloc_port: +fail_port_exists: + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + sfc_put_adapter(sa); + + return rc; +} + +int +sfc_repr_proxy_del_port(uint16_t pf_port_id, uint16_t repr_id) +{ + struct sfc_repr_proxy_port *port; + struct sfc_repr_proxy *rp; + struct sfc_adapter *sa; + int rc; + + sa = sfc_get_adapter_by_pf_port_id(pf_port_id); + rp = sfc_repr_proxy_by_adapter(sa); + + sfc_log_init(sa, "entry"); + + port = sfc_repr_proxy_find_port(rp, repr_id); + if (port == NULL) { + sfc_err(sa, "failed: no such port"); + rc = ENOENT; + goto fail_no_port; + } + + if (rp->started) { + rc = sfc_repr_proxy_mbox_send(&rp->mbox, port, + SFC_REPR_PROXY_MBOX_DEL_PORT); + if (rc != 0) { + sfc_err(sa, "failed to remove proxy port %u", + port->repr_id); + goto fail_port_remove; + } + } else { + TAILQ_REMOVE(&rp->ports, port, entries); + } + + rte_free(port); + sfc_log_init(sa, "done"); + + sfc_put_adapter(sa); + + return 0; + +fail_port_remove: +fail_no_port: + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + sfc_put_adapter(sa); + + return rc; } diff --git a/drivers/net/sfc/sfc_repr_proxy.h b/drivers/net/sfc/sfc_repr_proxy.h index 953b9922c8..e4a6213c10 100644 --- a/drivers/net/sfc/sfc_repr_proxy.h +++ b/drivers/net/sfc/sfc_repr_proxy.h @@ -12,6 +12,8 @@ #include +#include "efx.h" + #ifdef __cplusplus extern "C" { #endif @@ -24,14 +26,42 @@ extern "C" { #define SFC_REPR_PROXY_NB_TXQ_MIN (1) #define SFC_REPR_PROXY_NB_TXQ_MAX (1) +struct sfc_repr_proxy_port { + TAILQ_ENTRY(sfc_repr_proxy_port) entries; + uint16_t repr_id; + uint16_t rte_port_id; + efx_mport_id_t egress_mport; +}; + +enum sfc_repr_proxy_mbox_op { + SFC_REPR_PROXY_MBOX_ADD_PORT, + SFC_REPR_PROXY_MBOX_DEL_PORT, +}; + +struct sfc_repr_proxy_mbox { + struct sfc_repr_proxy_port *port; + enum sfc_repr_proxy_mbox_op op; + + bool write_marker; + bool ack; +}; + +TAILQ_HEAD(sfc_repr_proxy_ports, sfc_repr_proxy_port); + struct sfc_repr_proxy { uint32_t service_core_id; uint32_t service_id; + efx_mport_id_t mport_alias; + struct sfc_repr_proxy_ports ports; + bool started; + + struct sfc_repr_proxy_mbox mbox; }; struct sfc_adapter; int sfc_repr_proxy_attach(struct sfc_adapter *sa); +void sfc_repr_proxy_pre_detach(struct sfc_adapter *sa); void sfc_repr_proxy_detach(struct sfc_adapter *sa); int sfc_repr_proxy_start(struct sfc_adapter *sa); void sfc_repr_proxy_stop(struct sfc_adapter *sa); diff --git a/drivers/net/sfc/sfc_repr_proxy_api.h b/drivers/net/sfc/sfc_repr_proxy_api.h new file mode 100644 index 0000000000..af9009ca3c --- /dev/null +++ b/drivers/net/sfc/sfc_repr_proxy_api.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2019-2021 Xilinx, Inc. + * Copyright(c) 2019 Solarflare Communications Inc. + * + * This software was jointly developed between OKTET Labs (under contract + * for Solarflare) and Solarflare Communications, Inc. + */ + +#ifndef _SFC_REPR_PROXY_API_H +#define _SFC_REPR_PROXY_API_H + +#include + +#include "efx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int sfc_repr_proxy_add_port(uint16_t pf_port_id, uint16_t repr_id, + uint16_t rte_port_id, + const efx_mport_sel_t *mport_set); +int sfc_repr_proxy_del_port(uint16_t pf_port_id, uint16_t repr_id); + +#ifdef __cplusplus +} +#endif +#endif /* _SFC_REPR_PROXY_API_H */ From patchwork Fri Aug 27 06:56:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97434 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 D263EA0C43; Fri, 27 Aug 2021 08:59:25 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 626884121F; Fri, 27 Aug 2021 08:58:34 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id C8FC9411E9 for ; Fri, 27 Aug 2021 08:58:30 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 8E8A57F6DB; Fri, 27 Aug 2021 09:58:30 +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 878BD7F6E1; Fri, 27 Aug 2021 09:57:34 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 878BD7F6E1 Authentication-Results: shelob.oktetlabs.ru/878BD7F6E1; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:55 +0300 Message-Id: <20210827065717.1838258-17-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 16/38] net/sfc: implement representor queue setup and release 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: Igor Romanov Implement queue creation and destruction both in port representors and representor proxy. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_repr.c | 279 +++++++++++++++++++++++++++ drivers/net/sfc/sfc_repr_proxy.c | 132 +++++++++++++ drivers/net/sfc/sfc_repr_proxy.h | 22 +++ drivers/net/sfc/sfc_repr_proxy_api.h | 15 ++ 4 files changed, 448 insertions(+) diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index f684b1d7ef..b3876586cc 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -30,6 +30,25 @@ struct sfc_repr_shared { uint16_t switch_port_id; }; +struct sfc_repr_rxq { + /* Datapath members */ + struct rte_ring *ring; + + /* Non-datapath members */ + struct sfc_repr_shared *shared; + uint16_t queue_id; +}; + +struct sfc_repr_txq { + /* Datapath members */ + struct rte_ring *ring; + efx_mport_id_t egress_mport; + + /* Non-datapath members */ + struct sfc_repr_shared *shared; + uint16_t queue_id; +}; + /** Primary process representor private data */ struct sfc_repr { /** @@ -50,6 +69,14 @@ struct sfc_repr { SFC_GENERIC_LOG(ERR, __VA_ARGS__); \ } while (0) +#define sfcr_warn(sr, ...) \ + do { \ + const struct sfc_repr *_sr = (sr); \ + \ + (void)_sr; \ + SFC_GENERIC_LOG(WARNING, __VA_ARGS__); \ + } while (0) + #define sfcr_info(sr, ...) \ do { \ const struct sfc_repr *_sr = (sr); \ @@ -269,6 +296,243 @@ sfc_repr_dev_infos_get(struct rte_eth_dev *dev, return 0; } +static int +sfc_repr_ring_create(uint16_t pf_port_id, uint16_t repr_id, + const char *type_name, uint16_t qid, uint16_t nb_desc, + unsigned int socket_id, struct rte_ring **ring) +{ + char ring_name[RTE_RING_NAMESIZE]; + int ret; + + ret = snprintf(ring_name, sizeof(ring_name), "sfc_%u_repr_%u_%sq%u", + pf_port_id, repr_id, type_name, qid); + if (ret >= (int)sizeof(ring_name)) + return -ENAMETOOLONG; + + /* + * Single producer/consumer rings are used since the API for Tx/Rx + * packet burst for representors are guaranteed to be called from + * a single thread, and the user of the other end (representor proxy) + * is also single-threaded. + */ + *ring = rte_ring_create(ring_name, nb_desc, socket_id, + RING_F_SP_ENQ | RING_F_SC_DEQ); + if (*ring == NULL) + return -rte_errno; + + return 0; +} + +static int +sfc_repr_rx_qcheck_conf(struct sfc_repr *sr, + const struct rte_eth_rxconf *rx_conf) +{ + int ret = 0; + + sfcr_info(sr, "entry"); + + if (rx_conf->rx_thresh.pthresh != 0 || + rx_conf->rx_thresh.hthresh != 0 || + rx_conf->rx_thresh.wthresh != 0) { + sfcr_warn(sr, + "RxQ prefetch/host/writeback thresholds are not supported"); + } + + if (rx_conf->rx_free_thresh != 0) + sfcr_warn(sr, "RxQ free threshold is not supported"); + + if (rx_conf->rx_drop_en == 0) + sfcr_warn(sr, "RxQ drop disable is not supported"); + + if (rx_conf->rx_deferred_start) { + sfcr_err(sr, "Deferred start is not supported"); + ret = -EINVAL; + } + + sfcr_info(sr, "done: %s", rte_strerror(-ret)); + + return ret; +} + +static int +sfc_repr_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id, + uint16_t nb_rx_desc, unsigned int socket_id, + __rte_unused const struct rte_eth_rxconf *rx_conf, + struct rte_mempool *mb_pool) +{ + struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); + struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); + struct sfc_repr_rxq *rxq; + int ret; + + sfcr_info(sr, "entry"); + + ret = sfc_repr_rx_qcheck_conf(sr, rx_conf); + if (ret != 0) + goto fail_check_conf; + + ret = -ENOMEM; + rxq = rte_zmalloc_socket("sfc-repr-rxq", sizeof(*rxq), + RTE_CACHE_LINE_SIZE, socket_id); + if (rxq == NULL) { + sfcr_err(sr, "%s() failed to alloc RxQ", __func__); + goto fail_rxq_alloc; + } + + rxq->shared = srs; + rxq->queue_id = rx_queue_id; + + ret = sfc_repr_ring_create(srs->pf_port_id, srs->repr_id, + "rx", rxq->queue_id, nb_rx_desc, + socket_id, &rxq->ring); + if (ret != 0) { + sfcr_err(sr, "%s() failed to create ring", __func__); + goto fail_ring_create; + } + + ret = sfc_repr_proxy_add_rxq(srs->pf_port_id, srs->repr_id, + rxq->queue_id, rxq->ring, mb_pool); + if (ret != 0) { + SFC_ASSERT(ret > 0); + ret = -ret; + sfcr_err(sr, "%s() failed to add proxy RxQ", __func__); + goto fail_proxy_add_rxq; + } + + dev->data->rx_queues[rx_queue_id] = rxq; + + sfcr_info(sr, "done"); + + return 0; + +fail_proxy_add_rxq: + rte_ring_free(rxq->ring); + +fail_ring_create: + rte_free(rxq); + +fail_rxq_alloc: +fail_check_conf: + sfcr_err(sr, "%s() failed: %s", __func__, rte_strerror(-ret)); + return ret; +} + +static void +sfc_repr_rx_queue_release(void *queue) +{ + struct sfc_repr_rxq *rxq = queue; + struct sfc_repr_shared *srs; + + if (rxq == NULL) + return; + + srs = rxq->shared; + sfc_repr_proxy_del_rxq(srs->pf_port_id, srs->repr_id, rxq->queue_id); + rte_ring_free(rxq->ring); + rte_free(rxq); +} + +static int +sfc_repr_tx_qcheck_conf(struct sfc_repr *sr, + const struct rte_eth_txconf *tx_conf) +{ + int ret = 0; + + sfcr_info(sr, "entry"); + + if (tx_conf->tx_rs_thresh != 0) + sfcr_warn(sr, "RS bit in transmit descriptor is not supported"); + + if (tx_conf->tx_free_thresh != 0) + sfcr_warn(sr, "TxQ free threshold is not supported"); + + if (tx_conf->tx_thresh.pthresh != 0 || + tx_conf->tx_thresh.hthresh != 0 || + tx_conf->tx_thresh.wthresh != 0) { + sfcr_warn(sr, + "prefetch/host/writeback thresholds are not supported"); + } + + if (tx_conf->tx_deferred_start) { + sfcr_err(sr, "Deferred start is not supported"); + ret = -EINVAL; + } + + sfcr_info(sr, "done: %s", rte_strerror(-ret)); + + return ret; +} + +static int +sfc_repr_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id, + uint16_t nb_tx_desc, unsigned int socket_id, + const struct rte_eth_txconf *tx_conf) +{ + struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); + struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); + struct sfc_repr_txq *txq; + int ret; + + sfcr_info(sr, "entry"); + + ret = sfc_repr_tx_qcheck_conf(sr, tx_conf); + if (ret != 0) + goto fail_check_conf; + + ret = -ENOMEM; + txq = rte_zmalloc_socket("sfc-repr-txq", sizeof(*txq), + RTE_CACHE_LINE_SIZE, socket_id); + if (txq == NULL) + goto fail_txq_alloc; + + txq->shared = srs; + txq->queue_id = tx_queue_id; + + ret = sfc_repr_ring_create(srs->pf_port_id, srs->repr_id, + "tx", txq->queue_id, nb_tx_desc, + socket_id, &txq->ring); + if (ret != 0) + goto fail_ring_create; + + ret = sfc_repr_proxy_add_txq(srs->pf_port_id, srs->repr_id, + txq->queue_id, txq->ring, + &txq->egress_mport); + if (ret != 0) + goto fail_proxy_add_txq; + + dev->data->tx_queues[tx_queue_id] = txq; + + sfcr_info(sr, "done"); + + return 0; + +fail_proxy_add_txq: + rte_ring_free(txq->ring); + +fail_ring_create: + rte_free(txq); + +fail_txq_alloc: +fail_check_conf: + sfcr_err(sr, "%s() failed: %s", __func__, rte_strerror(-ret)); + return ret; +} + +static void +sfc_repr_tx_queue_release(void *queue) +{ + struct sfc_repr_txq *txq = queue; + struct sfc_repr_shared *srs; + + if (txq == NULL) + return; + + srs = txq->shared; + sfc_repr_proxy_del_txq(srs->pf_port_id, srs->repr_id, txq->queue_id); + rte_ring_free(txq->ring); + rte_free(txq); +} + static void sfc_repr_close(struct sfc_repr *sr) { @@ -287,6 +551,7 @@ sfc_repr_dev_close(struct rte_eth_dev *dev) { struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev); + unsigned int i; sfcr_info(sr, "entry"); @@ -303,6 +568,16 @@ sfc_repr_dev_close(struct rte_eth_dev *dev) break; } + for (i = 0; i < dev->data->nb_rx_queues; i++) { + sfc_repr_rx_queue_release(dev->data->rx_queues[i]); + dev->data->rx_queues[i] = NULL; + } + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + sfc_repr_tx_queue_release(dev->data->tx_queues[i]); + dev->data->tx_queues[i] = NULL; + } + /* * Cleanup all resources. * Rollback primary process sfc_repr_eth_dev_init() below. @@ -326,6 +601,10 @@ static const struct eth_dev_ops sfc_repr_dev_ops = { .dev_configure = sfc_repr_dev_configure, .dev_close = sfc_repr_dev_close, .dev_infos_get = sfc_repr_dev_infos_get, + .rx_queue_setup = sfc_repr_rx_queue_setup, + .rx_queue_release = sfc_repr_rx_queue_release, + .tx_queue_setup = sfc_repr_tx_queue_setup, + .tx_queue_release = sfc_repr_tx_queue_release, }; diff --git a/drivers/net/sfc/sfc_repr_proxy.c b/drivers/net/sfc/sfc_repr_proxy.c index f64fa2efc7..6a89cca40a 100644 --- a/drivers/net/sfc/sfc_repr_proxy.c +++ b/drivers/net/sfc/sfc_repr_proxy.c @@ -528,3 +528,135 @@ sfc_repr_proxy_del_port(uint16_t pf_port_id, uint16_t repr_id) return rc; } + +int +sfc_repr_proxy_add_rxq(uint16_t pf_port_id, uint16_t repr_id, + uint16_t queue_id, struct rte_ring *rx_ring, + struct rte_mempool *mp) +{ + struct sfc_repr_proxy_port *port; + struct sfc_repr_proxy_rxq *rxq; + struct sfc_repr_proxy *rp; + struct sfc_adapter *sa; + + sa = sfc_get_adapter_by_pf_port_id(pf_port_id); + rp = sfc_repr_proxy_by_adapter(sa); + + sfc_log_init(sa, "entry"); + + port = sfc_repr_proxy_find_port(rp, repr_id); + if (port == NULL) { + sfc_err(sa, "%s() failed: no such port", __func__); + return ENOENT; + } + + rxq = &port->rxq[queue_id]; + if (rp->dp_rxq[queue_id].mp != NULL && rp->dp_rxq[queue_id].mp != mp) { + sfc_err(sa, "multiple mempools per queue are not supported"); + sfc_put_adapter(sa); + return ENOTSUP; + } + + rxq->ring = rx_ring; + rxq->mb_pool = mp; + rp->dp_rxq[queue_id].mp = mp; + rp->dp_rxq[queue_id].ref_count++; + + sfc_log_init(sa, "done"); + sfc_put_adapter(sa); + + return 0; +} + +void +sfc_repr_proxy_del_rxq(uint16_t pf_port_id, uint16_t repr_id, + uint16_t queue_id) +{ + struct sfc_repr_proxy_port *port; + struct sfc_repr_proxy_rxq *rxq; + struct sfc_repr_proxy *rp; + struct sfc_adapter *sa; + + sa = sfc_get_adapter_by_pf_port_id(pf_port_id); + rp = sfc_repr_proxy_by_adapter(sa); + + sfc_log_init(sa, "entry"); + + port = sfc_repr_proxy_find_port(rp, repr_id); + if (port == NULL) { + sfc_err(sa, "%s() failed: no such port", __func__); + return; + } + + rxq = &port->rxq[queue_id]; + + rxq->ring = NULL; + rxq->mb_pool = NULL; + rp->dp_rxq[queue_id].ref_count--; + if (rp->dp_rxq[queue_id].ref_count == 0) + rp->dp_rxq[queue_id].mp = NULL; + + sfc_log_init(sa, "done"); + sfc_put_adapter(sa); +} + +int +sfc_repr_proxy_add_txq(uint16_t pf_port_id, uint16_t repr_id, + uint16_t queue_id, struct rte_ring *tx_ring, + efx_mport_id_t *egress_mport) +{ + struct sfc_repr_proxy_port *port; + struct sfc_repr_proxy_txq *txq; + struct sfc_repr_proxy *rp; + struct sfc_adapter *sa; + + sa = sfc_get_adapter_by_pf_port_id(pf_port_id); + rp = sfc_repr_proxy_by_adapter(sa); + + sfc_log_init(sa, "entry"); + + port = sfc_repr_proxy_find_port(rp, repr_id); + if (port == NULL) { + sfc_err(sa, "%s() failed: no such port", __func__); + return ENOENT; + } + + txq = &port->txq[queue_id]; + + txq->ring = tx_ring; + + *egress_mport = port->egress_mport; + + sfc_log_init(sa, "done"); + sfc_put_adapter(sa); + + return 0; +} + +void +sfc_repr_proxy_del_txq(uint16_t pf_port_id, uint16_t repr_id, + uint16_t queue_id) +{ + struct sfc_repr_proxy_port *port; + struct sfc_repr_proxy_txq *txq; + struct sfc_repr_proxy *rp; + struct sfc_adapter *sa; + + sa = sfc_get_adapter_by_pf_port_id(pf_port_id); + rp = sfc_repr_proxy_by_adapter(sa); + + sfc_log_init(sa, "entry"); + + port = sfc_repr_proxy_find_port(rp, repr_id); + if (port == NULL) { + sfc_err(sa, "%s() failed: no such port", __func__); + return; + } + + txq = &port->txq[queue_id]; + + txq->ring = NULL; + + sfc_log_init(sa, "done"); + sfc_put_adapter(sa); +} diff --git a/drivers/net/sfc/sfc_repr_proxy.h b/drivers/net/sfc/sfc_repr_proxy.h index e4a6213c10..bd7ad7148a 100644 --- a/drivers/net/sfc/sfc_repr_proxy.h +++ b/drivers/net/sfc/sfc_repr_proxy.h @@ -12,8 +12,13 @@ #include +#include +#include + #include "efx.h" +#include "sfc_repr.h" + #ifdef __cplusplus extern "C" { #endif @@ -26,11 +31,27 @@ extern "C" { #define SFC_REPR_PROXY_NB_TXQ_MIN (1) #define SFC_REPR_PROXY_NB_TXQ_MAX (1) +struct sfc_repr_proxy_rxq { + struct rte_ring *ring; + struct rte_mempool *mb_pool; +}; + +struct sfc_repr_proxy_txq { + struct rte_ring *ring; +}; + struct sfc_repr_proxy_port { TAILQ_ENTRY(sfc_repr_proxy_port) entries; uint16_t repr_id; uint16_t rte_port_id; efx_mport_id_t egress_mport; + struct sfc_repr_proxy_rxq rxq[SFC_REPR_RXQ_MAX]; + struct sfc_repr_proxy_txq txq[SFC_REPR_TXQ_MAX]; +}; + +struct sfc_repr_proxy_dp_rxq { + struct rte_mempool *mp; + unsigned int ref_count; }; enum sfc_repr_proxy_mbox_op { @@ -54,6 +75,7 @@ struct sfc_repr_proxy { efx_mport_id_t mport_alias; struct sfc_repr_proxy_ports ports; bool started; + struct sfc_repr_proxy_dp_rxq dp_rxq[SFC_REPR_PROXY_NB_RXQ_MAX]; struct sfc_repr_proxy_mbox mbox; }; diff --git a/drivers/net/sfc/sfc_repr_proxy_api.h b/drivers/net/sfc/sfc_repr_proxy_api.h index af9009ca3c..d1c0760efa 100644 --- a/drivers/net/sfc/sfc_repr_proxy_api.h +++ b/drivers/net/sfc/sfc_repr_proxy_api.h @@ -12,6 +12,9 @@ #include +#include +#include + #include "efx.h" #ifdef __cplusplus @@ -23,6 +26,18 @@ int sfc_repr_proxy_add_port(uint16_t pf_port_id, uint16_t repr_id, const efx_mport_sel_t *mport_set); int sfc_repr_proxy_del_port(uint16_t pf_port_id, uint16_t repr_id); +int sfc_repr_proxy_add_rxq(uint16_t pf_port_id, uint16_t repr_id, + uint16_t queue_id, struct rte_ring *rx_ring, + struct rte_mempool *mp); +void sfc_repr_proxy_del_rxq(uint16_t pf_port_id, uint16_t repr_id, + uint16_t queue_id); + +int sfc_repr_proxy_add_txq(uint16_t pf_port_id, uint16_t repr_id, + uint16_t queue_id, struct rte_ring *tx_ring, + efx_mport_id_t *egress_mport); +void sfc_repr_proxy_del_txq(uint16_t pf_port_id, uint16_t repr_id, + uint16_t queue_id); + #ifdef __cplusplus } #endif From patchwork Fri Aug 27 06:56:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97437 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 A6BD9A0C43; Fri, 27 Aug 2021 08:59:45 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6716441287; Fri, 27 Aug 2021 08:58:43 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 06FB941251 for ; Fri, 27 Aug 2021 08:58:37 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 6D19E7F6DE; Fri, 27 Aug 2021 09:58:36 +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 A56B87F6E2; Fri, 27 Aug 2021 09:57:34 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru A56B87F6E2 Authentication-Results: shelob.oktetlabs.ru/A56B87F6E2; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:56 +0300 Message-Id: <20210827065717.1838258-18-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 17/38] net/sfc: implement representor RxQ start/stop 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: Igor Romanov Add extra libefx flags to Rx queue information initialization function interface to be able to specify the ingress m-port flag for a representor RxQ. Rx prefix of packets on that queue will contain ingress m-port field required for packet forwarding in representor proxy. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_ev.h | 8 ++ drivers/net/sfc/sfc_repr_proxy.c | 194 +++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_repr_proxy.h | 7 ++ 3 files changed, 209 insertions(+) diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h index 590cfb1694..bcb7fbe466 100644 --- a/drivers/net/sfc/sfc_ev.h +++ b/drivers/net/sfc/sfc_ev.h @@ -110,6 +110,14 @@ sfc_counters_rxq_sw_index(const struct sfc_adapter_shared *sas) return sas->counters_rxq_allocated ? 0 : SFC_SW_INDEX_INVALID; } +static inline sfc_sw_index_t +sfc_repr_rxq_sw_index(const struct sfc_adapter_shared *sas, + unsigned int repr_queue_id) +{ + return sfc_counters_rxq_sw_index(sas) + sfc_repr_nb_rxq(sas) + + repr_queue_id; +} + /* * Functions below define event queue to transmit/receive queue and vice * versa mapping. diff --git a/drivers/net/sfc/sfc_repr_proxy.c b/drivers/net/sfc/sfc_repr_proxy.c index 6a89cca40a..03b6421b04 100644 --- a/drivers/net/sfc/sfc_repr_proxy.c +++ b/drivers/net/sfc/sfc_repr_proxy.c @@ -15,6 +15,8 @@ #include "sfc_repr_proxy.h" #include "sfc_repr_proxy_api.h" #include "sfc.h" +#include "sfc_ev.h" +#include "sfc_rx.h" /** * Amount of time to wait for the representor proxy routine (which is @@ -136,6 +138,181 @@ sfc_repr_proxy_routine(void *arg) return 0; } +static int +sfc_repr_proxy_rxq_attach(struct sfc_adapter *sa) +{ + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_repr_proxy *rp = &sa->repr_proxy; + unsigned int i; + + sfc_log_init(sa, "entry"); + + for (i = 0; i < sfc_repr_nb_rxq(sas); i++) { + sfc_sw_index_t sw_index = sfc_repr_rxq_sw_index(sas, i); + + rp->dp_rxq[i].sw_index = sw_index; + } + + sfc_log_init(sa, "done"); + + return 0; +} + +static void +sfc_repr_proxy_rxq_detach(struct sfc_adapter *sa) +{ + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_repr_proxy *rp = &sa->repr_proxy; + unsigned int i; + + sfc_log_init(sa, "entry"); + + for (i = 0; i < sfc_repr_nb_rxq(sas); i++) + rp->dp_rxq[i].sw_index = 0; + + sfc_log_init(sa, "done"); +} + +static int +sfc_repr_proxy_rxq_init(struct sfc_adapter *sa, + struct sfc_repr_proxy_dp_rxq *rxq) +{ + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + uint16_t nb_rx_desc = SFC_REPR_PROXY_RX_DESC_COUNT; + struct sfc_rxq_info *rxq_info; + struct rte_eth_rxconf rxconf = { + .rx_free_thresh = SFC_REPR_PROXY_RXQ_REFILL_LEVEL, + .rx_drop_en = 1, + }; + int rc; + + sfc_log_init(sa, "entry"); + + rxq_info = &sas->rxq_info[rxq->sw_index]; + if (rxq_info->state & SFC_RXQ_INITIALIZED) { + sfc_log_init(sa, "RxQ is already initialized - skip"); + return 0; + } + + nb_rx_desc = RTE_MIN(nb_rx_desc, sa->rxq_max_entries); + nb_rx_desc = RTE_MAX(nb_rx_desc, sa->rxq_min_entries); + + rc = sfc_rx_qinit_info(sa, rxq->sw_index, EFX_RXQ_FLAG_INGRESS_MPORT); + if (rc != 0) { + sfc_err(sa, "failed to init representor proxy RxQ info"); + goto fail_repr_rxq_init_info; + } + + rc = sfc_rx_qinit(sa, rxq->sw_index, nb_rx_desc, sa->socket_id, &rxconf, + rxq->mp); + if (rc != 0) { + sfc_err(sa, "failed to init representor proxy RxQ"); + goto fail_repr_rxq_init; + } + + sfc_log_init(sa, "done"); + + return 0; + +fail_repr_rxq_init: +fail_repr_rxq_init_info: + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + + return rc; +} + +static void +sfc_repr_proxy_rxq_fini(struct sfc_adapter *sa) +{ + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_repr_proxy *rp = &sa->repr_proxy; + struct sfc_rxq_info *rxq_info; + unsigned int i; + + sfc_log_init(sa, "entry"); + + if (!sfc_repr_available(sas)) { + sfc_log_init(sa, "representors not supported - skip"); + return; + } + + for (i = 0; i < sfc_repr_nb_rxq(sas); i++) { + struct sfc_repr_proxy_dp_rxq *rxq = &rp->dp_rxq[i]; + + rxq_info = &sas->rxq_info[rxq->sw_index]; + if (rxq_info->state != SFC_RXQ_INITIALIZED) { + sfc_log_init(sa, + "representor RxQ %u is already finalized - skip", + i); + continue; + } + + sfc_rx_qfini(sa, rxq->sw_index); + } + + sfc_log_init(sa, "done"); +} + +static void +sfc_repr_proxy_rxq_stop(struct sfc_adapter *sa) +{ + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + unsigned int i; + + sfc_log_init(sa, "entry"); + + for (i = 0; i < sfc_repr_nb_rxq(sas); i++) + sfc_rx_qstop(sa, sa->repr_proxy.dp_rxq[i].sw_index); + + sfc_repr_proxy_rxq_fini(sa); + + sfc_log_init(sa, "done"); +} + +static int +sfc_repr_proxy_rxq_start(struct sfc_adapter *sa) +{ + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_repr_proxy *rp = &sa->repr_proxy; + unsigned int i; + int rc; + + sfc_log_init(sa, "entry"); + + if (!sfc_repr_available(sas)) { + sfc_log_init(sa, "representors not supported - skip"); + return 0; + } + + for (i = 0; i < sfc_repr_nb_rxq(sas); i++) { + struct sfc_repr_proxy_dp_rxq *rxq = &rp->dp_rxq[i]; + + rc = sfc_repr_proxy_rxq_init(sa, rxq); + if (rc != 0) { + sfc_err(sa, "failed to init representor proxy RxQ %u", + i); + goto fail_init; + } + + rc = sfc_rx_qstart(sa, rxq->sw_index); + if (rc != 0) { + sfc_err(sa, "failed to start representor proxy RxQ %u", + i); + goto fail_start; + } + } + + sfc_log_init(sa, "done"); + + return 0; + +fail_start: +fail_init: + sfc_repr_proxy_rxq_stop(sa); + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + return rc; +} + static int sfc_repr_proxy_ports_init(struct sfc_adapter *sa) { @@ -217,6 +394,10 @@ sfc_repr_proxy_attach(struct sfc_adapter *sa) return 0; } + rc = sfc_repr_proxy_rxq_attach(sa); + if (rc != 0) + goto fail_rxq_attach; + rc = sfc_repr_proxy_ports_init(sa); if (rc != 0) goto fail_ports_init; @@ -277,6 +458,9 @@ sfc_repr_proxy_attach(struct sfc_adapter *sa) sfc_repr_proxy_ports_fini(sa); fail_ports_init: + sfc_repr_proxy_rxq_detach(sa); + +fail_rxq_attach: sfc_log_init(sa, "failed: %s", rte_strerror(rc)); return rc; } @@ -297,6 +481,7 @@ sfc_repr_proxy_detach(struct sfc_adapter *sa) rte_service_map_lcore_set(rp->service_id, rp->service_core_id, 0); rte_service_component_unregister(rp->service_id); sfc_repr_proxy_ports_fini(sa); + sfc_repr_proxy_rxq_detach(sa); sfc_log_init(sa, "done"); } @@ -319,6 +504,10 @@ sfc_repr_proxy_start(struct sfc_adapter *sa) return 0; } + rc = sfc_repr_proxy_rxq_start(sa); + if (rc != 0) + goto fail_rxq_start; + /* Service core may be in "stopped" state, start it */ rc = rte_service_lcore_start(rp->service_core_id); if (rc != 0 && rc != -EALREADY) { @@ -360,6 +549,9 @@ sfc_repr_proxy_start(struct sfc_adapter *sa) /* Service lcore may be shared and we never stop it */ fail_start_core: + sfc_repr_proxy_rxq_stop(sa); + +fail_rxq_start: sfc_log_init(sa, "failed: %s", rte_strerror(rc)); return rc; } @@ -394,6 +586,8 @@ sfc_repr_proxy_stop(struct sfc_adapter *sa) /* Service lcore may be shared and we never stop it */ + sfc_repr_proxy_rxq_stop(sa); + rp->started = false; sfc_log_init(sa, "done"); diff --git a/drivers/net/sfc/sfc_repr_proxy.h b/drivers/net/sfc/sfc_repr_proxy.h index bd7ad7148a..dca3fca2b9 100644 --- a/drivers/net/sfc/sfc_repr_proxy.h +++ b/drivers/net/sfc/sfc_repr_proxy.h @@ -18,6 +18,7 @@ #include "efx.h" #include "sfc_repr.h" +#include "sfc_dp.h" #ifdef __cplusplus extern "C" { @@ -31,6 +32,10 @@ extern "C" { #define SFC_REPR_PROXY_NB_TXQ_MIN (1) #define SFC_REPR_PROXY_NB_TXQ_MAX (1) +#define SFC_REPR_PROXY_RX_DESC_COUNT 256 +#define SFC_REPR_PROXY_RXQ_REFILL_LEVEL (SFC_REPR_PROXY_RX_DESC_COUNT / 4) +#define SFC_REPR_PROXY_RX_BURST 32 + struct sfc_repr_proxy_rxq { struct rte_ring *ring; struct rte_mempool *mb_pool; @@ -52,6 +57,8 @@ struct sfc_repr_proxy_port { struct sfc_repr_proxy_dp_rxq { struct rte_mempool *mp; unsigned int ref_count; + + sfc_sw_index_t sw_index; }; enum sfc_repr_proxy_mbox_op { From patchwork Fri Aug 27 06:56:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97436 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 26BD3A0C43; Fri, 27 Aug 2021 08:59:40 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 59B9C412A4; Fri, 27 Aug 2021 08:58:42 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id EC996411DF for ; Fri, 27 Aug 2021 08:58:36 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 6FD787F6E0; Fri, 27 Aug 2021 09:58:36 +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 C2A7A7F6E3; Fri, 27 Aug 2021 09:57:34 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru C2A7A7F6E3 Authentication-Results: shelob.oktetlabs.ru/C2A7A7F6E3; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:57 +0300 Message-Id: <20210827065717.1838258-19-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 18/38] net/sfc: implement representor TxQ start/stop 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: Igor Romanov Implement Tx queue start and stop in port representor proxy. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_ev.h | 8 ++ drivers/net/sfc/sfc_repr_proxy.c | 166 +++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_repr_proxy.h | 11 ++ drivers/net/sfc/sfc_tx.c | 15 ++- drivers/net/sfc/sfc_tx.h | 1 + 5 files changed, 199 insertions(+), 2 deletions(-) diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h index bcb7fbe466..a4ababc2bc 100644 --- a/drivers/net/sfc/sfc_ev.h +++ b/drivers/net/sfc/sfc_ev.h @@ -118,6 +118,14 @@ sfc_repr_rxq_sw_index(const struct sfc_adapter_shared *sas, repr_queue_id; } +static inline sfc_sw_index_t +sfc_repr_txq_sw_index(const struct sfc_adapter_shared *sas, + unsigned int repr_queue_id) +{ + /* Reserved TxQ for representors is the first reserved TxQ */ + return sfc_repr_available(sas) ? repr_queue_id : SFC_SW_INDEX_INVALID; +} + /* * Functions below define event queue to transmit/receive queue and vice * versa mapping. diff --git a/drivers/net/sfc/sfc_repr_proxy.c b/drivers/net/sfc/sfc_repr_proxy.c index 03b6421b04..a5be8fa270 100644 --- a/drivers/net/sfc/sfc_repr_proxy.c +++ b/drivers/net/sfc/sfc_repr_proxy.c @@ -17,6 +17,7 @@ #include "sfc.h" #include "sfc_ev.h" #include "sfc_rx.h" +#include "sfc_tx.h" /** * Amount of time to wait for the representor proxy routine (which is @@ -138,6 +139,155 @@ sfc_repr_proxy_routine(void *arg) return 0; } +static int +sfc_repr_proxy_txq_attach(struct sfc_adapter *sa) +{ + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_repr_proxy *rp = &sa->repr_proxy; + unsigned int i; + + sfc_log_init(sa, "entry"); + + for (i = 0; i < sfc_repr_nb_txq(sas); i++) { + sfc_sw_index_t sw_index = sfc_repr_txq_sw_index(sas, i); + + rp->dp_txq[i].sw_index = sw_index; + } + + sfc_log_init(sa, "done"); + + return 0; +} + +static void +sfc_repr_proxy_txq_detach(struct sfc_adapter *sa) +{ + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_repr_proxy *rp = &sa->repr_proxy; + unsigned int i; + + sfc_log_init(sa, "entry"); + + for (i = 0; i < sfc_repr_nb_txq(sas); i++) + rp->dp_txq[i].sw_index = 0; + + sfc_log_init(sa, "done"); +} + +int +sfc_repr_proxy_txq_init(struct sfc_adapter *sa) +{ + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_repr_proxy *rp = &sa->repr_proxy; + const struct rte_eth_txconf tx_conf = { + .tx_free_thresh = SFC_REPR_PROXY_TXQ_FREE_THRESH, + }; + struct sfc_txq_info *txq_info; + unsigned int init_i; + unsigned int i; + int rc; + + sfc_log_init(sa, "entry"); + + if (!sfc_repr_available(sas)) { + sfc_log_init(sa, "representors not supported - skip"); + return 0; + } + + for (init_i = 0; init_i < sfc_repr_nb_txq(sas); init_i++) { + struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[init_i]; + + txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index]; + if (txq_info->state == SFC_TXQ_INITIALIZED) { + sfc_log_init(sa, + "representor proxy TxQ %u is already initialized - skip", + init_i); + continue; + } + + sfc_tx_qinit_info(sa, txq->sw_index); + + rc = sfc_tx_qinit(sa, txq->sw_index, + SFC_REPR_PROXY_TX_DESC_COUNT, sa->socket_id, + &tx_conf); + + if (rc != 0) { + sfc_err(sa, "failed to init representor proxy TxQ %u", + init_i); + goto fail_init; + } + } + + sfc_log_init(sa, "done"); + + return 0; + +fail_init: + for (i = 0; i < init_i; i++) { + struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i]; + + txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index]; + if (txq_info->state == SFC_TXQ_INITIALIZED) + sfc_tx_qfini(sa, txq->sw_index); + } + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + + return rc; +} + +void +sfc_repr_proxy_txq_fini(struct sfc_adapter *sa) +{ + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_repr_proxy *rp = &sa->repr_proxy; + struct sfc_txq_info *txq_info; + unsigned int i; + + sfc_log_init(sa, "entry"); + + if (!sfc_repr_available(sas)) { + sfc_log_init(sa, "representors not supported - skip"); + return; + } + + for (i = 0; i < sfc_repr_nb_txq(sas); i++) { + struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i]; + + txq_info = &sfc_sa2shared(sa)->txq_info[txq->sw_index]; + if (txq_info->state != SFC_TXQ_INITIALIZED) { + sfc_log_init(sa, + "representor proxy TxQ %u is already finalized - skip", + i); + continue; + } + + sfc_tx_qfini(sa, txq->sw_index); + } + + sfc_log_init(sa, "done"); +} + +static int +sfc_repr_proxy_txq_start(struct sfc_adapter *sa) +{ + struct sfc_repr_proxy *rp = &sa->repr_proxy; + + sfc_log_init(sa, "entry"); + + RTE_SET_USED(rp); + + sfc_log_init(sa, "done"); + + return 0; +} + +static void +sfc_repr_proxy_txq_stop(struct sfc_adapter *sa) +{ + sfc_log_init(sa, "entry"); + sfc_log_init(sa, "done"); +} + static int sfc_repr_proxy_rxq_attach(struct sfc_adapter *sa) { @@ -398,6 +548,10 @@ sfc_repr_proxy_attach(struct sfc_adapter *sa) if (rc != 0) goto fail_rxq_attach; + rc = sfc_repr_proxy_txq_attach(sa); + if (rc != 0) + goto fail_txq_attach; + rc = sfc_repr_proxy_ports_init(sa); if (rc != 0) goto fail_ports_init; @@ -458,6 +612,9 @@ sfc_repr_proxy_attach(struct sfc_adapter *sa) sfc_repr_proxy_ports_fini(sa); fail_ports_init: + sfc_repr_proxy_txq_detach(sa); + +fail_txq_attach: sfc_repr_proxy_rxq_detach(sa); fail_rxq_attach: @@ -482,6 +639,7 @@ sfc_repr_proxy_detach(struct sfc_adapter *sa) rte_service_component_unregister(rp->service_id); sfc_repr_proxy_ports_fini(sa); sfc_repr_proxy_rxq_detach(sa); + sfc_repr_proxy_txq_detach(sa); sfc_log_init(sa, "done"); } @@ -508,6 +666,10 @@ sfc_repr_proxy_start(struct sfc_adapter *sa) if (rc != 0) goto fail_rxq_start; + rc = sfc_repr_proxy_txq_start(sa); + if (rc != 0) + goto fail_txq_start; + /* Service core may be in "stopped" state, start it */ rc = rte_service_lcore_start(rp->service_core_id); if (rc != 0 && rc != -EALREADY) { @@ -549,6 +711,9 @@ sfc_repr_proxy_start(struct sfc_adapter *sa) /* Service lcore may be shared and we never stop it */ fail_start_core: + sfc_repr_proxy_txq_stop(sa); + +fail_txq_start: sfc_repr_proxy_rxq_stop(sa); fail_rxq_start: @@ -587,6 +752,7 @@ sfc_repr_proxy_stop(struct sfc_adapter *sa) /* Service lcore may be shared and we never stop it */ sfc_repr_proxy_rxq_stop(sa); + sfc_repr_proxy_txq_stop(sa); rp->started = false; diff --git a/drivers/net/sfc/sfc_repr_proxy.h b/drivers/net/sfc/sfc_repr_proxy.h index dca3fca2b9..1fe7ff3695 100644 --- a/drivers/net/sfc/sfc_repr_proxy.h +++ b/drivers/net/sfc/sfc_repr_proxy.h @@ -36,6 +36,10 @@ extern "C" { #define SFC_REPR_PROXY_RXQ_REFILL_LEVEL (SFC_REPR_PROXY_RX_DESC_COUNT / 4) #define SFC_REPR_PROXY_RX_BURST 32 +#define SFC_REPR_PROXY_TX_DESC_COUNT 256 +#define SFC_REPR_PROXY_TXQ_FREE_THRESH (SFC_REPR_PROXY_TX_DESC_COUNT / 4) +#define SFC_REPR_PROXY_TX_BURST 32 + struct sfc_repr_proxy_rxq { struct rte_ring *ring; struct rte_mempool *mb_pool; @@ -61,6 +65,10 @@ struct sfc_repr_proxy_dp_rxq { sfc_sw_index_t sw_index; }; +struct sfc_repr_proxy_dp_txq { + sfc_sw_index_t sw_index; +}; + enum sfc_repr_proxy_mbox_op { SFC_REPR_PROXY_MBOX_ADD_PORT, SFC_REPR_PROXY_MBOX_DEL_PORT, @@ -83,6 +91,7 @@ struct sfc_repr_proxy { struct sfc_repr_proxy_ports ports; bool started; struct sfc_repr_proxy_dp_rxq dp_rxq[SFC_REPR_PROXY_NB_RXQ_MAX]; + struct sfc_repr_proxy_dp_txq dp_txq[SFC_REPR_PROXY_NB_TXQ_MAX]; struct sfc_repr_proxy_mbox mbox; }; @@ -92,6 +101,8 @@ struct sfc_adapter; int sfc_repr_proxy_attach(struct sfc_adapter *sa); void sfc_repr_proxy_pre_detach(struct sfc_adapter *sa); void sfc_repr_proxy_detach(struct sfc_adapter *sa); +int sfc_repr_proxy_txq_init(struct sfc_adapter *sa); +void sfc_repr_proxy_txq_fini(struct sfc_adapter *sa); int sfc_repr_proxy_start(struct sfc_adapter *sa); void sfc_repr_proxy_stop(struct sfc_adapter *sa); diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c index c1b2e964f8..13392cdd5a 100644 --- a/drivers/net/sfc/sfc_tx.c +++ b/drivers/net/sfc/sfc_tx.c @@ -290,7 +290,7 @@ sfc_tx_qfini(struct sfc_adapter *sa, sfc_sw_index_t sw_index) txq->evq = NULL; } -static int +int sfc_tx_qinit_info(struct sfc_adapter *sa, sfc_sw_index_t sw_index) { struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); @@ -378,6 +378,7 @@ sfc_tx_configure(struct sfc_adapter *sa) const unsigned int nb_tx_queues = sa->eth_dev->data->nb_tx_queues; const unsigned int nb_rsvd_tx_queues = sfc_nb_txq_reserved(sas); const unsigned int nb_txq_total = nb_tx_queues + nb_rsvd_tx_queues; + bool reconfigure; int rc = 0; sfc_log_init(sa, "nb_tx_queues=%u (old %u)", @@ -401,6 +402,7 @@ sfc_tx_configure(struct sfc_adapter *sa) goto done; if (sas->txq_info == NULL) { + reconfigure = false; sas->txq_info = rte_calloc_socket("sfc-txqs", nb_txq_total, sizeof(sas->txq_info[0]), 0, sa->socket_id); @@ -419,6 +421,8 @@ sfc_tx_configure(struct sfc_adapter *sa) struct sfc_txq_info *new_txq_info; struct sfc_txq *new_txq_ctrl; + reconfigure = true; + if (nb_tx_queues < sas->ethdev_txq_count) sfc_tx_fini_queues(sa, nb_tx_queues); @@ -457,12 +461,18 @@ sfc_tx_configure(struct sfc_adapter *sa) sas->ethdev_txq_count++; } - /* TODO: initialize reserved queues when supported. */ sas->txq_count = sas->ethdev_txq_count + nb_rsvd_tx_queues; + if (!reconfigure) { + rc = sfc_repr_proxy_txq_init(sa); + if (rc != 0) + goto fail_repr_proxy_txq_init; + } + done: return 0; +fail_repr_proxy_txq_init: fail_tx_qinit_info: fail_txqs_ctrl_realloc: fail_txqs_realloc: @@ -480,6 +490,7 @@ void sfc_tx_close(struct sfc_adapter *sa) { sfc_tx_fini_queues(sa, 0); + sfc_repr_proxy_txq_fini(sa); free(sa->txq_ctrl); sa->txq_ctrl = NULL; diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h index f1700b13ca..1a33199fdc 100644 --- a/drivers/net/sfc/sfc_tx.h +++ b/drivers/net/sfc/sfc_tx.h @@ -108,6 +108,7 @@ struct sfc_txq_info *sfc_txq_info_by_dp_txq(const struct sfc_dp_txq *dp_txq); int sfc_tx_configure(struct sfc_adapter *sa); void sfc_tx_close(struct sfc_adapter *sa); +int sfc_tx_qinit_info(struct sfc_adapter *sa, sfc_sw_index_t sw_index); int sfc_tx_qinit(struct sfc_adapter *sa, sfc_sw_index_t sw_index, uint16_t nb_tx_desc, unsigned int socket_id, const struct rte_eth_txconf *tx_conf); From patchwork Fri Aug 27 06:56:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97435 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 D5DE8A0C43; Fri, 27 Aug 2021 08:59:33 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 38DAD4126D; Fri, 27 Aug 2021 08:58:41 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 9FB1341251 for ; Fri, 27 Aug 2021 08:58:36 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 67B3B7F6DB; Fri, 27 Aug 2021 09:58:36 +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 E07F17F6E4; Fri, 27 Aug 2021 09:57:34 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru E07F17F6E4 Authentication-Results: shelob.oktetlabs.ru/E07F17F6E4; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:58 +0300 Message-Id: <20210827065717.1838258-20-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 19/38] net/sfc: implement port representor start and stop 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: Igor Romanov Implement queue start and stop operation both in port representors and representor proxy. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_mae.h | 9 +- drivers/net/sfc/sfc_repr.c | 181 +++++++++++ drivers/net/sfc/sfc_repr_proxy.c | 453 ++++++++++++++++++++++++++- drivers/net/sfc/sfc_repr_proxy.h | 16 + drivers/net/sfc/sfc_repr_proxy_api.h | 3 + 5 files changed, 644 insertions(+), 18 deletions(-) diff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h index 684f0daf7a..d835056aef 100644 --- a/drivers/net/sfc/sfc_mae.h +++ b/drivers/net/sfc/sfc_mae.h @@ -139,10 +139,17 @@ struct sfc_mae_counter_registry { uint32_t service_id; }; +/** + * MAE rules used to capture traffic generated by VFs and direct it to + * representors (one for each VF). + */ +#define SFC_MAE_NB_REPR_RULES_MAX (64) + /** Rules to forward traffic from PHY port to PF and from PF to PHY port */ #define SFC_MAE_NB_SWITCHDEV_RULES (2) /** Maximum required internal MAE rules */ -#define SFC_MAE_NB_RULES_MAX (SFC_MAE_NB_SWITCHDEV_RULES) +#define SFC_MAE_NB_RULES_MAX (SFC_MAE_NB_SWITCHDEV_RULES + \ + SFC_MAE_NB_REPR_RULES_MAX) struct sfc_mae_rule { efx_mae_match_spec_t *spec; diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index b3876586cc..bfe6dd4c9b 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -21,6 +22,7 @@ #include "sfc_ethdev_state.h" #include "sfc_repr_proxy_api.h" #include "sfc_switch.h" +#include "sfc_dp_tx.h" /** Multi-process shared representor private data */ struct sfc_repr_shared { @@ -144,6 +146,179 @@ sfc_repr_lock_fini(__rte_unused struct sfc_repr *sr) /* Just for symmetry of the API */ } +static void +sfc_repr_rx_queue_stop(void *queue) +{ + struct sfc_repr_rxq *rxq = queue; + + if (rxq == NULL) + return; + + rte_ring_reset(rxq->ring); +} + +static void +sfc_repr_tx_queue_stop(void *queue) +{ + struct sfc_repr_txq *txq = queue; + + if (txq == NULL) + return; + + rte_ring_reset(txq->ring); +} + +static int +sfc_repr_start(struct rte_eth_dev *dev) +{ + struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); + struct sfc_repr_shared *srs; + int ret; + + sfcr_info(sr, "entry"); + + SFC_ASSERT(sfc_repr_lock_is_locked(sr)); + + switch (sr->state) { + case SFC_ETHDEV_CONFIGURED: + break; + case SFC_ETHDEV_STARTED: + sfcr_info(sr, "already started"); + return 0; + default: + ret = -EINVAL; + goto fail_bad_state; + } + + sr->state = SFC_ETHDEV_STARTING; + + srs = sfc_repr_shared_by_eth_dev(dev); + ret = sfc_repr_proxy_start_repr(srs->pf_port_id, srs->repr_id); + if (ret != 0) { + SFC_ASSERT(ret > 0); + ret = -ret; + goto fail_start; + } + + sr->state = SFC_ETHDEV_STARTED; + + sfcr_info(sr, "done"); + + return 0; + +fail_start: + sr->state = SFC_ETHDEV_CONFIGURED; + +fail_bad_state: + sfcr_err(sr, "%s() failed: %s", __func__, rte_strerror(-ret)); + return ret; +} + +static int +sfc_repr_dev_start(struct rte_eth_dev *dev) +{ + struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); + int ret; + + sfcr_info(sr, "entry"); + + sfc_repr_lock(sr); + ret = sfc_repr_start(dev); + sfc_repr_unlock(sr); + + if (ret != 0) + goto fail_start; + + sfcr_info(sr, "done"); + + return 0; + +fail_start: + sfcr_err(sr, "%s() failed: %s", __func__, rte_strerror(-ret)); + return ret; +} + +static int +sfc_repr_stop(struct rte_eth_dev *dev) +{ + struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); + struct sfc_repr_shared *srs; + unsigned int i; + int ret; + + sfcr_info(sr, "entry"); + + SFC_ASSERT(sfc_repr_lock_is_locked(sr)); + + switch (sr->state) { + case SFC_ETHDEV_STARTED: + break; + case SFC_ETHDEV_CONFIGURED: + sfcr_info(sr, "already stopped"); + return 0; + default: + sfcr_err(sr, "stop in unexpected state %u", sr->state); + SFC_ASSERT(B_FALSE); + ret = -EINVAL; + goto fail_bad_state; + } + + srs = sfc_repr_shared_by_eth_dev(dev); + ret = sfc_repr_proxy_stop_repr(srs->pf_port_id, srs->repr_id); + if (ret != 0) { + SFC_ASSERT(ret > 0); + ret = -ret; + goto fail_stop; + } + + for (i = 0; i < dev->data->nb_rx_queues; i++) + sfc_repr_rx_queue_stop(dev->data->rx_queues[i]); + + for (i = 0; i < dev->data->nb_tx_queues; i++) + sfc_repr_tx_queue_stop(dev->data->tx_queues[i]); + + sr->state = SFC_ETHDEV_CONFIGURED; + sfcr_info(sr, "done"); + + return 0; + +fail_bad_state: +fail_stop: + sfcr_err(sr, "%s() failed: %s", __func__, rte_strerror(-ret)); + + return ret; +} + +static int +sfc_repr_dev_stop(struct rte_eth_dev *dev) +{ + struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); + int ret; + + sfcr_info(sr, "entry"); + + sfc_repr_lock(sr); + + ret = sfc_repr_stop(dev); + if (ret != 0) { + sfcr_err(sr, "%s() failed to stop representor", __func__); + goto fail_stop; + } + + sfc_repr_unlock(sr); + + sfcr_info(sr, "done"); + + return 0; + +fail_stop: + sfc_repr_unlock(sr); + + sfcr_err(sr, "%s() failed %s", __func__, rte_strerror(-ret)); + + return ret; +} + static int sfc_repr_check_conf(struct sfc_repr *sr, uint16_t nb_rx_queues, const struct rte_eth_conf *conf) @@ -557,6 +732,10 @@ sfc_repr_dev_close(struct rte_eth_dev *dev) sfc_repr_lock(sr); switch (sr->state) { + case SFC_ETHDEV_STARTED: + sfc_repr_stop(dev); + SFC_ASSERT(sr->state == SFC_ETHDEV_CONFIGURED); + /* FALLTHROUGH */ case SFC_ETHDEV_CONFIGURED: sfc_repr_close(sr); SFC_ASSERT(sr->state == SFC_ETHDEV_INITIALIZED); @@ -599,6 +778,8 @@ sfc_repr_dev_close(struct rte_eth_dev *dev) static const struct eth_dev_ops sfc_repr_dev_ops = { .dev_configure = sfc_repr_dev_configure, + .dev_start = sfc_repr_dev_start, + .dev_stop = sfc_repr_dev_stop, .dev_close = sfc_repr_dev_close, .dev_infos_get = sfc_repr_dev_infos_get, .rx_queue_setup = sfc_repr_rx_queue_setup, diff --git a/drivers/net/sfc/sfc_repr_proxy.c b/drivers/net/sfc/sfc_repr_proxy.c index a5be8fa270..ea03d5afdd 100644 --- a/drivers/net/sfc/sfc_repr_proxy.c +++ b/drivers/net/sfc/sfc_repr_proxy.c @@ -53,6 +53,19 @@ sfc_put_adapter(struct sfc_adapter *sa) sfc_adapter_unlock(sa); } +static struct sfc_repr_proxy_port * +sfc_repr_proxy_find_port(struct sfc_repr_proxy *rp, uint16_t repr_id) +{ + struct sfc_repr_proxy_port *port; + + TAILQ_FOREACH(port, &rp->ports, entries) { + if (port->repr_id == repr_id) + return port; + } + + return NULL; +} + static int sfc_repr_proxy_mbox_send(struct sfc_repr_proxy_mbox *mbox, struct sfc_repr_proxy_port *port, @@ -117,6 +130,12 @@ sfc_repr_proxy_mbox_handle(struct sfc_repr_proxy *rp) case SFC_REPR_PROXY_MBOX_DEL_PORT: TAILQ_REMOVE(&rp->ports, mbox->port, entries); break; + case SFC_REPR_PROXY_MBOX_START_PORT: + mbox->port->started = true; + break; + case SFC_REPR_PROXY_MBOX_STOP_PORT: + mbox->port->started = false; + break; default: SFC_ASSERT(0); return; @@ -463,6 +482,158 @@ sfc_repr_proxy_rxq_start(struct sfc_adapter *sa) return rc; } +static int +sfc_repr_proxy_mae_rule_insert(struct sfc_adapter *sa, + struct sfc_repr_proxy_port *port) +{ + struct sfc_repr_proxy *rp = &sa->repr_proxy; + efx_mport_sel_t mport_alias_selector; + efx_mport_sel_t mport_vf_selector; + struct sfc_mae_rule *mae_rule; + int rc; + + sfc_log_init(sa, "entry"); + + rc = efx_mae_mport_by_id(&port->egress_mport, + &mport_vf_selector); + if (rc != 0) { + sfc_err(sa, "failed to get VF mport for repr %u", + port->repr_id); + goto fail_get_vf; + } + + rc = efx_mae_mport_by_id(&rp->mport_alias, &mport_alias_selector); + if (rc != 0) { + sfc_err(sa, "failed to get mport selector for repr %u", + port->repr_id); + goto fail_get_alias; + } + + rc = sfc_mae_rule_add_mport_match_deliver(sa, &mport_vf_selector, + &mport_alias_selector, -1, + &mae_rule); + if (rc != 0) { + sfc_err(sa, "failed to insert MAE rule for repr %u", + port->repr_id); + goto fail_rule_add; + } + + port->mae_rule = mae_rule; + + sfc_log_init(sa, "done"); + + return 0; + +fail_rule_add: +fail_get_alias: +fail_get_vf: + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + return rc; +} + +static void +sfc_repr_proxy_mae_rule_remove(struct sfc_adapter *sa, + struct sfc_repr_proxy_port *port) +{ + struct sfc_mae_rule *mae_rule = port->mae_rule; + + sfc_mae_rule_del(sa, mae_rule); +} + +static int +sfc_repr_proxy_mport_filter_insert(struct sfc_adapter *sa) +{ + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_repr_proxy *rp = &sa->repr_proxy; + struct sfc_rxq *rxq_ctrl; + struct sfc_repr_proxy_filter *filter = &rp->mport_filter; + efx_mport_sel_t mport_alias_selector; + static const efx_filter_match_flags_t flags[RTE_DIM(filter->specs)] = { + EFX_FILTER_MATCH_UNKNOWN_UCAST_DST, + EFX_FILTER_MATCH_UNKNOWN_MCAST_DST }; + unsigned int i; + int rc; + + sfc_log_init(sa, "entry"); + + if (sfc_repr_nb_rxq(sas) == 1) { + rxq_ctrl = &sa->rxq_ctrl[rp->dp_rxq[0].sw_index]; + } else { + sfc_err(sa, "multiple representor proxy RxQs not supported"); + rc = ENOTSUP; + goto fail_multiple_queues; + } + + rc = efx_mae_mport_by_id(&rp->mport_alias, &mport_alias_selector); + if (rc != 0) { + sfc_err(sa, "failed to get repr proxy mport by ID"); + goto fail_get_selector; + } + + memset(filter->specs, 0, sizeof(filter->specs)); + for (i = 0; i < RTE_DIM(filter->specs); i++) { + filter->specs[i].efs_priority = EFX_FILTER_PRI_MANUAL; + filter->specs[i].efs_flags = EFX_FILTER_FLAG_RX; + filter->specs[i].efs_dmaq_id = rxq_ctrl->hw_index; + filter->specs[i].efs_match_flags = flags[i] | + EFX_FILTER_MATCH_MPORT; + filter->specs[i].efs_ingress_mport = mport_alias_selector.sel; + + rc = efx_filter_insert(sa->nic, &filter->specs[i]); + if (rc != 0) { + sfc_err(sa, "failed to insert repr proxy filter"); + goto fail_insert; + } + } + + sfc_log_init(sa, "done"); + + return 0; + +fail_insert: + while (i-- > 0) + efx_filter_remove(sa->nic, &filter->specs[i]); + +fail_get_selector: +fail_multiple_queues: + sfc_log_init(sa, "failed: %s", rte_strerror(rc)); + return rc; +} + +static void +sfc_repr_proxy_mport_filter_remove(struct sfc_adapter *sa) +{ + struct sfc_repr_proxy *rp = &sa->repr_proxy; + struct sfc_repr_proxy_filter *filter = &rp->mport_filter; + unsigned int i; + + for (i = 0; i < RTE_DIM(filter->specs); i++) + efx_filter_remove(sa->nic, &filter->specs[i]); +} + +static int +sfc_repr_proxy_port_rule_insert(struct sfc_adapter *sa, + struct sfc_repr_proxy_port *port) +{ + int rc; + + rc = sfc_repr_proxy_mae_rule_insert(sa, port); + if (rc != 0) + goto fail_mae_rule_insert; + + return 0; + +fail_mae_rule_insert: + return rc; +} + +static void +sfc_repr_proxy_port_rule_remove(struct sfc_adapter *sa, + struct sfc_repr_proxy_port *port) +{ + sfc_repr_proxy_mae_rule_remove(sa, port); +} + static int sfc_repr_proxy_ports_init(struct sfc_adapter *sa) { @@ -644,24 +815,105 @@ sfc_repr_proxy_detach(struct sfc_adapter *sa) sfc_log_init(sa, "done"); } +static int +sfc_repr_proxy_do_start_port(struct sfc_adapter *sa, + struct sfc_repr_proxy_port *port) +{ + struct sfc_repr_proxy *rp = &sa->repr_proxy; + int rc; + + rc = sfc_repr_proxy_port_rule_insert(sa, port); + if (rc != 0) + goto fail_filter_insert; + + if (rp->started) { + rc = sfc_repr_proxy_mbox_send(&rp->mbox, port, + SFC_REPR_PROXY_MBOX_START_PORT); + if (rc != 0) { + sfc_err(sa, "failed to start proxy port %u", + port->repr_id); + goto fail_port_start; + } + } else { + port->started = true; + } + + return 0; + +fail_port_start: + sfc_repr_proxy_port_rule_remove(sa, port); +fail_filter_insert: + sfc_err(sa, "%s() failed %s", __func__, rte_strerror(rc)); + + return rc; +} + +static int +sfc_repr_proxy_do_stop_port(struct sfc_adapter *sa, + struct sfc_repr_proxy_port *port) + +{ + struct sfc_repr_proxy *rp = &sa->repr_proxy; + int rc; + + if (rp->started) { + rc = sfc_repr_proxy_mbox_send(&rp->mbox, port, + SFC_REPR_PROXY_MBOX_STOP_PORT); + if (rc != 0) { + sfc_err(sa, "failed to stop proxy port %u: %s", + port->repr_id, rte_strerror(rc)); + return rc; + } + } else { + port->started = false; + } + + sfc_repr_proxy_port_rule_remove(sa, port); + + return 0; +} + +static bool +sfc_repr_proxy_port_enabled(struct sfc_repr_proxy_port *port) +{ + return port->rte_port_id != RTE_MAX_ETHPORTS && port->enabled; +} + +static bool +sfc_repr_proxy_ports_disabled(struct sfc_repr_proxy *rp) +{ + struct sfc_repr_proxy_port *port; + + TAILQ_FOREACH(port, &rp->ports, entries) { + if (sfc_repr_proxy_port_enabled(port)) + return false; + } + + return true; +} + int sfc_repr_proxy_start(struct sfc_adapter *sa) { struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); struct sfc_repr_proxy *rp = &sa->repr_proxy; + struct sfc_repr_proxy_port *last_port = NULL; + struct sfc_repr_proxy_port *port; int rc; sfc_log_init(sa, "entry"); - /* - * The condition to start the proxy is insufficient. It will be - * complemented with representor port start/stop support. - */ + /* Representor proxy is not started when no representors are started */ if (!sfc_repr_available(sas)) { sfc_log_init(sa, "representors not supported - skip"); return 0; } + if (sfc_repr_proxy_ports_disabled(rp)) { + sfc_log_init(sa, "no started representor ports - skip"); + return 0; + } + rc = sfc_repr_proxy_rxq_start(sa); if (rc != 0) goto fail_rxq_start; @@ -698,12 +950,40 @@ sfc_repr_proxy_start(struct sfc_adapter *sa) goto fail_runstate_set; } + TAILQ_FOREACH(port, &rp->ports, entries) { + if (sfc_repr_proxy_port_enabled(port)) { + rc = sfc_repr_proxy_do_start_port(sa, port); + if (rc != 0) + goto fail_start_id; + + last_port = port; + } + } + + rc = sfc_repr_proxy_mport_filter_insert(sa); + if (rc != 0) + goto fail_mport_filter_insert; + rp->started = true; sfc_log_init(sa, "done"); return 0; +fail_mport_filter_insert: +fail_start_id: + if (last_port != NULL) { + TAILQ_FOREACH(port, &rp->ports, entries) { + if (sfc_repr_proxy_port_enabled(port)) { + (void)sfc_repr_proxy_do_stop_port(sa, port); + if (port == last_port) + break; + } + } + } + + rte_service_runstate_set(rp->service_id, 0); + fail_runstate_set: rte_service_component_runstate_set(rp->service_id, 0); @@ -726,6 +1006,7 @@ sfc_repr_proxy_stop(struct sfc_adapter *sa) { struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); struct sfc_repr_proxy *rp = &sa->repr_proxy; + struct sfc_repr_proxy_port *port; int rc; sfc_log_init(sa, "entry"); @@ -735,6 +1016,24 @@ sfc_repr_proxy_stop(struct sfc_adapter *sa) return; } + if (sfc_repr_proxy_ports_disabled(rp)) { + sfc_log_init(sa, "no started representor ports - skip"); + return; + } + + TAILQ_FOREACH(port, &rp->ports, entries) { + if (sfc_repr_proxy_port_enabled(port)) { + rc = sfc_repr_proxy_do_stop_port(sa, port); + if (rc != 0) { + sfc_err(sa, + "failed to stop representor proxy port %u: %s", + port->repr_id, rte_strerror(rc)); + } + } + } + + sfc_repr_proxy_mport_filter_remove(sa); + rc = rte_service_runstate_set(rp->service_id, 0); if (rc < 0) { sfc_err(sa, "failed to stop %s: %s", @@ -759,19 +1058,6 @@ sfc_repr_proxy_stop(struct sfc_adapter *sa) sfc_log_init(sa, "done"); } -static struct sfc_repr_proxy_port * -sfc_repr_proxy_find_port(struct sfc_repr_proxy *rp, uint16_t repr_id) -{ - struct sfc_repr_proxy_port *port; - - TAILQ_FOREACH(port, &rp->ports, entries) { - if (port->repr_id == repr_id) - return port; - } - - return NULL; -} - int sfc_repr_proxy_add_port(uint16_t pf_port_id, uint16_t repr_id, uint16_t rte_port_id, const efx_mport_sel_t *mport_sel) @@ -1020,3 +1306,136 @@ sfc_repr_proxy_del_txq(uint16_t pf_port_id, uint16_t repr_id, sfc_log_init(sa, "done"); sfc_put_adapter(sa); } + +int +sfc_repr_proxy_start_repr(uint16_t pf_port_id, uint16_t repr_id) +{ + bool proxy_start_required = false; + struct sfc_repr_proxy_port *port; + struct sfc_repr_proxy *rp; + struct sfc_adapter *sa; + int rc; + + sa = sfc_get_adapter_by_pf_port_id(pf_port_id); + rp = sfc_repr_proxy_by_adapter(sa); + + sfc_log_init(sa, "entry"); + + port = sfc_repr_proxy_find_port(rp, repr_id); + if (port == NULL) { + sfc_err(sa, "%s() failed: no such port", __func__); + rc = ENOENT; + goto fail_not_found; + } + + if (port->enabled) { + rc = EALREADY; + sfc_err(sa, "failed: repr %u proxy port already started", + repr_id); + goto fail_already_started; + } + + if (sa->state == SFC_ETHDEV_STARTED) { + if (sfc_repr_proxy_ports_disabled(rp)) { + proxy_start_required = true; + } else { + rc = sfc_repr_proxy_do_start_port(sa, port); + if (rc != 0) { + sfc_err(sa, + "failed to start repr %u proxy port", + repr_id); + goto fail_start_id; + } + } + } + + port->enabled = true; + + if (proxy_start_required) { + rc = sfc_repr_proxy_start(sa); + if (rc != 0) { + sfc_err(sa, "failed to start proxy"); + goto fail_proxy_start; + } + } + + sfc_log_init(sa, "done"); + sfc_put_adapter(sa); + + return 0; + +fail_proxy_start: + port->enabled = false; + +fail_start_id: +fail_already_started: +fail_not_found: + sfc_err(sa, "failed to start repr %u proxy port: %s", repr_id, + rte_strerror(rc)); + sfc_put_adapter(sa); + + return rc; +} + +int +sfc_repr_proxy_stop_repr(uint16_t pf_port_id, uint16_t repr_id) +{ + struct sfc_repr_proxy_port *port; + struct sfc_repr_proxy_port *p; + struct sfc_repr_proxy *rp; + struct sfc_adapter *sa; + int rc; + + sa = sfc_get_adapter_by_pf_port_id(pf_port_id); + rp = sfc_repr_proxy_by_adapter(sa); + + sfc_log_init(sa, "entry"); + + port = sfc_repr_proxy_find_port(rp, repr_id); + if (port == NULL) { + sfc_err(sa, "%s() failed: no such port", __func__); + return ENOENT; + } + + if (!port->enabled) { + sfc_log_init(sa, "repr %u proxy port is not started - skip", + repr_id); + sfc_put_adapter(sa); + return 0; + } + + if (sa->state == SFC_ETHDEV_STARTED) { + bool last_enabled = true; + + TAILQ_FOREACH(p, &rp->ports, entries) { + if (p == port) + continue; + + if (sfc_repr_proxy_port_enabled(p)) { + last_enabled = false; + break; + } + } + + rc = 0; + if (last_enabled) + sfc_repr_proxy_stop(sa); + else + rc = sfc_repr_proxy_do_stop_port(sa, port); + + if (rc != 0) { + sfc_err(sa, + "failed to stop representor proxy TxQ %u: %s", + repr_id, rte_strerror(rc)); + sfc_put_adapter(sa); + return rc; + } + } + + port->enabled = false; + + sfc_log_init(sa, "done"); + sfc_put_adapter(sa); + + return 0; +} diff --git a/drivers/net/sfc/sfc_repr_proxy.h b/drivers/net/sfc/sfc_repr_proxy.h index 1fe7ff3695..c350713a55 100644 --- a/drivers/net/sfc/sfc_repr_proxy.h +++ b/drivers/net/sfc/sfc_repr_proxy.h @@ -19,6 +19,8 @@ #include "sfc_repr.h" #include "sfc_dp.h" +#include "sfc_flow.h" +#include "sfc_mae.h" #ifdef __cplusplus extern "C" { @@ -49,6 +51,14 @@ struct sfc_repr_proxy_txq { struct rte_ring *ring; }; +struct sfc_repr_proxy_filter { + /* + * 2 filters are required to match all incoming traffic, unknown + * unicast and unknown multicast. + */ + efx_filter_spec_t specs[2]; +}; + struct sfc_repr_proxy_port { TAILQ_ENTRY(sfc_repr_proxy_port) entries; uint16_t repr_id; @@ -56,6 +66,9 @@ struct sfc_repr_proxy_port { efx_mport_id_t egress_mport; struct sfc_repr_proxy_rxq rxq[SFC_REPR_RXQ_MAX]; struct sfc_repr_proxy_txq txq[SFC_REPR_TXQ_MAX]; + struct sfc_mae_rule *mae_rule; + bool enabled; + bool started; }; struct sfc_repr_proxy_dp_rxq { @@ -72,6 +85,8 @@ struct sfc_repr_proxy_dp_txq { enum sfc_repr_proxy_mbox_op { SFC_REPR_PROXY_MBOX_ADD_PORT, SFC_REPR_PROXY_MBOX_DEL_PORT, + SFC_REPR_PROXY_MBOX_START_PORT, + SFC_REPR_PROXY_MBOX_STOP_PORT, }; struct sfc_repr_proxy_mbox { @@ -92,6 +107,7 @@ struct sfc_repr_proxy { bool started; struct sfc_repr_proxy_dp_rxq dp_rxq[SFC_REPR_PROXY_NB_RXQ_MAX]; struct sfc_repr_proxy_dp_txq dp_txq[SFC_REPR_PROXY_NB_TXQ_MAX]; + struct sfc_repr_proxy_filter mport_filter; struct sfc_repr_proxy_mbox mbox; }; diff --git a/drivers/net/sfc/sfc_repr_proxy_api.h b/drivers/net/sfc/sfc_repr_proxy_api.h index d1c0760efa..95b065801d 100644 --- a/drivers/net/sfc/sfc_repr_proxy_api.h +++ b/drivers/net/sfc/sfc_repr_proxy_api.h @@ -38,6 +38,9 @@ int sfc_repr_proxy_add_txq(uint16_t pf_port_id, uint16_t repr_id, void sfc_repr_proxy_del_txq(uint16_t pf_port_id, uint16_t repr_id, uint16_t queue_id); +int sfc_repr_proxy_start_repr(uint16_t pf_port_id, uint16_t repr_id); +int sfc_repr_proxy_stop_repr(uint16_t pf_port_id, uint16_t repr_id); + #ifdef __cplusplus } #endif From patchwork Fri Aug 27 06:56:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97442 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 56135A0C43; Fri, 27 Aug 2021 09:00:19 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3E51741285; Fri, 27 Aug 2021 08:58:51 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 6AB94412A8 for ; Fri, 27 Aug 2021 08:58:42 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 277997F6FC; Fri, 27 Aug 2021 09:58:42 +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 051FA7F6E5; Fri, 27 Aug 2021 09:57:35 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 051FA7F6E5 Authentication-Results: shelob.oktetlabs.ru/051FA7F6E5; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:56:59 +0300 Message-Id: <20210827065717.1838258-21-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 20/38] net/sfc: implement port representor link update 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: Igor Romanov Implement the callback by reporting link down if the representor is not started, otherwise report link up with undefined link speed. Link speed is undefined since representors can pass traffic to each other even if the PF link is down. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_repr.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index bfe6dd4c9b..207e7c77a0 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -471,6 +471,24 @@ sfc_repr_dev_infos_get(struct rte_eth_dev *dev, return 0; } +static int +sfc_repr_dev_link_update(struct rte_eth_dev *dev, + __rte_unused int wait_to_complete) +{ + struct sfc_repr *sr = sfc_repr_by_eth_dev(dev); + struct rte_eth_link link; + + if (sr->state != SFC_ETHDEV_STARTED) { + sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, &link); + } else { + memset(&link, 0, sizeof(link)); + link.link_status = ETH_LINK_UP; + link.link_speed = ETH_SPEED_NUM_UNKNOWN; + } + + return rte_eth_linkstatus_set(dev, &link); +} + static int sfc_repr_ring_create(uint16_t pf_port_id, uint16_t repr_id, const char *type_name, uint16_t qid, uint16_t nb_desc, @@ -782,6 +800,7 @@ static const struct eth_dev_ops sfc_repr_dev_ops = { .dev_stop = sfc_repr_dev_stop, .dev_close = sfc_repr_dev_close, .dev_infos_get = sfc_repr_dev_infos_get, + .link_update = sfc_repr_dev_link_update, .rx_queue_setup = sfc_repr_rx_queue_setup, .rx_queue_release = sfc_repr_rx_queue_release, .tx_queue_setup = sfc_repr_tx_queue_setup, From patchwork Fri Aug 27 06:57:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97441 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 E7F9CA0C43; Fri, 27 Aug 2021 09:00:12 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E2877412BC; Fri, 27 Aug 2021 08:58:49 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 615A8412A6 for ; Fri, 27 Aug 2021 08:58:42 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 26BC47F6FD; Fri, 27 Aug 2021 09:58:42 +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 1EA9C7F6E6; Fri, 27 Aug 2021 09:57:35 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 1EA9C7F6E6 Authentication-Results: shelob.oktetlabs.ru/1EA9C7F6E6; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:57:00 +0300 Message-Id: <20210827065717.1838258-22-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 21/38] net/sfc: support multiple device probe 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: Igor Romanov Support probing the device multiple times so that additional port representors can be created with hotplug EAL API. To hotplug a representor, the PF must be hotplugged with different representor device argument. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_ethdev.c | 55 ++++++++++++++++++++++++------------ drivers/net/sfc/sfc_repr.c | 35 +++++++++++++---------- 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 8578ba0765..8f9afb2c67 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -2432,31 +2432,40 @@ sfc_parse_rte_devargs(const char *args, struct rte_eth_devargs *devargs) } static int -sfc_eth_dev_create(struct rte_pci_device *pci_dev, - struct sfc_ethdev_init_data *init_data, - struct rte_eth_dev **devp) +sfc_eth_dev_find_or_create(struct rte_pci_device *pci_dev, + struct sfc_ethdev_init_data *init_data, + struct rte_eth_dev **devp, + bool *dev_created) { struct rte_eth_dev *dev; + bool created = false; int rc; - rc = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name, - sizeof(struct sfc_adapter_shared), - eth_dev_pci_specific_init, pci_dev, - sfc_eth_dev_init, init_data); - if (rc != 0) { - SFC_GENERIC_LOG(ERR, "Failed to create sfc ethdev '%s'", - pci_dev->device.name); - return rc; - } - dev = rte_eth_dev_allocated(pci_dev->device.name); if (dev == NULL) { - SFC_GENERIC_LOG(ERR, "Failed to find allocated sfc ethdev '%s'", + rc = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name, + sizeof(struct sfc_adapter_shared), + eth_dev_pci_specific_init, pci_dev, + sfc_eth_dev_init, init_data); + if (rc != 0) { + SFC_GENERIC_LOG(ERR, "Failed to create sfc ethdev '%s'", + pci_dev->device.name); + return rc; + } + + created = true; + + dev = rte_eth_dev_allocated(pci_dev->device.name); + if (dev == NULL) { + SFC_GENERIC_LOG(ERR, + "Failed to find allocated sfc ethdev '%s'", pci_dev->device.name); - return -ENODEV; + return -ENODEV; + } } *devp = dev; + *dev_created = created; return 0; } @@ -2517,6 +2526,7 @@ static int sfc_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct sfc_ethdev_init_data init_data; struct rte_eth_devargs eth_da; struct rte_eth_dev *dev; + bool dev_created; int rc; if (pci_dev->device.devargs != NULL) { @@ -2538,13 +2548,21 @@ static int sfc_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, return -ENOTSUP; } - rc = sfc_eth_dev_create(pci_dev, &init_data, &dev); + /* + * Driver supports RTE_PCI_DRV_PROBE_AGAIN. Hence create device only + * if it does not already exist. Re-probing an existing device is + * expected to allow additional representors to be configured. + */ + rc = sfc_eth_dev_find_or_create(pci_dev, &init_data, &dev, + &dev_created); if (rc != 0) return rc; rc = sfc_eth_dev_create_representors(dev, ð_da); if (rc != 0) { - (void)rte_eth_dev_destroy(dev, sfc_eth_dev_uninit); + if (dev_created) + (void)rte_eth_dev_destroy(dev, sfc_eth_dev_uninit); + return rc; } @@ -2560,7 +2578,8 @@ static struct rte_pci_driver sfc_efx_pmd = { .id_table = pci_id_sfc_efx_map, .drv_flags = RTE_PCI_DRV_INTR_LSC | - RTE_PCI_DRV_NEED_MAPPING, + RTE_PCI_DRV_NEED_MAPPING | + RTE_PCI_DRV_PROBE_AGAIN, .probe = sfc_eth_dev_pci_probe, .remove = sfc_eth_dev_pci_remove, }; diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index 207e7c77a0..7a34a0a904 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -930,6 +930,7 @@ sfc_repr_create(struct rte_eth_dev *parent, uint16_t representor_id, struct sfc_repr_init_data repr_data; char name[RTE_ETH_NAME_MAX_LEN]; int ret; + struct rte_eth_dev *dev; if (snprintf(name, sizeof(name), "net_%s_representor_%u", parent->device->name, representor_id) >= @@ -938,20 +939,24 @@ sfc_repr_create(struct rte_eth_dev *parent, uint16_t representor_id, return -ENAMETOOLONG; } - memset(&repr_data, 0, sizeof(repr_data)); - repr_data.pf_port_id = parent->data->port_id; - repr_data.repr_id = representor_id; - repr_data.switch_domain_id = switch_domain_id; - repr_data.mport_sel = *mport_sel; - - ret = rte_eth_dev_create(parent->device, name, - sizeof(struct sfc_repr_shared), - NULL, NULL, - sfc_repr_eth_dev_init, &repr_data); - if (ret != 0) - SFC_GENERIC_LOG(ERR, "%s() failed to create device", __func__); - - SFC_GENERIC_LOG(INFO, "%s() done: %s", __func__, rte_strerror(-ret)); + dev = rte_eth_dev_allocated(name); + if (dev == NULL) { + memset(&repr_data, 0, sizeof(repr_data)); + repr_data.pf_port_id = parent->data->port_id; + repr_data.repr_id = representor_id; + repr_data.switch_domain_id = switch_domain_id; + repr_data.mport_sel = *mport_sel; + + ret = rte_eth_dev_create(parent->device, name, + sizeof(struct sfc_repr_shared), + NULL, NULL, + sfc_repr_eth_dev_init, &repr_data); + if (ret != 0) { + SFC_GENERIC_LOG(ERR, "%s() failed to create device", + __func__); + return ret; + } + } - return ret; + return 0; } From patchwork Fri Aug 27 06:57:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97438 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 ABC4DA0C43; Fri, 27 Aug 2021 08:59:53 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 458DE412A8; Fri, 27 Aug 2021 08:58:46 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 4809F41287 for ; Fri, 27 Aug 2021 08:58:42 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 1EC137F6E1; Fri, 27 Aug 2021 09:58:42 +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 382ED7F6E7; Fri, 27 Aug 2021 09:57:35 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 382ED7F6E7 Authentication-Results: shelob.oktetlabs.ru/382ED7F6E7; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:57:01 +0300 Message-Id: <20210827065717.1838258-23-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 22/38] net/sfc: implement representor Tx routine 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: Igor Romanov Forward traffic that is transmitted from a port representor to the corresponding virtual function using the dedicated TxQ. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_repr.c | 45 ++++++++++++++++ drivers/net/sfc/sfc_repr_proxy.c | 88 +++++++++++++++++++++++++++++++- drivers/net/sfc/sfc_repr_proxy.h | 8 +++ 3 files changed, 140 insertions(+), 1 deletion(-) diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index 7a34a0a904..e7386fb480 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -168,6 +168,49 @@ sfc_repr_tx_queue_stop(void *queue) rte_ring_reset(txq->ring); } +static uint16_t +sfc_repr_tx_burst(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +{ + struct sfc_repr_txq *txq = tx_queue; + unsigned int n_tx; + void **objs; + uint16_t i; + + /* + * mbuf is likely cache-hot. Set flag and egress m-port here instead of + * doing that in representors proxy. Also, it should help to avoid + * cache bounce. Moreover, potentially, it allows to use one + * multi-producer single-consumer ring for all representors. + * + * The only potential problem is doing so many times if enqueue + * fails and sender retries. + */ + for (i = 0; i < nb_pkts; ++i) { + struct rte_mbuf *m = tx_pkts[i]; + + m->ol_flags |= sfc_dp_mport_override; + *RTE_MBUF_DYNFIELD(m, sfc_dp_mport_offset, + efx_mport_id_t *) = txq->egress_mport; + } + + objs = (void *)&tx_pkts[0]; + n_tx = rte_ring_sp_enqueue_burst(txq->ring, objs, nb_pkts, NULL); + + /* + * Remove m-port override flag from packets that were not enqueued + * Setting the flag only for enqueued packets after the burst is + * not possible since the ownership of enqueued packets is + * transferred to representor proxy. + */ + for (i = n_tx; i < nb_pkts; ++i) { + struct rte_mbuf *m = tx_pkts[i]; + + m->ol_flags &= ~sfc_dp_mport_override; + } + + return n_tx; +} + static int sfc_repr_start(struct rte_eth_dev *dev) { @@ -782,6 +825,7 @@ sfc_repr_dev_close(struct rte_eth_dev *dev) (void)sfc_repr_proxy_del_port(srs->pf_port_id, srs->repr_id); + dev->tx_pkt_burst = NULL; dev->dev_ops = NULL; sfc_repr_unlock(sr); @@ -902,6 +946,7 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) goto fail_mac_addrs; } + dev->tx_pkt_burst = sfc_repr_tx_burst; dev->dev_ops = &sfc_repr_dev_ops; sr->state = SFC_ETHDEV_INITIALIZED; diff --git a/drivers/net/sfc/sfc_repr_proxy.c b/drivers/net/sfc/sfc_repr_proxy.c index ea03d5afdd..d8934bab65 100644 --- a/drivers/net/sfc/sfc_repr_proxy.c +++ b/drivers/net/sfc/sfc_repr_proxy.c @@ -25,6 +25,12 @@ */ #define SFC_REPR_PROXY_MBOX_POLL_TIMEOUT_MS 1000 +/** + * Amount of time to wait for the representor proxy routine (which is + * running on a service core) to terminate after service core is stopped. + */ +#define SFC_REPR_PROXY_ROUTINE_TERMINATE_TIMEOUT_MS 10000 + static struct sfc_repr_proxy * sfc_repr_proxy_by_adapter(struct sfc_adapter *sa) { @@ -148,16 +154,71 @@ sfc_repr_proxy_mbox_handle(struct sfc_repr_proxy *rp) __atomic_store_n(&mbox->ack, true, __ATOMIC_RELEASE); } +static void +sfc_repr_proxy_handle_tx(struct sfc_repr_proxy_dp_txq *rp_txq, + struct sfc_repr_proxy_txq *repr_txq) +{ + /* + * With multiple representor proxy queues configured it is + * possible that not all of the corresponding representor + * queues were created. Skip the queues that do not exist. + */ + if (repr_txq->ring == NULL) + return; + + if (rp_txq->available < RTE_DIM(rp_txq->tx_pkts)) { + rp_txq->available += + rte_ring_sc_dequeue_burst(repr_txq->ring, + (void **)(&rp_txq->tx_pkts[rp_txq->available]), + RTE_DIM(rp_txq->tx_pkts) - rp_txq->available, + NULL); + + if (rp_txq->available == rp_txq->transmitted) + return; + } + + rp_txq->transmitted += rp_txq->pkt_burst(rp_txq->dp, + &rp_txq->tx_pkts[rp_txq->transmitted], + rp_txq->available - rp_txq->transmitted); + + if (rp_txq->available == rp_txq->transmitted) { + rp_txq->available = 0; + rp_txq->transmitted = 0; + } +} + static int32_t sfc_repr_proxy_routine(void *arg) { + struct sfc_repr_proxy_port *port; struct sfc_repr_proxy *rp = arg; + unsigned int i; sfc_repr_proxy_mbox_handle(rp); + TAILQ_FOREACH(port, &rp->ports, entries) { + if (!port->started) + continue; + + for (i = 0; i < rp->nb_txq; i++) + sfc_repr_proxy_handle_tx(&rp->dp_txq[i], &port->txq[i]); + } + return 0; } +static struct sfc_txq_info * +sfc_repr_proxy_txq_info_get(struct sfc_adapter *sa, unsigned int repr_queue_id) +{ + struct sfc_adapter_shared *sas = sfc_sa2shared(sa); + struct sfc_repr_proxy_dp_txq *dp_txq; + + SFC_ASSERT(repr_queue_id < sfc_repr_nb_txq(sas)); + dp_txq = &sa->repr_proxy.dp_txq[repr_queue_id]; + + return &sas->txq_info[dp_txq->sw_index]; +} + static int sfc_repr_proxy_txq_attach(struct sfc_adapter *sa) { @@ -289,11 +350,20 @@ sfc_repr_proxy_txq_fini(struct sfc_adapter *sa) static int sfc_repr_proxy_txq_start(struct sfc_adapter *sa) { + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); struct sfc_repr_proxy *rp = &sa->repr_proxy; + unsigned int i; sfc_log_init(sa, "entry"); - RTE_SET_USED(rp); + for (i = 0; i < sfc_repr_nb_txq(sas); i++) { + struct sfc_repr_proxy_dp_txq *txq = &rp->dp_txq[i]; + + txq->dp = sfc_repr_proxy_txq_info_get(sa, i)->dp; + txq->pkt_burst = sa->eth_dev->tx_pkt_burst; + txq->available = 0; + txq->transmitted = 0; + } sfc_log_init(sa, "done"); @@ -922,6 +992,8 @@ sfc_repr_proxy_start(struct sfc_adapter *sa) if (rc != 0) goto fail_txq_start; + rp->nb_txq = sfc_repr_nb_txq(sas); + /* Service core may be in "stopped" state, start it */ rc = rte_service_lcore_start(rp->service_core_id); if (rc != 0 && rc != -EALREADY) { @@ -1007,6 +1079,9 @@ sfc_repr_proxy_stop(struct sfc_adapter *sa) struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); struct sfc_repr_proxy *rp = &sa->repr_proxy; struct sfc_repr_proxy_port *port; + const unsigned int wait_ms_total = + SFC_REPR_PROXY_ROUTINE_TERMINATE_TIMEOUT_MS; + unsigned int i; int rc; sfc_log_init(sa, "entry"); @@ -1050,6 +1125,17 @@ sfc_repr_proxy_stop(struct sfc_adapter *sa) /* Service lcore may be shared and we never stop it */ + /* + * Wait for the representor proxy routine to finish the last iteration. + * Give up on timeout. + */ + for (i = 0; i < wait_ms_total; i++) { + if (rte_service_may_be_active(rp->service_id) == 0) + break; + + rte_delay_ms(1); + } + sfc_repr_proxy_rxq_stop(sa); sfc_repr_proxy_txq_stop(sa); diff --git a/drivers/net/sfc/sfc_repr_proxy.h b/drivers/net/sfc/sfc_repr_proxy.h index c350713a55..d47e0a431a 100644 --- a/drivers/net/sfc/sfc_repr_proxy.h +++ b/drivers/net/sfc/sfc_repr_proxy.h @@ -79,6 +79,13 @@ struct sfc_repr_proxy_dp_rxq { }; struct sfc_repr_proxy_dp_txq { + eth_tx_burst_t pkt_burst; + struct sfc_dp_txq *dp; + + unsigned int available; + unsigned int transmitted; + struct rte_mbuf *tx_pkts[SFC_REPR_PROXY_TX_BURST]; + sfc_sw_index_t sw_index; }; @@ -110,6 +117,7 @@ struct sfc_repr_proxy { struct sfc_repr_proxy_filter mport_filter; struct sfc_repr_proxy_mbox mbox; + unsigned int nb_txq; }; struct sfc_adapter; From patchwork Fri Aug 27 06:57:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97439 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 C31A7A0C43; Fri, 27 Aug 2021 08:59:59 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 771AC412B5; Fri, 27 Aug 2021 08:58:47 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 4D7524129B for ; Fri, 27 Aug 2021 08:58:42 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 25EF57F6E0; Fri, 27 Aug 2021 09:58:42 +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 54A4D7F6E9; Fri, 27 Aug 2021 09:57:35 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 54A4D7F6E9 Authentication-Results: shelob.oktetlabs.ru/54A4D7F6E9; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:57:02 +0300 Message-Id: <20210827065717.1838258-24-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 23/38] net/sfc: use xword type for EF100 Rx prefix 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: Igor Romanov Layout of the EF100 Rx prefix is defined in terms of a 32 bytes long value type (xword). Replace oword with xword to avoid truncation. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_ef100_rx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/sfc/sfc_ef100_rx.c b/drivers/net/sfc/sfc_ef100_rx.c index d4cb96881c..15fce55361 100644 --- a/drivers/net/sfc/sfc_ef100_rx.c +++ b/drivers/net/sfc/sfc_ef100_rx.c @@ -379,7 +379,7 @@ static const efx_rx_prefix_layout_t sfc_ef100_rx_prefix_layout = { static bool sfc_ef100_rx_prefix_to_offloads(const struct sfc_ef100_rxq *rxq, - const efx_oword_t *rx_prefix, + const efx_xword_t *rx_prefix, struct rte_mbuf *m) { const efx_word_t *class; @@ -399,19 +399,19 @@ sfc_ef100_rx_prefix_to_offloads(const struct sfc_ef100_rxq *rxq, m->packet_type = sfc_ef100_rx_class_decode(*class, &ol_flags); if ((rxq->flags & SFC_EF100_RXQ_RSS_HASH) && - EFX_TEST_OWORD_BIT(rx_prefix[0], + EFX_TEST_XWORD_BIT(rx_prefix[0], ESF_GZ_RX_PREFIX_RSS_HASH_VALID_LBN)) { ol_flags |= PKT_RX_RSS_HASH; - /* EFX_OWORD_FIELD converts little-endian to CPU */ - m->hash.rss = EFX_OWORD_FIELD(rx_prefix[0], + /* EFX_XWORD_FIELD converts little-endian to CPU */ + m->hash.rss = EFX_XWORD_FIELD(rx_prefix[0], ESF_GZ_RX_PREFIX_RSS_HASH); } if (rxq->flags & SFC_EF100_RXQ_USER_MARK) { uint32_t user_mark; - /* EFX_OWORD_FIELD converts little-endian to CPU */ - user_mark = EFX_OWORD_FIELD(rx_prefix[0], + /* EFX_XWORD_FIELD converts little-endian to CPU */ + user_mark = EFX_XWORD_FIELD(rx_prefix[0], ESF_GZ_RX_PREFIX_USER_MARK); if (user_mark != SFC_EF100_USER_MARK_INVALID) { ol_flags |= PKT_RX_FDIR_ID; @@ -480,7 +480,7 @@ sfc_ef100_rx_process_ready_pkts(struct sfc_ef100_rxq *rxq, while (rxq->ready_pkts > 0 && rx_pkts != rx_pkts_end) { struct rte_mbuf *pkt; struct rte_mbuf *lastseg; - const efx_oword_t *rx_prefix; + const efx_xword_t *rx_prefix; uint16_t pkt_len; uint16_t seg_len; bool deliver; @@ -495,9 +495,9 @@ sfc_ef100_rx_process_ready_pkts(struct sfc_ef100_rxq *rxq, pkt->rearm_data[0] = rxq->rearm_data; /* data_off already moved past Rx prefix */ - rx_prefix = (const efx_oword_t *)sfc_ef100_rx_pkt_prefix(pkt); + rx_prefix = (const efx_xword_t *)sfc_ef100_rx_pkt_prefix(pkt); - pkt_len = EFX_OWORD_FIELD(rx_prefix[0], + pkt_len = EFX_XWORD_FIELD(rx_prefix[0], ESF_GZ_RX_PREFIX_LENGTH); SFC_ASSERT(pkt_len > 0); rte_pktmbuf_pkt_len(pkt) = pkt_len; From patchwork Fri Aug 27 06:57:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97440 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 BA2DFA0C43; Fri, 27 Aug 2021 09:00:06 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B1DB3412B2; Fri, 27 Aug 2021 08:58:48 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 5644A412A3 for ; Fri, 27 Aug 2021 08:58:42 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 230F27F6DF; Fri, 27 Aug 2021 09:58:42 +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 7000B7F6EB; Fri, 27 Aug 2021 09:57:35 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 7000B7F6EB Authentication-Results: shelob.oktetlabs.ru/7000B7F6EB; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:57:03 +0300 Message-Id: <20210827065717.1838258-25-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 24/38] net/sfc: handle ingress m-port in EF100 Rx prefix 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: Igor Romanov Set ingress mport dynamic field in mbuf in EF100. For a given PF, Rx queues of representor devices function on top of the only Rx queue operated by the PF representor proxy facility. This field is a means to demultiplex traffic hitting the queue. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_ef100_rx.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/net/sfc/sfc_ef100_rx.c b/drivers/net/sfc/sfc_ef100_rx.c index 15fce55361..bbf3bf4dc0 100644 --- a/drivers/net/sfc/sfc_ef100_rx.c +++ b/drivers/net/sfc/sfc_ef100_rx.c @@ -62,6 +62,7 @@ struct sfc_ef100_rxq { #define SFC_EF100_RXQ_RSS_HASH 0x10 #define SFC_EF100_RXQ_USER_MARK 0x20 #define SFC_EF100_RXQ_FLAG_INTR_EN 0x40 +#define SFC_EF100_RXQ_INGRESS_MPORT 0x80 unsigned int ptr_mask; unsigned int evq_phase_bit_shift; unsigned int ready_pkts; @@ -370,6 +371,8 @@ static const efx_rx_prefix_layout_t sfc_ef100_rx_prefix_layout = { SFC_EF100_RX_PREFIX_FIELD(LENGTH, B_FALSE), SFC_EF100_RX_PREFIX_FIELD(RSS_HASH_VALID, B_FALSE), SFC_EF100_RX_PREFIX_FIELD(CLASS, B_FALSE), + EFX_RX_PREFIX_FIELD(INGRESS_MPORT, + ESF_GZ_RX_PREFIX_INGRESS_MPORT, B_FALSE), SFC_EF100_RX_PREFIX_FIELD(RSS_HASH, B_FALSE), SFC_EF100_RX_PREFIX_FIELD(USER_MARK, B_FALSE), @@ -419,6 +422,15 @@ sfc_ef100_rx_prefix_to_offloads(const struct sfc_ef100_rxq *rxq, } } + if (rxq->flags & SFC_EF100_RXQ_INGRESS_MPORT) { + ol_flags |= sfc_dp_mport_override; + *RTE_MBUF_DYNFIELD(m, + sfc_dp_mport_offset, + typeof(&((efx_mport_id_t *)0)->id)) = + EFX_XWORD_FIELD(rx_prefix[0], + ESF_GZ_RX_PREFIX_INGRESS_MPORT); + } + m->ol_flags = ol_flags; return true; } @@ -806,6 +818,12 @@ sfc_ef100_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned int evq_read_ptr, else rxq->flags &= ~SFC_EF100_RXQ_USER_MARK; + if ((unsup_rx_prefix_fields & + (1U << EFX_RX_PREFIX_FIELD_INGRESS_MPORT)) == 0) + rxq->flags |= SFC_EF100_RXQ_INGRESS_MPORT; + else + rxq->flags &= ~SFC_EF100_RXQ_INGRESS_MPORT; + rxq->prefix_size = pinfo->erpl_length; rxq->rearm_data = sfc_ef100_mk_mbuf_rearm_data(rxq->dp.dpq.port_id, rxq->prefix_size); From patchwork Fri Aug 27 06:57:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97446 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 25B62A0C54; Fri, 27 Aug 2021 09:00:47 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id EE095412DA; Fri, 27 Aug 2021 08:58:58 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 6AF72410E9 for ; Fri, 27 Aug 2021 08:58:54 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 40E477F6E3; Fri, 27 Aug 2021 09:58:54 +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 8BC097F6EC; Fri, 27 Aug 2021 09:57:35 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 8BC097F6EC Authentication-Results: shelob.oktetlabs.ru/8BC097F6EC; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:57:04 +0300 Message-Id: <20210827065717.1838258-26-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 25/38] net/sfc: implement representor Rx routine 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: Igor Romanov Implement traffic forwarding for representor and representor proxy from virtual functions to representor Rx queues. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_repr.c | 12 +++ drivers/net/sfc/sfc_repr_proxy.c | 134 +++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_repr_proxy.h | 11 +++ 3 files changed, 157 insertions(+) diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index e7386fb480..a436b7e5e1 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -168,6 +168,16 @@ sfc_repr_tx_queue_stop(void *queue) rte_ring_reset(txq->ring); } +static uint16_t +sfc_repr_rx_burst(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) +{ + struct sfc_repr_rxq *rxq = rx_queue; + void **objs = (void *)&rx_pkts[0]; + + /* mbufs port is already filled correctly by representors proxy */ + return rte_ring_sc_dequeue_burst(rxq->ring, objs, nb_pkts, NULL); +} + static uint16_t sfc_repr_tx_burst(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) { @@ -825,6 +835,7 @@ sfc_repr_dev_close(struct rte_eth_dev *dev) (void)sfc_repr_proxy_del_port(srs->pf_port_id, srs->repr_id); + dev->rx_pkt_burst = NULL; dev->tx_pkt_burst = NULL; dev->dev_ops = NULL; @@ -946,6 +957,7 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) goto fail_mac_addrs; } + dev->rx_pkt_burst = sfc_repr_rx_burst; dev->tx_pkt_burst = sfc_repr_tx_burst; dev->dev_ops = &sfc_repr_dev_ops; diff --git a/drivers/net/sfc/sfc_repr_proxy.c b/drivers/net/sfc/sfc_repr_proxy.c index d8934bab65..535b07ea52 100644 --- a/drivers/net/sfc/sfc_repr_proxy.c +++ b/drivers/net/sfc/sfc_repr_proxy.c @@ -18,6 +18,7 @@ #include "sfc_ev.h" #include "sfc_rx.h" #include "sfc_tx.h" +#include "sfc_dp_rx.h" /** * Amount of time to wait for the representor proxy routine (which is @@ -31,6 +32,8 @@ */ #define SFC_REPR_PROXY_ROUTINE_TERMINATE_TIMEOUT_MS 10000 +#define SFC_REPR_INVALID_ROUTE_PORT_ID (UINT16_MAX) + static struct sfc_repr_proxy * sfc_repr_proxy_by_adapter(struct sfc_adapter *sa) { @@ -187,6 +190,113 @@ sfc_repr_proxy_handle_tx(struct sfc_repr_proxy_dp_txq *rp_txq, } } +static struct sfc_repr_proxy_port * +sfc_repr_proxy_rx_route_mbuf(struct sfc_repr_proxy *rp, struct rte_mbuf *m) +{ + struct sfc_repr_proxy_port *port; + efx_mport_id_t mport_id; + + mport_id.id = *RTE_MBUF_DYNFIELD(m, sfc_dp_mport_offset, + typeof(&((efx_mport_id_t *)0)->id)); + + TAILQ_FOREACH(port, &rp->ports, entries) { + if (port->egress_mport.id == mport_id.id) { + m->port = port->rte_port_id; + m->ol_flags &= ~sfc_dp_mport_override; + return port; + } + } + + return NULL; +} + +/* + * Returns true if a packet is encountered which should be forwarded to a + * port which is different from the one that is currently routed. + */ +static bool +sfc_repr_proxy_rx_route(struct sfc_repr_proxy *rp, + struct sfc_repr_proxy_dp_rxq *rp_rxq) +{ + unsigned int i; + + for (i = rp_rxq->routed; + i < rp_rxq->available && !rp_rxq->stop_route; + i++, rp_rxq->routed++) { + struct sfc_repr_proxy_port *port; + struct rte_mbuf *m = rp_rxq->pkts[i]; + + port = sfc_repr_proxy_rx_route_mbuf(rp, m); + /* Cannot find destination representor */ + if (port == NULL) { + /* Effectively drop the packet */ + rp_rxq->forwarded++; + continue; + } + + /* Currently routed packets are mapped to a different port */ + if (port->repr_id != rp_rxq->route_port_id && + rp_rxq->route_port_id != SFC_REPR_INVALID_ROUTE_PORT_ID) + return true; + + rp_rxq->route_port_id = port->repr_id; + } + + return false; +} + +static void +sfc_repr_proxy_rx_forward(struct sfc_repr_proxy *rp, + struct sfc_repr_proxy_dp_rxq *rp_rxq) +{ + struct sfc_repr_proxy_port *port; + + if (rp_rxq->route_port_id != SFC_REPR_INVALID_ROUTE_PORT_ID) { + port = sfc_repr_proxy_find_port(rp, rp_rxq->route_port_id); + + if (port != NULL && port->started) { + rp_rxq->forwarded += + rte_ring_sp_enqueue_burst(port->rxq[0].ring, + (void **)(&rp_rxq->pkts[rp_rxq->forwarded]), + rp_rxq->routed - rp_rxq->forwarded, NULL); + } else { + /* Drop all routed packets if the port is not started */ + rp_rxq->forwarded = rp_rxq->routed; + } + } + + if (rp_rxq->forwarded == rp_rxq->routed) { + rp_rxq->route_port_id = SFC_REPR_INVALID_ROUTE_PORT_ID; + rp_rxq->stop_route = false; + } else { + /* Stall packet routing if not all packets were forwarded */ + rp_rxq->stop_route = true; + } + + if (rp_rxq->available == rp_rxq->forwarded) + rp_rxq->available = rp_rxq->forwarded = rp_rxq->routed = 0; +} + +static void +sfc_repr_proxy_handle_rx(struct sfc_repr_proxy *rp, + struct sfc_repr_proxy_dp_rxq *rp_rxq) +{ + bool route_again; + + if (rp_rxq->available < RTE_DIM(rp_rxq->pkts)) { + rp_rxq->available += rp_rxq->pkt_burst(rp_rxq->dp, + &rp_rxq->pkts[rp_rxq->available], + RTE_DIM(rp_rxq->pkts) - rp_rxq->available); + if (rp_rxq->available == rp_rxq->forwarded) + return; + } + + do { + route_again = sfc_repr_proxy_rx_route(rp, rp_rxq); + sfc_repr_proxy_rx_forward(rp, rp_rxq); + } while (route_again && !rp_rxq->stop_route); +} + static int32_t sfc_repr_proxy_routine(void *arg) { @@ -204,6 +314,9 @@ sfc_repr_proxy_routine(void *arg) sfc_repr_proxy_handle_tx(&rp->dp_txq[i], &port->txq[i]); } + for (i = 0; i < rp->nb_rxq; i++) + sfc_repr_proxy_handle_rx(rp, &rp->dp_rxq[i]); + return 0; } @@ -412,6 +525,18 @@ sfc_repr_proxy_rxq_detach(struct sfc_adapter *sa) sfc_log_init(sa, "done"); } +static struct sfc_rxq_info * +sfc_repr_proxy_rxq_info_get(struct sfc_adapter *sa, unsigned int repr_queue_id) +{ + struct sfc_adapter_shared *sas = sfc_sa2shared(sa); + struct sfc_repr_proxy_dp_rxq *dp_rxq; + + SFC_ASSERT(repr_queue_id < sfc_repr_nb_rxq(sas)); + dp_rxq = &sa->repr_proxy.dp_rxq[repr_queue_id]; + + return &sas->rxq_info[dp_rxq->sw_index]; +} + static int sfc_repr_proxy_rxq_init(struct sfc_adapter *sa, struct sfc_repr_proxy_dp_rxq *rxq) @@ -539,6 +664,14 @@ sfc_repr_proxy_rxq_start(struct sfc_adapter *sa) i); goto fail_start; } + + rxq->dp = sfc_repr_proxy_rxq_info_get(sa, i)->dp; + rxq->pkt_burst = sa->eth_dev->rx_pkt_burst; + rxq->available = 0; + rxq->routed = 0; + rxq->forwarded = 0; + rxq->stop_route = false; + rxq->route_port_id = SFC_REPR_INVALID_ROUTE_PORT_ID; } sfc_log_init(sa, "done"); @@ -993,6 +1126,7 @@ sfc_repr_proxy_start(struct sfc_adapter *sa) goto fail_txq_start; rp->nb_txq = sfc_repr_nb_txq(sas); + rp->nb_rxq = sfc_repr_nb_rxq(sas); /* Service core may be in "stopped" state, start it */ rc = rte_service_lcore_start(rp->service_core_id); diff --git a/drivers/net/sfc/sfc_repr_proxy.h b/drivers/net/sfc/sfc_repr_proxy.h index d47e0a431a..b49b1a2a96 100644 --- a/drivers/net/sfc/sfc_repr_proxy.h +++ b/drivers/net/sfc/sfc_repr_proxy.h @@ -75,6 +75,16 @@ struct sfc_repr_proxy_dp_rxq { struct rte_mempool *mp; unsigned int ref_count; + eth_rx_burst_t pkt_burst; + struct sfc_dp_rxq *dp; + + uint16_t route_port_id; + bool stop_route; + unsigned int available; + unsigned int forwarded; + unsigned int routed; + struct rte_mbuf *pkts[SFC_REPR_PROXY_TX_BURST]; + sfc_sw_index_t sw_index; }; @@ -118,6 +128,7 @@ struct sfc_repr_proxy { struct sfc_repr_proxy_mbox mbox; unsigned int nb_txq; + unsigned int nb_rxq; }; struct sfc_adapter; From patchwork Fri Aug 27 06:57:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97445 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 08D55A0C43; Fri, 27 Aug 2021 09:00:39 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 47E18412D1; Fri, 27 Aug 2021 08:58:57 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id DC6EB412BF for ; Fri, 27 Aug 2021 08:58:53 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id AB4EF7F6E2; Fri, 27 Aug 2021 09:58:53 +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 A66857F6ED; Fri, 27 Aug 2021 09:57:35 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru A66857F6ED Authentication-Results: shelob.oktetlabs.ru/A66857F6ED; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Fri, 27 Aug 2021 09:57:05 +0300 Message-Id: <20210827065717.1838258-27-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 26/38] net/sfc: add simple port representor statistics 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: Igor Romanov Gather statistics of enqueued and dequeued packets in Rx and Tx burst callbacks to report in stats_get callback. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- drivers/net/sfc/sfc_repr.c | 60 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index a436b7e5e1..4fd81c3f6b 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -32,9 +32,14 @@ struct sfc_repr_shared { uint16_t switch_port_id; }; +struct sfc_repr_queue_stats { + union sfc_pkts_bytes packets_bytes; +}; + struct sfc_repr_rxq { /* Datapath members */ struct rte_ring *ring; + struct sfc_repr_queue_stats stats; /* Non-datapath members */ struct sfc_repr_shared *shared; @@ -45,6 +50,7 @@ struct sfc_repr_txq { /* Datapath members */ struct rte_ring *ring; efx_mport_id_t egress_mport; + struct sfc_repr_queue_stats stats; /* Non-datapath members */ struct sfc_repr_shared *shared; @@ -173,15 +179,30 @@ sfc_repr_rx_burst(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) { struct sfc_repr_rxq *rxq = rx_queue; void **objs = (void *)&rx_pkts[0]; + unsigned int n_rx; /* mbufs port is already filled correctly by representors proxy */ - return rte_ring_sc_dequeue_burst(rxq->ring, objs, nb_pkts, NULL); + n_rx = rte_ring_sc_dequeue_burst(rxq->ring, objs, nb_pkts, NULL); + + if (n_rx > 0) { + unsigned int n_bytes = 0; + unsigned int i = 0; + + do { + n_bytes += rx_pkts[i]->pkt_len; + } while (++i < n_rx); + + sfc_pkts_bytes_add(&rxq->stats.packets_bytes, n_rx, n_bytes); + } + + return n_rx; } static uint16_t sfc_repr_tx_burst(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) { struct sfc_repr_txq *txq = tx_queue; + unsigned int n_bytes = 0; unsigned int n_tx; void **objs; uint16_t i; @@ -201,6 +222,7 @@ sfc_repr_tx_burst(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) m->ol_flags |= sfc_dp_mport_override; *RTE_MBUF_DYNFIELD(m, sfc_dp_mport_offset, efx_mport_id_t *) = txq->egress_mport; + n_bytes += tx_pkts[i]->pkt_len; } objs = (void *)&tx_pkts[0]; @@ -210,14 +232,18 @@ sfc_repr_tx_burst(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) * Remove m-port override flag from packets that were not enqueued * Setting the flag only for enqueued packets after the burst is * not possible since the ownership of enqueued packets is - * transferred to representor proxy. + * transferred to representor proxy. The same logic applies to + * counting the enqueued packets' bytes. */ for (i = n_tx; i < nb_pkts; ++i) { struct rte_mbuf *m = tx_pkts[i]; m->ol_flags &= ~sfc_dp_mport_override; + n_bytes -= m->pkt_len; } + sfc_pkts_bytes_add(&txq->stats.packets_bytes, n_tx, n_bytes); + return n_tx; } @@ -849,6 +875,35 @@ sfc_repr_dev_close(struct rte_eth_dev *dev) return 0; } +static int +sfc_repr_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) +{ + union sfc_pkts_bytes queue_stats; + uint16_t i; + + for (i = 0; i < dev->data->nb_rx_queues; i++) { + struct sfc_repr_rxq *rxq = dev->data->rx_queues[i]; + + sfc_pkts_bytes_get(&rxq->stats.packets_bytes, + &queue_stats); + + stats->ipackets += queue_stats.pkts; + stats->ibytes += queue_stats.bytes; + } + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + struct sfc_repr_txq *txq = dev->data->tx_queues[i]; + + sfc_pkts_bytes_get(&txq->stats.packets_bytes, + &queue_stats); + + stats->opackets += queue_stats.pkts; + stats->obytes += queue_stats.bytes; + } + + return 0; +} + static const struct eth_dev_ops sfc_repr_dev_ops = { .dev_configure = sfc_repr_dev_configure, .dev_start = sfc_repr_dev_start, @@ -856,6 +911,7 @@ static const struct eth_dev_ops sfc_repr_dev_ops = { .dev_close = sfc_repr_dev_close, .dev_infos_get = sfc_repr_dev_infos_get, .link_update = sfc_repr_dev_link_update, + .stats_get = sfc_repr_stats_get, .rx_queue_setup = sfc_repr_rx_queue_setup, .rx_queue_release = sfc_repr_rx_queue_release, .tx_queue_setup = sfc_repr_tx_queue_setup, From patchwork Fri Aug 27 06:57:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97443 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 9C582A0C43; Fri, 27 Aug 2021 09:00:27 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E9851412C7; Fri, 27 Aug 2021 08:58:54 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id CC1CF410E9; Fri, 27 Aug 2021 08:58:53 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id A31997F6E6; Fri, 27 Aug 2021 09:58:53 +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 C30697F6EE; Fri, 27 Aug 2021 09:57:35 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru C30697F6EE Authentication-Results: shelob.oktetlabs.ru/C30697F6EE; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , stable@dpdk.org, Andy Moreton Date: Fri, 27 Aug 2021 09:57:06 +0300 Message-Id: <20210827065717.1838258-28-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 27/38] net/sfc: free MAE lock once switch domain is assigned 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: Viacheslav Galaktionov If for some reason the hardware switch ID initialization function fails, MAE lock is still held after the function finishes. This patch fixes that. Fixes: 1e7fbdf0ba19 ("net/sfc: support concept of switch domains/ports") Cc: stable@dpdk.org Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_switch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/sfc/sfc_switch.c b/drivers/net/sfc/sfc_switch.c index c37cdf4a61..80c884a599 100644 --- a/drivers/net/sfc/sfc_switch.c +++ b/drivers/net/sfc/sfc_switch.c @@ -214,9 +214,9 @@ sfc_mae_assign_switch_domain(struct sfc_adapter *sa, fail_mem_alloc: sfc_hw_switch_id_fini(sa, hw_switch_id); - rte_spinlock_unlock(&sfc_mae_switch.lock); fail_hw_switch_id_init: + rte_spinlock_unlock(&sfc_mae_switch.lock); return rc; } From patchwork Fri Aug 27 06:57:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97444 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 4A276A0C43; Fri, 27 Aug 2021 09:00:33 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 20134412CC; Fri, 27 Aug 2021 08:58:56 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id D4C71412A6 for ; Fri, 27 Aug 2021 08:58:53 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id AA2B37F6E3; Fri, 27 Aug 2021 09:58:53 +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 DF4DC7F6EF; Fri, 27 Aug 2021 09:57:35 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru DF4DC7F6EF Authentication-Results: shelob.oktetlabs.ru/DF4DC7F6EF; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , Andy Moreton Date: Fri, 27 Aug 2021 09:57:07 +0300 Message-Id: <20210827065717.1838258-29-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 28/38] common/sfc_efx/base: add multi-host function M-port selector 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: Viacheslav Galaktionov Provide helper function to compose multi-host aware PCIe function M-port selector. The firmware expects mport selectors to use different sets of values to represent a PCIe interface in mport selectors and elsewhere. In order to avoid having the user perform the conversion themselves, it is now done automatically when a selector is constructed. In addition, a type has been added to libefx for possible PCIe interfaces. This is done to abstract different representations away from the users. Allow to support matching traffic coming from an arbitrary PCIe end-point of the NIC and redirect traffic to it. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx.h | 22 +++++++ drivers/common/sfc_efx/base/efx_mae.c | 86 +++++++++++++++++++++++---- drivers/common/sfc_efx/version.map | 1 + 3 files changed, 96 insertions(+), 13 deletions(-) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 0a178128ba..159e7957a3 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -82,6 +82,13 @@ efx_family( #if EFSYS_OPT_PCI +/* PCIe interface numbers for multi-host configurations. */ +typedef enum efx_pcie_interface_e { + EFX_PCIE_INTERFACE_CALLER = 1000, + EFX_PCIE_INTERFACE_HOST_PRIMARY, + EFX_PCIE_INTERFACE_NIC_EMBEDDED, +} efx_pcie_interface_t; + typedef struct efx_pci_ops_s { /* * Function for reading PCIe configuration space. @@ -4237,6 +4244,21 @@ efx_mae_mport_by_pcie_function( __in uint32_t vf, __out efx_mport_sel_t *mportp); +/* + * Get MPORT selector of a multi-host PCIe function. + * + * The resulting MPORT selector is opaque to the caller and can be + * passed as an argument to efx_mae_match_spec_mport_set() + * and efx_mae_action_set_populate_deliver(). + */ +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_mport_by_pcie_mh_function( + __in efx_pcie_interface_t intf, + __in uint32_t pf, + __in uint32_t vf, + __out efx_mport_sel_t *mportp); + /* * Get MPORT selector by an MPORT ID * diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index 3f498fe189..37cc48eafc 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -727,35 +727,95 @@ efx_mae_mport_by_pcie_function( efx_dword_t dword; efx_rc_t rc; + rc = efx_mae_mport_by_pcie_mh_function(EFX_PCIE_INTERFACE_CALLER, + pf, vf, mportp); + if (rc != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + +static __checkReturn efx_rc_t +efx_mae_intf_to_selector( + __in efx_pcie_interface_t intf, + __out uint32_t *selector_intfp) +{ + efx_rc_t rc; + + switch (intf) { + case EFX_PCIE_INTERFACE_HOST_PRIMARY: + EFX_STATIC_ASSERT(MAE_MPORT_SELECTOR_HOST_PRIMARY <= + EFX_MASK32(MAE_MPORT_SELECTOR_FUNC_INTF_ID)); + *selector_intfp = MAE_MPORT_SELECTOR_HOST_PRIMARY; + break; + case EFX_PCIE_INTERFACE_NIC_EMBEDDED: + EFX_STATIC_ASSERT(MAE_MPORT_SELECTOR_NIC_EMBEDDED <= + EFX_MASK32(MAE_MPORT_SELECTOR_FUNC_INTF_ID)); + *selector_intfp = MAE_MPORT_SELECTOR_NIC_EMBEDDED; + break; + case EFX_PCIE_INTERFACE_CALLER: + EFX_STATIC_ASSERT(MAE_MPORT_SELECTOR_CALLER_INTF <= + EFX_MASK32(MAE_MPORT_SELECTOR_FUNC_INTF_ID)); + *selector_intfp = MAE_MPORT_SELECTOR_CALLER_INTF; + break; + default: + rc = EINVAL; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mae_mport_by_pcie_mh_function( + __in efx_pcie_interface_t intf, + __in uint32_t pf, + __in uint32_t vf, + __out efx_mport_sel_t *mportp) +{ + uint32_t selector_intf; + efx_dword_t dword; + efx_rc_t rc; + EFX_STATIC_ASSERT(EFX_PCI_VF_INVALID == MAE_MPORT_SELECTOR_FUNC_VF_ID_NULL); - if (pf > EFX_MASK32(MAE_MPORT_SELECTOR_FUNC_PF_ID)) { - rc = EINVAL; + rc = efx_mae_intf_to_selector(intf, &selector_intf); + if (rc != 0) goto fail1; + + if (pf > EFX_MASK32(MAE_MPORT_SELECTOR_FUNC_MH_PF_ID)) { + rc = EINVAL; + goto fail2; } if (vf > EFX_MASK32(MAE_MPORT_SELECTOR_FUNC_VF_ID)) { rc = EINVAL; - goto fail2; + goto fail3; } - EFX_POPULATE_DWORD_3(dword, - MAE_MPORT_SELECTOR_TYPE, MAE_MPORT_SELECTOR_TYPE_FUNC, - MAE_MPORT_SELECTOR_FUNC_PF_ID, pf, + + EFX_POPULATE_DWORD_4(dword, + MAE_MPORT_SELECTOR_TYPE, MAE_MPORT_SELECTOR_TYPE_MH_FUNC, + MAE_MPORT_SELECTOR_FUNC_INTF_ID, selector_intf, + MAE_MPORT_SELECTOR_FUNC_MH_PF_ID, pf, MAE_MPORT_SELECTOR_FUNC_VF_ID, vf); memset(mportp, 0, sizeof (*mportp)); - /* - * The constructed DWORD is little-endian, - * but the resulting value is meant to be - * passed to MCDIs, where it will undergo - * host-order to little endian conversion. - */ - mportp->sel = EFX_DWORD_FIELD(dword, EFX_DWORD_0); + mportp->sel = dword.ed_u32[0]; return (0); +fail3: + EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 3488367f68..225909892b 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -125,6 +125,7 @@ INTERNAL { efx_mae_match_specs_class_cmp; efx_mae_match_specs_equal; efx_mae_mport_by_pcie_function; + efx_mae_mport_by_pcie_mh_function; efx_mae_mport_by_phy_port; efx_mae_mport_by_id; efx_mae_mport_free; From patchwork Fri Aug 27 06:57:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97447 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 3F595A0C43; Fri, 27 Aug 2021 09:00:53 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2D4C241283; Fri, 27 Aug 2021 08:59:01 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 9F27541281 for ; Fri, 27 Aug 2021 08:58:59 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 7561D7F6E1; Fri, 27 Aug 2021 09:58:59 +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 0451B7F6F0; Fri, 27 Aug 2021 09:57:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 0451B7F6F0 Authentication-Results: shelob.oktetlabs.ru/0451B7F6F0; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , Andy Moreton Date: Fri, 27 Aug 2021 09:57:08 +0300 Message-Id: <20210827065717.1838258-30-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 29/38] common/sfc_efx/base: retrieve function interfaces for VNICs 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: Viacheslav Galaktionov This information is required to be able to fully identify the function. Add this information to the NIC configuration structure for easy access. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/ef10_impl.h | 3 +- drivers/common/sfc_efx/base/ef10_nic.c | 4 +- drivers/common/sfc_efx/base/efx.h | 1 + drivers/common/sfc_efx/base/efx_impl.h | 6 +++ drivers/common/sfc_efx/base/efx_mcdi.c | 55 +++++++++++++++++++++++-- 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/drivers/common/sfc_efx/base/ef10_impl.h b/drivers/common/sfc_efx/base/ef10_impl.h index 7c8d51b7a5..d48f238479 100644 --- a/drivers/common/sfc_efx/base/ef10_impl.h +++ b/drivers/common/sfc_efx/base/ef10_impl.h @@ -1372,7 +1372,8 @@ extern __checkReturn efx_rc_t efx_mcdi_get_function_info( __in efx_nic_t *enp, __out uint32_t *pfp, - __out_opt uint32_t *vfp); + __out_opt uint32_t *vfp, + __out_opt efx_pcie_interface_t *intfp); LIBEFX_INTERNAL extern __checkReturn efx_rc_t diff --git a/drivers/common/sfc_efx/base/ef10_nic.c b/drivers/common/sfc_efx/base/ef10_nic.c index eda0ad3068..3cd9ff89d0 100644 --- a/drivers/common/sfc_efx/base/ef10_nic.c +++ b/drivers/common/sfc_efx/base/ef10_nic.c @@ -1847,6 +1847,7 @@ efx_mcdi_nic_board_cfg( efx_nic_cfg_t *encp = &(enp->en_nic_cfg); ef10_link_state_t els; efx_port_t *epp = &(enp->en_port); + efx_pcie_interface_t intf; uint32_t board_type = 0; uint32_t base, nvec; uint32_t port; @@ -1875,11 +1876,12 @@ efx_mcdi_nic_board_cfg( * - PCIe PF: pf = PF number, vf = 0xffff. * - PCIe VF: pf = parent PF, vf = VF number. */ - if ((rc = efx_mcdi_get_function_info(enp, &pf, &vf)) != 0) + if ((rc = efx_mcdi_get_function_info(enp, &pf, &vf, &intf)) != 0) goto fail3; encp->enc_pf = pf; encp->enc_vf = vf; + encp->enc_intf = intf; if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0) goto fail4; diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 159e7957a3..996126217e 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -1511,6 +1511,7 @@ typedef struct efx_nic_cfg_s { uint32_t enc_bist_mask; #endif /* EFSYS_OPT_BIST */ #if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() + efx_pcie_interface_t enc_intf; uint32_t enc_pf; uint32_t enc_vf; uint32_t enc_privilege_mask; diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h index 992edbabe3..e0efbb8cdd 100644 --- a/drivers/common/sfc_efx/base/efx_impl.h +++ b/drivers/common/sfc_efx/base/efx_impl.h @@ -1529,6 +1529,12 @@ efx_mcdi_get_workarounds( #if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() +LIBEFX_INTERNAL +extern __checkReturn efx_rc_t +efx_mcdi_intf_from_pcie( + __in uint32_t pcie_intf, + __out efx_pcie_interface_t *efx_intf); + LIBEFX_INTERNAL extern __checkReturn efx_rc_t efx_mcdi_init_evq( diff --git a/drivers/common/sfc_efx/base/efx_mcdi.c b/drivers/common/sfc_efx/base/efx_mcdi.c index b68fc0503d..69bf7ce70f 100644 --- a/drivers/common/sfc_efx/base/efx_mcdi.c +++ b/drivers/common/sfc_efx/base/efx_mcdi.c @@ -2130,6 +2130,36 @@ efx_mcdi_mac_stats_periodic( #if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() + __checkReturn efx_rc_t +efx_mcdi_intf_from_pcie( + __in uint32_t pcie_intf, + __out efx_pcie_interface_t *efx_intf) +{ + efx_rc_t rc; + + switch (pcie_intf) { + case PCIE_INTERFACE_CALLER: + *efx_intf = EFX_PCIE_INTERFACE_CALLER; + break; + case PCIE_INTERFACE_HOST_PRIMARY: + *efx_intf = EFX_PCIE_INTERFACE_HOST_PRIMARY; + break; + case PCIE_INTERFACE_NIC_EMBEDDED: + *efx_intf = EFX_PCIE_INTERFACE_NIC_EMBEDDED; + break; + default: + rc = EINVAL; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + /* * This function returns the pf and vf number of a function. If it is a pf the * vf number is 0xffff. The vf number is the index of the vf on that @@ -2140,18 +2170,21 @@ efx_mcdi_mac_stats_periodic( efx_mcdi_get_function_info( __in efx_nic_t *enp, __out uint32_t *pfp, - __out_opt uint32_t *vfp) + __out_opt uint32_t *vfp, + __out_opt efx_pcie_interface_t *intfp) { + efx_pcie_interface_t intf; efx_mcdi_req_t req; EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_FUNCTION_INFO_IN_LEN, - MC_CMD_GET_FUNCTION_INFO_OUT_LEN); + MC_CMD_GET_FUNCTION_INFO_OUT_V2_LEN); + uint32_t pcie_intf; efx_rc_t rc; req.emr_cmd = MC_CMD_GET_FUNCTION_INFO; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_GET_FUNCTION_INFO_IN_LEN; req.emr_out_buf = payload; - req.emr_out_length = MC_CMD_GET_FUNCTION_INFO_OUT_LEN; + req.emr_out_length = MC_CMD_GET_FUNCTION_INFO_OUT_V2_LEN; efx_mcdi_execute(enp, &req); @@ -2169,8 +2202,24 @@ efx_mcdi_get_function_info( if (vfp != NULL) *vfp = MCDI_OUT_DWORD(req, GET_FUNCTION_INFO_OUT_VF); + if (req.emr_out_length < MC_CMD_GET_FUNCTION_INFO_OUT_V2_LEN) { + intf = EFX_PCIE_INTERFACE_HOST_PRIMARY; + } else { + pcie_intf = MCDI_OUT_DWORD(req, + GET_FUNCTION_INFO_OUT_V2_INTF); + + rc = efx_mcdi_intf_from_pcie(pcie_intf, &intf); + if (rc != 0) + goto fail3; + } + + if (intfp != NULL) + *intfp = intf; + return (0); +fail3: + EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: From patchwork Fri Aug 27 06:57:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97448 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 A87A3A0C43; Fri, 27 Aug 2021 09:00:58 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5B774412D5; Fri, 27 Aug 2021 08:59:02 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 3795B41286 for ; Fri, 27 Aug 2021 08:59:00 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 06AF57F6E3; Fri, 27 Aug 2021 09:59:00 +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 20A1F7F6F1; Fri, 27 Aug 2021 09:57:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 20A1F7F6F1 Authentication-Results: shelob.oktetlabs.ru/20A1F7F6F1; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , Andy Moreton Date: Fri, 27 Aug 2021 09:57:09 +0300 Message-Id: <20210827065717.1838258-31-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 30/38] common/sfc_efx/base: add a means to read MAE mport journal 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: Viacheslav Galaktionov This is required to provide the driver with the current state of mports. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx.h | 56 +++++++ drivers/common/sfc_efx/base/efx_mae.c | 224 +++++++++++++++++++++++++ drivers/common/sfc_efx/base/efx_mcdi.h | 54 ++++++ drivers/common/sfc_efx/version.map | 1 + 4 files changed, 335 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 996126217e..e77b297950 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -4205,6 +4205,42 @@ typedef struct efx_mport_id_s { uint32_t id; } efx_mport_id_t; +typedef enum efx_mport_type_e { + EFX_MPORT_TYPE_NET_PORT = 0, + EFX_MPORT_TYPE_ALIAS, + EFX_MPORT_TYPE_VNIC, +} efx_mport_type_t; + +typedef enum efx_mport_vnic_client_type_e { + EFX_MPORT_VNIC_CLIENT_FUNCTION = 1, + EFX_MPORT_VNIC_CLIENT_PLUGIN, +} efx_mport_vnic_client_type_t; + +typedef struct efx_mport_desc_s { + efx_mport_id_t emd_id; + boolean_t emd_can_receive_on; + boolean_t emd_can_deliver_to; + boolean_t emd_can_delete; + boolean_t emd_zombie; + efx_mport_type_t emd_type; + union { + struct { + uint32_t ep_index; + } emd_net_port; + struct { + efx_mport_id_t ea_target_mport_id; + } emd_alias; + struct { + efx_mport_vnic_client_type_t ev_client_type; + efx_pcie_interface_t ev_intf; + uint16_t ev_pf; + uint16_t ev_vf; + /* MCDI client handle for this VNIC. */ + uint32_t ev_handle; + } emd_vnic; + }; +} efx_mport_desc_t; + #define EFX_MPORT_NULL (0U) /* @@ -4635,6 +4671,26 @@ efx_mae_mport_free( __in efx_nic_t *enp, __in const efx_mport_id_t *mportp); +typedef __checkReturn efx_rc_t +(efx_mae_read_mport_journal_cb)( + __in void *cb_datap, + __in efx_mport_desc_t *mportp, + __in size_t mport_len); + +/* + * Read mport descriptions from the MAE journal (which describes added and + * removed mports) and pass them to a user-supplied callback. The user gets + * only one chance to process the data it's given. Once the callback function + * finishes, that particular mport description will be gone. + * The journal will be fully repopulated on PCI reset (efx_nic_reset function). + */ +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mae_read_mport_journal( + __in efx_nic_t *enp, + __in efx_mae_read_mport_journal_cb *cbp, + __in void *cb_datap); + #endif /* EFSYS_OPT_MAE */ #if EFSYS_OPT_VIRTIO diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index 37cc48eafc..110addd92d 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -3292,4 +3292,228 @@ efx_mae_mport_free( return (rc); } +static __checkReturn efx_rc_t +efx_mae_read_mport_journal_single( + __in uint8_t *entry_buf, + __out efx_mport_desc_t *desc) +{ + uint32_t pcie_intf; + efx_rc_t rc; + + memset(desc, 0, sizeof (*desc)); + + desc->emd_id.id = MCDI_STRUCT_DWORD(entry_buf, + MAE_MPORT_DESC_V2_MPORT_ID); + + desc->emd_can_receive_on = MCDI_STRUCT_DWORD_FIELD(entry_buf, + MAE_MPORT_DESC_V2_FLAGS, + MAE_MPORT_DESC_V2_CAN_RECEIVE_ON); + + desc->emd_can_deliver_to = MCDI_STRUCT_DWORD_FIELD(entry_buf, + MAE_MPORT_DESC_V2_FLAGS, + MAE_MPORT_DESC_V2_CAN_DELIVER_TO); + + desc->emd_can_delete = MCDI_STRUCT_DWORD_FIELD(entry_buf, + MAE_MPORT_DESC_V2_FLAGS, + MAE_MPORT_DESC_V2_CAN_DELETE); + + desc->emd_zombie = MCDI_STRUCT_DWORD_FIELD(entry_buf, + MAE_MPORT_DESC_V2_FLAGS, + MAE_MPORT_DESC_V2_IS_ZOMBIE); + + desc->emd_type = MCDI_STRUCT_DWORD(entry_buf, + MAE_MPORT_DESC_V2_MPORT_TYPE); + + /* + * We can't check everything here. If some additional checks are + * required, they should be performed by the callback function. + */ + switch (desc->emd_type) { + case EFX_MPORT_TYPE_NET_PORT: + desc->emd_net_port.ep_index = + MCDI_STRUCT_DWORD(entry_buf, + MAE_MPORT_DESC_V2_NET_PORT_IDX); + break; + case EFX_MPORT_TYPE_ALIAS: + desc->emd_alias.ea_target_mport_id.id = + MCDI_STRUCT_DWORD(entry_buf, + MAE_MPORT_DESC_V2_ALIAS_DELIVER_MPORT_ID); + break; + case EFX_MPORT_TYPE_VNIC: + desc->emd_vnic.ev_client_type = + MCDI_STRUCT_DWORD(entry_buf, + MAE_MPORT_DESC_V2_VNIC_CLIENT_TYPE); + if (desc->emd_vnic.ev_client_type != + EFX_MPORT_VNIC_CLIENT_FUNCTION) + break; + + pcie_intf = MCDI_STRUCT_DWORD(entry_buf, + MAE_MPORT_DESC_V2_VNIC_FUNCTION_INTERFACE); + rc = efx_mcdi_intf_from_pcie(pcie_intf, + &desc->emd_vnic.ev_intf); + if (rc != 0) + goto fail1; + + desc->emd_vnic.ev_pf = MCDI_STRUCT_WORD(entry_buf, + MAE_MPORT_DESC_V2_VNIC_FUNCTION_PF_IDX); + desc->emd_vnic.ev_vf = MCDI_STRUCT_WORD(entry_buf, + MAE_MPORT_DESC_V2_VNIC_FUNCTION_VF_IDX); + desc->emd_vnic.ev_handle = MCDI_STRUCT_DWORD(entry_buf, + MAE_MPORT_DESC_V2_VNIC_CLIENT_HANDLE); + break; + default: + rc = EINVAL; + goto fail2; + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + +static __checkReturn efx_rc_t +efx_mae_read_mport_journal_batch( + __in efx_nic_t *enp, + __in efx_mae_read_mport_journal_cb *cbp, + __in void *cb_datap, + __out uint32_t *morep) +{ + efx_mcdi_req_t req; + EFX_MCDI_DECLARE_BUF(payload, + MC_CMD_MAE_MPORT_READ_JOURNAL_IN_LEN, + MC_CMD_MAE_MPORT_READ_JOURNAL_OUT_LENMAX_MCDI2); + uint32_t n_entries; + uint32_t entry_sz; + uint8_t *entry_buf; + unsigned int i; + efx_rc_t rc; + + EFX_STATIC_ASSERT(EFX_MPORT_TYPE_NET_PORT == + MAE_MPORT_DESC_V2_MPORT_TYPE_NET_PORT); + EFX_STATIC_ASSERT(EFX_MPORT_TYPE_ALIAS == + MAE_MPORT_DESC_V2_MPORT_TYPE_ALIAS); + EFX_STATIC_ASSERT(EFX_MPORT_TYPE_VNIC == + MAE_MPORT_DESC_V2_MPORT_TYPE_VNIC); + + EFX_STATIC_ASSERT(EFX_MPORT_VNIC_CLIENT_FUNCTION == + MAE_MPORT_DESC_V2_VNIC_CLIENT_TYPE_FUNCTION); + EFX_STATIC_ASSERT(EFX_MPORT_VNIC_CLIENT_PLUGIN == + MAE_MPORT_DESC_V2_VNIC_CLIENT_TYPE_PLUGIN); + + if (cbp == NULL) { + rc = EINVAL; + goto fail1; + } + + req.emr_cmd = MC_CMD_MAE_MPORT_READ_JOURNAL; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_MAE_MPORT_READ_JOURNAL_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_MAE_MPORT_READ_JOURNAL_OUT_LENMAX_MCDI2; + + MCDI_IN_SET_DWORD(req, MAE_MPORT_READ_JOURNAL_IN_FLAGS, 0); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail2; + } + + if (req.emr_out_length_used < + MC_CMD_MAE_MPORT_READ_JOURNAL_OUT_LENMIN) { + rc = EMSGSIZE; + goto fail3; + } + + if (morep != NULL) { + *morep = MCDI_OUT_DWORD_FIELD(req, + MAE_MPORT_READ_JOURNAL_OUT_FLAGS, + MAE_MPORT_READ_JOURNAL_OUT_MORE); + } + n_entries = MCDI_OUT_DWORD(req, + MAE_MPORT_READ_JOURNAL_OUT_MPORT_DESC_COUNT); + entry_sz = MCDI_OUT_DWORD(req, + MAE_MPORT_READ_JOURNAL_OUT_SIZEOF_MPORT_DESC); + entry_buf = MCDI_OUT2(req, uint8_t, + MAE_MPORT_READ_JOURNAL_OUT_MPORT_DESC_DATA); + + if (entry_sz < MAE_MPORT_DESC_V2_VNIC_CLIENT_HANDLE_OFST + + MAE_MPORT_DESC_V2_VNIC_CLIENT_HANDLE_LEN) { + rc = EINVAL; + goto fail4; + } + if (n_entries * entry_sz / entry_sz != n_entries) { + rc = EINVAL; + goto fail5; + } + if (req.emr_out_length_used != + MC_CMD_MAE_MPORT_READ_JOURNAL_OUT_LENMIN + n_entries * entry_sz) { + rc = EINVAL; + goto fail6; + } + + for (i = 0; i < n_entries; i++) { + efx_mport_desc_t desc; + + rc = efx_mae_read_mport_journal_single(entry_buf, &desc); + if (rc != 0) + continue; + + (*cbp)(cb_datap, &desc, sizeof (desc)); + entry_buf += entry_sz; + } + + return (0); + +fail6: + EFSYS_PROBE(fail6); +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_mae_read_mport_journal( + __in efx_nic_t *enp, + __in efx_mae_read_mport_journal_cb *cbp, + __in void *cb_datap) +{ + const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); + uint32_t more = 0; + efx_rc_t rc; + + if (encp->enc_mae_supported == B_FALSE) { + rc = ENOTSUP; + goto fail1; + } + + do { + rc = efx_mae_read_mport_journal_batch(enp, cbp, cb_datap, + &more); + if (rc != 0) + goto fail2; + } while (more != 0); + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + #endif /* EFSYS_OPT_MAE */ diff --git a/drivers/common/sfc_efx/base/efx_mcdi.h b/drivers/common/sfc_efx/base/efx_mcdi.h index 90b70de97b..96f237b1b0 100644 --- a/drivers/common/sfc_efx/base/efx_mcdi.h +++ b/drivers/common/sfc_efx/base/efx_mcdi.h @@ -462,6 +462,60 @@ efx_mcdi_phy_module_get_info( EFX_DWORD_FIELD(*(MCDI_OUT2(_emr, efx_dword_t, _ofst) + \ (_idx)), _field) +#define MCDI_OUT_INDEXED_STRUCT_MEMBER(_emr, _type, _arr_ofst, _idx, \ + _member_ofst) \ + ((_type *)(MCDI_OUT2(_emr, uint8_t, _arr_ofst) + \ + _idx * MC_CMD_ ## _arr_ofst ## _LEN + \ + _member_ofst ## _OFST)) + +#define MCDI_OUT_INDEXED_MEMBER_DWORD(_emr, _arr_ofst, _idx, \ + _member_ofst) \ + EFX_DWORD_FIELD( \ + *(MCDI_OUT_INDEXED_STRUCT_MEMBER(_emr, efx_dword_t, \ + _arr_ofst, _idx, \ + _member_ofst)), \ + EFX_DWORD_0) + +#define MCDI_OUT_INDEXED_MEMBER_QWORD(_emr, _arr_ofst, _idx, \ + _member_ofst) \ + ((uint64_t)EFX_QWORD_FIELD( \ + *(MCDI_OUT_INDEXED_STRUCT_MEMBER(_emr, efx_qword_t, \ + _arr_ofst, _idx, \ + _member_ofst)), \ + EFX_DWORD_0) | \ + (uint64_t)EFX_QWORD_FIELD( \ + *(MCDI_OUT_INDEXED_STRUCT_MEMBER(_emr, efx_qword_t, \ + _arr_ofst, _idx, \ + _member_ofst)), \ + EFX_DWORD_1) << 32) + +#define MCDI_STRUCT_MEMBER(_buf, _type, _ofst) \ + ((_type *)((char *)_buf + _ofst ## _OFST)) \ + +#define MCDI_STRUCT_BYTE(_buf, _ofst) \ + EFX_BYTE_FIELD(*MCDI_STRUCT_MEMBER(_buf, efx_byte_t, _ofst), \ + EFX_BYTE_0) + +#define MCDI_STRUCT_BYTE_FIELD(_buf, _ofst, _field) \ + EFX_BYTE_FIELD(*MCDI_STRUCT_MEMBER(_buf, efx_byte_t, _ofst), \ + _field) + +#define MCDI_STRUCT_WORD(_buf, _ofst) \ + EFX_WORD_FIELD(*MCDI_STRUCT_MEMBER(_buf, efx_word_t, _ofst), \ + EFX_WORD_0) + +#define MCDI_STRUCT_WORD_FIELD(_buf, _ofst, _field) \ + EFX_WORD_FIELD(*MCDI_STRUCT_MEMBER(_buf, efx_word_t, _ofst), \ + _field) + +#define MCDI_STRUCT_DWORD(_buf, _ofst) \ + EFX_DWORD_FIELD(*MCDI_STRUCT_MEMBER(_buf, efx_dword_t, _ofst), \ + EFX_DWORD_0) + +#define MCDI_STRUCT_DWORD_FIELD(_buf, _ofst, _field) \ + EFX_DWORD_FIELD(*MCDI_STRUCT_MEMBER(_buf, efx_dword_t, _ofst), \ + _field) + #define MCDI_EV_FIELD(_eqp, _field) \ EFX_QWORD_FIELD(*_eqp, MCDI_EVENT_ ## _field) diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 225909892b..10216bb37d 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -133,6 +133,7 @@ INTERNAL { efx_mae_mport_invalid; efx_mae_outer_rule_insert; efx_mae_outer_rule_remove; + efx_mae_read_mport_journal; efx_mcdi_fini; efx_mcdi_get_proxy_handle; From patchwork Fri Aug 27 06:57:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97449 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 44FA1A0C43; Fri, 27 Aug 2021 09:01:06 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0A01B41284; Fri, 27 Aug 2021 08:59:04 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id DF28B41283 for ; Fri, 27 Aug 2021 08:59:00 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id A85C47F6E5; Fri, 27 Aug 2021 09:58:59 +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 40A367F6F2; Fri, 27 Aug 2021 09:57:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 40A367F6F2 Authentication-Results: shelob.oktetlabs.ru/40A367F6F2; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , Andy Moreton Date: Fri, 27 Aug 2021 09:57:10 +0300 Message-Id: <20210827065717.1838258-32-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 31/38] common/sfc_efx/base: allow getting VNIC MCDI client handles 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: Viacheslav Galaktionov Equality checks between VNICs should be done by comparing their client handles. This means that clients should be able to retrieve client handles for arbitrary functions and themselves. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx.h | 15 ++++++ drivers/common/sfc_efx/base/efx_mcdi.c | 73 ++++++++++++++++++++++++++ drivers/common/sfc_efx/version.map | 2 + 3 files changed, 90 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index e77b297950..b61984a8e3 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -391,6 +391,21 @@ extern __checkReturn boolean_t efx_mcdi_request_abort( __in efx_nic_t *enp); +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mcdi_get_client_handle( + __in efx_nic_t *enp, + __in efx_pcie_interface_t intf, + __in uint16_t pf, + __in uint16_t vf, + __out uint32_t *handle); + +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mcdi_get_own_client_handle( + __in efx_nic_t *enp, + __out uint32_t *handle); + LIBEFX_API extern void efx_mcdi_fini( diff --git a/drivers/common/sfc_efx/base/efx_mcdi.c b/drivers/common/sfc_efx/base/efx_mcdi.c index 69bf7ce70f..cdf7181e0d 100644 --- a/drivers/common/sfc_efx/base/efx_mcdi.c +++ b/drivers/common/sfc_efx/base/efx_mcdi.c @@ -647,6 +647,79 @@ efx_mcdi_request_abort( return (aborted); } + __checkReturn efx_rc_t +efx_mcdi_get_client_handle( + __in efx_nic_t *enp, + __in efx_pcie_interface_t intf, + __in uint16_t pf, + __in uint16_t vf, + __out uint32_t *handle) +{ + efx_mcdi_req_t req; + EFX_MCDI_DECLARE_BUF(payload, + MC_CMD_GET_CLIENT_HANDLE_IN_LEN, + MC_CMD_GET_CLIENT_HANDLE_OUT_LEN); + efx_rc_t rc; + + if (handle == NULL) { + rc = EINVAL; + goto fail1; + } + + req.emr_cmd = MC_CMD_GET_CLIENT_HANDLE; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_GET_CLIENT_HANDLE_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_GET_CLIENT_HANDLE_OUT_LEN; + + MCDI_IN_SET_DWORD(req, GET_CLIENT_HANDLE_IN_TYPE, + MC_CMD_GET_CLIENT_HANDLE_IN_TYPE_FUNC); + MCDI_IN_SET_WORD(req, GET_CLIENT_HANDLE_IN_FUNC_PF, pf); + MCDI_IN_SET_WORD(req, GET_CLIENT_HANDLE_IN_FUNC_VF, vf); + MCDI_IN_SET_DWORD(req, GET_CLIENT_HANDLE_IN_FUNC_INTF, intf); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail2; + } + + if (req.emr_out_length_used < MC_CMD_GET_CLIENT_HANDLE_OUT_LEN) { + rc = EMSGSIZE; + goto fail3; + } + + *handle = MCDI_OUT_DWORD(req, GET_CLIENT_HANDLE_OUT_HANDLE); + + return 0; +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mcdi_get_own_client_handle( + __in efx_nic_t *enp, + __out uint32_t *handle) +{ + efx_rc_t rc; + + rc = efx_mcdi_get_client_handle(enp, PCIE_INTERFACE_CALLER, + PCIE_FUNCTION_PF_NULL, PCIE_FUNCTION_VF_NULL, handle); + if (rc != 0) + goto fail1; + + return (0); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + void efx_mcdi_get_timeout( __in efx_nic_t *enp, diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 10216bb37d..346deb4b12 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -136,6 +136,8 @@ INTERNAL { efx_mae_read_mport_journal; efx_mcdi_fini; + efx_mcdi_get_client_handle; + efx_mcdi_get_own_client_handle; efx_mcdi_get_proxy_handle; efx_mcdi_get_timeout; efx_mcdi_init; From patchwork Fri Aug 27 06:57:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97450 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 A9308A0C55; Fri, 27 Aug 2021 09:01:12 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 32D68412E2; Fri, 27 Aug 2021 08:59:07 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 8DE9B412E2 for ; Fri, 27 Aug 2021 08:59:05 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 659467F6E4; Fri, 27 Aug 2021 09:59:05 +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 5D48D7F6F3; Fri, 27 Aug 2021 09:57:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 5D48D7F6F3 Authentication-Results: shelob.oktetlabs.ru/5D48D7F6F3; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , Andy Moreton Date: Fri, 27 Aug 2021 09:57:11 +0300 Message-Id: <20210827065717.1838258-33-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 32/38] net/sfc: maintain controller to EFX interface mapping 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: Viacheslav Galaktionov Newer hardware may have arbitrarily complex controller configurations, and for this reason the mapping has been made dynamic: it is represented with a dynamic array that is indexed by controller numbers and each element contains an EFX interface number. Since the number of controllers is expected to be small, this approach should not hurt the performance. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_ethdev.c | 184 +++++++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_switch.c | 57 +++++++++++ drivers/net/sfc/sfc_switch.h | 8 ++ 3 files changed, 249 insertions(+) diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 8f9afb2c67..8536a2b111 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -30,6 +30,7 @@ #include "sfc_dp_rx.h" #include "sfc_repr.h" #include "sfc_sw_stats.h" +#include "sfc_switch.h" #define SFC_XSTAT_ID_INVALID_VAL UINT64_MAX #define SFC_XSTAT_ID_INVALID_NAME '\0' @@ -1862,6 +1863,177 @@ sfc_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t ethdev_qid) return sap->dp_rx->intr_disable(rxq_info->dp); } +struct sfc_mport_journal_ctx { + struct sfc_adapter *sa; + uint16_t switch_domain_id; + uint32_t mcdi_handle; + bool controllers_assigned; + efx_pcie_interface_t *controllers; + size_t nb_controllers; +}; + +static int +sfc_journal_ctx_add_controller(struct sfc_mport_journal_ctx *ctx, + efx_pcie_interface_t intf) +{ + efx_pcie_interface_t *new_controllers; + size_t i, target; + size_t new_size; + + if (ctx->controllers == NULL) { + ctx->controllers = rte_malloc("sfc_controller_mapping", + sizeof(ctx->controllers[0]), 0); + if (ctx->controllers == NULL) + return ENOMEM; + + ctx->controllers[0] = intf; + ctx->nb_controllers = 1; + + return 0; + } + + for (i = 0; i < ctx->nb_controllers; i++) { + if (ctx->controllers[i] == intf) + return 0; + if (ctx->controllers[i] > intf) + break; + } + target = i; + + ctx->nb_controllers += 1; + new_size = ctx->nb_controllers * sizeof(ctx->controllers[0]); + + new_controllers = rte_realloc(ctx->controllers, new_size, 0); + if (new_controllers == NULL) { + rte_free(ctx->controllers); + return ENOMEM; + } + ctx->controllers = new_controllers; + + for (i = target + 1; i < ctx->nb_controllers; i++) + ctx->controllers[i] = ctx->controllers[i - 1]; + + ctx->controllers[target] = intf; + + return 0; +} + +static efx_rc_t +sfc_process_mport_journal_entry(struct sfc_mport_journal_ctx *ctx, + efx_mport_desc_t *mport) +{ + efx_mport_sel_t ethdev_mport; + int rc; + + sfc_dbg(ctx->sa, + "processing mport id %u (controller %u pf %u vf %u)", + mport->emd_id.id, mport->emd_vnic.ev_intf, + mport->emd_vnic.ev_pf, mport->emd_vnic.ev_vf); + efx_mae_mport_invalid(ðdev_mport); + + if (!ctx->controllers_assigned) { + rc = sfc_journal_ctx_add_controller(ctx, + mport->emd_vnic.ev_intf); + if (rc != 0) + return rc; + } + + return 0; +} + +static efx_rc_t +sfc_process_mport_journal_cb(void *data, efx_mport_desc_t *mport, + size_t mport_len) +{ + struct sfc_mport_journal_ctx *ctx = data; + + if (ctx == NULL || ctx->sa == NULL) { + sfc_err(ctx->sa, "received NULL context or SFC adapter"); + return EINVAL; + } + + if (mport_len != sizeof(*mport)) { + sfc_err(ctx->sa, "actual and expected mport buffer sizes differ"); + return EINVAL; + } + + SFC_ASSERT(sfc_adapter_is_locked(ctx->sa)); + + /* + * If a zombie flag is set, it means the mport has been marked for + * deletion and cannot be used for any new operations. The mport will + * be destroyed completely once all references to it are released. + */ + if (mport->emd_zombie) { + sfc_dbg(ctx->sa, "mport is a zombie, skipping"); + return 0; + } + if (mport->emd_type != EFX_MPORT_TYPE_VNIC) { + sfc_dbg(ctx->sa, "mport is not a VNIC, skipping"); + return 0; + } + if (mport->emd_vnic.ev_client_type != EFX_MPORT_VNIC_CLIENT_FUNCTION) { + sfc_dbg(ctx->sa, "mport is not a function, skipping"); + return 0; + } + if (mport->emd_vnic.ev_handle == ctx->mcdi_handle) { + sfc_dbg(ctx->sa, "mport is this driver instance, skipping"); + return 0; + } + + return sfc_process_mport_journal_entry(ctx, mport); +} + +static int +sfc_process_mport_journal(struct sfc_adapter *sa) +{ + struct sfc_mport_journal_ctx ctx; + const efx_pcie_interface_t *controllers; + size_t nb_controllers; + efx_rc_t efx_rc; + int rc; + + memset(&ctx, 0, sizeof(ctx)); + ctx.sa = sa; + ctx.switch_domain_id = sa->mae.switch_domain_id; + + efx_rc = efx_mcdi_get_own_client_handle(sa->nic, &ctx.mcdi_handle); + if (efx_rc != 0) { + sfc_err(sa, "failed to get own MCDI handle"); + SFC_ASSERT(efx_rc > 0); + return efx_rc; + } + + rc = sfc_mae_switch_domain_controllers(ctx.switch_domain_id, + &controllers, &nb_controllers); + if (rc != 0) { + sfc_err(sa, "failed to get controller mapping"); + return rc; + } + + ctx.controllers_assigned = controllers != NULL; + ctx.controllers = NULL; + ctx.nb_controllers = 0; + + efx_rc = efx_mae_read_mport_journal(sa->nic, + sfc_process_mport_journal_cb, &ctx); + if (efx_rc != 0) { + sfc_err(sa, "failed to process MAE mport journal"); + SFC_ASSERT(efx_rc > 0); + return efx_rc; + } + + if (controllers == NULL) { + rc = sfc_mae_switch_domain_map_controllers(ctx.switch_domain_id, + ctx.controllers, + ctx.nb_controllers); + if (rc != 0) + return rc; + } + + return 0; +} + static const struct eth_dev_ops sfc_eth_dev_ops = { .dev_configure = sfc_dev_configure, .dev_start = sfc_dev_start, @@ -2494,6 +2666,18 @@ sfc_eth_dev_create_representors(struct rte_eth_dev *dev, return -ENOTSUP; } + /* + * This is needed to construct the DPDK controller -> EFX interface + * mapping. + */ + sfc_adapter_lock(sa); + rc = sfc_process_mport_journal(sa); + sfc_adapter_unlock(sa); + if (rc != 0) { + SFC_ASSERT(rc > 0); + return -rc; + } + for (i = 0; i < eth_da->nb_representor_ports; ++i) { const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); efx_mport_sel_t mport_sel; diff --git a/drivers/net/sfc/sfc_switch.c b/drivers/net/sfc/sfc_switch.c index 80c884a599..f72f6648b8 100644 --- a/drivers/net/sfc/sfc_switch.c +++ b/drivers/net/sfc/sfc_switch.c @@ -87,6 +87,10 @@ struct sfc_mae_switch_domain { struct sfc_mae_switch_ports ports; /** RTE switch domain ID allocated for a group of devices */ uint16_t id; + /** DPDK controller -> EFX interface mapping */ + efx_pcie_interface_t *controllers; + /** Number of DPDK controllers and EFX interfaces */ + size_t nb_controllers; }; TAILQ_HEAD(sfc_mae_switch_domains, sfc_mae_switch_domain); @@ -220,6 +224,59 @@ sfc_mae_assign_switch_domain(struct sfc_adapter *sa, return rc; } +int +sfc_mae_switch_domain_controllers(uint16_t switch_domain_id, + const efx_pcie_interface_t **controllers, + size_t *nb_controllers) +{ + struct sfc_mae_switch_domain *domain; + + if (controllers == NULL || nb_controllers == NULL) + return EINVAL; + + rte_spinlock_lock(&sfc_mae_switch.lock); + + domain = sfc_mae_find_switch_domain_by_id(switch_domain_id); + if (domain == NULL) { + rte_spinlock_unlock(&sfc_mae_switch.lock); + return EINVAL; + } + + *controllers = domain->controllers; + *nb_controllers = domain->nb_controllers; + + rte_spinlock_unlock(&sfc_mae_switch.lock); + return 0; +} + +int +sfc_mae_switch_domain_map_controllers(uint16_t switch_domain_id, + efx_pcie_interface_t *controllers, + size_t nb_controllers) +{ + struct sfc_mae_switch_domain *domain; + + rte_spinlock_lock(&sfc_mae_switch.lock); + + domain = sfc_mae_find_switch_domain_by_id(switch_domain_id); + if (domain == NULL) { + rte_spinlock_unlock(&sfc_mae_switch.lock); + return EINVAL; + } + + /* Controller mapping may be set only once */ + if (domain->controllers != NULL) { + rte_spinlock_unlock(&sfc_mae_switch.lock); + return EINVAL; + } + + domain->controllers = controllers; + domain->nb_controllers = nb_controllers; + + rte_spinlock_unlock(&sfc_mae_switch.lock); + return 0; +} + /* This function expects to be called only when the lock is held */ static struct sfc_mae_switch_port * sfc_mae_find_switch_port_by_entity(const struct sfc_mae_switch_domain *domain, diff --git a/drivers/net/sfc/sfc_switch.h b/drivers/net/sfc/sfc_switch.h index a1a2ab9848..1eee5fc0b6 100644 --- a/drivers/net/sfc/sfc_switch.h +++ b/drivers/net/sfc/sfc_switch.h @@ -44,6 +44,14 @@ struct sfc_mae_switch_port_request { int sfc_mae_assign_switch_domain(struct sfc_adapter *sa, uint16_t *switch_domain_id); +int sfc_mae_switch_domain_controllers(uint16_t switch_domain_id, + const efx_pcie_interface_t **controllers, + size_t *nb_controllers); + +int sfc_mae_switch_domain_map_controllers(uint16_t switch_domain_id, + efx_pcie_interface_t *controllers, + size_t nb_controllers); + int sfc_mae_assign_switch_port(uint16_t switch_domain_id, const struct sfc_mae_switch_port_request *req, uint16_t *switch_port_id); From patchwork Fri Aug 27 06:57:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97452 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 99413A0C41; Fri, 27 Aug 2021 09:01:24 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8C21441293; Fri, 27 Aug 2021 08:59:14 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id EB94241269 for ; Fri, 27 Aug 2021 08:59:11 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id C1AEC7F6E7; Fri, 27 Aug 2021 09:59:11 +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 769167F6F4; Fri, 27 Aug 2021 09:57:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 769167F6F4 Authentication-Results: shelob.oktetlabs.ru/769167F6F4; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , Andy Moreton Date: Fri, 27 Aug 2021 09:57:12 +0300 Message-Id: <20210827065717.1838258-34-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 33/38] net/sfc: store PCI address for represented entities 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: Viacheslav Galaktionov This information will be useful when representor info API is implemented. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_ethdev.c | 11 +++++++++-- drivers/net/sfc/sfc_repr.c | 20 +++++++++++++++----- drivers/net/sfc/sfc_repr.h | 10 +++++++++- drivers/net/sfc/sfc_switch.c | 14 ++++++++++++++ drivers/net/sfc/sfc_switch.h | 11 +++++++++++ 5 files changed, 58 insertions(+), 8 deletions(-) diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 8536a2b111..49ba820501 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -2680,6 +2680,7 @@ sfc_eth_dev_create_representors(struct rte_eth_dev *dev, for (i = 0; i < eth_da->nb_representor_ports; ++i) { const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + struct sfc_repr_entity_info entity; efx_mport_sel_t mport_sel; rc = efx_mae_mport_by_pcie_function(encp->enc_pf, @@ -2692,8 +2693,14 @@ sfc_eth_dev_create_representors(struct rte_eth_dev *dev, continue; } - rc = sfc_repr_create(dev, eth_da->representor_ports[i], - sa->mae.switch_domain_id, &mport_sel); + memset(&entity, 0, sizeof(entity)); + entity.type = eth_da->type; + entity.intf = encp->enc_intf; + entity.pf = encp->enc_pf; + entity.vf = eth_da->representor_ports[i]; + + rc = sfc_repr_create(dev, &entity, sa->mae.switch_domain_id, + &mport_sel); if (rc != 0) { sfc_err(sa, "cannot create representor %u: %s - ignore", eth_da->representor_ports[i], diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index 4fd81c3f6b..a42e70c92c 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -924,6 +924,9 @@ struct sfc_repr_init_data { uint16_t repr_id; uint16_t switch_domain_id; efx_mport_sel_t mport_sel; + efx_pcie_interface_t intf; + uint16_t pf; + uint16_t vf; }; static int @@ -961,6 +964,9 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) switch_port_request.ethdev_mportp = ðdev_mport_sel; switch_port_request.entity_mportp = &repr_data->mport_sel; switch_port_request.ethdev_port_id = dev->data->port_id; + switch_port_request.port_data.repr.intf = repr_data->intf; + switch_port_request.port_data.repr.pf = repr_data->pf; + switch_port_request.port_data.repr.vf = repr_data->vf; ret = sfc_repr_assign_mae_switch_port(repr_data->switch_domain_id, &switch_port_request, @@ -1037,8 +1043,10 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) } int -sfc_repr_create(struct rte_eth_dev *parent, uint16_t representor_id, - uint16_t switch_domain_id, const efx_mport_sel_t *mport_sel) +sfc_repr_create(struct rte_eth_dev *parent, + struct sfc_repr_entity_info *entity, + uint16_t switch_domain_id, + const efx_mport_sel_t *mport_sel) { struct sfc_repr_init_data repr_data; char name[RTE_ETH_NAME_MAX_LEN]; @@ -1046,8 +1054,7 @@ sfc_repr_create(struct rte_eth_dev *parent, uint16_t representor_id, struct rte_eth_dev *dev; if (snprintf(name, sizeof(name), "net_%s_representor_%u", - parent->device->name, representor_id) >= - (int)sizeof(name)) { + parent->device->name, entity->vf) >= (int)sizeof(name)) { SFC_GENERIC_LOG(ERR, "%s() failed name too long", __func__); return -ENAMETOOLONG; } @@ -1056,9 +1063,12 @@ sfc_repr_create(struct rte_eth_dev *parent, uint16_t representor_id, if (dev == NULL) { memset(&repr_data, 0, sizeof(repr_data)); repr_data.pf_port_id = parent->data->port_id; - repr_data.repr_id = representor_id; + repr_data.repr_id = entity->vf; repr_data.switch_domain_id = switch_domain_id; repr_data.mport_sel = *mport_sel; + repr_data.intf = entity->intf; + repr_data.pf = entity->pf; + repr_data.vf = entity->vf; ret = rte_eth_dev_create(parent->device, name, sizeof(struct sfc_repr_shared), diff --git a/drivers/net/sfc/sfc_repr.h b/drivers/net/sfc/sfc_repr.h index 1347206006..2093973761 100644 --- a/drivers/net/sfc/sfc_repr.h +++ b/drivers/net/sfc/sfc_repr.h @@ -26,7 +26,15 @@ extern "C" { /** Max count of the representor Tx queues */ #define SFC_REPR_TXQ_MAX 1 -int sfc_repr_create(struct rte_eth_dev *parent, uint16_t representor_id, +struct sfc_repr_entity_info { + enum rte_eth_representor_type type; + efx_pcie_interface_t intf; + uint16_t pf; + uint16_t vf; +}; + +int sfc_repr_create(struct rte_eth_dev *parent, + struct sfc_repr_entity_info *entity, uint16_t switch_domain_id, const efx_mport_sel_t *mport_sel); diff --git a/drivers/net/sfc/sfc_switch.c b/drivers/net/sfc/sfc_switch.c index f72f6648b8..7a0b332f33 100644 --- a/drivers/net/sfc/sfc_switch.c +++ b/drivers/net/sfc/sfc_switch.c @@ -63,6 +63,8 @@ struct sfc_mae_switch_port { enum sfc_mae_switch_port_type type; /** RTE switch port ID */ uint16_t id; + + union sfc_mae_switch_port_data data; }; TAILQ_HEAD(sfc_mae_switch_ports, sfc_mae_switch_port); @@ -335,6 +337,18 @@ sfc_mae_assign_switch_port(uint16_t switch_domain_id, port->ethdev_mport = *req->ethdev_mportp; port->ethdev_port_id = req->ethdev_port_id; + switch (req->type) { + case SFC_MAE_SWITCH_PORT_INDEPENDENT: + /* No data */ + break; + case SFC_MAE_SWITCH_PORT_REPRESENTOR: + memcpy(&port->data.repr, &req->port_data, + sizeof(port->data.repr)); + break; + default: + SFC_ASSERT(B_FALSE); + } + *switch_port_id = port->id; rte_spinlock_unlock(&sfc_mae_switch.lock); diff --git a/drivers/net/sfc/sfc_switch.h b/drivers/net/sfc/sfc_switch.h index 1eee5fc0b6..a072507375 100644 --- a/drivers/net/sfc/sfc_switch.h +++ b/drivers/net/sfc/sfc_switch.h @@ -34,11 +34,22 @@ enum sfc_mae_switch_port_type { SFC_MAE_SWITCH_PORT_REPRESENTOR, }; +struct sfc_mae_switch_port_repr_data { + efx_pcie_interface_t intf; + uint16_t pf; + uint16_t vf; +}; + +union sfc_mae_switch_port_data { + struct sfc_mae_switch_port_repr_data repr; +}; + struct sfc_mae_switch_port_request { enum sfc_mae_switch_port_type type; const efx_mport_sel_t *entity_mportp; const efx_mport_sel_t *ethdev_mportp; uint16_t ethdev_port_id; + union sfc_mae_switch_port_data port_data; }; int sfc_mae_assign_switch_domain(struct sfc_adapter *sa, From patchwork Fri Aug 27 06:57:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97451 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 D0A48A0C41; Fri, 27 Aug 2021 09:01:18 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6824F412A2; Fri, 27 Aug 2021 08:59:12 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 3845141269 for ; Fri, 27 Aug 2021 08:59:11 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 00D147F6E6; Fri, 27 Aug 2021 09:59:10 +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 8FD887F6F5; Fri, 27 Aug 2021 09:57:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 8FD887F6F5 Authentication-Results: shelob.oktetlabs.ru/8FD887F6F5; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , Andy Moreton Date: Fri, 27 Aug 2021 09:57:13 +0300 Message-Id: <20210827065717.1838258-35-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 34/38] net/sfc: include controller and port in representor name 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: Viacheslav Galaktionov Make representor names unique on multi-host configurations. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_repr.c | 28 ++++++++++++++++++++++++++-- drivers/net/sfc/sfc_switch.c | 28 ++++++++++++++++++++++++++++ drivers/net/sfc/sfc_switch.h | 4 ++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index a42e70c92c..d50efe6562 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -1050,11 +1050,35 @@ sfc_repr_create(struct rte_eth_dev *parent, { struct sfc_repr_init_data repr_data; char name[RTE_ETH_NAME_MAX_LEN]; + int controller; int ret; + int rc; struct rte_eth_dev *dev; - if (snprintf(name, sizeof(name), "net_%s_representor_%u", - parent->device->name, entity->vf) >= (int)sizeof(name)) { + controller = -1; + rc = sfc_mae_switch_domain_get_controller(switch_domain_id, + entity->intf, &controller); + if (rc != 0) { + SFC_GENERIC_LOG(ERR, "%s() failed to get DPDK controller for %d", + __func__, entity->intf); + return -rc; + } + + switch (entity->type) { + case RTE_ETH_REPRESENTOR_VF: + ret = snprintf(name, sizeof(name), "net_%s_representor_c%upf%uvf%u", + parent->device->name, controller, entity->pf, + entity->vf); + break; + case RTE_ETH_REPRESENTOR_PF: + ret = snprintf(name, sizeof(name), "net_%s_representor_c%upf%u", + parent->device->name, controller, entity->pf); + break; + default: + return -ENOTSUP; + } + + if (ret >= (int)sizeof(name)) { SFC_GENERIC_LOG(ERR, "%s() failed name too long", __func__); return -ENAMETOOLONG; } diff --git a/drivers/net/sfc/sfc_switch.c b/drivers/net/sfc/sfc_switch.c index 7a0b332f33..225d07fa15 100644 --- a/drivers/net/sfc/sfc_switch.c +++ b/drivers/net/sfc/sfc_switch.c @@ -279,6 +279,34 @@ sfc_mae_switch_domain_map_controllers(uint16_t switch_domain_id, return 0; } +int +sfc_mae_switch_domain_get_controller(uint16_t switch_domain_id, + efx_pcie_interface_t intf, + int *controller) +{ + const efx_pcie_interface_t *controllers; + size_t nb_controllers; + size_t i; + int rc; + + rc = sfc_mae_switch_domain_controllers(switch_domain_id, &controllers, + &nb_controllers); + if (rc != 0) + return rc; + + if (controllers == NULL) + return ENOENT; + + for (i = 0; i < nb_controllers; i++) { + if (controllers[i] == intf) { + *controller = i; + return 0; + } + } + + return ENOENT; +} + /* This function expects to be called only when the lock is held */ static struct sfc_mae_switch_port * sfc_mae_find_switch_port_by_entity(const struct sfc_mae_switch_domain *domain, diff --git a/drivers/net/sfc/sfc_switch.h b/drivers/net/sfc/sfc_switch.h index a072507375..294baae9a2 100644 --- a/drivers/net/sfc/sfc_switch.h +++ b/drivers/net/sfc/sfc_switch.h @@ -63,6 +63,10 @@ int sfc_mae_switch_domain_map_controllers(uint16_t switch_domain_id, efx_pcie_interface_t *controllers, size_t nb_controllers); +int sfc_mae_switch_domain_get_controller(uint16_t switch_domain_id, + efx_pcie_interface_t intf, + int *controller); + int sfc_mae_assign_switch_port(uint16_t switch_domain_id, const struct sfc_mae_switch_port_request *req, uint16_t *switch_port_id); From patchwork Fri Aug 27 06:57:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97453 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 F3F5AA0C41; Fri, 27 Aug 2021 09:01:31 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 34E2241252; Fri, 27 Aug 2021 08:59:37 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 8EFC341252 for ; Fri, 27 Aug 2021 08:59:35 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 66D967F6EB; Fri, 27 Aug 2021 09:59:35 +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 AA9287F6F8; Fri, 27 Aug 2021 09:57:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru AA9287F6F8 Authentication-Results: shelob.oktetlabs.ru/AA9287F6F8; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , Andy Moreton Date: Fri, 27 Aug 2021 09:57:14 +0300 Message-Id: <20210827065717.1838258-36-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 35/38] net/sfc: support new representor parameter syntax 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: Viacheslav Galaktionov Allow the user to specify representor entities using the structured parameter values. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_ethdev.c | 181 ++++++++++++++++++++++++++++------- drivers/net/sfc/sfc_switch.c | 24 +++++ drivers/net/sfc/sfc_switch.h | 4 + 3 files changed, 176 insertions(+), 33 deletions(-) diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 49ba820501..29c8d220a2 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -2642,18 +2642,143 @@ sfc_eth_dev_find_or_create(struct rte_pci_device *pci_dev, return 0; } +static int +sfc_eth_dev_create_repr(struct sfc_adapter *sa, + efx_pcie_interface_t controller, + uint16_t port, + uint16_t repr_port, + enum rte_eth_representor_type type) +{ + struct sfc_repr_entity_info entity; + efx_mport_sel_t mport_sel; + int rc; + + switch (type) { + case RTE_ETH_REPRESENTOR_NONE: + return 0; + case RTE_ETH_REPRESENTOR_VF: + case RTE_ETH_REPRESENTOR_PF: + break; + case RTE_ETH_REPRESENTOR_SF: + sfc_err(sa, "SF representors are not supported"); + return ENOTSUP; + default: + sfc_err(sa, "unknown representor type: %d", type); + return ENOTSUP; + } + + rc = efx_mae_mport_by_pcie_mh_function(controller, + port, + repr_port, + &mport_sel); + if (rc != 0) { + sfc_err(sa, + "failed to get m-port selector for controller %u port %u repr_port %u: %s", + controller, port, repr_port, rte_strerror(-rc)); + return rc; + } + + memset(&entity, 0, sizeof(entity)); + entity.type = type; + entity.intf = controller; + entity.pf = port; + entity.vf = repr_port; + + rc = sfc_repr_create(sa->eth_dev, &entity, sa->mae.switch_domain_id, + &mport_sel); + if (rc != 0) { + sfc_err(sa, + "failed to create representor for controller %u port %u repr_port %u: %s", + controller, port, repr_port, rte_strerror(-rc)); + return rc; + } + + return 0; +} + +static int +sfc_eth_dev_create_repr_port(struct sfc_adapter *sa, + const struct rte_eth_devargs *eth_da, + efx_pcie_interface_t controller, + uint16_t port) +{ + int first_error = 0; + uint16_t i; + int rc; + + if (eth_da->type == RTE_ETH_REPRESENTOR_PF) { + return sfc_eth_dev_create_repr(sa, controller, port, + EFX_PCI_VF_INVALID, + eth_da->type); + } + + for (i = 0; i < eth_da->nb_representor_ports; i++) { + rc = sfc_eth_dev_create_repr(sa, controller, port, + eth_da->representor_ports[i], + eth_da->type); + if (rc != 0 && first_error == 0) + first_error = rc; + } + + return first_error; +} + +static int +sfc_eth_dev_create_repr_controller(struct sfc_adapter *sa, + const struct rte_eth_devargs *eth_da, + efx_pcie_interface_t controller) +{ + const efx_nic_cfg_t *encp; + int first_error = 0; + uint16_t default_port; + uint16_t i; + int rc; + + if (eth_da->nb_ports == 0) { + encp = efx_nic_cfg_get(sa->nic); + default_port = encp->enc_intf == controller ? encp->enc_pf : 0; + return sfc_eth_dev_create_repr_port(sa, eth_da, controller, + default_port); + } + + for (i = 0; i < eth_da->nb_ports; i++) { + rc = sfc_eth_dev_create_repr_port(sa, eth_da, controller, + eth_da->ports[i]); + if (rc != 0 && first_error == 0) + first_error = rc; + } + + return first_error; +} + static int sfc_eth_dev_create_representors(struct rte_eth_dev *dev, const struct rte_eth_devargs *eth_da) { + efx_pcie_interface_t intf; + const efx_nic_cfg_t *encp; struct sfc_adapter *sa; - unsigned int i; + uint16_t switch_domain_id; + uint16_t i; int rc; - if (eth_da->nb_representor_ports == 0) - return 0; - sa = sfc_adapter_by_eth_dev(dev); + switch_domain_id = sa->mae.switch_domain_id; + + switch (eth_da->type) { + case RTE_ETH_REPRESENTOR_NONE: + return 0; + case RTE_ETH_REPRESENTOR_PF: + case RTE_ETH_REPRESENTOR_VF: + break; + case RTE_ETH_REPRESENTOR_SF: + sfc_err(sa, "SF representors are not supported"); + return -ENOTSUP; + default: + sfc_err(sa, "unknown representor type: %d", + eth_da->type); + return -ENOTSUP; + } if (!sa->switchdev) { sfc_err(sa, "cannot create representors in non-switchdev mode"); @@ -2678,34 +2803,20 @@ sfc_eth_dev_create_representors(struct rte_eth_dev *dev, return -rc; } - for (i = 0; i < eth_da->nb_representor_ports; ++i) { - const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); - struct sfc_repr_entity_info entity; - efx_mport_sel_t mport_sel; - - rc = efx_mae_mport_by_pcie_function(encp->enc_pf, - eth_da->representor_ports[i], &mport_sel); - if (rc != 0) { - sfc_err(sa, - "failed to get representor %u m-port: %s - ignore", - eth_da->representor_ports[i], - rte_strerror(-rc)); - continue; - } - - memset(&entity, 0, sizeof(entity)); - entity.type = eth_da->type; - entity.intf = encp->enc_intf; - entity.pf = encp->enc_pf; - entity.vf = eth_da->representor_ports[i]; - - rc = sfc_repr_create(dev, &entity, sa->mae.switch_domain_id, - &mport_sel); - if (rc != 0) { - sfc_err(sa, "cannot create representor %u: %s - ignore", - eth_da->representor_ports[i], - rte_strerror(-rc)); + if (eth_da->nb_mh_controllers > 0) { + for (i = 0; i < eth_da->nb_mh_controllers; i++) { + rc = sfc_mae_switch_domain_get_intf(switch_domain_id, + eth_da->mh_controllers[i], + &intf); + if (rc != 0) { + sfc_err(sa, "failed to get representor"); + continue; + } + sfc_eth_dev_create_repr_controller(sa, eth_da, intf); } + } else { + encp = efx_nic_cfg_get(sa->nic); + sfc_eth_dev_create_repr_controller(sa, eth_da, encp->enc_intf); } return 0; @@ -2729,9 +2840,13 @@ static int sfc_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, memset(ð_da, 0, sizeof(eth_da)); } - init_data.nb_representors = eth_da.nb_representor_ports; + /* If no VF representors specified, check for PF ones */ + if (eth_da.nb_representor_ports > 0) + init_data.nb_representors = eth_da.nb_representor_ports; + else + init_data.nb_representors = eth_da.nb_ports; - if (eth_da.nb_representor_ports > 0 && + if (init_data.nb_representors > 0 && rte_eal_process_type() != RTE_PROC_PRIMARY) { SFC_GENERIC_LOG(ERR, "Create representors from secondary process not supported, dev '%s'", diff --git a/drivers/net/sfc/sfc_switch.c b/drivers/net/sfc/sfc_switch.c index 225d07fa15..5cd9b46d26 100644 --- a/drivers/net/sfc/sfc_switch.c +++ b/drivers/net/sfc/sfc_switch.c @@ -307,6 +307,30 @@ sfc_mae_switch_domain_get_controller(uint16_t switch_domain_id, return ENOENT; } +int sfc_mae_switch_domain_get_intf(uint16_t switch_domain_id, + int controller, + efx_pcie_interface_t *intf) +{ + const efx_pcie_interface_t *controllers; + size_t nb_controllers; + int rc; + + rc = sfc_mae_switch_domain_controllers(switch_domain_id, &controllers, + &nb_controllers); + if (rc != 0) + return rc; + + if (controllers == NULL) + return ENOENT; + + if ((size_t)controller > nb_controllers) + return EINVAL; + + *intf = controllers[controller]; + + return 0; +} + /* This function expects to be called only when the lock is held */ static struct sfc_mae_switch_port * sfc_mae_find_switch_port_by_entity(const struct sfc_mae_switch_domain *domain, diff --git a/drivers/net/sfc/sfc_switch.h b/drivers/net/sfc/sfc_switch.h index 294baae9a2..d187c6dbbb 100644 --- a/drivers/net/sfc/sfc_switch.h +++ b/drivers/net/sfc/sfc_switch.h @@ -67,6 +67,10 @@ int sfc_mae_switch_domain_get_controller(uint16_t switch_domain_id, efx_pcie_interface_t intf, int *controller); +int sfc_mae_switch_domain_get_intf(uint16_t switch_domain_id, + int controller, + efx_pcie_interface_t *intf); + int sfc_mae_assign_switch_port(uint16_t switch_domain_id, const struct sfc_mae_switch_port_request *req, uint16_t *switch_port_id); From patchwork Fri Aug 27 06:57:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97454 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 72950A0C41; Fri, 27 Aug 2021 09:01:37 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5B6B641256; Fri, 27 Aug 2021 08:59:41 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 0256C41256 for ; Fri, 27 Aug 2021 08:59:40 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id CEAB87F6EC; Fri, 27 Aug 2021 09:59:39 +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 C60B87F6F9; Fri, 27 Aug 2021 09:57:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru C60B87F6F9 Authentication-Results: shelob.oktetlabs.ru/C60B87F6F9; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , Andy Moreton Date: Fri, 27 Aug 2021 09:57:15 +0300 Message-Id: <20210827065717.1838258-37-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 36/38] net/sfc: use switch port ID as representor ID 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: Viacheslav Galaktionov Representor IDs must be unique for each representor. VFs, which are currently used, are not unique as they may repeat in combination with different PCI controllers and PFs. On the other hand, switch port IDs are unique, so they are a better fit for this role. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_repr.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index d50efe6562..4cbfdbcb66 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -921,7 +921,6 @@ static const struct eth_dev_ops sfc_repr_dev_ops = { struct sfc_repr_init_data { uint16_t pf_port_id; - uint16_t repr_id; uint16_t switch_domain_id; efx_mport_sel_t mport_sel; efx_pcie_interface_t intf; @@ -979,7 +978,7 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) } ret = sfc_repr_proxy_add_port(repr_data->pf_port_id, - repr_data->repr_id, + srs->switch_port_id, dev->data->port_id, &repr_data->mport_sel); if (ret != 0) { @@ -1006,7 +1005,7 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) dev->process_private = sr; srs->pf_port_id = repr_data->pf_port_id; - srs->repr_id = repr_data->repr_id; + srs->repr_id = srs->switch_port_id; srs->switch_domain_id = repr_data->switch_domain_id; dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR; @@ -1034,7 +1033,7 @@ sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params) fail_alloc_sr: (void)sfc_repr_proxy_del_port(repr_data->pf_port_id, - repr_data->repr_id); + srs->switch_port_id); fail_create_port: fail_mae_assign_switch_port: @@ -1087,7 +1086,6 @@ sfc_repr_create(struct rte_eth_dev *parent, if (dev == NULL) { memset(&repr_data, 0, sizeof(repr_data)); repr_data.pf_port_id = parent->data->port_id; - repr_data.repr_id = entity->vf; repr_data.switch_domain_id = switch_domain_id; repr_data.mport_sel = *mport_sel; repr_data.intf = entity->intf; From patchwork Fri Aug 27 06:57:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 97456 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 767AFA0C41; Fri, 27 Aug 2021 09:01:49 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E7D02412B1; Fri, 27 Aug 2021 08:59:48 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 99FD04125D for ; Fri, 27 Aug 2021 08:59:46 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 66C347F6ED; Fri, 27 Aug 2021 09:59:46 +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 E1E4D7F6FA; Fri, 27 Aug 2021 09:57:36 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru E1E4D7F6FA Authentication-Results: shelob.oktetlabs.ru/E1E4D7F6FA; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , Andy Moreton Date: Fri, 27 Aug 2021 09:57:16 +0300 Message-Id: <20210827065717.1838258-38-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 37/38] net/sfc: implement the representor info API 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: Viacheslav Galaktionov Let the driver provide the user with information about available representors by implementing the representor_info_get operation. Due to the lack of any structure to representor IDs, every ID range describes exactly one representor. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- doc/guides/rel_notes/release_21_11.rst | 6 + drivers/net/sfc/sfc_ethdev.c | 229 +++++++++++++++++++++++++ drivers/net/sfc/sfc_switch.c | 104 +++++++++-- drivers/net/sfc/sfc_switch.h | 24 +++ 4 files changed, 352 insertions(+), 11 deletions(-) diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index d707a554ef..911e500ce5 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -55,6 +55,12 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Updated Solarflare network PMD.** + + Updated the Solarflare ``sfc_efx`` driver with changes including: + + * Added port representors support on SN1000 SmartNICs + Removed Items ------------- diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 29c8d220a2..62b81ed61a 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -1922,7 +1922,11 @@ static efx_rc_t sfc_process_mport_journal_entry(struct sfc_mport_journal_ctx *ctx, efx_mport_desc_t *mport) { + struct sfc_mae_switch_port_request req; + efx_mport_sel_t entity_selector; efx_mport_sel_t ethdev_mport; + uint16_t switch_port_id; + efx_rc_t efx_rc; int rc; sfc_dbg(ctx->sa, @@ -1938,6 +1942,63 @@ sfc_process_mport_journal_entry(struct sfc_mport_journal_ctx *ctx, return rc; } + /* Build Mport selector */ + efx_rc = efx_mae_mport_by_pcie_mh_function(mport->emd_vnic.ev_intf, + mport->emd_vnic.ev_pf, + mport->emd_vnic.ev_vf, + &entity_selector); + if (efx_rc != 0) { + sfc_err(ctx->sa, "failed to build entity mport selector for c%upf%uvf%u", + mport->emd_vnic.ev_intf, + mport->emd_vnic.ev_pf, + mport->emd_vnic.ev_vf); + return efx_rc; + } + + rc = sfc_mae_switch_port_id_by_entity(ctx->switch_domain_id, + &entity_selector, + SFC_MAE_SWITCH_PORT_REPRESENTOR, + &switch_port_id); + switch (rc) { + case 0: + /* Already registered */ + break; + case ENOENT: + /* + * No representor has been created for this entity. + * Create a dummy switch registry entry with an invalid ethdev + * mport selector. When a corresponding representor is created, + * this entry will be updated. + */ + req.type = SFC_MAE_SWITCH_PORT_REPRESENTOR; + req.entity_mportp = &entity_selector; + req.ethdev_mportp = ðdev_mport; + req.ethdev_port_id = RTE_MAX_ETHPORTS; + req.port_data.repr.intf = mport->emd_vnic.ev_intf; + req.port_data.repr.pf = mport->emd_vnic.ev_pf; + req.port_data.repr.vf = mport->emd_vnic.ev_vf; + + rc = sfc_mae_assign_switch_port(ctx->switch_domain_id, + &req, &switch_port_id); + if (rc != 0) { + sfc_err(ctx->sa, + "failed to assign MAE switch port for c%upf%uvf%u: %s", + mport->emd_vnic.ev_intf, + mport->emd_vnic.ev_pf, + mport->emd_vnic.ev_vf, + rte_strerror(rc)); + return rc; + } + break; + default: + sfc_err(ctx->sa, "failed to find MAE switch port for c%upf%uvf%u: %s", + mport->emd_vnic.ev_intf, + mport->emd_vnic.ev_pf, + mport->emd_vnic.ev_vf, + rte_strerror(rc)); + return rc; + } + return 0; } @@ -2034,6 +2095,173 @@ sfc_process_mport_journal(struct sfc_adapter *sa) return 0; } +static void +sfc_count_representors_cb(enum sfc_mae_switch_port_type type, + const efx_mport_sel_t *ethdev_mportp __rte_unused, + uint16_t ethdev_port_id __rte_unused, + const efx_mport_sel_t *entity_mportp __rte_unused, + uint16_t switch_port_id __rte_unused, + union sfc_mae_switch_port_data *port_datap + __rte_unused, + void *user_datap) +{ + int *counter = user_datap; + + SFC_ASSERT(counter != NULL); + + if (type == SFC_MAE_SWITCH_PORT_REPRESENTOR) + (*counter)++; +} + +struct sfc_get_representors_ctx { + struct rte_eth_representor_info *info; + struct sfc_adapter *sa; + uint16_t switch_domain_id; + const efx_pcie_interface_t *controllers; + size_t nb_controllers; +}; + +static void +sfc_get_representors_cb(enum sfc_mae_switch_port_type type, + const efx_mport_sel_t *ethdev_mportp __rte_unused, + uint16_t ethdev_port_id __rte_unused, + const efx_mport_sel_t *entity_mportp __rte_unused, + uint16_t switch_port_id, + union sfc_mae_switch_port_data *port_datap, + void *user_datap) +{ + struct sfc_get_representors_ctx *ctx = user_datap; + struct rte_eth_representor_range *range; + int ret; + int rc; + + SFC_ASSERT(ctx != NULL); + SFC_ASSERT(ctx->info != NULL); + SFC_ASSERT(ctx->sa != NULL); + + if (type != SFC_MAE_SWITCH_PORT_REPRESENTOR) { + sfc_dbg(ctx->sa, "not a representor, skipping"); + return; + } + if (ctx->info->nb_ranges >= ctx->info->nb_ranges_alloc) { + sfc_dbg(ctx->sa, "info structure is full already"); + return; + } + + range = &ctx->info->ranges[ctx->info->nb_ranges]; + rc = sfc_mae_switch_controller_from_mapping(ctx->controllers, + ctx->nb_controllers, + port_datap->repr.intf, + &range->controller); + if (rc != 0) { + sfc_err(ctx->sa, "invalid representor controller: %d", + port_datap->repr.intf); + range->controller = -1; + } + range->pf = port_datap->repr.pf; + range->id_base = switch_port_id; + range->id_end = switch_port_id; + + if (port_datap->repr.vf != EFX_PCI_VF_INVALID) { + range->type = RTE_ETH_REPRESENTOR_VF; + range->vf = port_datap->repr.vf; + ret = snprintf(range->name, RTE_DEV_NAME_MAX_LEN, + "c%dpf%dvf%d", range->controller, range->pf, + range->vf); + } else { + range->type = RTE_ETH_REPRESENTOR_PF; + ret = snprintf(range->name, RTE_DEV_NAME_MAX_LEN, + "c%dpf%d", range->controller, range->pf); + } + if (ret >= RTE_DEV_NAME_MAX_LEN) { + sfc_err(ctx->sa, "representor name has been truncated: %s", + range->name); + } + + ctx->info->nb_ranges++; +} + +static int +sfc_representor_info_get(struct rte_eth_dev *dev, + struct rte_eth_representor_info *info) +{ + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); + struct sfc_get_representors_ctx get_repr_ctx; + const efx_nic_cfg_t *nic_cfg; + uint16_t switch_domain_id; + uint32_t nb_repr; + int controller; + int rc; + + sfc_adapter_lock(sa); + + if (sa->mae.status != SFC_MAE_STATUS_SUPPORTED) { + sfc_adapter_unlock(sa); + return -ENOTSUP; + } + + rc = sfc_process_mport_journal(sa); + if (rc != 0) { + sfc_adapter_unlock(sa); + SFC_ASSERT(rc > 0); + return -rc; + } + + switch_domain_id = sa->mae.switch_domain_id; + + nb_repr = 0; + rc = sfc_mae_switch_ports_iterate(switch_domain_id, + sfc_count_representors_cb, + &nb_repr); + if (rc != 0) { + sfc_adapter_unlock(sa); + SFC_ASSERT(rc > 0); + return -rc; + } + + if (info == NULL) { + sfc_adapter_unlock(sa); + return nb_repr; + } + + rc = sfc_mae_switch_domain_controllers(switch_domain_id, + &get_repr_ctx.controllers, + &get_repr_ctx.nb_controllers); + if (rc != 0) { + sfc_adapter_unlock(sa); + SFC_ASSERT(rc > 0); + return -rc; + } + + nic_cfg = efx_nic_cfg_get(sa->nic); + + rc = sfc_mae_switch_domain_get_controller(switch_domain_id, + nic_cfg->enc_intf, + &controller); + if (rc != 0) { + sfc_err(sa, "invalid controller: %d", nic_cfg->enc_intf); + controller = -1; + } + + info->controller = controller; + info->pf = nic_cfg->enc_pf; + + get_repr_ctx.info = info; + get_repr_ctx.sa = sa; + get_repr_ctx.switch_domain_id = switch_domain_id; + rc = sfc_mae_switch_ports_iterate(switch_domain_id, + sfc_get_representors_cb, + &get_repr_ctx); + if (rc != 0) { + sfc_adapter_unlock(sa); + SFC_ASSERT(rc > 0); + return -rc; + } + + sfc_adapter_unlock(sa); + return nb_repr; +} + static const struct eth_dev_ops sfc_eth_dev_ops = { .dev_configure = sfc_dev_configure, .dev_start = sfc_dev_start, @@ -2081,6 +2309,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = { .xstats_get_by_id = sfc_xstats_get_by_id, .xstats_get_names_by_id = sfc_xstats_get_names_by_id, .pool_ops_supported = sfc_pool_ops_supported, + .representor_info_get = sfc_representor_info_get, }; struct sfc_ethdev_init_data { diff --git a/drivers/net/sfc/sfc_switch.c b/drivers/net/sfc/sfc_switch.c index 5cd9b46d26..dc5b9a676c 100644 --- a/drivers/net/sfc/sfc_switch.c +++ b/drivers/net/sfc/sfc_switch.c @@ -151,6 +151,34 @@ sfc_mae_find_switch_domain_by_id(uint16_t switch_domain_id) return NULL; } +int +sfc_mae_switch_ports_iterate(uint16_t switch_domain_id, + sfc_mae_switch_port_iterator_cb *cb, + void *data) +{ + struct sfc_mae_switch_domain *domain; + struct sfc_mae_switch_port *port; + + if (cb == NULL) + return EINVAL; + + rte_spinlock_lock(&sfc_mae_switch.lock); + + domain = sfc_mae_find_switch_domain_by_id(switch_domain_id); + if (domain == NULL) { + rte_spinlock_unlock(&sfc_mae_switch.lock); + return EINVAL; + } + + TAILQ_FOREACH(port, &domain->ports, switch_domain_ports) { + cb(port->type, &port->ethdev_mport, port->ethdev_port_id, + &port->entity_mport, port->id, &port->data, data); + } + + rte_spinlock_unlock(&sfc_mae_switch.lock); + return 0; +} + /* This function expects to be called only when the lock is held */ static struct sfc_mae_switch_domain * sfc_mae_find_switch_domain_by_hw_switch_id(const struct sfc_hw_switch_id *id) @@ -280,19 +308,12 @@ sfc_mae_switch_domain_map_controllers(uint16_t switch_domain_id, } int -sfc_mae_switch_domain_get_controller(uint16_t switch_domain_id, - efx_pcie_interface_t intf, - int *controller) +sfc_mae_switch_controller_from_mapping(const efx_pcie_interface_t *controllers, + size_t nb_controllers, + efx_pcie_interface_t intf, + int *controller) { - const efx_pcie_interface_t *controllers; - size_t nb_controllers; size_t i; - int rc; - - rc = sfc_mae_switch_domain_controllers(switch_domain_id, &controllers, - &nb_controllers); - if (rc != 0) - return rc; if (controllers == NULL) return ENOENT; @@ -307,6 +328,26 @@ sfc_mae_switch_domain_get_controller(uint16_t switch_domain_id, return ENOENT; } +int +sfc_mae_switch_domain_get_controller(uint16_t switch_domain_id, + efx_pcie_interface_t intf, + int *controller) +{ + const efx_pcie_interface_t *controllers; + size_t nb_controllers; + int rc; + + rc = sfc_mae_switch_domain_controllers(switch_domain_id, &controllers, + &nb_controllers); + if (rc != 0) + return rc; + + return sfc_mae_switch_controller_from_mapping(controllers, + nb_controllers, + intf, + controller); +} + int sfc_mae_switch_domain_get_intf(uint16_t switch_domain_id, int controller, efx_pcie_interface_t *intf) @@ -350,6 +391,30 @@ sfc_mae_find_switch_port_by_entity(const struct sfc_mae_switch_domain *domain, return NULL; } +/* This function expects to be called only when the lock is held */ +static int +sfc_mae_find_switch_port_id_by_entity(uint16_t switch_domain_id, + const efx_mport_sel_t *entity_mportp, + enum sfc_mae_switch_port_type type, + uint16_t *switch_port_id) +{ + struct sfc_mae_switch_domain *domain; + struct sfc_mae_switch_port *port; + + SFC_ASSERT(rte_spinlock_is_locked(&sfc_mae_switch.lock)); + + domain = sfc_mae_find_switch_domain_by_id(switch_domain_id); + if (domain == NULL) + return EINVAL; + + port = sfc_mae_find_switch_port_by_entity(domain, entity_mportp, type); + if (port == NULL) + return ENOENT; + + *switch_port_id = port->id; + return 0; +} + int sfc_mae_assign_switch_port(uint16_t switch_domain_id, const struct sfc_mae_switch_port_request *req, @@ -455,3 +520,20 @@ sfc_mae_switch_port_by_ethdev(uint16_t switch_domain_id, return rc; } + +int +sfc_mae_switch_port_id_by_entity(uint16_t switch_domain_id, + const efx_mport_sel_t *entity_mportp, + enum sfc_mae_switch_port_type type, + uint16_t *switch_port_id) +{ + int rc; + + rte_spinlock_lock(&sfc_mae_switch.lock); + rc = sfc_mae_find_switch_port_id_by_entity(switch_domain_id, + entity_mportp, type, + switch_port_id); + rte_spinlock_unlock(&sfc_mae_switch.lock); + + return rc; +} diff --git a/drivers/net/sfc/sfc_switch.h b/drivers/net/sfc/sfc_switch.h index d187c6dbbb..a77d2e6f28 100644 --- a/drivers/net/sfc/sfc_switch.h +++ b/drivers/net/sfc/sfc_switch.h @@ -52,6 +52,19 @@ struct sfc_mae_switch_port_request { union sfc_mae_switch_port_data port_data; }; +typedef void (sfc_mae_switch_port_iterator_cb)( + enum sfc_mae_switch_port_type type, + const efx_mport_sel_t *ethdev_mportp, + uint16_t ethdev_port_id, + const efx_mport_sel_t *entity_mportp, + uint16_t switch_port_id, + union sfc_mae_switch_port_data *port_datap, + void *user_datap); + +int sfc_mae_switch_ports_iterate(uint16_t switch_domain_id, + sfc_mae_switch_port_iterator_cb *cb, + void *data); + int sfc_mae_assign_switch_domain(struct sfc_adapter *sa, uint16_t *switch_domain_id); @@ -63,6 +76,12 @@ int sfc_mae_switch_domain_map_controllers(uint16_t switch_domain_id, efx_pcie_interface_t *controllers, size_t nb_controllers); +int sfc_mae_switch_controller_from_mapping( + const efx_pcie_interface_t *controllers, + size_t nb_controllers, + efx_pcie_interface_t intf, + int *controller); + int sfc_mae_switch_domain_get_controller(uint16_t switch_domain_id, efx_pcie_interface_t intf, int *controller); @@ -79,6 +98,11 @@ int sfc_mae_switch_port_by_ethdev(uint16_t switch_domain_id, uint16_t ethdev_port_id, efx_mport_sel_t *mport_sel); +int sfc_mae_switch_port_id_by_entity(uint16_t switch_domain_id, + const efx_mport_sel_t *entity_mportp, + enum sfc_mae_switch_port_type type, + uint16_t *switch_port_id); + #ifdef __cplusplus } #endif From patchwork Fri Aug 27 06:57: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: 97455 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 EDD97A0C41; Fri, 27 Aug 2021 09:01:42 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 82C9041290; Fri, 27 Aug 2021 08:59:47 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id D3F164125D; Fri, 27 Aug 2021 08:59:45 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 9DF427F6ED; Fri, 27 Aug 2021 09:59:45 +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 07EEF7F6FB; Fri, 27 Aug 2021 09:57:37 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 07EEF7F6FB Authentication-Results: shelob.oktetlabs.ru/07EEF7F6FB; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Viacheslav Galaktionov , stable@dpdk.org, Andy Moreton Date: Fri, 27 Aug 2021 09:57:17 +0300 Message-Id: <20210827065717.1838258-39-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 38/38] net/sfc: update comment about representor support 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: Viacheslav Galaktionov The representor support has been implemented to some extent, and the fact that ethdev mport is equivalent to entity mport is by design. Fixes: 1fb65e4dae8 ("net/sfc: support flow action port ID in transfer rules") Cc: stable@dpdk.org Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_mae.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index 7be77054ab..fa60c948ca 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -228,10 +228,7 @@ sfc_mae_attach(struct sfc_adapter *sa) sfc_log_init(sa, "assign RTE switch port"); switch_port_request.type = SFC_MAE_SWITCH_PORT_INDEPENDENT; switch_port_request.entity_mportp = &entity_mport; - /* - * As of now, the driver does not support representors, so - * RTE ethdev MPORT simply matches that of the entity. - */ + /* RTE ethdev MPORT matches that of the entity for independent ports. */ switch_port_request.ethdev_mportp = &entity_mport; switch_port_request.ethdev_port_id = sas->port_id; rc = sfc_mae_assign_switch_port(mae->switch_domain_id,