aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNick Nunley <nicholasx.d.nunley@intel.com>2010-03-26 07:36:47 -0400
committerDavid S. Miller <davem@davemloft.net>2010-03-31 02:42:27 -0400
commit757b77e2b208490868cf21fd22d796eb9bd199c5 (patch)
tree628dccdbed780dc38d9843bb30d5c5920b830258 /drivers
parent3365a2934cce29fa9196bc4fd7086f62e799ee84 (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')
-rw-r--r--drivers/net/igb/e1000_82575.h2
-rw-r--r--drivers/net/igb/igb.h2
-rw-r--r--drivers/net/igb/igb_main.c45
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 */
114union e1000_adv_tx_desc { 116union 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
327enum e1000_state_t { 329enum 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
5136static inline void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr, 5149static 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;