ixgbe: implement SIOCGHWTSTAMP ioctl
authorJacob Keller <jacob.e.keller@intel.com>
Fri, 28 Feb 2014 23:48:58 +0000 (15:48 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 3 Mar 2014 00:06:44 +0000 (19:06 -0500)
This patch adds support for the new SIOCGHWTSTAMP ioctl, which enables a
process to determine the current timestamp configuration. In order to
implement this, store a copy of the timestamp configuration. In
addition, we can remove the 'int cmd' parameter as the new set_ts_config
function doesn't use it. I also fixed a typo in the function
description.

-v2
* Only save the settings after validating them

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c

index cca13a5438e2abf20b3cd5b23dd62e579c6dbd24..4371ef0ed4a0b5608d3b5731bab19bffbc28770b 100644 (file)
@@ -765,6 +765,7 @@ struct ixgbe_adapter {
        struct ptp_clock_info ptp_caps;
        struct work_struct ptp_tx_work;
        struct sk_buff *ptp_tx_skb;
+       struct hwtstamp_config tstamp_config;
        unsigned long ptp_tx_start;
        unsigned long last_overflow_check;
        unsigned long last_rx_ptp_check;
@@ -957,8 +958,8 @@ static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring,
        rx_ring->last_rx_timestamp = jiffies;
 }
 
-int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, struct ifreq *ifr,
-                            int cmd);
+int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
+int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
 void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_reset(struct ixgbe_adapter *adapter);
 void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr);
index 72807431c88a1c144c6e016adb00c3a6fe0ba9ad..10b35d82e3091a33b95aa28f6d4cb2eb259a430f 100644 (file)
@@ -7197,7 +7197,9 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
 
        switch (cmd) {
        case SIOCSHWTSTAMP:
-               return ixgbe_ptp_hwtstamp_ioctl(adapter, req, cmd);
+               return ixgbe_ptp_set_ts_config(adapter, req);
+       case SIOCGHWTSTAMP:
+               return ixgbe_ptp_get_ts_config(adapter, req);
        default:
                return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd);
        }
index 9e54fcc13bc95288c8ed93cc4743769757c69e54..9ef730f2916ade4ab887fe9be4e8f394d0f399f3 100644 (file)
@@ -576,14 +576,21 @@ void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
        shhwtstamps->hwtstamp = ns_to_ktime(ns);
 }
 
+int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
+{
+       struct hwtstamp_config *config = &adapter->tstamp_config;
+
+       return copy_to_user(ifr->ifr_data, config,
+                           sizeof(*config)) ? -EFAULT : 0;
+}
+
 /**
- * ixgbe_ptp_hwtstamp_ioctl - control hardware time stamping
+ * ixgbe_ptp_set_ts_config - control hardware time stamping
  * @adapter: pointer to adapter struct
  * @ifreq: ioctl data
- * @cmd: particular ioctl requested
  *
  * Outgoing time stamping can be enabled and disabled. Play nice and
- * disable it when requested, although it shouldn't case any overhead
+ * disable it when requested, although it shouldn't cause any overhead
  * when no packet needs it. At most one packet in the queue may be
  * marked for time stamping, otherwise it would be impossible to tell
  * for sure to which packet the hardware time stamp belongs.
@@ -599,8 +606,7 @@ void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
  * Event mode. This more accurately tells the user what the hardware is going
  * to do anyways.
  */
-int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
-                            struct ifreq *ifr, int cmd)
+int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
 {
        struct ixgbe_hw *hw = &adapter->hw;
        struct hwtstamp_config config;
@@ -702,6 +708,10 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
        regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH);
        regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
 
+       /* save these settings for future reference */
+       memcpy(&adapter->tstamp_config, &config,
+              sizeof(adapter->tstamp_config));
+
        return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
                -EFAULT : 0;
 }
@@ -809,6 +819,9 @@ void ixgbe_ptp_reset(struct ixgbe_adapter *adapter)
        IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000);
        IXGBE_WRITE_FLUSH(hw);
 
+       /* Reset the saved tstamp_config */
+       memset(&adapter->tstamp_config, 0, sizeof(adapter->tstamp_config));
+
        ixgbe_ptp_start_cyclecounter(adapter);
 
        spin_lock_irqsave(&adapter->tmreg_lock, flags);