[v4,2/2] net/cnxk: support ops to update precolor VLAN table

Message ID 20220621073511.878557-2-skori@marvell.com (mailing list archive)
State Accepted, archived
Delegated to: Jerin Jacob
Headers
Series [v4,1/2] common/cnxk: update precolor table setup for VLAN |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/github-robot: build success github build: passed
ci/iol-aarch64-unit-testing success Testing PASS
ci/iol-x86_64-unit-testing success Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS
ci/iol-abi-testing success Testing PASS

Commit Message

Sunil Kumar Kori June 21, 2022, 7:35 a.m. UTC
  From: Sunil Kumar Kori <skori@marvell.com>

Implement API to update VLAN table for pre-coloring for
incoming packet per nixlf for CN10K platform.

Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
v3..v4:
 - Remove Depends On tag from commit log.
 - Rebase on top of dpdk-next-net/main.
 - Fix clang build failures.

v2..v3:
 - Fix dscp table runtime update error.

v1..v2:
 - Aligned with latest input color spec.

 drivers/net/cnxk/cnxk_ethdev.c     |   1 +
 drivers/net/cnxk/cnxk_ethdev.h     |   3 +-
 drivers/net/cnxk/cnxk_ethdev_mtr.c | 282 ++++++++++++++++++++++++++---
 3 files changed, 259 insertions(+), 27 deletions(-)
  

Comments

Jerin Jacob Aug. 22, 2022, 12:33 p.m. UTC | #1
On Tue, Jun 21, 2022 at 1:05 PM <skori@marvell.com> wrote:
>
> From: Sunil Kumar Kori <skori@marvell.com>
>
> Implement API to update VLAN table for pre-coloring for
> incoming packet per nixlf for CN10K platform.
>
> Signed-off-by: Sunil Kumar Kori <skori@marvell.com>


Squashed 1/2 and 2/2 and Updated the git commit as follows and applied
to dpdk-next-net-eventdev/for-main. Thanks

    net/cnxk: support for ingress meter pre-color

    Added support for ingress meter pre-coloring for incoming
    packet for CN10K platform.

    Signed-off-by: Sunil Kumar Kori <skori@marvell.com>

