Linux wireless drivers development
 help / color / mirror / Atom feed
* [RFC 10/12] net: add wireless TX status socket option
From: Johannes Berg @ 2011-10-14 15:11 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20111014151119.246288840@sipsolutions.net>

From: Johannes Berg <johannes.berg@intel.com>

The 802.1X EAPOL handshake hostapd does requires
knowing whether the frame was ack'ed by the peer.
Currently, we fudge this pretty badly by not even
transmitting the frame as a normal data frame but
injecting it with radiotap and getting the status
out of radiotap monitor as well. This is rather
complex, confuses users (mon.wlan0 presence) and
doesn't work with all hardware.

To get rid of that hack, introduce a real wifi TX
status option for data frame transmissions.

This works similar to the existing TX timestamping
in that it reflects the SKB back to the socket's
error queue with a SCM_WIFI_STATUS cmsg that has
an int indicating ACK status (0/1).

Since it is possible that at some point we will
want to have TX timestamping and wifi status in a
single errqueue SKB (there's little point in not
doing that), redefine SO_EE_ORIGIN_TIMESTAMPING
to SO_EE_ORIGIN_TXSTATUS which can collect more
than just the timestamp; keep the old constant
as an alias of course. Currently the internal APIs
don't make that possible, but it wouldn't be hard
to split them up in a way that makes it possible.

Thanks to Neil Horman for helping me figure out
the functions that add the control messages.

TODO:
 * sock_tx_timestamp() function should be renamed,
   maybe to sock_tx_status()?
 * sock_recv_timestamp() should also be renamed,
   I had a hard time figuring out the difference
   between that and sock_recv_ts_and_drops(). The
   former is generic, while the latter adds RX
   information only, maybe that should be reflected
   in new names?

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 arch/alpha/include/asm/socket.h   |    3 +++
 arch/arm/include/asm/socket.h     |    3 +++
 arch/avr32/include/asm/socket.h   |    3 +++
 arch/cris/include/asm/socket.h    |    3 +++
 arch/frv/include/asm/socket.h     |    3 +++
 arch/h8300/include/asm/socket.h   |    3 +++
 arch/ia64/include/asm/socket.h    |    3 +++
 arch/m32r/include/asm/socket.h    |    3 +++
 arch/m68k/include/asm/socket.h    |    3 +++
 arch/mips/include/asm/socket.h    |    3 +++
 arch/mn10300/include/asm/socket.h |    3 +++
 arch/parisc/include/asm/socket.h  |    3 +++
 arch/powerpc/include/asm/socket.h |    3 +++
 arch/s390/include/asm/socket.h    |    3 +++
 arch/sparc/include/asm/socket.h   |    3 +++
 arch/xtensa/include/asm/socket.h  |    3 +++
 include/asm-generic/socket.h      |    3 +++
 include/linux/errqueue.h          |    3 ++-
 include/linux/skbuff.h            |   19 +++++++++++++++++--
 include/net/sock.h                |    7 +++++++
 net/core/skbuff.c                 |   20 ++++++++++++++++++++
 net/core/sock.c                   |    9 +++++++++
 net/socket.c                      |   19 +++++++++++++++++++
 23 files changed, 125 insertions(+), 3 deletions(-)

--- a/include/asm-generic/socket.h	2011-10-12 19:24:34.000000000 +0200
+++ b/include/asm-generic/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -64,4 +64,7 @@
 #define SO_DOMAIN		39
 
 #define SO_RXQ_OVFL             40
+
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS	SO_WIFI_STATUS
 #endif /* __ASM_GENERIC_SOCKET_H */
--- a/net/core/sock.c	2011-10-12 19:24:40.000000000 +0200
+++ b/net/core/sock.c	2011-10-13 13:45:19.000000000 +0200
@@ -743,6 +743,11 @@ set_rcvbuf:
 		else
 			sock_reset_flag(sk, SOCK_RXQ_OVFL);
 		break;
+
+	case SO_WIFI_STATUS:
+		sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool);
+		break;
+
 	default:
 		ret = -ENOPROTOOPT;
 		break;
@@ -964,6 +969,10 @@ int sock_getsockopt(struct socket *sock,
 		v.val = !!sock_flag(sk, SOCK_RXQ_OVFL);
 		break;
 
+	case SO_WIFI_STATUS:
+		v.val = !!sock_flag(sk, SOCK_WIFI_STATUS);
+		break;
+
 	default:
 		return -ENOPROTOOPT;
 	}
--- a/include/net/sock.h	2011-10-12 19:24:34.000000000 +0200
+++ b/include/net/sock.h	2011-10-13 13:45:19.000000000 +0200
@@ -564,6 +564,7 @@ enum sock_flags {
 	SOCK_FASYNC, /* fasync() active */
 	SOCK_RXQ_OVFL,
 	SOCK_ZEROCOPY, /* buffers from userspace */
+	SOCK_WIFI_STATUS, /* push wifi status to userspace */
 };
 
 static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
@@ -1705,7 +1706,10 @@ static inline int sock_intr_errno(long t
 
 extern void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
 	struct sk_buff *skb);
+extern void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
+	struct sk_buff *skb);
 
+/* XXX: rename this function now? */
 static __inline__ void
 sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
 {
@@ -1732,6 +1736,9 @@ sock_recv_timestamp(struct msghdr *msg,
 		__sock_recv_timestamp(msg, sk, skb);
 	else
 		sk->sk_stamp = kt;
+
+	if (sock_flag(sk, SOCK_WIFI_STATUS) && skb->wifi_acked_valid)
+		__sock_recv_wifi_status(msg, sk, skb);
 }
 
 extern void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
--- a/arch/alpha/include/asm/socket.h	2011-10-12 19:24:33.000000000 +0200
+++ b/arch/alpha/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -69,6 +69,9 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 /* O_NONBLOCK clashes with the bits used for socket types.  Therefore we
  * have to define SOCK_NONBLOCK to a different value here.
  */
--- a/arch/arm/include/asm/socket.h	2011-10-12 19:24:33.000000000 +0200
+++ b/arch/arm/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -62,4 +62,7 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #endif /* _ASM_SOCKET_H */
--- a/arch/avr32/include/asm/socket.h	2011-10-12 19:24:32.000000000 +0200
+++ b/arch/avr32/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -62,4 +62,7 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #endif /* __ASM_AVR32_SOCKET_H */
--- a/arch/cris/include/asm/socket.h	2011-10-12 19:24:33.000000000 +0200
+++ b/arch/cris/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -64,6 +64,9 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #endif /* _ASM_SOCKET_H */
 
 
--- a/arch/frv/include/asm/socket.h	2011-10-12 19:24:33.000000000 +0200
+++ b/arch/frv/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -62,5 +62,8 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #endif /* _ASM_SOCKET_H */
 
--- a/arch/h8300/include/asm/socket.h	2011-10-12 19:24:32.000000000 +0200
+++ b/arch/h8300/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -62,4 +62,7 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #endif /* _ASM_SOCKET_H */
--- a/arch/ia64/include/asm/socket.h	2011-10-12 19:24:33.000000000 +0200
+++ b/arch/ia64/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -71,4 +71,7 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #endif /* _ASM_IA64_SOCKET_H */
--- a/arch/m32r/include/asm/socket.h	2011-10-12 19:24:33.000000000 +0200
+++ b/arch/m32r/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -62,4 +62,7 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #endif /* _ASM_M32R_SOCKET_H */
--- a/arch/m68k/include/asm/socket.h	2011-10-12 19:24:33.000000000 +0200
+++ b/arch/m68k/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -62,4 +62,7 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #endif /* _ASM_SOCKET_H */
--- a/arch/mips/include/asm/socket.h	2011-10-12 19:24:33.000000000 +0200
+++ b/arch/mips/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -82,6 +82,9 @@ To add: #define SO_REUSEPORT 0x0200	/* A
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #ifdef __KERNEL__
 
 /** sock_type - Socket types
--- a/arch/mn10300/include/asm/socket.h	2011-10-12 19:24:32.000000000 +0200
+++ b/arch/mn10300/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -62,4 +62,7 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #endif /* _ASM_SOCKET_H */
--- a/arch/parisc/include/asm/socket.h	2011-10-12 19:24:32.000000000 +0200
+++ b/arch/parisc/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -61,6 +61,9 @@
 
 #define SO_RXQ_OVFL             0x4021
 
+#define SO_WIFI_STATUS		0x4022
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 /* O_NONBLOCK clashes with the bits used for socket types.  Therefore we
  * have to define SOCK_NONBLOCK to a different value here.
  */
--- a/arch/powerpc/include/asm/socket.h	2011-10-12 19:24:33.000000000 +0200
+++ b/arch/powerpc/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -69,4 +69,7 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #endif	/* _ASM_POWERPC_SOCKET_H */
--- a/arch/s390/include/asm/socket.h	2011-10-12 19:24:32.000000000 +0200
+++ b/arch/s390/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -70,4 +70,7 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #endif /* _ASM_SOCKET_H */
--- a/arch/sparc/include/asm/socket.h	2011-10-12 19:24:32.000000000 +0200
+++ b/arch/sparc/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -58,6 +58,9 @@
 
 #define SO_RXQ_OVFL             0x0024
 
+#define SO_WIFI_STATUS		0x0025
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		0x5001
 #define SO_SECURITY_ENCRYPTION_TRANSPORT	0x5002
--- a/arch/xtensa/include/asm/socket.h	2011-10-12 19:24:32.000000000 +0200
+++ b/arch/xtensa/include/asm/socket.h	2011-10-13 13:45:19.000000000 +0200
@@ -73,4 +73,7 @@
 
 #define SO_RXQ_OVFL             40
 
+#define SO_WIFI_STATUS		41
+#define SCM_WIFI_STATUS		SO_WIFI_STATUS
+
 #endif	/* _XTENSA_SOCKET_H */
--- a/include/linux/errqueue.h	2011-10-12 19:24:33.000000000 +0200
+++ b/include/linux/errqueue.h	2011-10-13 13:45:19.000000000 +0200
@@ -17,7 +17,8 @@ struct sock_extended_err {
 #define SO_EE_ORIGIN_LOCAL	1
 #define SO_EE_ORIGIN_ICMP	2
 #define SO_EE_ORIGIN_ICMP6	3
-#define SO_EE_ORIGIN_TIMESTAMPING 4
+#define SO_EE_ORIGIN_TXSTATUS	4
+#define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS
 
 #define SO_EE_OFFENDER(ee)	((struct sockaddr*)((ee)+1))
 
--- a/include/linux/skbuff.h	2011-10-12 19:24:33.000000000 +0200
+++ b/include/linux/skbuff.h	2011-10-13 13:45:19.000000000 +0200
@@ -190,6 +190,9 @@ enum {
 
 	/* device driver supports TX zero-copy buffers */
 	SKBTX_DEV_ZEROCOPY = 1 << 4,
+
+	/* generate wifi status information (where possible) */
+	SKBTX_WIFI_STATUS = 1 << 5,
 };
 
 /*
@@ -322,6 +325,8 @@ typedef unsigned char *sk_buff_data_t;
  *	@queue_mapping: Queue mapping for multiqueue devices
  *	@ndisc_nodetype: router type (from link layer)
  *	@ooo_okay: allow the mapping of a socket to a queue to be changed
+ *	@wifi_acked_valid: wifi_acked was set
+ *	@wifi_acked: whether frame was acked on wifi or not
  *	@dma_cookie: a cookie to one of several possible DMA operations
  *		done by skb DMA functions
  *	@secmark: security marking
@@ -414,10 +419,11 @@ struct sk_buff {
 	__u8			ndisc_nodetype:2;
 #endif
 	__u8			ooo_okay:1;
+	__u8			wifi_acked_valid:1;
+	__u8			wifi_acked:1;
+	/* 11/13 bit hole (depending on nodetype presence) */
 	kmemcheck_bitfield_end(flags2);
 
-	/* 0/13 bit hole */
-
 #ifdef CONFIG_NET_DMA
 	dma_cookie_t		dma_cookie;
 #endif
@@ -2062,6 +2068,15 @@ static inline void skb_tx_timestamp(stru
 	sw_tx_timestamp(skb);
 }
 
+/**
+ * skb_complete_wifi_ack - deliver skb with wifi status
+ *
+ * @skb: the original outgoing packet
+ * @acked: ack status
+ *
+ */
+void skb_complete_wifi_ack(struct sk_buff *skb, bool acked);
+
 extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len);
 extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
 
--- a/net/core/skbuff.c	2011-10-12 19:24:34.000000000 +0200
+++ b/net/core/skbuff.c	2011-10-13 13:45:19.000000000 +0200
@@ -3150,6 +3150,26 @@ void skb_tstamp_tx(struct sk_buff *orig_
 }
 EXPORT_SYMBOL_GPL(skb_tstamp_tx);
 
+void skb_complete_wifi_ack(struct sk_buff *skb, bool acked)
+{
+	struct sock *sk = skb->sk;
+	struct sock_exterr_skb *serr;
+	int err;
+
+	skb->wifi_acked_valid = 1;
+	skb->wifi_acked = acked;
+
+	serr = SKB_EXT_ERR(skb);
+	memset(serr, 0, sizeof(*serr));
+	serr->ee.ee_errno = ENOMSG;
+	serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS;
+
+	err = sock_queue_err_skb(sk, skb);
+	if (err)
+		kfree_skb(skb);
+}
+EXPORT_SYMBOL_GPL(skb_complete_wifi_ack);
+
 
 /**
  * skb_partial_csum_set - set up and verify partial csum values for packet
--- a/net/socket.c	2011-10-12 19:24:34.000000000 +0200
+++ b/net/socket.c	2011-10-13 13:45:19.000000000 +0200
@@ -531,6 +531,7 @@ void sock_release(struct socket *sock)
 }
 EXPORT_SYMBOL(sock_release);
 
+/* XXX: rename this function now */
 int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags)
 {
 	*tx_flags = 0;
@@ -538,6 +539,8 @@ int sock_tx_timestamp(struct sock *sk, _
 		*tx_flags |= SKBTX_HW_TSTAMP;
 	if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE))
 		*tx_flags |= SKBTX_SW_TSTAMP;
