diff options
author | Barry Song <barry.song@analog.com> | 2010-05-17 20:19:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-05-17 20:19:40 -0400 |
commit | fe92afedee23e1d91f0133360a24d2bf48270739 (patch) | |
tree | 20564c377f57af2a94644abcd18b953a6aba8c7c /drivers/net/bfin_mac.c | |
parent | ab6e3feba1f1bc3b9418b854da6f481408d243de (diff) |
netdev: bfin_mac: add support for IEEE 1588 PTP
Newer on-chip MAC peripherals support IEEE 1588 PTP in the hardware, so
extend the driver to support this functionality.
Signed-off-by: Barry Song <barry.song@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bfin_mac.c')
-rw-r--r-- | drivers/net/bfin_mac.c | 341 |
1 files changed, 340 insertions, 1 deletions
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 35548701899f..a173d8a40484 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/dma.h> | 33 | #include <asm/dma.h> |
34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
35 | 35 | ||
36 | #include <asm/div64.h> | ||
36 | #include <asm/dpmc.h> | 37 | #include <asm/dpmc.h> |
37 | #include <asm/blackfin.h> | 38 | #include <asm/blackfin.h> |
38 | #include <asm/cacheflush.h> | 39 | #include <asm/cacheflush.h> |
@@ -551,6 +552,309 @@ static int bfin_mac_set_mac_address(struct net_device *dev, void *p) | |||
551 | return 0; | 552 | return 0; |
552 | } | 553 | } |
553 | 554 | ||
555 | #ifdef CONFIG_BFIN_MAC_USE_HWSTAMP | ||
556 | #define bfin_mac_hwtstamp_is_none(cfg) ((cfg) == HWTSTAMP_FILTER_NONE) | ||
557 | |||
558 | static int bfin_mac_hwtstamp_ioctl(struct net_device *netdev, | ||
559 | struct ifreq *ifr, int cmd) | ||
560 | { | ||
561 | struct hwtstamp_config config; | ||
562 | struct bfin_mac_local *lp = netdev_priv(netdev); | ||
563 | u16 ptpctl; | ||
564 | u32 ptpfv1, ptpfv2, ptpfv3, ptpfoff; | ||
565 | |||
566 | if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) | ||
567 | return -EFAULT; | ||
568 | |||
569 | pr_debug("%s config flag:0x%x, tx_type:0x%x, rx_filter:0x%x\n", | ||
570 | __func__, config.flags, config.tx_type, config.rx_filter); | ||
571 | |||
572 | /* reserved for future extensions */ | ||
573 | if (config.flags) | ||
574 | return -EINVAL; | ||
575 | |||
576 | if ((config.tx_type != HWTSTAMP_TX_OFF) && | ||
577 | (config.tx_type != HWTSTAMP_TX_ON)) | ||
578 | return -ERANGE; | ||
579 | |||
580 | ptpctl = bfin_read_EMAC_PTP_CTL(); | ||
581 | |||
582 | switch (config.rx_filter) { | ||
583 | case HWTSTAMP_FILTER_NONE: | ||
584 | /* | ||
585 | * Dont allow any timestamping | ||
586 | */ | ||
587 | ptpfv3 = 0xFFFFFFFF; | ||
588 | bfin_write_EMAC_PTP_FV3(ptpfv3); | ||
589 | break; | ||
590 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | ||
591 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | ||
592 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | ||
593 | /* | ||
594 | * Clear the five comparison mask bits (bits[12:8]) in EMAC_PTP_CTL) | ||
595 | * to enable all the field matches. | ||
596 | */ | ||
597 | ptpctl &= ~0x1F00; | ||
598 | bfin_write_EMAC_PTP_CTL(ptpctl); | ||
599 | /* | ||
600 | * Keep the default values of the EMAC_PTP_FOFF register. | ||
601 | */ | ||
602 | ptpfoff = 0x4A24170C; | ||
603 | bfin_write_EMAC_PTP_FOFF(ptpfoff); | ||
604 | /* | ||
605 | * Keep the default values of the EMAC_PTP_FV1 and EMAC_PTP_FV2 | ||
606 | * registers. | ||
607 | */ | ||
608 | ptpfv1 = 0x11040800; | ||
609 | bfin_write_EMAC_PTP_FV1(ptpfv1); | ||
610 | ptpfv2 = 0x0140013F; | ||
611 | bfin_write_EMAC_PTP_FV2(ptpfv2); | ||
612 | /* | ||
613 | * The default value (0xFFFC) allows the timestamping of both | ||
614 | * received Sync messages and Delay_Req messages. | ||
615 | */ | ||
616 | ptpfv3 = 0xFFFFFFFC; | ||
617 | bfin_write_EMAC_PTP_FV3(ptpfv3); | ||
618 | |||
619 | config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; | ||
620 | break; | ||
621 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | ||
622 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | ||
623 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: | ||
624 | /* Clear all five comparison mask bits (bits[12:8]) in the | ||
625 | * EMAC_PTP_CTL register to enable all the field matches. | ||
626 | */ | ||
627 | ptpctl &= ~0x1F00; | ||
628 | bfin_write_EMAC_PTP_CTL(ptpctl); | ||
629 | /* | ||
630 | * Keep the default values of the EMAC_PTP_FOFF register, except set | ||
631 | * the PTPCOF field to 0x2A. | ||
632 | */ | ||
633 | ptpfoff = 0x2A24170C; | ||
634 | bfin_write_EMAC_PTP_FOFF(ptpfoff); | ||
635 | /* | ||
636 | * Keep the default values of the EMAC_PTP_FV1 and EMAC_PTP_FV2 | ||
637 | * registers. | ||
638 | */ | ||
639 | ptpfv1 = 0x11040800; | ||
640 | bfin_write_EMAC_PTP_FV1(ptpfv1); | ||
641 | ptpfv2 = 0x0140013F; | ||
642 | bfin_write_EMAC_PTP_FV2(ptpfv2); | ||
643 | /* | ||
644 | * To allow the timestamping of Pdelay_Req and Pdelay_Resp, set | ||
645 | * the value to 0xFFF0. | ||
646 | */ | ||
647 | ptpfv3 = 0xFFFFFFF0; | ||
648 | bfin_write_EMAC_PTP_FV3(ptpfv3); | ||
649 | |||
650 | config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; | ||
651 | break; | ||
652 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | ||
653 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | ||
654 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | ||
655 | /* | ||
656 | * Clear bits 8 and 12 of the EMAC_PTP_CTL register to enable only the | ||
657 | * EFTM and PTPCM field comparison. | ||
658 | */ | ||
659 | ptpctl &= ~0x1100; | ||
660 | bfin_write_EMAC_PTP_CTL(ptpctl); | ||
661 | /* | ||
662 | * Keep the default values of all the fields of the EMAC_PTP_FOFF | ||
663 | * register, except set the PTPCOF field to 0x0E. | ||
664 | */ | ||
665 | ptpfoff = 0x0E24170C; | ||
666 | bfin_write_EMAC_PTP_FOFF(ptpfoff); | ||
667 | /* | ||
668 | * Program bits [15:0] of the EMAC_PTP_FV1 register to 0x88F7, which | ||
669 | * corresponds to PTP messages on the MAC layer. | ||
670 | */ | ||
671 | ptpfv1 = 0x110488F7; | ||
672 | bfin_write_EMAC_PTP_FV1(ptpfv1); | ||
673 | ptpfv2 = 0x0140013F; | ||
674 | bfin_write_EMAC_PTP_FV2(ptpfv2); | ||
675 | /* | ||
676 | * To allow the timestamping of Pdelay_Req and Pdelay_Resp | ||
677 | * messages, set the value to 0xFFF0. | ||
678 | */ | ||
679 | ptpfv3 = 0xFFFFFFF0; | ||
680 | bfin_write_EMAC_PTP_FV3(ptpfv3); | ||
681 | |||
682 | config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; | ||
683 | break; | ||
684 | default: | ||
685 | return -ERANGE; | ||
686 | } | ||
687 | |||
688 | if (config.tx_type == HWTSTAMP_TX_OFF && | ||
689 | bfin_mac_hwtstamp_is_none(config.rx_filter)) { | ||
690 | ptpctl &= ~PTP_EN; | ||
691 | bfin_write_EMAC_PTP_CTL(ptpctl); | ||
692 | |||
693 | SSYNC(); | ||
694 | } else { | ||
695 | ptpctl |= PTP_EN; | ||
696 | bfin_write_EMAC_PTP_CTL(ptpctl); | ||
697 | |||
698 | /* | ||
699 | * clear any existing timestamp | ||
700 | */ | ||
701 | bfin_read_EMAC_PTP_RXSNAPLO(); | ||
702 | bfin_read_EMAC_PTP_RXSNAPHI(); | ||
703 | |||
704 | bfin_read_EMAC_PTP_TXSNAPLO(); | ||
705 | bfin_read_EMAC_PTP_TXSNAPHI(); | ||
706 | |||
707 | /* | ||
708 | * Set registers so that rollover occurs soon to test this. | ||
709 | */ | ||
710 | bfin_write_EMAC_PTP_TIMELO(0x00000000); | ||
711 | bfin_write_EMAC_PTP_TIMEHI(0xFF800000); | ||
712 | |||
713 | SSYNC(); | ||
714 | |||
715 | lp->compare.last_update = 0; | ||
716 | timecounter_init(&lp->clock, | ||
717 | &lp->cycles, | ||
718 | ktime_to_ns(ktime_get_real())); | ||
719 | timecompare_update(&lp->compare, 0); | ||
720 | } | ||
721 | |||
722 | lp->stamp_cfg = config; | ||
723 | return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? | ||
724 | -EFAULT : 0; | ||
725 | } | ||
726 | |||
727 | static void bfin_dump_hwtamp(char *s, ktime_t *hw, ktime_t *ts, struct timecompare *cmp) | ||
728 | { | ||
729 | ktime_t sys = ktime_get_real(); | ||
730 | |||
731 | pr_debug("%s %s hardware:%d,%d transform system:%d,%d system:%d,%d, cmp:%lld, %lld\n", | ||
732 | __func__, s, hw->tv.sec, hw->tv.nsec, ts->tv.sec, ts->tv.nsec, sys.tv.sec, | ||
733 | sys.tv.nsec, cmp->offset, cmp->skew); | ||
734 | } | ||
735 | |||
736 | static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb) | ||
737 | { | ||
738 | struct bfin_mac_local *lp = netdev_priv(netdev); | ||
739 | union skb_shared_tx *shtx = skb_tx(skb); | ||
740 | |||
741 | if (shtx->hardware) { | ||
742 | int timeout_cnt = MAX_TIMEOUT_CNT; | ||
743 | |||
744 | /* When doing time stamping, keep the connection to the socket | ||
745 | * a while longer | ||
746 | */ | ||
747 | shtx->in_progress = 1; | ||
748 | |||
749 | /* | ||
750 | * The timestamping is done at the EMAC module's MII/RMII interface | ||
751 | * when the module sees the Start of Frame of an event message packet. This | ||
752 | * interface is the closest possible place to the physical Ethernet transmission | ||
753 | * medium, providing the best timing accuracy. | ||
754 | */ | ||
755 | while ((!(bfin_read_EMAC_PTP_ISTAT() & TXTL)) && (--timeout_cnt)) | ||
756 | udelay(1); | ||
757 | if (timeout_cnt == 0) | ||
758 | printk(KERN_ERR DRV_NAME | ||
759 | ": fails to timestamp the TX packet\n"); | ||
760 | else { | ||
761 | struct skb_shared_hwtstamps shhwtstamps; | ||
762 | u64 ns; | ||
763 | u64 regval; | ||
764 | |||
765 | regval = bfin_read_EMAC_PTP_TXSNAPLO(); | ||
766 | regval |= (u64)bfin_read_EMAC_PTP_TXSNAPHI() << 32; | ||
767 | memset(&shhwtstamps, 0, sizeof(shhwtstamps)); | ||
768 | ns = timecounter_cyc2time(&lp->clock, | ||
769 | regval); | ||
770 | timecompare_update(&lp->compare, ns); | ||
771 | shhwtstamps.hwtstamp = ns_to_ktime(ns); | ||
772 | shhwtstamps.syststamp = | ||
773 | timecompare_transform(&lp->compare, ns); | ||
774 | skb_tstamp_tx(skb, &shhwtstamps); | ||
775 | |||
776 | bfin_dump_hwtamp("TX", &shhwtstamps.hwtstamp, &shhwtstamps.syststamp, &lp->compare); | ||
777 | } | ||
778 | } | ||
779 | } | ||
780 | |||
781 | static void bfin_rx_hwtstamp(struct net_device *netdev, struct sk_buff *skb) | ||
782 | { | ||
783 | struct bfin_mac_local *lp = netdev_priv(netdev); | ||
784 | u32 valid; | ||
785 | u64 regval, ns; | ||
786 | struct skb_shared_hwtstamps *shhwtstamps; | ||
787 | |||
788 | if (bfin_mac_hwtstamp_is_none(lp->stamp_cfg.rx_filter)) | ||
789 | return; | ||
790 | |||
791 | valid = bfin_read_EMAC_PTP_ISTAT() & RXEL; | ||
792 | if (!valid) | ||
793 | return; | ||
794 | |||
795 | shhwtstamps = skb_hwtstamps(skb); | ||
796 | |||
797 | regval = bfin_read_EMAC_PTP_RXSNAPLO(); | ||
798 | regval |= (u64)bfin_read_EMAC_PTP_RXSNAPHI() << 32; | ||
799 | ns = timecounter_cyc2time(&lp->clock, regval); | ||
800 | timecompare_update(&lp->compare, ns); | ||
801 | memset(shhwtstamps, 0, sizeof(*shhwtstamps)); | ||
802 | shhwtstamps->hwtstamp = ns_to_ktime(ns); | ||
803 | shhwtstamps->syststamp = timecompare_transform(&lp->compare, ns); | ||
804 | |||
805 | bfin_dump_hwtamp("RX", &shhwtstamps->hwtstamp, &shhwtstamps->syststamp, &lp->compare); | ||
806 | } | ||
807 | |||
808 | /* | ||
809 | * bfin_read_clock - read raw cycle counter (to be used by time counter) | ||
810 | */ | ||
811 | static cycle_t bfin_read_clock(const struct cyclecounter *tc) | ||
812 | { | ||
813 | u64 stamp; | ||
814 | |||
815 | stamp = bfin_read_EMAC_PTP_TIMELO(); | ||
816 | stamp |= (u64)bfin_read_EMAC_PTP_TIMEHI() << 32ULL; | ||
817 | |||
818 | return stamp; | ||
819 | } | ||
820 | |||
821 | #define PTP_CLK 25000000 | ||
822 | |||
823 | static void bfin_mac_hwtstamp_init(struct net_device *netdev) | ||
824 | { | ||
825 | struct bfin_mac_local *lp = netdev_priv(netdev); | ||
826 | u64 append; | ||
827 | |||
828 | /* Initialize hardware timer */ | ||
829 | append = PTP_CLK * (1ULL << 32); | ||
830 | do_div(append, get_sclk()); | ||
831 | bfin_write_EMAC_PTP_ADDEND((u32)append); | ||
832 | |||
833 | memset(&lp->cycles, 0, sizeof(lp->cycles)); | ||
834 | lp->cycles.read = bfin_read_clock; | ||
835 | lp->cycles.mask = CLOCKSOURCE_MASK(64); | ||
836 | lp->cycles.mult = 1000000000 / PTP_CLK; | ||
837 | lp->cycles.shift = 0; | ||
838 | |||
839 | /* Synchronize our NIC clock against system wall clock */ | ||
840 | memset(&lp->compare, 0, sizeof(lp->compare)); | ||
841 | lp->compare.source = &lp->clock; | ||
842 | lp->compare.target = ktime_get_real; | ||
843 | lp->compare.num_samples = 10; | ||
844 | |||
845 | /* Initialize hwstamp config */ | ||
846 | lp->stamp_cfg.rx_filter = HWTSTAMP_FILTER_NONE; | ||
847 | lp->stamp_cfg.tx_type = HWTSTAMP_TX_OFF; | ||
848 | } | ||
849 | |||
850 | #else | ||
851 | # define bfin_mac_hwtstamp_is_none(cfg) 0 | ||
852 | # define bfin_mac_hwtstamp_init(dev) | ||
853 | # define bfin_mac_hwtstamp_ioctl(dev, ifr, cmd) (-EOPNOTSUPP) | ||
854 | # define bfin_rx_hwtstamp(dev, skb) | ||
855 | # define bfin_tx_hwtstamp(dev, skb) | ||
856 | #endif | ||
857 | |||
554 | static void adjust_tx_list(void) | 858 | static void adjust_tx_list(void) |
555 | { | 859 | { |
556 | int timeout_cnt = MAX_TIMEOUT_CNT; | 860 | int timeout_cnt = MAX_TIMEOUT_CNT; |
@@ -608,18 +912,32 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb, | |||
608 | { | 912 | { |
609 | u16 *data; | 913 | u16 *data; |
610 | u32 data_align = (unsigned long)(skb->data) & 0x3; | 914 | u32 data_align = (unsigned long)(skb->data) & 0x3; |
915 | union skb_shared_tx *shtx = skb_tx(skb); | ||
916 | |||
611 | current_tx_ptr->skb = skb; | 917 | current_tx_ptr->skb = skb; |
612 | 918 | ||
613 | if (data_align == 0x2) { | 919 | if (data_align == 0x2) { |
614 | /* move skb->data to current_tx_ptr payload */ | 920 | /* move skb->data to current_tx_ptr payload */ |
615 | data = (u16 *)(skb->data) - 1; | 921 | data = (u16 *)(skb->data) - 1; |
616 | *data = (u16)(skb->len); | 922 | *data = (u16)(skb->len); |
923 | /* | ||
924 | * When transmitting an Ethernet packet, the PTP_TSYNC module requires | ||
925 | * a DMA_Length_Word field associated with the packet. The lower 12 bits | ||
926 | * of this field are the length of the packet payload in bytes and the higher | ||
927 | * 4 bits are the timestamping enable field. | ||
928 | */ | ||
929 | if (shtx->hardware) | ||
930 | *data |= 0x1000; | ||
931 | |||
617 | current_tx_ptr->desc_a.start_addr = (u32)data; | 932 | current_tx_ptr->desc_a.start_addr = (u32)data; |
618 | /* this is important! */ | 933 | /* this is important! */ |
619 | blackfin_dcache_flush_range((u32)data, | 934 | blackfin_dcache_flush_range((u32)data, |
620 | (u32)((u8 *)data + skb->len + 4)); | 935 | (u32)((u8 *)data + skb->len + 4)); |
621 | } else { | 936 | } else { |
622 | *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len); | 937 | *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len); |
938 | /* enable timestamping for the sent packet */ | ||
939 | if (shtx->hardware) | ||
940 | *((u16 *)(current_tx_ptr->packet)) |= 0x1000; | ||
623 | memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data, | 941 | memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data, |
624 | skb->len); | 942 | skb->len); |
625 | current_tx_ptr->desc_a.start_addr = | 943 | current_tx_ptr->desc_a.start_addr = |
@@ -653,6 +971,9 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb, | |||
653 | 971 | ||
654 | out: | 972 | out: |
655 | adjust_tx_list(); | 973 | adjust_tx_list(); |
974 | |||
975 | bfin_tx_hwtstamp(dev, skb); | ||
976 | |||
656 | current_tx_ptr = current_tx_ptr->next; | 977 | current_tx_ptr = current_tx_ptr->next; |
657 | dev->stats.tx_packets++; | 978 | dev->stats.tx_packets++; |
658 | dev->stats.tx_bytes += (skb->len); | 979 | dev->stats.tx_bytes += (skb->len); |
@@ -663,9 +984,11 @@ static void bfin_mac_rx(struct net_device *dev) | |||
663 | { | 984 | { |
664 | struct sk_buff *skb, *new_skb; | 985 | struct sk_buff *skb, *new_skb; |
665 | unsigned short len; | 986 | unsigned short len; |
987 | struct bfin_mac_local *lp __maybe_unused = netdev_priv(dev); | ||
666 | 988 | ||
667 | /* allocate a new skb for next time receive */ | 989 | /* allocate a new skb for next time receive */ |
668 | skb = current_rx_ptr->skb; | 990 | skb = current_rx_ptr->skb; |
991 | |||
669 | new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN); | 992 | new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN); |
670 | if (!new_skb) { | 993 | if (!new_skb) { |
671 | printk(KERN_NOTICE DRV_NAME | 994 | printk(KERN_NOTICE DRV_NAME |
@@ -690,6 +1013,9 @@ static void bfin_mac_rx(struct net_device *dev) | |||
690 | (unsigned long)skb->tail); | 1013 | (unsigned long)skb->tail); |
691 | 1014 | ||
692 | skb->protocol = eth_type_trans(skb, dev); | 1015 | skb->protocol = eth_type_trans(skb, dev); |
1016 | |||
1017 | bfin_rx_hwtstamp(dev, skb); | ||
1018 | |||
693 | #if defined(BFIN_MAC_CSUM_OFFLOAD) | 1019 | #if defined(BFIN_MAC_CSUM_OFFLOAD) |
694 | skb->csum = current_rx_ptr->status.ip_payload_csum; | 1020 | skb->csum = current_rx_ptr->status.ip_payload_csum; |
695 | skb->ip_summed = CHECKSUM_COMPLETE; | 1021 | skb->ip_summed = CHECKSUM_COMPLETE; |
@@ -871,6 +1197,16 @@ static void bfin_mac_set_multicast_list(struct net_device *dev) | |||
871 | } | 1197 | } |
872 | } | 1198 | } |
873 | 1199 | ||
1200 | static int bfin_mac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | ||
1201 | { | ||
1202 | switch (cmd) { | ||
1203 | case SIOCSHWTSTAMP: | ||
1204 | return bfin_mac_hwtstamp_ioctl(netdev, ifr, cmd); | ||
1205 | default: | ||
1206 | return -EOPNOTSUPP; | ||
1207 | } | ||
1208 | } | ||
1209 | |||
874 | /* | 1210 | /* |
875 | * this puts the device in an inactive state | 1211 | * this puts the device in an inactive state |
876 | */ | 1212 | */ |
@@ -955,6 +1291,7 @@ static const struct net_device_ops bfin_mac_netdev_ops = { | |||
955 | .ndo_set_mac_address = bfin_mac_set_mac_address, | 1291 | .ndo_set_mac_address = bfin_mac_set_mac_address, |
956 | .ndo_tx_timeout = bfin_mac_timeout, | 1292 | .ndo_tx_timeout = bfin_mac_timeout, |
957 | .ndo_set_multicast_list = bfin_mac_set_multicast_list, | 1293 | .ndo_set_multicast_list = bfin_mac_set_multicast_list, |
1294 | .ndo_do_ioctl = bfin_mac_ioctl, | ||
958 | .ndo_validate_addr = eth_validate_addr, | 1295 | .ndo_validate_addr = eth_validate_addr, |
959 | .ndo_change_mtu = eth_change_mtu, | 1296 | .ndo_change_mtu = eth_change_mtu, |
960 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1297 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -1046,6 +1383,8 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) | |||
1046 | goto out_err_reg_ndev; | 1383 | goto out_err_reg_ndev; |
1047 | } | 1384 | } |
1048 | 1385 | ||
1386 | bfin_mac_hwtstamp_init(ndev); | ||
1387 | |||
1049 | /* now, print out the card info, in a short format.. */ | 1388 | /* now, print out the card info, in a short format.. */ |
1050 | dev_info(&pdev->dev, "%s, Version %s\n", DRV_DESC, DRV_VERSION); | 1389 | dev_info(&pdev->dev, "%s, Version %s\n", DRV_DESC, DRV_VERSION); |
1051 | 1390 | ||