> ---
> v3..v4:
>  - Remove Depends On tag from commit log.
>  - Rebase on top of dpdk-next-net/main.
>  - Fix clang build failures.
>
> v2..v3:
>  - Fix dscp table runtime update error.
>
> v1..v2:
>  - Aligned with latest input color spec.
>
>  drivers/net/cnxk/cnxk_ethdev.c     |   1 +
>  drivers/net/cnxk/cnxk_ethdev.h     |   3 +-
>  drivers/net/cnxk/cnxk_ethdev_mtr.c | 282 ++++++++++++++++++++++++++---
>  3 files changed, 259 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
> index 09e57361d2..55945456c1 100644
> --- a/drivers/net/cnxk/cnxk_ethdev.c
> +++ b/drivers/net/cnxk/cnxk_ethdev.c
> @@ -1679,6 +1679,7 @@ cnxk_eth_dev_init(struct rte_eth_dev *eth_dev)
>         dev->eth_dev = eth_dev;
>         dev->configured = 0;
>         dev->ptype_disable = 0;
> +       dev->proto = RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN;
>
>         TAILQ_INIT(&dev->inb.list);
>         TAILQ_INIT(&dev->outb.list);
> diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
> index e99230285c..feb24f2839 100644
> --- a/drivers/net/cnxk/cnxk_ethdev.h
> +++ b/drivers/net/cnxk/cnxk_ethdev.h
> @@ -412,7 +412,8 @@ struct cnxk_eth_dev {
>         uint64_t clk_delta;
>
>         /* Ingress policer */
> -       enum roc_nix_bpf_color precolor_tbl[ROC_NIX_BPF_PRE_COLOR_MAX];
> +       enum roc_nix_bpf_color precolor_tbl[ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP];
> +       enum rte_mtr_color_in_protocol proto;
>         struct cnxk_mtr_profiles mtr_profiles;
>         struct cnxk_mtr_policy mtr_policy;
>         struct cnxk_mtr mtr;
> diff --git a/drivers/net/cnxk/cnxk_ethdev_mtr.c b/drivers/net/cnxk/cnxk_ethdev_mtr.c
> index 02803bdf75..be2cb7d628 100644
> --- a/drivers/net/cnxk/cnxk_ethdev_mtr.c
> +++ b/drivers/net/cnxk/cnxk_ethdev_mtr.c
> @@ -48,7 +48,12 @@ static struct rte_mtr_capabilities mtr_capa = {
>                       RTE_MTR_STATS_N_PKTS_RED | RTE_MTR_STATS_N_PKTS_DROPPED |
>                       RTE_MTR_STATS_N_BYTES_GREEN |
>                       RTE_MTR_STATS_N_BYTES_YELLOW | RTE_MTR_STATS_N_BYTES_RED |
> -                     RTE_MTR_STATS_N_BYTES_DROPPED};
> +                     RTE_MTR_STATS_N_BYTES_DROPPED,
> +       .input_color_proto_mask = RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN |
> +                       RTE_MTR_COLOR_IN_PROTO_INNER_VLAN |
> +                       RTE_MTR_COLOR_IN_PROTO_OUTER_IP |
> +                       RTE_MTR_COLOR_IN_PROTO_INNER_IP,
> +       .separate_input_color_table_per_port = true};
>
>  static struct cnxk_meter_node *
>  nix_mtr_find(struct cnxk_eth_dev *dev, uint32_t meter_id)
> @@ -470,6 +475,7 @@ cnxk_nix_mtr_create(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
>         struct cnxk_mtr_profile_node *profile;
>         struct cnxk_mtr_policy_node *policy;
>         struct cnxk_mtr *fm = &dev->mtr;
> +       enum rte_color *table = NULL;
>         struct cnxk_meter_node *mtr;
>         int i;
>
> @@ -521,18 +527,40 @@ cnxk_nix_mtr_create(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
>         mtr->is_next = false;
>         mtr->level = ROC_NIX_BPF_LEVEL_IDX_INVALID;
>
> +       /* populate dscp table for input coloring */
>         if (params->dscp_table) {
> -               mtr->params.dscp_table =
> -                       plt_zmalloc(ROC_NIX_BPF_PRE_COLOR_MAX, ROC_ALIGN);
> -               if (mtr->params.dscp_table == NULL) {
> +               table = (enum rte_color *)plt_zmalloc(sizeof(enum rte_color) *
> +                       ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP, ROC_ALIGN);
> +               if (table == NULL) {
>                         plt_free(mtr);
>                         return -rte_mtr_error_set(error, ENOMEM,
>                                         RTE_MTR_ERROR_TYPE_UNSPECIFIED,
>                                         NULL, "Memory alloc failed.");
>                 }
>
> -               for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
> -                       mtr->params.dscp_table[i] = params->dscp_table[i];
> +               for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
> +                       table[i] = params->dscp_table[i];
> +
> +               mtr->params.dscp_table = table;
> +       }
> +
> +
> +       /* populate vlan table for input coloring */
> +       if (params->vlan_table) {
> +               table = (enum rte_color *)plt_zmalloc(sizeof(enum rte_color) *
> +                       ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN, ROC_ALIGN);
> +               if (table == NULL) {
> +                       plt_free(mtr->params.dscp_table);
> +                       plt_free(mtr);
> +                       return -rte_mtr_error_set(error, ENOMEM,
> +                                       RTE_MTR_ERROR_TYPE_UNSPECIFIED,
> +                                       NULL, "Memory alloc failed.");
> +               }
> +
> +               for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
> +                       table[i] = params->vlan_table[i];
> +
> +               mtr->params.vlan_table = table;
>         }
>
>         profile->ref_cnt++;
> @@ -619,7 +647,13 @@ cnxk_nix_mtr_destroy(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
>         mtr->policy->ref_cnt--;
>         mtr->profile->ref_cnt--;
>         TAILQ_REMOVE(fm, mtr, next);
> -       plt_free(mtr->params.dscp_table);
> +
> +       if (mtr->params.dscp_table)
> +               plt_free(mtr->params.dscp_table);
> +
> +       if (mtr->params.vlan_table)
> +               plt_free(mtr->params.vlan_table);
> +
>         plt_free(mtr);
>
>  exit:
> @@ -689,7 +723,7 @@ cnxk_nix_mtr_dscp_table_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
>                                enum rte_color *dscp_table,
>                                struct rte_mtr_error *error)
>  {
> -       enum roc_nix_bpf_color nix_dscp_tbl[ROC_NIX_BPF_PRE_COLOR_MAX];
> +       enum roc_nix_bpf_color nix_dscp_tbl[ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP];
>         enum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,
>                                               ROC_NIX_BPF_COLOR_YELLOW,
>                                               ROC_NIX_BPF_COLOR_RED};
> @@ -707,16 +741,30 @@ cnxk_nix_mtr_dscp_table_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
>         }
>
>         if (!dscp_table) {
> -               for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
> +               for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
>                         nix_dscp_tbl[i] = ROC_NIX_BPF_COLOR_GREEN;
>         } else {
> -               for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
> +               for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
>                         nix_dscp_tbl[i] = color_map[dscp_table[i]];
>         }
>
> -       table.count = ROC_NIX_BPF_PRE_COLOR_MAX;
> -       table.mode = ROC_NIX_BPF_PC_MODE_DSCP_OUTER;
> -       for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
> +       table.count = ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP;
> +
> +       switch (dev->proto) {
> +       case RTE_MTR_COLOR_IN_PROTO_OUTER_IP:
> +               table.mode = ROC_NIX_BPF_PC_MODE_DSCP_OUTER;
> +               break;
> +       case RTE_MTR_COLOR_IN_PROTO_INNER_IP:
> +               table.mode = ROC_NIX_BPF_PC_MODE_DSCP_INNER;
> +               break;
> +       default:
> +               rc = -rte_mtr_error_set(error, EINVAL,
> +                       RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
> +                       "Invalid input color protocol");
> +               goto exit;
> +       }
> +
> +       for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
>                 table.color[i] = nix_dscp_tbl[i];
>
>         rc = roc_nix_bpf_pre_color_tbl_setup(nix, mtr->bpf_id,
> @@ -727,13 +775,138 @@ cnxk_nix_mtr_dscp_table_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
>                 goto exit;
>         }
>
> -       for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
> +       for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
>                 dev->precolor_tbl[i] = nix_dscp_tbl[i];
>
>  exit:
>         return rc;
>  }
>
> +static int
> +cnxk_nix_mtr_vlan_table_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
> +                              enum rte_color *vlan_table,
> +                              struct rte_mtr_error *error)
> +{
> +       enum roc_nix_bpf_color nix_vlan_tbl[ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN];
> +       enum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,
> +                                             ROC_NIX_BPF_COLOR_YELLOW,
> +                                             ROC_NIX_BPF_COLOR_RED};
> +       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
> +       struct roc_nix_bpf_precolor table;
> +       struct roc_nix *nix = &dev->nix;
> +       struct cnxk_meter_node *mtr;
> +       int rc, i;
> +
> +       mtr = nix_mtr_find(dev, mtr_id);
> +       if (mtr == NULL) {
> +               return -rte_mtr_error_set(error, ENOENT,
> +                                         RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
> +                                         "Meter object not found");
> +       }
> +
> +       if (!vlan_table) {
> +               for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
> +                       nix_vlan_tbl[i] = ROC_NIX_BPF_COLOR_GREEN;
> +       } else {
> +               for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
> +                       nix_vlan_tbl[i] = color_map[vlan_table[i]];
> +       }
> +
> +       table.count = ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN;
> +
> +       switch (dev->proto) {
> +       case RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN:
> +               table.mode = ROC_NIX_BPF_PC_MODE_VLAN_OUTER;
> +               break;
> +       case RTE_MTR_COLOR_IN_PROTO_INNER_VLAN:
> +               table.mode = ROC_NIX_BPF_PC_MODE_VLAN_INNER;
> +               break;
> +       default:
> +               rc = -rte_mtr_error_set(error, EINVAL,
> +                       RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
> +                       "Invalid input color protocol");
> +               goto exit;
> +       }
> +
> +       for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
> +               table.color[i] = nix_vlan_tbl[i];
> +
> +       rc = roc_nix_bpf_pre_color_tbl_setup(nix, mtr->bpf_id,
> +                                            lvl_map[mtr->level], &table);
> +       if (rc) {
> +               rte_mtr_error_set(error, rc, RTE_MTR_ERROR_TYPE_UNSPECIFIED,
> +                                 NULL, NULL);
> +               goto exit;
> +       }
> +
> +       for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
> +               dev->precolor_tbl[i] = nix_vlan_tbl[i];
> +
> +exit:
> +       return rc;
> +}
> +
> +static int
> +cnxk_nix_mtr_in_proto_set(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
> +                         enum rte_mtr_color_in_protocol proto,
> +                         uint32_t priority, struct rte_mtr_error *error)
> +{
> +       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
> +       struct cnxk_meter_node *mtr;
> +
> +       RTE_SET_USED(priority);
> +
> +       mtr = nix_mtr_find(dev, mtr_id);
> +       if (mtr == NULL) {
> +               return -rte_mtr_error_set(error, ENOENT,
> +                                         RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
> +                                         "Meter object not found");
> +       }
> +
> +       dev->proto = proto;
> +       return 0;
> +}
> +
> +static int
> +cnxk_nix_mtr_in_proto_get(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
> +                         uint64_t *proto_mask, struct rte_mtr_error *error)
> +{
> +       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
> +       struct cnxk_meter_node *mtr;
> +
> +       mtr = nix_mtr_find(dev, mtr_id);
> +       if (mtr == NULL) {
> +               return -rte_mtr_error_set(error, ENOENT,
> +                                         RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
> +                                         "Meter object not found");
> +       }
> +
> +       *proto_mask = dev->proto;
> +       return 0;
> +}
> +
> +static int
> +cnxk_nix_mtr_in_proto_prio_get(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
> +                              enum rte_mtr_color_in_protocol proto,
> +                              uint32_t *priority, struct rte_mtr_error *error)
> +{
> +       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
> +       struct cnxk_meter_node *mtr;
> +
> +       RTE_SET_USED(proto);
> +
> +       mtr = nix_mtr_find(dev, mtr_id);
> +       if (mtr == NULL) {
> +               return -rte_mtr_error_set(error, ENOENT,
> +                                         RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
> +                                         "Meter object not found");
> +       }
> +
> +       plt_info("Only single priority supported i.e. 0");
> +       *priority = 0;
> +       return 0;
> +}
> +
>  static int
>  cnxk_nix_mtr_stats_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
>                           uint64_t stats_mask, struct rte_mtr_error *error)
> @@ -870,6 +1043,10 @@ const struct rte_mtr_ops nix_mtr_ops = {
>         .meter_enable = cnxk_nix_mtr_enable,
>         .meter_disable = cnxk_nix_mtr_disable,
>         .meter_dscp_table_update = cnxk_nix_mtr_dscp_table_update,
> +       .meter_vlan_table_update = cnxk_nix_mtr_vlan_table_update,
> +       .in_proto_set = cnxk_nix_mtr_in_proto_set,
> +       .in_proto_get = cnxk_nix_mtr_in_proto_get,
> +       .in_proto_prio_get = cnxk_nix_mtr_in_proto_prio_get,
>         .stats_update = cnxk_nix_mtr_stats_update,
>         .stats_read = cnxk_nix_mtr_stats_read,
>  };
> @@ -1041,6 +1218,9 @@ nix_mtr_level_update(struct rte_eth_dev *eth_dev, uint32_t id, uint32_t level)
>  static void
>  nix_mtr_config_map(struct cnxk_meter_node *mtr, struct roc_nix_bpf_cfg *cfg)
>  {
> +       enum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,
> +                                             ROC_NIX_BPF_COLOR_YELLOW,
> +                                             ROC_NIX_BPF_COLOR_RED};
>         enum roc_nix_bpf_algo alg_map[] = {
>                 ROC_NIX_BPF_ALGO_NONE, ROC_NIX_BPF_ALGO_2697,
>                 ROC_NIX_BPF_ALGO_2698, ROC_NIX_BPF_ALGO_4115};
> @@ -1049,6 +1229,28 @@ nix_mtr_config_map(struct cnxk_meter_node *mtr, struct roc_nix_bpf_cfg *cfg)
>
>         cfg->alg = alg_map[profile->profile.alg];
>         cfg->lmode = profile->profile.packet_mode;
> +       cfg->icolor = color_map[mtr->params.default_input_color];
> +
> +       switch (RTE_MTR_COLOR_IN_PROTO_OUTER_IP) {
> +       case RTE_MTR_COLOR_IN_PROTO_OUTER_IP:
> +               cfg->pc_mode = ROC_NIX_BPF_PC_MODE_DSCP_OUTER;
> +               cfg->tnl_ena = false;
> +               break;
> +       case RTE_MTR_COLOR_IN_PROTO_INNER_IP:
> +               cfg->pc_mode = ROC_NIX_BPF_PC_MODE_DSCP_INNER;
> +               cfg->tnl_ena = true;
> +               break;
> +       case RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN:
> +               cfg->pc_mode = ROC_NIX_BPF_PC_MODE_VLAN_OUTER;
> +               cfg->tnl_ena = false;
> +               break;
> +       case RTE_MTR_COLOR_IN_PROTO_INNER_VLAN:
> +               cfg->pc_mode = ROC_NIX_BPF_PC_MODE_VLAN_INNER;
> +               cfg->tnl_ena = true;
> +               break;
> +       default:
> +               break;
> +       }
>
>         switch (cfg->alg) {
>         case ROC_NIX_BPF_ALGO_2697:
> @@ -1090,23 +1292,50 @@ nix_mtr_config_map(struct cnxk_meter_node *mtr, struct roc_nix_bpf_cfg *cfg)
>  }
>
>  static void
> -nix_dscp_table_map(struct cnxk_meter_node *mtr,
> -                  struct roc_nix_bpf_precolor *tbl)
> +nix_precolor_table_map(struct cnxk_meter_node *mtr,
> +                      struct roc_nix_bpf_precolor *tbl,
> +                      enum rte_mtr_color_in_protocol proto)
>  {
>         enum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,
>                                               ROC_NIX_BPF_COLOR_YELLOW,
>                                               ROC_NIX_BPF_COLOR_RED};
>         int i;
>
> -       tbl->count = ROC_NIX_BPF_PRE_COLOR_MAX;
> -       tbl->mode = ROC_NIX_BPF_PC_MODE_DSCP_OUTER;
> -
> -       for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
> -               tbl->color[i] = ROC_NIX_BPF_COLOR_GREEN;
> -
> -       if (mtr->params.dscp_table) {
> -               for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
> -                       tbl->color[i] = color_map[mtr->params.dscp_table[i]];
> +       switch (proto) {
> +       case RTE_MTR_COLOR_IN_PROTO_OUTER_IP:
> +       case RTE_MTR_COLOR_IN_PROTO_INNER_IP:
> +               tbl->count = ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP;
> +               tbl->mode = (proto == RTE_MTR_COLOR_IN_PROTO_OUTER_IP) ?
> +                                   ROC_NIX_BPF_PC_MODE_DSCP_OUTER :
> +                                   ROC_NIX_BPF_PC_MODE_DSCP_INNER;
> +
> +               for (i = 0; i < tbl->count; i++)
> +                       tbl->color[i] = ROC_NIX_BPF_COLOR_GREEN;
> +
> +               if (mtr->params.dscp_table) {
> +                       for (i = 0; i < tbl->count; i++)
> +                               tbl->color[i] =
> +                                       color_map[mtr->params.dscp_table[i]];
> +               }
> +               break;
> +       case RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN:
> +       case RTE_MTR_COLOR_IN_PROTO_INNER_VLAN:
> +               tbl->count = ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN;
> +               tbl->mode = (proto == RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN) ?
> +                                   ROC_NIX_BPF_PC_MODE_VLAN_OUTER :
> +                                   ROC_NIX_BPF_PC_MODE_VLAN_INNER;
> +
> +               for (i = 0; i < tbl->count; i++)
> +                       tbl->color[i] = ROC_NIX_BPF_COLOR_GREEN;
> +
> +               if (mtr->params.vlan_table) {
> +                       for (i = 0; i < tbl->count; i++)
> +                               tbl->color[i] =
> +                                       color_map[mtr->params.vlan_table[i]];
> +               }
> +               break;
> +       default:
> +               break;
>         }
>  }
>
> @@ -1245,7 +1474,8 @@ nix_mtr_configure(struct rte_eth_dev *eth_dev, uint32_t id)
>
>                                 memset(&tbl, 0,
>                                        sizeof(struct roc_nix_bpf_precolor));
> -                               nix_dscp_table_map(mtr[i], &tbl);
> +                               nix_precolor_table_map(mtr[i], &tbl,
> +                                                      dev->proto);
>                                 rc = roc_nix_bpf_pre_color_tbl_setup(nix,
>                                         mtr[i]->bpf_id, lvl_map[mtr[i]->level],
>                                         &tbl);
> --
> 2.25.1
>
  

