From 00242a687de63329de81b363deb96d28c87e0bcc Mon Sep 17 00:00:00 2001 From: Satha Rao Date: Wed, 23 Jun 2021 10:17:00 +0530 Subject: [PATCH] net/cnxk: support RETA and RSS hash This patch will implement RETA and RSS hash apis. Also added device argument to lock rx context. Signed-off-by: Satha Rao --- doc/guides/nics/features/cnxk.ini | 2 + doc/guides/nics/features/cnxk_vec.ini | 2 + doc/guides/nics/features/cnxk_vf.ini | 2 + drivers/net/cnxk/cnxk_ethdev.c | 4 + drivers/net/cnxk/cnxk_ethdev.h | 10 ++ drivers/net/cnxk/cnxk_ethdev_devargs.c | 4 + drivers/net/cnxk/cnxk_ethdev_ops.c | 121 +++++++++++++++++++++++++ 7 files changed, 145 insertions(+) diff --git a/doc/guides/nics/features/cnxk.ini b/doc/guides/nics/features/cnxk.ini index b1564221cc..e4f4609506 100644 --- a/doc/guides/nics/features/cnxk.ini +++ b/doc/guides/nics/features/cnxk.ini @@ -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 diff --git a/doc/guides/nics/features/cnxk_vec.ini b/doc/guides/nics/features/cnxk_vec.ini index 862a2ad0b2..3234c30583 100644 --- a/doc/guides/nics/features/cnxk_vec.ini +++ b/doc/guides/nics/features/cnxk_vec.ini @@ -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 diff --git a/doc/guides/nics/features/cnxk_vf.ini b/doc/guides/nics/features/cnxk_vf.ini index 9a492bb05e..d254d4dcb9 100644 --- a/doc/guides/nics/features/cnxk_vf.ini +++ b/doc/guides/nics/features/cnxk_vf.ini @@ -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 diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c index b2a8f3a744..abd9bf1ee4 100644 --- a/drivers/net/cnxk/cnxk_ethdev.c +++ b/drivers/net/cnxk/cnxk_ethdev.c @@ -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 diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h index fa6f16f733..cd08e3a869 100644 --- a/drivers/net/cnxk/cnxk_ethdev.h +++ b/drivers/net/cnxk/cnxk_ethdev.h @@ -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); diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c index 7fd06eb10c..c76b6281c7 100644 --- a/drivers/net/cnxk/cnxk_ethdev_devargs.c +++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c @@ -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; diff --git a/drivers/net/cnxk/cnxk_ethdev_ops.c b/drivers/net/cnxk/cnxk_ethdev_ops.c index 91de6b7079..d257763b10 100644 --- a/drivers/net/cnxk/cnxk_ethdev_ops.c +++ b/drivers/net/cnxk/cnxk_ethdev_ops.c @@ -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; +} -- 2.20.1