net/cnxk: support RETA and RSS hash
authorSatha Rao <skoteshwar@marvell.com>
Wed, 23 Jun 2021 04:47:00 +0000 (10:17 +0530)
committerJerin Jacob <jerinj@marvell.com>
Wed, 30 Jun 2021 01:29:04 +0000 (03:29 +0200)
This patch will implement RETA and RSS hash apis. Also added
device argument to lock rx context.

Signed-off-by: Satha Rao <skoteshwar@marvell.com>
doc/guides/nics/features/cnxk.ini
doc/guides/nics/features/cnxk_vec.ini
doc/guides/nics/features/cnxk_vf.ini
drivers/net/cnxk/cnxk_ethdev.c
drivers/net/cnxk/cnxk_ethdev.h
drivers/net/cnxk/cnxk_ethdev_devargs.c
drivers/net/cnxk/cnxk_ethdev_ops.c

index b156422..e4f4609 100644 (file)
@@ -23,6 +23,8 @@ Promiscuous mode     = Y
 Allmulticast mode    = Y
 Unicast MAC filter   = Y
 RSS hash             = Y
+RSS key update       = Y
+RSS reta update      = Y
 Inner RSS            = Y
 Flow control         = Y
 Jumbo frame          = Y
index 862a2ad..3234c30 100644 (file)
@@ -22,6 +22,8 @@ Promiscuous mode     = Y
 Allmulticast mode    = Y
 Unicast MAC filter   = Y
 RSS hash             = Y
+RSS key update       = Y
+RSS reta update      = Y
 Inner RSS            = Y
 Flow control         = Y
 Jumbo frame          = Y
index 9a492bb..d254d4d 100644 (file)
@@ -19,6 +19,8 @@ Queue start/stop     = Y
 MTU update           = Y
 TSO                  = Y
 RSS hash             = Y
+RSS key update       = Y
+RSS reta update      = Y
 Inner RSS            = Y
 Jumbo frame          = Y
 Scattered Rx         = Y
index b2a8f3a..abd9bf1 100644 (file)
@@ -1266,6 +1266,10 @@ struct eth_dev_ops cnxk_eth_dev_ops = {
        .timesync_write_time = cnxk_nix_timesync_write_time,
        .timesync_adjust_time = cnxk_nix_timesync_adjust_time,
        .read_clock = cnxk_nix_read_clock,
+       .reta_update = cnxk_nix_reta_update,
+       .reta_query = cnxk_nix_reta_query,
+       .rss_hash_update = cnxk_nix_rss_hash_update,
+       .rss_hash_conf_get = cnxk_nix_rss_hash_conf_get,
 };
 
 static int
index fa6f16f..cd08e3a 100644 (file)
@@ -330,6 +330,16 @@ uint64_t cnxk_nix_rxq_mbuf_setup(struct cnxk_eth_dev *dev);
 /* RSS */
 uint32_t cnxk_rss_ethdev_to_nix(struct cnxk_eth_dev *dev, uint64_t ethdev_rss,
                                uint8_t rss_level);
+int cnxk_nix_reta_update(struct rte_eth_dev *eth_dev,
+                        struct rte_eth_rss_reta_entry64 *reta_conf,
+                        uint16_t reta_size);
+int cnxk_nix_reta_query(struct rte_eth_dev *eth_dev,
+                       struct rte_eth_rss_reta_entry64 *reta_conf,
+                       uint16_t reta_size);
+int cnxk_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
+                            struct rte_eth_rss_conf *rss_conf);
+int cnxk_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
+                              struct rte_eth_rss_conf *rss_conf);
 
 /* Link */
 void cnxk_nix_toggle_flag_link_cfg(struct cnxk_eth_dev *dev, bool set);
index 7fd06eb..c76b628 100644 (file)
@@ -109,6 +109,7 @@ parse_switch_header_type(const char *key, const char *value, void *extra_args)
 #define CNXK_FLOW_MAX_PRIORITY "flow_max_priority"
 #define CNXK_SWITCH_HEADER_TYPE "switch_header"
 #define CNXK_RSS_TAG_AS_XOR    "tag_as_xor"
+#define CNXK_LOCK_RX_CTX       "lock_rx_ctx"
 
 int
 cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
@@ -120,6 +121,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
        uint16_t flow_max_priority = 3;
        uint16_t rss_tag_as_xor = 0;
        uint16_t scalar_enable = 0;
+       uint8_t lock_rx_ctx = 0;
        struct rte_kvargs *kvlist;
 
        if (devargs == NULL)
@@ -143,6 +145,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
                           &parse_switch_header_type, &switch_header_type);
        rte_kvargs_process(kvlist, CNXK_RSS_TAG_AS_XOR, &parse_flag,
                           &rss_tag_as_xor);
+       rte_kvargs_process(kvlist, CNXK_LOCK_RX_CTX, &parse_flag, &lock_rx_ctx);
        rte_kvargs_free(kvlist);
 
 null_devargs:
