M(NPC_GET_SECRET_KEY, 0x6013, npc_get_secret_key,                     \
                                   npc_get_secret_key_req,              \
                                   npc_get_secret_key_rsp)              \
+M(NPC_GET_FIELD_STATUS, 0x6014, npc_get_field_status,                     \
+                                  npc_get_field_status_req,              \
+                                  npc_get_field_status_rsp)              \
 /* NIX mbox IDs (range 0x8000 - 0xFFFF) */                             \
 M(NIX_LF_ALLOC,                0x8000, nix_lf_alloc,                           \
                                 nix_lf_alloc_req, nix_lf_alloc_rsp)    \
        u64 clk;
 };
 
+struct npc_get_field_status_req {
+       struct mbox_msghdr hdr;
+       u8 intf;
+       u8 field;
+};
+
+struct npc_get_field_status_rsp {
+       struct mbox_msghdr hdr;
+       u8 enable;
+};
+
 struct set_vf_perm  {
        struct  mbox_msghdr hdr;
        u16     vf;
 
        if (blkaddr < 0)
                return;
 
+       /* Ucast rule should not be installed if DMAC
+        * extraction is not supported by the profile.
+        */
+       if (!npc_is_feature_supported(rvu, BIT_ULL(NPC_DMAC), pfvf->nix_rx_intf))
+               return;
+
        index = npc_get_nixlf_mcam_index(mcam, pcifunc,
                                         nixlf, NIXLF_UCAST_ENTRY);
 
        /* Get 'pcifunc' of PF device */
        pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK;
        pfvf = rvu_get_pfvf(rvu, pcifunc);
+
+       /* Bcast rule should not be installed if both DMAC
+        * and LXMB extraction is not supported by the profile.
+        */
+       if (!npc_is_feature_supported(rvu, BIT_ULL(NPC_DMAC), pfvf->nix_rx_intf) &&
+           !npc_is_feature_supported(rvu, BIT_ULL(NPC_LXMB), pfvf->nix_rx_intf))
+               return;
+
        index = npc_get_nixlf_mcam_index(mcam, pcifunc,
                                         nixlf, NIXLF_BCAST_ENTRY);
 
        vf_func = pcifunc & RVU_PFVF_FUNC_MASK;
        pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK;
        pfvf = rvu_get_pfvf(rvu, pcifunc);
+
+       /* Mcast rule should not be installed if both DMAC
+        * and LXMB extraction is not supported by the profile.
+        */
+       if (!npc_is_feature_supported(rvu, BIT_ULL(NPC_DMAC), pfvf->nix_rx_intf) &&
+           !npc_is_feature_supported(rvu, BIT_ULL(NPC_LXMB), pfvf->nix_rx_intf))
+               return;
+
        index = npc_get_nixlf_mcam_index(mcam, pcifunc,
                                         nixlf, NIXLF_ALLMULTI_ENTRY);
 
 
        [NPC_UNKNOWN]   = "unknown",
 };
 
+bool npc_is_feature_supported(struct rvu *rvu, u64 features, u8 intf)
+{
+       struct npc_mcam *mcam = &rvu->hw->mcam;
+       u64 mcam_features;
+       u64 unsupported;
+
+       mcam_features = is_npc_intf_tx(intf) ? mcam->tx_features : mcam->rx_features;
+       unsupported = (mcam_features ^ features) & ~mcam_features;
+
+       /* Return false if at least one of the input flows is not extracted */
+       return !unsupported;
+}
+
 const char *npc_get_field_name(u8 hdr)
 {
        if (hdr >= ARRAY_SIZE(npc_flow_names))
        nr_bytes = FIELD_GET(NPC_BYTESM, cfg) + 1;
        hdr = FIELD_GET(NPC_HDR_OFFSET, cfg);
        key = FIELD_GET(NPC_KEY_OFFSET, cfg);
-       start_kwi = key / 8;
-       offset = (key * 8) % 64;
 
        /* For Tx, Layer A has NIX_INST_HDR_S(64 bytes) preceding
         * ethernet header.
 
 #define NPC_SCAN_HDR(name, hlid, hlt, hstart, hlen)                           \
 do {                                                                          \
+       start_kwi = key / 8;                                                   \
+       offset = (key * 8) % 64;                                               \
        if (lid == (hlid) && lt == (hlt)) {                                    \
                if ((hstart) >= hdr &&                                         \
                    ((hstart) + (hlen)) <= (hdr + nr_bytes)) {                 \
                        bit_offset = (hdr + nr_bytes - (hstart) - (hlen)) * 8; \
                        npc_set_layer_mdata(mcam, (name), cfg, lid, lt, intf); \
+                       offset += bit_offset;                                  \
+                       start_kwi += offset / 64;                              \
+                       offset %= 64;                                          \
                        npc_set_kw_masks(mcam, (name), (hlen) * 8,             \
-                                        start_kwi, offset + bit_offset, intf);\
+                                        start_kwi, offset, intf);             \
                }                                                              \
        }                                                                      \
 } while (0)
 
        unsupported = (*mcam_features ^ features) & ~(*mcam_features);
        if (unsupported) {
-               dev_info(rvu->dev, "Unsupported flow(s):\n");
+               dev_warn(rvu->dev, "Unsupported flow(s):\n");
                for_each_set_bit(bit, (unsigned long *)&unsupported, 64)
-                       dev_info(rvu->dev, "%s ", npc_get_field_name(bit));
+                       dev_warn(rvu->dev, "%s ", npc_get_field_name(bit));
                return -EOPNOTSUPP;
        }
 
        action.match_id = req->match_id;
        action.flow_key_alg = req->flow_key_alg;
 
-       if (req->op == NIX_RX_ACTION_DEFAULT && pfvf->def_ucast_rule)
-               action = pfvf->def_ucast_rule->rx_action;
+       if (req->op == NIX_RX_ACTION_DEFAULT) {
+               if (pfvf->def_ucast_rule) {
+                       action = pfvf->def_ucast_rule->rx_action;
+               } else {
+                       /* For profiles which do not extract DMAC, the default
+                        * unicast entry is unused. Hence modify action for the
+                        * requests which use same action as default unicast
+                        * entry
+                        */
+                       *(u64 *)&action = 0;
+                       action.pf_func = target;
+                       action.op = NIX_RX_ACTIONOP_UCAST;
+               }
+       }
 
        entry->action = *(u64 *)&action;
 
        if (npc_check_field(rvu, blkaddr, NPC_DMAC, req->intf))
                goto process_flow;
 