+	if (sock_flag(sk, SOCK_WIFI_STATUS))
+		*tx_flags |= SKBTX_WIFI_STATUS;
 	return 0;
 }
 EXPORT_SYMBOL(sock_tx_timestamp);
@@ -674,6 +677,22 @@ void __sock_recv_timestamp(struct msghdr
 }
 EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
 
+void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
+	struct sk_buff *skb)
+{
+	int ack;
+
+	if (!sock_flag(sk, SOCK_WIFI_STATUS))
+		return;
+	if (!skb->wifi_acked_valid)
+		return;
+
+	ack = skb->wifi_acked;
+
+	put_cmsg(msg, SOL_SOCKET, SCM_WIFI_STATUS, sizeof(ack), &ack);
+}
+EXPORT_SYMBOL_GPL(__sock_recv_wifi_status);
+
 static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
 				   struct sk_buff *skb)
 {



^ permalink raw reply

* [RFC 11/12] nl80211: advertise socket TX status capability
From: Johannes Berg @ 2011-10-14 15:11 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20111014151119.246288840@sipsolutions.net>

From: Johannes Berg <johannes.berg@intel.com>

The new wifi socket TX capability should be
supported by wifi drivers, let them advertise
whether they do or not.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/linux/nl80211.h |   15 +++++++++++++++
 include/net/cfg80211.h  |    3 ++-
 net/wireless/nl80211.c  |    2 ++
 3 files changed, 19 insertions(+), 1 deletion(-)

--- a/include/linux/nl80211.h	2011-10-13 13:45:18.000000000 +0200
+++ b/include/linux/nl80211.h	2011-10-13 13:52:09.000000000 +0200
@@ -1136,6 +1136,9 @@ enum nl80211_commands {
  *	with support for the features listed in this attribute, see
  *	&enum nl80211_ap_sme_features.
  *
+ * @NL80211_ATTR_FEATURE_FLAGS: This u32 attribute contains flags from
+ *	&enum nl80211_feature_flags and is advertised in wiphy information.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1366,6 +1369,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_DEVICE_AP_MLME,
 
+	NL80211_ATTR_FEATURE_FLAGS,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -2690,4 +2695,14 @@ enum nl80211_ap_sme_features {
 	NL80211_AP_SME_WSC	= 1 << 0,
 };
 
+/**
+ * enum nl80211_feature_flags - device/driver features
+ * @NL80211_FEATURE_SK_TX_STATUS: This driver supports reflecting back
+ *	TX status to the socket error queue when requested with the
+ *	socket option.
+ */
+enum nl80211_feature_flags {
+	NL80211_FEATURE_SK_TX_STATUS	= 1 << 0,
+};
+
 #endif /* __LINUX_NL80211_H */
--- a/include/net/cfg80211.h	2011-10-13 13:45:18.000000000 +0200
+++ b/include/net/cfg80211.h	2011-10-13 13:52:50.000000000 +0200
@@ -1870,6 +1870,7 @@ struct wiphy_wowlan_support {
  * @software_iftypes: bitmask of software interface types, these are not
  *	subject to any restrictions since they are purely managed in SW.
  * @flags: wiphy flags, see &enum wiphy_flags
+ * @features: features advertised to nl80211, see &enum nl80211_feature_flags.
  * @bss_priv_size: each BSS struct has private data allocated with it,
  *	this variable determines its size
  * @max_scan_ssids: maximum number of SSIDs the device can scan for in
@@ -1931,7 +1932,7 @@ struct wiphy {
 	/* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */
 	u16 interface_modes;
 
-	u32 flags;
+	u32 flags, features;
 
 	u32 ap_sme_capa;
 
--- a/net/wireless/nl80211.c	2011-10-13 13:45:18.000000000 +0200
+++ b/net/wireless/nl80211.c	2011-10-13 13:53:22.000000000 +0200
@@ -1013,6 +1013,8 @@ static int nl80211_send_wiphy(struct sk_
 		NLA_PUT_U32(msg, NL80211_ATTR_DEVICE_AP_MLME,
 			    dev->wiphy.ap_sme_capa);
 
+	NLA_PUT_U32(msg, NL80211_ATTR_FEATURE_FLAGS, dev->wiphy.features);
+
 	return genlmsg_end(msg, hdr);
 
  nla_put_failure:



^ permalink raw reply

* [RFC 12/12] mac80211: implement wifi TX status
From: Johannes Berg @ 2011-10-14 15:11 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20111014151119.246288840@sipsolutions.net>

From: Johannes Berg <johannes.berg@intel.com>

Implement the socket wifi TX status error
queue reflection in mac80211.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/mac80211.h     |    5 +---
 net/mac80211/ieee80211_i.h |    4 +++
 net/mac80211/main.c        |   18 ++++++++++++++
 net/mac80211/status.c      |   38 ++++++++++++++++++++++++++++++
 net/mac80211/tx.c          |   56 ++++++++++++++++++++++++++++++++++++++++++---
 5 files changed, 115 insertions(+), 6 deletions(-)

--- a/net/mac80211/status.c	2011-10-13 22:02:03.000000000 +0200
+++ b/net/mac80211/status.c	2011-10-13 22:02:03.000000000 +0200
@@ -452,6 +452,24 @@ void ieee80211_tx_status(struct ieee8021
 		}
 	}
 
+	if (unlikely(info->ack_frame_id)) {
+		struct sk_buff *ack_skb;
+		unsigned long flags;
+
+		spin_lock_irqsave(&local->ack_status_lock, flags);
+		ack_skb = idr_find(&local->ack_status_frames,
+				   info->ack_frame_id);
+		if (ack_skb)
+			idr_remove(&local->ack_status_frames,
+				   info->ack_frame_id);
+		spin_unlock_irqrestore(&local->ack_status_lock, flags);
+
+		/* consumes ack_skb */
+		if (ack_skb)
+			skb_complete_wifi_ack(ack_skb,
+				info->flags & IEEE80211_TX_STAT_ACK);
+	}
+
 	/* this was a transmitted frame, but now we want to reuse it */
 	skb_orphan(skb);
 
@@ -556,6 +574,26 @@ EXPORT_SYMBOL(ieee80211_report_low_ack);
 
 void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
+	struct ieee80211_local *local = hw_to_local(hw);
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+	if (unlikely(info->ack_frame_id)) {
+		struct sk_buff *ack_skb;
+		unsigned long flags;
+
+		spin_lock_irqsave(&local->ack_status_lock, flags);
+		ack_skb = idr_find(&local->ack_status_frames,
+				   info->ack_frame_id);
+		if (ack_skb)
+			idr_remove(&local->ack_status_frames,
+				   info->ack_frame_id);
+		spin_unlock_irqrestore(&local->ack_status_lock, flags);
+
+		/* consumes ack_skb */
+		if (ack_skb)
+			dev_kfree_skb_any(ack_skb);
+	}
+
 	dev_kfree_skb_any(skb);
 }
 EXPORT_SYMBOL(ieee80211_free_txskb);
--- a/net/mac80211/tx.c	2011-10-13 22:02:02.000000000 +0200
+++ b/net/mac80211/tx.c	2011-10-13 22:02:03.000000000 +0200
@@ -1684,8 +1684,10 @@ netdev_tx_t ieee80211_subif_start_xmit(s
 	int nh_pos, h_pos;
 	struct sta_info *sta = NULL;
 	bool wme_sta = false, authorized = false, tdls_auth = false;
-	struct sk_buff *tmp_skb;
 	bool tdls_direct = false;
+	bool multicast;
+	u32 info_flags = 0;
+	u16 info_id = 0;
 
 	if (unlikely(skb->len < ETH_HLEN)) {
 		ret = NETDEV_TX_OK;
@@ -1872,7 +1874,8 @@ netdev_tx_t ieee80211_subif_start_xmit(s
 	 * if it is a multicast address (which can only happen
 	 * in AP mode)
 	 */
-	if (!is_multicast_ether_addr(hdr.addr1)) {
+	multicast = is_multicast_ether_addr(hdr.addr1);
+	if (!multicast) {
 		rcu_read_lock();
 		sta = sta_info_get(sdata, hdr.addr1);
 		if (sta) {
@@ -1913,11 +1916,54 @@ netdev_tx_t ieee80211_subif_start_xmit(s
 		goto fail;
 	}
 
+	if (unlikely(!multicast && skb->sk &&
+		     skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) {
+		struct sk_buff *orig_skb = skb;
+
+		skb = skb_clone(skb, GFP_ATOMIC);
+		if (skb) {
+			unsigned long flags;
+			int id, r;
+
+			spin_lock_irqsave(&local->ack_status_lock, flags);
+			r = idr_get_new_above(&local->ack_status_frames,
+					      orig_skb, 1, &id);
+			if (r == -EAGAIN) {
+				idr_pre_get(&local->ack_status_frames,
+					    GFP_ATOMIC);
+				r = idr_get_new_above(&local->ack_status_frames,
+						      orig_skb, 1, &id);
+			}
+			if (WARN_ON(!id) || id > 0xffff) {
+				idr_remove(&local->ack_status_frames, id);
+				r = -ERANGE;
+			}
+			spin_unlock_irqrestore(&local->ack_status_lock, flags);
+
+			if (!r) {
+				info_id = id;
+				info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
+			} else if (skb_shared(skb)) {
+				kfree_skb(orig_skb);
+			} else {
+				kfree_skb(skb);
+				skb = orig_skb;
+			}
+		} else {
+			/* couldn't clone -- lose tx status ... */
+			skb = orig_skb;
+		}
+	}
+
 	/*
 	 * If the skb is shared we need to obtain our own copy.
 	 */
 	if (skb_shared(skb)) {
-		tmp_skb = skb;
+		struct sk_buff *tmp_skb = skb;
+
+		/* can't happen -- skb is a clone if info_id != 0 */
+		WARN_ON(info_id);
+
 		skb = skb_clone(skb, GFP_ATOMIC);
 		kfree_skb(tmp_skb);
 
@@ -2018,6 +2064,10 @@ netdev_tx_t ieee80211_subif_start_xmit(s
 	memset(info, 0, sizeof(*info));
 
 	dev->trans_start = jiffies;
+
+	info->flags = info_flags;
+	info->ack_frame_id = info_id;
+
 	ieee80211_xmit(sdata, skb);
 
 	return NETDEV_TX_OK;
--- a/include/net/mac80211.h	2011-10-13 22:02:03.000000000 +0200
+++ b/include/net/mac80211.h	2011-10-13 22:02:03.000000000 +0200
@@ -518,7 +518,7 @@ struct ieee80211_tx_rate {
  * @flags: transmit info flags, defined above
  * @band: the band to transmit on (use for checking for races)
  * @antenna_sel_tx: antenna to use, 0 for automatic diversity
- * @pad: padding, ignore
+ * @ack_frame_id: internal frame ID for TX status, used internally
  * @control: union for control data
  * @status: union for status data
  * @driver_data: array of driver_data pointers
@@ -535,8 +535,7 @@ struct ieee80211_tx_info {
 
 	u8 antenna_sel_tx;
 
-	/* 2 byte hole */
-	u8 pad[2];
+	u16 ack_frame_id;
 
 	union {
 		struct {
--- a/net/mac80211/ieee80211_i.h	2011-10-13 22:01:52.000000000 +0200
+++ b/net/mac80211/ieee80211_i.h	2011-10-13 22:02:03.000000000 +0200
@@ -24,6 +24,7 @@
 #include <linux/spinlock.h>
 #include <linux/etherdevice.h>
 #include <linux/leds.h>
+#include <linux/idr.h>
 #include <net/ieee80211_radiotap.h>
 #include <net/cfg80211.h>
 #include <net/mac80211.h>
@@ -1011,6 +1012,9 @@ struct ieee80211_local {
 	u32 hw_roc_cookie;
 	bool hw_roc_for_tx;
 
+	struct idr ack_status_frames;
+	spinlock_t ack_status_lock;
+
 	/* dummy netdev for use w/ NAPI */
 	struct net_device napi_dev;
 
--- a/net/mac80211/main.c	2011-10-13 22:01:52.000000000 +0200
+++ b/net/mac80211/main.c	2011-10-13 22:02:03.000000000 +0200
@@ -597,6 +597,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(
 			WIPHY_FLAG_4ADDR_AP |
 			WIPHY_FLAG_4ADDR_STATION;
 
+	wiphy->features = NL80211_FEATURE_SK_TX_STATUS;
+
 	if (!ops->set_key)
 		wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
 
@@ -670,6 +672,11 @@ struct ieee80211_hw *ieee80211_alloc_hw(
 	INIT_WORK(&local->sched_scan_stopped_work,
 		  ieee80211_sched_scan_stopped_work);
 
+	spin_lock_init(&local->ack_status_lock);
+	idr_init(&local->ack_status_frames);
+	/* preallocate at least one entry */
+	idr_pre_get(&local->ack_status_frames, GFP_KERNEL);
+
 	sta_info_init(local);
 
 	for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
@@ -1049,6 +1056,13 @@ void ieee80211_unregister_hw(struct ieee
 }
 EXPORT_SYMBOL(ieee80211_unregister_hw);
 
+static int ieee80211_free_ack_frame(int id, void *p, void *data)
+{
+	WARN_ONCE(1, "Have pending ack frames!\n");
+	kfree_skb(p);
+	return 0;
+}
+
 void ieee80211_free_hw(struct ieee80211_hw *hw)
 {
 	struct ieee80211_local *local = hw_to_local(hw);
@@ -1059,6 +1073,10 @@ void ieee80211_free_hw(struct ieee80211_
 	if (local->wiphy_ciphers_allocated)
 		kfree(local->hw.wiphy->cipher_suites);
 
+	idr_for_each(&local->ack_status_frames,
+		     ieee80211_free_ack_frame, NULL);
+	idr_destroy(&local->ack_status_frames);
+
 	wiphy_free(local->hw.wiphy);
 }
 EXPORT_SYMBOL(ieee80211_free_hw);



^ permalink raw reply

* [PATCH] patch on comment
From: Loiseau Lucien @ 2011-10-14 15:30 UTC (permalink / raw)
  Cc: linux-wireless
In-Reply-To: <1318433496.3933.44.camel@jlt3.sipsolutions.net>

Digging into the source code, i noticed that the documentation tells 
that the tx function from ieee80211_ops should return NETDEV_TX_OK while 
the tx function is now a void function. Here is a very little patch to 
remove this information from the comment :

--- mac80211.h
+++ mac80211.h
@@ -1744,8 +1744,6 @@
   *    configuration in the TX control data. This handler should,
   *    preferably, never fail and stop queues appropriately, more
   *    importantly, however, it must never fail for A-MPDU-queues.
- *    This function should return NETDEV_TX_OK except in very
- *    limited cases.
   *    Must be implemented and atomic.
   *
   * @start: Called before the first netdevice attached to the hardware


Best Regards,

Lucien Loiseau.

^ permalink raw reply

* Re: [PATCH] ssb: Convert to use crc8 code in kernel library
From: Arend van Spriel @ 2011-10-14 15:30 UTC (permalink / raw)
  To: Pavel Roskin
  Cc: Larry Finger, John W Linville, Michael Buesch, zajec5@gmail.com,
	b43-dev@lists.infradead.org, linux-wireless@vger.kernel.org
In-Reply-To: <20111014111103.5658d4aa@mj>

On 10/14/2011 05:11 PM, Pavel Roskin wrote:
> On Sat, 08 Oct 2011 17:28:42 -0500
> Larry Finger <Larry.Finger@lwfinger.net> wrote:
> 
>> +static inline void htol16_buf(u16 *buf, unsigned int size)
>> +{
>> +	size /= 2;
>> +	while (size--)
>> +		*(__le16 *)(buf + size) = cpu_to_le16(*(buf + size));
>>  }
> 
> I'm not not sure compilers would optimize it out on little-endian
> systems.  Perhaps you want a define that uses this code on
> big-endian systems and does nothing on little endian systems.
> 
> Also, it would be nice to have a compile-time check that size is even.
> Or maybe size should be the number of 16-bit words, but then it would be
> better to call the argument "count" or something like that.
> 

I think this patch was already dropped.

Gr. AvS


^ permalink raw reply

* Re: iwlagn: WARN_ON() in iwl_get_idle_rx_chain_count()
From: wwguy @ 2011-10-14 15:29 UTC (permalink / raw)
  To: Michał Mirosław
  Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org,
	netdev@vger.kernel.org
In-Reply-To: <20111014150219.GA20672@rere.qmqm.pl>

[-- Attachment #1: Type: text/plain, Size: 23352 bytes --]

Hi Michal,

Could you try the attach patch and see if it fix your problem.

Thanks
Wey

On Fri, 2011-10-14 at 08:02 -0700, Michał Mirosław wrote:
> WARN_ON() in iwl_get_idle_rx_chain_count() gets triggered on system shutdown
> when WiFi card is associated to an AP. This is on kernel built from
> Linus' tree, commit 37cf95162af4036b4198756a590aab8126fa2ce4 (3.1.0-rc9+).
> It looks HT-related, I can't reproduce this on 802.11g network.
> 
> Best Regards,
> Michał Mirosław
> 
> 
> 09:00.0 Network controller: Intel Corporation Centrino Wireless-N 1030 (rev 34)
>         Subsystem: Intel Corporation Centrino Wireless-N 1030 BGN
>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
>         Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
>         Latency: 0, Cache Line Size: 64 bytes
>         Interrupt: pin A routed to IRQ 52
>         Region 0: Memory at f7a00000 (64-bit, non-prefetchable) [size=8K]
>         Capabilities: <access denied>
>         Kernel driver in use: iwlagn
> 
> Oct 14 00:04:26 oko kernel: [ 2796.354030] ------------[ cut here ]------------
> Oct 14 00:04:26 oko kernel: [ 2796.354996] WARNING: at /usr/src/linux-git/drivers/net/wireless/iwlwifi/iwl-agn-lib.c:1766 iwlagn_set_rxon_chain+0x107/0x1b2 [iwlagn]()
> Oct 14 00:04:26 oko kernel: [ 2796.355955] Hardware name: Vostro 3350
> Oct 14 00:04:26 oko kernel: [ 2796.356906] invalid SMPS mode 0
> Oct 14 00:04:26 oko kernel: [ 2796.356920] Modules linked in: acpi_cpufreq mperf cpufreq_conservative autofs4 rfcomm cpufreq_stats bnep cpufreq_powersave cpufreq_userspace pci_stub binfmt_misc microcode uinput nfs lockd auth_rpcgss nfs_acl sunrpc ext2 coretemp loop kvm_intel kvm aesni_intel cryptd aes_x86_64 aes_generic ecb btusb radeon bluetooth uvcvideo usb_storage videodev arc4 media uas iwlagn v4l2_compat_ioctl32 i915 crc16 snd_hda_codec_idt ttm drm_kms_helper mac80211 drm snd_hda_intel snd_hda_codec ehci_hcd snd_hwdep xhci_hcd snd_pcm snd_seq usbcore joydev sg cfg80211 snd_timer sr_mod snd_seq_device snd r8169 psmouse dell_wmi cdrom dell_laptop soundcore i2c_algo_bit pcspkr evdev sparse_keymap processor snd_page_alloc video cfbcopyarea mii dcdbas button cfbimgblt cfbfillrect wmi ac battery ext3 jbd mbcache dm_mod sd_mod crc_t10dif ahci libahci libata scsi_mod thermal thermal_sys [last unloaded: vboxdrv]
> Oct 14 00:04:26 oko kernel: [ 2796.365031] Pid: 3017, comm: wpa_supplicant Not tainted 3.1.0-rc9+ #12
> Oct 14 00:04:26 oko kernel: [ 2796.366263] Call Trace:
> Oct 14 00:04:26 oko kernel: [ 2796.367490]  [<ffffffff8103437f>] ? warn_slowpath_common+0x78/0x8c
> Oct 14 00:04:26 oko kernel: [ 2796.368673]  [<ffffffff8103442b>] ? warn_slowpath_fmt+0x45/0x4a
> Oct 14 00:04:26 oko kernel: [ 2796.369836]  [<ffffffffa0310733>] ? __sta_info_destroy+0x267/0x2af [mac80211]
> Oct 14 00:04:26 oko kernel: [ 2796.371046]  [<ffffffffa03a93f1>] ? iwlagn_set_rxon_chain+0x107/0x1b2 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.372274]  [<ffffffffa03b2f9e>] ? iwlagn_bss_info_changed+0x245/0x4b3 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.373753]  [<ffffffff8102c1e5>] ? get_parent_ip+0x9/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.374990]  [<ffffffffa031c03a>] ? __ieee80211_recalc_idle+0xef/0x194 [mac80211]
> Oct 14 00:04:26 oko kernel: [ 2796.376272]  [<ffffffffa031cbee>] ? ieee80211_recalc_idle+0x1e/0x42 [mac80211]
> Oct 14 00:04:26 oko kernel: [ 2796.377506]  [<ffffffffa0319690>] ? ieee80211_mgd_deauth+0x19c/0x1c0 [mac80211]
> Oct 14 00:04:26 oko kernel: [ 2796.378771]  [<ffffffff812e96ed>] ? sub_preempt_count+0x83/0x94
> Oct 14 00:04:26 oko kernel: [ 2796.380083]  [<ffffffffa01ca76c>] ? __cfg80211_mlme_deauth+0x107/0x116 [cfg80211]
> Oct 14 00:04:26 oko kernel: [ 2796.381293]  [<ffffffff812e64d9>] ? schedule_hrtimeout_range_clock+0xc8/0x103
> Oct 14 00:04:26 oko kernel: [ 2796.382550]  [<ffffffff8102c1e5>] ? get_parent_ip+0x9/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.383803]  [<ffffffffa01ca7e4>] ? cfg80211_mlme_deauth+0x69/0x82 [cfg80211]
> Oct 14 00:04:26 oko kernel: [ 2796.385039]  [<ffffffff81023735>] ? __wake_up_common+0x40/0x77
> Oct 14 00:04:26 oko kernel: [ 2796.386309]  [<ffffffffa01c15ed>] ? nl80211_deauthenticate+0xbc/0xc7 [cfg80211]
> Oct 14 00:04:26 oko kernel: [ 2796.387607]  [<ffffffffa01c35cb>] ? nl80211_pre_doit+0x85/0xfb [cfg80211]
> Oct 14 00:04:26 oko kernel: [ 2796.389171]  [<ffffffff81250f71>] ? genl_rcv_msg+0x1cb/0x1f9
> Oct 14 00:04:26 oko kernel: [ 2796.390753]  [<ffffffff81250da6>] ? genl_rcv+0x28/0x28
> Oct 14 00:04:26 oko kernel: [ 2796.392295]  [<ffffffff81250a06>] ? netlink_rcv_skb+0x36/0x7a
> Oct 14 00:04:26 oko kernel: [ 2796.393896]  [<ffffffff81250d9d>] ? genl_rcv+0x1f/0x28
> Oct 14 00:04:26 oko kernel: [ 2796.395521]  [<ffffffff81250537>] ? netlink_unicast+0xe6/0x14e
> Oct 14 00:04:26 oko kernel: [ 2796.397095]  [<ffffffff81250819>] ? netlink_sendmsg+0x27a/0x2b2
> Oct 14 00:04:26 oko kernel: [ 2796.398741]  [<ffffffff810f45dc>] ? __pollwait+0xce/0xce
> Oct 14 00:04:26 oko kernel: [ 2796.400378]  [<ffffffff8122172d>] ? sock_sendmsg+0xc1/0xde
> Oct 14 00:04:26 oko kernel: [ 2796.402042]  [<ffffffff8122160e>] ? sock_recvmsg+0xcd/0xec
> Oct 14 00:04:26 oko kernel: [ 2796.403645]  [<ffffffff8102c1e5>] ? get_parent_ip+0x9/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.405148]  [<ffffffff8122160e>] ? sock_recvmsg+0xcd/0xec
> Oct 14 00:04:26 oko kernel: [ 2796.406650]  [<ffffffff812228d4>] ? move_addr_to_kernel+0x24/0x46
> Oct 14 00:04:26 oko kernel: [ 2796.408098]  [<ffffffff812219c5>] ? __sys_sendmsg+0x1e8/0x288
> Oct 14 00:04:26 oko kernel: [ 2796.408102]  [<ffffffff812e9798>] ? add_preempt_count+0x9a/0x9c
> Oct 14 00:04:26 oko kernel: [ 2796.408107]  [<ffffffff8102c1e5>] ? get_parent_ip+0x9/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.408109]  [<ffffffff812e96ed>] ? sub_preempt_count+0x83/0x94
> Oct 14 00:04:26 oko kernel: [ 2796.408112]  [<ffffffff812e6f14>] ? _raw_spin_unlock_irq+0x23/0x2f
> Oct 14 00:04:26 oko kernel: [ 2796.408115]  [<ffffffff810022e1>] ? do_signal+0x51d/0x5f3
> Oct 14 00:04:26 oko kernel: [ 2796.408119]  [<ffffffff81008f1b>] ? init_fpu+0x72/0x7f
> Oct 14 00:04:26 oko kernel: [ 2796.408122]  [<ffffffff8100969f>] ? check_for_xstate+0x1c/0x6f
> Oct 14 00:04:26 oko kernel: [ 2796.408124]  [<ffffffff81009966>] ? restore_i387_xstate+0x9e/0x17c
> Oct 14 00:04:26 oko kernel: [ 2796.408128]  [<ffffffff81044e92>] ? do_sigaltstack+0xaa/0x13e
> Oct 14 00:04:26 oko kernel: [ 2796.408131]  [<ffffffff812233c5>] ? sys_sendmsg+0x39/0x58
> Oct 14 00:04:26 oko kernel: [ 2796.408134]  [<ffffffff812ec17b>] ? system_call_fastpath+0x16/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.408176] ---[ end trace 634279251cfb99d1 ]---
> Oct 14 00:04:26 oko kernel: [ 2796.409026] ------------[ cut here ]------------
> Oct 14 00:04:26 oko kernel: [ 2796.409046] WARNING: at /usr/src/linux-git/drivers/net/wireless/iwlwifi/iwl-agn-lib.c:1766 iwlagn_set_rxon_chain+0x107/0x1b2 [iwlagn]()
> Oct 14 00:04:26 oko kernel: [ 2796.409048] Hardware name: Vostro 3350
> Oct 14 00:04:26 oko kernel: [ 2796.409049] invalid SMPS mode 0
> Oct 14 00:04:26 oko kernel: [ 2796.409050] Modules linked in: acpi_cpufreq mperf cpufreq_conservative autofs4 rfcomm cpufreq_stats bnep cpufreq_powersave cpufreq_userspace pci_stub binfmt_misc microcode uinput nfs lockd auth_rpcgss nfs_acl sunrpc ext2 coretemp loop kvm_intel kvm aesni_intel cryptd aes_x86_64 aes_generic ecb btusb radeon bluetooth uvcvideo usb_storage videodev arc4 media uas iwlagn v4l2_compat_ioctl32 i915 crc16 snd_hda_codec_idt ttm drm_kms_helper mac80211 drm snd_hda_intel snd_hda_codec ehci_hcd snd_hwdep xhci_hcd snd_pcm snd_seq usbcore joydev sg cfg80211 snd_timer sr_mod snd_seq_device snd r8169 psmouse dell_wmi cdrom dell_laptop soundcore i2c_algo_bit pcspkr evdev sparse_keymap processor snd_page_alloc video cfbcopyarea mii dcdbas button cfbimgblt cfbfillrect wmi ac battery ext3 jbd mbcache dm_mod sd_mod crc_t10dif ahci libahci libata scsi_mod thermal thermal_sys [last unloaded: vboxdrv]
> Oct 14 00:04:26 oko kernel: [ 2796.409109] Pid: 3017, comm: wpa_supplicant Tainted: G        W   3.1.0-rc9+ #12
> Oct 14 00:04:26 oko kernel: [ 2796.409110] Call Trace:
> Oct 14 00:04:26 oko kernel: [ 2796.409116]  [<ffffffff8103437f>] ? warn_slowpath_common+0x78/0x8c
> Oct 14 00:04:26 oko kernel: [ 2796.409119]  [<ffffffff8103442b>] ? warn_slowpath_fmt+0x45/0x4a
> Oct 14 00:04:26 oko kernel: [ 2796.409133]  [<ffffffffa03b78e7>] ? iwl_send_cmd+0x1a4/0x303 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.409140]  [<ffffffffa03a93f1>] ? iwlagn_set_rxon_chain+0x107/0x1b2 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.409145]  [<ffffffffa03a276d>] ? iwl_update_chain_flags+0x32/0x58 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.409156]  [<ffffffffa03af7cd>] ? iwl_power_set_mode+0xf4/0x157 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.409163]  [<ffffffffa03af9e0>] ? iwl_power_update_mode+0x1b0/0x1b9 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.409170]  [<ffffffffa03b2cd8>] ? iwlagn_mac_config+0x206/0x287 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.409185]  [<ffffffffa0319690>] ? ieee80211_mgd_deauth+0x19c/0x1c0 [mac80211]
> Oct 14 00:04:26 oko kernel: [ 2796.409188]  [<ffffffff812e96ed>] ? sub_preempt_count+0x83/0x94
> Oct 14 00:04:26 oko kernel: [ 2796.409201]  [<ffffffffa01ca76c>] ? __cfg80211_mlme_deauth+0x107/0x116 [cfg80211]
> Oct 14 00:04:26 oko kernel: [ 2796.409206]  [<ffffffff812e64d9>] ? schedule_hrtimeout_range_clock+0xc8/0x103
> Oct 14 00:04:26 oko kernel: [ 2796.409208]  [<ffffffff8102c1e5>] ? get_parent_ip+0x9/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.409216]  [<ffffffffa01ca7e4>] ? cfg80211_mlme_deauth+0x69/0x82 [cfg80211]
> Oct 14 00:04:26 oko kernel: [ 2796.409220]  [<ffffffff81023735>] ? __wake_up_common+0x40/0x77
> Oct 14 00:04:26 oko kernel: [ 2796.409228]  [<ffffffffa01c15ed>] ? nl80211_deauthenticate+0xbc/0xc7 [cfg80211]
> Oct 14 00:04:26 oko kernel: [ 2796.409238]  [<ffffffffa01c35cb>] ? nl80211_pre_doit+0x85/0xfb [cfg80211]
> Oct 14 00:04:26 oko kernel: [ 2796.409244]  [<ffffffff81250f71>] ? genl_rcv_msg+0x1cb/0x1f9
> Oct 14 00:04:26 oko kernel: [ 2796.409246]  [<ffffffff81250da6>] ? genl_rcv+0x28/0x28
> Oct 14 00:04:26 oko kernel: [ 2796.409249]  [<ffffffff81250a06>] ? netlink_rcv_skb+0x36/0x7a
> Oct 14 00:04:26 oko kernel: [ 2796.409251]  [<ffffffff81250d9d>] ? genl_rcv+0x1f/0x28
> Oct 14 00:04:26 oko kernel: [ 2796.409253]  [<ffffffff81250537>] ? netlink_unicast+0xe6/0x14e
> Oct 14 00:04:26 oko kernel: [ 2796.409256]  [<ffffffff81250819>] ? netlink_sendmsg+0x27a/0x2b2
> Oct 14 00:04:26 oko kernel: [ 2796.409262]  [<ffffffff810f45dc>] ? __pollwait+0xce/0xce
> Oct 14 00:04:26 oko kernel: [ 2796.409266]  [<ffffffff8122172d>] ? sock_sendmsg+0xc1/0xde
> Oct 14 00:04:26 oko kernel: [ 2796.409268]  [<ffffffff8122160e>] ? sock_recvmsg+0xcd/0xec
> Oct 14 00:04:26 oko kernel: [ 2796.409271]  [<ffffffff8102c1e5>] ? get_parent_ip+0x9/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.409273]  [<ffffffff8122160e>] ? sock_recvmsg+0xcd/0xec
> Oct 14 00:04:26 oko kernel: [ 2796.409276]  [<ffffffff812228d4>] ? move_addr_to_kernel+0x24/0x46
> Oct 14 00:04:26 oko kernel: [ 2796.409279]  [<ffffffff812219c5>] ? __sys_sendmsg+0x1e8/0x288
> Oct 14 00:04:26 oko kernel: [ 2796.409282]  [<ffffffff812e9798>] ? add_preempt_count+0x9a/0x9c
> Oct 14 00:04:26 oko kernel: [ 2796.409284]  [<ffffffff8102c1e5>] ? get_parent_ip+0x9/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.409286]  [<ffffffff812e96ed>] ? sub_preempt_count+0x83/0x94
> Oct 14 00:04:26 oko kernel: [ 2796.409289]  [<ffffffff812e6f14>] ? _raw_spin_unlock_irq+0x23/0x2f
> Oct 14 00:04:26 oko kernel: [ 2796.409294]  [<ffffffff810022e1>] ? do_signal+0x51d/0x5f3
> Oct 14 00:04:26 oko kernel: [ 2796.409297]  [<ffffffff81008f1b>] ? init_fpu+0x72/0x7f
> Oct 14 00:04:26 oko kernel: [ 2796.409300]  [<ffffffff8100969f>] ? check_for_xstate+0x1c/0x6f
> Oct 14 00:04:26 oko kernel: [ 2796.409303]  [<ffffffff81009966>] ? restore_i387_xstate+0x9e/0x17c
> Oct 14 00:04:26 oko kernel: [ 2796.409305]  [<ffffffff81044e92>] ? do_sigaltstack+0xaa/0x13e
> Oct 14 00:04:26 oko kernel: [ 2796.409308]  [<ffffffff812233c5>] ? sys_sendmsg+0x39/0x58
> Oct 14 00:04:26 oko kernel: [ 2796.409312]  [<ffffffff812ec17b>] ? system_call_fastpath+0x16/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.409314] ---[ end trace 634279251cfb99d2 ]---
> Oct 14 00:04:26 oko kernel: [ 2796.409315] ------------[ cut here ]------------
> Oct 14 00:04:26 oko kernel: [ 2796.409325] WARNING: at /usr/src/linux-git/drivers/net/wireless/iwlwifi/iwl-agn-lib.c:1766 iwlagn_set_rxon_chain+0x107/0x1b2 [iwlagn]()
> Oct 14 00:04:26 oko kernel: [ 2796.409327] Hardware name: Vostro 3350
> Oct 14 00:04:26 oko kernel: [ 2796.409328] invalid SMPS mode 0
> Oct 14 00:04:26 oko kernel: [ 2796.409329] Modules linked in: acpi_cpufreq mperf cpufreq_conservative autofs4 rfcomm cpufreq_stats bnep cpufreq_powersave cpufreq_userspace pci_stub binfmt_misc microcode uinput nfs lockd auth_rpcgss nfs_acl sunrpc ext2 coretemp loop kvm_intel kvm aesni_intel cryptd aes_x86_64 aes_generic ecb btusb radeon bluetooth uvcvideo usb_storage videodev arc4 media uas iwlagn v4l2_compat_ioctl32 i915 crc16 snd_hda_codec_idt ttm drm_kms_helper mac80211 drm snd_hda_intel snd_hda_codec ehci_hcd snd_hwdep xhci_hcd snd_pcm snd_seq usbcore joydev sg cfg80211 snd_timer sr_mod snd_seq_device snd r8169 psmouse dell_wmi cdrom dell_laptop soundcore i2c_algo_bit pcspkr evdev sparse_keymap processor snd_page_alloc video cfbcopyarea mii dcdbas button cfbimgblt cfbfillrect wmi ac battery ext3 jbd mbcache dm_mod sd_mod crc_t10dif ahci libahci libata scsi_mod thermal thermal_sys [last unloaded: vboxdrv]
> Oct 14 00:04:26 oko kernel: [ 2796.409371] Pid: 3017, comm: wpa_supplicant Tainted: G        W   3.1.0-rc9+ #12
> Oct 14 00:04:26 oko kernel: [ 2796.409372] Call Trace:
> Oct 14 00:04:26 oko kernel: [ 2796.409381]  [<ffffffff8103437f>] ? warn_slowpath_common+0x78/0x8c
> Oct 14 00:04:26 oko kernel: [ 2796.409384]  [<ffffffff8103442b>] ? warn_slowpath_fmt+0x45/0x4a
> Oct 14 00:04:26 oko kernel: [ 2796.409392]  [<ffffffffa03b78e7>] ? iwl_send_cmd+0x1a4/0x303 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.409399]  [<ffffffffa03a93f1>] ? iwlagn_set_rxon_chain+0x107/0x1b2 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.409408]  [<ffffffffa03a276d>] ? iwl_update_chain_flags+0x32/0x58 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.409415]  [<ffffffffa03af7cd>] ? iwl_power_set_mode+0xf4/0x157 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.409421]  [<ffffffffa03af9e0>] ? iwl_power_update_mode+0x1b0/0x1b9 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.409429]  [<ffffffffa03b2cd8>] ? iwlagn_mac_config+0x206/0x287 [iwlagn]
> Oct 14 00:04:26 oko kernel: [ 2796.409439]  [<ffffffffa0319690>] ? ieee80211_mgd_deauth+0x19c/0x1c0 [mac80211]
> Oct 14 00:04:26 oko kernel: [ 2796.409442]  [<ffffffff812e96ed>] ? sub_preempt_count+0x83/0x94
> Oct 14 00:04:26 oko kernel: [ 2796.409457]  [<ffffffffa01ca76c>] ? __cfg80211_mlme_deauth+0x107/0x116 [cfg80211]
> Oct 14 00:04:26 oko kernel: [ 2796.409460]  [<ffffffff812e64d9>] ? schedule_hrtimeout_range_clock+0xc8/0x103
> Oct 14 00:04:26 oko kernel: [ 2796.409463]  [<ffffffff8102c1e5>] ? get_parent_ip+0x9/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.409477]  [<ffffffffa01ca7e4>] ? cfg80211_mlme_deauth+0x69/0x82 [cfg80211]
> Oct 14 00:04:26 oko kernel: [ 2796.409479]  [<ffffffff81023735>] ? __wake_up_common+0x40/0x77
> Oct 14 00:04:26 oko kernel: [ 2796.409490]  [<ffffffffa01c15ed>] ? nl80211_deauthenticate+0xbc/0xc7 [cfg80211]
> Oct 14 00:04:26 oko kernel: [ 2796.409498]  [<ffffffffa01c35cb>] ? nl80211_pre_doit+0x85/0xfb [cfg80211]
> Oct 14 00:04:26 oko kernel: [ 2796.409502]  [<ffffffff81250f71>] ? genl_rcv_msg+0x1cb/0x1f9
> Oct 14 00:04:26 oko kernel: [ 2796.409505]  [<ffffffff81250da6>] ? genl_rcv+0x28/0x28
> Oct 14 00:04:26 oko kernel: [ 2796.409507]  [<ffffffff81250a06>] ? netlink_rcv_skb+0x36/0x7a
> Oct 14 00:04:26 oko kernel: [ 2796.409509]  [<ffffffff81250d9d>] ? genl_rcv+0x1f/0x28
> Oct 14 00:04:26 oko kernel: [ 2796.409511]  [<ffffffff81250537>] ? netlink_unicast+0xe6/0x14e
> Oct 14 00:04:26 oko kernel: [ 2796.409514]  [<ffffffff81250819>] ? netlink_sendmsg+0x27a/0x2b2
> Oct 14 00:04:26 oko kernel: [ 2796.409517]  [<ffffffff810f45dc>] ? __pollwait+0xce/0xce
> Oct 14 00:04:26 oko kernel: [ 2796.409519]  [<ffffffff8122172d>] ? sock_sendmsg+0xc1/0xde
> Oct 14 00:04:26 oko kernel: [ 2796.409521]  [<ffffffff8122160e>] ? sock_recvmsg+0xcd/0xec
> Oct 14 00:04:26 oko kernel: [ 2796.409526]  [<ffffffff8102c1e5>] ? get_parent_ip+0x9/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.409529]  [<ffffffff8122160e>] ? sock_recvmsg+0xcd/0xec
> Oct 14 00:04:26 oko kernel: [ 2796.409532]  [<ffffffff812228d4>] ? move_addr_to_kernel+0x24/0x46
> Oct 14 00:04:26 oko kernel: [ 2796.409534]  [<ffffffff812219c5>] ? __sys_sendmsg+0x1e8/0x288
> Oct 14 00:04:26 oko kernel: [ 2796.409537]  [<ffffffff812e9798>] ? add_preempt_count+0x9a/0x9c
> Oct 14 00:04:26 oko kernel: [ 2796.409539]  [<ffffffff8102c1e5>] ? get_parent_ip+0x9/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.409542]  [<ffffffff812e96ed>] ? sub_preempt_count+0x83/0x94
> Oct 14 00:04:26 oko kernel: [ 2796.409544]  [<ffffffff812e6f14>] ? _raw_spin_unlock_irq+0x23/0x2f
> Oct 14 00:04:26 oko kernel: [ 2796.409548]  [<ffffffff810022e1>] ? do_signal+0x51d/0x5f3
> Oct 14 00:04:26 oko kernel: [ 2796.409551]  [<ffffffff81008f1b>] ? init_fpu+0x72/0x7f
> Oct 14 00:04:26 oko kernel: [ 2796.409554]  [<ffffffff8100969f>] ? check_for_xstate+0x1c/0x6f
> Oct 14 00:04:26 oko kernel: [ 2796.409556]  [<ffffffff81009966>] ? restore_i387_xstate+0x9e/0x17c
> Oct 14 00:04:26 oko kernel: [ 2796.409559]  [<ffffffff81044e92>] ? do_sigaltstack+0xaa/0x13e
> Oct 14 00:04:26 oko kernel: [ 2796.409564]  [<ffffffff812233c5>] ? sys_sendmsg+0x39/0x58
> Oct 14 00:04:26 oko kernel: [ 2796.409568]  [<ffffffff812ec17b>] ? system_call_fastpath+0x16/0x1b
> Oct 14 00:04:26 oko kernel: [ 2796.409570] ---[ end trace 634279251cfb99d3 ]---
> Oct 14 00:04:26 oko kernel: [ 2796.409586] cfg80211: Calling CRDA for country: PL
> Oct 14 00:04:27 oko kernel: [ 2796.573759] ------------[ cut here ]------------
> Oct 14 00:04:27 oko kernel: [ 2796.575276] WARNING: at /usr/src/linux-git/drivers/net/wireless/iwlwifi/iwl-agn-lib.c:1766 iwlagn_set_rxon_chain+0x107/0x1b2 [iwlagn]()
> Oct 14 00:04:27 oko kernel: [ 2796.576866] Hardware name: Vostro 3350
> Oct 14 00:04:27 oko kernel: [ 2796.578449] invalid SMPS mode 0
> Oct 14 00:04:27 oko kernel: [ 2796.578488] Modules linked in: acpi_cpufreq mperf cpufreq_conservative autofs4 rfcomm cpufreq_stats bnep cpufreq_powersave cpufreq_userspace pci_stub binfmt_misc microcode uinput nfs lockd auth_rpcgss nfs_acl sunrpc ext2 coretemp loop kvm_intel kvm aesni_intel cryptd aes_x86_64 aes_generic ecb btusb radeon bluetooth uvcvideo usb_storage videodev arc4 media uas iwlagn v4l2_compat_ioctl32 i915 crc16 snd_hda_codec_idt ttm drm_kms_helper mac80211 drm snd_hda_intel snd_hda_codec ehci_hcd snd_hwdep xhci_hcd snd_pcm snd_seq usbcore joydev sg cfg80211 snd_timer sr_mod snd_seq_device snd r8169 psmouse dell_wmi cdrom dell_laptop soundcore i2c_algo_bit pcspkr evdev sparse_keymap processor snd_page_alloc video cfbcopyarea mii dcdbas button cfbimgblt cfbfillrect wmi ac battery ext3 jbd mbcache dm_mod sd_mod crc_t10dif ahci libahci libata scsi_mod thermal thermal_sys [last unloaded: vboxdrv]
> Oct 14 00:04:27 oko kernel: [ 2796.591110] Pid: 2973, comm: NetworkManager Tainted: G        W   3.1.0-rc9+ #12
> Oct 14 00:04:27 oko kernel: [ 2796.592295] Call Trace:
> Oct 14 00:04:27 oko kernel: [ 2796.593474]  [<ffffffff8103437f>] ? warn_slowpath_common+0x78/0x8c
> Oct 14 00:04:27 oko kernel: [ 2796.594693]  [<ffffffff8103442b>] ? warn_slowpath_fmt+0x45/0x4a
> Oct 14 00:04:27 oko kernel: [ 2796.595910]  [<ffffffff812e96ed>] ? sub_preempt_count+0x83/0x94
> Oct 14 00:04:27 oko kernel: [ 2796.597087]  [<ffffffffa03a93f1>] ? iwlagn_set_rxon_chain+0x107/0x1b2 [iwlagn]
> Oct 14 00:04:27 oko kernel: [ 2796.598296]  [<ffffffff812e6f14>] ? _raw_spin_unlock_irq+0x23/0x2f
> Oct 14 00:04:27 oko kernel: [ 2796.599507]  [<ffffffffa03adc8c>] ? iwl_teardown_interface+0x4a/0x7e [iwlagn]
> Oct 14 00:04:27 oko kernel: [ 2796.600697]  [<ffffffffa03ae569>] ? iwl_mac_remove_interface+0x4e/0x5e [iwlagn]
> Oct 14 00:04:27 oko kernel: [ 2796.601914]  [<ffffffffa031c3f3>] ? ieee80211_do_stop+0x314/0x465 [mac80211]
> Oct 14 00:04:27 oko kernel: [ 2796.603133]  [<ffffffff81039618>] ? _local_bh_enable_ip.isra.12+0x94/0xa2
> Oct 14 00:04:27 oko kernel: [ 2796.604328]  [<ffffffffa031c557>] ? ieee80211_stop+0x13/0x17 [mac80211]
> Oct 14 00:04:27 oko kernel: [ 2796.605523]  [<ffffffff8122f754>] ? __dev_close_many+0x7f/0xab
> Oct 14 00:04:27 oko kernel: [ 2796.606752]  [<ffffffff8122f7b0>] ? __dev_close+0x30/0x47
> Oct 14 00:04:27 oko kernel: [ 2796.607981]  [<ffffffff812e96ed>] ? sub_preempt_count+0x83/0x94
> Oct 14 00:04:27 oko kernel: [ 2796.609179]  [<ffffffff81233e6a>] ? __dev_change_flags+0x9d/0x118
> Oct 14 00:04:27 oko kernel: [ 2796.610406]  [<ffffffff81233f4b>] ? dev_change_flags+0x12/0x42
> Oct 14 00:04:27 oko kernel: [ 2796.611639]  [<ffffffff8123da18>] ? do_setlink+0x287/0x6f8
> Oct 14 00:04:27 oko kernel: [ 2796.612848]  [<ffffffff810da6a2>] ? __kmalloc_node_track_caller+0xcb/0x105
> Oct 14 00:04:27 oko kernel: [ 2796.614089]  [<ffffffff812263ef>] ? sock_rmalloc+0x2b/0x4b
> Oct 14 00:04:27 oko kernel: [ 2796.615338]  [<ffffffff8123e20a>] ? __rtnl_unlock+0xc/0xc
> Oct 14 00:04:27 oko kernel: [ 2796.616549]  [<ffffffff8123e0d2>] ? rtnl_setlink+0xc4/0xe6
> Oct 14 00:04:27 oko kernel: [ 2796.617799]  [<ffffffff81250a06>] ? netlink_rcv_skb+0x36/0x7a
> Oct 14 00:04:27 oko kernel: [ 2796.619042]  [<ffffffff8123d64d>] ? rtnetlink_rcv+0x1f/0x28
> Oct 14 00:04:27 oko kernel: [ 2796.620261]  [<ffffffff81250537>] ? netlink_unicast+0xe6/0x14e
> Oct 14 00:04:27 oko kernel: [ 2796.621476]  [<ffffffff81250819>] ? netlink_sendmsg+0x27a/0x2b2
> Oct 14 00:04:27 oko kernel: [ 2796.622718]  [<ffffffff8122172d>] ? sock_sendmsg+0xc1/0xde
> Oct 14 00:04:27 oko kernel: [ 2796.623961]  [<ffffffff8122160e>] ? sock_recvmsg+0xcd/0xec
> Oct 14 00:04:27 oko kernel: [ 2796.625173]  [<ffffffff8122172d>] ? sock_sendmsg+0xc1/0xde
> Oct 14 00:04:27 oko kernel: [ 2796.626407]  [<ffffffff8116d88c>] ? cpumask_any_but+0x24/0x34
> Oct 14 00:04:27 oko kernel: [ 2796.627641]  [<ffffffff812228d4>] ? move_addr_to_kernel+0x24/0x46
> Oct 14 00:04:27 oko kernel: [ 2796.628853]  [<ffffffff812219c5>] ? __sys_sendmsg+0x1e8/0x288
> Oct 14 00:04:27 oko kernel: [ 2796.630089]  [<ffffffff812df81a>] ? __bad_area_nosemaphore+0x87/0x1f0
> Oct 14 00:04:27 oko kernel: [ 2796.631335]  [<ffffffff810e79c6>] ? fget_light+0x85/0x8d
> Oct 14 00:04:27 oko kernel: [ 2796.632537]  [<ffffffff812230a0>] ? sys_sendto+0x108/0x137
> Oct 14 00:04:27 oko kernel: [ 2796.633768]  [<ffffffff810f6c44>] ? dput+0xe6/0xf3
> Oct 14 00:04:27 oko kernel: [ 2796.634992]  [<ffffffff812233c5>] ? sys_sendmsg+0x39/0x58
> Oct 14 00:04:27 oko kernel: [ 2796.636194]  [<ffffffff812ec17b>] ? system_call_fastpath+0x16/0x1b
> Oct 14 00:04:27 oko kernel: [ 2796.637398] ---[ end trace 634279251cfb99d4 ]---
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