Patch

diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 09e57361d2..55945456c1 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -1679,6 +1679,7 @@  cnxk_eth_dev_init(struct rte_eth_dev *eth_dev)
 	dev->eth_dev = eth_dev;
 	dev->configured = 0;
 	dev->ptype_disable = 0;
+	dev->proto = RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN;
 
 	TAILQ_INIT(&dev->inb.list);
 	TAILQ_INIT(&dev->outb.list);
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index e99230285c..feb24f2839 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -412,7 +412,8 @@  struct cnxk_eth_dev {
 	uint64_t clk_delta;
 
 	/* Ingress policer */
-	enum roc_nix_bpf_color precolor_tbl[ROC_NIX_BPF_PRE_COLOR_MAX];
+	enum roc_nix_bpf_color precolor_tbl[ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP];
+	enum rte_mtr_color_in_protocol proto;
 	struct cnxk_mtr_profiles mtr_profiles;
 	struct cnxk_mtr_policy mtr_policy;
 	struct cnxk_mtr mtr;
diff --git a/drivers/net/cnxk/cnxk_ethdev_mtr.c b/drivers/net/cnxk/cnxk_ethdev_mtr.c
index 02803bdf75..be2cb7d628 100644
--- a/drivers/net/cnxk/cnxk_ethdev_mtr.c
+++ b/drivers/net/cnxk/cnxk_ethdev_mtr.c
@@ -48,7 +48,12 @@  static struct rte_mtr_capabilities mtr_capa = {
 		      RTE_MTR_STATS_N_PKTS_RED | RTE_MTR_STATS_N_PKTS_DROPPED |
 		      RTE_MTR_STATS_N_BYTES_GREEN |
 		      RTE_MTR_STATS_N_BYTES_YELLOW | RTE_MTR_STATS_N_BYTES_RED |
-		      RTE_MTR_STATS_N_BYTES_DROPPED};
+		      RTE_MTR_STATS_N_BYTES_DROPPED,
+	.input_color_proto_mask = RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN |
+			RTE_MTR_COLOR_IN_PROTO_INNER_VLAN |
+			RTE_MTR_COLOR_IN_PROTO_OUTER_IP |
+			RTE_MTR_COLOR_IN_PROTO_INNER_IP,
+	.separate_input_color_table_per_port = true};
 
 static struct cnxk_meter_node *
 nix_mtr_find(struct cnxk_eth_dev *dev, uint32_t meter_id)
