diff options
author | Matt Carlson <mcarlson@broadcom.com> | 2012-12-03 14:36:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-12-04 12:58:50 -0500 |
commit | 0a633ac2284a92f0c65972bd8019146ed7d66159 (patch) | |
tree | 71493fca1b2525ab87143b9a76e18ed526dc8d14 /drivers | |
parent | 7d41e49ac2a10a269bb50b4b019d75eed16fd55d (diff) |
tg3: PTP - Add the hardware timestamp ioctl
This patch implements the SIOCSHWTSTAMP ioctl as described in
Documentation/networking/timestamping.txt
[Removed HWTSTAMP_FILTER_ALL handling by returning -ERANGE based on input
from Richard Cochran.]
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')
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 7b80031cd2bf..a718a382b4bf 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -12760,6 +12760,96 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | |||
12760 | 12760 | ||
12761 | } | 12761 | } |
12762 | 12762 | ||
12763 | static int tg3_hwtstamp_ioctl(struct net_device *dev, | ||
12764 | struct ifreq *ifr, int cmd) | ||
12765 | { | ||
12766 | struct tg3 *tp = netdev_priv(dev); | ||
12767 | struct hwtstamp_config stmpconf; | ||
12768 | |||
12769 | if (!tg3_flag(tp, PTP_CAPABLE)) | ||
12770 | return -EINVAL; | ||
12771 | |||
12772 | if (copy_from_user(&stmpconf, ifr->ifr_data, sizeof(stmpconf))) | ||
12773 | return -EFAULT; | ||
12774 | |||
12775 | if (stmpconf.flags) | ||
12776 | return -EINVAL; | ||
12777 | |||
12778 | switch (stmpconf.tx_type) { | ||
12779 | case HWTSTAMP_TX_ON: | ||
12780 | tg3_flag_set(tp, TX_TSTAMP_EN); | ||
12781 | break; | ||
12782 | case HWTSTAMP_TX_OFF: | ||
12783 | tg3_flag_clear(tp, TX_TSTAMP_EN); | ||
12784 | break; | ||
12785 | default: | ||
12786 | return -ERANGE; | ||
12787 | } | ||
12788 | |||
12789 | switch (stmpconf.rx_filter) { | ||
12790 | case HWTSTAMP_FILTER_NONE: | ||
12791 | tp->rxptpctl = 0; | ||
12792 | break; | ||
12793 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | ||
12794 | tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V1_EN | | ||
12795 | TG3_RX_PTP_CTL_ALL_V1_EVENTS; | ||
12796 | break; | ||
12797 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | ||
12798 | tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V1_EN | | ||
12799 | TG3_RX_PTP_CTL_SYNC_EVNT; | ||
12800 | break; | ||
12801 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | ||
12802 | tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V1_EN | | ||
12803 | TG3_RX_PTP_CTL_DELAY_REQ; | ||
12804 | break; | ||
12805 | case HWTSTAMP_FILTER_PTP_V2_EVENT: | ||
12806 | tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_EN | | ||
12807 | TG3_RX_PTP_CTL_ALL_V2_EVENTS; | ||
12808 | break; | ||
12809 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | ||
12810 | tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | | ||
12811 | TG3_RX_PTP_CTL_ALL_V2_EVENTS; | ||
12812 | break; | ||
12813 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | ||
12814 | tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | | ||
12815 | TG3_RX_PTP_CTL_ALL_V2_EVENTS; | ||
12816 | break; | ||
12817 | case HWTSTAMP_FILTER_PTP_V2_SYNC: | ||
12818 | tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_EN | | ||
12819 | TG3_RX_PTP_CTL_SYNC_EVNT; | ||
12820 | break; | ||
12821 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | ||
12822 | tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | | ||
12823 | TG3_RX_PTP_CTL_SYNC_EVNT; | ||
12824 | break; | ||
12825 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | ||
12826 | tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | | ||
12827 | TG3_RX_PTP_CTL_SYNC_EVNT; | ||
12828 | break; | ||
12829 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: | ||
12830 | tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_EN | | ||
12831 | TG3_RX_PTP_CTL_DELAY_REQ; | ||
12832 | break; | ||
12833 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | ||
12834 | tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | | ||
12835 | TG3_RX_PTP_CTL_DELAY_REQ; | ||
12836 | break; | ||
12837 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | ||
12838 | tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | | ||
12839 | TG3_RX_PTP_CTL_DELAY_REQ; | ||
12840 | break; | ||
12841 | default: | ||
12842 | return -ERANGE; | ||
12843 | } | ||
12844 | |||
12845 | if (netif_running(dev) && tp->rxptpctl) | ||
12846 | tw32(TG3_RX_PTP_CTL, | ||
12847 | tp->rxptpctl | TG3_RX_PTP_CTL_HWTS_INTERLOCK); | ||
12848 | |||
12849 | return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ? | ||
12850 | -EFAULT : 0; | ||
12851 | } | ||
12852 | |||
12763 | static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 12853 | static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
12764 | { | 12854 | { |
12765 | struct mii_ioctl_data *data = if_mii(ifr); | 12855 | struct mii_ioctl_data *data = if_mii(ifr); |
@@ -12810,6 +12900,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
12810 | 12900 | ||
12811 | return err; | 12901 | return err; |
12812 | 12902 | ||
12903 | case SIOCSHWTSTAMP: | ||
12904 | return tg3_hwtstamp_ioctl(dev, ifr, cmd); | ||
12905 | |||
12813 | default: | 12906 | default: |
12814 | /* do nothing */ | 12907 | /* do nothing */ |
12815 | break; | 12908 | break; |