aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/adi
diff options
context:
space:
mode:
authorRichard Cochran <richardcochran@gmail.com>2012-10-31 02:27:23 -0400
committerDavid S. Miller <davem@davemloft.net>2012-11-01 11:41:35 -0400
commitbc3c5f634de23ca767c2d04d356ddf5bbe2144e2 (patch)
treecb152135d7336f280762ed2aaa6450e6d9d4d688 /drivers/net/ethernet/adi
parent85c153d2c7e51efcf0f715118c3c30b62c5fce68 (diff)
bfin_mac: replace sys time stamps with raw ones instead.
This patch replaces the sys time stamps and timecompare code with simple raw hardware time stamps in nanosecond resolution. The only tricky bit is to find a PTP Hardware Clock period slower than the input clock period and a power of two. Compile tested only. Signed-off-by: Richard Cochran <richardcochran@gmail.com> Tested-by: Bob Liu <lliubbo@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/adi')
-rw-r--r--drivers/net/ethernet/adi/bfin_mac.c91
-rw-r--r--drivers/net/ethernet/adi/bfin_mac.h7
2 files changed, 28 insertions, 70 deletions
diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c
index 2349abba33d8..885fa80e9220 100644
--- a/drivers/net/ethernet/adi/bfin_mac.c
+++ b/drivers/net/ethernet/adi/bfin_mac.c
@@ -555,7 +555,7 @@ static int bfin_mac_ethtool_get_ts_info(struct net_device *dev,
555 info->so_timestamping = 555 info->so_timestamping =
556 SOF_TIMESTAMPING_TX_HARDWARE | 556 SOF_TIMESTAMPING_TX_HARDWARE |
557 SOF_TIMESTAMPING_RX_HARDWARE | 557 SOF_TIMESTAMPING_RX_HARDWARE |
558 SOF_TIMESTAMPING_SYS_HARDWARE; 558 SOF_TIMESTAMPING_RAW_HARDWARE;
559 info->phc_index = -1; 559 info->phc_index = -1;
560 info->tx_types = 560 info->tx_types =
561 (1 << HWTSTAMP_TX_OFF) | 561 (1 << HWTSTAMP_TX_OFF) |
@@ -653,6 +653,20 @@ static int bfin_mac_set_mac_address(struct net_device *dev, void *p)
653#ifdef CONFIG_BFIN_MAC_USE_HWSTAMP 653#ifdef CONFIG_BFIN_MAC_USE_HWSTAMP
654#define bfin_mac_hwtstamp_is_none(cfg) ((cfg) == HWTSTAMP_FILTER_NONE) 654#define bfin_mac_hwtstamp_is_none(cfg) ((cfg) == HWTSTAMP_FILTER_NONE)
655 655
656static u32 bfin_select_phc_clock(u32 input_clk, unsigned int *shift_result)
657{
658 u32 ipn = 1000000000UL / input_clk;
659 u32 ppn = 1;
660 unsigned int shift = 0;
661
662 while (ppn <= ipn) {
663 ppn <<= 1;
664 shift++;
665 }
666 *shift_result = shift;
667 return 1000000000UL / ppn;
668}
669
656static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev, 670static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev,
657 struct ifreq *ifr, int cmd) 671 struct ifreq *ifr, int cmd)
658{ 672{
@@ -802,19 +816,7 @@ static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev,
802 bfin_read_EMAC_PTP_TXSNAPLO(); 816 bfin_read_EMAC_PTP_TXSNAPLO();
803 bfin_read_EMAC_PTP_TXSNAPHI(); 817 bfin_read_EMAC_PTP_TXSNAPHI();
804 818
805 /*
806 * Set registers so that rollover occurs soon to test this.
807 */
808 bfin_write_EMAC_PTP_TIMELO(0x00000000);
809 bfin_write_EMAC_PTP_TIMEHI(0xFF800000);
810
811 SSYNC(); 819 SSYNC();
812
813 lp->compare.last_update = 0;
814 timecounter_init(&lp->clock,
815 &lp->cycles,
816 ktime_to_ns(ktime_get_real()));
817 timecompare_update(&lp->compare, 0);
818 } 820 }
819 821
820 lp->stamp_cfg = config; 822 lp->stamp_cfg = config;
@@ -822,15 +824,6 @@ static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev,
822 -EFAULT : 0; 824 -EFAULT : 0;
823} 825}
824 826
825static void bfin_dump_hwtamp(char *s, ktime_t *hw, ktime_t *ts, struct timecompare *cmp)
826{
827 ktime_t sys = ktime_get_real();
828
829 pr_debug("%s %s hardware:%d,%d transform system:%d,%d system:%d,%d, cmp:%lld, %lld\n",
830 __func__, s, hw->tv.sec, hw->tv.nsec, ts->tv.sec, ts->tv.nsec, sys.tv.sec,
831 sys.tv.nsec, cmp->offset, cmp->skew);
832}
833
834static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb) 827static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
835{ 828{
836 struct bfin_mac_local *lp = netdev_priv(netdev); 829 struct bfin_mac_local *lp = netdev_priv(netdev);
@@ -861,15 +854,9 @@ static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
861 regval = bfin_read_EMAC_PTP_TXSNAPLO(); 854 regval = bfin_read_EMAC_PTP_TXSNAPLO();
862 regval |= (u64)bfin_read_EMAC_PTP_TXSNAPHI() << 32; 855 regval |= (u64)bfin_read_EMAC_PTP_TXSNAPHI() << 32;
863 memset(&shhwtstamps, 0, sizeof(shhwtstamps)); 856 memset(&shhwtstamps, 0, sizeof(shhwtstamps));
864 ns = timecounter_cyc2time(&lp->clock, 857 ns = regval << lp->shift;
865 regval);
866 timecompare_update(&lp->compare, ns);
867 shhwtstamps.hwtstamp = ns_to_ktime(ns); 858 shhwtstamps.hwtstamp = ns_to_ktime(ns);
868 shhwtstamps.syststamp =
869 timecompare_transform(&lp->compare, ns);
870 skb_tstamp_tx(skb, &shhwtstamps); 859 skb_tstamp_tx(skb, &shhwtstamps);
871
872 bfin_dump_hwtamp("TX", &shhwtstamps.hwtstamp, &shhwtstamps.syststamp, &lp->compare);
873 } 860 }
874 } 861 }
875} 862}
@@ -892,51 +879,25 @@ static void bfin_rx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
892 879
893 regval = bfin_read_EMAC_PTP_RXSNAPLO(); 880 regval = bfin_read_EMAC_PTP_RXSNAPLO();
894 regval |= (u64)bfin_read_EMAC_PTP_RXSNAPHI() << 32; 881 regval |= (u64)bfin_read_EMAC_PTP_RXSNAPHI() << 32;
895 ns = timecounter_cyc2time(&lp->clock, regval); 882 ns = regval << lp->shift;
896 timecompare_update(&lp->compare, ns);
897 memset(shhwtstamps, 0, sizeof(*shhwtstamps)); 883 memset(shhwtstamps, 0, sizeof(*shhwtstamps));
898 shhwtstamps->hwtstamp = ns_to_ktime(ns); 884 shhwtstamps->hwtstamp = ns_to_ktime(ns);
899 shhwtstamps->syststamp = timecompare_transform(&lp->compare, ns);
900
901 bfin_dump_hwtamp("RX", &shhwtstamps->hwtstamp, &shhwtstamps->syststamp, &lp->compare);
902}
903
904/*
905 * bfin_read_clock - read raw cycle counter (to be used by time counter)
906 */
907static cycle_t bfin_read_clock(const struct cyclecounter *tc)
908{
909 u64 stamp;
910
911 stamp = bfin_read_EMAC_PTP_TIMELO();
912 stamp |= (u64)bfin_read_EMAC_PTP_TIMEHI() << 32ULL;
913
914 return stamp;
915} 885}
916 886
917#define PTP_CLK 25000000
918
919static void bfin_mac_hwtstamp_init(struct net_device *netdev) 887static void bfin_mac_hwtstamp_init(struct net_device *netdev)
920{ 888{
921 struct bfin_mac_local *lp = netdev_priv(netdev); 889 struct bfin_mac_local *lp = netdev_priv(netdev);
922 u64 append; 890 u64 addend;
891 u32 input_clk, phc_clk;
923 892
924 /* Initialize hardware timer */ 893 /* Initialize hardware timer */
925 append = PTP_CLK * (1ULL << 32); 894 input_clk = get_sclk();
926 do_div(append, get_sclk()); 895 phc_clk = bfin_select_phc_clock(input_clk, &lp->shift);
927 bfin_write_EMAC_PTP_ADDEND((u32)append); 896 addend = phc_clk * (1ULL << 32);
928 897 do_div(addend, input_clk);
929 memset(&lp->cycles, 0, sizeof(lp->cycles)); 898 bfin_write_EMAC_PTP_ADDEND((u32)addend);
930 lp->cycles.read = bfin_read_clock; 899
931 lp->cycles.mask = CLOCKSOURCE_MASK(64); 900 lp->addend = addend;
932 lp->cycles.mult = 1000000000 / PTP_CLK;
933 lp->cycles.shift = 0;
934
935 /* Synchronize our NIC clock against system wall clock */
936 memset(&lp->compare, 0, sizeof(lp->compare));
937 lp->compare.source = &lp->clock;
938 lp->compare.target = ktime_get_real;
939 lp->compare.num_samples = 10;
940 901
941 /* Initialize hwstamp config */ 902 /* Initialize hwstamp config */
942 lp->stamp_cfg.rx_filter = HWTSTAMP_FILTER_NONE; 903 lp->stamp_cfg.rx_filter = HWTSTAMP_FILTER_NONE;
diff --git a/drivers/net/ethernet/adi/bfin_mac.h b/drivers/net/ethernet/adi/bfin_mac.h
index 960905c08223..57f042c3111c 100644
--- a/drivers/net/ethernet/adi/bfin_mac.h
+++ b/drivers/net/ethernet/adi/bfin_mac.h
@@ -11,8 +11,6 @@
11#define _BFIN_MAC_H_ 11#define _BFIN_MAC_H_
12 12
13#include <linux/net_tstamp.h> 13#include <linux/net_tstamp.h>
14#include <linux/clocksource.h>
15#include <linux/timecompare.h>
16#include <linux/timer.h> 14#include <linux/timer.h>
17#include <linux/etherdevice.h> 15#include <linux/etherdevice.h>
18#include <linux/bfin_mac.h> 16#include <linux/bfin_mac.h>
@@ -94,9 +92,8 @@ struct bfin_mac_local {
94 struct mii_bus *mii_bus; 92 struct mii_bus *mii_bus;
95 93
96#if defined(CONFIG_BFIN_MAC_USE_HWSTAMP) 94#if defined(CONFIG_BFIN_MAC_USE_HWSTAMP)
97 struct cyclecounter cycles; 95 u32 addend;
98 struct timecounter clock; 96 unsigned int shift;
99 struct timecompare compare;
100 struct hwtstamp_config stamp_cfg; 97 struct hwtstamp_config stamp_cfg;
101#endif 98#endif
102}; 99};