/** * ixgbe_ptp_reset * @adapter: the ixgbe private board structure * * When the MAC resets, all of the hardware configuration for timesync is * reset. This function should be called to re-enable the device for PTP, * using the last known settings. However, we do lose the current clock time, * so we fallback to resetting it based on the kernel's realtime clock. * * This function will maintain the hwtstamp_config settings, and it retriggers * the SDP output if it's enabled. */ void ixgbe_ptp_reset(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; unsigned long flags; /* reset the hardware timestamping mode */ ixgbe_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config); switch (hw->mac.type) { case ixgbe_mac_X540: case ixgbe_mac_82599EB: ixgbe_ptp_start_cyclecounter(adapter); spin_lock_irqsave(&adapter->tmreg_lock, flags); timecounter_init(&adapter->hw_tc, &adapter->hw_cc, ktime_to_ns(ktime_get_real())); spin_unlock_irqrestore(&adapter->tmreg_lock, flags); adapter->last_overflow_check = jiffies; break; default: return; } /* * Now that the shift has been calculated and the systime * registers reset, (re-)enable the Clock out feature */ if (adapter->ptp_setup_sdp) adapter->ptp_setup_sdp(adapter); }
/** * ixgbe_ptp_init * @adapter - the ixgbe private adapter structure * * This function performs the required steps for enabling ptp * support. If ptp support has already been loaded it simply calls the * cyclecounter init routine and exits. */ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) { struct net_device *netdev = adapter->netdev; switch (adapter->hw.mac.type) { case ixgbe_mac_X540: snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); adapter->ptp_caps.owner = THIS_MODULE; adapter->ptp_caps.max_adj = 250000000; adapter->ptp_caps.n_alarm = 0; adapter->ptp_caps.n_ext_ts = 0; adapter->ptp_caps.n_per_out = 0; adapter->ptp_caps.pps = 1; adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq; adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; adapter->ptp_caps.gettime = ixgbe_ptp_gettime; adapter->ptp_caps.settime = ixgbe_ptp_settime; adapter->ptp_caps.enable = ixgbe_ptp_enable; break; case ixgbe_mac_82599EB: snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr); adapter->ptp_caps.owner = THIS_MODULE; adapter->ptp_caps.max_adj = 250000000; adapter->ptp_caps.n_alarm = 0; adapter->ptp_caps.n_ext_ts = 0; adapter->ptp_caps.n_per_out = 0; adapter->ptp_caps.pps = 0; adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq; adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; adapter->ptp_caps.gettime = ixgbe_ptp_gettime; adapter->ptp_caps.settime = ixgbe_ptp_settime; adapter->ptp_caps.enable = ixgbe_ptp_enable; break; default: adapter->ptp_clock = NULL; return; } spin_lock_init(&adapter->tmreg_lock); ixgbe_ptp_start_cyclecounter(adapter); /* (Re)start the overflow check */ adapter->flags2 |= IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED; adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps); if (IS_ERR(adapter->ptp_clock)) { adapter->ptp_clock = NULL; e_dev_err("ptp_clock_register failed\n"); } else e_dev_info("registered PHC device on %s\n", netdev->name); return; }