[-- Attachment #2: 0001-iwlagn-check-for-SMPS-mode.patch --]
[-- Type: text/x-patch, Size: 1549 bytes --]

>From d52f49a327e7bfb4d07b056e16312ffd23477b8e Mon Sep 17 00:00:00 2001
From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Date: Fri, 14 Oct 2011 08:26:07 -0700
Subject: [PATCH 1/1] iwlagn: check for SMPS mode

Check and report WARN only when its invalid

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c  |    1 +
 drivers/net/wireless/iwlwifi/iwl-agn-rxon.c |    3 +++
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 1a52ed2..6465983 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -827,6 +827,7 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
 	case IEEE80211_SMPS_STATIC:
 	case IEEE80211_SMPS_DYNAMIC:
 		return IWL_NUM_IDLE_CHAINS_SINGLE;
+	case IEEE80211_SMPS_AUTOMATIC:
 	case IEEE80211_SMPS_OFF:
 		return active_cnt;
 	default:
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index a580efe..94c7779 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -541,6 +541,9 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
 
 	mutex_lock(&priv->shrd->mutex);
 
+	if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
+		goto out;
+
 	if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) {
 		IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
 		goto out;
-- 
1.7.0.4


^ permalink raw reply related

* Ath9k, single antenna on ar9280
From: Stanislav Demakov @ 2011-10-14 15:46 UTC (permalink / raw)
  To: linux-wireless

I've noticed that set_antenna and get_antenna functionality was added
to the ath9k driver. But iw phy set antenna command still isn't
working.

I know that before there was a workaround by setting chainmasks number
to 1, but this is not exactly what I need. I just need to enable only
one physical antenna and allow the adapter work only in 1x1 mode.
Is it possible?

^ permalink raw reply

* Re: [PATCH] ssb: Convert to use crc8 code in kernel library
From: Larry Finger @ 2011-10-14 16:30 UTC (permalink / raw)
  To: Pavel Roskin
  Cc: John W Linville, Michael Buesch, zajec5, b43-dev, linux-wireless
In-Reply-To: <20111014111103.5658d4aa@mj>

On 10/14/2011 10:11 AM, Pavel Roskin wrote:
> On Sat, 08 Oct 2011 17:28:42 -0500
> Larry Finger<Larry.Finger@lwfinger.net>  wrote:
>
>> +static inline void htol16_buf(u16 *buf, unsigned int size)
>> +{
>> +	size /= 2;
>> +	while (size--)
>> +		*(__le16 *)(buf + size) = cpu_to_le16(*(buf + size));
>>   }
>
> I'm not not sure compilers would optimize it out on little-endian
> systems.  Perhaps you want a define that uses this code on
> big-endian systems and does nothing on little endian systems.
>
> Also, it would be nice to have a compile-time check that size is even.
> Or maybe size should be the number of 16-bit words, but then it would be
> better to call the argument "count" or something like that.

The patch was dropped. Even so, as this routine is found in brcmsmac, your 
comments warrant further discussion.

I am pretty sure that the compiler would optimize out the entire htol16_buf 
routine. After substitution for cpu_to_le16() on a little-endian system, the 
statement in the while loop becomes '*(buf + size) = *(buf + size)', which is 
certainly optimized away, as will the now empty while loop. The entire routine 
is reduced to 'size /= 2'. As this will have no effect on the external world, it 
will also be dropped leaving an empty htol16_buf(). I don't think any "#ifdef 
__BIG_ENDIAN ... #endif" statements are needed.

Your suggestion that the argument be renamed is good, but there is no need to 
check for an even number as the data in question come from 16-bit reads of the
SPROM on the b43 device. That number of 16-bit quantities was multiplied by 2 to 
get the byte count before calling this routine. Of course, the routine should 
have been passed the number of 16-bit words, not the byte count. My second 
version would have done this.

Larry

^ permalink raw reply

* Re: [PATCH] ssb: Convert to use crc8 code in kernel library
From: Michael Büsch @ 2011-10-14 16:47 UTC (permalink / raw)
  To: Larry Finger; +Cc: Pavel Roskin, linux-wireless, b43-dev
In-Reply-To: <4E986392.7020008@lwfinger.net>

On Fri, 14 Oct 2011 11:30:10 -0500
Larry Finger <Larry.Finger@lwfinger.net> wrote:

> I am pretty sure that the compiler would optimize out the entire htol16_buf 
> routine. After substitution for cpu_to_le16() on a little-endian system, the 
> statement in the while loop becomes '*(buf + size) = *(buf + size)', which is 

(There also is cpu_to_le16s(). Just for the record.)

-- 
Greetings, Michael.

^ permalink raw reply

* Re: [PATCH] patch on comment
From: Bob Copeland @ 2011-10-14 17:19 UTC (permalink / raw)
  To: Loiseau Lucien; +Cc: linux-wireless
In-Reply-To: <4E985579.9010401@gmail.com>

On Fri, Oct 14, 2011 at 11:30 AM, Loiseau Lucien
<loiseau.lucien@gmail.com> wrote:
> Digging into the source code, i noticed that the documentation tells that
> the tx function from ieee80211_ops should return NETDEV_TX_OK while the tx
> function is now a void function.

This is good, but as presented, you've left the job for others to make
the patch suitable for applying to the kernel.  Please see
Documentation/SubmittingPatches for more info.  For example, a better
email / commit message might be:

[PATCH] mac80211: remove reference to NETDEV_TX_OK

The kerneldoc states that ieee80211_ops.tx must return NETDEV_TX_OK,
but tx is now a void function.  Remove the stale comment.

Signed-off-by: <your-s-o-b-here>

---
[patch goes here]

It's almost the same as what you wrote, but there is a Signed-off-by,
and the subject and description are fit for the long term kernel
history.

If you perform these few extra steps when submitting, John can just
queue your patch directly from his inbox, and you get to keep all the
credit.  If you make the maintainer's job hard, he might drop it on
the floor until someone else does the work.

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply

* Compat-wireless release for 2011-10-14 is baked
From: Compat-wireless cronjob account @ 2011-10-14 19:05 UTC (permalink / raw)
  To: linux-wireless

>From git://github.com/mcgrof/compat-wireless
   8163a60..49eb82e  master     -> origin/master
>From git://github.com/sfrothwell/linux-next
 + 53c998a...0bb9d7e akpm-end   -> origin/akpm-end  (forced update)
   65112dc..37cf951  akpm-start -> origin/akpm-start
 + 7b64d23...970cc26 master     -> origin/master  (forced update)
   65112dc..37cf951  stable     -> origin/stable
 * [new tag]         next-20111014 -> next-20111014

compat-wireless code metrics

    814119 - Total upstream lines of code being pulled
      2431 - backport code changes
      2113 - backport code additions
       318 - backport code deletions
      8588 - backport from compat module
     11019 - total backport code
    1.3535 - % of code consists of backport work

^ permalink raw reply

* Re: iwlagn: WARN_ON() in iwl_get_idle_rx_chain_count()
From: Michał Mirosław @ 2011-10-14 19:21 UTC (permalink / raw)
  To: wwguy
  Cc: Intel Linux Wireless, linux-wireless@vger.kernel.org,
	netdev@vger.kernel.org
In-Reply-To: <1318606158.12009.2.camel@wwguy-ubuntu>

On Fri, Oct 14, 2011 at 08:29:18AM -0700, wwguy wrote:
> Could you try the attach patch and see if it fix your problem.
[attached patch removed]

Backported and applied. I'll test it for couple of days.

Best Regards,
Michał Mirosław

^ permalink raw reply

* [PATCH 1/6] iwlagn: update wowlan API
From: Wey-Yi Guy @ 2011-10-14 19:54 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Johannes Berg, Wey-Yi Guy
In-Reply-To: <1318622088-14679-1-git-send-email-wey-yi.w.guy@intel.com>

From: Johannes Berg <johannes.berg@intel.com>

The WoWLAN API changed due to netdetect and
we now have a more generic "D3 configuration"
command that enables the sysassert & rfkill
wakeup triggers.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c      |   13 ++++++++++---
 drivers/net/wireless/iwlwifi/iwl-commands.h |   27 +++++++++++++++++++--------
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index ccba69b..47dbcca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2028,6 +2028,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
 		.tkip = &tkip_cmd,
 		.use_tkip = false,
 	};