@@ -150,6 +153,7 @@ null_devargs:
        dev->nix.rss_tag_as_xor = !!rss_tag_as_xor;
        dev->nix.max_sqb_count = sqb_count;
        dev->nix.reta_sz = reta_sz;
+       dev->nix.lock_rx_ctx = lock_rx_ctx;
        dev->npc.flow_prealloc_size = flow_prealloc_size;
        dev->npc.flow_max_priority = flow_max_priority;
        dev->npc.switch_header_type = switch_header_type;
index 91de6b7..d257763 100644 (file)
@@ -724,3 +724,124 @@ cnxk_nix_dev_get_reg(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
 
        return rc;
 }
+
+int
+cnxk_nix_reta_update(struct rte_eth_dev *eth_dev,
+                    struct rte_eth_rss_reta_entry64 *reta_conf,
+                    uint16_t reta_size)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       uint16_t reta[ROC_NIX_RSS_RETA_MAX];
+       struct roc_nix *nix = &dev->nix;
+       int i, j, rc = -EINVAL, idx = 0;
+
+       if (reta_size != dev->nix.reta_sz) {
+               plt_err("Size of hash lookup table configured (%d) does not "
+                       "match the number hardware can supported (%d)",
+                       reta_size, dev->nix.reta_sz);
+               goto fail;
+       }
+
+       /* Copy RETA table */
+       for (i = 0; i < (int)(dev->nix.reta_sz / RTE_RETA_GROUP_SIZE); i++) {
+               for (j = 0; j < RTE_RETA_GROUP_SIZE; j++) {
+                       if ((reta_conf[i].mask >> j) & 0x01)
+                               reta[idx] = reta_conf[i].reta[j];
+                       idx++;
+               }
+       }
+
+       return roc_nix_rss_reta_set(nix, 0, reta);
+
+fail:
+       return rc;
+}
+
+int
+cnxk_nix_reta_query(struct rte_eth_dev *eth_dev,
+                   struct rte_eth_rss_reta_entry64 *reta_conf,
+                   uint16_t reta_size)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       uint16_t reta[ROC_NIX_RSS_RETA_MAX];
+       struct roc_nix *nix = &dev->nix;
+       int rc = -EINVAL, i, j, idx = 0;
+
+       if (reta_size != dev->nix.reta_sz) {
+               plt_err("Size of hash lookup table configured (%d) does not "
+                       "match the number hardware can supported (%d)",
+                       reta_size, dev->nix.reta_sz);
+               goto fail;
+       }
+
+       rc = roc_nix_rss_reta_get(nix, 0, reta);
+       if (rc)
+               goto fail;
+
+       /* Copy RETA table */
+       for (i = 0; i < (int)(dev->nix.reta_sz / RTE_RETA_GROUP_SIZE); i++) {
+               for (j = 0; j < RTE_RETA_GROUP_SIZE; j++) {
+                       if ((reta_conf[i].mask >> j) & 0x01)
+                               reta_conf[i].reta[j] = reta[idx];
+                       idx++;
+               }
+       }
+
+       return 0;
+
+fail:
+       return rc;
+}
+
+int
+cnxk_nix_rss_hash_update(struct rte_eth_dev *eth_dev,
+                        struct rte_eth_rss_conf *rss_conf)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       struct roc_nix *nix = &dev->nix;
+       uint8_t rss_hash_level;
+       uint32_t flowkey_cfg;
+       int rc = -EINVAL;
+       uint8_t alg_idx;
+
+       if (rss_conf->rss_key && rss_conf->rss_key_len != ROC_NIX_RSS_KEY_LEN) {
+               plt_err("Hash key size mismatch %d vs %d",
+                       rss_conf->rss_key_len, ROC_NIX_RSS_KEY_LEN);
+               goto fail;
+       }
+
+       if (rss_conf->rss_key)
+               roc_nix_rss_key_set(nix, rss_conf->rss_key);
+
+       rss_hash_level = ETH_RSS_LEVEL(rss_conf->rss_hf);
+       if (rss_hash_level)
+               rss_hash_level -= 1;
+       flowkey_cfg =
+               cnxk_rss_ethdev_to_nix(dev, rss_conf->rss_hf, rss_hash_level);
+
+       rc = roc_nix_rss_flowkey_set(nix, &alg_idx, flowkey_cfg,
+                                    ROC_NIX_RSS_GROUP_DEFAULT,
+                                    ROC_NIX_RSS_MCAM_IDX_DEFAULT);
+       if (rc) {
+               plt_err("Failed to set RSS hash function rc=%d", rc);
+               return rc;
+       }
+
+fail:
+       return rc;
+}
+
+int
+cnxk_nix_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
+                          struct rte_eth_rss_conf *rss_conf)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+
+       if (rss_conf->rss_key)
+               roc_nix_rss_key_get(&dev->nix, rss_conf->rss_key);
+
+       rss_conf->rss_key_len = ROC_NIX_RSS_KEY_LEN;
+       rss_conf->rss_hf = dev->ethdev_rss_hf;
+
+       return 0;
+}