From: Sony Chacko Date: Thu, 16 Jun 2016 05:47:03 +0000 (-0700) Subject: net/qede: support RSS hash configuration X-Git-Tag: spdx-start~6425 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=4c98f2768eef435cfcbf44d8094ec02177ba8440;p=dpdk.git net/qede: support RSS hash configuration Add support for setting hash configuration based on adapter capability and update corresponding NIC documentation. Signed-off-by: Sony Chacko --- diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst index 286fe006b2..1974ac763a 100644 --- a/doc/guides/nics/overview.rst +++ b/doc/guides/nics/overview.rst @@ -102,7 +102,7 @@ Most of these differences are summarized below. Unicast MAC filter Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Multicast MAC filter Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y RSS hash Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y - RSS key update Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y + RSS key update Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y RSS reta update Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y VMDq Y Y Y Y Y Y Y SR-IOV Y Y Y Y Y Y Y Y Y Y Y diff --git a/doc/guides/nics/qede.rst b/doc/guides/nics/qede.rst index 9ff3d1dfd6..c5fbd83732 100644 --- a/doc/guides/nics/qede.rst +++ b/doc/guides/nics/qede.rst @@ -51,7 +51,7 @@ Supported Features - VLAN offload - Filtering and stripping - Stateless checksum offloads (IPv4/TCP/UDP) - Multiple Rx/Tx queues (queue-pairs) -- RSS (with default table/key) +- RSS (with user configurable table/key) - TSS - Multiple MAC address - Default pause flow control @@ -61,7 +61,6 @@ Non-supported Features ---------------------- - Scatter-Gather Rx/Tx frames -- User configurable RETA table/key - Unequal number of Rx/Tx queues - MTU change (dynamic) - SR-IOV PF diff --git a/drivers/net/qede/qede_eth_if.h b/drivers/net/qede/qede_eth_if.h index 61f677cae7..26968eb09e 100644 --- a/drivers/net/qede/qede_eth_if.h +++ b/drivers/net/qede/qede_eth_if.h @@ -53,6 +53,7 @@ struct qed_dev_eth_info { struct qed_update_vport_rss_params { uint16_t rss_ind_table[128]; uint32_t rss_key[10]; + u8 rss_caps; }; struct qed_stop_rxq_params { diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c index 1273fd3dfd..84ff6f859d 100644 --- a/drivers/net/qede/qede_ethdev.c +++ b/drivers/net/qede/qede_ethdev.c @@ -753,6 +753,47 @@ qede_dev_supported_ptypes_get(struct rte_eth_dev *eth_dev) return NULL; } +int qede_rss_hash_update(struct rte_eth_dev *eth_dev, + struct rte_eth_rss_conf *rss_conf) +{ + struct qed_update_vport_params vport_update_params; + struct qede_dev *qdev = eth_dev->data->dev_private; + struct ecore_dev *edev = &qdev->edev; + uint8_t rss_caps; + uint32_t *key = (uint32_t *)rss_conf->rss_key; + uint64_t hf = rss_conf->rss_hf; + int i; + + if (hf == 0) + DP_ERR(edev, "hash function 0 will disable RSS\n"); + + rss_caps = 0; + rss_caps |= (hf & ETH_RSS_IPV4) ? ECORE_RSS_IPV4 : 0; + rss_caps |= (hf & ETH_RSS_IPV6) ? ECORE_RSS_IPV6 : 0; + rss_caps |= (hf & ETH_RSS_IPV6_EX) ? ECORE_RSS_IPV6 : 0; + rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_TCP) ? ECORE_RSS_IPV4_TCP : 0; + rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_TCP) ? ECORE_RSS_IPV6_TCP : 0; + rss_caps |= (hf & ETH_RSS_IPV6_TCP_EX) ? ECORE_RSS_IPV6_TCP : 0; + + /* If the mapping doesn't fit any supported, return */ + if (rss_caps == 0 && hf != 0) + return -EINVAL; + + memset(&vport_update_params, 0, sizeof(vport_update_params)); + + if (key != NULL) + memcpy(qdev->rss_params.rss_key, rss_conf->rss_key, + rss_conf->rss_key_len); + + qdev->rss_params.rss_caps = rss_caps; + memcpy(&vport_update_params.rss_params, &qdev->rss_params, + sizeof(vport_update_params.rss_params)); + vport_update_params.update_rss_flg = 1; + vport_update_params.vport_id = 0; + + return qdev->ops->vport_update(edev, &vport_update_params); +} + static const struct eth_dev_ops qede_eth_dev_ops = { .dev_configure = qede_dev_configure, .dev_infos_get = qede_dev_info_get, @@ -780,6 +821,7 @@ static const struct eth_dev_ops qede_eth_dev_ops = { .flow_ctrl_set = qede_flow_ctrl_set, .flow_ctrl_get = qede_flow_ctrl_get, .dev_supported_ptypes_get = qede_dev_supported_ptypes_get, + .rss_hash_update = qede_rss_hash_update, }; static const struct eth_dev_ops qede_eth_vf_dev_ops = { @@ -804,6 +846,7 @@ static const struct eth_dev_ops qede_eth_vf_dev_ops = { .vlan_offload_set = qede_vlan_offload_set, .vlan_filter_set = qede_vlan_filter_set, .dev_supported_ptypes_get = qede_dev_supported_ptypes_get, + .rss_hash_update = qede_rss_hash_update, }; static void qede_update_pf_params(struct ecore_dev *edev) diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c index 94f3c78597..ccce5fdbcd 100644 --- a/drivers/net/qede/qede_rxtx.c +++ b/drivers/net/qede/qede_rxtx.c @@ -532,13 +532,18 @@ static int qede_config_rss(struct rte_eth_dev *eth_dev, struct qed_update_vport_rss_params *rss_params) { + struct rte_eth_rss_conf rss_conf; enum rte_eth_rx_mq_mode mode = eth_dev->data->dev_conf.rxmode.mq_mode; - struct rte_eth_rss_conf rss_conf = - eth_dev->data->dev_conf.rx_adv_conf.rss_conf; struct qede_dev *qdev = eth_dev->data->dev_private; struct ecore_dev *edev = &qdev->edev; + uint8_t rss_caps; unsigned int i; + uint64_t hf; + uint32_t *key; + rss_conf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf; + key = (uint32_t *)rss_conf.rss_key; + hf = rss_conf.rss_hf; PMD_INIT_FUNC_TRACE(edev); /* Check if RSS conditions are met. @@ -553,16 +558,12 @@ qede_config_rss(struct rte_eth_dev *eth_dev, DP_INFO(edev, "RSS flag is set\n"); - if (rss_conf.rss_hf == 0) { - DP_NOTICE(edev, false, "No RSS hash function to apply\n"); - return -EINVAL; - } + if (rss_conf.rss_hf == 0) + DP_NOTICE(edev, false, "RSS hash function = 0, disables RSS\n"); - if (rss_conf.rss_key != NULL) { - DP_NOTICE(edev, false, - "User provided RSS key is not supported\n"); - return -EINVAL; - } + if (rss_conf.rss_key != NULL) + memcpy(qdev->rss_params.rss_key, rss_conf.rss_key, + rss_conf.rss_key_len); memset(rss_params, 0, sizeof(*rss_params)); @@ -570,8 +571,23 @@ qede_config_rss(struct rte_eth_dev *eth_dev, rss_params->rss_ind_table[i] = qede_rxfh_indir_default(i, QEDE_RSS_CNT(qdev)); - qede_prandom_bytes(rss_params->rss_key, - sizeof(rss_params->rss_key)); + /* key and protocols */ + if (rss_conf.rss_key == NULL) + qede_prandom_bytes(rss_params->rss_key, + sizeof(rss_params->rss_key)); + else + memcpy(rss_params->rss_key, rss_conf.rss_key, + rss_conf.rss_key_len); + + rss_caps = 0; + rss_caps |= (hf & ETH_RSS_IPV4) ? ECORE_RSS_IPV4 : 0; + rss_caps |= (hf & ETH_RSS_IPV6) ? ECORE_RSS_IPV6 : 0; + rss_caps |= (hf & ETH_RSS_IPV6_EX) ? ECORE_RSS_IPV6 : 0; + rss_caps |= (hf & ETH_RSS_NONFRAG_IPV4_TCP) ? ECORE_RSS_IPV4_TCP : 0; + rss_caps |= (hf & ETH_RSS_NONFRAG_IPV6_TCP) ? ECORE_RSS_IPV6_TCP : 0; + rss_caps |= (hf & ETH_RSS_IPV6_TCP_EX) ? ECORE_RSS_IPV6_TCP : 0; + + rss_params->rss_caps = rss_caps; DP_INFO(edev, "RSS check passes\n");