+	struct iwlagn_d3_config_cmd d3_cfg_cmd = {};
 	int ret, i;
 	u16 seq;
 
@@ -2085,13 +2086,14 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
 	if (wowlan->four_way_handshake)
 		wakeup_filter_cmd.enabled |=
 			cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
-	if (wowlan->rfkill_release)
-		wakeup_filter_cmd.enabled |=
-			cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_RFKILL);
 	if (wowlan->n_patterns)
 		wakeup_filter_cmd.enabled |=
 			cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH);
 
+	if (wowlan->rfkill_release)
+		d3_cfg_cmd.wakeup_flags |=
+			cpu_to_le32(IWLAGN_D3_WAKEUP_RFKILL);
+
 	iwl_scan_cancel_timeout(priv, 200);
 
 	memcpy(&rxon, &ctx->active, sizeof(rxon));
@@ -2179,6 +2181,11 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
 		}
 	}
 
+	ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC,
+				     sizeof(d3_cfg_cmd), &d3_cfg_cmd);
+	if (ret)
+		goto error;
+
 	ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER,
 				 CMD_SYNC, sizeof(wakeup_filter_cmd),
 				 &wakeup_filter_cmd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 69d5f85..f4eccf5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -198,6 +198,7 @@ enum {
 	REPLY_WOWLAN_TKIP_PARAMS = 0xe3,
 	REPLY_WOWLAN_KEK_KCK_MATERIAL = 0xe4,
 	REPLY_WOWLAN_GET_STATUS = 0xe5,
+	REPLY_D3_CONFIG = 0xd3,
 
 	REPLY_MAX = 0xff
 };
