Revert "net/smc: fix listen processing for SMC-Rv2"
[linux-2.6-microblaze.git] / net / socket.c
index 6887840..6ee634c 100644 (file)
@@ -683,9 +683,18 @@ void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags)
 {
        u8 flags = *tx_flags;
 
-       if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE)
+       if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE) {
                flags |= SKBTX_HW_TSTAMP;
 
+               /* PTP hardware clocks can provide a free running cycle counter
+                * as a time base for virtual clocks. Tell driver to use the
+                * free running cycle counter for timestamp if socket is bound
+                * to virtual clock.
+                */
+               if (tsflags & SOF_TIMESTAMPING_BIND_PHC)
+                       flags |= SKBTX_HW_TSTAMP_USE_CYCLES;
+       }
+
        if (tsflags & SOF_TIMESTAMPING_TX_SOFTWARE)
                flags |= SKBTX_SW_TSTAMP;
 
@@ -796,7 +805,28 @@ 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)
+static ktime_t get_timestamp(struct sock *sk, struct sk_buff *skb, int *if_index)
+{
+       bool cycles = sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC;
+       struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
+       struct net_device *orig_dev;
+       ktime_t hwtstamp;
+
+       rcu_read_lock();
+       orig_dev = dev_get_by_napi_id(skb_napi_id(skb));
+       if (orig_dev) {
+               *if_index = orig_dev->ifindex;
+               hwtstamp = netdev_get_tstamp(orig_dev, shhwtstamps, cycles);
+       } else {
+               hwtstamp = shhwtstamps->hwtstamp;
+       }
+       rcu_read_unlock();
+
+       return hwtstamp;
+}
+
+static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb,
+                          int if_index)
 {
        struct scm_ts_pktinfo ts_pktinfo;
        struct net_device *orig_dev;
@@ -806,11 +836,14 @@ static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb)
 
        memset(&ts_pktinfo, 0, sizeof(ts_pktinfo));
 
-       rcu_read_lock();
-       orig_dev = dev_get_by_napi_id(skb_napi_id(skb));
-       if (orig_dev)
-               ts_pktinfo.if_index = orig_dev->ifindex;
-       rcu_read_unlock();
+       if (!if_index) {
+               rcu_read_lock();
+               orig_dev = dev_get_by_napi_id(skb_napi_id(skb));
+               if (orig_dev)
+                       if_index = orig_dev->ifindex;
+               rcu_read_unlock();
+       }
+       ts_pktinfo.if_index = if_index;
 
        ts_pktinfo.pkt_length = skb->len - skb_mac_offset(skb);
        put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO,
@@ -830,6 +863,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
        int empty = 1, false_tstamp = 0;
        struct skb_shared_hwtstamps *shhwtstamps =
                skb_hwtstamps(skb);
+       int if_index;
        ktime_t hwtstamp;
 
        /* Race occurred between timestamp enabling and packet
@@ -878,18 +912,22 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
        if (shhwtstamps &&
            (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
            !skb_is_swtx_tstamp(skb, false_tstamp)) {
-               if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC)
-                       hwtstamp = ptp_convert_timestamp(shhwtstamps,
-                                                        sk->sk_bind_phc);
+               if_index = 0;
+               if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP_NETDEV)
+                       hwtstamp = get_timestamp(sk, skb, &if_index);
                else
                        hwtstamp = shhwtstamps->hwtstamp;
 
+               if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC)
+                       hwtstamp = ptp_convert_timestamp(&hwtstamp,
+                                                        sk->sk_bind_phc);
+
                if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) {
                        empty = 0;
 
                        if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
                            !skb_is_err_queue(skb))
-                               put_ts_pktinfo(msg, skb);
+                               put_ts_pktinfo(msg, skb, if_index);
                }
        }
        if (!empty) {
@@ -930,13 +968,22 @@ static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
                        sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
 }
 
-void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
-       struct sk_buff *skb)
+static void sock_recv_mark(struct msghdr *msg, struct sock *sk,
+                          struct sk_buff *skb)
+{
+       if (sock_flag(sk, SOCK_RCVMARK) && skb)
+               put_cmsg(msg, SOL_SOCKET, SO_MARK, sizeof(__u32),
+                        &skb->mark);
+}
+
+void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
+                      struct sk_buff *skb)
 {
        sock_recv_timestamp(msg, sk, skb);
        sock_recv_drops(msg, sk, skb);
+       sock_recv_mark(msg, sk, skb);
 }
-EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops);
+EXPORT_SYMBOL_GPL(__sock_recv_cmsgs);
 
 INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *,
                                           size_t, int));