From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by dpdk.org (Postfix) with ESMTP id 6F18416829 for ; Thu, 7 Sep 2017 13:21:02 +0200 (CEST) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga105.fm.intel.com with ESMTP; 07 Sep 2017 04:21:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.42,358,1500966000"; d="scan'208";a="146527049" Received: from unknown (HELO dpdk9.sh.intel.com) ([10.67.118.52]) by orsmga005.jf.intel.com with ESMTP; 07 Sep 2017 04:21:00 -0700 From: Beilei Xing To: jingjing.wu@intel.com Cc: andrey.chilikin@intel.com, dev@dpdk.org Date: Thu, 7 Sep 2017 19:20:58 +0800 Message-Id: <1504783263-20575-2-git-send-email-beilei.xing@intel.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1504783263-20575-1-git-send-email-beilei.xing@intel.com> References: <1503647430-93905-2-git-send-email-beilei.xing@intel.com> <1504783263-20575-1-git-send-email-beilei.xing@intel.com> Subject: [dpdk-dev] [PATCH v2 1/6] net/i40e: support RSS for GTP-C and GTP-U X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Sep 2017 11:21:03 -0000 GTP-C and GTP-U are supported by new profile. Enable RSS for GTP-C and GTP-U after downloading profile. Signed-off-by: Beilei Xing --- drivers/net/i40e/i40e_ethdev.c | 168 ++++++++++++++++++++++++++++++++++++++++ drivers/net/i40e/i40e_ethdev.h | 21 +++++ drivers/net/i40e/rte_pmd_i40e.c | 4 + 3 files changed, 193 insertions(+) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 4a2e3f2..5483622 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -65,6 +65,7 @@ #include "i40e_rxtx.h" #include "i40e_pf.h" #include "i40e_regs.h" +#include "rte_pmd_i40e.h" #define ETH_I40E_FLOATING_VEB_ARG "enable_floating_veb" #define ETH_I40E_FLOATING_VEB_LIST_ARG "floating_veb_list" @@ -1034,6 +1035,24 @@ i40e_init_fdir_filter_list(struct rte_eth_dev *dev) return ret; } +static void +i40e_init_customer_pctype(struct i40e_pf *pf) +{ + int i; + + for (i = I40E_PERSONALIZED_GTPC; i < I40E_PERSONALIZED_MAX; i++) { + pf->new_pctype[i].index = i; + pf->new_pctype[i].pctype = I40E_INVALID_PCTYPE; + pf->new_pctype[i].valid = false; + if (i == I40E_PERSONALIZED_GTPC) + rte_memcpy(pf->new_pctype[i].name, "GTPC", + sizeof("GTPC")); + else if (i == I40E_PERSONALIZED_GTPU) + rte_memcpy(pf->new_pctype[i].name, "GTPU", + sizeof("GTPU")); + } +} + static int eth_i40e_dev_init(struct rte_eth_dev *dev) { @@ -1299,6 +1318,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev) /* initialize Traffic Manager configuration */ i40e_tm_conf_init(dev); + i40e_init_customer_pctype(pf); + ret = i40e_init_ethtype_filter_list(dev); if (ret < 0) goto err_init_ethtype_filter_list; @@ -1903,6 +1924,30 @@ i40e_apply_link_speed(struct rte_eth_dev *dev) return i40e_phy_conf_link(hw, abilities, speed, true); } +static void +i40e_config_new_pctype(struct i40e_pf *pf, bool enable) +{ + struct i40e_hw *hw = I40E_PF_TO_HW(pf); + uint64_t hena; + int i; + + hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)); + hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32; + + for (i = 0; i < I40E_PERSONALIZED_MAX; i++) { + if (pf->new_pctype[i].valid == true) { + if (enable) + hena |= 1ULL << pf->new_pctype[i].pctype; + else + hena &= ~(1ULL << pf->new_pctype[i].pctype); + } + } + + i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena); + i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32)); + I40E_WRITE_FLUSH(hw); +} + static int i40e_dev_start(struct rte_eth_dev *dev) { @@ -2048,6 +2093,8 @@ i40e_dev_start(struct rte_eth_dev *dev) "please call hierarchy_commit() " "before starting the port"); + i40e_config_new_pctype(pf, true); + return I40E_SUCCESS; err_up: @@ -2128,6 +2175,8 @@ i40e_dev_close(struct rte_eth_dev *dev) uint32_t reg; int i; + i40e_config_new_pctype(pf, false); + PMD_INIT_FUNC_TRACE(); i40e_dev_stop(dev); @@ -6739,6 +6788,9 @@ i40e_get_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t *key_len) return 0; } +#define I40E_PROFILE_INFO_SIZE sizeof(struct i40e_profile_info) +#define I40E_MAX_PROFILE_NUM 16 + static int i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf) { @@ -6760,6 +6812,7 @@ i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf) else hena &= ~I40E_RSS_HENA_ALL; hena |= i40e_config_hena(rss_hf, hw->mac.type); + i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena); i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32)); I40E_WRITE_FLUSH(hw); @@ -10858,6 +10911,121 @@ is_i40e_supported(struct rte_eth_dev *dev) return is_device_supported(dev, &rte_i40e_pmd); } +struct i40e_personalized_pctype* +i40e_find_personalized_pctype(struct i40e_pf *pf, uint8_t index) +{ + int i; + + for (i = 0; i < I40E_PERSONALIZED_MAX; i++) { + if (pf->new_pctype[i].index == index) + return &pf->new_pctype[i]; + } + return NULL; +} + +void +i40e_update_personalized_pctype(struct i40e_pf *pf, uint8_t *pkg, + uint32_t pkg_size) +{ + int proto_num; + struct rte_pmd_i40e_proto_info *proto; + int pctype_num; + struct rte_pmd_i40e_ptype_info *pctype; + struct i40e_personalized_pctype *new_pctype = NULL; + uint8_t proto_id; + uint8_t pctype_value; + char *name; + int i, j, n; + int ret; + + /* get information about protocols */ + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)&proto_num, sizeof(proto_num), + RTE_PMD_I40E_PKG_INFO_PROTOCOL_NUM); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to get protocol number"); + return; + } + if (!proto_num) { + PMD_DRV_LOG(INFO, "No new protocol added"); + return; + } + + proto = (struct rte_pmd_i40e_proto_info *) + malloc(proto_num * sizeof(struct rte_pmd_i40e_proto_info)); + if (!proto) { + PMD_DRV_LOG(ERR, "Failed to allocate memory"); + return; + } + + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)proto, proto_num, + RTE_PMD_I40E_PKG_INFO_PROTOCOL_LIST); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to get protocol list"); + return; + } + + /* get information about packet types */ + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)&pctype_num, sizeof(pctype_num), + RTE_PMD_I40E_PKG_INFO_PCTYPE_NUM); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to get pctype number"); + free(proto); + return; + } + if (!proto_num) { + PMD_DRV_LOG(INFO, "No new pctype added"); + free(proto); + return; + } + pctype = (struct rte_pmd_i40e_ptype_info *) + malloc(pctype_num * sizeof(struct rte_pmd_i40e_ptype_info)); + if (!pctype) { + PMD_DRV_LOG(ERR, "Failed to allocate memory"); + free(proto); + return; + } + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)pctype, pctype_num, + RTE_PMD_I40E_PKG_INFO_PCTYPE_LIST); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to get pctype list"); + free(pctype); + free(proto); + return; + } + for (i = 0; i < pctype_num; i++) { + pctype_value = pctype[i].ptype_id; + for (j = 0; j < RTE_PMD_I40E_PROTO_NUM; j++) { + proto_id = pctype[i].protocols[j]; + if (proto_id == RTE_PMD_I40E_PROTO_UNUSED) + continue; + for (n = 0; n < proto_num; n++) { + if (proto[n].proto_id != proto_id) + continue; + name = proto[n].name; + if (!memcmp(name, "GTPC", sizeof("GTPC"))) + new_pctype = + i40e_find_personalized_pctype(pf, + I40E_PERSONALIZED_GTPC); + else if (!memcmp(name, "GTPU", sizeof("GTPU"))) + new_pctype = + i40e_find_personalized_pctype(pf, + I40E_PERSONALIZED_GTPU); + if (new_pctype) { + new_pctype->pctype = pctype_value; + new_pctype->valid = true; + } + break; + } + } + } + free(pctype); + free(proto); +} + /* Create a QinQ cloud filter * * The Fortville NIC has limited resources for tunnel filters, diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index 48abc05..4f0aeda 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -722,6 +722,21 @@ struct i40e_tm_conf { bool committed; }; +enum i40e_new_proto { + I40E_PERSONALIZED_GTPC = 0, + I40E_PERSONALIZED_GTPU, + I40E_PERSONALIZED_MAX, +}; + +#define I40E_INVALID_PCTYPE 0xFF +#define I40E_NEW_PROTO_NAME_LEN 8 +struct i40e_personalized_pctype { + uint8_t index; /* Indicate which personalized pctype */ + char name[I40E_NEW_PROTO_NAME_LEN]; + uint8_t pctype; /* New pctype value */ + bool valid; /* Check if it's valid */ +}; + /* * Structure to store private data specific for PF instance. */ @@ -786,6 +801,8 @@ struct i40e_pf { bool mpls_replace_flag; /* 1 - MPLS filter replace is done */ bool qinq_replace_flag; /* QINQ filter replace is done */ struct i40e_tm_conf tm_conf; + /* customer personalized pctype */ + struct i40e_personalized_pctype new_pctype[I40E_PERSONALIZED_MAX]; }; enum pending_msg { @@ -1003,6 +1020,10 @@ void i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val); int i40e_tm_ops_get(struct rte_eth_dev *dev, void *ops); void i40e_tm_conf_init(struct rte_eth_dev *dev); void i40e_tm_conf_uninit(struct rte_eth_dev *dev); +struct i40e_personalized_pctype* +i40e_find_personalized_pctype(struct i40e_pf *pf, uint8_t index); +void i40e_update_personalized_pctype(struct i40e_pf *pf, uint8_t *pkg, + uint32_t pkg_size); #define I40E_DEV_TO_PCI(eth_dev) \ RTE_DEV_TO_PCI((eth_dev)->device) diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c index 157fc12..f9283ce 100644 --- a/drivers/net/i40e/rte_pmd_i40e.c +++ b/drivers/net/i40e/rte_pmd_i40e.c @@ -1565,6 +1565,7 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff, { struct rte_eth_dev *dev; struct i40e_hw *hw; + struct i40e_pf *pf; struct i40e_package_header *pkg_hdr; struct i40e_generic_seg_header *profile_seg_hdr; struct i40e_generic_seg_header *metadata_seg_hdr; @@ -1588,6 +1589,7 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff, return -ENOTSUP; hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); if (size < (sizeof(struct i40e_package_header) + sizeof(struct i40e_metadata_segment) + @@ -1608,6 +1610,8 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff, return -EINVAL; } + i40e_update_personalized_pctype(pf, buff, size); + /* Find metadata segment */ metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA, pkg_hdr); -- 2.5.5