}
 EXPORT_SYMBOL(cgx_get_pdata);
 
+static u64 mac2u64 (u8 *mac_addr)
+{
+       u64 mac = 0;
+       int index;
+
+       for (index = ETH_ALEN - 1; index >= 0; index--)
+               mac |= ((u64)*mac_addr++) << (8 * index);
+       return mac;
+}
+
+int cgx_lmac_addr_set(u8 cgx_id, u8 lmac_id, u8 *mac_addr)
+{
+       struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+       u64 cfg;
+
+       /* copy 6bytes from macaddr */
+       /* memcpy(&cfg, mac_addr, 6); */
+
+       cfg = mac2u64 (mac_addr);
+
+       cgx_write(cgx_dev, 0, (CGXX_CMRX_RX_DMAC_CAM0 + (lmac_id * 0x8)),
+                 cfg | CGX_DMAC_CAM_ADDR_ENABLE | ((u64)lmac_id << 49));
+
+       cfg = cgx_read(cgx_dev, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
+       cfg |= CGX_DMAC_CTL0_CAM_ENABLE;
+       cgx_write(cgx_dev, lmac_id, CGXX_CMRX_RX_DMAC_CTL0, cfg);
+
+       return 0;
+}
+EXPORT_SYMBOL(cgx_lmac_addr_set);
+
+u64 cgx_lmac_addr_get(u8 cgx_id, u8 lmac_id)
+{
+       struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+       u64 cfg;
+
+       cfg = cgx_read(cgx_dev, 0, CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8);
+       return cfg & CGX_RX_DMAC_ADR_MASK;
+}
+EXPORT_SYMBOL(cgx_lmac_addr_get);
+
+void cgx_lmac_promisc_config(int cgx_id, int lmac_id, bool enable)
+{
+       struct cgx *cgx = cgx_get_pdata(cgx_id);
+       u64 cfg = 0;
+
+       if (!cgx)
+               return;
+
+       if (enable) {
+               /* Enable promiscuous mode on LMAC */
+               cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
+               cfg &= ~(CGX_DMAC_CAM_ACCEPT | CGX_DMAC_MCAST_MODE);
+               cfg |= CGX_DMAC_BCAST_MODE;
+               cgx_write(cgx, lmac_id, CGXX_CMRX_RX_DMAC_CTL0, cfg);
+
+               cfg = cgx_read(cgx, 0,
+                              (CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8));
+               cfg &= ~CGX_DMAC_CAM_ADDR_ENABLE;
+               cgx_write(cgx, 0,
+                         (CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8), cfg);
+       } else {
+               /* Disable promiscuous mode */
+               cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
+               cfg |= CGX_DMAC_CAM_ACCEPT | CGX_DMAC_MCAST_MODE;
+               cgx_write(cgx, lmac_id, CGXX_CMRX_RX_DMAC_CTL0, cfg);
+               cfg = cgx_read(cgx, 0,
+                              (CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8));
+               cfg |= CGX_DMAC_CAM_ADDR_ENABLE;
+               cgx_write(cgx, 0,
+                         (CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8), cfg);
+       }
+}
+EXPORT_SYMBOL(cgx_lmac_promisc_config);
+
 int cgx_get_rx_stats(void *cgxd, int lmac_id, int idx, u64 *rx_stat)
 {
        struct cgx *cgx = cgxd;
 
 #define CGXX_CMRX_RX_ID_MAP            0x060
 #define CGXX_CMRX_RX_STAT0             0x070
 #define CGXX_CMRX_RX_LMACS             0x128
+#define CGXX_CMRX_RX_DMAC_CTL0         0x1F8
+#define  CGX_DMAC_CTL0_CAM_ENABLE              BIT_ULL(3)
+#define  CGX_DMAC_CAM_ACCEPT                   BIT_ULL(3)
+#define  CGX_DMAC_MCAST_MODE                   BIT_ULL(1)
+#define  CGX_DMAC_BCAST_MODE                   BIT_ULL(0)
+#define CGXX_CMRX_RX_DMAC_CAM0         0x200
+#define  CGX_DMAC_CAM_ADDR_ENABLE              BIT_ULL(48)
+#define CGXX_CMRX_RX_DMAC_CAM1         0x400
+#define CGX_RX_DMAC_ADR_MASK                   GENMASK_ULL(47, 0)
 #define CGXX_CMRX_TX_STAT0             0x700
 #define CGXX_SCRATCH0_REG              0x1050
 #define CGXX_SCRATCH1_REG              0x1058
 int cgx_get_tx_stats(void *cgxd, int lmac_id, int idx, u64 *tx_stat);
 int cgx_get_rx_stats(void *cgxd, int lmac_id, int idx, u64 *rx_stat);
 int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable);
+int cgx_lmac_addr_set(u8 cgx_id, u8 lmac_id, u8 *mac_addr);
+u64 cgx_lmac_addr_get(u8 cgx_id, u8 lmac_id);
+void cgx_lmac_promisc_config(int cgx_id, int lmac_id, bool enable);
 #endif /* CGX_H */
 
 M(CGX_START_RXTX,      0x200, msg_req, msg_rsp)                        \
 M(CGX_STOP_RXTX,       0x201, msg_req, msg_rsp)                        \
 M(CGX_STATS,           0x202, msg_req, cgx_stats_rsp)                  \
+M(CGX_MAC_ADDR_SET,    0x203, cgx_mac_addr_set_or_get,                 \
+                               cgx_mac_addr_set_or_get)                \
+M(CGX_MAC_ADDR_GET,    0x204, cgx_mac_addr_set_or_get,                 \
+                               cgx_mac_addr_set_or_get)                \
+M(CGX_PROMISC_ENABLE,  0x205, msg_req, msg_rsp)                        \
+M(CGX_PROMISC_DISABLE, 0x206, msg_req, msg_rsp)                        \
 /* NPA mbox IDs (range 0x400 - 0x5FF) */                               \
 /* SSO/SSOW mbox IDs (range 0x600 - 0x7FF) */                          \
 /* TIM mbox IDs (range 0x800 - 0x9FF) */                               \
        u64 tx_stats[CGX_TX_STATS_COUNT];
 };
 