@@ -470,6 +475,7 @@  cnxk_nix_mtr_create(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
 	struct cnxk_mtr_profile_node *profile;
 	struct cnxk_mtr_policy_node *policy;
 	struct cnxk_mtr *fm = &dev->mtr;
+	enum rte_color *table = NULL;
 	struct cnxk_meter_node *mtr;
 	int i;
 
@@ -521,18 +527,40 @@  cnxk_nix_mtr_create(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
 	mtr->is_next = false;
 	mtr->level = ROC_NIX_BPF_LEVEL_IDX_INVALID;
 
+	/* populate dscp table for input coloring */
 	if (params->dscp_table) {
-		mtr->params.dscp_table =
-			plt_zmalloc(ROC_NIX_BPF_PRE_COLOR_MAX, ROC_ALIGN);
-		if (mtr->params.dscp_table == NULL) {
+		table = (enum rte_color *)plt_zmalloc(sizeof(enum rte_color) *
+			ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP, ROC_ALIGN);
+		if (table == NULL) {
 			plt_free(mtr);
 			return -rte_mtr_error_set(error, ENOMEM,
 					RTE_MTR_ERROR_TYPE_UNSPECIFIED,
 					NULL, "Memory alloc failed.");
 		}
 
-		for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
-			mtr->params.dscp_table[i] = params->dscp_table[i];
+		for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
+			table[i] = params->dscp_table[i];
+
+		mtr->params.dscp_table = table;
+	}
+
+
+	/* populate vlan table for input coloring */
+	if (params->vlan_table) {
+		table = (enum rte_color *)plt_zmalloc(sizeof(enum rte_color) *
+			ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN, ROC_ALIGN);
+		if (table == NULL) {
+			plt_free(mtr->params.dscp_table);
+			plt_free(mtr);
+			return -rte_mtr_error_set(error, ENOMEM,
+					RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+					NULL, "Memory alloc failed.");
+		}
+
+		for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
+			table[i] = params->vlan_table[i];
+
+		mtr->params.vlan_table = table;
 	}
 
 	profile->ref_cnt++;
@@ -619,7 +647,13 @@  cnxk_nix_mtr_destroy(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
 	mtr->policy->ref_cnt--;
 	mtr->profile->ref_cnt--;
 	TAILQ_REMOVE(fm, mtr, next);
-	plt_free(mtr->params.dscp_table);
+
+	if (mtr->params.dscp_table)
+		plt_free(mtr->params.dscp_table);
+
+	if (mtr->params.vlan_table)
+		plt_free(mtr->params.vlan_table);
+
 	plt_free(mtr);
 
 exit:
@@ -689,7 +723,7 @@  cnxk_nix_mtr_dscp_table_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
 			       enum rte_color *dscp_table,
 			       struct rte_mtr_error *error)
 {
-	enum roc_nix_bpf_color nix_dscp_tbl[ROC_NIX_BPF_PRE_COLOR_MAX];
+	enum roc_nix_bpf_color nix_dscp_tbl[ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP];
 	enum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,
 					      ROC_NIX_BPF_COLOR_YELLOW,
 					      ROC_NIX_BPF_COLOR_RED};
@@ -707,16 +741,30 @@  cnxk_nix_mtr_dscp_table_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
 	}
 
 	if (!dscp_table) {
-		for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
+		for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
 			nix_dscp_tbl[i] = ROC_NIX_BPF_COLOR_GREEN;
 	} else {
-		for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
+		for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
 			nix_dscp_tbl[i] = color_map[dscp_table[i]];
 	}
 
-	table.count = ROC_NIX_BPF_PRE_COLOR_MAX;
-	table.mode = ROC_NIX_BPF_PC_MODE_DSCP_OUTER;
-	for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
+	table.count = ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP;
+
+	switch (dev->proto) {
+	case RTE_MTR_COLOR_IN_PROTO_OUTER_IP:
+		table.mode = ROC_NIX_BPF_PC_MODE_DSCP_OUTER;
+		break;
+	case RTE_MTR_COLOR_IN_PROTO_INNER_IP:
+		table.mode = ROC_NIX_BPF_PC_MODE_DSCP_INNER;
+		break;
+	default:
+		rc = -rte_mtr_error_set(error, EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
+			"Invalid input color protocol");
+		goto exit;
+	}
+
+	for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
 		table.color[i] = nix_dscp_tbl[i];
 
 	rc = roc_nix_bpf_pre_color_tbl_setup(nix, mtr->bpf_id,
@@ -727,13 +775,138 @@  cnxk_nix_mtr_dscp_table_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
 		goto exit;
 	}
 
-	for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
+	for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP; i++)
 		dev->precolor_tbl[i] = nix_dscp_tbl[i];
 
 exit:
 	return rc;
 }
 