-       if (is_pffunc_af(req->hdr.pcifunc)) {
+       if (is_pffunc_af(req->hdr.pcifunc) &&
+           req->features & BIT_ULL(NPC_DMAC)) {
                if (is_unicast_ether_addr(req->packet.dmac)) {
-                       dev_err(rvu->dev,
-                               "%s: mkex profile does not support ucast flow\n",
-                               __func__);
+                       dev_warn(rvu->dev,
+                                "%s: mkex profile does not support ucast flow\n",
+                                __func__);
                        return NPC_FLOW_NOT_SUPPORTED;
                }
 
                if (!npc_is_field_present(rvu, NPC_LXMB, req->intf)) {
-                       dev_err(rvu->dev,
-                               "%s: mkex profile does not support bcast/mcast flow",
-                               __func__);
+                       dev_warn(rvu->dev,
+                                "%s: mkex profile does not support bcast/mcast flow",
+                                __func__);
                        return NPC_FLOW_NOT_SUPPORTED;
                }
 
 
        return 0;
 }
+
+int rvu_mbox_handler_npc_get_field_status(struct rvu *rvu,
+                                         struct npc_get_field_status_req *req,
+                                         struct npc_get_field_status_rsp *rsp)
+{
+       int blkaddr;
+
+       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
+       if (blkaddr < 0)
+               return NPC_MCAM_INVALID_REQ;
+
+       if (!is_npc_interface_valid(rvu, req->intf))
+               return NPC_FLOW_INTF_INVALID;
+
+       if (npc_check_field(rvu, blkaddr, req->field, req->intf))
+               rsp->enable = 1;
+
+       return 0;
+}
 
 static int otx2_mcam_entry_init(struct otx2_nic *pfvf)
 {
        struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;
+       struct npc_get_field_status_req *freq;
+       struct npc_get_field_status_rsp *frsp;
        struct npc_mcam_alloc_entry_req *req;
        struct npc_mcam_alloc_entry_rsp *rsp;
        int vf_vlan_max_flows;
        flow_cfg->rx_vlan_offset = flow_cfg->unicast_offset +
                                        OTX2_MAX_UNICAST_FLOWS;
        pfvf->flags |= OTX2_FLAG_UCAST_FLTR_SUPPORT;
-       pfvf->flags |= OTX2_FLAG_RX_VLAN_SUPPORT;
-       pfvf->flags |= OTX2_FLAG_VF_VLAN_SUPPORT;
+
+       /* Check if NPC_DMAC field is supported
+        * by the mkex profile before setting VLAN support flag.
+        */
+       freq = otx2_mbox_alloc_msg_npc_get_field_status(&pfvf->mbox);
+       if (!freq) {
+               mutex_unlock(&pfvf->mbox.lock);
+               return -ENOMEM;
+       }
+
+       freq->field = NPC_DMAC;
+       if (otx2_sync_mbox_msg(&pfvf->mbox)) {
+               mutex_unlock(&pfvf->mbox.lock);
+               return -EINVAL;
+       }
+
+       frsp = (struct npc_get_field_status_rsp *)otx2_mbox_get_rsp
+              (&pfvf->mbox.mbox, 0, &freq->hdr);
+
+       if (frsp->enable) {
+               pfvf->flags |= OTX2_FLAG_RX_VLAN_SUPPORT;
+               pfvf->flags |= OTX2_FLAG_VF_VLAN_SUPPORT;
+       }
 
        pfvf->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC;
        mutex_unlock(&pfvf->mbox.lock);