}
 }
 
+void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable)
+{
+       struct cgx *cgx = cgxd;
+       u64 cfg;
+
+       if (!cgx)
+               return;
+
+       if (enable) {
+               /* Enable inbound PTP timestamping */
+               cfg = cgx_read(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL);
+               cfg |= CGX_GMP_GMI_RXX_FRM_CTL_PTP_MODE;
+               cgx_write(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL, cfg);
+
+               cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
+               cfg |= CGX_SMUX_RX_FRM_CTL_PTP_MODE;
+               cgx_write(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL, cfg);
+       } else {
+               /* Disable inbound PTP stamping */
+               cfg = cgx_read(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL);
+               cfg &= ~CGX_GMP_GMI_RXX_FRM_CTL_PTP_MODE;
+               cgx_write(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL, cfg);
+
+               cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
+               cfg &= ~CGX_SMUX_RX_FRM_CTL_PTP_MODE;
+               cgx_write(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL, cfg);
+       }
+}
+
 /* CGX Firmware interface low level support */
 static int cgx_fwi_cmd_send(u64 req, u64 *resp, struct lmac *lmac)
 {
 
 
 #define CGXX_SMUX_RX_FRM_CTL           0x20020
 #define CGX_SMUX_RX_FRM_CTL_CTL_BCK    BIT_ULL(3)
+#define CGX_SMUX_RX_FRM_CTL_PTP_MODE   BIT_ULL(12)
 #define CGXX_GMP_GMI_RXX_FRM_CTL       0x38028
 #define CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK        BIT_ULL(3)
+#define CGX_GMP_GMI_RXX_FRM_CTL_PTP_MODE BIT_ULL(12)
 #define CGXX_SMUX_TX_CTL               0x20178
 #define CGXX_SMUX_TX_PAUSE_PKT_TIME    0x20110
 #define CGXX_SMUX_TX_PAUSE_PKT_INTERVAL        0x20120
                           u8 *tx_pause, u8 *rx_pause);
 int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id,
                           u8 tx_pause, u8 rx_pause);
+void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable);
+
 #endif /* CGX_H */
 
 M(CGX_GET_LINKINFO,    0x209, cgx_get_linkinfo, msg_req, cgx_link_info_msg) \
 M(CGX_INTLBK_ENABLE,   0x20A, cgx_intlbk_enable, msg_req, msg_rsp)     \
 M(CGX_INTLBK_DISABLE,  0x20B, cgx_intlbk_disable, msg_req, msg_rsp)    \
+M(CGX_PTP_RX_ENABLE,   0x20C, cgx_ptp_rx_enable, msg_req, msg_rsp)     \
+M(CGX_PTP_RX_DISABLE,  0x20D, cgx_ptp_rx_disable, msg_req, msg_rsp)    \
 M(CGX_CFG_PAUSE_FRM,   0x20E, cgx_cfg_pause_frm, cgx_pause_frm_cfg,    \
                               cgx_pause_frm_cfg)                       \
 /* NPA mbox IDs (range 0x400 - 0x5FF) */                               \
                                 nix_lso_format_cfg,                    \
                                 nix_lso_format_cfg_rsp)                \
 M(NIX_RXVLAN_ALLOC,    0x8012, nix_rxvlan_alloc, msg_req, msg_rsp)     \
+M(NIX_LF_PTP_TX_ENABLE, 0x8013, nix_lf_ptp_tx_enable, msg_req, msg_rsp)        \
+M(NIX_LF_PTP_TX_DISABLE, 0x8014, nix_lf_ptp_tx_disable, msg_req, msg_rsp) \
 M(NIX_BP_ENABLE,       0x8016, nix_bp_enable, nix_bp_cfg_req,  \
                                nix_bp_cfg_rsp) \
 M(NIX_BP_DISABLE,      0x8017, nix_bp_disable, nix_bp_cfg_req, msg_rsp) \
 
 void rvu_npc_freemem(struct rvu *rvu);
 int rvu_npc_get_pkind(struct rvu *rvu, u16 pf);
 void rvu_npc_set_pkind(struct rvu *rvu, int pkind, struct rvu_pfvf *pfvf);
+int npc_config_ts_kpuaction(struct rvu *rvu, int pf, u16 pcifunc, bool en);
 void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,
                                 int nixlf, u64 chan, u8 *mac_addr);
 void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
 
        return 0;
 }
 
