net/qede: support RSS hash configuration
authorSony Chacko <sony.chacko@qlogic.com>
Thu, 16 Jun 2016 05:47:03 +0000 (22:47 -0700)
committerBruce Richardson <bruce.richardson@intel.com>
Thu, 23 Jun 2016 14:22:06 +0000 (16:22 +0200)
Add support for setting hash configuration based on adapter capability
and update corresponding NIC documentation.

Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
doc/guides/nics/overview.rst
doc/guides/nics/qede.rst
drivers/net/qede/qede_eth_if.h
drivers/net/qede/qede_ethdev.c
drivers/net/qede/qede_rxtx.c

index 286fe00..1974ac7 100644 (file)
@@ -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
index 9ff3d1d..c5fbd83 100644 (file)
@@ -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
index 61f677c..26968eb 100644 (file)
@@ -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 {
index 1273fd3..84ff6f8 100644 (file)
@@ -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)
index 94f3c78..ccce5fd 100644 (file)
@@ -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");