if (flags & FUNC_QCFG_RESP_FLAGS_FW_DCBX_AGENT_ENABLED)
                        bp->fw_cap |= BNXT_FW_CAP_DCBX_AGENT;
        }
-       if (BNXT_PF(bp) && (flags & FUNC_QCFG_RESP_FLAGS_MULTI_HOST))
+       if (BNXT_PF(bp) && (flags & FUNC_QCFG_RESP_FLAGS_MULTI_HOST)) {
                bp->flags |= BNXT_FLAG_MULTI_HOST;
+               if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC)
+                       bp->fw_cap &= ~BNXT_FW_CAP_PTP_RTC;
+       }
        if (flags & FUNC_QCFG_RESP_FLAGS_RING_MONITOR_ENABLED)
                bp->fw_cap |= BNXT_FW_CAP_RING_MONITOR;
 
 
 #include <linux/net_tstamp.h>
 #include <linux/timekeeping.h>
 #include <linux/ptp_classify.h>
+#include <linux/clocksource.h>
 #include "bnxt_hsi.h"
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
                                                ptp_info);
        struct hwrm_port_mac_cfg_input *req;
        struct bnxt *bp = ptp->bp;
-       int rc;
+       int rc = 0;
 
-       rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
-       if (rc)
-               return rc;
+       if (!(ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)) {
+               int neg_adj = 0;
+               u32 diff;
+               u64 adj;
 
-       req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
-       req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
-       rc = hwrm_req_send(ptp->bp, req);
-       if (rc)
-               netdev_err(ptp->bp->dev,
-                          "ptp adjfreq failed. rc = %d\n", rc);
+               if (ppb < 0) {
+                       neg_adj = 1;
+                       ppb = -ppb;
+               }
+               adj = ptp->cmult;
+               adj *= ppb;
+               diff = div_u64(adj, 1000000000ULL);
+
+               spin_lock_bh(&ptp->ptp_lock);
+               timecounter_read(&ptp->tc);
+               ptp->cc.mult = neg_adj ? ptp->cmult - diff : ptp->cmult + diff;
+               spin_unlock_bh(&ptp->ptp_lock);
+       } else {
+               rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
+               if (rc)
+                       return rc;
+
+               req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
+               req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
+               rc = hwrm_req_send(ptp->bp, req);
+               if (rc)
+                       netdev_err(ptp->bp->dev,
+                                  "ptp adjfreq failed. rc = %d\n", rc);
+       }
        return rc;
 }
 
                memset(&ptp->cc, 0, sizeof(ptp->cc));
                ptp->cc.read = bnxt_cc_read;
                ptp->cc.mask = CYCLECOUNTER_MASK(48);
-               ptp->cc.shift = 0;
-               ptp->cc.mult = 1;
+               ptp->cc.shift = BNXT_CYCLES_SHIFT;
+               ptp->cc.mult = clocksource_khz2mult(BNXT_DEVCLK_FREQ, ptp->cc.shift);
+               ptp->cmult = ptp->cc.mult;
                ptp->next_overflow_check = jiffies + BNXT_PHC_OVERFLOW_PERIOD;
        }
        if (init_tc)
 
 #define BNXT_PTP_GRC_WIN_BASE  0x6000
 
 #define BNXT_MAX_PHC_DRIFT     31000000
+#define BNXT_CYCLES_SHIFT      23
+#define BNXT_DEVCLK_FREQ       1000000
 #define BNXT_LO_TIMER_MASK     0x0000ffffffffUL
 #define BNXT_HI_TIMER_MASK     0xffff00000000UL
 
        u64                     old_time;
        unsigned long           next_period;
        unsigned long           next_overflow_check;
-       /* 48-bit PHC overflows in 78 hours.  Check overflow every 19 hours. */
-       #define BNXT_PHC_OVERFLOW_PERIOD        (19 * 3600 * HZ)
+       u32                     cmult;
+       /* a 23b shift cyclecounter will overflow in ~36 mins.  Check overflow every 18 mins. */
+       #define BNXT_PHC_OVERFLOW_PERIOD        (18 * 60 * HZ)
 
        u16                     tx_seqid;
        u16                     tx_hdr_off;