From patchwork Thu Jul 24 06:42:28 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Helin" X-Patchwork-Id: 90 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 3CD44B360 for ; Thu, 24 Jul 2014 08:41:19 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 23 Jul 2014 23:42:45 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.01,722,1400050800"; d="scan'208";a="548226825" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by orsmga001.jf.intel.com with ESMTP; 23 Jul 2014 23:42:44 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id s6O6gg8p017105; Thu, 24 Jul 2014 14:42:42 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id s6O6gdT3011668; Thu, 24 Jul 2014 14:42:41 +0800 Received: (from hzhan75@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id s6O6gdCN011664; Thu, 24 Jul 2014 14:42:39 +0800 From: Helin Zhang To: dev@dpdk.org Date: Thu, 24 Jul 2014 14:42:28 +0800 Message-Id: <1406184149-11531-5-git-send-email-helin.zhang@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: <1406184149-11531-1-git-send-email-helin.zhang@intel.com> References: <1406184149-11531-1-git-send-email-helin.zhang@intel.com> Subject: [dpdk-dev] [PATCH 4/5] i40e: support configuring symmetric hash function X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 Jul 2014 06:41:20 -0000 Symmetric hash function can be configured: * Set symmetric hash enable per port. * Set symmetric hash enable per pctype (packet classification type). * Set the swap configurations. Commands are implemented for 'rx_classification_filter_ctl' to support above operations which can be called in applications. Also 'check_command_supported' is also implemented to check if a specific capability(command) is supported or not. Signed-off-by: Helin Zhang --- lib/librte_ether/Makefile | 1 + lib/librte_ether/rte_eth_features.h | 65 ++++++ lib/librte_pmd_i40e/Makefile | 6 + lib/librte_pmd_i40e/i40e_ethdev.c | 409 ++++++++++++++++++++++++++++++++++++ lib/librte_pmd_i40e/rte_i40e.h | 95 +++++++++ 5 files changed, 576 insertions(+) create mode 100644 lib/librte_ether/rte_eth_features.h create mode 100644 lib/librte_pmd_i40e/rte_i40e.h diff --git a/lib/librte_ether/Makefile b/lib/librte_ether/Makefile index b310f8b..8089723 100644 --- a/lib/librte_ether/Makefile +++ b/lib/librte_ether/Makefile @@ -46,6 +46,7 @@ SRCS-y += rte_ethdev.c # SYMLINK-y-include += rte_ether.h SYMLINK-y-include += rte_ethdev.h +SYMLINK-y-include += rte_eth_features.h # this lib depends upon: DEPDIRS-y += lib/librte_eal lib/librte_mempool lib/librte_ring lib/librte_mbuf diff --git a/lib/librte_ether/rte_eth_features.h b/lib/librte_ether/rte_eth_features.h new file mode 100644 index 0000000..d1790e2 --- /dev/null +++ b/lib/librte_ether/rte_eth_features.h @@ -0,0 +1,65 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTE_ETH_FEATURES_H_ +#define _RTE_ETH_FEATURES_H_ + +/** + * @file + * + * Ethernet device specific features + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define RTE_CMD_UNKNOWN 0 +/**< Command unknown. */ +#define RTE_CMD_GET_SYM_HASH_ENABLE_PER_PCTYPE 1 +/**< Command to set symmetric hash enable per pctype. */ +#define RTE_CMD_SET_SYM_HASH_ENABLE_PER_PCTYPE 2 +/**< Command to get symmetric hash enable per port. */ +#define RTE_CMD_GET_SYM_HASH_ENABLE_PER_PORT 3 +/**< Command to set symmetric hash enable per port. */ +#define RTE_CMD_SET_SYM_HASH_ENABLE_PER_PORT 4 +/**< Command to get filter swap configurations. */ +#define RTE_CMD_GET_FILTER_SWAP 5 +/**< Command to set filter swap configurations. */ +#define RTE_CMD_SET_FILTER_SWAP 6 + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_ETH_FEATURES_H_ */ diff --git a/lib/librte_pmd_i40e/Makefile b/lib/librte_pmd_i40e/Makefile index 4b31675..a777a76 100644 --- a/lib/librte_pmd_i40e/Makefile +++ b/lib/librte_pmd_i40e/Makefile @@ -87,6 +87,12 @@ SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev.c SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_rxtx.c SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_ethdev_vf.c SRCS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e_pf.c + +# +# Export include file +# +SYMLINK-$(CONFIG_RTE_LIBRTE_I40E_PMD)-include += rte_i40e.h + # this lib depends upon: DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_eal lib/librte_ether DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_mempool lib/librte_mbuf diff --git a/lib/librte_pmd_i40e/i40e_ethdev.c b/lib/librte_pmd_i40e/i40e_ethdev.c index cc04c70..b699638 100644 --- a/lib/librte_pmd_i40e/i40e_ethdev.c +++ b/lib/librte_pmd_i40e/i40e_ethdev.c @@ -48,7 +48,9 @@ #include #include #include +#include +#include "rte_i40e.h" #include "i40e_logs.h" #include "i40e/i40e_register_x710_int.h" #include "i40e/i40e_prototype.h" @@ -204,6 +206,13 @@ static int i40e_dev_rss_hash_update(struct rte_eth_dev *dev, static int i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf); static void i40e_select_hash_function(struct i40e_hw *hw); +static void i40e_init_hash_function(struct i40e_hw *hw); +static int i40e_dev_check_command_supported( + struct rte_eth_dev *dev __rte_unused, + uint32_t cmd); +static int i40e_rx_classification_filter_ctl(struct rte_eth_dev *dev, + uint32_t cmd, + void *args); /* Default hash key buffer for RSS */ static uint32_t rss_key_default[I40E_PFQF_HKEY_MAX_INDEX + 1]; @@ -249,6 +258,8 @@ static struct eth_dev_ops i40e_eth_dev_ops = { .reta_query = i40e_dev_rss_reta_query, .rss_hash_update = i40e_dev_rss_hash_update, .rss_hash_conf_get = i40e_dev_rss_hash_conf_get, + .check_command_supported = i40e_dev_check_command_supported, + .rx_classification_filter_ctl = i40e_rx_classification_filter_ctl, }; static struct eth_driver rte_i40e_pmd = { @@ -385,6 +396,8 @@ eth_i40e_dev_init(__rte_unused struct eth_driver *eth_drv, return ret; } + /* Init hash functions */ + i40e_init_hash_function(hw); /* Select hash functions */ i40e_select_hash_function(hw); @@ -3961,6 +3974,342 @@ i40e_pf_config_mq_rx(struct i40e_pf *pf) return 0; } +static int +i40e_get_filter_swap(struct i40e_hw *hw, struct rte_i40e_filter_swap_info *info) +{ + uint32_t reg; + + if (!hw || !info) { + PMD_DRV_LOG(ERR, "Invalid pointer\n"); + return -1; + } + + switch (info->pctype) { + case ETH_PCTYPE_NONF_IPV4_UDP: + case ETH_PCTYPE_NONF_IPV4_TCP: + case ETH_PCTYPE_NONF_IPV4_SCTP: + case ETH_PCTYPE_NONF_IPV4_OTHER: + case ETH_PCTYPE_FRAG_IPV4: + case ETH_PCTYPE_NONF_IPV6_UDP: + case ETH_PCTYPE_NONF_IPV6_TCP: + case ETH_PCTYPE_NONF_IPV6_SCTP: + case ETH_PCTYPE_NONF_IPV6_OTHER: + case ETH_PCTYPE_FRAG_IPV6: + case ETH_PCTYPE_L2_PAYLOAD: + reg = I40E_READ_REG(hw, I40E_GLQF_SWAP(0, info->pctype)); + PMD_DRV_LOG(DEBUG, "Value read from I40E_GLQF_SWAP[0,%d]: " + "0x%x\n", info->pctype, reg); + + /** + * The offset and length read from register in word unit, + * which need to be converted in byte unit before being saved. + */ + info->off0_src0 = + (uint8_t)((reg & I40E_GLQF_SWAP_OFF0_SRC0_MASK) >> + I40E_GLQF_SWAP_OFF0_SRC0_SHIFT) << 1; + info->off0_src1 = + (uint8_t)((reg & I40E_GLQF_SWAP_OFF0_SRC1_MASK) >> + I40E_GLQF_SWAP_OFF0_SRC1_SHIFT) << 1; + info->len0 = (uint8_t)((reg & I40E_GLQF_SWAP_FLEN0_MASK) >> + I40E_GLQF_SWAP_FLEN0_SHIFT) << 1; + info->off1_src0 = + (uint8_t)((reg & I40E_GLQF_SWAP_OFF1_SRC0_MASK) >> + I40E_GLQF_SWAP_OFF1_SRC0_SHIFT) << 1; + info->off1_src1 = + (uint8_t)((reg & I40E_GLQF_SWAP_OFF1_SRC1_MASK) >> + I40E_GLQF_SWAP_OFF1_SRC1_SHIFT) << 1; + info->len1 = (uint8_t)((reg & I40E_GLQF_SWAP_FLEN1_MASK) >> + I40E_GLQF_SWAP_FLEN1_SHIFT) << 1; + break; + case ETH_PCTYPE_FCOE_OX: + case ETH_PCTYPE_FCOE_RX: + case ETH_PCTYPE_FCOE_OTHER: + default: + PMD_DRV_LOG(ERR, "PCTYPE[%u] is out of supported range\n", + info->pctype); + return -1; + } + + return 0; +} + +static int +i40e_set_filter_swap(struct i40e_hw *hw, struct rte_i40e_filter_swap_info *info) +{ +#define I40E_FIELD_LEN_MAX 0x1f +#define I40E_FIELD_OFFSET_MAX 0x7f + uint32_t reg; + + if (!hw || !info) { + PMD_DRV_LOG(ERR, "Invalid pointer\n"); + return -1; + } + + switch (info->pctype) { + case ETH_PCTYPE_NONF_IPV4_UDP: + case ETH_PCTYPE_NONF_IPV4_TCP: + case ETH_PCTYPE_NONF_IPV4_SCTP: + case ETH_PCTYPE_NONF_IPV4_OTHER: + case ETH_PCTYPE_FRAG_IPV4: + case ETH_PCTYPE_NONF_IPV6_UDP: + case ETH_PCTYPE_NONF_IPV6_TCP: + case ETH_PCTYPE_NONF_IPV6_SCTP: + case ETH_PCTYPE_NONF_IPV6_OTHER: + case ETH_PCTYPE_FRAG_IPV6: + case ETH_PCTYPE_L2_PAYLOAD: + if (info->off0_src0 > I40E_FIELD_OFFSET_MAX) { + PMD_DRV_LOG(ERR, "off0_src0 (0x%x) exceeds the " + "maximum of 0x%x\n", info->off0_src0, + I40E_FIELD_OFFSET_MAX); + return -1; + } else if (info->off0_src1 > I40E_FIELD_OFFSET_MAX) { + PMD_DRV_LOG(ERR, "off0_src1 (0x%x) exceeds the " + "maximum of 0x%x\n", info->off0_src1, + I40E_FIELD_OFFSET_MAX); + return -1; + } else if (info->len0 > I40E_FIELD_LEN_MAX) { + PMD_DRV_LOG(ERR, "len0 (0x%x) exceeds the maximum " + "of 0x%x\n", info->len0, I40E_FIELD_LEN_MAX); + return -1; + } else if (info->off1_src0 > I40E_FIELD_OFFSET_MAX) { + PMD_DRV_LOG(ERR, "off1_src0 (0x%x) exceeds the " + "maximum of 0x%x\n", info->off1_src0, + I40E_FIELD_OFFSET_MAX); + return -1; + } else if (info->off1_src1 > I40E_FIELD_OFFSET_MAX) { + PMD_DRV_LOG(ERR, "off1_src1 (0x%x) exceeds the " + "maximum of 0x%x\n", info->off1_src1, + I40E_FIELD_OFFSET_MAX); + return -1; + } else if (info->len1 > I40E_FIELD_LEN_MAX) { + PMD_DRV_LOG(ERR, "len1 (0x%x) exceeds the maximum " + "of 0x%x\n", info->len1, I40E_FIELD_LEN_MAX); + return -1; + } + + /** + * The offset and length given in byte unit, which need to be + * converted in word unit before being written to the register, + * as hardware requires it in word unit. + */ + reg = (info->off0_src0 >> 1) << I40E_GLQF_SWAP_OFF0_SRC0_SHIFT; + reg |= (info->off0_src1 >> 1) << + I40E_GLQF_SWAP_OFF0_SRC1_SHIFT; + reg |= (info->len0 >> 1) << I40E_GLQF_SWAP_FLEN0_SHIFT; + reg |= (info->off1_src0 >> 1) << + I40E_GLQF_SWAP_OFF1_SRC0_SHIFT; + reg |= (info->off1_src1 >> 1) << + I40E_GLQF_SWAP_OFF1_SRC1_SHIFT; + reg |= (info->len1 >> 1) << I40E_GLQF_SWAP_FLEN1_SHIFT; + PMD_DRV_LOG(DEBUG, "Value to be written to " + "I40E_GLQF_SWAP[0,%d]: 0x%x\n", info->pctype, reg); + I40E_WRITE_REG(hw, I40E_GLQF_SWAP(0, info->pctype), reg); + I40E_WRITE_FLUSH(hw); + break; + case ETH_PCTYPE_FCOE_OX: + case ETH_PCTYPE_FCOE_RX: + case ETH_PCTYPE_FCOE_OTHER: + default: + PMD_DRV_LOG(ERR, "PCTYPE[%u] is out of supported range\n", + info->pctype); + return -1; + } + + return 0; +} + +static int +i40e_get_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t *enable) +{ + uint32_t reg; + + if (!hw || !enable) { + PMD_DRV_LOG(ERR, "Invalid pointer\n"); + return -1; + } + + reg = I40E_READ_REG(hw, I40E_PRTQF_CTL_0); + *enable = reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK ? 1 : 0; + + return 0; +} + +static int +i40e_set_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t *enable) +{ + uint32_t reg; + + if (!hw || !enable) { + PMD_DRV_LOG(ERR, "Invalid pointer\n"); + return -1; + } + + reg = I40E_READ_REG(hw, I40E_PRTQF_CTL_0); + if (*enable > 0) { + if (reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK) { + PMD_DRV_LOG(INFO, "Symmetric hash has already " + "been enabled\n"); + return 0; + } + reg |= I40E_PRTQF_CTL_0_HSYM_ENA_MASK; + } else { + if (!(reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK)) { + PMD_DRV_LOG(INFO, "Symmetric hash has already " + "been disabled\n"); + return 0; + } + reg &= ~I40E_PRTQF_CTL_0_HSYM_ENA_MASK; + } + I40E_WRITE_REG(hw, I40E_PRTQF_CTL_0, reg); + I40E_WRITE_FLUSH(hw); + + return 0; +} + +static int +i40e_get_symmetric_hash_enable_per_pctype(struct i40e_hw *hw, + struct rte_i40e_sym_hash_enable_info *info) +{ + uint32_t reg; + + if (!hw || !info) { + PMD_DRV_LOG(ERR, "Invalid pointer\n"); + return -1; + } + + switch (info->pctype) { + case ETH_PCTYPE_NONF_IPV4_UDP: + case ETH_PCTYPE_NONF_IPV4_TCP: + case ETH_PCTYPE_NONF_IPV4_SCTP: + case ETH_PCTYPE_NONF_IPV4_OTHER: + case ETH_PCTYPE_FRAG_IPV4: + case ETH_PCTYPE_NONF_IPV6_UDP: + case ETH_PCTYPE_NONF_IPV6_TCP: + case ETH_PCTYPE_NONF_IPV6_SCTP: + case ETH_PCTYPE_NONF_IPV6_OTHER: + case ETH_PCTYPE_FRAG_IPV6: + case ETH_PCTYPE_L2_PAYLOAD: + reg = I40E_READ_REG(hw, I40E_GLQF_HSYM(info->pctype)); + break; + case ETH_PCTYPE_FCOE_OX: + case ETH_PCTYPE_FCOE_RX: + case ETH_PCTYPE_FCOE_OTHER: + default: + PMD_DRV_LOG(ERR, "PCTYPE[%u] is out of supported range\n", + info->pctype); + return -1; + } + + info->enable = reg & I40E_GLQF_HSYM_SYMH_ENA_MASK ? 1 : 0; + + return 0; +} + +static int +i40e_set_symmetric_hash_enable_per_pctype(struct i40e_hw *hw, + struct rte_i40e_sym_hash_enable_info *info) +{ + uint32_t reg; + + if (!hw || !info) { + PMD_DRV_LOG(ERR, "Invalid pointer\n"); + return -1; + } + + switch (info->pctype) { + case ETH_PCTYPE_NONF_IPV4_UDP: + case ETH_PCTYPE_NONF_IPV4_TCP: + case ETH_PCTYPE_NONF_IPV4_SCTP: + case ETH_PCTYPE_NONF_IPV4_OTHER: + case ETH_PCTYPE_FRAG_IPV4: + case ETH_PCTYPE_NONF_IPV6_UDP: + case ETH_PCTYPE_NONF_IPV6_TCP: + case ETH_PCTYPE_NONF_IPV6_SCTP: + case ETH_PCTYPE_NONF_IPV6_OTHER: + case ETH_PCTYPE_FRAG_IPV6: + case ETH_PCTYPE_L2_PAYLOAD: + reg = info->enable ? I40E_GLQF_HSYM_SYMH_ENA_MASK : 0; + I40E_WRITE_REG(hw, I40E_GLQF_HSYM(info->pctype), reg); + I40E_WRITE_FLUSH(hw); + break; + case ETH_PCTYPE_FCOE_OX: + case ETH_PCTYPE_FCOE_RX: + case ETH_PCTYPE_FCOE_OTHER: + default: + PMD_DRV_LOG(ERR, "PCTYPE[%u] is out of supported range\n", + info->pctype); + return -1; + } + + return 0; +} + +static int +i40e_dev_check_command_supported(struct rte_eth_dev *dev __rte_unused, + uint32_t cmd) +{ + uint32_t i; + /* Check the commands defined for i40e only in rte_eth_features.h */ + static const uint32_t i40e_commands[] = { + RTE_CMD_GET_SYM_HASH_ENABLE_PER_PCTYPE, + RTE_CMD_SET_SYM_HASH_ENABLE_PER_PCTYPE, + RTE_CMD_GET_SYM_HASH_ENABLE_PER_PORT, + RTE_CMD_SET_SYM_HASH_ENABLE_PER_PORT, + RTE_CMD_GET_FILTER_SWAP, + RTE_CMD_SET_FILTER_SWAP, + }; + + for (i = 0; i < RTE_DIM(i40e_commands); i++) { + if (i40e_commands[i] == cmd) + return 1; + } + + return 0; +} + +static int +i40e_rx_classification_filter_ctl(struct rte_eth_dev *dev, + uint32_t cmd, + void *args) +{ + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int ret = 0; + + switch (cmd) { + case RTE_CMD_GET_SYM_HASH_ENABLE_PER_PCTYPE: + ret = i40e_get_symmetric_hash_enable_per_pctype(hw, + (struct rte_i40e_sym_hash_enable_info *)args); + break; + case RTE_CMD_SET_SYM_HASH_ENABLE_PER_PCTYPE: + ret = i40e_set_symmetric_hash_enable_per_pctype(hw, + (struct rte_i40e_sym_hash_enable_info *)args); + break; + case RTE_CMD_GET_SYM_HASH_ENABLE_PER_PORT: + ret = i40e_get_symmetric_hash_enable_per_port(hw, + (uint8_t *)args); + break; + case RTE_CMD_SET_SYM_HASH_ENABLE_PER_PORT: + ret = i40e_set_symmetric_hash_enable_per_port(hw, + (uint8_t *)args); + break; + case RTE_CMD_GET_FILTER_SWAP: + ret = i40e_get_filter_swap(hw, + (struct rte_i40e_filter_swap_info *)args); + break; + case RTE_CMD_SET_FILTER_SWAP: + ret = i40e_set_filter_swap(hw, + (struct rte_i40e_filter_swap_info *)args); + break; + default: + ret = -1; + PMD_DRV_LOG(ERR, "Unknown command which is not " + "supported by i40e\n"); + break; + } + + return ret; +} + static void i40e_select_hash_function(struct i40e_hw *hw) { @@ -3986,3 +4335,63 @@ i40e_select_hash_function(struct i40e_hw *hw) I40E_WRITE_REG(hw, I40E_GLQF_CTL, reg); I40E_WRITE_FLUSH(hw); } + +/** + * Initialize filter swap configurations and symmetric hash control + * configurations, as only global reset can reload the firmware + * configurations. + */ +static void +i40e_init_hash_function(struct i40e_hw *hw) +{ + static struct rte_i40e_filter_swap_info swap_info[] = { + {ETH_PCTYPE_NONF_IPV4_UDP, + 0x1e, 0x36, 0x04, 0x3a, 0x3c, 0x02}, + {ETH_PCTYPE_NONF_IPV4_TCP, + 0x1e, 0x36, 0x04, 0x3a, 0x3c, 0x02}, + {ETH_PCTYPE_NONF_IPV4_SCTP, + 0x1e, 0x36, 0x04, 0x00, 0x00, 0x00}, + {ETH_PCTYPE_NONF_IPV4_OTHER, + 0x1e, 0x36, 0x04, 0x00, 0x00, 0x00}, + {ETH_PCTYPE_FRAG_IPV4, + 0x1e, 0x36, 0x04, 0x00, 0x00, 0x00}, + {ETH_PCTYPE_NONF_IPV6_UDP, + 0x1a, 0x2a, 0x10, 0x3a, 0x3c, 0x02}, + {ETH_PCTYPE_NONF_IPV6_TCP, + 0x1a, 0x2a, 0x10, 0x3a, 0x3c, 0x02}, + {ETH_PCTYPE_NONF_IPV6_SCTP, + 0x1a, 0x2a, 0x10, 0x00, 0x00, 0x00}, + {ETH_PCTYPE_NONF_IPV6_OTHER, + 0x1a, 0x2a, 0x10, 0x00, 0x00, 0x00}, + {ETH_PCTYPE_FRAG_IPV6, + 0x1a, 0x2a, 0x10, 0x00, 0x00, 0x00}, + {ETH_PCTYPE_L2_PAYLOAD, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + }; + static struct rte_i40e_sym_hash_enable_info sym_hash_ena_info[] = { + {ETH_PCTYPE_NONF_IPV4_UDP, 0}, + {ETH_PCTYPE_NONF_IPV4_TCP, 0}, + {ETH_PCTYPE_NONF_IPV4_SCTP, 0}, + {ETH_PCTYPE_NONF_IPV4_OTHER, 0}, + {ETH_PCTYPE_FRAG_IPV4, 0}, + {ETH_PCTYPE_NONF_IPV6_UDP, 0}, + {ETH_PCTYPE_NONF_IPV6_TCP, 0}, + {ETH_PCTYPE_NONF_IPV6_SCTP, 0}, + {ETH_PCTYPE_NONF_IPV6_OTHER, 0}, + {ETH_PCTYPE_FRAG_IPV6, 0}, + {ETH_PCTYPE_L2_PAYLOAD, 0}, + }; + uint32_t i; + + /* initialize filter swap */ + for (i = 0; i < RTE_DIM(swap_info); i++) + i40e_set_filter_swap(hw, &swap_info[i]); + + /* disable all symmetric hash per pctype */ + for (i = 0; i < RTE_DIM(sym_hash_ena_info); i++) + i40e_set_symmetric_hash_enable_per_pctype(hw, + &sym_hash_ena_info[i]); + + /* disable symmetric hash per port */ + i40e_set_symmetric_hash_enable_per_port(hw, 0); +} diff --git a/lib/librte_pmd_i40e/rte_i40e.h b/lib/librte_pmd_i40e/rte_i40e.h new file mode 100644 index 0000000..211e566 --- /dev/null +++ b/lib/librte_pmd_i40e/rte_i40e.h @@ -0,0 +1,95 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTE_I40E_H_ +#define _RTE_I40E_H_ + +/** + * @file + * + * RTE I40E + * + * The I40E defines the commands and structures specifically for i40e hardware + * features. As different types of NIC hardware may have different features, + * they might not be common for all types of NIC hardwares. The commands and + * structures can be used in applications directly together with generalized + * APIs declared in rte_ethdev.h. The commands couldn't be supported by + * non-i40e PMD. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * For commands: + * 'RTE_CMD_GET_FILTER_SWAP' + * 'RTE_CMD_SET_FILTER_SWAP' + * + * A structure used to get/set filter swap. All of the offsets and + * length are defined in bytes. + */ +struct rte_i40e_filter_swap_info { + /**< Packet classification type, defined in rte_ethdev.h */ + uint8_t pctype; + /**< Offset of the 1st field of the 1st couple to be swapped. */ + uint8_t off0_src0; + /**< Offset of the 2nd field of the 1st couple to be swapped. */ + uint8_t off0_src1; + /**< Field length of the first couple. */ + uint8_t len0; + /**< Offset of the 1st field of the 2nd couple to be swapped. */ + uint8_t off1_src0; + /**< Offset of the 2nd field of the 2nd couple to be swapped. */ + uint8_t off1_src1; + /**< Field length of the second couple. */ + uint8_t len1; +}; + +/** + * For commands: + * 'RTE_CMD_GET_SYM_HASH_ENABLE_PER_PCTYPE' + * 'RTE_CMD_SET_SYM_HASH_ENABLE_PER_PCTYPE' + * + * A structure used to set/get symmetric hash enable per pctype. + */ +struct rte_i40e_sym_hash_enable_info { + uint8_t pctype; /**< packet classification type */ + uint8_t enable; /**< enable or disable flag */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +#endif /* _RTE_I40E_H_ */