diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/ethtool.c | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 6d6d7d25caaa..a723b1321691 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/ethtool.h> | 18 | #include <linux/ethtool.h> |
19 | #include <linux/netdevice.h> | 19 | #include <linux/netdevice.h> |
20 | #include <linux/net_tstamp.h> | ||
21 | #include <linux/phy.h> | ||
20 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
21 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
22 | #include <linux/vmalloc.h> | 24 | #include <linux/vmalloc.h> |
@@ -1278,6 +1280,40 @@ out: | |||
1278 | return ret; | 1280 | return ret; |
1279 | } | 1281 | } |
1280 | 1282 | ||
1283 | static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr) | ||
1284 | { | ||
1285 | int err = 0; | ||
1286 | struct ethtool_ts_info info; | ||
1287 | const struct ethtool_ops *ops = dev->ethtool_ops; | ||
1288 | struct phy_device *phydev = dev->phydev; | ||
1289 | |||
1290 | memset(&info, 0, sizeof(info)); | ||
1291 | info.cmd = ETHTOOL_GET_TS_INFO; | ||
1292 | |||
1293 | if (phydev && phydev->drv && phydev->drv->ts_info) { | ||
1294 | |||
1295 | err = phydev->drv->ts_info(phydev, &info); | ||
1296 | |||
1297 | } else if (dev->ethtool_ops && dev->ethtool_ops->get_ts_info) { | ||
1298 | |||
1299 | err = ops->get_ts_info(dev, &info); | ||
1300 | |||
1301 | } else { | ||
1302 | info.so_timestamping = | ||
1303 | SOF_TIMESTAMPING_RX_SOFTWARE | | ||
1304 | SOF_TIMESTAMPING_SOFTWARE; | ||
1305 | info.phc_index = -1; | ||
1306 | } | ||
1307 | |||
1308 | if (err) | ||
1309 | return err; | ||
1310 | |||
1311 | if (copy_to_user(useraddr, &info, sizeof(info))) | ||
1312 | err = -EFAULT; | ||
1313 | |||
1314 | return err; | ||
1315 | } | ||
1316 | |||
1281 | /* The main entry point in this file. Called from net/core/dev.c */ | 1317 | /* The main entry point in this file. Called from net/core/dev.c */ |
1282 | 1318 | ||
1283 | int dev_ethtool(struct net *net, struct ifreq *ifr) | 1319 | int dev_ethtool(struct net *net, struct ifreq *ifr) |
@@ -1295,11 +1331,13 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1295 | return -EFAULT; | 1331 | return -EFAULT; |
1296 | 1332 | ||
1297 | if (!dev->ethtool_ops) { | 1333 | if (!dev->ethtool_ops) { |
1298 | /* ETHTOOL_GDRVINFO does not require any driver support. | 1334 | /* A few commands do not require any driver support, |
1299 | * It is also unprivileged and does not change anything, | 1335 | * are unprivileged, and do not change anything, so we |
1300 | * so we can take a shortcut to it. */ | 1336 | * can take a shortcut to them. */ |
1301 | if (ethcmd == ETHTOOL_GDRVINFO) | 1337 | if (ethcmd == ETHTOOL_GDRVINFO) |
1302 | return ethtool_get_drvinfo(dev, useraddr); | 1338 | return ethtool_get_drvinfo(dev, useraddr); |
1339 | else if (ethcmd == ETHTOOL_GET_TS_INFO) | ||
1340 | return ethtool_get_ts_info(dev, useraddr); | ||
1303 | else | 1341 | else |
1304 | return -EOPNOTSUPP; | 1342 | return -EOPNOTSUPP; |
1305 | } | 1343 | } |
@@ -1330,6 +1368,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1330 | case ETHTOOL_GRXCLSRULE: | 1368 | case ETHTOOL_GRXCLSRULE: |
1331 | case ETHTOOL_GRXCLSRLALL: | 1369 | case ETHTOOL_GRXCLSRLALL: |
1332 | case ETHTOOL_GFEATURES: | 1370 | case ETHTOOL_GFEATURES: |
1371 | case ETHTOOL_GET_TS_INFO: | ||
1333 | break; | 1372 | break; |
1334 | default: | 1373 | default: |
1335 | if (!capable(CAP_NET_ADMIN)) | 1374 | if (!capable(CAP_NET_ADMIN)) |
@@ -1496,6 +1535,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1496 | case ETHTOOL_GET_DUMP_DATA: | 1535 | case ETHTOOL_GET_DUMP_DATA: |
1497 | rc = ethtool_get_dump_data(dev, useraddr); | 1536 | rc = ethtool_get_dump_data(dev, useraddr); |
1498 | break; | 1537 | break; |
1538 | case ETHTOOL_GET_TS_INFO: | ||
1539 | rc = ethtool_get_ts_info(dev, useraddr); | ||
1540 | break; | ||
1499 | default: | 1541 | default: |
1500 | rc = -EOPNOTSUPP; | 1542 | rc = -EOPNOTSUPP; |
1501 | } | 1543 | } |