Skip to content

Commit

Permalink
net: dsa: forward hardware timestamping ioctls to switch driver
Browse files Browse the repository at this point in the history
This patch adds support to the dsa slave network device so that
switch drivers can implement the SIOC[GS]HWTSTAMP ioctls and the
ethtool timestamp-info interface.

Signed-off-by: Brandon Streiff <brandon.streiff@ni.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Brandon Streiff authored and David S. Miller committed Feb 14, 2018
1 parent 4eb3be2 commit 0336369
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
15 changes: 15 additions & 0 deletions include/net/dsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/workqueue.h>
#include <linux/of.h>
#include <linux/ethtool.h>
#include <linux/net_tstamp.h>
#include <net/devlink.h>
#include <net/switchdev.h>

Expand Down Expand Up @@ -367,6 +368,12 @@ struct dsa_switch_ops {
int (*set_wol)(struct dsa_switch *ds, int port,
struct ethtool_wolinfo *w);

/*
* ethtool timestamp info
*/
int (*get_ts_info)(struct dsa_switch *ds, int port,
struct ethtool_ts_info *ts);

/*
* Suspend and resume
*/
Expand Down Expand Up @@ -469,6 +476,14 @@ struct dsa_switch_ops {
int port, struct net_device *br);
void (*crosschip_bridge_leave)(struct dsa_switch *ds, int sw_index,
int port, struct net_device *br);

/*
* PTP functionality
*/
int (*port_hwtstamp_get)(struct dsa_switch *ds, int port,
struct ifreq *ifr);
int (*port_hwtstamp_set)(struct dsa_switch *ds, int port,
struct ifreq *ifr);
};

struct dsa_switch_driver {
Expand Down
29 changes: 29 additions & 0 deletions net/dsa/slave.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,22 @@ dsa_slave_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,

static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->dp->ds;
int port = p->dp->index;

/* Pass through to switch driver if it supports timestamping */
switch (cmd) {
case SIOCGHWTSTAMP:
if (ds->ops->port_hwtstamp_get)
return ds->ops->port_hwtstamp_get(ds, port, ifr);
break;
case SIOCSHWTSTAMP:
if (ds->ops->port_hwtstamp_set)
return ds->ops->port_hwtstamp_set(ds, port, ifr);
break;
}

if (!dev->phydev)
return -ENODEV;

Expand Down Expand Up @@ -918,6 +934,18 @@ static int dsa_slave_set_rxnfc(struct net_device *dev,
return ds->ops->set_rxnfc(ds, dp->index, nfc);
}

static int dsa_slave_get_ts_info(struct net_device *dev,
struct ethtool_ts_info *ts)
{
struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->dp->ds;

if (!ds->ops->get_ts_info)
return -EOPNOTSUPP;

return ds->ops->get_ts_info(ds, p->dp->index, ts);
}

static const struct ethtool_ops dsa_slave_ethtool_ops = {
.get_drvinfo = dsa_slave_get_drvinfo,
.get_regs_len = dsa_slave_get_regs_len,
Expand All @@ -938,6 +966,7 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
.set_link_ksettings = phy_ethtool_set_link_ksettings,
.get_rxnfc = dsa_slave_get_rxnfc,
.set_rxnfc = dsa_slave_set_rxnfc,
.get_ts_info = dsa_slave_get_ts_info,
};

/* legacy way, bypassing the bridge *****************************************/
Expand Down

0 comments on commit 0336369

Please sign in to comment.