diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2009-10-27 19:46:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-28 06:25:33 -0400 |
commit | c5b9bd5e4f7caea10d113f610b85cc2093cc3179 (patch) | |
tree | 034d59e0788e5fd548b411be50aba0fd7228b049 /drivers/net/igb/igb_main.c | |
parent | 4fc82adfb01bdee79ec21e44557dc409ef31419a (diff) |
igb: cleanup some of the code related to hw timestamping
The code for the hw timestamping is a bit bulky and making some of the
functions difficult to read. In order to clean things up a bit I am moving
the timestamping operations into seperate functions.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/igb/igb_main.c')
-rw-r--r-- | drivers/net/igb/igb_main.c | 397 |
1 files changed, 182 insertions, 215 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 5724ac8c1ca9..7e628bad17d5 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -220,38 +220,6 @@ MODULE_LICENSE("GPL"); | |||
220 | MODULE_VERSION(DRV_VERSION); | 220 | MODULE_VERSION(DRV_VERSION); |
221 | 221 | ||
222 | /** | 222 | /** |
223 | * Scale the NIC clock cycle by a large factor so that | ||
224 | * relatively small clock corrections can be added or | ||
225 | * substracted at each clock tick. The drawbacks of a | ||
226 | * large factor are a) that the clock register overflows | ||
227 | * more quickly (not such a big deal) and b) that the | ||
228 | * increment per tick has to fit into 24 bits. | ||
229 | * | ||
230 | * Note that | ||
231 | * TIMINCA = IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS * | ||
232 | * IGB_TSYNC_SCALE | ||
233 | * TIMINCA += TIMINCA * adjustment [ppm] / 1e9 | ||
234 | * | ||
235 | * The base scale factor is intentionally a power of two | ||
236 | * so that the division in %struct timecounter can be done with | ||
237 | * a shift. | ||
238 | */ | ||
239 | #define IGB_TSYNC_SHIFT (19) | ||
240 | #define IGB_TSYNC_SCALE (1<<IGB_TSYNC_SHIFT) | ||
241 | |||
242 | /** | ||
243 | * The duration of one clock cycle of the NIC. | ||
244 | * | ||
245 | * @todo This hard-coded value is part of the specification and might change | ||
246 | * in future hardware revisions. Add revision check. | ||
247 | */ | ||
248 | #define IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS 16 | ||
249 | |||
250 | #if (IGB_TSYNC_SCALE * IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS) >= (1<<24) | ||
251 | # error IGB_TSYNC_SCALE and/or IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS are too large to fit into TIMINCA | ||
252 | #endif | ||
253 | |||
254 | /** | ||
255 | * igb_read_clock - read raw cycle counter (to be used by time counter) | 223 | * igb_read_clock - read raw cycle counter (to be used by time counter) |
256 | */ | 224 | */ |
257 | static cycle_t igb_read_clock(const struct cyclecounter *tc) | 225 | static cycle_t igb_read_clock(const struct cyclecounter *tc) |
@@ -259,11 +227,11 @@ static cycle_t igb_read_clock(const struct cyclecounter *tc) | |||
259 | struct igb_adapter *adapter = | 227 | struct igb_adapter *adapter = |
260 | container_of(tc, struct igb_adapter, cycles); | 228 | container_of(tc, struct igb_adapter, cycles); |
261 | struct e1000_hw *hw = &adapter->hw; | 229 | struct e1000_hw *hw = &adapter->hw; |
262 | u64 stamp; | 230 | u64 stamp = 0; |
263 | 231 | int shift = 0; | |
264 | stamp = rd32(E1000_SYSTIML); | ||
265 | stamp |= (u64)rd32(E1000_SYSTIMH) << 32ULL; | ||
266 | 232 | ||
233 | stamp |= (u64)rd32(E1000_SYSTIML) << shift; | ||
234 | stamp |= (u64)rd32(E1000_SYSTIMH) << (shift + 32); | ||
267 | return stamp; | 235 | return stamp; |
268 | } | 236 | } |
269 | 237 | ||
@@ -1669,59 +1637,58 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
1669 | dev_info(&pdev->dev, "DCA enabled\n"); | 1637 | dev_info(&pdev->dev, "DCA enabled\n"); |
1670 | igb_setup_dca(adapter); | 1638 | igb_setup_dca(adapter); |
1671 | } | 1639 | } |
1672 | #endif | ||
1673 | 1640 | ||
1674 | /* | ||
1675 | * Initialize hardware timer: we keep it running just in case | ||
1676 | * that some program needs it later on. | ||
1677 | */ | ||
1678 | memset(&adapter->cycles, 0, sizeof(adapter->cycles)); | ||
1679 | adapter->cycles.read = igb_read_clock; | ||
1680 | adapter->cycles.mask = CLOCKSOURCE_MASK(64); | ||
1681 | adapter->cycles.mult = 1; | ||
1682 | adapter->cycles.shift = IGB_TSYNC_SHIFT; | ||
1683 | wr32(E1000_TIMINCA, | ||
1684 | (1<<24) | | ||
1685 | IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS * IGB_TSYNC_SCALE); | ||
1686 | #if 0 | ||
1687 | /* | ||
1688 | * Avoid rollover while we initialize by resetting the time counter. | ||
1689 | */ | ||
1690 | wr32(E1000_SYSTIML, 0x00000000); | ||
1691 | wr32(E1000_SYSTIMH, 0x00000000); | ||
1692 | #else | ||
1693 | /* | ||
1694 | * Set registers so that rollover occurs soon to test this. | ||
1695 | */ | ||
1696 | wr32(E1000_SYSTIML, 0x00000000); | ||
1697 | wr32(E1000_SYSTIMH, 0xFF800000); | ||
1698 | #endif | 1641 | #endif |
1699 | wrfl(); | ||
1700 | timecounter_init(&adapter->clock, | ||
1701 | &adapter->cycles, | ||
1702 | ktime_to_ns(ktime_get_real())); | ||
1703 | 1642 | ||
1704 | /* | 1643 | switch (hw->mac.type) { |
1705 | * Synchronize our NIC clock against system wall clock. NIC | 1644 | case e1000_82576: |
1706 | * time stamp reading requires ~3us per sample, each sample | 1645 | /* |
1707 | * was pretty stable even under load => only require 10 | 1646 | * Initialize hardware timer: we keep it running just in case |
1708 | * samples for each offset comparison. | 1647 | * that some program needs it later on. |
1709 | */ | 1648 | */ |
1710 | memset(&adapter->compare, 0, sizeof(adapter->compare)); | 1649 | memset(&adapter->cycles, 0, sizeof(adapter->cycles)); |
1711 | adapter->compare.source = &adapter->clock; | 1650 | adapter->cycles.read = igb_read_clock; |
1712 | adapter->compare.target = ktime_get_real; | 1651 | adapter->cycles.mask = CLOCKSOURCE_MASK(64); |
1713 | adapter->compare.num_samples = 10; | 1652 | adapter->cycles.mult = 1; |
1714 | timecompare_update(&adapter->compare, 0); | 1653 | /** |
1715 | 1654 | * Scale the NIC clock cycle by a large factor so that | |
1716 | #ifdef DEBUG | 1655 | * relatively small clock corrections can be added or |
1717 | { | 1656 | * substracted at each clock tick. The drawbacks of a large |
1718 | char buffer[160]; | 1657 | * factor are a) that the clock register overflows more quickly |
1719 | printk(KERN_DEBUG | 1658 | * (not such a big deal) and b) that the increment per tick has |
1720 | "igb: %s: hw %p initialized timer\n", | 1659 | * to fit into 24 bits. As a result we need to use a shift of |
1721 | igb_get_time_str(adapter, buffer), | 1660 | * 19 so we can fit a value of 16 into the TIMINCA register. |
1722 | &adapter->hw); | 1661 | */ |
1662 | adapter->cycles.shift = IGB_82576_TSYNC_SHIFT; | ||
1663 | wr32(E1000_TIMINCA, | ||
1664 | (1 << E1000_TIMINCA_16NS_SHIFT) | | ||
1665 | (16 << IGB_82576_TSYNC_SHIFT)); | ||
1666 | |||
1667 | /* Set registers so that rollover occurs soon to test this. */ | ||
1668 | wr32(E1000_SYSTIML, 0x00000000); | ||
1669 | wr32(E1000_SYSTIMH, 0xFF800000); | ||
1670 | wrfl(); | ||
1671 | |||
1672 | timecounter_init(&adapter->clock, | ||
1673 | &adapter->cycles, | ||
1674 | ktime_to_ns(ktime_get_real())); | ||
1675 | /* | ||
1676 | * Synchronize our NIC clock against system wall clock. NIC | ||
1677 | * time stamp reading requires ~3us per sample, each sample | ||
1678 | * was pretty stable even under load => only require 10 | ||
1679 | * samples for each offset comparison. | ||
1680 | */ | ||
1681 | memset(&adapter->compare, 0, sizeof(adapter->compare)); | ||
1682 | adapter->compare.source = &adapter->clock; | ||
1683 | adapter->compare.target = ktime_get_real; | ||
1684 | adapter->compare.num_samples = 10; | ||
1685 | timecompare_update(&adapter->compare, 0); | ||
1686 | break; | ||
1687 | case e1000_82575: | ||
1688 | /* 82575 does not support timesync */ | ||
1689 | default: | ||
1690 | break; | ||
1723 | } | 1691 | } |
1724 | #endif | ||
1725 | 1692 | ||
1726 | dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n"); | 1693 | dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n"); |
1727 | /* print bus type/speed/width info */ | 1694 | /* print bus type/speed/width info */ |
@@ -3596,7 +3563,7 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb, | |||
3596 | u8 hdr_len = 0; | 3563 | u8 hdr_len = 0; |
3597 | int count = 0; | 3564 | int count = 0; |
3598 | int tso = 0; | 3565 | int tso = 0; |
3599 | union skb_shared_tx *shtx; | 3566 | union skb_shared_tx *shtx = skb_tx(skb); |
3600 | 3567 | ||
3601 | /* need: 1 descriptor per page, | 3568 | /* need: 1 descriptor per page, |
3602 | * + 2 desc gap to keep tail from touching head, | 3569 | * + 2 desc gap to keep tail from touching head, |
@@ -3608,16 +3575,6 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb, | |||
3608 | return NETDEV_TX_BUSY; | 3575 | return NETDEV_TX_BUSY; |
3609 | } | 3576 | } |
3610 | 3577 | ||
3611 | /* | ||
3612 | * TODO: check that there currently is no other packet with | ||
3613 | * time stamping in the queue | ||
3614 | * | ||
3615 | * When doing time stamping, keep the connection to the socket | ||
3616 | * a while longer: it is still needed by skb_hwtstamp_tx(), | ||
3617 | * called either in igb_tx_hwtstamp() or by our caller when | ||
3618 | * doing software time stamping. | ||
3619 | */ | ||
3620 | shtx = skb_tx(skb); | ||
3621 | if (unlikely(shtx->hardware)) { | 3578 | if (unlikely(shtx->hardware)) { |
3622 | shtx->in_progress = 1; | 3579 | shtx->in_progress = 1; |
3623 | tx_flags |= IGB_TX_FLAGS_TSTAMP; | 3580 | tx_flags |= IGB_TX_FLAGS_TSTAMP; |
@@ -4633,37 +4590,54 @@ static int igb_poll(struct napi_struct *napi, int budget) | |||
4633 | } | 4590 | } |
4634 | 4591 | ||
4635 | /** | 4592 | /** |
4636 | * igb_hwtstamp - utility function which checks for TX time stamp | 4593 | * igb_systim_to_hwtstamp - convert system time value to hw timestamp |
4637 | * @adapter: board private structure | 4594 | * @adapter: board private structure |
4595 | * @shhwtstamps: timestamp structure to update | ||
4596 | * @regval: unsigned 64bit system time value. | ||
4597 | * | ||
4598 | * We need to convert the system time value stored in the RX/TXSTMP registers | ||
4599 | * into a hwtstamp which can be used by the upper level timestamping functions | ||
4600 | */ | ||
4601 | static void igb_systim_to_hwtstamp(struct igb_adapter *adapter, | ||
4602 | struct skb_shared_hwtstamps *shhwtstamps, | ||
4603 | u64 regval) | ||
4604 | { | ||
4605 | u64 ns; | ||
4606 | |||
4607 | ns = timecounter_cyc2time(&adapter->clock, regval); | ||
4608 | timecompare_update(&adapter->compare, ns); | ||
4609 | memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps)); | ||
4610 | shhwtstamps->hwtstamp = ns_to_ktime(ns); | ||
4611 | shhwtstamps->syststamp = timecompare_transform(&adapter->compare, ns); | ||
4612 | } | ||
4613 | |||
4614 | /** | ||
4615 | * igb_tx_hwtstamp - utility function which checks for TX time stamp | ||
4616 | * @q_vector: pointer to q_vector containing needed info | ||
4638 | * @skb: packet that was just sent | 4617 | * @skb: packet that was just sent |
4639 | * | 4618 | * |
4640 | * If we were asked to do hardware stamping and such a time stamp is | 4619 | * If we were asked to do hardware stamping and such a time stamp is |
4641 | * available, then it must have been for this skb here because we only | 4620 | * available, then it must have been for this skb here because we only |
4642 | * allow only one such packet into the queue. | 4621 | * allow only one such packet into the queue. |
4643 | */ | 4622 | */ |
4644 | static void igb_tx_hwtstamp(struct igb_adapter *adapter, struct sk_buff *skb) | 4623 | static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb) |
4645 | { | 4624 | { |
4625 | struct igb_adapter *adapter = q_vector->adapter; | ||
4646 | union skb_shared_tx *shtx = skb_tx(skb); | 4626 | union skb_shared_tx *shtx = skb_tx(skb); |
4647 | struct e1000_hw *hw = &adapter->hw; | 4627 | struct e1000_hw *hw = &adapter->hw; |
4628 | struct skb_shared_hwtstamps shhwtstamps; | ||
4629 | u64 regval; | ||
4648 | 4630 | ||
4649 | if (unlikely(shtx->hardware)) { | 4631 | /* if skb does not support hw timestamp or TX stamp not valid exit */ |
4650 | u32 valid = rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID; | 4632 | if (likely(!shtx->hardware) || |
4651 | if (valid) { | 4633 | !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID)) |
4652 | u64 regval = rd32(E1000_TXSTMPL); | 4634 | return; |
4653 | u64 ns; | 4635 | |
4654 | struct skb_shared_hwtstamps shhwtstamps; | 4636 | regval = rd32(E1000_TXSTMPL); |
4655 | 4637 | regval |= (u64)rd32(E1000_TXSTMPH) << 32; | |
4656 | memset(&shhwtstamps, 0, sizeof(shhwtstamps)); | 4638 | |
4657 | regval |= (u64)rd32(E1000_TXSTMPH) << 32; | 4639 | igb_systim_to_hwtstamp(adapter, &shhwtstamps, regval); |
4658 | ns = timecounter_cyc2time(&adapter->clock, | 4640 | skb_tstamp_tx(skb, &shhwtstamps); |
4659 | regval); | ||
4660 | timecompare_update(&adapter->compare, ns); | ||
4661 | shhwtstamps.hwtstamp = ns_to_ktime(ns); | ||
4662 | shhwtstamps.syststamp = | ||
4663 | timecompare_transform(&adapter->compare, ns); | ||
4664 | skb_tstamp_tx(skb, &shhwtstamps); | ||
4665 | } | ||
4666 | } | ||
4667 | } | 4641 | } |
4668 | 4642 | ||
4669 | /** | 4643 | /** |
@@ -4706,7 +4680,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) | |||
4706 | total_packets += segs; | 4680 | total_packets += segs; |
4707 | total_bytes += bytecount; | 4681 | total_bytes += bytecount; |
4708 | 4682 | ||
4709 | igb_tx_hwtstamp(adapter, skb); | 4683 | igb_tx_hwtstamp(q_vector, skb); |
4710 | } | 4684 | } |
4711 | 4685 | ||
4712 | igb_unmap_and_free_tx_resource(tx_ring, buffer_info); | 4686 | igb_unmap_and_free_tx_resource(tx_ring, buffer_info); |
@@ -4831,6 +4805,34 @@ static inline void igb_rx_checksum_adv(struct igb_ring *ring, | |||
4831 | dev_dbg(&ring->pdev->dev, "cksum success: bits %08X\n", status_err); | 4805 | dev_dbg(&ring->pdev->dev, "cksum success: bits %08X\n", status_err); |
4832 | } | 4806 | } |
4833 | 4807 | ||
4808 | static inline void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr, | ||
4809 | struct sk_buff *skb) | ||
4810 | { | ||
4811 | struct igb_adapter *adapter = q_vector->adapter; | ||
4812 | struct e1000_hw *hw = &adapter->hw; | ||
4813 | u64 regval; | ||
4814 | |||
4815 | /* | ||
4816 | * If this bit is set, then the RX registers contain the time stamp. No | ||
4817 | * other packet will be time stamped until we read these registers, so | ||
4818 | * read the registers to make them available again. Because only one | ||
4819 | * packet can be time stamped at a time, we know that the register | ||
4820 | * values must belong to this one here and therefore we don't need to | ||
4821 | * compare any of the additional attributes stored for it. | ||
4822 | * | ||
4823 | * If nothing went wrong, then it should have a skb_shared_tx that we | ||
4824 | * can turn into a skb_shared_hwtstamps. | ||
4825 | */ | ||
4826 | if (likely(!(staterr & E1000_RXDADV_STAT_TS))) | ||
4827 | return; | ||
4828 | if (!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID)) | ||
4829 | return; | ||
4830 | |||
4831 | regval = rd32(E1000_RXSTMPL); | ||
4832 | regval |= (u64)rd32(E1000_RXSTMPH) << 32; | ||
4833 | |||
4834 | igb_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval); | ||
4835 | } | ||
4834 | static inline u16 igb_get_hlen(struct igb_ring *rx_ring, | 4836 | static inline u16 igb_get_hlen(struct igb_ring *rx_ring, |
4835 | union e1000_adv_rx_desc *rx_desc) | 4837 | union e1000_adv_rx_desc *rx_desc) |
4836 | { | 4838 | { |
@@ -4848,10 +4850,8 @@ static inline u16 igb_get_hlen(struct igb_ring *rx_ring, | |||
4848 | static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector, | 4850 | static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector, |
4849 | int *work_done, int budget) | 4851 | int *work_done, int budget) |
4850 | { | 4852 | { |
4851 | struct igb_adapter *adapter = q_vector->adapter; | ||
4852 | struct igb_ring *rx_ring = q_vector->rx_ring; | 4853 | struct igb_ring *rx_ring = q_vector->rx_ring; |
4853 | struct net_device *netdev = rx_ring->netdev; | 4854 | struct net_device *netdev = rx_ring->netdev; |
4854 | struct e1000_hw *hw = &adapter->hw; | ||
4855 | struct pci_dev *pdev = rx_ring->pdev; | 4855 | struct pci_dev *pdev = rx_ring->pdev; |
4856 | union e1000_adv_rx_desc *rx_desc , *next_rxd; | 4856 | union e1000_adv_rx_desc *rx_desc , *next_rxd; |
4857 | struct igb_buffer *buffer_info , *next_buffer; | 4857 | struct igb_buffer *buffer_info , *next_buffer; |
@@ -4930,52 +4930,12 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector, | |||
4930 | goto next_desc; | 4930 | goto next_desc; |
4931 | } | 4931 | } |
4932 | send_up: | 4932 | send_up: |
4933 | /* | ||
4934 | * If this bit is set, then the RX registers contain | ||
4935 | * the time stamp. No other packet will be time | ||
4936 | * stamped until we read these registers, so read the | ||
4937 | * registers to make them available again. Because | ||
4938 | * only one packet can be time stamped at a time, we | ||
4939 | * know that the register values must belong to this | ||
4940 | * one here and therefore we don't need to compare | ||
4941 | * any of the additional attributes stored for it. | ||
4942 | * | ||
4943 | * If nothing went wrong, then it should have a | ||
4944 | * skb_shared_tx that we can turn into a | ||
4945 | * skb_shared_hwtstamps. | ||
4946 | * | ||
4947 | * TODO: can time stamping be triggered (thus locking | ||
4948 | * the registers) without the packet reaching this point | ||
4949 | * here? In that case RX time stamping would get stuck. | ||
4950 | * | ||
4951 | * TODO: in "time stamp all packets" mode this bit is | ||
4952 | * not set. Need a global flag for this mode and then | ||
4953 | * always read the registers. Cannot be done without | ||
4954 | * a race condition. | ||
4955 | */ | ||
4956 | if (unlikely(staterr & E1000_RXD_STAT_TS)) { | ||
4957 | u64 regval; | ||
4958 | u64 ns; | ||
4959 | struct skb_shared_hwtstamps *shhwtstamps = | ||
4960 | skb_hwtstamps(skb); | ||
4961 | |||
4962 | WARN(!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID), | ||
4963 | "igb: no RX time stamp available for time stamped packet"); | ||
4964 | regval = rd32(E1000_RXSTMPL); | ||
4965 | regval |= (u64)rd32(E1000_RXSTMPH) << 32; | ||
4966 | ns = timecounter_cyc2time(&adapter->clock, regval); | ||
4967 | timecompare_update(&adapter->compare, ns); | ||
4968 | memset(shhwtstamps, 0, sizeof(*shhwtstamps)); | ||
4969 | shhwtstamps->hwtstamp = ns_to_ktime(ns); | ||
4970 | shhwtstamps->syststamp = | ||
4971 | timecompare_transform(&adapter->compare, ns); | ||
4972 | } | ||
4973 | |||
4974 | if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) { | 4933 | if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) { |
4975 | dev_kfree_skb_irq(skb); | 4934 | dev_kfree_skb_irq(skb); |
4976 | goto next_desc; | 4935 | goto next_desc; |
4977 | } | 4936 | } |
4978 | 4937 | ||
4938 | igb_rx_hwtstamp(q_vector, staterr, skb); | ||
4979 | total_bytes += skb->len; | 4939 | total_bytes += skb->len; |
4980 | total_packets++; | 4940 | total_packets++; |
4981 | 4941 | ||
@@ -5161,13 +5121,11 @@ static int igb_hwtstamp_ioctl(struct net_device *netdev, | |||
5161 | struct igb_adapter *adapter = netdev_priv(netdev); | 5121 | struct igb_adapter *adapter = netdev_priv(netdev); |
5162 | struct e1000_hw *hw = &adapter->hw; | 5122 | struct e1000_hw *hw = &adapter->hw; |
5163 | struct hwtstamp_config config; | 5123 | struct hwtstamp_config config; |
5164 | u32 tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED; | 5124 | u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED; |
5165 | u32 tsync_rx_ctl_bit = E1000_TSYNCRXCTL_ENABLED; | 5125 | u32 tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED; |
5166 | u32 tsync_rx_ctl_type = 0; | ||
5167 | u32 tsync_rx_cfg = 0; | 5126 | u32 tsync_rx_cfg = 0; |
5168 | int is_l4 = 0; | 5127 | bool is_l4 = false; |
5169 | int is_l2 = 0; | 5128 | bool is_l2 = false; |
5170 | short port = 319; /* PTP */ | ||
5171 | u32 regval; | 5129 | u32 regval; |
5172 | 5130 | ||
5173 | if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) | 5131 | if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) |
@@ -5179,10 +5137,8 @@ static int igb_hwtstamp_ioctl(struct net_device *netdev, | |||
5179 | 5137 | ||
5180 | switch (config.tx_type) { | 5138 | switch (config.tx_type) { |
5181 | case HWTSTAMP_TX_OFF: | 5139 | case HWTSTAMP_TX_OFF: |
5182 | tsync_tx_ctl_bit = 0; | 5140 | tsync_tx_ctl = 0; |
5183 | break; | ||
5184 | case HWTSTAMP_TX_ON: | 5141 | case HWTSTAMP_TX_ON: |
5185 | tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED; | ||
5186 | break; | 5142 | break; |
5187 | default: | 5143 | default: |
5188 | return -ERANGE; | 5144 | return -ERANGE; |
@@ -5190,7 +5146,7 @@ static int igb_hwtstamp_ioctl(struct net_device *netdev, | |||
5190 | 5146 | ||
5191 | switch (config.rx_filter) { | 5147 | switch (config.rx_filter) { |
5192 | case HWTSTAMP_FILTER_NONE: | 5148 | case HWTSTAMP_FILTER_NONE: |
5193 | tsync_rx_ctl_bit = 0; | 5149 | tsync_rx_ctl = 0; |
5194 | break; | 5150 | break; |
5195 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | 5151 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: |
5196 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | 5152 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: |
@@ -5201,86 +5157,97 @@ static int igb_hwtstamp_ioctl(struct net_device *netdev, | |||
5201 | * possible to time stamp both Sync and Delay_Req messages | 5157 | * possible to time stamp both Sync and Delay_Req messages |
5202 | * => fall back to time stamping all packets | 5158 | * => fall back to time stamping all packets |
5203 | */ | 5159 | */ |
5204 | tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_ALL; | 5160 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL; |
5205 | config.rx_filter = HWTSTAMP_FILTER_ALL; | 5161 | config.rx_filter = HWTSTAMP_FILTER_ALL; |
5206 | break; | 5162 | break; |
5207 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | 5163 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: |
5208 | tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1; | 5164 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1; |
5209 | tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE; | 5165 | tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE; |
5210 | is_l4 = 1; | 5166 | is_l4 = true; |
5211 | break; | 5167 | break; |
5212 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | 5168 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: |
5213 | tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1; | 5169 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1; |
5214 | tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE; | 5170 | tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE; |
5215 | is_l4 = 1; | 5171 | is_l4 = true; |
5216 | break; | 5172 | break; |
5217 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | 5173 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: |
5218 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | 5174 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: |
5219 | tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L2_L4_V2; | 5175 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2; |
5220 | tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE; | 5176 | tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE; |
5221 | is_l2 = 1; | 5177 | is_l2 = true; |
5222 | is_l4 = 1; | 5178 | is_l4 = true; |
5223 | config.rx_filter = HWTSTAMP_FILTER_SOME; | 5179 | config.rx_filter = HWTSTAMP_FILTER_SOME; |
5224 | break; | 5180 | break; |
5225 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | 5181 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: |
5226 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | 5182 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: |
5227 | tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L2_L4_V2; | 5183 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2; |
5228 | tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE; | 5184 | tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE; |
5229 | is_l2 = 1; | 5185 | is_l2 = true; |
5230 | is_l4 = 1; | 5186 | is_l4 = true; |
5231 | config.rx_filter = HWTSTAMP_FILTER_SOME; | 5187 | config.rx_filter = HWTSTAMP_FILTER_SOME; |
5232 | break; | 5188 | break; |
5233 | case HWTSTAMP_FILTER_PTP_V2_EVENT: | 5189 | case HWTSTAMP_FILTER_PTP_V2_EVENT: |
5234 | case HWTSTAMP_FILTER_PTP_V2_SYNC: | 5190 | case HWTSTAMP_FILTER_PTP_V2_SYNC: |
5235 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: | 5191 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: |
5236 | tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_EVENT_V2; | 5192 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_EVENT_V2; |
5237 | config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; | 5193 | config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; |
5238 | is_l2 = 1; | 5194 | is_l2 = true; |
5239 | break; | 5195 | break; |
5240 | default: | 5196 | default: |
5241 | return -ERANGE; | 5197 | return -ERANGE; |
5242 | } | 5198 | } |
5243 | 5199 | ||
5200 | if (hw->mac.type == e1000_82575) { | ||
5201 | if (tsync_rx_ctl | tsync_tx_ctl) | ||
5202 | return -EINVAL; | ||
5203 | return 0; | ||
5204 | } | ||
5205 | |||
5244 | /* enable/disable TX */ | 5206 | /* enable/disable TX */ |
5245 | regval = rd32(E1000_TSYNCTXCTL); | 5207 | regval = rd32(E1000_TSYNCTXCTL); |
5246 | regval = (regval & ~E1000_TSYNCTXCTL_ENABLED) | tsync_tx_ctl_bit; | 5208 | regval &= ~E1000_TSYNCTXCTL_ENABLED; |
5209 | regval |= tsync_tx_ctl; | ||
5247 | wr32(E1000_TSYNCTXCTL, regval); | 5210 | wr32(E1000_TSYNCTXCTL, regval); |
5248 | 5211 | ||
5249 | /* enable/disable RX, define which PTP packets are time stamped */ | 5212 | /* enable/disable RX */ |
5250 | regval = rd32(E1000_TSYNCRXCTL); | 5213 | regval = rd32(E1000_TSYNCRXCTL); |
5251 | regval = (regval & ~E1000_TSYNCRXCTL_ENABLED) | tsync_rx_ctl_bit; | 5214 | regval &= ~(E1000_TSYNCRXCTL_ENABLED | E1000_TSYNCRXCTL_TYPE_MASK); |
5252 | regval = (regval & ~0xE) | tsync_rx_ctl_type; | 5215 | regval |= tsync_rx_ctl; |
5253 | wr32(E1000_TSYNCRXCTL, regval); | 5216 | wr32(E1000_TSYNCRXCTL, regval); |
5254 | wr32(E1000_TSYNCRXCFG, tsync_rx_cfg); | ||
5255 | 5217 | ||
5256 | /* | 5218 | /* define which PTP packets are time stamped */ |
5257 | * Ethertype Filter Queue Filter[0][15:0] = 0x88F7 | 5219 | wr32(E1000_TSYNCRXCFG, tsync_rx_cfg); |
5258 | * (Ethertype to filter on) | ||
5259 | * Ethertype Filter Queue Filter[0][26] = 0x1 (Enable filter) | ||
5260 | * Ethertype Filter Queue Filter[0][30] = 0x1 (Enable Timestamping) | ||
5261 | */ | ||
5262 | wr32(E1000_ETQF0, is_l2 ? 0x440088f7 : 0); | ||
5263 | |||
5264 | /* L4 Queue Filter[0]: only filter by source and destination port */ | ||
5265 | wr32(E1000_SPQF0, htons(port)); | ||
5266 | wr32(E1000_IMIREXT(0), is_l4 ? | ||
5267 | ((1<<12) | (1<<19) /* bypass size and control flags */) : 0); | ||
5268 | wr32(E1000_IMIR(0), is_l4 ? | ||
5269 | (htons(port) | ||
5270 | | (0<<16) /* immediate interrupt disabled */ | ||
5271 | | 0 /* (1<<17) bit cleared: do not bypass | ||
5272 | destination port check */) | ||
5273 | : 0); | ||
5274 | wr32(E1000_FTQF0, is_l4 ? | ||
5275 | (0x11 /* UDP */ | ||
5276 | | (1<<15) /* VF not compared */ | ||
5277 | | (1<<27) /* Enable Timestamping */ | ||
5278 | | (7<<28) /* only source port filter enabled, | ||
5279 | source/target address and protocol | ||
5280 | masked */) | ||
5281 | : ((1<<15) | (15<<28) /* all mask bits set = filter not | ||
5282 | enabled */)); | ||
5283 | 5220 | ||
5221 | /* define ethertype filter for timestamped packets */ | ||
5222 | if (is_l2) | ||
5223 | wr32(E1000_ETQF(3), | ||
5224 | (E1000_ETQF_FILTER_ENABLE | /* enable filter */ | ||
5225 | E1000_ETQF_1588 | /* enable timestamping */ | ||
5226 | ETH_P_1588)); /* 1588 eth protocol type */ | ||
5227 | else | ||
5228 | wr32(E1000_ETQF(3), 0); | ||
5229 | |||
5230 | #define PTP_PORT 319 | ||
5231 | /* L4 Queue Filter[3]: filter by destination port and protocol */ | ||
5232 | if (is_l4) { | ||
5233 | u32 ftqf = (IPPROTO_UDP /* UDP */ | ||
5234 | | E1000_FTQF_VF_BP /* VF not compared */ | ||
5235 | | E1000_FTQF_1588_TIME_STAMP /* Enable Timestamping */ | ||
5236 | | E1000_FTQF_MASK); /* mask all inputs */ | ||
5237 | ftqf &= ~E1000_FTQF_MASK_PROTO_BP; /* enable protocol check */ | ||
5238 | |||
5239 | wr32(E1000_IMIR(3), htons(PTP_PORT)); | ||
5240 | wr32(E1000_IMIREXT(3), | ||
5241 | (E1000_IMIREXT_SIZE_BP | E1000_IMIREXT_CTRL_BP)); | ||
5242 | if (hw->mac.type == e1000_82576) { | ||
5243 | /* enable source port check */ | ||
5244 | wr32(E1000_SPQF(3), htons(PTP_PORT)); | ||
5245 | ftqf &= ~E1000_FTQF_MASK_SOURCE_PORT_BP; | ||
5246 | } | ||
5247 | wr32(E1000_FTQF(3), ftqf); | ||
5248 | } else { | ||
5249 | wr32(E1000_FTQF(3), E1000_FTQF_MASK); | ||
5250 | } | ||
5284 | wrfl(); | 5251 | wrfl(); |
5285 | 5252 | ||
5286 | adapter->hwtstamp_config = config; | 5253 | adapter->hwtstamp_config = config; |