[dpdk-dev] [PATCH v2 1/6] net/i40e: support RSS for GTP-C and GTP-U
Beilei Xing
beilei.xing at intel.com
Thu Sep 7 13:20:58 CEST 2017
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 <beilei.xing at intel.com>
---
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
More information about the dev
mailing list