aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMatthew Vick <matthew.vick@intel.com>2012-08-18 03:26:33 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-09-17 05:04:24 -0400
commit1f6e8178d6851951876ad8524f4de7a0e6b111be (patch)
treee7a363f6216bc4456ae57d4cd1895bcf5f958ce8 /drivers
parent201987e3d03fadf0d87980981b7421198e3e5922 (diff)
igb: Prevent dropped Tx timestamps via work items and interrupts.
In rare circumstances, it's possible a descriptor writeback will occur before a timestamped Tx packet will go out on the wire, leading to the driver believing the hardware failed to timestamp the packet. Schedule a work item for 82576 and use the available time sync interrupt registers on 82580 and above to account for this. Cc: Richard Cochran <richardcochran@gmail.com> Signed-off-by: Matthew Vick <matthew.vick@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_defines.h5
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_regs.h2
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h8
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c61
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ptp.c102
5 files changed, 153 insertions, 25 deletions
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index ec7e4fe3e3ee..0b27e8fe06bf 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -360,6 +360,7 @@
360#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */ 360#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
361#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */ 361#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
362#define E1000_ICR_VMMB 0x00000100 /* VM MB event */ 362#define E1000_ICR_VMMB 0x00000100 /* VM MB event */
363#define E1000_ICR_TS 0x00080000 /* Time Sync Interrupt */
363#define E1000_ICR_DRSTA 0x40000000 /* Device Reset Asserted */ 364#define E1000_ICR_DRSTA 0x40000000 /* Device Reset Asserted */
364/* If this bit asserted, the driver should claim the interrupt */ 365/* If this bit asserted, the driver should claim the interrupt */
365#define E1000_ICR_INT_ASSERTED 0x80000000 366#define E1000_ICR_INT_ASSERTED 0x80000000
@@ -399,6 +400,7 @@
399#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ 400#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
400#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ 401#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
401#define E1000_IMS_VMMB E1000_ICR_VMMB /* Mail box activity */ 402#define E1000_IMS_VMMB E1000_ICR_VMMB /* Mail box activity */
403#define E1000_IMS_TS E1000_ICR_TS /* Time Sync Interrupt */
402#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ 404#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
403#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ 405#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
404#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ 406#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
@@ -510,6 +512,9 @@
510 512
511#define E1000_TIMINCA_16NS_SHIFT 24 513#define E1000_TIMINCA_16NS_SHIFT 24
512 514
515#define E1000_TSICR_TXTS 0x00000002
516#define E1000_TSIM_TXTS 0x00000002
517
513#define E1000_MDICNFG_EXT_MDIO 0x80000000 /* MDI ext/int destination */ 518#define E1000_MDICNFG_EXT_MDIO 0x80000000 /* MDI ext/int destination */
514#define E1000_MDICNFG_COM_MDIO 0x40000000 /* MDI shared w/ lan 0 */ 519#define E1000_MDICNFG_COM_MDIO 0x40000000 /* MDI shared w/ lan 0 */
515#define E1000_MDICNFG_PHY_MASK 0x03E00000 520#define E1000_MDICNFG_PHY_MASK 0x03E00000
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h
index 28394bea5253..faec840a5a8a 100644
--- a/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -91,6 +91,8 @@
91#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */ 91#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
92#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */ 92#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */
93#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */ 93#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */
94#define E1000_TSICR 0x0B66C /* Interrupt Cause Register */
95#define E1000_TSIM 0x0B674 /* Interrupt Mask Register */
94 96
95/* Filtering Registers */ 97/* Filtering Registers */
96#define E1000_SAQF(_n) (0x5980 + 4 * (_n)) 98#define E1000_SAQF(_n) (0x5980 + 4 * (_n))
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 797346998d52..43c8e2914263 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -381,6 +381,8 @@ struct igb_adapter {
381 struct ptp_clock *ptp_clock; 381 struct ptp_clock *ptp_clock;
382 struct ptp_clock_info ptp_caps; 382 struct ptp_clock_info ptp_caps;
383 struct delayed_work ptp_overflow_work; 383 struct delayed_work ptp_overflow_work;
384 struct work_struct ptp_tx_work;
385 struct sk_buff *ptp_tx_skb;
384 spinlock_t tmreg_lock; 386 spinlock_t tmreg_lock;
385 struct cyclecounter cc; 387 struct cyclecounter cc;
386 struct timecounter tc; 388 struct timecounter tc;
@@ -394,6 +396,7 @@ struct igb_adapter {
394#define IGB_FLAG_QUAD_PORT_A (1 << 2) 396#define IGB_FLAG_QUAD_PORT_A (1 << 2)
395#define IGB_FLAG_QUEUE_PAIRS (1 << 3) 397#define IGB_FLAG_QUEUE_PAIRS (1 << 3)
396#define IGB_FLAG_DMAC (1 << 4) 398#define IGB_FLAG_DMAC (1 << 4)
399#define IGB_FLAG_PTP (1 << 5)
397 400
398/* DMA Coalescing defines */ 401/* DMA Coalescing defines */
399#define IGB_MIN_TXPBSIZE 20408 402#define IGB_MIN_TXPBSIZE 20408
@@ -440,8 +443,9 @@ extern void igb_set_fw_version(struct igb_adapter *);
440#ifdef CONFIG_IGB_PTP 443#ifdef CONFIG_IGB_PTP
441extern void igb_ptp_init(struct igb_adapter *adapter); 444extern void igb_ptp_init(struct igb_adapter *adapter);
442extern void igb_ptp_stop(struct igb_adapter *adapter); 445extern void igb_ptp_stop(struct igb_adapter *adapter);
443extern void igb_ptp_tx_hwtstamp(struct igb_q_vector *q_vector, 446extern void igb_ptp_reset(struct igb_adapter *adapter);
444 struct igb_tx_buffer *buffer_info); 447extern void igb_ptp_tx_work(struct work_struct *work);
448extern void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter);
445extern void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector, 449extern void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector,
446 union e1000_adv_rx_desc *rx_desc, 450 union e1000_adv_rx_desc *rx_desc,
447 struct sk_buff *skb); 451 struct sk_buff *skb);
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 6e39f0ca9fc4..19d7666dfccb 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1751,6 +1751,11 @@ void igb_reset(struct igb_adapter *adapter)
1751 /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ 1751 /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
1752 wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE); 1752 wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
1753 1753
1754#ifdef CONFIG_IGB_PTP
1755 /* Re-enable PTP, where applicable. */
1756 igb_ptp_reset(adapter);
1757#endif /* CONFIG_IGB_PTP */
1758
1754 igb_get_phy_info(hw); 1759 igb_get_phy_info(hw);
1755} 1760}
1756 1761
@@ -4234,7 +4239,7 @@ static __le32 igb_tx_cmd_type(u32 tx_flags)
4234 4239
4235#ifdef CONFIG_IGB_PTP 4240#ifdef CONFIG_IGB_PTP
4236 /* set timestamp bit if present */ 4241 /* set timestamp bit if present */
4237 if (tx_flags & IGB_TX_FLAGS_TSTAMP) 4242 if (unlikely(tx_flags & IGB_TX_FLAGS_TSTAMP))
4238 cmd_type |= cpu_to_le32(E1000_ADVTXD_MAC_TSTAMP); 4243 cmd_type |= cpu_to_le32(E1000_ADVTXD_MAC_TSTAMP);
4239#endif /* CONFIG_IGB_PTP */ 4244#endif /* CONFIG_IGB_PTP */
4240 4245
@@ -4445,6 +4450,9 @@ static inline int igb_maybe_stop_tx(struct igb_ring *tx_ring, const u16 size)
4445netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb, 4450netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
4446 struct igb_ring *tx_ring) 4451 struct igb_ring *tx_ring)
4447{ 4452{
4453#ifdef CONFIG_IGB_PTP
4454 struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
4455#endif /* CONFIG_IGB_PTP */
4448 struct igb_tx_buffer *first; 4456 struct igb_tx_buffer *first;
4449 int tso; 4457 int tso;
4450 u32 tx_flags = 0; 4458 u32 tx_flags = 0;
@@ -4468,9 +4476,14 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
4468 first->gso_segs = 1; 4476 first->gso_segs = 1;
4469 4477
4470#ifdef CONFIG_IGB_PTP 4478#ifdef CONFIG_IGB_PTP
4471 if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { 4479 if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
4480 !(adapter->ptp_tx_skb))) {
4472 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 4481 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
4473 tx_flags |= IGB_TX_FLAGS_TSTAMP; 4482 tx_flags |= IGB_TX_FLAGS_TSTAMP;
4483
4484 adapter->ptp_tx_skb = skb_get(skb);
4485 if (adapter->hw.mac.type == e1000_82576)
4486 schedule_work(&adapter->ptp_tx_work);
4474 } 4487 }
4475#endif /* CONFIG_IGB_PTP */ 4488#endif /* CONFIG_IGB_PTP */
4476 4489
@@ -4859,6 +4872,19 @@ static irqreturn_t igb_msix_other(int irq, void *data)
4859 mod_timer(&adapter->watchdog_timer, jiffies + 1); 4872 mod_timer(&adapter->watchdog_timer, jiffies + 1);
4860 } 4873 }
4861 4874
4875#ifdef CONFIG_IGB_PTP
4876 if (icr & E1000_ICR_TS) {
4877 u32 tsicr = rd32(E1000_TSICR);
4878
4879 if (tsicr & E1000_TSICR_TXTS) {
4880 /* acknowledge the interrupt */
4881 wr32(E1000_TSICR, E1000_TSICR_TXTS);
4882 /* retrieve hardware timestamp */
4883 schedule_work(&adapter->ptp_tx_work);
4884 }
4885 }
4886#endif /* CONFIG_IGB_PTP */
4887
4862 wr32(E1000_EIMS, adapter->eims_other); 4888 wr32(E1000_EIMS, adapter->eims_other);
4863 4889
4864 return IRQ_HANDLED; 4890 return IRQ_HANDLED;
@@ -5650,6 +5676,19 @@ static irqreturn_t igb_intr_msi(int irq, void *data)
5650 mod_timer(&adapter->watchdog_timer, jiffies + 1); 5676 mod_timer(&adapter->watchdog_timer, jiffies + 1);
5651 } 5677 }
5652 5678
5679#ifdef CONFIG_IGB_PTP
5680 if (icr & E1000_ICR_TS) {
5681 u32 tsicr = rd32(E1000_TSICR);
5682
5683 if (tsicr & E1000_TSICR_TXTS) {
5684 /* acknowledge the interrupt */
5685 wr32(E1000_TSICR, E1000_TSICR_TXTS);
5686 /* retrieve hardware timestamp */
5687 schedule_work(&adapter->ptp_tx_work);
5688 }
5689 }
5690#endif /* CONFIG_IGB_PTP */
5691
5653 napi_schedule(&q_vector->napi); 5692 napi_schedule(&q_vector->napi);
5654 5693
5655 return IRQ_HANDLED; 5694 return IRQ_HANDLED;
@@ -5691,6 +5730,19 @@ static irqreturn_t igb_intr(int irq, void *data)
5691 mod_timer(&adapter->watchdog_timer, jiffies + 1); 5730 mod_timer(&adapter->watchdog_timer, jiffies + 1);
5692 } 5731 }
5693 5732
5733#ifdef CONFIG_IGB_PTP
5734 if (icr & E1000_ICR_TS) {
5735 u32 tsicr = rd32(E1000_TSICR);
5736
5737 if (tsicr & E1000_TSICR_TXTS) {
5738 /* acknowledge the interrupt */
5739 wr32(E1000_TSICR, E1000_TSICR_TXTS);
5740 /* retrieve hardware timestamp */
5741 schedule_work(&adapter->ptp_tx_work);
5742 }
5743 }
5744#endif /* CONFIG_IGB_PTP */
5745
5694 napi_schedule(&q_vector->napi); 5746 napi_schedule(&q_vector->napi);
5695 5747
5696 return IRQ_HANDLED; 5748 return IRQ_HANDLED;
@@ -5794,11 +5846,6 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
5794 total_bytes += tx_buffer->bytecount; 5846 total_bytes += tx_buffer->bytecount;
5795 total_packets += tx_buffer->gso_segs; 5847 total_packets += tx_buffer->gso_segs;
5796 5848
5797#ifdef CONFIG_IGB_PTP
5798 /* retrieve hardware timestamp */
5799 igb_ptp_tx_hwtstamp(q_vector, tx_buffer);
5800#endif /* CONFIG_IGB_PTP */
5801
5802 /* free the skb */ 5849 /* free the skb */
5803 dev_kfree_skb_any(tx_buffer->skb); 5850 dev_kfree_skb_any(tx_buffer->skb);
5804 tx_buffer->skb = NULL; 5851 tx_buffer->skb = NULL;
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index e69555f1f73e..d57060c0813d 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -289,6 +289,31 @@ static int igb_ptp_enable(struct ptp_clock_info *ptp,
289 return -EOPNOTSUPP; 289 return -EOPNOTSUPP;
290} 290}
291 291
292/**
293 * igb_ptp_tx_work
294 * @work: pointer to work struct
295 *
296 * This work function polls the TSYNCTXCTL valid bit to determine when a
297 * timestamp has been taken for the current stored skb.
298 */
299void igb_ptp_tx_work(struct work_struct *work)
300{
301 struct igb_adapter *adapter = container_of(work, struct igb_adapter,
302 ptp_tx_work);
303 struct e1000_hw *hw = &adapter->hw;
304 u32 tsynctxctl;
305
306 if (!adapter->ptp_tx_skb)
307 return;
308
309 tsynctxctl = rd32(E1000_TSYNCTXCTL);
310 if (tsynctxctl & E1000_TSYNCTXCTL_VALID)
311 igb_ptp_tx_hwtstamp(adapter);
312 else
313 /* reschedule to check later */
314 schedule_work(&adapter->ptp_tx_work);
315}
316
292static void igb_ptp_overflow_check(struct work_struct *work) 317static void igb_ptp_overflow_check(struct work_struct *work)
293{ 318{
294 struct igb_adapter *igb = 319 struct igb_adapter *igb =
@@ -305,31 +330,25 @@ static void igb_ptp_overflow_check(struct work_struct *work)
305 330
306/** 331/**
307 * igb_ptp_tx_hwtstamp - utility function which checks for TX time stamp 332 * igb_ptp_tx_hwtstamp - utility function which checks for TX time stamp
308 * @q_vector: pointer to q_vector containing needed info 333 * @adapter: Board private structure.
309 * @buffer: pointer to igb_tx_buffer structure
310 * 334 *
311 * If we were asked to do hardware stamping and such a time stamp is 335 * If we were asked to do hardware stamping and such a time stamp is
312 * available, then it must have been for this skb here because we only 336 * available, then it must have been for this skb here because we only
313 * allow only one such packet into the queue. 337 * allow only one such packet into the queue.
314 */ 338 */
315void igb_ptp_tx_hwtstamp(struct igb_q_vector *q_vector, 339void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter)
316 struct igb_tx_buffer *buffer_info)
317{ 340{
318 struct igb_adapter *adapter = q_vector->adapter;
319 struct e1000_hw *hw = &adapter->hw; 341 struct e1000_hw *hw = &adapter->hw;
320 struct skb_shared_hwtstamps shhwtstamps; 342 struct skb_shared_hwtstamps shhwtstamps;
321 u64 regval; 343 u64 regval;
322 344
323 /* if skb does not support hw timestamp or TX stamp not valid exit */
324 if (likely(!(buffer_info->tx_flags & IGB_TX_FLAGS_TSTAMP)) ||
325 !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID))
326 return;
327
328 regval = rd32(E1000_TXSTMPL); 345 regval = rd32(E1000_TXSTMPL);
329 regval |= (u64)rd32(E1000_TXSTMPH) << 32; 346 regval |= (u64)rd32(E1000_TXSTMPH) << 32;
330 347
331 igb_ptp_systim_to_hwtstamp(adapter, &shhwtstamps, regval); 348 igb_ptp_systim_to_hwtstamp(adapter, &shhwtstamps, regval);
332 skb_tstamp_tx(buffer_info->skb, &shhwtstamps); 349 skb_tstamp_tx(adapter->ptp_tx_skb, &shhwtstamps);
350 dev_kfree_skb_any(adapter->ptp_tx_skb);
351 adapter->ptp_tx_skb = NULL;
333} 352}
334 353
335void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector, 354void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector,
@@ -603,16 +622,26 @@ void igb_ptp_init(struct igb_adapter *adapter)
603 622
604 spin_lock_init(&adapter->tmreg_lock); 623 spin_lock_init(&adapter->tmreg_lock);
605 624
625 INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work);
626
606 schedule_delayed_work(&adapter->ptp_overflow_work, 627 schedule_delayed_work(&adapter->ptp_overflow_work,
607 IGB_SYSTIM_OVERFLOW_PERIOD); 628 IGB_SYSTIM_OVERFLOW_PERIOD);
608 629
630 /* Initialize the time sync interrupts for devices that support it. */
631 if (hw->mac.type >= e1000_82580) {
632 wr32(E1000_TSIM, E1000_TSIM_TXTS);
633 wr32(E1000_IMS, E1000_IMS_TS);
634 }
635
609 adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps); 636 adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps);
610 if (IS_ERR(adapter->ptp_clock)) { 637 if (IS_ERR(adapter->ptp_clock)) {
611 adapter->ptp_clock = NULL; 638 adapter->ptp_clock = NULL;
612 dev_err(&adapter->pdev->dev, "ptp_clock_register failed\n"); 639 dev_err(&adapter->pdev->dev, "ptp_clock_register failed\n");
613 } else 640 } else {
614 dev_info(&adapter->pdev->dev, "added PHC on %s\n", 641 dev_info(&adapter->pdev->dev, "added PHC on %s\n",
615 adapter->netdev->name); 642 adapter->netdev->name);
643 adapter->flags |= IGB_FLAG_PTP;
644 }
616} 645}
617 646
618/** 647/**
@@ -624,20 +653,61 @@ void igb_ptp_init(struct igb_adapter *adapter)
624void igb_ptp_stop(struct igb_adapter *adapter) 653void igb_ptp_stop(struct igb_adapter *adapter)
625{ 654{
626 switch (adapter->hw.mac.type) { 655 switch (adapter->hw.mac.type) {
627 case e1000_i211:
628 case e1000_i210:
629 case e1000_i350:
630 case e1000_82580:
631 case e1000_82576: 656 case e1000_82576:
657 case e1000_82580:
658 case e1000_i350:
632 cancel_delayed_work_sync(&adapter->ptp_overflow_work); 659 cancel_delayed_work_sync(&adapter->ptp_overflow_work);
633 break; 660 break;
661 case e1000_i210:
662 case e1000_i211:
663 /* No delayed work to cancel. */
664 break;
634 default: 665 default:
635 return; 666 return;
636 } 667 }
637 668
669 cancel_work_sync(&adapter->ptp_tx_work);
670
638 if (adapter->ptp_clock) { 671 if (adapter->ptp_clock) {
639 ptp_clock_unregister(adapter->ptp_clock); 672 ptp_clock_unregister(adapter->ptp_clock);
640 dev_info(&adapter->pdev->dev, "removed PHC on %s\n", 673 dev_info(&adapter->pdev->dev, "removed PHC on %s\n",
641 adapter->netdev->name); 674 adapter->netdev->name);
675 adapter->flags &= ~IGB_FLAG_PTP;
642 } 676 }
643} 677}
678
679/**
680 * igb_ptp_reset - Re-enable the adapter for PTP following a reset.
681 * @adapter: Board private structure.
682 *
683 * This function handles the reset work required to re-enable the PTP device.
684 **/
685void igb_ptp_reset(struct igb_adapter *adapter)
686{
687 struct e1000_hw *hw = &adapter->hw;
688
689 if (!(adapter->flags & IGB_FLAG_PTP))
690 return;
691
692 switch (adapter->hw.mac.type) {
693 case e1000_82576:
694 /* Dial the nominal frequency. */
695 wr32(E1000_TIMINCA, INCPERIOD_82576 | INCVALUE_82576);
696 break;
697 case e1000_82580:
698 case e1000_i350:
699 case e1000_i210:
700 case e1000_i211:
701 /* Enable the timer functions and interrupts. */
702 wr32(E1000_TSAUXC, 0x0);
703 wr32(E1000_TSIM, E1000_TSIM_TXTS);
704 wr32(E1000_IMS, E1000_IMS_TS);
705 break;
706 default:
707 /* No work to do. */
708 return;
709 }
710
711 timecounter_init(&adapter->tc, &adapter->cc,
712 ktime_to_ns(ktime_get_real()));
713}