diff options
author | Nick Nunley <nicholasx.d.nunley@intel.com> | 2010-03-26 07:36:47 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-03-31 02:42:27 -0400 |
commit | 757b77e2b208490868cf21fd22d796eb9bd199c5 (patch) | |
tree | 628dccdbed780dc38d9843bb30d5c5920b830258 /drivers/net/igb | |
parent | 3365a2934cce29fa9196bc4fd7086f62e799ee84 (diff) |
igb: add per-packet timestamping
This patch adds support for per-packet timestamping for the
82580 adapter. The rx timestamp code is also pulled out of the
inlined rx hotpath and instead moved to a seperate function.
This version adds a comment explaining the per-packet timestamping
code added to igb_hwtstamp_ioctl().
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@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')
-rw-r--r-- | drivers/net/igb/e1000_82575.h | 2 | ||||
-rw-r--r-- | drivers/net/igb/igb.h | 2 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 45 |
3 files changed, 41 insertions, 8 deletions
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index c1cad8ae522e..cbd1e1259e4d 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h | |||
@@ -53,6 +53,7 @@ extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw); | |||
53 | #define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 | 53 | #define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 |
54 | #define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 | 54 | #define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 |
55 | #define E1000_SRRCTL_DROP_EN 0x80000000 | 55 | #define E1000_SRRCTL_DROP_EN 0x80000000 |
56 | #define E1000_SRRCTL_TIMESTAMP 0x40000000 | ||
56 | 57 | ||
57 | #define E1000_MRQC_ENABLE_RSS_4Q 0x00000002 | 58 | #define E1000_MRQC_ENABLE_RSS_4Q 0x00000002 |
58 | #define E1000_MRQC_ENABLE_VMDQ 0x00000003 | 59 | #define E1000_MRQC_ENABLE_VMDQ 0x00000003 |
@@ -109,6 +110,7 @@ union e1000_adv_rx_desc { | |||
109 | #define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0 | 110 | #define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0 |
110 | #define E1000_RXDADV_HDRBUFLEN_SHIFT 5 | 111 | #define E1000_RXDADV_HDRBUFLEN_SHIFT 5 |
111 | #define E1000_RXDADV_STAT_TS 0x10000 /* Pkt was time stamped */ | 112 | #define E1000_RXDADV_STAT_TS 0x10000 /* Pkt was time stamped */ |
113 | #define E1000_RXDADV_STAT_TSIP 0x08000 /* timestamp in packet */ | ||
112 | 114 | ||
113 | /* Transmit Descriptor - Advanced */ | 115 | /* Transmit Descriptor - Advanced */ |
114 | union e1000_adv_tx_desc { | 116 | union e1000_adv_tx_desc { |
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index a1775705b24c..4f69b6d951b3 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h | |||
@@ -107,6 +107,7 @@ struct vf_data_storage { | |||
107 | #define MAXIMUM_ETHERNET_VLAN_SIZE 1522 | 107 | #define MAXIMUM_ETHERNET_VLAN_SIZE 1522 |
108 | 108 | ||
109 | /* Supported Rx Buffer Sizes */ | 109 | /* Supported Rx Buffer Sizes */ |
110 | #define IGB_RXBUFFER_64 64 /* Used for packet split */ | ||
110 | #define IGB_RXBUFFER_128 128 /* Used for packet split */ | 111 | #define IGB_RXBUFFER_128 128 /* Used for packet split */ |
111 | #define IGB_RXBUFFER_1024 1024 | 112 | #define IGB_RXBUFFER_1024 1024 |
112 | #define IGB_RXBUFFER_2048 2048 | 113 | #define IGB_RXBUFFER_2048 2048 |
@@ -324,6 +325,7 @@ struct igb_adapter { | |||
324 | 325 | ||
325 | #define IGB_82576_TSYNC_SHIFT 19 | 326 | #define IGB_82576_TSYNC_SHIFT 19 |
326 | #define IGB_82580_TSYNC_SHIFT 24 | 327 | #define IGB_82580_TSYNC_SHIFT 24 |
328 | #define IGB_TS_HDR_LEN 16 | ||
327 | enum e1000_state_t { | 329 | enum e1000_state_t { |
328 | __IGB_TESTING, | 330 | __IGB_TESTING, |
329 | __IGB_RESETTING, | 331 | __IGB_RESETTING, |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 7d755dd2688d..ea875709f053 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -2576,6 +2576,8 @@ void igb_configure_rx_ring(struct igb_adapter *adapter, | |||
2576 | E1000_SRRCTL_BSIZEPKT_SHIFT; | 2576 | E1000_SRRCTL_BSIZEPKT_SHIFT; |
2577 | srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF; | 2577 | srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF; |
2578 | } | 2578 | } |
2579 | if (hw->mac.type == e1000_82580) | ||
2580 | srrctl |= E1000_SRRCTL_TIMESTAMP; | ||
2579 | /* Only set Drop Enable if we are supporting multiple queues */ | 2581 | /* Only set Drop Enable if we are supporting multiple queues */ |
2580 | if (adapter->vfs_allocated_count || adapter->num_rx_queues > 1) | 2582 | if (adapter->vfs_allocated_count || adapter->num_rx_queues > 1) |
2581 | srrctl |= E1000_SRRCTL_DROP_EN; | 2583 | srrctl |= E1000_SRRCTL_DROP_EN; |
@@ -3910,6 +3912,9 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu) | |||
3910 | * i.e. RXBUFFER_2048 --> size-4096 slab | 3912 | * i.e. RXBUFFER_2048 --> size-4096 slab |
3911 | */ | 3913 | */ |
3912 | 3914 | ||
3915 | if (adapter->hw.mac.type == e1000_82580) | ||
3916 | max_frame += IGB_TS_HDR_LEN; | ||
3917 | |||
3913 | if (max_frame <= IGB_RXBUFFER_1024) | 3918 | if (max_frame <= IGB_RXBUFFER_1024) |
3914 | rx_buffer_len = IGB_RXBUFFER_1024; | 3919 | rx_buffer_len = IGB_RXBUFFER_1024; |
3915 | else if (max_frame <= MAXIMUM_ETHERNET_VLAN_SIZE) | 3920 | else if (max_frame <= MAXIMUM_ETHERNET_VLAN_SIZE) |
@@ -3917,6 +3922,14 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu) | |||
3917 | else | 3922 | else |
3918 | rx_buffer_len = IGB_RXBUFFER_128; | 3923 | rx_buffer_len = IGB_RXBUFFER_128; |
3919 | 3924 | ||
3925 | if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN + IGB_TS_HDR_LEN) || | ||
3926 | (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE + IGB_TS_HDR_LEN)) | ||
3927 | rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE + IGB_TS_HDR_LEN; | ||
3928 | |||
3929 | if ((adapter->hw.mac.type == e1000_82580) && | ||
3930 | (rx_buffer_len == IGB_RXBUFFER_128)) | ||
3931 | rx_buffer_len += IGB_RXBUFFER_64; | ||
3932 | |||
3920 | if (netif_running(netdev)) | 3933 | if (netif_running(netdev)) |
3921 | igb_down(adapter); | 3934 | igb_down(adapter); |
3922 | 3935 | ||
@@ -5133,7 +5146,7 @@ static inline void igb_rx_checksum_adv(struct igb_ring *ring, | |||
5133 | dev_dbg(&ring->pdev->dev, "cksum success: bits %08X\n", status_err); | 5146 | dev_dbg(&ring->pdev->dev, "cksum success: bits %08X\n", status_err); |
5134 | } | 5147 | } |
5135 | 5148 | ||
5136 | static inline void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr, | 5149 | static void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr, |
5137 | struct sk_buff *skb) | 5150 | struct sk_buff *skb) |
5138 | { | 5151 | { |
5139 | struct igb_adapter *adapter = q_vector->adapter; | 5152 | struct igb_adapter *adapter = q_vector->adapter; |
@@ -5151,13 +5164,18 @@ static inline void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr, | |||
5151 | * If nothing went wrong, then it should have a skb_shared_tx that we | 5164 | * If nothing went wrong, then it should have a skb_shared_tx that we |
5152 | * can turn into a skb_shared_hwtstamps. | 5165 | * can turn into a skb_shared_hwtstamps. |
5153 | */ | 5166 | */ |
5154 | if (likely(!(staterr & E1000_RXDADV_STAT_TS))) | 5167 | if (staterr & E1000_RXDADV_STAT_TSIP) { |
5155 | return; | 5168 | u32 *stamp = (u32 *)skb->data; |
5156 | if (!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID)) | 5169 | regval = le32_to_cpu(*(stamp + 2)); |
5157 | return; | 5170 | regval |= (u64)le32_to_cpu(*(stamp + 3)) << 32; |
5171 | skb_pull(skb, IGB_TS_HDR_LEN); | ||
5172 | } else { | ||
5173 | if(!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID)) | ||
5174 | return; | ||
5158 | 5175 | ||
5159 | regval = rd32(E1000_RXSTMPL); | 5176 | regval = rd32(E1000_RXSTMPL); |
5160 | regval |= (u64)rd32(E1000_RXSTMPH) << 32; | 5177 | regval |= (u64)rd32(E1000_RXSTMPH) << 32; |
5178 | } | ||
5161 | 5179 | ||
5162 | igb_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval); | 5180 | igb_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval); |
5163 | } | 5181 | } |
@@ -5265,7 +5283,8 @@ send_up: | |||
5265 | goto next_desc; | 5283 | goto next_desc; |
5266 | } | 5284 | } |
5267 | 5285 | ||
5268 | igb_rx_hwtstamp(q_vector, staterr, skb); | 5286 | if (staterr & (E1000_RXDADV_STAT_TSIP | E1000_RXDADV_STAT_TS)) |
5287 | igb_rx_hwtstamp(q_vector, staterr, skb); | ||
5269 | total_bytes += skb->len; | 5288 | total_bytes += skb->len; |
5270 | total_packets++; | 5289 | total_packets++; |
5271 | 5290 | ||
@@ -5545,6 +5564,16 @@ static int igb_hwtstamp_ioctl(struct net_device *netdev, | |||
5545 | return 0; | 5564 | return 0; |
5546 | } | 5565 | } |
5547 | 5566 | ||
5567 | /* | ||
5568 | * Per-packet timestamping only works if all packets are | ||
5569 | * timestamped, so enable timestamping in all packets as | ||
5570 | * long as one rx filter was configured. | ||
5571 | */ | ||
5572 | if ((hw->mac.type == e1000_82580) && tsync_rx_ctl) { | ||
5573 | tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED; | ||
5574 | tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL; | ||
5575 | } | ||
5576 | |||
5548 | /* enable/disable TX */ | 5577 | /* enable/disable TX */ |
5549 | regval = rd32(E1000_TSYNCTXCTL); | 5578 | regval = rd32(E1000_TSYNCTXCTL); |
5550 | regval &= ~E1000_TSYNCTXCTL_ENABLED; | 5579 | regval &= ~E1000_TSYNCTXCTL_ENABLED; |