From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-ft4.fr.colt.net (smtp-ft4.fr.colt.net [213.41.78.208]) by dpdk.org (Postfix) with ESMTP id B0C7EAFD3 for ; Wed, 30 Apr 2014 15:55:31 +0200 (CEST) Received: from smtp-ex5.fr.colt.net (smtp-ex5.fr.colt.net [213.41.78.121]) by smtp-ft4.fr.colt.net (8.14.3/8.14.3/Debian-5+lenny1) with ESMTP id s3UDtaCv007650 for ; Wed, 30 Apr 2014 15:55:36 +0200 Received: from 33.106-14-84.ripe.coltfrance.com ([84.14.106.33] helo=proxy.6wind.com) by smtp-ex5.fr.colt.net with esmtp (Exim) (envelope-from ) id 1WfUz0-0003cK-22 for ; Wed, 30 Apr 2014 15:55:35 +0200 Received: from 6wind.com (unknown [10.16.0.189]) by proxy.6wind.com (Postfix) with SMTP id 81D3B283C5; Wed, 30 Apr 2014 15:55:33 +0200 (CEST) Received: by 6wind.com (sSMTP sendmail emulation); Wed, 30 Apr 2014 15:55:33 +0200 From: Ivan Boule To: dev@dpdk.org Date: Wed, 30 Apr 2014 15:55:23 +0200 Message-Id: <1398866126-16931-3-git-send-email-ivan.boule@6wind.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1398866126-16931-1-git-send-email-ivan.boule@6wind.com> References: <1398866126-16931-1-git-send-email-ivan.boule@6wind.com> X-ACL-Warn: 1/1 recipients OK. Subject: [dpdk-dev] [PATCH 2/5] ethdev: allow to set RSS hash computation flags and/or key 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: Wed, 30 Apr 2014 13:55:32 -0000 1) Add a new function "rss_hash_conf_update" in the PMD API to dynamically update the RSS flags and/or the RSS key used by a NIC to compute the RSS hash of input packets. The new function uses the existing data structure "rte_eth_rss_conf" for the argument that contains the new hash flags and/or the new hash key to use. 2) Add the ixgbe-specific function "ixgbe_dev_rss_hash_conf_update" and the igb-specific function "eth_igb_rss_hash_conf_update" to update the RSS hash configuration of ixgbe and igb controllers respectively. Note: Configuring the RSS hash flags and the RSS key used by a NIC consists in updating appropriate PCI registers of the NIC. These operations have been manually tested with the interactive commands "write reg" and "write regbit" of the testpmd application. Signed-off-by: Ivan Boule --- lib/librte_ether/rte_ethdev.c | 23 +++++++++ lib/librte_ether/rte_ethdev.h | 25 ++++++++++ lib/librte_pmd_e1000/e1000_ethdev.h | 3 ++ lib/librte_pmd_e1000/igb_ethdev.c | 1 + lib/librte_pmd_e1000/igb_rxtx.c | 93 +++++++++++++++++++++-------------- lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 1 + lib/librte_pmd_ixgbe/ixgbe_ethdev.h | 3 ++ lib/librte_pmd_ixgbe/ixgbe_rxtx.c | 90 ++++++++++++++++++++------------- 8 files changed, 169 insertions(+), 70 deletions(-) diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 473c98b..c00dff0 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1572,6 +1572,29 @@ rte_eth_dev_rss_reta_query(uint8_t port_id, struct rte_eth_rss_reta *reta_conf) } int +rte_eth_dev_rss_hash_conf_update(uint8_t port_id, + struct rte_eth_rss_conf *rss_conf) +{ + struct rte_eth_dev *dev; + uint16_t rss_hash_protos; + + if (port_id >= nb_ports) { + PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id); + return (-ENODEV); + } + rss_hash_protos = rss_conf->rss_hf; + if ((rss_hash_protos != 0) && + ((rss_hash_protos & ETH_RSS_PROTO_MASK) == 0)) { + PMD_DEBUG_TRACE("Invalid rss_hash_protos=0x%x\n", + rss_hash_protos); + return (-EINVAL); + } + dev = &rte_eth_devices[port_id]; + FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_conf_update, -ENOTSUP); + return (*dev->dev_ops->rss_hash_conf_update)(dev, rss_conf); +} + +int rte_eth_led_on(uint8_t port_id) { struct rte_eth_dev *dev; diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index dea7471..a970761 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -331,6 +331,8 @@ struct rte_eth_rss_conf { #define ETH_RSS_IPV4_UDP 0x0040 /**< IPv4/UDP packet. */ #define ETH_RSS_IPV6_UDP 0x0080 /**< IPv6/UDP packet. */ #define ETH_RSS_IPV6_UDP_EX 0x0100 /**< IPv6/UDP with extension headers. */ + +#define ETH_RSS_PROTO_MASK 0x01FF /**< Mask of valid RSS hash protocols */ /* Definitions used for redirection table entry size */ #define ETH_RSS_RETA_NUM_ENTRIES 128 #define ETH_RSS_RETA_MAX_QUEUE 16 @@ -966,6 +968,10 @@ typedef int (*reta_query_t)(struct rte_eth_dev *dev, struct rte_eth_rss_reta *reta_conf); /**< @internal Query RSS redirection table on an Ethernet device */ +typedef int (*rss_hash_conf_update_t)(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf); +/**< @internal Update RSS hash configuration of an Ethernet device */ + typedef int (*eth_dev_led_on_t)(struct rte_eth_dev *dev); /**< @internal Turn on SW controllable LED on an Ethernet device */ @@ -1153,6 +1159,8 @@ struct eth_dev_ops { bypass_wd_reset_t bypass_wd_reset; #endif + /** Configure RSS hash protocols. */ + rss_hash_conf_update_t rss_hash_conf_update; }; /** @@ -2859,6 +2867,23 @@ int rte_eth_dev_bypass_wd_timeout_show(uint8_t port, uint32_t *wd_timeout); */ int rte_eth_dev_bypass_wd_reset(uint8_t port); + /** + * Configuration of Receive Side Scaling hash computation of Ethernet device. + * + * @param port + * The port identifier of the Ethernet device. + * @param rss_conf + * The new configuration to use for RSS hash computation on the port. + * @return + * - (0) if successful. + * - (-ENODEV) if port identifier is invalid. + * - (-ENOTSUP) if hardware doesn't support. + * - (-EINVAL) if bad parameter. + */ +int +rte_eth_dev_rss_hash_conf_update(uint8_t port_id, + struct rte_eth_rss_conf *rss_conf); + #ifdef __cplusplus } #endif diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e1000_ethdev.h index d09064e..e228c53 100644 --- a/lib/librte_pmd_e1000/e1000_ethdev.h +++ b/lib/librte_pmd_e1000/e1000_ethdev.h @@ -138,6 +138,9 @@ uint16_t eth_igb_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts, uint16_t eth_igb_recv_scattered_pkts(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); +int eth_igb_rss_hash_conf_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf); + int eth_igbvf_rx_init(struct rte_eth_dev *dev); void eth_igbvf_tx_init(struct rte_eth_dev *dev); diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c index 673b4de..07ae149 100644 --- a/lib/librte_pmd_e1000/igb_ethdev.c +++ b/lib/librte_pmd_e1000/igb_ethdev.c @@ -193,6 +193,7 @@ static struct eth_dev_ops eth_igb_ops = { .mac_addr_remove = eth_igb_rar_clear, .reta_update = eth_igb_rss_reta_update, .reta_query = eth_igb_rss_reta_query, + .rss_hash_conf_update = eth_igb_rss_hash_conf_update, }; /* diff --git a/lib/librte_pmd_e1000/igb_rxtx.c b/lib/librte_pmd_e1000/igb_rxtx.c index 1ebe2f5..5499fd8 100644 --- a/lib/librte_pmd_e1000/igb_rxtx.c +++ b/lib/librte_pmd_e1000/igb_rxtx.c @@ -1518,54 +1518,36 @@ igb_rss_disable(struct rte_eth_dev *dev) E1000_WRITE_REG(hw, E1000_MRQC, mrqc); } -static void -igb_rss_configure(struct rte_eth_dev *dev) +int +eth_igb_rss_hash_conf_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) { struct e1000_hw *hw; - uint8_t *hash_key; + uint8_t *hash_key; uint32_t rss_key; uint32_t mrqc; - uint32_t shift; uint16_t rss_hf; uint16_t i; hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf; - if (rss_hf == 0) /* Disable RSS. */ { - igb_rss_disable(dev); - return; - } - hash_key = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key; - if (hash_key == NULL) - hash_key = rss_intel_key; /* Default hash key. */ - - /* Fill in RSS hash key. */ - for (i = 0; i < 10; i++) { - rss_key = hash_key[(i * 4)]; - rss_key |= hash_key[(i * 4) + 1] << 8; - rss_key |= hash_key[(i * 4) + 2] << 16; - rss_key |= hash_key[(i * 4) + 3] << 24; - E1000_WRITE_REG_ARRAY(hw, E1000_RSSRK(0), i, rss_key); + hash_key = rss_conf->rss_key; + if (hash_key != NULL) { + /* Fill in RSS hash key */ + for (i = 0; i < 10; i++) { + rss_key = hash_key[(i * 4)]; + rss_key |= hash_key[(i * 4) + 1] << 8; + rss_key |= hash_key[(i * 4) + 2] << 16; + rss_key |= hash_key[(i * 4) + 3] << 24; + E1000_WRITE_REG_ARRAY(hw, E1000_RSSRK(0), i, rss_key); + } } - - /* Fill in redirection table. */ - shift = (hw->mac.type == e1000_82575) ? 6 : 0; - for (i = 0; i < 128; i++) { - union e1000_reta { - uint32_t dword; - uint8_t bytes[4]; - } reta; - uint8_t q_idx; - - q_idx = (uint8_t) ((dev->data->nb_rx_queues > 1) ? - i % dev->data->nb_rx_queues : 0); - reta.bytes[i & 3] = (uint8_t) (q_idx << shift); - if ((i & 3) == 3) - E1000_WRITE_REG(hw, E1000_RETA(i >> 2), reta.dword); + rss_hf = rss_conf->rss_hf; + if (rss_hf == 0) { /* Disable RSS */ + igb_rss_disable(dev); + return 0; } - /* Set configured hashing functions in MRQC register. */ + /* Set configured hashing protocols in MRQC register */ mrqc = E1000_MRQC_ENABLE_RSS_4Q; /* RSS enabled. */ if (rss_hf & ETH_RSS_IPV4) mrqc |= E1000_MRQC_RSS_FIELD_IPV4; @@ -1586,6 +1568,43 @@ igb_rss_configure(struct rte_eth_dev *dev) if (rss_hf & ETH_RSS_IPV6_UDP_EX) mrqc |= E1000_MRQC_RSS_FIELD_IPV6_UDP_EX; E1000_WRITE_REG(hw, E1000_MRQC, mrqc); + return 0; +} + +static void +igb_rss_configure(struct rte_eth_dev *dev) +{ + struct rte_eth_rss_conf rss_conf; + struct e1000_hw *hw; + uint32_t shift; + uint16_t i; + + hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + /* Fill in redirection table. */ + shift = (hw->mac.type == e1000_82575) ? 6 : 0; + for (i = 0; i < 128; i++) { + union e1000_reta { + uint32_t dword; + uint8_t bytes[4]; + } reta; + uint8_t q_idx; + + q_idx = (uint8_t) ((dev->data->nb_rx_queues > 1) ? + i % dev->data->nb_rx_queues : 0); + reta.bytes[i & 3] = (uint8_t) (q_idx << shift); + if ((i & 3) == 3) + E1000_WRITE_REG(hw, E1000_RETA(i >> 2), reta.dword); + } + + /* + * Configure the RSS key and the RSS protocols used to compute + * the RSS hash of input packets. + */ + rss_conf = dev->data->dev_conf.rx_adv_conf.rss_conf; + if (rss_conf.rss_key == NULL) + rss_conf.rss_key = rss_intel_key; /* Default hash key */ + (void) eth_igb_rss_hash_conf_update(dev, &rss_conf); } /* diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c index 6dd52d7..5910501 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c @@ -300,6 +300,7 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = { .bypass_ver_show = ixgbe_bypass_ver_show, .bypass_wd_reset = ixgbe_bypass_wd_reset, #endif /* RTE_NIC_BYPASS */ + .rss_hash_conf_update = ixgbe_dev_rss_hash_conf_update, }; /* diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h index 9d7e93f..3d33ad2 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h @@ -235,6 +235,9 @@ uint16_t ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t ixgbe_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts); +int ixgbe_dev_rss_hash_conf_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf); + /* * Flow director function prototypes */ diff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c index 7930dbd..877ecfd 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c +++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c @@ -2291,50 +2291,37 @@ ixgbe_rss_disable(struct rte_eth_dev *dev) IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); } -static void -ixgbe_rss_configure(struct rte_eth_dev *dev) +int +ixgbe_dev_rss_hash_conf_update(struct rte_eth_dev *dev, + struct rte_eth_rss_conf *rss_conf) { struct ixgbe_hw *hw; - uint8_t *hash_key; - uint32_t rss_key; + uint8_t *hash_key; uint32_t mrqc; - uint32_t reta; + uint32_t rss_key; uint16_t rss_hf; uint16_t i; - uint16_t j; - PMD_INIT_FUNC_TRACE(); hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); - - rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf; + hash_key = rss_conf->rss_key; + if (hash_key != NULL) { + /* Fill in RSS hash key */ + for (i = 0; i < 10; i++) { + rss_key = hash_key[(i * 4)]; + rss_key |= hash_key[(i * 4) + 1] << 8; + rss_key |= hash_key[(i * 4) + 2] << 16; + rss_key |= hash_key[(i * 4) + 3] << 24; + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_RSSRK(0), i, rss_key); + } + } + rss_hf = rss_conf->rss_hf; if (rss_hf == 0) { /* Disable RSS */ ixgbe_rss_disable(dev); - return; - } - hash_key = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key; - if (hash_key == NULL) - hash_key = rss_intel_key; /* Default hash key */ - - /* Fill in RSS hash key */ - for (i = 0; i < 10; i++) { - rss_key = hash_key[(i * 4)]; - rss_key |= hash_key[(i * 4) + 1] << 8; - rss_key |= hash_key[(i * 4) + 2] << 16; - rss_key |= hash_key[(i * 4) + 3] << 24; - IXGBE_WRITE_REG_ARRAY(hw, IXGBE_RSSRK(0), i, rss_key); - } - - /* Fill in redirection table */ - reta = 0; - for (i = 0, j = 0; i < 128; i++, j++) { - if (j == dev->data->nb_rx_queues) j = 0; - reta = (reta << 8) | j; - if ((i & 3) == 3) - IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), rte_bswap32(reta)); + return 0; } - /* Set configured hashing functions in MRQC register */ - mrqc = IXGBE_MRQC_RSSEN; /* RSS enable */ + /* Set configured hashing protocols in MRQC register */ + mrqc = IXGBE_MRQC_RSSEN; /* Enable RSS */ if (rss_hf & ETH_RSS_IPV4) mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4; if (rss_hf & ETH_RSS_IPV4_TCP) @@ -2354,6 +2341,43 @@ ixgbe_rss_configure(struct rte_eth_dev *dev) if (rss_hf & ETH_RSS_IPV6_UDP_EX) mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP; IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); + return 0; +} + +static void +ixgbe_rss_configure(struct rte_eth_dev *dev) +{ + struct rte_eth_rss_conf rss_conf; + struct ixgbe_hw *hw; + uint32_t reta; + uint16_t i; + uint16_t j; + + PMD_INIT_FUNC_TRACE(); + hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + /* + * Fill in redirection table + * The byte-swap is needed because NIC registers are in + * little-endian order. + */ + reta = 0; + for (i = 0, j = 0; i < 128; i++, j++) { + if (j == dev->data->nb_rx_queues) j = 0; + reta = (reta << 8) | j; + if ((i & 3) == 3) + IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), + rte_bswap32(reta)); + } + + /* + * Configure the RSS key and the RSS protocols used to compute + * the RSS hash of input packets. + */ + rss_conf = dev->data->dev_conf.rx_adv_conf.rss_conf; + if (rss_conf.rss_key == NULL) + rss_conf.rss_key = rss_intel_key; /* Default hash key */ + (void) ixgbe_dev_rss_hash_conf_update(dev, &rss_conf); } #define NUM_VFTA_REGISTERS 128 -- 1.7.10.4