From patchwork Fri Sep 22 22:35:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xing, Beilei" X-Patchwork-Id: 29091 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id CC5837CFD; Fri, 22 Sep 2017 11:43:06 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 298D32C01 for ; Fri, 22 Sep 2017 11:42:56 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Sep 2017 02:42:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.42,427,1500966000"; d="scan'208"; a="1174782452" Received: from unknown (HELO dpdk9.sh.intel.com) ([10.67.118.52]) by orsmga001.jf.intel.com with ESMTP; 22 Sep 2017 02:42:55 -0700 From: Beilei Xing To: jingjing.wu@intel.com Cc: andrey.chilikin@intel.com, dev@dpdk.org Date: Sat, 23 Sep 2017 06:35:08 +0800 Message-Id: <1506119714-53437-3-git-send-email-beilei.xing@intel.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1506119714-53437-1-git-send-email-beilei.xing@intel.com> References: <1504783263-20575-1-git-send-email-beilei.xing@intel.com> <1506119714-53437-1-git-send-email-beilei.xing@intel.com> Subject: [dpdk-dev] [PATCH v3 2/8] net/i40e: update ptype and pctype info X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Update new packet type and new pctype info when downloading profile. Signed-off-by: Beilei Xing --- drivers/net/i40e/i40e_ethdev.c | 312 ++++++++++++++++++++++++++++++++++++++++ drivers/net/i40e/i40e_ethdev.h | 24 ++++ drivers/net/i40e/rte_pmd_i40e.c | 6 +- 3 files changed, 341 insertions(+), 1 deletion(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 720f067..dcff8cc 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" @@ -1036,6 +1037,18 @@ 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_FILTER_PCTYPE_INVALID; + pf->new_pctype[i].valid = false; + } +} + static int eth_i40e_dev_init(struct rte_eth_dev *dev) { @@ -1301,6 +1314,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; @@ -10893,6 +10908,303 @@ 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; +} + +static int +i40e_update_personalized_pctype(struct rte_eth_dev *dev, uint8_t *pkg, + uint32_t pkg_size, uint32_t proto_num, + struct rte_pmd_i40e_proto_info *proto) +{ + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + uint32_t 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[64]; + uint32_t i, j, n; + int ret; + + 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"); + return -1; + } + if (!pctype_num) { + PMD_DRV_LOG(INFO, "No new pctype added"); + return -1; + } + + pctype = rte_zmalloc("new_pctype", + pctype_num * sizeof(struct rte_pmd_i40e_ptype_info), + 0); + if (!pctype) { + PMD_DRV_LOG(ERR, "Failed to allocate memory"); + return -1; + } + /* get information about new pctype list */ + 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"); + rte_free(pctype); + return -1; + } + + /* Update personalized pctype. */ + for (i = 0; i < pctype_num; i++) { + pctype_value = pctype[i].ptype_id; + memset(name, 0, sizeof(name)); + 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; + strcat(name, proto[n].name); + strcat(name, "_"); + break; + } + } + if (!memcmp(name, "GTPC", sizeof("GTPC") - 1)) + new_pctype = + i40e_find_personalized_pctype(pf, + I40E_PERSONALIZED_GTPC); + else if (!memcmp(name, "GTPU_IPV4", + sizeof("GTPU_IPV4") - 1)) + new_pctype = + i40e_find_personalized_pctype(pf, + I40E_PERSONALIZED_GTPU_IPV4); + else if (!memcmp(name, "GTPU_IPV6", + sizeof("GTPU_IPV6") - 1)) + new_pctype = + i40e_find_personalized_pctype(pf, + I40E_PERSONALIZED_GTPU_IPV6); + else if (!memcmp(name, "GTPU", sizeof("GTPU") - 1)) + new_pctype = + i40e_find_personalized_pctype(pf, + I40E_PERSONALIZED_GTPU); + if (new_pctype) { + new_pctype->pctype = pctype_value; + new_pctype->valid = true; + } + } + + rte_free(pctype); + return 0; +} + +static int +i40e_update_personalized_ptype(struct rte_eth_dev *dev, uint8_t *pkg, + uint32_t pkg_size, uint32_t proto_num, + struct rte_pmd_i40e_proto_info *proto) +{ + struct rte_pmd_i40e_ptype_mapping *ptype_mapping; + uint8_t port_id = dev->data->port_id; + uint32_t ptype_num; + struct rte_pmd_i40e_ptype_info *ptype; + uint8_t proto_id; + char name[16]; + uint32_t i, j, n; + int ip_id = 0; + int ret; + + /* get information about new ptype num */ + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)&ptype_num, sizeof(ptype_num), + RTE_PMD_I40E_PKG_INFO_PTYPE_NUM); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to get ptype number"); + return -1; + } + if (!ptype_num) { + PMD_DRV_LOG(INFO, "No new ptype added"); + return -1; + } + /* get information about new ptype list */ + ptype = rte_zmalloc("new_ptype", + ptype_num * sizeof(struct rte_pmd_i40e_ptype_info), + 0); + if (!ptype) { + PMD_DRV_LOG(ERR, "Failed to allocate memory"); + return -1; + } + ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, + (uint8_t *)ptype, ptype_num, + RTE_PMD_I40E_PKG_INFO_PTYPE_LIST); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to get ptype list"); + rte_free(ptype); + return -1; + } + + ptype_mapping = rte_zmalloc("ptype_mapping", + ptype_num * + sizeof(struct rte_pmd_i40e_ptype_mapping), + 0); + if (!ptype_mapping) { + PMD_DRV_LOG(ERR, "Failed to allocate memory"); + rte_free(ptype); + return -1; + } + + /* Update ptype mapping table. */ + for (i = 0; i < ptype_num; i++) { + ptype_mapping[i].hw_ptype = ptype[i].ptype_id; + ptype_mapping[i].sw_ptype = 0; + ip_id = 0; + for (j = 0; j < RTE_PMD_I40E_PROTO_NUM; j++) { + proto_id = ptype[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; + memset(name, 0, sizeof(name)); + strcpy(name, proto[n].name); + if (!memcmp(name, "IPV4", sizeof("IPV4") - 1)) { + if (ip_id == 0) { + ptype_mapping[i].sw_ptype |= + RTE_PTYPE_L3_IPV4_EXT_UNKNOWN; + ip_id++; + } else if (ip_id == 1) { + ptype_mapping[i].sw_ptype |= + RTE_PTYPE_INNER_L3_IPV4; + ip_id++; + } else if (ip_id == 2) + ptype_mapping[i].sw_ptype |= + RTE_PTYPE_INNER_L4_NONFRAG; + } else if (!memcmp(name, "IPV6", + sizeof("IPV6") - 1)) { + if (ip_id == 0) { + ptype_mapping[i].sw_ptype |= + RTE_PTYPE_L3_IPV6_EXT_UNKNOWN; + ip_id++; + } else if (ip_id == 1) { + ptype_mapping[i].sw_ptype |= + RTE_PTYPE_INNER_L3_IPV6; + ip_id++; + } else if (ip_id == 2) + ptype_mapping[i].sw_ptype |= + RTE_PTYPE_INNER_L4_FRAG; + } else if (!memcmp(name, "GTPC", + sizeof("GTPC"))) + ptype_mapping[i].sw_ptype |= + RTE_PTYPE_TUNNEL_GTPC; + else if (!memcmp(name, "GTPU", sizeof("GTPU"))) + ptype_mapping[i].sw_ptype |= + RTE_PTYPE_TUNNEL_GTPU; + else if (!memcmp(name, "UDP", sizeof("UDP"))) + ptype_mapping[i].sw_ptype |= + RTE_PTYPE_INNER_L4_UDP; + else if (!memcmp(name, "TCP", sizeof("TCP"))) + ptype_mapping[i].sw_ptype |= + RTE_PTYPE_INNER_L4_TCP; + else if (!memcmp(name, "SCTP", sizeof("SCTP"))) + ptype_mapping[i].sw_ptype |= + RTE_PTYPE_INNER_L4_SCTP; + else if (!memcmp(name, "ICMP", + sizeof("ICMP") - 1)) + ptype_mapping[i].sw_ptype |= + RTE_PTYPE_INNER_L4_ICMP; + + break; + } + } + } + + ret = rte_pmd_i40e_ptype_mapping_update(port_id, ptype_mapping, + ptype_num, 0); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to update mapping table."); + rte_free(ptype_mapping); + rte_free(ptype); + return -1; + } + + rte_free(ptype_mapping); + rte_free(ptype); + return 0; +} + +void +i40e_update_personalized_info(struct rte_eth_dev *dev, uint8_t *pkg, + uint32_t pkg_size) +{ + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + uint32_t proto_num; + struct rte_pmd_i40e_proto_info *proto; + uint32_t i; + int ret; + + /* get information about protocol number */ + 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 = rte_zmalloc("new_proto", + proto_num * sizeof(struct rte_pmd_i40e_proto_info), + 0); + if (!proto) { + PMD_DRV_LOG(ERR, "Failed to allocate memory"); + return; + } + + /* get information about protocol list */ + 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"); + rte_free(proto); + return; + } + + /* Check if GTP is supported. */ + for (i = 0; i < proto_num; i++) { + if (!memcmp(proto[i].name, "GTP", sizeof("GTP") - 1)) { + pf->gtp_support = true; + break; + } + } + + /* Update pctype info */ + ret = i40e_update_personalized_pctype(dev, pkg, pkg_size, + proto_num, proto); + if (ret) + PMD_DRV_LOG(INFO, "No pctype is updated."); + + /* Update ptype info */ + ret = i40e_update_personalized_ptype(dev, pkg, pkg_size, + proto_num, proto); + if (ret) + PMD_DRV_LOG(INFO, "No pctype is updated."); + + rte_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 ad80f0f..85ae07b 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_IPV4, + I40E_PERSONALIZED_GTPU_IPV6, + I40E_PERSONALIZED_GTPU, + I40E_PERSONALIZED_MAX, +}; + +#define I40E_FILTER_PCTYPE_INVALID 0 +struct i40e_personalized_pctype { + uint8_t index; /* Indicate which personalized pctype */ + 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,11 @@ 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; + + /* Dynamic Device Personalization */ + bool gtp_support; /* 1 - support GTP-C and GTP-U */ + /* customer personalized pctype */ + struct i40e_personalized_pctype new_pctype[I40E_PERSONALIZED_MAX]; }; enum pending_msg { @@ -1003,6 +1023,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_info(struct rte_eth_dev *dev, 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 9f9c808..d1313f6 100644 --- a/drivers/net/i40e/rte_pmd_i40e.c +++ b/drivers/net/i40e/rte_pmd_i40e.c @@ -1608,6 +1608,8 @@ rte_pmd_i40e_process_ddp_package(uint8_t port, uint8_t *buff, return -EINVAL; } + i40e_update_personalized_info(dev, buff, size); + /* Find metadata segment */ metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA, pkg_hdr); @@ -2090,7 +2092,9 @@ static int check_invalid_pkt_type(uint32_t pkt_type) tnl != RTE_PTYPE_TUNNEL_VXLAN && tnl != RTE_PTYPE_TUNNEL_NVGRE && tnl != RTE_PTYPE_TUNNEL_GENEVE && - tnl != RTE_PTYPE_TUNNEL_GRENAT) + tnl != RTE_PTYPE_TUNNEL_GRENAT && + tnl != RTE_PTYPE_TUNNEL_GTPC && + tnl != RTE_PTYPE_TUNNEL_GTPU) return -1; if (il2 &&