From patchwork Wed Dec 27 04:21:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 135597 X-Patchwork-Delegate: ajit.khaparde@broadcom.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 2B77D437A1; Wed, 27 Dec 2023 05:22:44 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2ED2840A75; Wed, 27 Dec 2023 05:21:44 +0100 (CET) Received: from mail-qt1-f174.google.com (mail-qt1-f174.google.com [209.85.160.174]) by mails.dpdk.org (Postfix) with ESMTP id 11C974069D for ; Wed, 27 Dec 2023 05:21:39 +0100 (CET) Received: by mail-qt1-f174.google.com with SMTP id d75a77b69052e-427e83601c4so3805221cf.0 for ; Tue, 26 Dec 2023 20:21:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1703650898; x=1704255698; darn=dpdk.org; h=mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:from:to:cc:subject:date:message-id:reply-to; bh=jFkdE5yxNFM1s+xri0E7kWHQCY7JdOrW6/qJ/p/33JM=; b=DQaV+b37PJHHKRizRZlWE1JE5q2A46QujbuT7x/fMpj3bANQh06u1qtjTokPRXqSVN /lMGIw/D4LrarmT1JuY0TEoUODBHOAZ4TAzgAYR9XFCepC1gIqHLsCzxyXO6d2v+8ND+ 2oaoCzX7taQQURI2Ip8NjCoeMBOF0ZUzl9qSw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703650898; x=1704255698; h=mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=jFkdE5yxNFM1s+xri0E7kWHQCY7JdOrW6/qJ/p/33JM=; b=nkSgajJEpGsLQxxaCTkUdj/4epHWQsIKCBDwotw9SsxtTc4CfVKt0ZXykEBXGRthXl oZ+CKtWf/4Z9gGX5nF04P3UKzndZyoBuPmvyzX/cI1L7/rsyC5yki+lSOaBDYfNJWjJi y3tvsjRLjPiDTn6CsR+my0CP8oVXxSq9P0jI+qwt/k1lu5hymngk8sAfHHoOvvY0sa58 Wi/ofrhKKiiSdmFZkQhYJH1gsKySPX6V7oOsBx3zls88KXriIaR4V7d/wWcdkBBieveG wBzvTvIz6A1Tzcsrjdg9BVwqr7GAFLiuaash4mDuR2+9VK5dDRXwInqSSr4Kl6x/xNbQ DrbA== X-Gm-Message-State: AOJu0YzMv4YHh6v2T9Vc+rahdnLIdE5oDZRdAPwiOxluSsw2EMb0TU9m mJTLsA0jKrqWM75iWsuOhaE2Yu52sce9ubiB9w83cY1WmzxJCQxQA41mgFOJQwjzgOH7dP0COPg z+gFUfhShgT+8dwjXJ14R+hXGPP0UTgMLDeDQ77uprlsNxLSWFbc6r130G0tFAdyeougMK8835P M= X-Google-Smtp-Source: AGHT+IGd9p+wIpYO2FNf9RpkE2fplKgpRbDwP6yPGd1okbF0rNZPsd4LqEOZrAEC+AMXtMwcEH7XGw== X-Received: by 2002:a05:622a:107:b0:427:f034:b74 with SMTP id u7-20020a05622a010700b00427f0340b74mr69375qtw.73.1703650897804; Tue, 26 Dec 2023 20:21:37 -0800 (PST) Received: from localhost.localdomain ([2605:a601:a780:1400:c066:75e3:74c8:50e6]) by smtp.gmail.com with ESMTPSA id bt7-20020ac86907000000b00427e120889bsm1415488qtb.91.2023.12.26.20.21.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Dec 2023 20:21:36 -0800 (PST) From: Ajit Khaparde To: dev@dpdk.org Cc: Damodharam Ammepalli Subject: [PATCH v3 09/18] net/bnxt: extend RSS hash support for P7 devices Date: Tue, 26 Dec 2023 20:21:10 -0800 Message-Id: <20231227042119.72469-10-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.39.2 (Apple Git-143) In-Reply-To: <20231227042119.72469-1-ajit.khaparde@broadcom.com> References: <20231227042119.72469-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 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 P7 adapters support XOR based and checksum based RSS hashing. Add support for checksum and XOR based RSS hash for these adapters. Signed-off-by: Ajit Khaparde Reviewed-by: Damodharam Ammepalli --- drivers/net/bnxt/bnxt.h | 15 +-- drivers/net/bnxt/bnxt_ethdev.c | 72 ++++++--------- drivers/net/bnxt/bnxt_flow.c | 37 +++++++- drivers/net/bnxt/bnxt_hwrm.c | 6 ++ drivers/net/bnxt/bnxt_reps.c | 2 +- drivers/net/bnxt/bnxt_vnic.c | 161 +++++++++++++++++++++++++++++++-- drivers/net/bnxt/bnxt_vnic.h | 18 +++- 7 files changed, 242 insertions(+), 69 deletions(-) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index cd85a944e8..e7b288c849 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -638,15 +638,6 @@ struct bnxt_rep_info { #define BNXT_FW_STATUS_HEALTHY 0x8000 #define BNXT_FW_STATUS_SHUTDOWN 0x100000 -#define BNXT_ETH_RSS_SUPPORT ( \ - RTE_ETH_RSS_IPV4 | \ - RTE_ETH_RSS_NONFRAG_IPV4_TCP | \ - RTE_ETH_RSS_NONFRAG_IPV4_UDP | \ - RTE_ETH_RSS_IPV6 | \ - RTE_ETH_RSS_NONFRAG_IPV6_TCP | \ - RTE_ETH_RSS_NONFRAG_IPV6_UDP | \ - RTE_ETH_RSS_LEVEL_MASK) - #define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input) struct bnxt_flow_stat_info { @@ -815,7 +806,10 @@ struct bnxt { #define BNXT_VNIC_CAP_VLAN_RX_STRIP BIT(3) #define BNXT_RX_VLAN_STRIP_EN(bp) ((bp)->vnic_cap_flags & BNXT_VNIC_CAP_VLAN_RX_STRIP) #define BNXT_VNIC_CAP_OUTER_RSS_TRUSTED_VF BIT(4) -#define BNXT_VNIC_CAP_L2_CQE_MODE BIT(8) +#define BNXT_VNIC_CAP_XOR_MODE BIT(5) +#define BNXT_VNIC_CAP_CHKSM_MODE BIT(6) +#define BNXT_VNIC_CAP_L2_CQE_MODE BIT(8) + unsigned int rx_nr_rings; unsigned int rx_cp_nr_rings; unsigned int rx_num_qs_per_vnic; @@ -1176,4 +1170,5 @@ void bnxt_handle_vf_cfg_change(void *arg); int bnxt_flow_meter_ops_get(struct rte_eth_dev *eth_dev, void *arg); struct bnxt_vnic_info *bnxt_get_default_vnic(struct bnxt *bp); struct tf *bnxt_get_tfp_session(struct bnxt *bp, enum bnxt_session_type type); +uint64_t bnxt_eth_rss_support(struct bnxt *bp); #endif diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index 0f1c4326c4..ef5e65ff16 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -982,6 +982,25 @@ uint32_t bnxt_get_speed_capabilities(struct bnxt *bp) return speed_capa; } +uint64_t bnxt_eth_rss_support(struct bnxt *bp) +{ + uint64_t support; + + support = RTE_ETH_RSS_IPV4 | + RTE_ETH_RSS_NONFRAG_IPV4_TCP | + RTE_ETH_RSS_NONFRAG_IPV4_UDP | + RTE_ETH_RSS_IPV6 | + RTE_ETH_RSS_NONFRAG_IPV6_TCP | + RTE_ETH_RSS_NONFRAG_IPV6_UDP | + RTE_ETH_RSS_LEVEL_MASK; + + if (bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE) + support |= (RTE_ETH_RSS_IPV4_CHKSUM | + RTE_ETH_RSS_L4_CHKSUM); + + return support; +} + static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *dev_info) { @@ -1023,7 +1042,7 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, dev_info->tx_queue_offload_capa = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE; dev_info->tx_offload_capa = bnxt_get_tx_port_offloads(bp) | dev_info->tx_queue_offload_capa; - dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT; + dev_info->flow_type_rss_offloads = bnxt_eth_rss_support(bp); dev_info->speed_capa = bnxt_get_speed_capabilities(bp); dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | @@ -2175,7 +2194,7 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, if (!rss_conf->rss_hf) PMD_DRV_LOG(ERR, "Hash type NONE\n"); } else { - if (rss_conf->rss_hf & BNXT_ETH_RSS_SUPPORT) + if (rss_conf->rss_hf & bnxt_eth_rss_support(bp)) return -EINVAL; } @@ -2185,6 +2204,12 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, vnic->hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss_conf->rss_hf, RTE_ETH_RSS_LEVEL(rss_conf->rss_hf)); + rc = bnxt_rte_eth_to_hwrm_ring_select_mode(bp, rss_conf->rss_hf, vnic); + if (rc != 0) + return rc; + + /* Cache the hash function */ + bp->rss_conf.rss_hf = rss_conf->rss_hf; /* Cache the hash function */ bp->rss_conf.rss_hf = rss_conf->rss_hf; @@ -2218,60 +2243,21 @@ static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev, struct bnxt *bp = eth_dev->data->dev_private; struct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp); int len, rc; - uint32_t hash_types; rc = is_bnxt_in_error(bp); if (rc) return rc; - /* RSS configuration is the same for all VNICs */ + /* Return the RSS configuration of the default VNIC. */ if (vnic && vnic->rss_hash_key) { if (rss_conf->rss_key) { len = rss_conf->rss_key_len <= HW_HASH_KEY_SIZE ? rss_conf->rss_key_len : HW_HASH_KEY_SIZE; memcpy(rss_conf->rss_key, vnic->rss_hash_key, len); } - - hash_types = vnic->hash_type; - rss_conf->rss_hf = 0; - if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4) { - rss_conf->rss_hf |= RTE_ETH_RSS_IPV4; - hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4; - } - if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4) { - rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP; - hash_types &= - ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4; - } - if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4) { - rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP; - hash_types &= - ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4; - } - if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6) { - rss_conf->rss_hf |= RTE_ETH_RSS_IPV6; - hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6; - } - if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6) { - rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP; - hash_types &= - ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6; - } - if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6) { - rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP; - hash_types &= - ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6; - } - + bnxt_hwrm_rss_to_rte_hash_conf(vnic, &rss_conf->rss_hf); rss_conf->rss_hf |= bnxt_hwrm_to_rte_rss_level(bp, vnic->hash_mode); - - if (hash_types) { - PMD_DRV_LOG(ERR, - "Unknown RSS config from firmware (%08x), RSS disabled", - vnic->hash_type); - return -ENOTSUP; - } } else { rss_conf->rss_hf = 0; } diff --git a/drivers/net/bnxt/bnxt_flow.c b/drivers/net/bnxt/bnxt_flow.c index 15f0e1b308..2d707b48d2 100644 --- a/drivers/net/bnxt/bnxt_flow.c +++ b/drivers/net/bnxt/bnxt_flow.c @@ -881,6 +881,7 @@ static void bnxt_vnic_cleanup(struct bnxt *bp, struct bnxt_vnic_info *vnic) vnic->fw_grp_ids = NULL; vnic->rx_queue_cnt = 0; + vnic->hash_type = 0; } static int bnxt_vnic_prep(struct bnxt *bp, struct bnxt_vnic_info *vnic, @@ -1067,7 +1068,7 @@ bnxt_vnic_rss_cfg_update(struct bnxt *bp, { const struct rte_flow_action_rss *rss; unsigned int rss_idx, i, j, fw_idx; - uint16_t hash_type; + uint32_t hash_type; uint64_t types; int rc; @@ -1115,9 +1116,9 @@ bnxt_vnic_rss_cfg_update(struct bnxt *bp, } } - /* Currently only Toeplitz hash is supported. */ - if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT && - rss->func != RTE_ETH_HASH_FUNCTION_TOEPLITZ) { + if (BNXT_IS_HASH_FUNC_DEFAULT(rss->func) && + BNXT_IS_HASH_FUNC_TOEPLITZ(rss->func) && + BNXT_IS_HASH_FUNC_SIMPLE_XOR(bp, rss->func)) { rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, @@ -1175,6 +1176,34 @@ bnxt_vnic_rss_cfg_update(struct bnxt *bp, vnic->hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss->types, rss->level); + /* For P7 chips update the hash_type if hash_type not explicitly passed. + * TODO: For P5 chips. + */ + if (BNXT_CHIP_P7(bp) && + vnic->hash_mode == BNXT_HASH_MODE_DEFAULT && !hash_type) + vnic->hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 | + HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6; + + /* TODO: + * hash will be performed on the L3 and L4 packet headers. + * specific RSS hash types like IPv4-TCP etc... or L4-chksum or IPV4-chksum + * will NOT have any bearing and will not be honored. + * Check and reject flow create accordingly. TODO. + */ + + rc = bnxt_rte_flow_to_hwrm_ring_select_mode(rss->func, + rss->types, + bp, vnic); + if (rc) { + rte_flow_error_set(error, + ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + act, + "Unsupported RSS hash parameters"); + rc = -rte_errno; + goto ret; + } + /* Update RSS key only if key_len != 0 */ if (rss->key_len != 0) memcpy(vnic->rss_hash_key, rss->key, rss->key_len); diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index d649f217ec..587433a878 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -1025,6 +1025,12 @@ int bnxt_hwrm_vnic_qcaps(struct bnxt *bp) PMD_DRV_LOG(DEBUG, "Rx VLAN strip capability enabled\n"); } + if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RING_SELECT_MODE_XOR_CAP) + bp->vnic_cap_flags |= BNXT_VNIC_CAP_XOR_MODE; + + if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RING_SELECT_MODE_TOEPLITZ_CHKSM_CAP) + bp->vnic_cap_flags |= BNXT_VNIC_CAP_CHKSM_MODE; + bp->max_tpa_v2 = rte_le_to_cpu_16(resp->max_aggs_supported); HWRM_UNLOCK(); diff --git a/drivers/net/bnxt/bnxt_reps.c b/drivers/net/bnxt/bnxt_reps.c index 78337431af..d96d972904 100644 --- a/drivers/net/bnxt/bnxt_reps.c +++ b/drivers/net/bnxt/bnxt_reps.c @@ -569,7 +569,7 @@ int bnxt_rep_dev_info_get_op(struct rte_eth_dev *eth_dev, dev_info->rx_offload_capa = bnxt_get_rx_port_offloads(parent_bp); dev_info->tx_offload_capa = bnxt_get_tx_port_offloads(parent_bp); - dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT; + dev_info->flow_type_rss_offloads = bnxt_eth_rss_support(parent_bp); dev_info->switch_info.name = eth_dev->device->name; dev_info->switch_info.domain_id = rep_bp->switch_domain_id; diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c index bf93120d28..6a57f85ea7 100644 --- a/drivers/net/bnxt/bnxt_vnic.c +++ b/drivers/net/bnxt/bnxt_vnic.c @@ -256,10 +256,15 @@ int bnxt_vnic_grp_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic) return 0; } -uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type) +uint32_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type) { - uint16_t hwrm_type = 0; + uint32_t hwrm_type = 0; + if (rte_type & RTE_ETH_RSS_IPV4_CHKSUM) + hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4; + if (rte_type & RTE_ETH_RSS_L4_CHKSUM) + hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 | + HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6; if ((rte_type & RTE_ETH_RSS_IPV4) || (rte_type & RTE_ETH_RSS_ECPRI)) hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4; @@ -273,6 +278,9 @@ uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type) hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6; if (rte_type & RTE_ETH_RSS_NONFRAG_IPV6_UDP) hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6; + if (rte_type & RTE_ETH_RSS_IPV4_CHKSUM) + hwrm_type |= + HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM; return hwrm_type; } @@ -287,6 +295,8 @@ int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t lvl) RTE_ETH_RSS_NONFRAG_IPV6_TCP)); bool l3_only = l3 && !l4; bool l3_and_l4 = l3 && l4; + bool cksum = !!(hash_f & + (RTE_ETH_RSS_IPV4_CHKSUM | RTE_ETH_RSS_L4_CHKSUM)); /* If FW has not advertised capability to configure outer/inner * RSS hashing , just log a message. HW will work in default RSS mode. @@ -302,12 +312,12 @@ int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t lvl) switch (lvl) { case BNXT_RSS_LEVEL_INNERMOST: /* Irrespective of what RTE says, FW always does 4 tuple */ - if (l3_and_l4 || l4 || l3_only) + if (l3_and_l4 || l4 || l3_only || cksum) mode = BNXT_HASH_MODE_INNERMOST; break; case BNXT_RSS_LEVEL_OUTERMOST: /* Irrespective of what RTE says, FW always does 4 tuple */ - if (l3_and_l4 || l4 || l3_only) + if (l3_and_l4 || l4 || l3_only || cksum) mode = BNXT_HASH_MODE_OUTERMOST; break; default: @@ -733,6 +743,16 @@ bnxt_vnic_rss_create(struct bnxt *bp, goto fail_cleanup; } + /* Remove unsupported types */ + rss_info->rss_types &= bnxt_eth_rss_support(bp); + + /* If only unsupported type(s) are specified then quit */ + if (rss_info->rss_types == 0) { + PMD_DRV_LOG(ERR, + "Unsupported RSS hash type(s)\n"); + goto fail_cleanup; + } + /* hwrm_type conversion */ vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_info->rss_types); vnic->hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss_info->rss_types, @@ -803,9 +823,11 @@ bnxt_vnic_rss_hash_algo_update(struct bnxt *bp, struct bnxt_vnic_rss_info *rss_info) { uint8_t old_rss_hash_key[HW_HASH_KEY_SIZE] = { 0 }; - uint16_t hash_type; - uint8_t hash_mode; + uint32_t hash_type; + uint8_t hash_mode; + uint8_t ring_mode; uint32_t apply = 0; + int rc; /* validate key length */ if (rss_info->key_len != 0 && rss_info->key_len != HW_HASH_KEY_SIZE) { @@ -815,12 +837,40 @@ bnxt_vnic_rss_hash_algo_update(struct bnxt *bp, return -EINVAL; } + /* Remove unsupported types */ + rss_info->rss_types &= bnxt_eth_rss_support(bp); + + /* If only unsupported type(s) are specified then quit */ + if (!rss_info->rss_types) { + PMD_DRV_LOG(ERR, + "Unsupported RSS hash type\n"); + return -EINVAL; + } + /* hwrm_type conversion */ hash_type = bnxt_rte_to_hwrm_hash_types(rss_info->rss_types); hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss_info->rss_types, rss_info->rss_level); + ring_mode = vnic->ring_select_mode; + + /* For P7 chips update the hash_type if hash_type not explicitly passed. + * TODO: For P5 chips. + */ + if (BNXT_CHIP_P7(bp) && + hash_mode == BNXT_HASH_MODE_DEFAULT && !hash_type) + vnic->hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 | + HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6; + + rc = bnxt_rte_flow_to_hwrm_ring_select_mode(rss_info->rss_func, + rss_info->rss_types, + bp, + vnic); + if (rc) + return -EINVAL; + if (vnic->hash_mode != hash_mode || - vnic->hash_type != hash_type) { + vnic->hash_type != hash_type || + vnic->ring_select_mode != ring_mode) { apply = 1; vnic->hash_mode = hash_mode; vnic->hash_type = hash_type; @@ -839,10 +889,10 @@ bnxt_vnic_rss_hash_algo_update(struct bnxt *bp, if (apply) { if (bnxt_hwrm_vnic_rss_cfg(bp, vnic)) { memcpy(vnic->rss_hash_key, old_rss_hash_key, HW_HASH_KEY_SIZE); - BNXT_TF_DBG(ERR, "Error configuring vnic RSS config\n"); + PMD_DRV_LOG(ERR, "Error configuring vnic RSS config\n"); return -EINVAL; } - BNXT_TF_DBG(INFO, "Rss config successfully applied\n"); + PMD_DRV_LOG(INFO, "Rss config successfully applied\n"); } return 0; } @@ -1245,3 +1295,96 @@ bnxt_get_default_vnic(struct bnxt *bp) { return &bp->vnic_info[bp->vnic_queue_db.dflt_vnic_id]; } + +uint8_t _bnxt_rte_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f) +{ + /* If RTE_ETH_HASH_FUNCTION_DEFAULT || RTE_ETH_HASH_FUNCTION_TOEPLITZ */ + uint8_t mode = HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ; + + if (hash_f == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) + mode = HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_XOR; + + return mode; +} + +int bnxt_rte_flow_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f, + uint64_t types, struct bnxt *bp, + struct bnxt_vnic_info *vnic) +{ + if (hash_f != RTE_ETH_HASH_FUNCTION_TOEPLITZ && + hash_f != RTE_ETH_HASH_FUNCTION_DEFAULT) { + if (hash_f == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ || + (!BNXT_CHIP_P7(bp) && hash_f == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)) { + PMD_DRV_LOG(ERR, "Unsupported hash function\n"); + return -ENOTSUP; + } + } + + if (types & RTE_ETH_RSS_IPV4_CHKSUM || types & RTE_ETH_RSS_L4_CHKSUM) { + if ((bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE) && + (hash_f == RTE_ETH_HASH_FUNCTION_DEFAULT || + hash_f == RTE_ETH_HASH_FUNCTION_TOEPLITZ)) { + /* Checksum mode cannot with hash func makes no sense */ + vnic->ring_select_mode = + HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM; + /* shadow copy types as !hash_f is always true with default func */ + return 0; + } + PMD_DRV_LOG(ERR, "Hash function not supported with checksun type\n"); + return -ENOTSUP; + } + + vnic->ring_select_mode = _bnxt_rte_to_hwrm_ring_select_mode(hash_f); + return 0; +} + +int bnxt_rte_eth_to_hwrm_ring_select_mode(struct bnxt *bp, uint64_t types, + struct bnxt_vnic_info *vnic) +{ + /* If the config update comes via ethdev, there is no way to + * specify anything for hash function. + * So its either TOEPLITZ or the Checksum mode. + * Note that checksum mode is not supported on older devices. + */ + if (types == RTE_ETH_RSS_IPV4_CHKSUM) { + if (bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE) + vnic->ring_select_mode = + HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM; + else + return -ENOTSUP; + } + + /* Older devices can support TOEPLITZ only. + * Thor2 supports other hash functions, but can't change using this path. + */ + vnic->ring_select_mode = + HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ; + return 0; +} + +void bnxt_hwrm_rss_to_rte_hash_conf(struct bnxt_vnic_info *vnic, + uint64_t *rss_conf) +{ + uint32_t hash_types; + + hash_types = vnic->hash_type; + *rss_conf = 0; + if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4) + *rss_conf |= RTE_ETH_RSS_IPV4; + if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4) + *rss_conf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP; + if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4) + *rss_conf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP; + if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6) + *rss_conf |= RTE_ETH_RSS_IPV6; + if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6) + *rss_conf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP; + if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6) + *rss_conf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP; + if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV6 || + hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV4) + *rss_conf |= RTE_ETH_RSS_AH; + if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV6 || + hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV4) + *rss_conf |= RTE_ETH_RSS_ESP; +} diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h index 7a6a0aa739..d01c9ebdb4 100644 --- a/drivers/net/bnxt/bnxt_vnic.h +++ b/drivers/net/bnxt/bnxt_vnic.h @@ -31,6 +31,11 @@ (BNXT_VF(bp) && BNXT_VF_IS_TRUSTED(bp) && \ !((bp)->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS_TRUSTED_VF)) || \ (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp))) +#define BNXT_IS_HASH_FUNC_DEFAULT(f) ((f) != RTE_ETH_HASH_FUNCTION_DEFAULT) +#define BNXT_IS_HASH_FUNC_TOEPLITZ(f) ((f) != RTE_ETH_HASH_FUNCTION_TOEPLITZ) +#define BNXT_IS_HASH_FUNC_SIMPLE_XOR(b, f) \ + ((b)->vnic_cap_flags & BNXT_VNIC_CAP_XOR_MODE && \ + ((f) != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)) struct bnxt_vnic_info { STAILQ_ENTRY(bnxt_vnic_info) next; @@ -73,6 +78,7 @@ struct bnxt_vnic_info { STAILQ_HEAD(, bnxt_filter_info) filter; STAILQ_HEAD(, rte_flow) flow_list; + uint8_t ring_select_mode; }; struct bnxt_vnic_queue_db { @@ -83,6 +89,7 @@ struct bnxt_vnic_queue_db { /* RSS structure to pass values as an structure argument*/ struct bnxt_vnic_rss_info { + uint32_t rss_func; uint32_t rss_level; uint64_t rss_types; uint32_t key_len; /**< Hash key length in bytes. */ @@ -102,7 +109,7 @@ void bnxt_free_vnic_mem(struct bnxt *bp); int bnxt_alloc_vnic_mem(struct bnxt *bp); int bnxt_vnic_grp_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic); void bnxt_prandom_bytes(void *dest_ptr, size_t len); -uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type); +uint32_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type); int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t lvl); uint64_t bnxt_hwrm_to_rte_rss_level(struct bnxt *bp, uint32_t mode); @@ -139,5 +146,12 @@ struct bnxt_vnic_info * bnxt_vnic_queue_id_get_next(struct bnxt *bp, uint16_t queue_id, uint16_t *vnic_idx); void bnxt_vnic_tpa_cfg(struct bnxt *bp, uint16_t queue_id, bool flag); - +uint8_t _bnxt_rte_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f); +int bnxt_rte_flow_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f, + uint64_t types, struct bnxt *bp, + struct bnxt_vnic_info *vnic); +int bnxt_rte_eth_to_hwrm_ring_select_mode(struct bnxt *bp, uint64_t types, + struct bnxt_vnic_info *vnic); +void bnxt_hwrm_rss_to_rte_hash_conf(struct bnxt_vnic_info *vnic, + uint64_t *rss_conf); #endif