+static int
+cnxk_nix_mtr_vlan_table_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
+			       enum rte_color *vlan_table,
+			       struct rte_mtr_error *error)
+{
+	enum roc_nix_bpf_color nix_vlan_tbl[ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN];
+	enum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,
+					      ROC_NIX_BPF_COLOR_YELLOW,
+					      ROC_NIX_BPF_COLOR_RED};
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct roc_nix_bpf_precolor table;
+	struct roc_nix *nix = &dev->nix;
+	struct cnxk_meter_node *mtr;
+	int rc, i;
+
+	mtr = nix_mtr_find(dev, mtr_id);
+	if (mtr == NULL) {
+		return -rte_mtr_error_set(error, ENOENT,
+					  RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
+					  "Meter object not found");
+	}
+
+	if (!vlan_table) {
+		for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
+			nix_vlan_tbl[i] = ROC_NIX_BPF_COLOR_GREEN;
+	} else {
+		for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
+			nix_vlan_tbl[i] = color_map[vlan_table[i]];
+	}
+
+	table.count = ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN;
+
+	switch (dev->proto) {
+	case RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN:
+		table.mode = ROC_NIX_BPF_PC_MODE_VLAN_OUTER;
+		break;
+	case RTE_MTR_COLOR_IN_PROTO_INNER_VLAN:
+		table.mode = ROC_NIX_BPF_PC_MODE_VLAN_INNER;
+		break;
+	default:
+		rc = -rte_mtr_error_set(error, EINVAL,
+			RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
+			"Invalid input color protocol");
+		goto exit;
+	}
+
+	for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
+		table.color[i] = nix_vlan_tbl[i];
+
+	rc = roc_nix_bpf_pre_color_tbl_setup(nix, mtr->bpf_id,
+					     lvl_map[mtr->level], &table);
+	if (rc) {
+		rte_mtr_error_set(error, rc, RTE_MTR_ERROR_TYPE_UNSPECIFIED,
+				  NULL, NULL);
+		goto exit;
+	}
+
+	for (i = 0; i < ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN; i++)
+		dev->precolor_tbl[i] = nix_vlan_tbl[i];
+
+exit:
+	return rc;
+}
+
+static int
+cnxk_nix_mtr_in_proto_set(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
+			  enum rte_mtr_color_in_protocol proto,
+			  uint32_t priority, struct rte_mtr_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct cnxk_meter_node *mtr;
+
+	RTE_SET_USED(priority);
+
+	mtr = nix_mtr_find(dev, mtr_id);
+	if (mtr == NULL) {
+		return -rte_mtr_error_set(error, ENOENT,
+					  RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
+					  "Meter object not found");
+	}
+
+	dev->proto = proto;
+	return 0;
+}
+
+static int
+cnxk_nix_mtr_in_proto_get(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
+			  uint64_t *proto_mask, struct rte_mtr_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct cnxk_meter_node *mtr;
+
+	mtr = nix_mtr_find(dev, mtr_id);
+	if (mtr == NULL) {
+		return -rte_mtr_error_set(error, ENOENT,
+					  RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
+					  "Meter object not found");
+	}
+
+	*proto_mask = dev->proto;
+	return 0;
+}
+
+static int
+cnxk_nix_mtr_in_proto_prio_get(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
+			       enum rte_mtr_color_in_protocol proto,
+			       uint32_t *priority, struct rte_mtr_error *error)
+{
+	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+	struct cnxk_meter_node *mtr;
+
+	RTE_SET_USED(proto);
+
+	mtr = nix_mtr_find(dev, mtr_id);
+	if (mtr == NULL) {
+		return -rte_mtr_error_set(error, ENOENT,
+					  RTE_MTR_ERROR_TYPE_MTR_ID, NULL,
+					  "Meter object not found");
+	}
+
+	plt_info("Only single priority supported i.e. 0");
+	*priority = 0;
+	return 0;
+}
+
 static int
 cnxk_nix_mtr_stats_update(struct rte_eth_dev *eth_dev, uint32_t mtr_id,
 			  uint64_t stats_mask, struct rte_mtr_error *error)