+/* Structure for requesting the operation for
+ * setting/getting mac address in the CGX interface
+ */
+struct cgx_mac_addr_set_or_get {
+       struct mbox_msghdr hdr;
+       u8 mac_addr[ETH_ALEN];
+};
 #endif /* MBOX_H */
 
                                   struct msg_rsp *rsp);
 int rvu_mbox_handler_CGX_STATS(struct rvu *rvu, struct msg_req *req,
                               struct cgx_stats_rsp *rsp);
+int rvu_mbox_handler_CGX_MAC_ADDR_SET(struct rvu *rvu,
+                                     struct cgx_mac_addr_set_or_get *req,
+                                     struct cgx_mac_addr_set_or_get *rsp);
+int rvu_mbox_handler_CGX_MAC_ADDR_GET(struct rvu *rvu,
+                                     struct cgx_mac_addr_set_or_get *req,
+                                     struct cgx_mac_addr_set_or_get *rsp);
+int rvu_mbox_handler_CGX_PROMISC_ENABLE(struct rvu *rvu, struct msg_req *req,
+                                       struct msg_rsp *rsp);
+int rvu_mbox_handler_CGX_PROMISC_DISABLE(struct rvu *rvu, struct msg_req *req,
+                                        struct msg_rsp *rsp);
 #endif /* RVU_H */
 
        }
        return 0;
 }
+
+int rvu_mbox_handler_CGX_MAC_ADDR_SET(struct rvu *rvu,
+                                     struct cgx_mac_addr_set_or_get *req,
+                                     struct cgx_mac_addr_set_or_get *rsp)
+{
+       int pf = rvu_get_pf(req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+
+       rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+
+       cgx_lmac_addr_set(cgx_id, lmac_id, req->mac_addr);
+
+       return 0;
+}
+
+int rvu_mbox_handler_CGX_MAC_ADDR_GET(struct rvu *rvu,
+                                     struct cgx_mac_addr_set_or_get *req,
+                                     struct cgx_mac_addr_set_or_get *rsp)
+{
+       int pf = rvu_get_pf(req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       int rc = 0, i;
+       u64 cfg;
+
+       rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+
+       rsp->hdr.rc = rc;
+       cfg = cgx_lmac_addr_get(cgx_id, lmac_id);
+       /* copy 48 bit mac address to req->mac_addr */
+       for (i = 0; i < ETH_ALEN; i++)
+               rsp->mac_addr[i] = cfg >> (ETH_ALEN - 1 - i) * 8;
+       return 0;
+}
+
+int rvu_mbox_handler_CGX_PROMISC_ENABLE(struct rvu *rvu, struct msg_req *req,
+                                       struct msg_rsp *rsp)
+{
+       u16 pcifunc = req->hdr.pcifunc;
+       int pf = rvu_get_pf(pcifunc);
+       u8 cgx_id, lmac_id;
+
+       /* 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 ((req->hdr.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);
+
+       cgx_lmac_promisc_config(cgx_id, lmac_id, true);
+       return 0;
+}
+
+int rvu_mbox_handler_CGX_PROMISC_DISABLE(struct rvu *rvu, struct msg_req *req,
+                                        struct msg_rsp *rsp)
+{
+       u16 pcifunc = req->hdr.pcifunc;
+       int pf = rvu_get_pf(pcifunc);
+       u8 cgx_id, lmac_id;
+
+       /* 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 ((req->hdr.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);
+
+       cgx_lmac_promisc_config(cgx_id, lmac_id, false);
+       return 0;
+}