diff options
author | Matt Carlson <mcarlson@broadcom.com> | 2012-12-03 14:37:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-12-04 12:58:50 -0500 |
commit | fb4ce8ad8036e6b3d5ab021fd10934b80270cc11 (patch) | |
tree | bb6571793fe08cab873a1e19560aac5303a3b1c7 /drivers/net | |
parent | 0a633ac2284a92f0c65972bd8019146ed7d66159 (diff) |
tg3: PTP - Enable the timestamping feature in hardware and fill skb tx/rx timestamps
This patch implements the hardware timestamping as described in
Documentation/networking/timestamping.txt
Update version to 3.128.
Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 57 |
1 files changed, 52 insertions, 5 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index a718a382b4bf..3f7b1c309c63 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -93,10 +93,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) | |||
93 | 93 | ||
94 | #define DRV_MODULE_NAME "tg3" | 94 | #define DRV_MODULE_NAME "tg3" |
95 | #define TG3_MAJ_NUM 3 | 95 | #define TG3_MAJ_NUM 3 |
96 | #define TG3_MIN_NUM 127 | 96 | #define TG3_MIN_NUM 128 |
97 | #define DRV_MODULE_VERSION \ | 97 | #define DRV_MODULE_VERSION \ |
98 | __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) | 98 | __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) |
99 | #define DRV_MODULE_RELDATE "November 14, 2012" | 99 | #define DRV_MODULE_RELDATE "December 03, 2012" |
100 | 100 | ||
101 | #define RESET_KIND_SHUTDOWN 0 | 101 | #define RESET_KIND_SHUTDOWN 0 |
102 | #define RESET_KIND_INIT 1 | 102 | #define RESET_KIND_INIT 1 |
@@ -5663,6 +5663,14 @@ static const struct ptp_clock_info tg3_ptp_caps = { | |||
5663 | .enable = tg3_ptp_enable, | 5663 | .enable = tg3_ptp_enable, |
5664 | }; | 5664 | }; |
5665 | 5665 | ||
5666 | static void tg3_hwclock_to_timestamp(struct tg3 *tp, u64 hwclock, | ||
5667 | struct skb_shared_hwtstamps *timestamp) | ||
5668 | { | ||
5669 | memset(timestamp, 0, sizeof(struct skb_shared_hwtstamps)); | ||
5670 | timestamp->hwtstamp = ns_to_ktime((hwclock & TG3_TSTAMP_MASK) + | ||
5671 | tp->ptp_adjust); | ||
5672 | } | ||
5673 | |||
5666 | /* tp->lock must be held */ | 5674 | /* tp->lock must be held */ |
5667 | static void tg3_ptp_init(struct tg3 *tp) | 5675 | static void tg3_ptp_init(struct tg3 *tp) |
5668 | { | 5676 | { |
@@ -5875,6 +5883,16 @@ static void tg3_tx(struct tg3_napi *tnapi) | |||
5875 | return; | 5883 | return; |
5876 | } | 5884 | } |
5877 | 5885 | ||
5886 | if (tnapi->tx_ring[sw_idx].len_flags & TXD_FLAG_HWTSTAMP) { | ||
5887 | struct skb_shared_hwtstamps timestamp; | ||
5888 | u64 hwclock = tr32(TG3_TX_TSTAMP_LSB); | ||
5889 | hwclock |= (u64)tr32(TG3_TX_TSTAMP_MSB) << 32; | ||
5890 | |||
5891 | tg3_hwclock_to_timestamp(tp, hwclock, ×tamp); | ||
5892 | |||
5893 | skb_tstamp_tx(skb, ×tamp); | ||
5894 | } | ||
5895 | |||
5878 | pci_unmap_single(tp->pdev, | 5896 | pci_unmap_single(tp->pdev, |
5879 | dma_unmap_addr(ri, mapping), | 5897 | dma_unmap_addr(ri, mapping), |
5880 | skb_headlen(skb), | 5898 | skb_headlen(skb), |
@@ -6142,6 +6160,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
6142 | dma_addr_t dma_addr; | 6160 | dma_addr_t dma_addr; |
6143 | u32 opaque_key, desc_idx, *post_ptr; | 6161 | u32 opaque_key, desc_idx, *post_ptr; |
6144 | u8 *data; | 6162 | u8 *data; |
6163 | u64 tstamp = 0; | ||
6145 | 6164 | ||
6146 | desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; | 6165 | desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; |
6147 | opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; | 6166 | opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; |
@@ -6176,6 +6195,14 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
6176 | len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - | 6195 | len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - |
6177 | ETH_FCS_LEN; | 6196 | ETH_FCS_LEN; |
6178 | 6197 | ||
6198 | if ((desc->type_flags & RXD_FLAG_PTPSTAT_MASK) == | ||
6199 | RXD_FLAG_PTPSTAT_PTPV1 || | ||
6200 | (desc->type_flags & RXD_FLAG_PTPSTAT_MASK) == | ||
6201 | RXD_FLAG_PTPSTAT_PTPV2) { | ||
6202 | tstamp = tr32(TG3_RX_TSTAMP_LSB); | ||
6203 | tstamp |= (u64)tr32(TG3_RX_TSTAMP_MSB) << 32; | ||
6204 | } | ||
6205 | |||
6179 | if (len > TG3_RX_COPY_THRESH(tp)) { | 6206 | if (len > TG3_RX_COPY_THRESH(tp)) { |
6180 | int skb_size; | 6207 | int skb_size; |
6181 | unsigned int frag_size; | 6208 | unsigned int frag_size; |
@@ -6219,6 +6246,10 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
6219 | } | 6246 | } |
6220 | 6247 | ||
6221 | skb_put(skb, len); | 6248 | skb_put(skb, len); |
6249 | if (tstamp) | ||
6250 | tg3_hwclock_to_timestamp(tp, tstamp, | ||
6251 | skb_hwtstamps(skb)); | ||
6252 | |||
6222 | if ((tp->dev->features & NETIF_F_RXCSUM) && | 6253 | if ((tp->dev->features & NETIF_F_RXCSUM) && |
6223 | (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) && | 6254 | (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) && |
6224 | (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK) | 6255 | (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK) |
@@ -7276,6 +7307,12 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
7276 | vlan = vlan_tx_tag_get(skb); | 7307 | vlan = vlan_tx_tag_get(skb); |
7277 | } | 7308 | } |
7278 | 7309 | ||
7310 | if ((unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) && | ||
7311 | tg3_flag(tp, TX_TSTAMP_EN)) { | ||
7312 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | ||
7313 | base_flags |= TXD_FLAG_HWTSTAMP; | ||
7314 | } | ||
7315 | |||
7279 | len = skb_headlen(skb); | 7316 | len = skb_headlen(skb); |
7280 | 7317 | ||
7281 | mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE); | 7318 | mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE); |
@@ -9144,9 +9181,15 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
9144 | */ | 9181 | */ |
9145 | tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; | 9182 | tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; |
9146 | 9183 | ||
9147 | tw32(GRC_MODE, | 9184 | val = GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP; |
9148 | tp->grc_mode | | 9185 | if (tp->rxptpctl) |
9149 | (GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP)); | 9186 | tw32(TG3_RX_PTP_CTL, |
9187 | tp->rxptpctl | TG3_RX_PTP_CTL_HWTS_INTERLOCK); | ||
9188 | |||
9189 | if (tg3_flag(tp, PTP_CAPABLE)) | ||
9190 | val |= GRC_MODE_TIME_SYNC_ENABLE; | ||
9191 | |||
9192 | tw32(GRC_MODE, tp->grc_mode | val); | ||
9150 | 9193 | ||
9151 | /* Setup the timer prescalar register. Clock is always 66Mhz. */ | 9194 | /* Setup the timer prescalar register. Clock is always 66Mhz. */ |
9152 | val = tr32(GRC_MISC_CFG); | 9195 | val = tr32(GRC_MISC_CFG); |
@@ -16565,6 +16608,10 @@ static int tg3_init_one(struct pci_dev *pdev, | |||
16565 | 16608 | ||
16566 | pci_set_drvdata(pdev, dev); | 16609 | pci_set_drvdata(pdev, dev); |
16567 | 16610 | ||
16611 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || | ||
16612 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) | ||
16613 | tg3_flag_set(tp, PTP_CAPABLE); | ||
16614 | |||
16568 | if (tg3_flag(tp, 5717_PLUS)) { | 16615 | if (tg3_flag(tp, 5717_PLUS)) { |
16569 | /* Resume a low-power mode */ | 16616 | /* Resume a low-power mode */ |
16570 | tg3_frob_aux_power(tp, false); | 16617 | tg3_frob_aux_power(tp, false); |