@@ -3801,6 +3802,19 @@ struct iwl_bt_coex_prot_env_cmd {
 } __attribute__((packed));
 
 /*
+ * REPLY_D3_CONFIG
+ */
+enum iwlagn_d3_wakeup_filters {
+	IWLAGN_D3_WAKEUP_RFKILL		= BIT(0),
+	IWLAGN_D3_WAKEUP_SYSASSERT	= BIT(1),
+};
+
+struct iwlagn_d3_config_cmd {
+	__le32 min_sleep_time;
+	__le32 wakeup_flags;
+} __packed;
+
+/*
  * REPLY_WOWLAN_PATTERNS
  */
 #define IWLAGN_WOWLAN_MIN_PATTERN_LEN	16
@@ -3830,19 +3844,16 @@ enum iwlagn_wowlan_wakeup_filters {
 	IWLAGN_WOWLAN_WAKEUP_BEACON_MISS	= BIT(2),
 	IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE	= BIT(3),
 	IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL	= BIT(4),
-	IWLAGN_WOWLAN_WAKEUP_RFKILL		= BIT(5),
-	IWLAGN_WOWLAN_WAKEUP_UCODE_ERROR	= BIT(6),
-	IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ	= BIT(7),
-	IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE	= BIT(8),
-	IWLAGN_WOWLAN_WAKEUP_ALWAYS		= BIT(9),
-	IWLAGN_WOWLAN_WAKEUP_ENABLE_NET_DETECT	= BIT(10),
+	IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ	= BIT(5),
+	IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE	= BIT(6),
+	IWLAGN_WOWLAN_WAKEUP_ALWAYS		= BIT(7),
+	IWLAGN_WOWLAN_WAKEUP_ENABLE_NET_DETECT	= BIT(8),
 };
 
 struct iwlagn_wowlan_wakeup_filter_cmd {
 	__le32 enabled;
 	__le16 non_qos_seq;
-	u8 min_sleep_seconds;
-	u8 reserved;
+	__le16 reserved;
 	__le16 qos_seq[8];
 };
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/6] iwlagn: remove unnecessary type for tracing operations
From: Wey-Yi Guy @ 2011-10-14 19:54 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Don Fry, Wey-Yi Guy
In-Reply-To: <1318622088-14679-1-git-send-email-wey-yi.w.guy@intel.com>

