/** * igb_ptp_reset - Re-enable the adapter for PTP following a reset. * @adapter: Board private structure. * * This function handles the reset work required to re-enable the PTP device. **/ void igb_ptp_reset(struct igb_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; unsigned long flags; /* reset the tstamp_config */ igb_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config); spin_lock_irqsave(&adapter->tmreg_lock, flags); switch (adapter->hw.mac.type) { case e1000_82576: /* Dial the nominal frequency. */ wr32(E1000_TIMINCA, INCPERIOD_82576 | INCVALUE_82576); break; case e1000_82580: case e1000_i354: case e1000_i350: case e1000_i210: case e1000_i211: wr32(E1000_TSAUXC, 0x0); wr32(E1000_TSSDP, 0x0); wr32(E1000_TSIM, TSYNC_INTERRUPTS | (adapter->pps_sys_wrap_on ? TSINTR_SYS_WRAP : 0)); wr32(E1000_IMS, E1000_IMS_TS); break; default: /* No work to do. */ goto out; } /* Re-initialize the timer. */ if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) { struct timespec64 ts = ktime_to_timespec64(ktime_get_real()); igb_ptp_write_i210(adapter, &ts); } else { timecounter_init(&adapter->tc, &adapter->cc, ktime_to_ns(ktime_get_real())); } out: spin_unlock_irqrestore(&adapter->tmreg_lock, flags); wrfl(); if (adapter->ptp_flags & IGB_PTP_OVERFLOW_CHECK) schedule_delayed_work(&adapter->ptp_overflow_work, IGB_SYSTIM_OVERFLOW_PERIOD); }
static int igb_ptp_settime_i210(struct ptp_clock_info *ptp, const struct timespec *ts) { struct igb_adapter *igb = container_of(ptp, struct igb_adapter, ptp_caps); unsigned long flags; spin_lock_irqsave(&igb->tmreg_lock, flags); igb_ptp_write_i210(igb, ts); spin_unlock_irqrestore(&igb->tmreg_lock, flags); return 0; }
static int igb_ptp_adjtime_i210(struct ptp_clock_info *ptp, s64 delta) { struct igb_adapter *igb = container_of(ptp, struct igb_adapter, ptp_caps); unsigned long flags; struct timespec now, then = ns_to_timespec(delta); spin_lock_irqsave(&igb->tmreg_lock, flags); igb_ptp_read_i210(igb, &now); now = timespec_add(now, then); igb_ptp_write_i210(igb, (const struct timespec *)&now); spin_unlock_irqrestore(&igb->tmreg_lock, flags); return 0; }
/** * igb_ptp_reset - Re-enable the adapter for PTP following a reset. * @adapter: Board private structure. * * This function handles the reset work required to re-enable the PTP device. **/ void igb_ptp_reset(struct igb_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; unsigned long flags; if (!(adapter->flags & IGB_FLAG_PTP)) return; /* reset the tstamp_config */ igb_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config); spin_lock_irqsave(&adapter->tmreg_lock, flags); switch (adapter->hw.mac.type) { case e1000_82576: /* Dial the nominal frequency. */ E1000_WRITE_REG(hw, E1000_TIMINCA, INCPERIOD_82576 | INCVALUE_82576); break; case e1000_82580: case e1000_i350: case e1000_i354: case e1000_i210: case e1000_i211: E1000_WRITE_REG(hw, E1000_TSAUXC, 0x0); E1000_WRITE_REG(hw, E1000_TSSDP, 0x0); E1000_WRITE_REG(hw, E1000_TSIM, TSYNC_INTERRUPTS); E1000_WRITE_REG(hw, E1000_IMS, E1000_IMS_TS); break; default: /* No work to do. */ goto out; } /* Re-initialize the timer. */ if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) { struct timespec64 ts64 = ktime_to_timespec64(ktime_get_real()); igb_ptp_write_i210(adapter, &ts64); } else { timecounter_init(&adapter->tc, &adapter->cc, ktime_to_ns(ktime_get_real())); } out: spin_unlock_irqrestore(&adapter->tmreg_lock, flags); }