+static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
+{
+       int pf = rvu_get_pf(pcifunc);
+       u8 cgx_id, lmac_id;
+       void *cgxd;
+
+       /* This msg is expected only from PFs that are mapped to CGX LMACs,
+        * if received from other PF/VF simply ACK, nothing to do.
+        */
+       if ((pcifunc & RVU_PFVF_FUNC_MASK) ||
+           !is_pf_cgxmapped(rvu, pf))
+               return -ENODEV;
+
+       rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+       cgxd = rvu_cgx_pdata(cgx_id, rvu);
+
+       cgx_lmac_ptp_config(cgxd, lmac_id, enable);
+       /* If PTP is enabled then inform NPC that packets to be
+        * parsed by this PF will have their data shifted by 8 bytes
+        * and if PTP is disabled then no shift is required
+        */
+       if (npc_config_ts_kpuaction(rvu, pf, pcifunc, enable))
+               return -EINVAL;
+
+       return 0;
+}
+
+int rvu_mbox_handler_cgx_ptp_rx_enable(struct rvu *rvu, struct msg_req *req,
+                                      struct msg_rsp *rsp)
+{
+       return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, true);
+}
+
+int rvu_mbox_handler_cgx_ptp_rx_disable(struct rvu *rvu, struct msg_req *req,
+                                       struct msg_rsp *rsp)
+{
+       return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, false);
+}
+
 static int rvu_cgx_config_linkevents(struct rvu *rvu, u16 pcifunc, bool en)
 {
        int pf = rvu_get_pf(pcifunc);
 
        nix_ctx_free(rvu, pfvf);
 }
 
+#define NIX_AF_LFX_TX_CFG_PTP_EN       BIT_ULL(32)
+
+static int rvu_nix_lf_ptp_tx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
+{
+       struct rvu_hwinfo *hw = rvu->hw;
+       struct rvu_block *block;
+       int blkaddr;
+       int nixlf;
+       u64 cfg;
+
+       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
+       if (blkaddr < 0)
+               return NIX_AF_ERR_AF_LF_INVALID;
+
+       block = &hw->block[blkaddr];
+       nixlf = rvu_get_lf(rvu, block, pcifunc, 0);
+       if (nixlf < 0)
+               return NIX_AF_ERR_AF_LF_INVALID;
+
+       cfg = rvu_read64(rvu, blkaddr, NIX_AF_LFX_TX_CFG(nixlf));
+
+       if (enable)
+               cfg |= NIX_AF_LFX_TX_CFG_PTP_EN;
+       else
+               cfg &= ~NIX_AF_LFX_TX_CFG_PTP_EN;
+
+       rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_CFG(nixlf), cfg);
+
+       return 0;
+}
+
+int rvu_mbox_handler_nix_lf_ptp_tx_enable(struct rvu *rvu, struct msg_req *req,
+                                         struct msg_rsp *rsp)
+{
+       return rvu_nix_lf_ptp_tx_cfg(rvu, req->hdr.pcifunc, true);
+}
+
+int rvu_mbox_handler_nix_lf_ptp_tx_disable(struct rvu *rvu, struct msg_req *req,
+                                          struct msg_rsp *rsp)
+{
+       return rvu_nix_lf_ptp_tx_cfg(rvu, req->hdr.pcifunc, false);
+}
+
 int rvu_mbox_handler_nix_lso_format_cfg(struct rvu *rvu,
                                        struct nix_lso_format_cfg *req,
                                        struct nix_lso_format_cfg_rsp *rsp)
 
 #define NIXLF_PROMISC_ENTRY    2
 
 #define NPC_PARSE_RESULT_DMAC_OFFSET   8
+#define NPC_HW_TSTAMP_OFFSET           8
 
 static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam,
                                      int blkaddr, u16 pcifunc);
        return -1;
 }
 
+#define NPC_AF_ACTION0_PTR_ADVANCE     GENMASK_ULL(27, 20)
+
+int npc_config_ts_kpuaction(struct rvu *rvu, int pf, u16 pcifunc, bool enable)
+{
+       int pkind, blkaddr;
+       u64 val;
+
+       pkind = rvu_npc_get_pkind(rvu, pf);
+       if (pkind < 0) {
+               dev_err(rvu->dev, "%s: pkind not mapped\n", __func__);
+               return -EINVAL;
+       }
+
+       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, pcifunc);
+       if (blkaddr < 0) {
+               dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
+               return -EINVAL;
+       }
+
+       val = rvu_read64(rvu, blkaddr, NPC_AF_PKINDX_ACTION0(pkind));
+       val &= ~NPC_AF_ACTION0_PTR_ADVANCE;
+       /* If timestamp is enabled then configure NPC to shift 8 bytes */
+       if (enable)
+               val |= FIELD_PREP(NPC_AF_ACTION0_PTR_ADVANCE,
+                                 NPC_HW_TSTAMP_OFFSET);
+       rvu_write64(rvu, blkaddr, NPC_AF_PKINDX_ACTION0(pkind), val);
+
+       return 0;
+}
+
 static int npc_get_nixlf_mcam_index(struct npc_mcam *mcam,
                                    u16 pcifunc, int nixlf, int type)
 {