From: Don Fry <donald.h.fry@intel.com>

The device tracing routines only use the priv pointer as an opaque
value.  Change from a typed iwl_priv pointer to a null pointer and
eliminate the need to include iwl_priv.h.  CMD_ASYNC is defined in
iwl_shared.h which is the only reason it is included.

Signed-off-by: Don Fry <donald.h.fry@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-devtrace.c |    2 +-
 drivers/net/wireless/iwlwifi/iwl-devtrace.h |   23 +++++++++++------------
 2 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index a635a7e..2a2c8de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -28,7 +28,7 @@
 
 /* sparse doesn't like tracepoint macros */
 #ifndef __CHECKER__
-#include "iwl-dev.h"
+#include "iwl-trans.h"
 
 #define CREATE_TRACE_POINTS
 #include "iwl-devtrace.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 8a51c5c..f9d3319 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -29,7 +29,6 @@
 
 #include <linux/tracepoint.h>
 
-struct iwl_priv;
 
 #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__)
 #undef TRACE_EVENT
@@ -37,14 +36,14 @@ struct iwl_priv;
 static inline void trace_ ## name(proto) {}
 #endif
 
-#define PRIV_ENTRY	__field(struct iwl_priv *, priv)
+#define PRIV_ENTRY	__field(void *, priv)
 #define PRIV_ASSIGN	__entry->priv = priv
 
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM iwlwifi_io
 
 TRACE_EVENT(iwlwifi_dev_ioread32,
-	TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val),
+	TP_PROTO(void *priv, u32 offs, u32 val),
 	TP_ARGS(priv, offs, val),
 	TP_STRUCT__entry(
 		PRIV_ENTRY
@@ -60,7 +59,7 @@ TRACE_EVENT(iwlwifi_dev_ioread32,
 );
 
 TRACE_EVENT(iwlwifi_dev_iowrite8,
-	TP_PROTO(struct iwl_priv *priv, u32 offs, u8 val),
+	TP_PROTO(void *priv, u32 offs, u8 val),
 	TP_ARGS(priv, offs, val),
 	TP_STRUCT__entry(
 		PRIV_ENTRY
@@ -76,7 +75,7 @@ TRACE_EVENT(iwlwifi_dev_iowrite8,
 );
 
 TRACE_EVENT(iwlwifi_dev_iowrite32,
-	TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val),
+	TP_PROTO(void *priv, u32 offs, u32 val),
 	TP_ARGS(priv, offs, val),
 	TP_STRUCT__entry(
 		PRIV_ENTRY
@@ -95,7 +94,7 @@ TRACE_EVENT(iwlwifi_dev_iowrite32,
 #define TRACE_SYSTEM iwlwifi_ucode
 
 TRACE_EVENT(iwlwifi_dev_ucode_cont_event,
-	TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev),
+	TP_PROTO(void *priv, u32 time, u32 data, u32 ev),
 	TP_ARGS(priv, time, data, ev),
 	TP_STRUCT__entry(
 		PRIV_ENTRY
@@ -115,7 +114,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_cont_event,
 );
 
 TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
-	TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry),
+	TP_PROTO(void *priv, u32 wraps, u32 n_entry, u32 p_entry),
 	TP_ARGS(priv, wraps, n_entry, p_entry),
 	TP_STRUCT__entry(
 		PRIV_ENTRY
@@ -139,7 +138,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
 #define TRACE_SYSTEM iwlwifi
 
 TRACE_EVENT(iwlwifi_dev_hcmd,
-	TP_PROTO(struct iwl_priv *priv, u32 flags,
+	TP_PROTO(void *priv, u32 flags,
 		 const void *hcmd0, size_t len0,
 		 const void *hcmd1, size_t len1,
 		 const void *hcmd2, size_t len2),
@@ -164,7 +163,7 @@ TRACE_EVENT(iwlwifi_dev_hcmd,
 );
 
 TRACE_EVENT(iwlwifi_dev_rx,
-	TP_PROTO(struct iwl_priv *priv, void *rxbuf, size_t len),
+	TP_PROTO(void *priv, void *rxbuf, size_t len),
 	TP_ARGS(priv, rxbuf, len),
 	TP_STRUCT__entry(
 		PRIV_ENTRY
@@ -179,7 +178,7 @@ TRACE_EVENT(iwlwifi_dev_rx,
 );
 
 TRACE_EVENT(iwlwifi_dev_tx,
-	TP_PROTO(struct iwl_priv *priv, void *tfd, size_t tfdlen,
+	TP_PROTO(void *priv, void *tfd, size_t tfdlen,
 		 void *buf0, size_t buf0_len,
 		 void *buf1, size_t buf1_len),
 	TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len),
@@ -211,7 +210,7 @@ TRACE_EVENT(iwlwifi_dev_tx,
 );
 
 TRACE_EVENT(iwlwifi_dev_ucode_error,
-	TP_PROTO(struct iwl_priv *priv, u32 desc, u32 tsf_low,
+	TP_PROTO(void *priv, u32 desc, u32 tsf_low,
 		 u32 data1, u32 data2, u32 line, u32 blink1,
 		 u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
 		 u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver,
@@ -271,7 +270,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
 );
 
 TRACE_EVENT(iwlwifi_dev_ucode_event,
-	TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev),
+	TP_PROTO(void *priv, u32 time, u32 data, u32 ev),
 	TP_ARGS(priv, time, data, ev),
 	TP_STRUCT__entry(
 		PRIV_ENTRY
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 0/6] update for 3.2
From: Wey-Yi Guy @ 2011-10-14 19:54 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Wey-Yi Guy

We address the race issue point out by Stanislaw.
We also fix a Wowlan firmware related problem.
Plus more cleanup works 

Don Fry (2):
  iwlagn: remove unnecessary type for tracing operations
  iwlagn: simplify iwl_alloc_all

Emmanuel Grumbach (1):
  iwlagn: fix the race in the unmapping of the HCMD

Johannes Berg (2):
  iwlagn: update wowlan API
  iwlagn: use 6 Mbps rate for no-CCK scans

Wey-Yi Guy (1):
  iwlwifi: HW rev for 105 and 135 series

these patches are also available from wireless-next-2.6 branch on
 git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git

kernel.org is back, but I still not establish my account yet; so all the
patches are not push into git.kernel.org yet. I will push as soon I have my kernel.org account ready


 drivers/net/wireless/iwlwifi/iwl-agn.c        |   23 +++++++++++++--------
 drivers/net/wireless/iwlwifi/iwl-commands.h   |   27 +++++++++++++++++-------
 drivers/net/wireless/iwlwifi/iwl-csr.h        |    4 +-
 drivers/net/wireless/iwlwifi/iwl-devtrace.c   |    2 +-
 drivers/net/wireless/iwlwifi/iwl-devtrace.h   |   23 ++++++++++-----------
 drivers/net/wireless/iwlwifi/iwl-scan.c       |    3 +-
 drivers/net/wireless/iwlwifi/iwl-trans-pcie.c |   12 +++++++---
 7 files changed, 57 insertions(+), 37 deletions(-)


^ permalink raw reply

* [PATCH 5/6] iwlagn: fix the race in the unmapping of the HCMD
From: Wey-Yi Guy @ 2011-10-14 19:54 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Emmanuel Grumbach, Wey-Yi Guy
In-Reply-To: <1318622088-14679-1-git-send-email-wey-yi.w.guy@intel.com>

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

As Stanislaw pointed out, my patch

	iwlagn: fix a race in the unmapping of the TFDs

solved only part of the problem. The race still exists for TFDs of
the host commands. Fix that too.

Reported-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-trans-pcie.c |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 8e8c75c..da34110 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -407,6 +407,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
 	struct iwl_queue *q = &txq->q;
 	enum dma_data_direction dma_dir;
 	unsigned long flags;
+	spinlock_t *lock;
 
 	if (!q->n_bd)
 		return;
@@ -414,19 +415,22 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
 	/* In the command queue, all the TBs are mapped as BIDI
 	 * so unmap them as such.
 	 */
-	if (txq_id == trans->shrd->cmd_queue)
+	if (txq_id == trans->shrd->cmd_queue) {
 		dma_dir = DMA_BIDIRECTIONAL;
-	else
+		lock = &trans->hcmd_lock;
+	} else {
 		dma_dir = DMA_TO_DEVICE;
+		lock = &trans->shrd->sta_lock;
+	}
 
-	spin_lock_irqsave(&trans->shrd->sta_lock, flags);
+	spin_lock_irqsave(lock, flags);
 	while (q->write_ptr != q->read_ptr) {
 		/* The read_ptr needs to bound by q->n_window */
 		iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr),
 				    dma_dir);
 		q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
 	}
-	spin_unlock_irqrestore(&trans->shrd->sta_lock, flags);
+	spin_unlock_irqrestore(lock, flags);
 }
 
 /**
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 3/6] iwlwifi: HW rev for 105 and 135 series
From: Wey-Yi Guy @ 2011-10-14 19:54 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Wey-Yi Guy
In-Reply-To: <1318622088-14679-1-git-send-email-wey-yi.w.guy@intel.com>

Set the HW rev. for both 105 and 135 series

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-csr.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index b9f3267..fbc3095 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -284,8 +284,8 @@
 #define CSR_HW_REV_TYPE_6x35	       CSR_HW_REV_TYPE_6x05
 #define CSR_HW_REV_TYPE_2x30	       (0x00000C0)
 #define CSR_HW_REV_TYPE_2x00	       (0x0000100)
-#define CSR_HW_REV_TYPE_200	       (0x0000110)
-#define CSR_HW_REV_TYPE_230	       (0x0000120)
+#define CSR_HW_REV_TYPE_105	       (0x0000110)
+#define CSR_HW_REV_TYPE_135	       (0x0000120)
 #define CSR_HW_REV_TYPE_NONE           (0x00001F0)
 
 /* EEPROM REG */
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 6/6] iwlagn: use 6 Mbps rate for no-CCK scans
From: Wey-Yi Guy @ 2011-10-14 19:54 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Johannes Berg, Wey-Yi Guy
In-Reply-To: <1318622088-14679-1-git-send-email-wey-yi.w.guy@intel.com>

From: Johannes Berg <johannes.berg@intel.com>

When userspace requested that a scan not be
done with CCK rates, use 6 Mbps. This is used
for example for P2P scanning.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-scan.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index e5d727f..a26fbd3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -678,7 +678,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 			priv->contexts[IWL_RXON_CTX_BSS].active.flags &
 						RXON_FLG_CHANNEL_MODE_MSK)
 				       >> RXON_FLG_CHANNEL_MODE_POS;
-		if (chan_mod == CHANNEL_MODE_PURE_40) {
+		if ((priv->scan_request && priv->scan_request->no_cck) ||
+		    chan_mod == CHANNEL_MODE_PURE_40) {
 			rate = IWL_RATE_6M_PLCP;
 		} else {
 			rate = IWL_RATE_1M_PLCP;
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 4/6] iwlagn: simplify iwl_alloc_all
From: Wey-Yi Guy @ 2011-10-14 19:54 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Don Fry, Wey-Yi Guy
In-Reply-To: <1318622088-14679-1-git-send-email-wey-yi.w.guy@intel.com>

From: Don Fry <donald.h.fry@intel.com>

The iwl_alloc_all routine is only called once.  Delete the argument
and print an error in the calling routine if needed.

Signed-off-by: Don Fry <donald.h.fry@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 47dbcca..9d463cf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3178,7 +3178,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
 }
 
 /* This function both allocates and initializes hw and priv. */
-static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
+static struct ieee80211_hw *iwl_alloc_all(void)
 {
 	struct iwl_priv *priv;
 	/* mac80211 allocates memory for this device instance, including
@@ -3186,11 +3186,8 @@ static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
 	struct ieee80211_hw *hw;
 
 	hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops);
-	if (hw == NULL) {
-		pr_err("%s: Can not allocate network device\n",
-		       cfg->name);
+	if (!hw)
 		goto out;
-	}
 
 	priv = hw->priv;
 	priv->hw = hw;
@@ -3211,8 +3208,9 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
 	/************************
 	 * 1. Allocating HW data
 	 ************************/
-	hw = iwl_alloc_all(cfg);
+	hw = iwl_alloc_all();
 	if (!hw) {
+		pr_err("%s: Cannot allocate network device\n", cfg->name);
 		err = -ENOMEM;
 		goto out;
 	}
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2] mac80211: handle HT PHY BSS membership selector value correctly
From: Christian Lamparter @ 2011-10-14 22:14 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: linux-wireless, johannes, linville
In-Reply-To: <201110141012.21010.chunkeey@googlemail.com>

802.11n-2009 extends the supported rates element with a
magic value which can be used to prevent legacy stations
from joining the BSS.

However, this magic value is not a rate like the others
and the magic can simply be ignored/skipped at this late
stage.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>---
---
v2:
	Jouni's comment... Although I'm still not sure what is
	the difference between the membership and basic
	rate flag at this point.
---
 include/linux/ieee80211.h |    3 ++
 net/mac80211/mlme.c       |   75 +++++++++++++++++++++++++--------------------
 2 files changed, 45 insertions(+), 33 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 48363c3..9789aed 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -770,6 +770,9 @@ struct ieee80211_mgmt {
 	} u;
 } __attribute__ ((packed));
 
+/* Supported Rates value encodings in 802.11n-2009 7.3.2.2 */
+#define BSS_MEMBERSHIP_SELECTOR_HT_PHY	127
+
 /* mgmt header + 1 byte category code */
 #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u)
 
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 0e5d8da..c0e54c5 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1463,6 +1463,42 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
 	return RX_MGMT_CFG80211_DISASSOC;
 }
 
+static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
+				u8 *supp_rates, unsigned int supp_rates_len,
+				u32 *rates, u32 *basic_rates,
+				bool *have_higher_than_11mbit)
+{
+	int i, j;
+
+	for (i = 0; i < supp_rates_len; i++) {
+		int rate = (supp_rates[i] & 0x7f) * 5;
+		bool is_basic = !!(supp_rates[i] & 0x80);
+
+		if (rate > 110)
+			*have_higher_than_11mbit = true;
+
+		/*
+		 * BSS_MEMBERSHIP_SELECTOR_HT_PHY is defined in 802.11n-2009
+		 * 7.3.2.2 as a magic value instead of a rate. Hence, skip it.
+		 *
+		 * Note: Even through the membership selector and the basic
+		 *	 rate flag share the same bit, they are not exactly
+		 *	 the same.
+		 */
+		if (!!(supp_rates[i] & 0x80) &&
+		    (supp_rates[i] & 0x7f) == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
+			continue;
+
+		for (j = 0; j < sband->n_bitrates; j++) {
+			if (sband->bitrates[j].bitrate == rate) {
+				*rates |= BIT(j);
+				if (is_basic)
+					*basic_rates |= BIT(j);
+				break;
+			}
+		}
+	}
+}
 
 static bool ieee80211_assoc_success(struct ieee80211_work *wk,
 				    struct ieee80211_mgmt *mgmt, size_t len)
@@ -1479,7 +1515,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
 	struct ieee802_11_elems elems;
 	struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
 	u32 changed = 0;
-	int i, j, err;
+	int err;
 	bool have_higher_than_11mbit = false;
 	u16 ap_ht_cap_flags;
 
@@ -1525,39 +1561,12 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
 	basic_rates = 0;
 	sband = local->hw.wiphy->bands[wk->chan->band];
 
-	for (i = 0; i < elems.supp_rates_len; i++) {
-		int rate = (elems.supp_rates[i] & 0x7f) * 5;
-		bool is_basic = !!(elems.supp_rates[i] & 0x80);
-
-		if (rate > 110)
-			have_higher_than_11mbit = true;
-
-		for (j = 0; j < sband->n_bitrates; j++) {
-			if (sband->bitrates[j].bitrate == rate) {
-				rates |= BIT(j);
-				if (is_basic)
-					basic_rates |= BIT(j);
-				break;
-			}
-		}
-	}
-
-	for (i = 0; i < elems.ext_supp_rates_len; i++) {
-		int rate = (elems.ext_supp_rates[i] & 0x7f) * 5;
-		bool is_basic = !!(elems.ext_supp_rates[i] & 0x80);
+	ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len,
+			    &rates, &basic_rates, &have_higher_than_11mbit);
 
-		if (rate > 110)
-			have_higher_than_11mbit = true;
-
-		for (j = 0; j < sband->n_bitrates; j++) {
-			if (sband->bitrates[j].bitrate == rate) {
-				rates |= BIT(j);
-				if (is_basic)
-					basic_rates |= BIT(j);
-				break;
-			}
-		}
-	}
+	ieee80211_get_rates(sband, elems.ext_supp_rates,
+			    elems.ext_supp_rates_len, &rates, &basic_rates,
+			    &have_higher_than_11mbit);
 
 	sta->sta.supp_rates[wk->chan->band] = rates;
 	sdata->vif.bss_conf.basic_rates = basic_rates;
-- 
1.7.6.3

^ permalink raw reply related

* [PATCH] Implement support for QOS-enable and QOS-disable from userspace
From: Rishi Panjwani @ 2011-10-15  0:38 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Rishi Panjwani

Implement support for QOS-enable and QOS-disable from userspace
    
In order to allow user space based QOS control we use the available debugfs
infrastructure. With this feature, user can make changes to qos parameters,
thereby allowing creation and deletion of user defined priority streams and
features like uapsd. This feature has been added for testing purposes. As
described in the commit description, all parameters are necessary for create_qos
and delete_qos
   
Rishi Panjwani (1):
  ath6kl: Implement support for QOS-enable and QOS-disable from
    userspace

 drivers/net/wireless/ath/ath6kl/debug.c |  250 +++++++++++++++++++++++++++++--
 1 files changed, 236 insertions(+), 14 deletions(-)


^ permalink raw reply

* [PATCH] ath6kl: Implement support for QOS-enable and QOS-disable from userspace
From: Rishi Panjwani @ 2011-10-15  0:38 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Rishi Panjwani
In-Reply-To: <1318639086-28236-1-git-send-email-rpanjwan@qca.qualcomm.com>

In order to allow user space based QOS control we use the available debugfs
infrastructure. With this feature, user can make changes to qos parameters,
thereby allowing creation and deletion of user defined priority streams and
features like uapsd. This feature has been added for testing purposes.

All 21 parameters for the create_qos command are mandatory in the correct
order. They have to be written to the create_qos file in
the ath6kl debug directory. These parameters(in order) are:
1)user priority
2)direction
3)traffic class
4)traffic type
5)voice PS capability
6)min service intvl
7)max service intvl
8)inactivity intvl
9)suspension intvl
10)serv start time
11)tsid
12)nominal msdu
13)max msdu
14)min data rate
15)mean data rate
16)peak data rate
17)max burst size
18)delay bound
19)min phy rate
20)surplus bw allowance
21)medium time
For eg :
echo "6 2 3 1 1 9999999 9999999 9999999 7777777 0 6 45000 200 56789000
56789000 5678900 0 0 9999999 20000 0" > create_qos