@@ -870,6 +1043,10 @@  const struct rte_mtr_ops nix_mtr_ops = {
 	.meter_enable = cnxk_nix_mtr_enable,
 	.meter_disable = cnxk_nix_mtr_disable,
 	.meter_dscp_table_update = cnxk_nix_mtr_dscp_table_update,
+	.meter_vlan_table_update = cnxk_nix_mtr_vlan_table_update,
+	.in_proto_set = cnxk_nix_mtr_in_proto_set,
+	.in_proto_get = cnxk_nix_mtr_in_proto_get,
+	.in_proto_prio_get = cnxk_nix_mtr_in_proto_prio_get,
 	.stats_update = cnxk_nix_mtr_stats_update,
 	.stats_read = cnxk_nix_mtr_stats_read,
 };
@@ -1041,6 +1218,9 @@  nix_mtr_level_update(struct rte_eth_dev *eth_dev, uint32_t id, uint32_t level)
 static void
 nix_mtr_config_map(struct cnxk_meter_node *mtr, struct roc_nix_bpf_cfg *cfg)
 {
+	enum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,
+					      ROC_NIX_BPF_COLOR_YELLOW,
+					      ROC_NIX_BPF_COLOR_RED};
 	enum roc_nix_bpf_algo alg_map[] = {
 		ROC_NIX_BPF_ALGO_NONE, ROC_NIX_BPF_ALGO_2697,
 		ROC_NIX_BPF_ALGO_2698, ROC_NIX_BPF_ALGO_4115};
