#include "rvu.h"
 #include "rvu_reg.h"
 #include "rvu_struct.h"
+#include "rvu_npc_hash.h"
 
 #define DRV_NAME "octeontx2-af"
 
 enum rvu_af_dl_param_id {
        RVU_AF_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
        RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
+       RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
 };
 
+static int rvu_af_npc_exact_feature_get(struct devlink *devlink, u32 id,
+                                       struct devlink_param_gset_ctx *ctx)
+{
+       struct rvu_devlink *rvu_dl = devlink_priv(devlink);
+       struct rvu *rvu = rvu_dl->rvu;
+       bool enabled;
+
+       enabled = rvu_npc_exact_has_match_table(rvu);
+
+       snprintf(ctx->val.vstr, sizeof(ctx->val.vstr), "%s",
+                enabled ? "enabled" : "disabled");
+
+       return 0;
+}
+
+static int rvu_af_npc_exact_feature_disable(struct devlink *devlink, u32 id,
+                                           struct devlink_param_gset_ctx *ctx)
+{
+       struct rvu_devlink *rvu_dl = devlink_priv(devlink);
+       struct rvu *rvu = rvu_dl->rvu;
+
+       rvu_npc_exact_disable_feature(rvu);
+
+       return 0;
+}
+
+static int rvu_af_npc_exact_feature_validate(struct devlink *devlink, u32 id,
+                                            union devlink_param_value val,
+                                            struct netlink_ext_ack *extack)
+{
+       struct rvu_devlink *rvu_dl = devlink_priv(devlink);
+       struct rvu *rvu = rvu_dl->rvu;
+       u64 enable;
+
+       if (kstrtoull(val.vstr, 10, &enable)) {
+               NL_SET_ERR_MSG_MOD(extack,
+                                  "Only 1 value is supported");
+               return -EINVAL;
+       }
+
+       if (enable != 1) {
+               NL_SET_ERR_MSG_MOD(extack,
+                                  "Only disabling exact match feature is supported");
+               return -EINVAL;
+       }
+
+       if (rvu_npc_exact_can_disable_feature(rvu))
+               return 0;
+
+       NL_SET_ERR_MSG_MOD(extack,
+                          "Can't disable exact match feature; Please try before any configuration");
+       return -EFAULT;
+}
+
 static const struct devlink_param rvu_af_dl_params[] = {
        DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
                             "dwrr_mtu", DEVLINK_PARAM_TYPE_U32,
                             BIT(DEVLINK_PARAM_CMODE_RUNTIME),
                             rvu_af_dl_dwrr_mtu_get, rvu_af_dl_dwrr_mtu_set,
                             rvu_af_dl_dwrr_mtu_validate),
+       DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
+                            "npc_exact_feature_disable", DEVLINK_PARAM_TYPE_STRING,
+                            BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+                            rvu_af_npc_exact_feature_get,
+                            rvu_af_npc_exact_feature_disable,
+                            rvu_af_npc_exact_feature_validate),
 };
 
 /* Devlink switch mode */
 {
        struct rvu_devlink *rvu_dl;
        struct devlink *dl;
+       size_t size;
        int err;
 
        dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink),
                goto err_dl_health;
        }
 
-       err = devlink_params_register(dl, rvu_af_dl_params,
-                                     ARRAY_SIZE(rvu_af_dl_params));
+       /* Register exact match devlink only for CN10K-B */
+       size = ARRAY_SIZE(rvu_af_dl_params);
+       if (!rvu_npc_exact_has_match_table(rvu))
+               size -= 1;
+
+       err = devlink_params_register(dl, rvu_af_dl_params, size);
        if (err) {
                dev_err(rvu->dev,
                        "devlink params register failed with error %d", err);
 
        return 0;
 }
 
+/**
+ *     rvu_npc_exact_can_disable_feature - Check if feature can be disabled.
+ *      @rvu: resource virtualization unit.
+ */
+bool rvu_npc_exact_can_disable_feature(struct rvu *rvu)
+{
+       struct npc_exact_table *table = rvu->hw->table;
+       bool empty;
+
+       if (!rvu->hw->cap.npc_exact_match_enabled)
+               return false;
+
+       mutex_lock(&table->lock);
+       empty = list_empty(&table->lhead_gbl);
+       mutex_unlock(&table->lock);
+
+       return empty;
+}
+
+/**
+ *     rvu_npc_exact_disable_feature - Disable feature.
+ *      @rvu: resource virtualization unit.
+ */
+void rvu_npc_exact_disable_feature(struct rvu *rvu)
+{
+       rvu->hw->cap.npc_exact_match_enabled = false;
+}
+
 /**
  *      rvu_npc_exact_init - initialize exact match table
  *      @rvu: resource virtualization unit.