delete_qos requires 2 parameters:
1)traffic class
2)tsid
For eg :
echo "3 1" > delete_qos

Signed-off-by: Rishi Panjwani <rpanjwan@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/debug.c |  250 +++++++++++++++++++++++++++++--
 1 files changed, 236 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index dd37785..383a3c7 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1,18 +1,18 @@
 /*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
+* Copyright (c) 2004-2011 Atheros Communications Inc.
+*
+* Permission to use, copy, modify, and/or distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
 
 #include "core.h"
 
@@ -1240,6 +1240,222 @@ static const struct file_operations fops_disconnect_timeout = {
 	.llseek = default_llseek,
 };
 
+static ssize_t ath6kl_create_qos_write(struct file *file,
+						const char __user *user_buf,
+						size_t count, loff_t *ppos)
+{
+
+	struct ath6kl *ar = file->private_data;
+	char buf[100];
+	ssize_t len;
+	char *sptr, *token;
+	struct wmi_create_pstream_cmd pstream;
+	u32 val32;
+	u16 val16;
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+	buf[len] = '\0';
+	sptr = buf;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.user_pri))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.traffic_direc))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.traffic_class))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.traffic_type))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.voice_psc_cap))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.min_service_int = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.max_service_int = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.inactivity_int = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.suspension_int = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.service_start_time = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.tsid))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou16(token, 0, &val16))
+		return -EINVAL;
+	pstream.nominal_msdu = cpu_to_le16(val16);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou16(token, 0, &val16))
+		return -EINVAL;
+	pstream.max_msdu = cpu_to_le16(val16);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.min_data_rate = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.mean_data_rate = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.peak_data_rate = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.max_burst_size = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.delay_bound = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.min_phy_rate = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.sba = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.medium_time = cpu_to_le32(val32);
+
+	ath6kl_wmi_create_pstream_cmd(ar->wmi, &pstream);
+
+	return count;
+}
+
+
+static const struct file_operations fops_create_qos = {
+	.write = ath6kl_create_qos_write,
+	.open = ath6kl_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t ath6kl_delete_qos_write(struct file *file,
+				const char __user *user_buf,
+				size_t count, loff_t *ppos)
+{
+
+	struct ath6kl *ar = file->private_data;
+	char buf[100];
+	ssize_t len;
+	char *sptr, *token;
+	u8 traffic_class;
+	u8 tsid;
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+	buf[len] = '\0';
+	sptr = buf;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &traffic_class))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &tsid))
+		return -EINVAL;
+
+	ath6kl_wmi_delete_pstream_cmd(ar->wmi, traffic_class, tsid);
+
+	return count;
+}
+
+
+static const struct file_operations fops_delete_qos = {
+	.write = ath6kl_delete_qos_write,
+	.open = ath6kl_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
 int ath6kl_debug_init(struct ath6kl *ar)
 {
 	ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE);
@@ -1313,6 +1529,12 @@ int ath6kl_debug_init(struct ath6kl *ar)
 	debugfs_create_file("disconnect_timeout", S_IRUSR | S_IWUSR,
 			    ar->debugfs_phy, ar, &fops_disconnect_timeout);
 
+	debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar,
+				&fops_create_qos);
+
+	debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar,
+				&fops_delete_qos);
+
 	return 0;
 }
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH] ath6kl: Implement support for QOS-enable and QOS-disable from userspace
From: Rishi Panjwani @ 2011-10-15  0:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Rishi Panjwani
In-Reply-To: <1318639687-28457-1-git-send-email-rpanjwan@qca.qualcomm.com>

In order to allow user space based QOS control we use the available debugfs
infrastructure. With this feature, user can make changes to qos parameters,
thereby allowing creation and deletion of user defined priority streams and
features like uapsd. This feature has been added for testing purposes.

All 21 parameters for the create_qos command are mandatory in the correct
order. They have to be written to the create_qos file in
the ath6kl debug directory. These parameters(in order) are:
1)user priority
2)direction
3)traffic class
4)traffic type
5)voice PS capability
6)min service intvl
7)max service intvl
8)inactivity intvl
9)suspension intvl
10)serv start time
11)tsid
12)nominal msdu
13)max msdu
14)min data rate
15)mean data rate
16)peak data rate
17)max burst size
18)delay bound
19)min phy rate
20)surplus bw allowance
21)medium time
For eg :
echo "6 2 3 1 1 9999999 9999999 9999999 7777777 0 6 45000 200 56789000
56789000 5678900 0 0 9999999 20000 0" > create_qos

delete_qos requires 2 parameters:
1)traffic class
2)tsid
For eg :
echo "3 1" > delete_qos

Signed-off-by: Rishi Panjwani <rpanjwan@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/debug.c |  250 +++++++++++++++++++++++++++++--
 1 files changed, 236 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index dd37785..383a3c7 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1240,6 +1240,222 @@ static const struct file_operations fops_disconnect_timeout = {
 	.llseek = default_llseek,
 };
 
+static ssize_t ath6kl_create_qos_write(struct file *file,
+						const char __user *user_buf,
+						size_t count, loff_t *ppos)
+{
+
+	struct ath6kl *ar = file->private_data;
+	char buf[100];
+	ssize_t len;
+	char *sptr, *token;
+	struct wmi_create_pstream_cmd pstream;
+	u32 val32;
+	u16 val16;
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+	buf[len] = '\0';
+	sptr = buf;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.user_pri))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.traffic_direc))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.traffic_class))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.traffic_type))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.voice_psc_cap))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.min_service_int = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.max_service_int = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.inactivity_int = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.suspension_int = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.service_start_time = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.tsid))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou16(token, 0, &val16))
+		return -EINVAL;
+	pstream.nominal_msdu = cpu_to_le16(val16);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou16(token, 0, &val16))
+		return -EINVAL;
+	pstream.max_msdu = cpu_to_le16(val16);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.min_data_rate = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.mean_data_rate = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.peak_data_rate = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.max_burst_size = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.delay_bound = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.min_phy_rate = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.sba = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.medium_time = cpu_to_le32(val32);
+
+	ath6kl_wmi_create_pstream_cmd(ar->wmi, &pstream);
+
+	return count;
+}
+
+
+static const struct file_operations fops_create_qos = {
+	.write = ath6kl_create_qos_write,
+	.open = ath6kl_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t ath6kl_delete_qos_write(struct file *file,
+				const char __user *user_buf,
+				size_t count, loff_t *ppos)
+{
+
+	struct ath6kl *ar = file->private_data;
+	char buf[100];
+	ssize_t len;
+	char *sptr, *token;
+	u8 traffic_class;
+	u8 tsid;
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+	buf[len] = '\0';
+	sptr = buf;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &traffic_class))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &tsid))
+		return -EINVAL;
+
+	ath6kl_wmi_delete_pstream_cmd(ar->wmi, traffic_class, tsid);
+
+	return count;
+}
+
+
+static const struct file_operations fops_delete_qos = {
+	.write = ath6kl_delete_qos_write,
+	.open = ath6kl_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
 int ath6kl_debug_init(struct ath6kl *ar)
 {
 	ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE);
@@ -1313,6 +1529,12 @@ int ath6kl_debug_init(struct ath6kl *ar)
 	debugfs_create_file("disconnect_timeout", S_IRUSR | S_IWUSR,
 			    ar->debugfs_phy, ar, &fops_disconnect_timeout);
 
+	debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar,
+				&fops_create_qos);
+
+	debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar,
+				&fops_delete_qos);
+
 	return 0;
 }
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH] Implement support for QOS-enable and QOS-disable from userspace
From: Rishi Panjwani @ 2011-10-15  0:48 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Rishi Panjwani

Implement support for QOS-enable and QOS-disable from userspace
    
In order to allow user space based QOS control we use the available debugfs
infrastructure. With this feature, user can make changes to qos parameters,
thereby allowing creation and deletion of user defined priority streams and
features like uapsd. This feature has been added for testing purposes. As
described in the commit description, all parameters are necessary for create_qos
and delete_qos
   
Rishi Panjwani (1):
  ath6kl: Implement support for QOS-enable and QOS-disable from
    userspace

 drivers/net/wireless/ath/ath6kl/debug.c |  250 +++++++++++++++++++++++++++++--
 1 files changed, 236 insertions(+), 14 deletions(-)


^ permalink raw reply

* RE: [PATCH] ath6kl: Implement support for QOS-enable and QOS-disable from userspace
From: Panjwani, Rishi @ 2011-10-15  0:52 UTC (permalink / raw)
  To: Valo, Kalle; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1318639687-28457-2-git-send-email-rpanjwan@qca.qualcomm.com>

All,

Kindly ignore the previous patch I had sent out. This is the patch I am looking forward to get publically reviewed and committed :

-----Original Message-----
From: Panjwani, Rishi 
Sent: Friday, October 14, 2011 5:48 PM
To: Valo, Kalle
Cc: linux-wireless@vger.kernel.org; Panjwani, Rishi
Subject: [PATCH] ath6kl: Implement support for QOS-enable and QOS-disable from userspace

In order to allow user space based QOS control we use the available debugfs infrastructure. With this feature, user can make changes to qos parameters, thereby allowing creation and deletion of user defined priority streams and features like uapsd. This feature has been added for testing purposes.

All 21 parameters for the create_qos command are mandatory in the correct order. They have to be written to the create_qos file in the ath6kl debug directory. These parameters(in order) are:
1)user priority
2)direction
3)traffic class
4)traffic type
5)voice PS capability
6)min service intvl
7)max service intvl
8)inactivity intvl
9)suspension intvl
10)serv start time
11)tsid
12)nominal msdu
13)max msdu
14)min data rate
15)mean data rate
16)peak data rate
17)max burst size
18)delay bound
19)min phy rate
20)surplus bw allowance
21)medium time
For eg :
echo "6 2 3 1 1 9999999 9999999 9999999 7777777 0 6 45000 200 56789000
56789000 5678900 0 0 9999999 20000 0" > create_qos

delete_qos requires 2 parameters:
1)traffic class
2)tsid
For eg :
echo "3 1" > delete_qos

Signed-off-by: Rishi Panjwani <rpanjwan@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/debug.c |  250 +++++++++++++++++++++++++++++--
 1 files changed, 236 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index dd37785..383a3c7 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1240,6 +1240,222 @@ static const struct file_operations fops_disconnect_timeout = {
 	.llseek = default_llseek,
 };
 
+static ssize_t ath6kl_create_qos_write(struct file *file,
+						const char __user *user_buf,
+						size_t count, loff_t *ppos)
+{
+
+	struct ath6kl *ar = file->private_data;
+	char buf[100];
+	ssize_t len;
+	char *sptr, *token;
+	struct wmi_create_pstream_cmd pstream;
+	u32 val32;
+	u16 val16;
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+	buf[len] = '\0';
+	sptr = buf;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.user_pri))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.traffic_direc))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.traffic_class))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.traffic_type))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.voice_psc_cap))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.min_service_int = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.max_service_int = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.inactivity_int = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.suspension_int = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.service_start_time = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &pstream.tsid))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou16(token, 0, &val16))
+		return -EINVAL;
+	pstream.nominal_msdu = cpu_to_le16(val16);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou16(token, 0, &val16))
+		return -EINVAL;
+	pstream.max_msdu = cpu_to_le16(val16);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.min_data_rate = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.mean_data_rate = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.peak_data_rate = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.max_burst_size = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.delay_bound = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.min_phy_rate = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.sba = cpu_to_le32(val32);
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou32(token, 0, &val32))
+		return -EINVAL;
+	pstream.medium_time = cpu_to_le32(val32);
+
+	ath6kl_wmi_create_pstream_cmd(ar->wmi, &pstream);
+
+	return count;
+}
+
+
+static const struct file_operations fops_create_qos = {
+	.write = ath6kl_create_qos_write,
+	.open = ath6kl_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t ath6kl_delete_qos_write(struct file *file,
+				const char __user *user_buf,
+				size_t count, loff_t *ppos)
+{
+
+	struct ath6kl *ar = file->private_data;
+	char buf[100];
+	ssize_t len;
+	char *sptr, *token;
+	u8 traffic_class;
+	u8 tsid;
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+	buf[len] = '\0';
+	sptr = buf;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &traffic_class))
+		return -EINVAL;
+
+	token = strsep(&sptr, " ");
+	if (!token)
+		return -EINVAL;
+	if (kstrtou8(token, 0, &tsid))
+		return -EINVAL;
+
+	ath6kl_wmi_delete_pstream_cmd(ar->wmi, traffic_class, tsid);
+
+	return count;
+}
+
+
+static const struct file_operations fops_delete_qos = {
+	.write = ath6kl_delete_qos_write,
+	.open = ath6kl_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
 int ath6kl_debug_init(struct ath6kl *ar)  {
 	ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE); @@ -1313,6 +1529,12 @@ int ath6kl_debug_init(struct ath6kl *ar)
 	debugfs_create_file("disconnect_timeout", S_IRUSR | S_IWUSR,
 			    ar->debugfs_phy, ar, &fops_disconnect_timeout);
 
+	debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar,
+				&fops_create_qos);
+
+	debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar,
+				&fops_delete_qos);
+
 	return 0;
 }
 
--
1.7.0.4


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox