aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/include/asm/socket.h3
-rw-r--r--arch/arm/include/asm/socket.h3
-rw-r--r--arch/avr32/include/asm/socket.h3
-rw-r--r--arch/cris/include/asm/socket.h3
-rw-r--r--arch/frv/include/asm/socket.h3
-rw-r--r--arch/h8300/include/asm/socket.h3
-rw-r--r--arch/ia64/include/asm/socket.h3
-rw-r--r--arch/m32r/include/asm/socket.h3
-rw-r--r--arch/m68k/include/asm/socket.h3
-rw-r--r--arch/mips/include/asm/socket.h3
-rw-r--r--arch/mn10300/include/asm/socket.h3
-rw-r--r--arch/parisc/include/asm/socket.h3
-rw-r--r--arch/powerpc/include/asm/socket.h3
-rw-r--r--arch/s390/include/asm/socket.h3
-rw-r--r--arch/sparc/include/asm/socket.h3
-rw-r--r--arch/xtensa/include/asm/socket.h3
-rw-r--r--include/asm-generic/socket.h3
-rw-r--r--include/linux/errqueue.h3
-rw-r--r--include/linux/skbuff.h19
-rw-r--r--include/net/sock.h6
-rw-r--r--net/core/skbuff.c20
-rw-r--r--net/core/sock.c9
-rw-r--r--net/socket.c18
23 files changed, 123 insertions, 3 deletions
diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h
index 06edfefc3373..082355f159e6 100644
--- a/arch/alpha/include/asm/socket.h
+++ b/arch/alpha/include/asm/socket.h
@@ -69,6 +69,9 @@
69 69
70#define SO_RXQ_OVFL 40 70#define SO_RXQ_OVFL 40
71 71
72#define SO_WIFI_STATUS 41
73#define SCM_WIFI_STATUS SO_WIFI_STATUS
74
72/* O_NONBLOCK clashes with the bits used for socket types. Therefore we 75/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
73 * have to define SOCK_NONBLOCK to a different value here. 76 * have to define SOCK_NONBLOCK to a different value here.
74 */ 77 */
diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h
index 90ffd04b8e74..dec6f9afb3cf 100644
--- a/arch/arm/include/asm/socket.h
+++ b/arch/arm/include/asm/socket.h
@@ -62,4 +62,7 @@
62 62
63#define SO_RXQ_OVFL 40 63#define SO_RXQ_OVFL 40
64 64
65#define SO_WIFI_STATUS 41
66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67
65#endif /* _ASM_SOCKET_H */ 68#endif /* _ASM_SOCKET_H */
diff --git a/arch/avr32/include/asm/socket.h b/arch/avr32/include/asm/socket.h
index c8d1fae49476..247b88c760be 100644
--- a/arch/avr32/include/asm/socket.h
+++ b/arch/avr32/include/asm/socket.h
@@ -62,4 +62,7 @@
62 62
63#define SO_RXQ_OVFL 40 63#define SO_RXQ_OVFL 40
64 64
65#define SO_WIFI_STATUS 41
66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67
65#endif /* __ASM_AVR32_SOCKET_H */ 68#endif /* __ASM_AVR32_SOCKET_H */
diff --git a/arch/cris/include/asm/socket.h b/arch/cris/include/asm/socket.h
index 1a4a61909ca8..e269264df7c4 100644
--- a/arch/cris/include/asm/socket.h
+++ b/arch/cris/include/asm/socket.h
@@ -64,6 +64,9 @@
64 64
65#define SO_RXQ_OVFL 40 65#define SO_RXQ_OVFL 40
66 66
67#define SO_WIFI_STATUS 41
68#define SCM_WIFI_STATUS SO_WIFI_STATUS
69
67#endif /* _ASM_SOCKET_H */ 70#endif /* _ASM_SOCKET_H */
68 71
69 72
diff --git a/arch/frv/include/asm/socket.h b/arch/frv/include/asm/socket.h
index a6b26880c1ec..ce80fdadcce5 100644
--- a/arch/frv/include/asm/socket.h
+++ b/arch/frv/include/asm/socket.h
@@ -62,5 +62,8 @@
62 62
63#define SO_RXQ_OVFL 40 63#define SO_RXQ_OVFL 40
64 64
65#define SO_WIFI_STATUS 41
66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67
65#endif /* _ASM_SOCKET_H */ 68#endif /* _ASM_SOCKET_H */
66 69
diff --git a/arch/h8300/include/asm/socket.h b/arch/h8300/include/asm/socket.h
index 04c0f4596eb5..cf1daab6f27e 100644
--- a/arch/h8300/include/asm/socket.h
+++ b/arch/h8300/include/asm/socket.h
@@ -62,4 +62,7 @@
62 62
63#define SO_RXQ_OVFL 40 63#define SO_RXQ_OVFL 40
64 64
65#define SO_WIFI_STATUS 41
66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67
65#endif /* _ASM_SOCKET_H */ 68#endif /* _ASM_SOCKET_H */
diff --git a/arch/ia64/include/asm/socket.h b/arch/ia64/include/asm/socket.h
index 51427eaa51ba..4b03664e3fb5 100644
--- a/arch/ia64/include/asm/socket.h
+++ b/arch/ia64/include/asm/socket.h
@@ -71,4 +71,7 @@
71 71
72#define SO_RXQ_OVFL 40 72#define SO_RXQ_OVFL 40
73 73
74#define SO_WIFI_STATUS 41
75#define SCM_WIFI_STATUS SO_WIFI_STATUS
76
74#endif /* _ASM_IA64_SOCKET_H */ 77#endif /* _ASM_IA64_SOCKET_H */
diff --git a/arch/m32r/include/asm/socket.h b/arch/m32r/include/asm/socket.h
index 469787c30098..e8b8c5bb053c 100644
--- a/arch/m32r/include/asm/socket.h
+++ b/arch/m32r/include/asm/socket.h
@@ -62,4 +62,7 @@
62 62
63#define SO_RXQ_OVFL 40 63#define SO_RXQ_OVFL 40
64 64
65#define SO_WIFI_STATUS 41
66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67
65#endif /* _ASM_M32R_SOCKET_H */ 68#endif /* _ASM_M32R_SOCKET_H */
diff --git a/arch/m68k/include/asm/socket.h b/arch/m68k/include/asm/socket.h
index 9bf49c87d954..d4708ce466e0 100644
--- a/arch/m68k/include/asm/socket.h
+++ b/arch/m68k/include/asm/socket.h
@@ -62,4 +62,7 @@
62 62
63#define SO_RXQ_OVFL 40 63#define SO_RXQ_OVFL 40
64 64
65#define SO_WIFI_STATUS 41
66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67
65#endif /* _ASM_SOCKET_H */ 68#endif /* _ASM_SOCKET_H */
diff --git a/arch/mips/include/asm/socket.h b/arch/mips/include/asm/socket.h
index 9de5190f2487..ad5c0a7a02a7 100644
--- a/arch/mips/include/asm/socket.h
+++ b/arch/mips/include/asm/socket.h
@@ -82,6 +82,9 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
82 82
83#define SO_RXQ_OVFL 40 83#define SO_RXQ_OVFL 40
84 84
85#define SO_WIFI_STATUS 41
86#define SCM_WIFI_STATUS SO_WIFI_STATUS
87
85#ifdef __KERNEL__ 88#ifdef __KERNEL__
86 89
87/** sock_type - Socket types 90/** sock_type - Socket types
diff --git a/arch/mn10300/include/asm/socket.h b/arch/mn10300/include/asm/socket.h
index 4e60c4281288..876356d78522 100644
--- a/arch/mn10300/include/asm/socket.h
+++ b/arch/mn10300/include/asm/socket.h
@@ -62,4 +62,7 @@
62 62
63#define SO_RXQ_OVFL 40 63#define SO_RXQ_OVFL 40
64 64
65#define SO_WIFI_STATUS 41
66#define SCM_WIFI_STATUS SO_WIFI_STATUS
67
65#endif /* _ASM_SOCKET_H */ 68#endif /* _ASM_SOCKET_H */
diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h
index 225b7d6a1a0a..d28c51b61067 100644
--- a/arch/parisc/include/asm/socket.h
+++ b/arch/parisc/include/asm/socket.h
@@ -61,6 +61,9 @@
61 61
62#define SO_RXQ_OVFL 0x4021 62#define SO_RXQ_OVFL 0x4021
63 63
64#define SO_WIFI_STATUS 0x4022
65#define SCM_WIFI_STATUS SO_WIFI_STATUS
66
64/* O_NONBLOCK clashes with the bits used for socket types. Therefore we 67/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
65 * have to define SOCK_NONBLOCK to a different value here. 68 * have to define SOCK_NONBLOCK to a different value here.
66 */ 69 */
diff --git a/arch/powerpc/include/asm/socket.h b/arch/powerpc/include/asm/socket.h
index 866f7606da68..2fc2af8fbf59 100644
--- a/arch/powerpc/include/asm/socket.h
+++ b/arch/powerpc/include/asm/socket.h
@@ -69,4 +69,7 @@
69 69
70#define SO_RXQ_OVFL 40 70#define SO_RXQ_OVFL 40
71 71
72#define SO_WIFI_STATUS 41
73#define SCM_WIFI_STATUS SO_WIFI_STATUS
74
72#endif /* _ASM_POWERPC_SOCKET_H */ 75#endif /* _ASM_POWERPC_SOCKET_H */
diff --git a/arch/s390/include/asm/socket.h b/arch/s390/include/asm/socket.h
index fdff1e995c73..67b5c1b14b51 100644
--- a/arch/s390/include/asm/socket.h
+++ b/arch/s390/include/asm/socket.h
@@ -70,4 +70,7 @@
70 70
71#define SO_RXQ_OVFL 40 71#define SO_RXQ_OVFL 40
72 72
73#define SO_WIFI_STATUS 41
74#define SCM_WIFI_STATUS SO_WIFI_STATUS
75
73#endif /* _ASM_SOCKET_H */ 76#endif /* _ASM_SOCKET_H */
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/asm/socket.h
index 9d3fefcff2f5..8af1b64168b3 100644
--- a/arch/sparc/include/asm/socket.h
+++ b/arch/sparc/include/asm/socket.h
@@ -58,6 +58,9 @@
58 58
59#define SO_RXQ_OVFL 0x0024 59#define SO_RXQ_OVFL 0x0024
60 60
61#define SO_WIFI_STATUS 0x0025
62#define SCM_WIFI_STATUS SO_WIFI_STATUS
63
61/* Security levels - as per NRL IPv6 - don't actually do anything */ 64/* Security levels - as per NRL IPv6 - don't actually do anything */
62#define SO_SECURITY_AUTHENTICATION 0x5001 65#define SO_SECURITY_AUTHENTICATION 0x5001
63#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 66#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
diff --git a/arch/xtensa/include/asm/socket.h b/arch/xtensa/include/asm/socket.h
index cbdf2ffaacff..bb06968be227 100644
--- a/arch/xtensa/include/asm/socket.h
+++ b/arch/xtensa/include/asm/socket.h
@@ -73,4 +73,7 @@
73 73
74#define SO_RXQ_OVFL 40 74#define SO_RXQ_OVFL 40
75 75
76#define SO_WIFI_STATUS 41
77#define SCM_WIFI_STATUS SO_WIFI_STATUS
78
76#endif /* _XTENSA_SOCKET_H */ 79#endif /* _XTENSA_SOCKET_H */
diff --git a/include/asm-generic/socket.h b/include/asm-generic/socket.h
index 9a6115e7cf63..49c1704173e7 100644
--- a/include/asm-generic/socket.h
+++ b/include/asm-generic/socket.h
@@ -64,4 +64,7 @@
64#define SO_DOMAIN 39 64#define SO_DOMAIN 39
65 65
66#define SO_RXQ_OVFL 40 66#define SO_RXQ_OVFL 40
67
68#define SO_WIFI_STATUS 41
69#define SCM_WIFI_STATUS SO_WIFI_STATUS
67#endif /* __ASM_GENERIC_SOCKET_H */ 70#endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/include/linux/errqueue.h b/include/linux/errqueue.h
index 034072cea853..c9f522bd17e4 100644
--- a/include/linux/errqueue.h
+++ b/include/linux/errqueue.h
@@ -17,7 +17,8 @@ struct sock_extended_err {
17#define SO_EE_ORIGIN_LOCAL 1 17#define SO_EE_ORIGIN_LOCAL 1
18#define SO_EE_ORIGIN_ICMP 2 18#define SO_EE_ORIGIN_ICMP 2
19#define SO_EE_ORIGIN_ICMP6 3 19#define SO_EE_ORIGIN_ICMP6 3
20#define SO_EE_ORIGIN_TIMESTAMPING 4 20#define SO_EE_ORIGIN_TXSTATUS 4
21#define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS
21 22
22#define SO_EE_OFFENDER(ee) ((struct sockaddr*)((ee)+1)) 23#define SO_EE_OFFENDER(ee) ((struct sockaddr*)((ee)+1))
23 24
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 6a6b352326d7..ff7e1306a2d2 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -218,6 +218,9 @@ enum {
218 218
219 /* device driver supports TX zero-copy buffers */ 219 /* device driver supports TX zero-copy buffers */
220 SKBTX_DEV_ZEROCOPY = 1 << 4, 220 SKBTX_DEV_ZEROCOPY = 1 << 4,
221
222 /* generate wifi status information (where possible) */
223 SKBTX_WIFI_STATUS = 1 << 5,
221}; 224};
222 225
223/* 226/*
@@ -352,6 +355,8 @@ typedef unsigned char *sk_buff_data_t;
352 * @ooo_okay: allow the mapping of a socket to a queue to be changed 355 * @ooo_okay: allow the mapping of a socket to a queue to be changed
353 * @l4_rxhash: indicate rxhash is a canonical 4-tuple hash over transport 356 * @l4_rxhash: indicate rxhash is a canonical 4-tuple hash over transport
354 * ports. 357 * ports.
358 * @wifi_acked_valid: wifi_acked was set
359 * @wifi_acked: whether frame was acked on wifi or not
355 * @dma_cookie: a cookie to one of several possible DMA operations 360 * @dma_cookie: a cookie to one of several possible DMA operations
356 * done by skb DMA functions 361 * done by skb DMA functions
357 * @secmark: security marking 362 * @secmark: security marking
@@ -445,10 +450,11 @@ struct sk_buff {
445#endif 450#endif
446 __u8 ooo_okay:1; 451 __u8 ooo_okay:1;
447 __u8 l4_rxhash:1; 452 __u8 l4_rxhash:1;
453 __u8 wifi_acked_valid:1;
454 __u8 wifi_acked:1;
455 /* 10/12 bit hole (depending on ndisc_nodetype presence) */
448 kmemcheck_bitfield_end(flags2); 456 kmemcheck_bitfield_end(flags2);
449 457
450 /* 0/13 bit hole */
451
452#ifdef CONFIG_NET_DMA 458#ifdef CONFIG_NET_DMA
453 dma_cookie_t dma_cookie; 459 dma_cookie_t dma_cookie;
454#endif 460#endif
@@ -2263,6 +2269,15 @@ static inline void skb_tx_timestamp(struct sk_buff *skb)
2263 sw_tx_timestamp(skb); 2269 sw_tx_timestamp(skb);
2264} 2270}
2265 2271
2272/**
2273 * skb_complete_wifi_ack - deliver skb with wifi status
2274 *
2275 * @skb: the original outgoing packet
2276 * @acked: ack status
2277 *
2278 */
2279void skb_complete_wifi_ack(struct sk_buff *skb, bool acked);
2280
2266extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len); 2281extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len);
2267extern __sum16 __skb_checksum_complete(struct sk_buff *skb); 2282extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
2268 2283
diff --git a/include/net/sock.h b/include/net/sock.h
index 5ac682f73d63..fa6f5381c5d6 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -564,6 +564,7 @@ enum sock_flags {
564 SOCK_FASYNC, /* fasync() active */ 564 SOCK_FASYNC, /* fasync() active */
565 SOCK_RXQ_OVFL, 565 SOCK_RXQ_OVFL,
566 SOCK_ZEROCOPY, /* buffers from userspace */ 566 SOCK_ZEROCOPY, /* buffers from userspace */
567 SOCK_WIFI_STATUS, /* push wifi status to userspace */
567}; 568};
568 569
569static inline void sock_copy_flags(struct sock *nsk, struct sock *osk) 570static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
@@ -1714,6 +1715,8 @@ static inline int sock_intr_errno(long timeo)
1714 1715
1715extern void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, 1716extern void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
1716 struct sk_buff *skb); 1717 struct sk_buff *skb);
1718extern void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
1719 struct sk_buff *skb);
1717 1720
1718static __inline__ void 1721static __inline__ void
1719sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) 1722sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
@@ -1741,6 +1744,9 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
1741 __sock_recv_timestamp(msg, sk, skb); 1744 __sock_recv_timestamp(msg, sk, skb);
1742 else 1745 else
1743 sk->sk_stamp = kt; 1746 sk->sk_stamp = kt;
1747
1748 if (sock_flag(sk, SOCK_WIFI_STATUS) && skb->wifi_acked_valid)
1749 __sock_recv_wifi_status(msg, sk, skb);
1744} 1750}
1745 1751
1746extern void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, 1752extern void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index ca4db40e75b8..2f6babd5a570 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3168,6 +3168,26 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,
3168} 3168}
3169EXPORT_SYMBOL_GPL(skb_tstamp_tx); 3169EXPORT_SYMBOL_GPL(skb_tstamp_tx);
3170 3170
3171void skb_complete_wifi_ack(struct sk_buff *skb, bool acked)
3172{
3173 struct sock *sk = skb->sk;
3174 struct sock_exterr_skb *serr;
3175 int err;
3176
3177 skb->wifi_acked_valid = 1;
3178 skb->wifi_acked = acked;
3179
3180 serr = SKB_EXT_ERR(skb);
3181 memset(serr, 0, sizeof(*serr));
3182 serr->ee.ee_errno = ENOMSG;
3183 serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS;
3184
3185 err = sock_queue_err_skb(sk, skb);
3186 if (err)
3187 kfree_skb(skb);
3188}
3189EXPORT_SYMBOL_GPL(skb_complete_wifi_ack);
3190
3171 3191
3172/** 3192/**
3173 * skb_partial_csum_set - set up and verify partial csum values for packet 3193 * skb_partial_csum_set - set up and verify partial csum values for packet
diff --git a/net/core/sock.c b/net/core/sock.c
index 4ed7b1d12f5e..cbdf51c0d5ac 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -740,6 +740,11 @@ set_rcvbuf:
740 case SO_RXQ_OVFL: 740 case SO_RXQ_OVFL:
741 sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool); 741 sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool);
742 break; 742 break;
743
744 case SO_WIFI_STATUS:
745 sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool);
746 break;
747
743 default: 748 default:
744 ret = -ENOPROTOOPT; 749 ret = -ENOPROTOOPT;
745 break; 750 break;
@@ -961,6 +966,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
961 v.val = !!sock_flag(sk, SOCK_RXQ_OVFL); 966 v.val = !!sock_flag(sk, SOCK_RXQ_OVFL);
962 break; 967 break;
963 968
969 case SO_WIFI_STATUS:
970 v.val = !!sock_flag(sk, SOCK_WIFI_STATUS);
971 break;
972
964 default: 973 default:
965 return -ENOPROTOOPT; 974 return -ENOPROTOOPT;
966 } 975 }
diff --git a/net/socket.c b/net/socket.c
index 2877647f347b..425ef4270460 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -538,6 +538,8 @@ int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags)
538 *tx_flags |= SKBTX_HW_TSTAMP; 538 *tx_flags |= SKBTX_HW_TSTAMP;
539 if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE)) 539 if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE))
540 *tx_flags |= SKBTX_SW_TSTAMP; 540 *tx_flags |= SKBTX_SW_TSTAMP;
541 if (sock_flag(sk, SOCK_WIFI_STATUS))
542 *tx_flags |= SKBTX_WIFI_STATUS;
541 return 0; 543 return 0;
542} 544}
543EXPORT_SYMBOL(sock_tx_timestamp); 545EXPORT_SYMBOL(sock_tx_timestamp);
@@ -674,6 +676,22 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
674} 676}
675EXPORT_SYMBOL_GPL(__sock_recv_timestamp); 677EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
676 678
679void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
680 struct sk_buff *skb)
681{
682 int ack;
683
684 if (!sock_flag(sk, SOCK_WIFI_STATUS))
685 return;
686 if (!skb->wifi_acked_valid)
687 return;
688
689 ack = skb->wifi_acked;
690
691 put_cmsg(msg, SOL_SOCKET, SCM_WIFI_STATUS, sizeof(ack), &ack);
692}
693EXPORT_SYMBOL_GPL(__sock_recv_wifi_status);
694
677static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, 695static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
678 struct sk_buff *skb) 696 struct sk_buff *skb)
679{ 697{