@@ -1787,4 +1787,6 @@ are netlink only.
n/a ``ETHTOOL_MSG_PHC_VCLOCKS_GET``
n/a ``ETHTOOL_MSG_MODULE_GET``
n/a ``ETHTOOL_MSG_MODULE_SET``
+ ``ETHTOOL_LIST_PTP`` n/a
+ ``ETHTOOL_GET_PTP`` n/a
=================================== =====================================
@@ -1629,6 +1629,8 @@ enum ethtool_fec_config_bits {
#define ETHTOOL_PHY_STUNABLE 0x0000004f /* Set PHY tunable configuration */
#define ETHTOOL_GFECPARAM 0x00000050 /* Get FEC settings */
#define ETHTOOL_SFECPARAM 0x00000051 /* Set FEC settings */
+#define ETHTOOL_LIST_PTP 0x00000052 /* List PTP providers */
+#define ETHTOOL_GET_PTP 0x00000053 /* Get current PTP provider */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
@@ -13,6 +13,12 @@
#include <linux/types.h>
#include <linux/socket.h> /* for SO_TIMESTAMPING */
+/* Hardware layer of the SO_TIMESTAMPING provider */
+enum timestamping_layer {
+ MAC_TIMESTAMPING = (1<<0),
+ PHY_TIMESTAMPING = (1<<1),
+};
+
/* SO_TIMESTAMPING flags */
enum {
SOF_TIMESTAMPING_TX_HARDWARE = (1<<0),
@@ -2319,6 +2319,48 @@ static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr)
return 0;
}
+static int ethtool_list_ptp(struct net_device *dev, void __user *useraddr)
+{
+ struct ethtool_value edata = {
+ .cmd = ETHTOOL_LIST_PTP,
+ .data = 0,
+ };
+ struct phy_device *phydev = dev->phydev;
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+
+ if (phy_has_tsinfo(phydev))
+ edata.data = PHY_TIMESTAMPING;
+ if (ops->get_ts_info)
+ edata.data |= MAC_TIMESTAMPING;
+
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int ethtool_get_ptp(struct net_device *dev, void __user *useraddr)
+{
+ struct ethtool_value edata = {
+ .cmd = ETHTOOL_GET_PTP,
+ .data = 0,
+ };
+ struct phy_device *phydev = dev->phydev;
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+
+ if (phy_has_tsinfo(phydev))
+ edata.data = PHY_TIMESTAMPING;
+ else if (ops->get_ts_info)
+ edata.data = MAC_TIMESTAMPING;
+ else
+ return -EOPNOTSUPP;
+
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+
+ return 0;
+}
+
int ethtool_get_module_info_call(struct net_device *dev,
struct ethtool_modinfo *modinfo)
{
@@ -2770,6 +2812,8 @@ __dev_ethtool(struct net *net, struct ifreq *ifr, void __user *useraddr,
case ETHTOOL_PHY_GTUNABLE:
case ETHTOOL_GLINKSETTINGS:
case ETHTOOL_GFECPARAM:
+ case ETHTOOL_LIST_PTP:
+ case ETHTOOL_GET_PTP:
break;
default:
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
@@ -2997,6 +3041,12 @@ __dev_ethtool(struct net *net, struct ifreq *ifr, void __user *useraddr,
case ETHTOOL_SFECPARAM:
rc = ethtool_set_fecparam(dev, useraddr);
break;
+ case ETHTOOL_LIST_PTP:
+ rc = ethtool_list_ptp(dev, useraddr);
+ break;
+ case ETHTOOL_GET_PTP:
+ rc = ethtool_get_ptp(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}