]> Pileus Git - ~andy/linux/commitdiff
ixp4xx_eth: Implement the SIOCGHWTSTAMP ioctl
authorBen Hutchings <bhutchings@solarflare.com>
Mon, 18 Nov 2013 23:28:30 +0000 (23:28 +0000)
committerBen Hutchings <bhutchings@solarflare.com>
Thu, 21 Nov 2013 17:17:48 +0000 (17:17 +0000)
This is untested.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
drivers/net/ethernet/xscale/ixp4xx_eth.c

index bcc224a83734cdb49c25993066babe904a42d32f..25283f17d82f34e093e8b41fe195f82ebb66db26 100644 (file)
@@ -373,7 +373,7 @@ static void ixp_tx_timestamp(struct port *port, struct sk_buff *skb)
        __raw_writel(TX_SNAPSHOT_LOCKED, &regs->channel[ch].ch_event);
 }
 
-static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+static int hwtstamp_set(struct net_device *netdev, struct ifreq *ifr)
 {
        struct hwtstamp_config cfg;
        struct ixp46x_ts_regs *regs;
@@ -417,6 +417,32 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
        return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
 }
 
+static int hwtstamp_get(struct net_device *netdev, struct ifreq *ifr)
+{
+       struct hwtstamp_config cfg;
+       struct port *port = netdev_priv(netdev);
+
+       cfg.flags = 0;
+       cfg.tx_type = port->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
+
+       switch (port->hwts_rx_en) {
+       case 0:
+               cfg.rx_filter = HWTSTAMP_FILTER_NONE;
+               break;
+       case PTP_SLAVE_MODE:
+               cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
+               break;
+       case PTP_MASTER_MODE:
+               cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               return -ERANGE;
+       }
+
+       return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
+}
+
 static int ixp4xx_mdio_cmd(struct mii_bus *bus, int phy_id, int location,
                           int write, u16 cmd)
 {
@@ -959,8 +985,12 @@ static int eth_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
        if (!netif_running(dev))
                return -EINVAL;
 
-       if (cpu_is_ixp46x() && cmd == SIOCSHWTSTAMP)
-               return hwtstamp_ioctl(dev, req, cmd);
+       if (cpu_is_ixp46x()) {
+               if (cmd == SIOCSHWTSTAMP)
+                       return hwtstamp_set(dev, req);
+               if (cmd == SIOCGHWTSTAMP)
+                       return hwtstamp_get(dev, req);
+       }
 
        return phy_mii_ioctl(port->phydev, req, cmd);
 }