enabled and the driver is using NAPI. The struct contains also two
   other fields, but they are reserved and undefined.
 
+SOF_TIMESTAMPING_OPT_TX_SWHW:
+
+  Request both hardware and software timestamps for outgoing packets
+  when SOF_TIMESTAMPING_TX_HARDWARE and SOF_TIMESTAMPING_TX_SOFTWARE
+  are enabled at the same time. If both timestamps are generated,
+  two separate messages will be looped to the socket's error queue,
+  each containing just one timestamp.
+
 New applications are encouraged to pass SOF_TIMESTAMPING_OPT_ID to
 disambiguate timestamps and SOF_TIMESTAMPING_OPT_TSONLY to operate
 regardless of the setting of sysctl net.core.tstamp_allow_data.
 
 void skb_tstamp_tx(struct sk_buff *orig_skb,
                   struct skb_shared_hwtstamps *hwtstamps);
 
-static inline void sw_tx_timestamp(struct sk_buff *skb)
-{
-       if (skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP &&
-           !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
-               skb_tstamp_tx(skb, NULL);
-}
-
 /**
  * skb_tx_timestamp() - Driver hook for transmit timestamping
  *
 static inline void skb_tx_timestamp(struct sk_buff *skb)
 {
        skb_clone_tx_timestamp(skb);
-       sw_tx_timestamp(skb);
+       if (skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP)
+               skb_tstamp_tx(skb, NULL);
 }
 
 /**
 
        SOF_TIMESTAMPING_OPT_TSONLY = (1<<11),
        SOF_TIMESTAMPING_OPT_STATS = (1<<12),
        SOF_TIMESTAMPING_OPT_PKTINFO = (1<<13),
+       SOF_TIMESTAMPING_OPT_TX_SWHW = (1<<14),
 
-       SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_PKTINFO,
+       SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_TX_SWHW,
        SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) |
                                 SOF_TIMESTAMPING_LAST
 };
 
        if (!sk)
                return;
 
+       if (!hwtstamps && !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TX_SWHW) &&
+           skb_shinfo(orig_skb)->tx_flags & SKBTX_IN_PROGRESS)
+               return;
+
        tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY;
        if (!skb_may_tx_timestamp(sk, tsonly))
                return;
 
        return skb->pkt_type == PACKET_OUTGOING;
 }
 
+/* On transmit, software and hardware timestamps are returned independently.
+ * As the two skb clones share the hardware timestamp, which may be updated
+ * before the software timestamp is received, a hardware TX timestamp may be
+ * returned only if there is no software TX timestamp. Ignore false software
+ * timestamps, which may be made in the __sock_recv_timestamp() call when the
+ * option SO_TIMESTAMP(NS) is enabled on the socket, even when the skb has a
+ * hardware timestamp.
+ */
+static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp)
+{
+       return skb->tstamp && !false_tstamp && skb_is_err_queue(skb);
+}
+
 static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb)
 {
        struct scm_ts_pktinfo ts_pktinfo;
 {
        int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
        struct scm_timestamping tss;
-       int empty = 1;
+       int empty = 1, false_tstamp = 0;
        struct skb_shared_hwtstamps *shhwtstamps =
                skb_hwtstamps(skb);
 
        /* Race occurred between timestamp enabling and packet
           receiving.  Fill in the current time for now. */
-       if (need_software_tstamp && skb->tstamp == 0)
+       if (need_software_tstamp && skb->tstamp == 0) {
                __net_timestamp(skb);
+               false_tstamp = 1;
+       }
 
        if (need_software_tstamp) {
                if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
                empty = 0;
        if (shhwtstamps &&
            (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
+           !skb_is_swtx_tstamp(skb, false_tstamp) &&
            ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
                empty = 0;
                if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&