diff options
author | Hangbin Liu <liuhangbin@gmail.com> | 2019-03-19 22:23:33 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-03-20 14:04:41 -0400 |
commit | 254c0a2bfedb9e1baf38bd82ca86494d4bc1e0cb (patch) | |
tree | ec307e1e39ade071f3f1b3d14c46da6d1fcaad68 /drivers/net/macvlan.c | |
parent | 1bfe45f4ae81dc961b4bcb2ce6860c4ee1af621a (diff) |
macvlan: pass get_ts_info and SIOC[SG]HWTSTAMP ioctl to real device
Similiar to commit a6111d3c93d0 ("vlan: Pass SIOC[SG]HWTSTAMP ioctls to
real device") and commit 37dd9255b2f6 ("vlan: Pass ethtool get_ts_info
queries to real device."), add MACVlan HW ptp support.
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/macvlan.c')
-rw-r--r-- | drivers/net/macvlan.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 0c0f105657d3..4a6be8fab884 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/notifier.h> | 24 | #include <linux/notifier.h> |
25 | #include <linux/netdevice.h> | 25 | #include <linux/netdevice.h> |
26 | #include <linux/etherdevice.h> | 26 | #include <linux/etherdevice.h> |
27 | #include <linux/net_tstamp.h> | ||
27 | #include <linux/ethtool.h> | 28 | #include <linux/ethtool.h> |
28 | #include <linux/if_arp.h> | 29 | #include <linux/if_arp.h> |
29 | #include <linux/if_vlan.h> | 30 | #include <linux/if_vlan.h> |
@@ -34,6 +35,7 @@ | |||
34 | #include <net/rtnetlink.h> | 35 | #include <net/rtnetlink.h> |
35 | #include <net/xfrm.h> | 36 | #include <net/xfrm.h> |
36 | #include <linux/netpoll.h> | 37 | #include <linux/netpoll.h> |
38 | #include <linux/phy.h> | ||
37 | 39 | ||
38 | #define MACVLAN_HASH_BITS 8 | 40 | #define MACVLAN_HASH_BITS 8 |
39 | #define MACVLAN_HASH_SIZE (1<<MACVLAN_HASH_BITS) | 41 | #define MACVLAN_HASH_SIZE (1<<MACVLAN_HASH_BITS) |
@@ -822,6 +824,30 @@ static int macvlan_change_mtu(struct net_device *dev, int new_mtu) | |||
822 | return 0; | 824 | return 0; |
823 | } | 825 | } |
824 | 826 | ||
827 | static int macvlan_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
828 | { | ||
829 | struct net_device *real_dev = macvlan_dev_real_dev(dev); | ||
830 | const struct net_device_ops *ops = real_dev->netdev_ops; | ||
831 | struct ifreq ifrr; | ||
832 | int err = -EOPNOTSUPP; | ||
833 | |||
834 | strncpy(ifrr.ifr_name, real_dev->name, IFNAMSIZ); | ||
835 | ifrr.ifr_ifru = ifr->ifr_ifru; | ||
836 | |||
837 | switch (cmd) { | ||
838 | case SIOCSHWTSTAMP: | ||
839 | case SIOCGHWTSTAMP: | ||
840 | if (netif_device_present(real_dev) && ops->ndo_do_ioctl) | ||
841 | err = ops->ndo_do_ioctl(real_dev, &ifrr, cmd); | ||
842 | break; | ||
843 | } | ||
844 | |||
845 | if (!err) | ||
846 | ifr->ifr_ifru = ifrr.ifr_ifru; | ||
847 | |||
848 | return err; | ||
849 | } | ||
850 | |||
825 | /* | 851 | /* |
826 | * macvlan network devices have devices nesting below it and are a special | 852 | * macvlan network devices have devices nesting below it and are a special |
827 | * "super class" of normal network devices; split their locks off into a | 853 | * "super class" of normal network devices; split their locks off into a |
@@ -1020,6 +1046,26 @@ static int macvlan_ethtool_get_link_ksettings(struct net_device *dev, | |||
1020 | return __ethtool_get_link_ksettings(vlan->lowerdev, cmd); | 1046 | return __ethtool_get_link_ksettings(vlan->lowerdev, cmd); |
1021 | } | 1047 | } |
1022 | 1048 | ||
1049 | static int macvlan_ethtool_get_ts_info(struct net_device *dev, | ||
1050 | struct ethtool_ts_info *info) | ||
1051 | { | ||
1052 | struct net_device *real_dev = macvlan_dev_real_dev(dev); | ||
1053 | const struct ethtool_ops *ops = real_dev->ethtool_ops; | ||
1054 | struct phy_device *phydev = real_dev->phydev; | ||
1055 | |||
1056 | if (phydev && phydev->drv && phydev->drv->ts_info) { | ||
1057 | return phydev->drv->ts_info(phydev, info); | ||
1058 | } else if (ops->get_ts_info) { | ||
1059 | return ops->get_ts_info(real_dev, info); | ||
1060 | } else { | ||
1061 | info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | | ||
1062 | SOF_TIMESTAMPING_SOFTWARE; | ||
1063 | info->phc_index = -1; | ||
1064 | } | ||
1065 | |||
1066 | return 0; | ||
1067 | } | ||
1068 | |||
1023 | static netdev_features_t macvlan_fix_features(struct net_device *dev, | 1069 | static netdev_features_t macvlan_fix_features(struct net_device *dev, |
1024 | netdev_features_t features) | 1070 | netdev_features_t features) |
1025 | { | 1071 | { |
@@ -1094,6 +1140,7 @@ static const struct ethtool_ops macvlan_ethtool_ops = { | |||
1094 | .get_link = ethtool_op_get_link, | 1140 | .get_link = ethtool_op_get_link, |
1095 | .get_link_ksettings = macvlan_ethtool_get_link_ksettings, | 1141 | .get_link_ksettings = macvlan_ethtool_get_link_ksettings, |
1096 | .get_drvinfo = macvlan_ethtool_get_drvinfo, | 1142 | .get_drvinfo = macvlan_ethtool_get_drvinfo, |
1143 | .get_ts_info = macvlan_ethtool_get_ts_info, | ||
1097 | }; | 1144 | }; |
1098 | 1145 | ||
1099 | static const struct net_device_ops macvlan_netdev_ops = { | 1146 | static const struct net_device_ops macvlan_netdev_ops = { |
@@ -1103,6 +1150,7 @@ static const struct net_device_ops macvlan_netdev_ops = { | |||
1103 | .ndo_stop = macvlan_stop, | 1150 | .ndo_stop = macvlan_stop, |
1104 | .ndo_start_xmit = macvlan_start_xmit, | 1151 | .ndo_start_xmit = macvlan_start_xmit, |
1105 | .ndo_change_mtu = macvlan_change_mtu, | 1152 | .ndo_change_mtu = macvlan_change_mtu, |
1153 | .ndo_do_ioctl = macvlan_do_ioctl, | ||
1106 | .ndo_fix_features = macvlan_fix_features, | 1154 | .ndo_fix_features = macvlan_fix_features, |
1107 | .ndo_change_rx_flags = macvlan_change_rx_flags, | 1155 | .ndo_change_rx_flags = macvlan_change_rx_flags, |
1108 | .ndo_set_mac_address = macvlan_set_mac_address, | 1156 | .ndo_set_mac_address = macvlan_set_mac_address, |