@@ -1049,6 +1229,28 @@  nix_mtr_config_map(struct cnxk_meter_node *mtr, struct roc_nix_bpf_cfg *cfg)
 
 	cfg->alg = alg_map[profile->profile.alg];
 	cfg->lmode = profile->profile.packet_mode;
+	cfg->icolor = color_map[mtr->params.default_input_color];
+
+	switch (RTE_MTR_COLOR_IN_PROTO_OUTER_IP) {
+	case RTE_MTR_COLOR_IN_PROTO_OUTER_IP:
+		cfg->pc_mode = ROC_NIX_BPF_PC_MODE_DSCP_OUTER;
+		cfg->tnl_ena = false;
+		break;
+	case RTE_MTR_COLOR_IN_PROTO_INNER_IP:
+		cfg->pc_mode = ROC_NIX_BPF_PC_MODE_DSCP_INNER;
+		cfg->tnl_ena = true;
+		break;
+	case RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN:
+		cfg->pc_mode = ROC_NIX_BPF_PC_MODE_VLAN_OUTER;
+		cfg->tnl_ena = false;
+		break;
+	case RTE_MTR_COLOR_IN_PROTO_INNER_VLAN:
+		cfg->pc_mode = ROC_NIX_BPF_PC_MODE_VLAN_INNER;
+		cfg->tnl_ena = true;
+		break;
+	default:
+		break;
+	}
 
 	switch (cfg->alg) {
 	case ROC_NIX_BPF_ALGO_2697:
@@ -1090,23 +1292,50 @@  nix_mtr_config_map(struct cnxk_meter_node *mtr, struct roc_nix_bpf_cfg *cfg)
 }
 
 static void
-nix_dscp_table_map(struct cnxk_meter_node *mtr,
-		   struct roc_nix_bpf_precolor *tbl)
+nix_precolor_table_map(struct cnxk_meter_node *mtr,
+		       struct roc_nix_bpf_precolor *tbl,
+		       enum rte_mtr_color_in_protocol proto)
 {
 	enum roc_nix_bpf_color color_map[] = {ROC_NIX_BPF_COLOR_GREEN,
 					      ROC_NIX_BPF_COLOR_YELLOW,
 					      ROC_NIX_BPF_COLOR_RED};
 	int i;
 
-	tbl->count = ROC_NIX_BPF_PRE_COLOR_MAX;
-	tbl->mode = ROC_NIX_BPF_PC_MODE_DSCP_OUTER;
-
-	for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
-		tbl->color[i] = ROC_NIX_BPF_COLOR_GREEN;
-
-	if (mtr->params.dscp_table) {
-		for (i = 0; i < ROC_NIX_BPF_PRE_COLOR_MAX; i++)
-			tbl->color[i] = color_map[mtr->params.dscp_table[i]];
+	switch (proto) {
+	case RTE_MTR_COLOR_IN_PROTO_OUTER_IP:
+	case RTE_MTR_COLOR_IN_PROTO_INNER_IP:
+		tbl->count = ROC_NIX_BPF_PRECOLOR_TBL_SIZE_DSCP;
+		tbl->mode = (proto == RTE_MTR_COLOR_IN_PROTO_OUTER_IP) ?
+				    ROC_NIX_BPF_PC_MODE_DSCP_OUTER :
+				    ROC_NIX_BPF_PC_MODE_DSCP_INNER;
+
+		for (i = 0; i < tbl->count; i++)
+			tbl->color[i] = ROC_NIX_BPF_COLOR_GREEN;
+
+		if (mtr->params.dscp_table) {
+			for (i = 0; i < tbl->count; i++)
+				tbl->color[i] =
+					color_map[mtr->params.dscp_table[i]];
+		}
+		break;
+	case RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN:
+	case RTE_MTR_COLOR_IN_PROTO_INNER_VLAN:
+		tbl->count = ROC_NIX_BPF_PRECOLOR_TBL_SIZE_VLAN;
+		tbl->mode = (proto == RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN) ?
+				    ROC_NIX_BPF_PC_MODE_VLAN_OUTER :
+				    ROC_NIX_BPF_PC_MODE_VLAN_INNER;
+
+		for (i = 0; i < tbl->count; i++)
+			tbl->color[i] = ROC_NIX_BPF_COLOR_GREEN;
+
+		if (mtr->params.vlan_table) {
+			for (i = 0; i < tbl->count; i++)
+				tbl->color[i] =
+					color_map[mtr->params.vlan_table[i]];
+		}
+		break;
+	default:
+		break;
 	}
 }
 
@@ -1245,7 +1474,8 @@  nix_mtr_configure(struct rte_eth_dev *eth_dev, uint32_t id)
 
 				memset(&tbl, 0,
 				       sizeof(struct roc_nix_bpf_precolor));
-				nix_dscp_table_map(mtr[i], &tbl);
+				nix_precolor_table_map(mtr[i], &tbl,
+						       dev->proto);
 				rc = roc_nix_bpf_pre_color_tbl_setup(nix,
 					mtr[i]->bpf_id, lvl_map[mtr[i]->level],
 					&tbl);