mac80211: update to wireless-testing 2016-06-20
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
		@@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
PKG_NAME:=mac80211
 | 
					PKG_NAME:=mac80211
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PKG_VERSION:=2016-05-12
 | 
					PKG_VERSION:=2016-06-20
 | 
				
			||||||
PKG_RELEASE:=1
 | 
					PKG_RELEASE:=1
 | 
				
			||||||
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 | 
					PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 | 
				
			||||||
PKG_BACKPORT_VERSION:=
 | 
					PKG_BACKPORT_VERSION:=
 | 
				
			||||||
PKG_MD5SUM:=2142cf38509896dca108624e7c193611
 | 
					PKG_MD5SUM:=29c79bdc3928ef5113b17042ebda9237
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
 | 
					PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
 | 
				
			||||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
 | 
					PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,21 +0,0 @@
 | 
				
			|||||||
From: Felix Fietkau <nbd@nbd.name>
 | 
					 | 
				
			||||||
Date: Sat, 14 May 2016 16:39:35 +0200
 | 
					 | 
				
			||||||
Subject: [PATCH] header: backport GENL_UNS_ADMIN_PERM
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 create mode 100644 backport-include/uapi/linux/genetlink.h
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- /dev/null
 | 
					 | 
				
			||||||
+++ b/backport-include/uapi/linux/genetlink.h
 | 
					 | 
				
			||||||
@@ -0,0 +1,10 @@
 | 
					 | 
				
			||||||
+#ifndef __COMPAT_UAPI_LINUX_GENETLINK_H
 | 
					 | 
				
			||||||
+#define __COMPAT_UAPI_LINUX_GENETLINK_H
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+#include_next <uapi/linux/genetlink.h>
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+#ifndef GENL_UNS_ADMIN_PERM
 | 
					 | 
				
			||||||
+#define GENL_UNS_ADMIN_PERM GENL_ADMIN_PERM
 | 
					 | 
				
			||||||
+#endif
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+#endif
 | 
					 | 
				
			||||||
@@ -1,158 +0,0 @@
 | 
				
			|||||||
From: Felix Fietkau <nbd@nbd.name>
 | 
					 | 
				
			||||||
Date: Sat, 14 May 2016 16:40:16 +0200
 | 
					 | 
				
			||||||
Subject: [PATCH] header: backport nla_put_u64_64bit and nla_put_64bit
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- a/backport-include/net/netlink.h
 | 
					 | 
				
			||||||
+++ b/backport-include/net/netlink.h
 | 
					 | 
				
			||||||
@@ -189,4 +189,148 @@ static inline __le64 nla_get_le64(const
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 #endif /* < 4.4 */
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/**
 | 
					 | 
				
			||||||
+ * nla_need_padding_for_64bit - test 64-bit alignment of the next attribute
 | 
					 | 
				
			||||||
+ * @skb: socket buffer the message is stored in
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * Return true if padding is needed to align the next attribute (nla_data()) to
 | 
					 | 
				
			||||||
+ * a 64-bit aligned area.
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+static inline bool nla_need_padding_for_64bit(struct sk_buff *skb)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 | 
					 | 
				
			||||||
+	/* The nlattr header is 4 bytes in size, that's why we test
 | 
					 | 
				
			||||||
+	 * if the skb->data _is_ aligned.  A NOP attribute, plus
 | 
					 | 
				
			||||||
+	 * nlattr header for next attribute, will make nla_data()
 | 
					 | 
				
			||||||
+	 * 8-byte aligned.
 | 
					 | 
				
			||||||
+	 */
 | 
					 | 
				
			||||||
+	if (IS_ALIGNED((unsigned long)skb_tail_pointer(skb), 8))
 | 
					 | 
				
			||||||
+		return true;
 | 
					 | 
				
			||||||
+#endif
 | 
					 | 
				
			||||||
+	return false;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/**
 | 
					 | 
				
			||||||
+ * nla_align_64bit - 64-bit align the nla_data() of next attribute
 | 
					 | 
				
			||||||
+ * @skb: socket buffer the message is stored in
 | 
					 | 
				
			||||||
+ * @padattr: attribute type for the padding
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * Conditionally emit a padding netlink attribute in order to make
 | 
					 | 
				
			||||||
+ * the next attribute we emit have a 64-bit aligned nla_data() area.
 | 
					 | 
				
			||||||
+ * This will only be done in architectures which do not have
 | 
					 | 
				
			||||||
+ * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS defined.
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * Returns zero on success or a negative error code.
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+static inline int nla_align_64bit(struct sk_buff *skb, int padattr)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	if (nla_need_padding_for_64bit(skb) &&
 | 
					 | 
				
			||||||
+	    !nla_reserve(skb, padattr, 0))
 | 
					 | 
				
			||||||
+		return -EMSGSIZE;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/**
 | 
					 | 
				
			||||||
+ * __nla_reserve_64bit - reserve room for attribute on the skb and align it
 | 
					 | 
				
			||||||
+ * @skb: socket buffer to reserve room on
 | 
					 | 
				
			||||||
+ * @attrtype: attribute type
 | 
					 | 
				
			||||||
+ * @attrlen: length of attribute payload
 | 
					 | 
				
			||||||
+ * @padattr: attribute type for the padding
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * Adds a netlink attribute header to a socket buffer and reserves
 | 
					 | 
				
			||||||
+ * room for the payload but does not copy it. It also ensure that this
 | 
					 | 
				
			||||||
+ * attribute will have a 64-bit aligned nla_data() area.
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * The caller is responsible to ensure that the skb provides enough
 | 
					 | 
				
			||||||
+ * tailroom for the attribute header and payload.
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+static inline struct nlattr *__nla_reserve_64bit(struct sk_buff *skb, int attrtype,
 | 
					 | 
				
			||||||
+						 int attrlen, int padattr)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	if (nla_need_padding_for_64bit(skb))
 | 
					 | 
				
			||||||
+		nla_align_64bit(skb, padattr);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return __nla_reserve(skb, attrtype, attrlen);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/**
 | 
					 | 
				
			||||||
+ * __nla_put_64bit - Add a netlink attribute to a socket buffer and align it
 | 
					 | 
				
			||||||
+ * @skb: socket buffer to add attribute to
 | 
					 | 
				
			||||||
+ * @attrtype: attribute type
 | 
					 | 
				
			||||||
+ * @attrlen: length of attribute payload
 | 
					 | 
				
			||||||
+ * @data: head of attribute payload
 | 
					 | 
				
			||||||
+ * @padattr: attribute type for the padding
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * The caller is responsible to ensure that the skb provides enough
 | 
					 | 
				
			||||||
+ * tailroom for the attribute header and payload.
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+static inline void __nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,
 | 
					 | 
				
			||||||
+				   const void *data, int padattr)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	struct nlattr *nla;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	nla = __nla_reserve_64bit(skb, attrtype, attrlen, padattr);
 | 
					 | 
				
			||||||
+	memcpy(nla_data(nla), data, attrlen);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/**
 | 
					 | 
				
			||||||
+ * nla_total_size_64bit - total length of attribute including padding
 | 
					 | 
				
			||||||
+ * @payload: length of payload
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+static inline int nla_total_size_64bit(int payload)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return NLA_ALIGN(nla_attr_size(payload))
 | 
					 | 
				
			||||||
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 | 
					 | 
				
			||||||
+		+ NLA_ALIGN(nla_attr_size(0))
 | 
					 | 
				
			||||||
+#endif
 | 
					 | 
				
			||||||
+		;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/**
 | 
					 | 
				
			||||||
+ * nla_put_64bit - Add a netlink attribute to a socket buffer and align it
 | 
					 | 
				
			||||||
+ * @skb: socket buffer to add attribute to
 | 
					 | 
				
			||||||
+ * @attrtype: attribute type
 | 
					 | 
				
			||||||
+ * @attrlen: length of attribute payload
 | 
					 | 
				
			||||||
+ * @data: head of attribute payload
 | 
					 | 
				
			||||||
+ * @padattr: attribute type for the padding
 | 
					 | 
				
			||||||
+ *
 | 
					 | 
				
			||||||
+ * Returns -EMSGSIZE if the tailroom of the skb is insufficient to store
 | 
					 | 
				
			||||||
+ * the attribute header and payload.
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+static inline int nla_put_64bit(struct sk_buff *skb, int attrtype, int attrlen,
 | 
					 | 
				
			||||||
+				const void *data, int padattr)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	size_t len;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	if (nla_need_padding_for_64bit(skb))
 | 
					 | 
				
			||||||
+		len = nla_total_size_64bit(attrlen);
 | 
					 | 
				
			||||||
+	else
 | 
					 | 
				
			||||||
+		len = nla_total_size(attrlen);
 | 
					 | 
				
			||||||
+	if (unlikely(skb_tailroom(skb) < len))
 | 
					 | 
				
			||||||
+		return -EMSGSIZE;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	__nla_put_64bit(skb, attrtype, attrlen, data, padattr);
 | 
					 | 
				
			||||||
+	return 0;
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+/**
 | 
					 | 
				
			||||||
+ * nla_put_u64_64bit - Add a u64 netlink attribute to a skb and align it
 | 
					 | 
				
			||||||
+ * @skb: socket buffer to add attribute to
 | 
					 | 
				
			||||||
+ * @attrtype: attribute type
 | 
					 | 
				
			||||||
+ * @value: numeric value
 | 
					 | 
				
			||||||
+ * @padattr: attribute type for the padding
 | 
					 | 
				
			||||||
+ */
 | 
					 | 
				
			||||||
+static inline int nla_put_u64_64bit(struct sk_buff *skb, int attrtype,
 | 
					 | 
				
			||||||
+				    u64 value, int padattr)
 | 
					 | 
				
			||||||
+{
 | 
					 | 
				
			||||||
+	return nla_put_64bit(skb, attrtype, sizeof(u64), &value, padattr);
 | 
					 | 
				
			||||||
+}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) */
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 #endif /* __BACKPORT_NET_NETLINK_H */
 | 
					 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
From: Felix Fietkau <nbd@nbd.name>
 | 
					 | 
				
			||||||
Date: Sat, 14 May 2016 16:44:57 +0200
 | 
					 | 
				
			||||||
Subject: [PATCH] compat: bump rhashtable backport version due to API changes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- a/compat/Kconfig
 | 
					 | 
				
			||||||
+++ b/compat/Kconfig
 | 
					 | 
				
			||||||
@@ -139,7 +139,7 @@ config BPAUTO_BUILD_WANT_DEV_COREDUMP
 | 
					 | 
				
			||||||
 config BPAUTO_RHASHTABLE
 | 
					 | 
				
			||||||
 	bool
 | 
					 | 
				
			||||||
 	# current API of rhashtable was introduced in version 4.1
 | 
					 | 
				
			||||||
-	depends on KERNEL_4_1
 | 
					 | 
				
			||||||
+	depends on KERNEL_4_7
 | 
					 | 
				
			||||||
 	# not very nice - but better than always having it
 | 
					 | 
				
			||||||
 	default y if MAC80211
 | 
					 | 
				
			||||||
 	#h-file linux/rhashtable.h
 | 
					 | 
				
			||||||
@@ -57,7 +57,7 @@
 | 
				
			|||||||
 	return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
 | 
					 	return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
 | 
				
			||||||
 #else
 | 
					 #else
 | 
				
			||||||
 	return bus->chipco.dev;
 | 
					 	return bus->chipco.dev;
 | 
				
			||||||
@@ -4901,7 +4901,7 @@ static int b43_wireless_core_init(struct
 | 
					@@ -4883,7 +4883,7 @@ static int b43_wireless_core_init(struct
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 	if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
 | 
					 	if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
 | 
				
			||||||
 		hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
 | 
					 		hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,9 +18,9 @@
 | 
				
			|||||||
 static int ieee80211_ifa6_changed(struct notifier_block *nb,
 | 
					 static int ieee80211_ifa6_changed(struct notifier_block *nb,
 | 
				
			||||||
 				  unsigned long data, void *arg)
 | 
					 				  unsigned long data, void *arg)
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
@@ -1089,14 +1089,14 @@ int ieee80211_register_hw(struct ieee802
 | 
					@@ -1090,14 +1090,14 @@ int ieee80211_register_hw(struct ieee802
 | 
				
			||||||
 
 | 
					 	if (result)
 | 
				
			||||||
 	rtnl_unlock();
 | 
					 		goto fail_flows;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
-#ifdef CONFIG_INET
 | 
					-#ifdef CONFIG_INET
 | 
				
			||||||
+#ifdef __disabled__CONFIG_INET
 | 
					+#ifdef __disabled__CONFIG_INET
 | 
				
			||||||
@@ -35,7 +35,7 @@
 | 
				
			|||||||
 	local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
 | 
					 	local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
 | 
				
			||||||
 	result = register_inet6addr_notifier(&local->ifa6_notifier);
 | 
					 	result = register_inet6addr_notifier(&local->ifa6_notifier);
 | 
				
			||||||
 	if (result)
 | 
					 	if (result)
 | 
				
			||||||
@@ -1105,13 +1105,13 @@ int ieee80211_register_hw(struct ieee802
 | 
					@@ -1106,13 +1106,13 @@ int ieee80211_register_hw(struct ieee802
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	return 0;
 | 
					 	return 0;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -51,8 +51,8 @@
 | 
				
			|||||||
+#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6)
 | 
					+#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6)
 | 
				
			||||||
  fail_ifa:
 | 
					  fail_ifa:
 | 
				
			||||||
 #endif
 | 
					 #endif
 | 
				
			||||||
 	rtnl_lock();
 | 
					 	ieee80211_txq_teardown_flows(local);
 | 
				
			||||||
@@ -1139,10 +1139,10 @@ void ieee80211_unregister_hw(struct ieee
 | 
					@@ -1142,10 +1142,10 @@ void ieee80211_unregister_hw(struct ieee
 | 
				
			||||||
 	tasklet_kill(&local->tx_pending_tasklet);
 | 
					 	tasklet_kill(&local->tx_pending_tasklet);
 | 
				
			||||||
 	tasklet_kill(&local->tasklet);
 | 
					 	tasklet_kill(&local->tasklet);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
From: Felix Fietkau <nbd@nbd.name>
 | 
					From: Felix Fietkau <nbd@openwrt.org>
 | 
				
			||||||
Date: Sun, 7 Jun 2015 13:53:35 +0200
 | 
					Date: Sun, 7 Jun 2015 13:53:35 +0200
 | 
				
			||||||
Subject: [PATCH] ath9k: force rx_clear when disabling rx
 | 
					Subject: [PATCH] ath9k: force rx_clear when disabling rx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
From: Felix Fietkau <nbd@nbd.name>
 | 
					From: Felix Fietkau <nbd@openwrt.org>
 | 
				
			||||||
Date: Thu, 2 Jul 2015 15:20:56 +0200
 | 
					Date: Thu, 2 Jul 2015 15:20:56 +0200
 | 
				
			||||||
Subject: [PATCH] ath9k: limit retries for powersave response frames
 | 
					Subject: [PATCH] ath9k: limit retries for powersave response frames
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -8,7 +8,7 @@ gone to sleep. To avoid wasting too much airtime on this, limit the
 | 
				
			|||||||
number of retries on such frames and ensure that no sample rate gets
 | 
					number of retries on such frames and ensure that no sample rate gets
 | 
				
			||||||
used.
 | 
					used.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
					Signed-off-by: Felix Fietkau <nbd@openwrt.org>
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath9k/xmit.c
 | 
					--- a/drivers/net/wireless/ath/ath9k/xmit.c
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,146 +0,0 @@
 | 
				
			|||||||
From: Bob Copeland <me@bobcopeland.com>
 | 
					 | 
				
			||||||
Date: Sun, 15 May 2016 13:19:16 -0400
 | 
					 | 
				
			||||||
Subject: [PATCH] mac80211: mesh: flush mesh paths unconditionally
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Currently, the mesh paths associated with a nexthop station are cleaned
 | 
					 | 
				
			||||||
up in the following code path:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __sta_info_destroy_part1
 | 
					 | 
				
			||||||
    synchronize_net()
 | 
					 | 
				
			||||||
    __sta_info_destroy_part2
 | 
					 | 
				
			||||||
     -> cleanup_single_sta
 | 
					 | 
				
			||||||
       -> mesh_sta_cleanup
 | 
					 | 
				
			||||||
         -> mesh_plink_deactivate
 | 
					 | 
				
			||||||
           -> mesh_path_flush_by_nexthop
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
However, there are a couple of problems here:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1) the paths aren't flushed at all if the MPM is running in userspace
 | 
					 | 
				
			||||||
   (e.g. when using wpa_supplicant or authsae)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2) there is no synchronize_rcu between removing the path and readers
 | 
					 | 
				
			||||||
   accessing the nexthop, which means the following race is possible:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CPU0                            CPU1
 | 
					 | 
				
			||||||
~~~~                            ~~~~
 | 
					 | 
				
			||||||
                                sta_info_destroy_part1()
 | 
					 | 
				
			||||||
                                synchronize_net()
 | 
					 | 
				
			||||||
rcu_read_lock()
 | 
					 | 
				
			||||||
mesh_nexthop_resolve()
 | 
					 | 
				
			||||||
  mpath = mesh_path_lookup()
 | 
					 | 
				
			||||||
                                [...] -> mesh_path_flush_by_nexthop()
 | 
					 | 
				
			||||||
  sta = rcu_dereference(
 | 
					 | 
				
			||||||
    mpath->next_hop)
 | 
					 | 
				
			||||||
                                kfree(sta)
 | 
					 | 
				
			||||||
  access sta <-- CRASH
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Fix both of these by unconditionally flushing paths before destroying
 | 
					 | 
				
			||||||
the sta, and by adding a synchronize_net() after path flush to ensure
 | 
					 | 
				
			||||||
no active readers can still dereference the sta.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Fixes this crash:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[  348.529295] BUG: unable to handle kernel paging request at 00020040
 | 
					 | 
				
			||||||
[  348.530014] IP: [<f929245d>] ieee80211_mps_set_frame_flags+0x40/0xaa [mac80211]
 | 
					 | 
				
			||||||
[  348.530014] *pde = 00000000
 | 
					 | 
				
			||||||
[  348.530014] Oops: 0000 [#1] PREEMPT
 | 
					 | 
				
			||||||
[  348.530014] Modules linked in: drbg ansi_cprng ctr ccm ppp_generic slhc ipt_MASQUERADE nf_nat_masquerade_ipv4 8021q ]
 | 
					 | 
				
			||||||
[  348.530014] CPU: 0 PID: 20597 Comm: wget Tainted: G           O 4.6.0-rc5-wt=V1 #1
 | 
					 | 
				
			||||||
[  348.530014] Hardware name: To Be Filled By O.E.M./To be filled by O.E.M., BIOS 080016  11/07/2014
 | 
					 | 
				
			||||||
[  348.530014] task: f64fa280 ti: f4f9c000 task.ti: f4f9c000
 | 
					 | 
				
			||||||
[  348.530014] EIP: 0060:[<f929245d>] EFLAGS: 00010246 CPU: 0
 | 
					 | 
				
			||||||
[  348.530014] EIP is at ieee80211_mps_set_frame_flags+0x40/0xaa [mac80211]
 | 
					 | 
				
			||||||
[  348.530014] EAX: f4ce63e0 EBX: 00000088 ECX: f3788416 EDX: 00020008
 | 
					 | 
				
			||||||
[  348.530014] ESI: 00000000 EDI: 00000088 EBP: f6409a4c ESP: f6409a40
 | 
					 | 
				
			||||||
[  348.530014]  DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
 | 
					 | 
				
			||||||
[  348.530014] CR0: 80050033 CR2: 00020040 CR3: 33190000 CR4: 00000690
 | 
					 | 
				
			||||||
[  348.530014] Stack:
 | 
					 | 
				
			||||||
[  348.530014]  00000000 f4ce63e0 f5f9bd80 f6409a64 f9291d80 0000ce67 f5d51e00 f4ce63e0
 | 
					 | 
				
			||||||
[  348.530014]  f3788416 f6409a80 f9291dc1 f4ce8320 f4ce63e0 f5d51e00 f4ce63e0 f4ce8320
 | 
					 | 
				
			||||||
[  348.530014]  f6409a98 f9277f6f 00000000 00000000 0000007c 00000000 f6409b2c f9278dd1
 | 
					 | 
				
			||||||
[  348.530014] Call Trace:
 | 
					 | 
				
			||||||
[  348.530014]  [<f9291d80>] mesh_nexthop_lookup+0xbb/0xc8 [mac80211]
 | 
					 | 
				
			||||||
[  348.530014]  [<f9291dc1>] mesh_nexthop_resolve+0x34/0xd8 [mac80211]
 | 
					 | 
				
			||||||
[  348.530014]  [<f9277f6f>] ieee80211_xmit+0x92/0xc1 [mac80211]
 | 
					 | 
				
			||||||
[  348.530014]  [<f9278dd1>] __ieee80211_subif_start_xmit+0x807/0x83c [mac80211]
 | 
					 | 
				
			||||||
[  348.530014]  [<c04df012>] ? sch_direct_xmit+0xd7/0x1b3
 | 
					 | 
				
			||||||
[  348.530014]  [<c022a8c6>] ? __local_bh_enable_ip+0x5d/0x7b
 | 
					 | 
				
			||||||
[  348.530014]  [<f956870c>] ? nf_nat_ipv4_out+0x4c/0xd0 [nf_nat_ipv4]
 | 
					 | 
				
			||||||
[  348.530014]  [<f957e036>] ? iptable_nat_ipv4_fn+0xf/0xf [iptable_nat]
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c6f45>] ? netif_skb_features+0x14d/0x30a
 | 
					 | 
				
			||||||
[  348.530014]  [<f9278e10>] ieee80211_subif_start_xmit+0xa/0xe [mac80211]
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c769c>] dev_hard_start_xmit+0x1f8/0x267
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c7261>] ?  validate_xmit_skb.isra.120.part.121+0x10/0x253
 | 
					 | 
				
			||||||
[  348.530014]  [<c04defc6>] sch_direct_xmit+0x8b/0x1b3
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c7a9c>] __dev_queue_xmit+0x2c8/0x513
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c7cfb>] dev_queue_xmit+0xa/0xc
 | 
					 | 
				
			||||||
[  348.530014]  [<f91bfc7a>] batadv_send_skb_packet+0xd6/0xec [batman_adv]
 | 
					 | 
				
			||||||
[  348.530014]  [<f91bfdc4>] batadv_send_unicast_skb+0x15/0x4a [batman_adv]
 | 
					 | 
				
			||||||
[  348.530014]  [<f91b5938>] batadv_dat_send_data+0x27e/0x310 [batman_adv]
 | 
					 | 
				
			||||||
[  348.530014]  [<f91c30b5>] ? batadv_tt_global_hash_find.isra.11+0x8/0xa [batman_adv]
 | 
					 | 
				
			||||||
[  348.530014]  [<f91b63f3>] batadv_dat_snoop_outgoing_arp_request+0x208/0x23d [batman_adv]
 | 
					 | 
				
			||||||
[  348.530014]  [<f91c0cd9>] batadv_interface_tx+0x206/0x385 [batman_adv]
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c769c>] dev_hard_start_xmit+0x1f8/0x267
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c7261>] ?  validate_xmit_skb.isra.120.part.121+0x10/0x253
 | 
					 | 
				
			||||||
[  348.530014]  [<c04defc6>] sch_direct_xmit+0x8b/0x1b3
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c7a9c>] __dev_queue_xmit+0x2c8/0x513
 | 
					 | 
				
			||||||
[  348.530014]  [<f80cbd2a>] ? igb_xmit_frame+0x57/0x72 [igb]
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c7cfb>] dev_queue_xmit+0xa/0xc
 | 
					 | 
				
			||||||
[  348.530014]  [<f843a326>] br_dev_queue_push_xmit+0xeb/0xfb [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<f843a35f>] br_forward_finish+0x29/0x74 [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<f843a23b>] ? deliver_clone+0x3b/0x3b [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<f843a714>] __br_forward+0x89/0xe7 [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<f843a336>] ? br_dev_queue_push_xmit+0xfb/0xfb [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<f843a234>] deliver_clone+0x34/0x3b [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<f843a68b>] ? br_flood+0x95/0x95 [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<f843a66d>] br_flood+0x77/0x95 [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<f843a809>] br_flood_forward+0x13/0x1a [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<f843a68b>] ? br_flood+0x95/0x95 [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<f843b877>] br_handle_frame_finish+0x392/0x3db [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<c04e9b2b>] ? nf_iterate+0x2b/0x6b
 | 
					 | 
				
			||||||
[  348.530014]  [<f843baa6>] br_handle_frame+0x1e6/0x240 [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<f843b4e5>] ? br_handle_local_finish+0x6a/0x6a [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c4ba0>] __netif_receive_skb_core+0x43a/0x66b
 | 
					 | 
				
			||||||
[  348.530014]  [<f843b8c0>] ? br_handle_frame_finish+0x3db/0x3db [bridge]
 | 
					 | 
				
			||||||
[  348.530014]  [<c023cea4>] ? resched_curr+0x19/0x37
 | 
					 | 
				
			||||||
[  348.530014]  [<c0240707>] ? check_preempt_wakeup+0xbf/0xfe
 | 
					 | 
				
			||||||
[  348.530014]  [<c0255dec>] ? ktime_get_with_offset+0x5c/0xfc
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c4fc1>] __netif_receive_skb+0x47/0x55
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c57ba>] netif_receive_skb_internal+0x40/0x5a
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c61ef>] napi_gro_receive+0x3a/0x94
 | 
					 | 
				
			||||||
[  348.530014]  [<f80ce8d5>] igb_poll+0x6fd/0x9ad [igb]
 | 
					 | 
				
			||||||
[  348.530014]  [<c0242bd8>] ? swake_up_locked+0x14/0x26
 | 
					 | 
				
			||||||
[  348.530014]  [<c04c5d29>] net_rx_action+0xde/0x250
 | 
					 | 
				
			||||||
[  348.530014]  [<c022a743>] __do_softirq+0x8a/0x163
 | 
					 | 
				
			||||||
[  348.530014]  [<c022a6b9>] ? __hrtimer_tasklet_trampoline+0x19/0x19
 | 
					 | 
				
			||||||
[  348.530014]  [<c021100f>] do_softirq_own_stack+0x26/0x2c
 | 
					 | 
				
			||||||
[  348.530014]  <IRQ>
 | 
					 | 
				
			||||||
[  348.530014]  [<c022a957>] irq_exit+0x31/0x6f
 | 
					 | 
				
			||||||
[  348.530014]  [<c0210eb2>] do_IRQ+0x8d/0xa0
 | 
					 | 
				
			||||||
[  348.530014]  [<c058152c>] common_interrupt+0x2c/0x40
 | 
					 | 
				
			||||||
[  348.530014] Code: e7 8c 00 66 81 ff 88 00 75 12 85 d2 75 0e b2 c3 b8 83 e9 29 f9 e8 a7 5f f9 c6 eb 74 66 81 e3 8c 005
 | 
					 | 
				
			||||||
[  348.530014] EIP: [<f929245d>] ieee80211_mps_set_frame_flags+0x40/0xaa [mac80211] SS:ESP 0068:f6409a40
 | 
					 | 
				
			||||||
[  348.530014] CR2: 0000000000020040
 | 
					 | 
				
			||||||
[  348.530014] ---[ end trace 48556ac26779732e ]---
 | 
					 | 
				
			||||||
[  348.530014] Kernel panic - not syncing: Fatal exception in interrupt
 | 
					 | 
				
			||||||
[  348.530014] Kernel Offset: disabled
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Cc: stable@vger.kernel.org
 | 
					 | 
				
			||||||
Reported-by: Fred Veldini <fred.veldini@gmail.com>
 | 
					 | 
				
			||||||
Tested-by: Fred Veldini <fred.veldini@gmail.com>
 | 
					 | 
				
			||||||
Signed-off-by: Bob Copeland <me@bobcopeland.com>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- a/net/mac80211/mesh.c
 | 
					 | 
				
			||||||
+++ b/net/mac80211/mesh.c
 | 
					 | 
				
			||||||
@@ -161,6 +161,10 @@ void mesh_sta_cleanup(struct sta_info *s
 | 
					 | 
				
			||||||
 		del_timer_sync(&sta->mesh->plink_timer);
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+	/* make sure no readers can access nexthop sta from here on */
 | 
					 | 
				
			||||||
+	mesh_path_flush_by_nexthop(sta);
 | 
					 | 
				
			||||||
+	synchronize_net();
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 	if (changed)
 | 
					 | 
				
			||||||
 		ieee80211_mbss_info_change_notify(sdata, changed);
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
@@ -13,7 +13,7 @@ Signed-off-by: Ben Greear <greearb@candelatech.com>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
					--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
					+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
				
			||||||
@@ -773,6 +773,7 @@ static void ath10k_peer_cleanup(struct a
 | 
					@@ -802,6 +802,7 @@ static void ath10k_peer_cleanup(struct a
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
 	struct ath10k_peer *peer, *tmp;
 | 
					 	struct ath10k_peer *peer, *tmp;
 | 
				
			||||||
 	int peer_id;
 | 
					 	int peer_id;
 | 
				
			||||||
@@ -21,7 +21,7 @@ Signed-off-by: Ben Greear <greearb@candelatech.com>
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
 	lockdep_assert_held(&ar->conf_mutex);
 | 
					 	lockdep_assert_held(&ar->conf_mutex);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -789,6 +790,17 @@ static void ath10k_peer_cleanup(struct a
 | 
					@@ -818,6 +819,17 @@ static void ath10k_peer_cleanup(struct a
 | 
				
			||||||
 			ar->peer_map[peer_id] = NULL;
 | 
					 			ar->peer_map[peer_id] = NULL;
 | 
				
			||||||
 		}
 | 
					 		}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -39,7 +39,7 @@ Signed-off-by: Ben Greear <greearb@candelatech.com>
 | 
				
			|||||||
 		list_del(&peer->list);
 | 
					 		list_del(&peer->list);
 | 
				
			||||||
 		kfree(peer);
 | 
					 		kfree(peer);
 | 
				
			||||||
 		ar->num_peers--;
 | 
					 		ar->num_peers--;
 | 
				
			||||||
@@ -799,6 +811,7 @@ static void ath10k_peer_cleanup(struct a
 | 
					@@ -828,6 +840,7 @@ static void ath10k_peer_cleanup(struct a
 | 
				
			||||||
 static void ath10k_peer_cleanup_all(struct ath10k *ar)
 | 
					 static void ath10k_peer_cleanup_all(struct ath10k *ar)
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
 	struct ath10k_peer *peer, *tmp;
 | 
					 	struct ath10k_peer *peer, *tmp;
 | 
				
			||||||
@@ -47,7 +47,7 @@ Signed-off-by: Ben Greear <greearb@candelatech.com>
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
 	lockdep_assert_held(&ar->conf_mutex);
 | 
					 	lockdep_assert_held(&ar->conf_mutex);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -807,6 +820,10 @@ static void ath10k_peer_cleanup_all(stru
 | 
					@@ -836,6 +849,10 @@ static void ath10k_peer_cleanup_all(stru
 | 
				
			||||||
 		list_del(&peer->list);
 | 
					 		list_del(&peer->list);
 | 
				
			||||||
 		kfree(peer);
 | 
					 		kfree(peer);
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
@@ -1,25 +0,0 @@
 | 
				
			|||||||
From: Felix Fietkau <nbd@nbd.name>
 | 
					 | 
				
			||||||
Date: Thu, 19 May 2016 17:32:13 +0200
 | 
					 | 
				
			||||||
Subject: [PATCH] mac80211: fix fast_tx header alignment
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The header field is defined as u8[] but also accessed as struct
 | 
					 | 
				
			||||||
ieee80211_hdr. Enforce an alignment of 2 to prevent unnecessary
 | 
					 | 
				
			||||||
unaligned accesses, which can be very harmful for performance on many
 | 
					 | 
				
			||||||
platforms.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Fixes: e495c24731a2 ("mac80211: extend fast-xmit for more ciphers")
 | 
					 | 
				
			||||||
Cc: stable@vger.kernel.org
 | 
					 | 
				
			||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- a/net/mac80211/sta_info.h
 | 
					 | 
				
			||||||
+++ b/net/mac80211/sta_info.h
 | 
					 | 
				
			||||||
@@ -280,7 +280,7 @@ struct ieee80211_fast_tx {
 | 
					 | 
				
			||||||
 	u8 sa_offs, da_offs, pn_offs;
 | 
					 | 
				
			||||||
 	u8 band;
 | 
					 | 
				
			||||||
 	u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV +
 | 
					 | 
				
			||||||
-	       sizeof(rfc1042_header)];
 | 
					 | 
				
			||||||
+	       sizeof(rfc1042_header)] __aligned(2);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	struct rcu_head rcu_head;
 | 
					 | 
				
			||||||
 };
 | 
					 | 
				
			||||||
@@ -10,7 +10,7 @@ Signed-off-by: Ben Greear <greearb@candelatech.com>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
					--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
					+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
				
			||||||
@@ -5949,9 +5949,17 @@ static int ath10k_sta_state(struct ieee8
 | 
					@@ -5992,9 +5992,17 @@ static int ath10k_sta_state(struct ieee8
 | 
				
			||||||
 				continue;
 | 
					 				continue;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 			if (peer->sta == sta) {
 | 
					 			if (peer->sta == sta) {
 | 
				
			||||||
@@ -0,0 +1,203 @@
 | 
				
			|||||||
 | 
					From: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			||||||
 | 
					Date: Fri, 19 Feb 2016 11:01:49 +0100
 | 
				
			||||||
 | 
					Subject: [PATCH] mac80211: add hdrlen to ieee80211_tx_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Add hdrlen to ieee80211_tx_data and use this
 | 
				
			||||||
 | 
					when wep/ccmd/tkip. This is preparation for
 | 
				
			||||||
 | 
					aligned4 code.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- a/net/mac80211/ieee80211_i.h
 | 
				
			||||||
 | 
					+++ b/net/mac80211/ieee80211_i.h
 | 
				
			||||||
 | 
					@@ -173,6 +173,7 @@ struct ieee80211_tx_data {
 | 
				
			||||||
 | 
					 	struct ieee80211_tx_rate rate;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	unsigned int flags;
 | 
				
			||||||
 | 
					+	unsigned int hdrlen;
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					--- a/net/mac80211/tx.c
 | 
				
			||||||
 | 
					+++ b/net/mac80211/tx.c
 | 
				
			||||||
 | 
					@@ -922,7 +922,7 @@ ieee80211_tx_h_fragment(struct ieee80211
 | 
				
			||||||
 | 
					 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 | 
				
			||||||
 | 
					 	struct ieee80211_hdr *hdr = (void *)skb->data;
 | 
				
			||||||
 | 
					 	int frag_threshold = tx->local->hw.wiphy->frag_threshold;
 | 
				
			||||||
 | 
					-	int hdrlen;
 | 
				
			||||||
 | 
					+	int hdrlen = tx->hdrlen;
 | 
				
			||||||
 | 
					 	int fragnum;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/* no matter what happens, tx->skb moves to tx->skbs */
 | 
				
			||||||
 | 
					@@ -943,8 +943,6 @@ ieee80211_tx_h_fragment(struct ieee80211
 | 
				
			||||||
 | 
					 	if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
 | 
				
			||||||
 | 
					 		return TX_DROP;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					 	/* internal error, why isn't DONTFRAG set? */
 | 
				
			||||||
 | 
					 	if (WARN_ON(skb->len + FCS_LEN <= frag_threshold))
 | 
				
			||||||
 | 
					 		return TX_DROP;
 | 
				
			||||||
 | 
					@@ -1176,6 +1174,8 @@ ieee80211_tx_prepare(struct ieee80211_su
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	hdr = (struct ieee80211_hdr *) skb->data;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+	tx->hdrlen = ieee80211_hdrlen(hdr->frame_control);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 	if (likely(sta)) {
 | 
				
			||||||
 | 
					 		if (!IS_ERR(sta))
 | 
				
			||||||
 | 
					 			tx->sta = sta;
 | 
				
			||||||
 | 
					--- a/net/mac80211/util.c
 | 
				
			||||||
 | 
					+++ b/net/mac80211/util.c
 | 
				
			||||||
 | 
					@@ -1226,6 +1226,7 @@ void ieee80211_send_auth(struct ieee8021
 | 
				
			||||||
 | 
					 	struct ieee80211_local *local = sdata->local;
 | 
				
			||||||
 | 
					 	struct sk_buff *skb;
 | 
				
			||||||
 | 
					 	struct ieee80211_mgmt *mgmt;
 | 
				
			||||||
 | 
					+	unsigned int hdrlen;
 | 
				
			||||||
 | 
					 	int err;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/* 24 + 6 = header + auth_algo + auth_transaction + status_code */
 | 
				
			||||||
 | 
					@@ -1250,8 +1251,10 @@ void ieee80211_send_auth(struct ieee8021
 | 
				
			||||||
 | 
					 		memcpy(skb_put(skb, extra_len), extra, extra_len);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
 | 
				
			||||||
 | 
					+		hdrlen = ieee80211_hdrlen(mgmt->frame_control);
 | 
				
			||||||
 | 
					 		mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
 | 
				
			||||||
 | 
					-		err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx);
 | 
				
			||||||
 | 
					+		err = ieee80211_wep_encrypt(local, skb, hdrlen, key,
 | 
				
			||||||
 | 
					+					    key_len, key_idx);
 | 
				
			||||||
 | 
					 		WARN_ON(err);
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					--- a/net/mac80211/wep.c
 | 
				
			||||||
 | 
					+++ b/net/mac80211/wep.c
 | 
				
			||||||
 | 
					@@ -89,11 +89,11 @@ static void ieee80211_wep_get_iv(struct
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
 | 
				
			||||||
 | 
					 				struct sk_buff *skb,
 | 
				
			||||||
 | 
					+				unsigned int hdrlen,
 | 
				
			||||||
 | 
					 				int keylen, int keyidx)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 | 
				
			||||||
 | 
					 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 | 
				
			||||||
 | 
					-	unsigned int hdrlen;
 | 
				
			||||||
 | 
					 	u8 *newhdr;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
 | 
				
			||||||
 | 
					@@ -101,7 +101,6 @@ static u8 *ieee80211_wep_add_iv(struct i
 | 
				
			||||||
 | 
					 	if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN))
 | 
				
			||||||
 | 
					 		return NULL;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 | 
				
			||||||
 | 
					 	newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN);
 | 
				
			||||||
 | 
					 	memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					@@ -160,6 +159,7 @@ int ieee80211_wep_encrypt_data(struct cr
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					 int ieee80211_wep_encrypt(struct ieee80211_local *local,
 | 
				
			||||||
 | 
					 			  struct sk_buff *skb,
 | 
				
			||||||
 | 
					+			  unsigned int hdrlen,
 | 
				
			||||||
 | 
					 			  const u8 *key, int keylen, int keyidx)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					 	u8 *iv;
 | 
				
			||||||
 | 
					@@ -169,7 +169,7 @@ int ieee80211_wep_encrypt(struct ieee802
 | 
				
			||||||
 | 
					 	if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN))
 | 
				
			||||||
 | 
					 		return -1;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx);
 | 
				
			||||||
 | 
					+	iv = ieee80211_wep_add_iv(local, skb, hdrlen, keylen, keyidx);
 | 
				
			||||||
 | 
					 	if (!iv)
 | 
				
			||||||
 | 
					 		return -1;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					@@ -306,13 +306,14 @@ static int wep_encrypt_skb(struct ieee80
 | 
				
			||||||
 | 
					 	struct ieee80211_key_conf *hw_key = info->control.hw_key;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	if (!hw_key) {
 | 
				
			||||||
 | 
					-		if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key,
 | 
				
			||||||
 | 
					+		if (ieee80211_wep_encrypt(tx->local, skb, tx->hdrlen,
 | 
				
			||||||
 | 
					+					  tx->key->conf.key,
 | 
				
			||||||
 | 
					 					  tx->key->conf.keylen,
 | 
				
			||||||
 | 
					 					  tx->key->conf.keyidx))
 | 
				
			||||||
 | 
					 			return -1;
 | 
				
			||||||
 | 
					 	} else if ((hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
 | 
				
			||||||
 | 
					 		   (hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
 | 
				
			||||||
 | 
					-		if (!ieee80211_wep_add_iv(tx->local, skb,
 | 
				
			||||||
 | 
					+		if (!ieee80211_wep_add_iv(tx->local, skb, tx->hdrlen,
 | 
				
			||||||
 | 
					 					  tx->key->conf.keylen,
 | 
				
			||||||
 | 
					 					  tx->key->conf.keyidx))
 | 
				
			||||||
 | 
					 			return -1;
 | 
				
			||||||
 | 
					--- a/net/mac80211/wep.h
 | 
				
			||||||
 | 
					+++ b/net/mac80211/wep.h
 | 
				
			||||||
 | 
					@@ -22,6 +22,7 @@ int ieee80211_wep_encrypt_data(struct cr
 | 
				
			||||||
 | 
					 				size_t klen, u8 *data, size_t data_len);
 | 
				
			||||||
 | 
					 int ieee80211_wep_encrypt(struct ieee80211_local *local,
 | 
				
			||||||
 | 
					 			  struct sk_buff *skb,
 | 
				
			||||||
 | 
					+			  unsigned int hdrlen,
 | 
				
			||||||
 | 
					 			  const u8 *key, int keylen, int keyidx);
 | 
				
			||||||
 | 
					 int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
 | 
				
			||||||
 | 
					 			       size_t klen, u8 *data, size_t data_len);
 | 
				
			||||||
 | 
					--- a/net/mac80211/wpa.c
 | 
				
			||||||
 | 
					+++ b/net/mac80211/wpa.c
 | 
				
			||||||
 | 
					@@ -43,7 +43,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
 | 
				
			||||||
 | 
					 	    skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control))
 | 
				
			||||||
 | 
					 		return TX_CONTINUE;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 | 
				
			||||||
 | 
					+	hdrlen = tx->hdrlen;
 | 
				
			||||||
 | 
					 	if (skb->len < hdrlen)
 | 
				
			||||||
 | 
					 		return TX_DROP;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					@@ -186,7 +186,6 @@ mic_fail_no_key:
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 | 
				
			||||||
 | 
					 	struct ieee80211_key *key = tx->key;
 | 
				
			||||||
 | 
					 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 | 
				
			||||||
 | 
					 	unsigned int hdrlen;
 | 
				
			||||||
 | 
					@@ -201,7 +200,7 @@ static int tkip_encrypt_skb(struct ieee8
 | 
				
			||||||
 | 
					 		return 0;
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 | 
				
			||||||
 | 
					+	hdrlen = tx->hdrlen;
 | 
				
			||||||
 | 
					 	len = skb->len - hdrlen;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	if (info->control.hw_key)
 | 
				
			||||||
 | 
					@@ -418,7 +417,7 @@ static int ccmp_encrypt_skb(struct ieee8
 | 
				
			||||||
 | 
					 		return 0;
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 | 
				
			||||||
 | 
					+	hdrlen = tx->hdrlen;
 | 
				
			||||||
 | 
					 	len = skb->len - hdrlen;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	if (info->control.hw_key)
 | 
				
			||||||
 | 
					@@ -651,7 +650,7 @@ static int gcmp_encrypt_skb(struct ieee8
 | 
				
			||||||
 | 
					 		return 0;
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 | 
				
			||||||
 | 
					+	hdrlen = tx->hdrlen;
 | 
				
			||||||
 | 
					 	len = skb->len - hdrlen;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	if (info->control.hw_key)
 | 
				
			||||||
 | 
					@@ -791,7 +790,6 @@ static ieee80211_tx_result
 | 
				
			||||||
 | 
					 ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
 | 
				
			||||||
 | 
					 			    struct sk_buff *skb)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 | 
				
			||||||
 | 
					 	struct ieee80211_key *key = tx->key;
 | 
				
			||||||
 | 
					 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 | 
				
			||||||
 | 
					 	int hdrlen;
 | 
				
			||||||
 | 
					@@ -807,8 +805,7 @@ ieee80211_crypto_cs_encrypt(struct ieee8
 | 
				
			||||||
 | 
					 		     pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC)))
 | 
				
			||||||
 | 
					 		return TX_DROP;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					+	hdrlen = tx->hdrlen;
 | 
				
			||||||
 | 
					 	pos = skb_push(skb, iv_len);
 | 
				
			||||||
 | 
					 	memmove(pos, pos + iv_len, hdrlen);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
@@ -0,0 +1,235 @@
 | 
				
			|||||||
 | 
					From: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			||||||
 | 
					Date: Fri, 19 Feb 2016 11:01:50 +0100
 | 
				
			||||||
 | 
					Subject: [PATCH] mac80211: add NEED_ALIGNED4_SKBS hw flag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HW/driver should set NEED_ALIGNED4_SKBS flag in case
 | 
				
			||||||
 | 
					require aligned skbs to four-byte boundaries.
 | 
				
			||||||
 | 
					This affect only TX direction.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Padding is added after ieee80211_hdr, before IV/LLC.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Before we have to do memmove(hdrlen) twice in the
 | 
				
			||||||
 | 
					dirver. Once before we pass this to HW and next
 | 
				
			||||||
 | 
					in tx completion (to be sure monitor will report
 | 
				
			||||||
 | 
					this tx frame correctly).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					With this patch we can skip this memmove() and save CPU.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Currently this was tested with ath9k, both hw/sw crypt for
 | 
				
			||||||
 | 
					wep/tkip/ccmp.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- a/include/net/mac80211.h
 | 
				
			||||||
 | 
					+++ b/include/net/mac80211.h
 | 
				
			||||||
 | 
					@@ -2014,6 +2014,9 @@ struct ieee80211_txq {
 | 
				
			||||||
 | 
					  * @IEEE80211_HW_TX_FRAG_LIST: Hardware (or driver) supports sending frag_list
 | 
				
			||||||
 | 
					  *	skbs, needed for zero-copy software A-MSDU.
 | 
				
			||||||
 | 
					  *
 | 
				
			||||||
 | 
					+ * @IEEE80211_HW_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte.
 | 
				
			||||||
 | 
					+ *	Padding will be added after ieee80211_hdr, before IV/LLC.
 | 
				
			||||||
 | 
					+ *
 | 
				
			||||||
 | 
					  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					 enum ieee80211_hw_flags {
 | 
				
			||||||
 | 
					@@ -2054,6 +2057,7 @@ enum ieee80211_hw_flags {
 | 
				
			||||||
 | 
					 	IEEE80211_HW_USES_RSS,
 | 
				
			||||||
 | 
					 	IEEE80211_HW_TX_AMSDU,
 | 
				
			||||||
 | 
					 	IEEE80211_HW_TX_FRAG_LIST,
 | 
				
			||||||
 | 
					+	IEEE80211_HW_NEEDS_ALIGNED4_SKBS,
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/* keep last, obviously */
 | 
				
			||||||
 | 
					 	NUM_IEEE80211_HW_FLAGS
 | 
				
			||||||
 | 
					--- a/net/mac80211/debugfs.c
 | 
				
			||||||
 | 
					+++ b/net/mac80211/debugfs.c
 | 
				
			||||||
 | 
					@@ -302,6 +302,7 @@ static const char *hw_flag_names[] = {
 | 
				
			||||||
 | 
					 	FLAG(USES_RSS),
 | 
				
			||||||
 | 
					 	FLAG(TX_AMSDU),
 | 
				
			||||||
 | 
					 	FLAG(TX_FRAG_LIST),
 | 
				
			||||||
 | 
					+	FLAG(NEEDS_ALIGNED4_SKBS),
 | 
				
			||||||
 | 
					 #undef FLAG
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					--- a/net/mac80211/ieee80211_i.h
 | 
				
			||||||
 | 
					+++ b/net/mac80211/ieee80211_i.h
 | 
				
			||||||
 | 
					@@ -1497,6 +1497,29 @@ ieee80211_have_rx_timestamp(struct ieee8
 | 
				
			||||||
 | 
					 	return false;
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+static inline unsigned int
 | 
				
			||||||
 | 
					+ieee80211_hdr_padsize(struct ieee80211_hw *hw, unsigned int hdrlen)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	/*
 | 
				
			||||||
 | 
					+	 * While hdrlen is already aligned to two-byte boundaries,
 | 
				
			||||||
 | 
					+	 * simple check with & 2 will return correct padsize.
 | 
				
			||||||
 | 
					+	 */
 | 
				
			||||||
 | 
					+	if (ieee80211_hw_check(hw, NEEDS_ALIGNED4_SKBS))
 | 
				
			||||||
 | 
					+		return hdrlen & 2;
 | 
				
			||||||
 | 
					+	return 0;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+static inline unsigned int
 | 
				
			||||||
 | 
					+ieee80211_padded_hdrlen(struct ieee80211_hw *hw, __le16 fc)
 | 
				
			||||||
 | 
					+{
 | 
				
			||||||
 | 
					+	unsigned int hdrlen;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	hdrlen = ieee80211_hdrlen(fc);
 | 
				
			||||||
 | 
					+	hdrlen += ieee80211_hdr_padsize(hw, hdrlen);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+	return hdrlen;
 | 
				
			||||||
 | 
					+}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
 | 
				
			||||||
 | 
					 				     struct ieee80211_rx_status *status,
 | 
				
			||||||
 | 
					 				     unsigned int mpdu_len,
 | 
				
			||||||
 | 
					--- a/net/mac80211/sta_info.h
 | 
				
			||||||
 | 
					+++ b/net/mac80211/sta_info.h
 | 
				
			||||||
 | 
					@@ -279,7 +279,7 @@ struct ieee80211_fast_tx {
 | 
				
			||||||
 | 
					 	u8 hdr_len;
 | 
				
			||||||
 | 
					 	u8 sa_offs, da_offs, pn_offs;
 | 
				
			||||||
 | 
					 	u8 band;
 | 
				
			||||||
 | 
					-	u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV +
 | 
				
			||||||
 | 
					+	u8 hdr[30 + 2 + 2 + IEEE80211_FAST_XMIT_MAX_IV +
 | 
				
			||||||
 | 
					 	       sizeof(rfc1042_header)] __aligned(2);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	struct rcu_head rcu_head;
 | 
				
			||||||
 | 
					--- a/net/mac80211/status.c
 | 
				
			||||||
 | 
					+++ b/net/mac80211/status.c
 | 
				
			||||||
 | 
					@@ -683,9 +683,22 @@ void ieee80211_tx_monitor(struct ieee802
 | 
				
			||||||
 | 
					 	struct sk_buff *skb2;
 | 
				
			||||||
 | 
					 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 | 
				
			||||||
 | 
					 	struct ieee80211_sub_if_data *sdata;
 | 
				
			||||||
 | 
					+	struct ieee80211_hdr *hdr = (void *)skb->data;
 | 
				
			||||||
 | 
					 	struct net_device *prev_dev = NULL;
 | 
				
			||||||
 | 
					+	unsigned int hdrlen, padsize;
 | 
				
			||||||
 | 
					 	int rtap_len;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+	/* Remove padding if was added */
 | 
				
			||||||
 | 
					+	if (ieee80211_hw_check(&local->hw, NEEDS_ALIGNED4_SKBS)) {
 | 
				
			||||||
 | 
					+		hdrlen = ieee80211_hdrlen(hdr->frame_control);
 | 
				
			||||||
 | 
					+		padsize = ieee80211_hdr_padsize(&local->hw, hdrlen);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+		if (padsize && skb->len > hdrlen + padsize) {
 | 
				
			||||||
 | 
					+			memmove(skb->data + padsize, skb->data, hdrlen);
 | 
				
			||||||
 | 
					+			skb_pull(skb, padsize);
 | 
				
			||||||
 | 
					+		}
 | 
				
			||||||
 | 
					+	}
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 	/* send frame to monitor interfaces now */
 | 
				
			||||||
 | 
					 	rtap_len = ieee80211_tx_radiotap_len(info);
 | 
				
			||||||
 | 
					 	if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) {
 | 
				
			||||||
 | 
					--- a/net/mac80211/tkip.c
 | 
				
			||||||
 | 
					+++ b/net/mac80211/tkip.c
 | 
				
			||||||
 | 
					@@ -201,10 +201,12 @@ void ieee80211_get_tkip_p2k(struct ieee8
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					 	struct ieee80211_key *key = (struct ieee80211_key *)
 | 
				
			||||||
 | 
					 			container_of(keyconf, struct ieee80211_key, conf);
 | 
				
			||||||
 | 
					+	struct ieee80211_hw *hw = &key->local->hw;
 | 
				
			||||||
 | 
					 	const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
 | 
				
			||||||
 | 
					 	struct tkip_ctx *ctx = &key->u.tkip.tx;
 | 
				
			||||||
 | 
					 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 | 
				
			||||||
 | 
					-	const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
 | 
				
			||||||
 | 
					+	const u8 *data = (u8 *)hdr + ieee80211_padded_hdrlen(hw,
 | 
				
			||||||
 | 
					+							hdr->frame_control);
 | 
				
			||||||
 | 
					 	u32 iv32 = get_unaligned_le32(&data[4]);
 | 
				
			||||||
 | 
					 	u16 iv16 = data[2] | (data[0] << 8);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					--- a/net/mac80211/tx.c
 | 
				
			||||||
 | 
					+++ b/net/mac80211/tx.c
 | 
				
			||||||
 | 
					@@ -1173,8 +1173,7 @@ ieee80211_tx_prepare(struct ieee80211_su
 | 
				
			||||||
 | 
					 	info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	hdr = (struct ieee80211_hdr *) skb->data;
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					-	tx->hdrlen = ieee80211_hdrlen(hdr->frame_control);
 | 
				
			||||||
 | 
					+	tx->hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	if (likely(sta)) {
 | 
				
			||||||
 | 
					 		if (!IS_ERR(sta))
 | 
				
			||||||
 | 
					@@ -2108,7 +2107,7 @@ netdev_tx_t ieee80211_monitor_start_xmit
 | 
				
			||||||
 | 
					 		goto fail;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
 | 
				
			||||||
 | 
					-	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 | 
				
			||||||
 | 
					+	hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	if (skb->len < len_rthdr + hdrlen)
 | 
				
			||||||
 | 
					 		goto fail;
 | 
				
			||||||
 | 
					@@ -2334,7 +2333,7 @@ static struct sk_buff *ieee80211_build_h
 | 
				
			||||||
 | 
					 	struct ieee80211_chanctx_conf *chanctx_conf;
 | 
				
			||||||
 | 
					 	struct ieee80211_sub_if_data *ap_sdata;
 | 
				
			||||||
 | 
					 	enum nl80211_band band;
 | 
				
			||||||
 | 
					-	int ret;
 | 
				
			||||||
 | 
					+	int padsize, ret;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	if (IS_ERR(sta))
 | 
				
			||||||
 | 
					 		sta = NULL;
 | 
				
			||||||
 | 
					@@ -2554,6 +2553,9 @@ static struct sk_buff *ieee80211_build_h
 | 
				
			||||||
 | 
					 		hdrlen += 2;
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+	/* Check aligned4 skb required */
 | 
				
			||||||
 | 
					+	padsize = ieee80211_hdr_padsize(&sdata->local->hw, hdrlen);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 	/*
 | 
				
			||||||
 | 
					 	 * Drop unicast frames to unauthorised stations unless they are
 | 
				
			||||||
 | 
					 	 * EAPOL frames from the local station.
 | 
				
			||||||
 | 
					@@ -2640,6 +2642,7 @@ static struct sk_buff *ieee80211_build_h
 | 
				
			||||||
 | 
					 	h_pos -= skip_header_bytes;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb);
 | 
				
			||||||
 | 
					+	head_need += padsize;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/*
 | 
				
			||||||
 | 
					 	 * So we need to modify the skb header and hence need a copy of
 | 
				
			||||||
 | 
					@@ -2678,6 +2681,9 @@ static struct sk_buff *ieee80211_build_h
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 #endif
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+	if (padsize)
 | 
				
			||||||
 | 
					+		memset(skb_push(skb, padsize), 0, padsize);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 	if (ieee80211_is_data_qos(fc)) {
 | 
				
			||||||
 | 
					 		__le16 *qos_control;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					@@ -2691,8 +2697,8 @@ static struct sk_buff *ieee80211_build_h
 | 
				
			||||||
 | 
					 	} else
 | 
				
			||||||
 | 
					 		memcpy(skb_push(skb, hdrlen), &hdr, hdrlen);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	nh_pos += hdrlen;
 | 
				
			||||||
 | 
					-	h_pos += hdrlen;
 | 
				
			||||||
 | 
					+	nh_pos += hdrlen + padsize;
 | 
				
			||||||
 | 
					+	h_pos += hdrlen + padsize;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	/* Update skb pointers to various headers since this modified frame
 | 
				
			||||||
 | 
					 	 * is going to go through Linux networking code that may potentially
 | 
				
			||||||
 | 
					@@ -2861,6 +2867,9 @@ void ieee80211_check_fast_xmit(struct st
 | 
				
			||||||
 | 
					 		fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					+	/* Check aligned4 skb required */
 | 
				
			||||||
 | 
					+	build.hdr_len += ieee80211_hdr_padsize(&local->hw, build.hdr_len);
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 	/* We store the key here so there's no point in using rcu_dereference()
 | 
				
			||||||
 | 
					 	 * but that's fine because the code that changes the pointers will call
 | 
				
			||||||
 | 
					 	 * this function after doing so. For a single CPU that would be enough,
 | 
				
			||||||
 | 
					--- a/net/mac80211/util.c
 | 
				
			||||||
 | 
					+++ b/net/mac80211/util.c
 | 
				
			||||||
 | 
					@@ -1224,6 +1224,7 @@ void ieee80211_send_auth(struct ieee8021
 | 
				
			||||||
 | 
					 			 u32 tx_flags)
 | 
				
			||||||
 | 
					 {
 | 
				
			||||||
 | 
					 	struct ieee80211_local *local = sdata->local;
 | 
				
			||||||
 | 
					+	struct ieee80211_hw *hw = &local->hw;
 | 
				
			||||||
 | 
					 	struct sk_buff *skb;
 | 
				
			||||||
 | 
					 	struct ieee80211_mgmt *mgmt;
 | 
				
			||||||
 | 
					 	unsigned int hdrlen;
 | 
				
			||||||
 | 
					@@ -1251,7 +1252,7 @@ void ieee80211_send_auth(struct ieee8021
 | 
				
			||||||
 | 
					 		memcpy(skb_put(skb, extra_len), extra, extra_len);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
 | 
				
			||||||
 | 
					-		hdrlen = ieee80211_hdrlen(mgmt->frame_control);
 | 
				
			||||||
 | 
					+		hdrlen = ieee80211_padded_hdrlen(hw, mgmt->frame_control);
 | 
				
			||||||
 | 
					 		mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
 | 
				
			||||||
 | 
					 		err = ieee80211_wep_encrypt(local, skb, hdrlen, key,
 | 
				
			||||||
 | 
					 					    key_len, key_idx);
 | 
				
			||||||
@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					From: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
 | 
				
			||||||
 | 
					Date: Thu, 23 Jun 2016 22:10:01 +0530
 | 
				
			||||||
 | 
					Subject: [PATCH] ath10k: Fix sending NULL/ Qos NULL data frames for
 | 
				
			||||||
 | 
					 QCA99X0 and later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For chipsets like QCA99X0, IPQ4019 and later we are not getting proper
 | 
				
			||||||
 | 
					NULL func status (always acked/successs !!) when hostapd does a
 | 
				
			||||||
 | 
					PROBE_CLIENT via nullfunc frames when the station is powered off
 | 
				
			||||||
 | 
					abruptly (inactive timer probes client via null func after the inactive
 | 
				
			||||||
 | 
					time reaches beyond the threshold). Fix this by disabling the workaround
 | 
				
			||||||
 | 
					(getting the ACK status of NULL func frames by sending via HTT mgmt-tx
 | 
				
			||||||
 | 
					 path) introduced by the change ("ath10k: fix beacon loss handling ")
 | 
				
			||||||
 | 
					for QCA99X0 and later chipsets. The normal tx path provides the proper
 | 
				
			||||||
 | 
					ACK status for NULL data frames. As of now disable this workaround for
 | 
				
			||||||
 | 
					chipsets QCA99X0 and later, once the 10.1 firmware is obselete we can
 | 
				
			||||||
 | 
					completely get rid of this workaround for all the chipsets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Signed-off-by: Tamizh chelvam <c_traja@qti.qualcomm.com>
 | 
				
			||||||
 | 
					Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- a/drivers/net/wireless/ath/ath10k/core.c
 | 
				
			||||||
 | 
					+++ b/drivers/net/wireless/ath/ath10k/core.c
 | 
				
			||||||
 | 
					@@ -181,6 +181,7 @@ static const struct ath10k_hw_params ath
 | 
				
			||||||
 | 
					 			.board = QCA99X0_HW_2_0_BOARD_DATA_FILE,
 | 
				
			||||||
 | 
					 			.board_size = QCA99X0_BOARD_DATA_SZ,
 | 
				
			||||||
 | 
					 			.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
 | 
				
			||||||
 | 
					+			.disable_null_func_workaround = true,
 | 
				
			||||||
 | 
					 		},
 | 
				
			||||||
 | 
					 	},
 | 
				
			||||||
 | 
					 	{
 | 
				
			||||||
 | 
					@@ -204,6 +205,7 @@ static const struct ath10k_hw_params ath
 | 
				
			||||||
 | 
					 			.board = QCA9984_HW_1_0_BOARD_DATA_FILE,
 | 
				
			||||||
 | 
					 			.board_size = QCA99X0_BOARD_DATA_SZ,
 | 
				
			||||||
 | 
					 			.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
 | 
				
			||||||
 | 
					+			.disable_null_func_workaround = true,
 | 
				
			||||||
 | 
					 		},
 | 
				
			||||||
 | 
					 	},
 | 
				
			||||||
 | 
					 	{
 | 
				
			||||||
 | 
					@@ -262,6 +264,7 @@ static const struct ath10k_hw_params ath
 | 
				
			||||||
 | 
					 			.board = QCA4019_HW_1_0_BOARD_DATA_FILE,
 | 
				
			||||||
 | 
					 			.board_size = QCA4019_BOARD_DATA_SZ,
 | 
				
			||||||
 | 
					 			.board_ext_size = QCA4019_BOARD_EXT_DATA_SZ,
 | 
				
			||||||
 | 
					+			.disable_null_func_workaround = true,
 | 
				
			||||||
 | 
					 		},
 | 
				
			||||||
 | 
					 	},
 | 
				
			||||||
 | 
					 };
 | 
				
			||||||
 | 
					--- a/drivers/net/wireless/ath/ath10k/core.h
 | 
				
			||||||
 | 
					+++ b/drivers/net/wireless/ath/ath10k/core.h
 | 
				
			||||||
 | 
					@@ -750,6 +750,12 @@ struct ath10k {
 | 
				
			||||||
 | 
					 			const char *board;
 | 
				
			||||||
 | 
					 			size_t board_size;
 | 
				
			||||||
 | 
					 			size_t board_ext_size;
 | 
				
			||||||
 | 
					+			/* Workaround of sending NULL data frames via
 | 
				
			||||||
 | 
					+			 * HTT mgmt TX and getting the proper ACK status does
 | 
				
			||||||
 | 
					+			 * not works for chipsets QCA99X0 and later, while
 | 
				
			||||||
 | 
					+			 * Tx data path reports the ACK status properly.
 | 
				
			||||||
 | 
					+			 */
 | 
				
			||||||
 | 
					+			bool disable_null_func_workaround;
 | 
				
			||||||
 | 
					 		} fw;
 | 
				
			||||||
 | 
					 	} hw_params;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
				
			||||||
 | 
					+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
				
			||||||
 | 
					@@ -3253,6 +3253,7 @@ ath10k_mac_tx_h_get_txmode(struct ath10k
 | 
				
			||||||
 | 
					 	 * mode though because AP don't sleep.
 | 
				
			||||||
 | 
					 	 */
 | 
				
			||||||
 | 
					 	if (ar->htt.target_version_major < 3 &&
 | 
				
			||||||
 | 
					+	    !ar->hw_params.fw.disable_null_func_workaround &&
 | 
				
			||||||
 | 
					 	    (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
 | 
				
			||||||
 | 
					 	    !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
 | 
				
			||||||
 | 
					 		      ar->running_fw->fw_file.fw_features))
 | 
				
			||||||
@@ -1,66 +0,0 @@
 | 
				
			|||||||
From: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
 | 
					 | 
				
			||||||
Date: Thu, 2 Jun 2016 19:54:41 +0530
 | 
					 | 
				
			||||||
Subject: [PATCH] ath10k: remove duplicate and unused rx rate flags
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
All these flags are not used and their use is completely
 | 
					 | 
				
			||||||
covered by 'ath10k_hw_rate_ofdm', 'ath10k_hw_rate_cck',
 | 
					 | 
				
			||||||
and RX_PPDU_START_RATE_FLAG
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
 | 
					 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
 | 
					 | 
				
			||||||
@@ -656,26 +656,6 @@ struct rx_msdu_end {
 | 
					 | 
				
			||||||
  *		Reserved: HW should fill with zero.  FW should ignore.
 | 
					 | 
				
			||||||
  */
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_SELECT_OFDM 0
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_SELECT_CCK  1
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_OFDM_48 0
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_OFDM_24 1
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_OFDM_12 2
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_OFDM_6  3
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_OFDM_54 4
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_OFDM_36 5
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_OFDM_18 6
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_OFDM_9  7
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_CCK_LP_11  0
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_CCK_LP_5_5 1
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_CCK_LP_2   2
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_CCK_LP_1   3
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_CCK_SP_11  4
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_CCK_SP_5_5 5
 | 
					 | 
				
			||||||
-#define RX_PPDU_START_SIG_RATE_CCK_SP_2   6
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
 #define HTT_RX_PPDU_START_PREAMBLE_LEGACY        0x04
 | 
					 | 
				
			||||||
 #define HTT_RX_PPDU_START_PREAMBLE_HT            0x08
 | 
					 | 
				
			||||||
 #define HTT_RX_PPDU_START_PREAMBLE_HT_WITH_TXBF  0x09
 | 
					 | 
				
			||||||
@@ -711,25 +691,6 @@ struct rx_msdu_end {
 | 
					 | 
				
			||||||
 /* No idea what this flag means. It seems to be always set in rate. */
 | 
					 | 
				
			||||||
 #define RX_PPDU_START_RATE_FLAG BIT(3)
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-enum rx_ppdu_start_rate {
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_OFDM_48M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_48M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_OFDM_24M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_24M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_OFDM_12M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_12M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_OFDM_6M  = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_6M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_OFDM_54M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_54M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_OFDM_36M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_36M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_OFDM_18M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_18M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_OFDM_9M  = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_OFDM_9M,
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_CCK_LP_11M  = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_LP_11M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_CCK_LP_5_5M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_LP_5_5M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_CCK_LP_2M   = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_LP_2M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_CCK_LP_1M   = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_LP_1M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_CCK_SP_11M  = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_SP_11M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_CCK_SP_5_5M = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_SP_5_5M,
 | 
					 | 
				
			||||||
-	RX_PPDU_START_RATE_CCK_SP_2M   = RX_PPDU_START_RATE_FLAG | ATH10K_HW_RATE_CCK_SP_2M,
 | 
					 | 
				
			||||||
-};
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
 struct rx_ppdu_start {
 | 
					 | 
				
			||||||
 	struct {
 | 
					 | 
				
			||||||
 		u8 pri20_mhz;
 | 
					 | 
				
			||||||
@@ -1,141 +0,0 @@
 | 
				
			|||||||
From: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
 | 
					 | 
				
			||||||
Date: Thu, 2 Jun 2016 19:54:42 +0530
 | 
					 | 
				
			||||||
Subject: [PATCH] ath10k: fix CCK h/w rates for QCA99X0 and newer chipsets
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CCK hardware table mapping from QCA99X0 onwards got revised.
 | 
					 | 
				
			||||||
The CCK hardware rate values are in a proper order wrt. to
 | 
					 | 
				
			||||||
rate and preamble as below
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ATH10K_HW_RATE_REV2_CCK_LP_1M = 1,
 | 
					 | 
				
			||||||
ATH10K_HW_RATE_REV2_CCK_LP_2M = 2,
 | 
					 | 
				
			||||||
ATH10K_HW_RATE_REV2_CCK_LP_5_5M = 3,
 | 
					 | 
				
			||||||
ATH10K_HW_RATE_REV2_CCK_LP_11M = 4,
 | 
					 | 
				
			||||||
ATH10K_HW_RATE_REV2_CCK_SP_2M = 5,
 | 
					 | 
				
			||||||
ATH10K_HW_RATE_REV2_CCK_SP_5_5M = 6,
 | 
					 | 
				
			||||||
ATH10K_HW_RATE_REV2_CCK_SP_11M = 7,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This results in reporting of rx frames (with CCK rates)
 | 
					 | 
				
			||||||
totally wrong for QCA99X0, QCA4019. Fix this by having
 | 
					 | 
				
			||||||
separate CCK rate table for these chipsets with rev2 suffix
 | 
					 | 
				
			||||||
and registering the correct rate mapping to mac80211 based on
 | 
					 | 
				
			||||||
the new hw_param (introduced) 'cck_rate_map_rev2' which shall
 | 
					 | 
				
			||||||
be true for any newchipsets from QCA99X0 onwards
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/core.c
 | 
					 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
 | 
					 | 
				
			||||||
@@ -148,6 +148,8 @@ static const struct ath10k_hw_params ath
 | 
					 | 
				
			||||||
 		.uart_pin = 7,
 | 
					 | 
				
			||||||
 		.otp_exe_param = 0x00000700,
 | 
					 | 
				
			||||||
 		.continuous_frag_desc = true,
 | 
					 | 
				
			||||||
+		.cck_rate_map_rev2 = true,
 | 
					 | 
				
			||||||
+		.cck_rate_map_rev2 = true,
 | 
					 | 
				
			||||||
 		.channel_counters_freq_hz = 150000,
 | 
					 | 
				
			||||||
 		.max_probe_resp_desc_thres = 24,
 | 
					 | 
				
			||||||
 		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
 | 
					 | 
				
			||||||
@@ -205,6 +207,7 @@ static const struct ath10k_hw_params ath
 | 
					 | 
				
			||||||
 		.has_shifted_cc_wraparound = true,
 | 
					 | 
				
			||||||
 		.otp_exe_param = 0x0010000,
 | 
					 | 
				
			||||||
 		.continuous_frag_desc = true,
 | 
					 | 
				
			||||||
+		.cck_rate_map_rev2 = true,
 | 
					 | 
				
			||||||
 		.channel_counters_freq_hz = 125000,
 | 
					 | 
				
			||||||
 		.max_probe_resp_desc_thres = 24,
 | 
					 | 
				
			||||||
 		.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
 | 
					 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/core.h
 | 
					 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/core.h
 | 
					 | 
				
			||||||
@@ -716,6 +716,12 @@ struct ath10k {
 | 
					 | 
				
			||||||
 		 */
 | 
					 | 
				
			||||||
 		bool continuous_frag_desc;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+		/* CCK hardware rate table mapping for the newer chipsets
 | 
					 | 
				
			||||||
+		 * like QCA99X0, QCA4019 got revised. The CCK h/w rate values
 | 
					 | 
				
			||||||
+		 * are in a proper order with respect to the rate/preamble
 | 
					 | 
				
			||||||
+		 */
 | 
					 | 
				
			||||||
+		bool cck_rate_map_rev2;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 		u32 channel_counters_freq_hz;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 		/* Mgmt tx descriptors threshold for limiting probe response
 | 
					 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/hw.h
 | 
					 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/hw.h
 | 
					 | 
				
			||||||
@@ -315,6 +315,16 @@ enum ath10k_hw_rate_cck {
 | 
					 | 
				
			||||||
 	ATH10K_HW_RATE_CCK_SP_2M,
 | 
					 | 
				
			||||||
 };
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+enum ath10k_hw_rate_rev2_cck {
 | 
					 | 
				
			||||||
+	ATH10K_HW_RATE_REV2_CCK_LP_1M = 1,
 | 
					 | 
				
			||||||
+	ATH10K_HW_RATE_REV2_CCK_LP_2M,
 | 
					 | 
				
			||||||
+	ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
 | 
					 | 
				
			||||||
+	ATH10K_HW_RATE_REV2_CCK_LP_11M,
 | 
					 | 
				
			||||||
+	ATH10K_HW_RATE_REV2_CCK_SP_2M,
 | 
					 | 
				
			||||||
+	ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
 | 
					 | 
				
			||||||
+	ATH10K_HW_RATE_REV2_CCK_SP_11M,
 | 
					 | 
				
			||||||
+};
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 enum ath10k_hw_4addr_pad {
 | 
					 | 
				
			||||||
 	ATH10K_HW_4ADDR_PAD_AFTER,
 | 
					 | 
				
			||||||
 	ATH10K_HW_4ADDR_PAD_BEFORE,
 | 
					 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
					 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
					 | 
				
			||||||
@@ -62,6 +62,32 @@ static struct ieee80211_rate ath10k_rate
 | 
					 | 
				
			||||||
 	{ .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
 | 
					 | 
				
			||||||
 };
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+static struct ieee80211_rate ath10k_rates_rev2[] = {
 | 
					 | 
				
			||||||
+	{ .bitrate = 10,
 | 
					 | 
				
			||||||
+	  .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_1M },
 | 
					 | 
				
			||||||
+	{ .bitrate = 20,
 | 
					 | 
				
			||||||
+	  .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_2M,
 | 
					 | 
				
			||||||
+	  .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_2M,
 | 
					 | 
				
			||||||
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
 | 
					 | 
				
			||||||
+	{ .bitrate = 55,
 | 
					 | 
				
			||||||
+	  .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
 | 
					 | 
				
			||||||
+	  .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
 | 
					 | 
				
			||||||
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
 | 
					 | 
				
			||||||
+	{ .bitrate = 110,
 | 
					 | 
				
			||||||
+	  .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_11M,
 | 
					 | 
				
			||||||
+	  .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_11M,
 | 
					 | 
				
			||||||
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	{ .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
 | 
					 | 
				
			||||||
+	{ .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
 | 
					 | 
				
			||||||
+	{ .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
 | 
					 | 
				
			||||||
+	{ .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
 | 
					 | 
				
			||||||
+	{ .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
 | 
					 | 
				
			||||||
+	{ .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
 | 
					 | 
				
			||||||
+	{ .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
 | 
					 | 
				
			||||||
+	{ .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
 | 
					 | 
				
			||||||
+};
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 #define ATH10K_MAC_FIRST_OFDM_RATE_IDX 4
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 #define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)
 | 
					 | 
				
			||||||
@@ -70,6 +96,9 @@ static struct ieee80211_rate ath10k_rate
 | 
					 | 
				
			||||||
 #define ath10k_g_rates (ath10k_rates + 0)
 | 
					 | 
				
			||||||
 #define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+#define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
 | 
					 | 
				
			||||||
+#define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 static bool ath10k_mac_bitrate_is_cck(int bitrate)
 | 
					 | 
				
			||||||
 {
 | 
					 | 
				
			||||||
 	switch (bitrate) {
 | 
					 | 
				
			||||||
@@ -7720,8 +7749,14 @@ int ath10k_mac_register(struct ath10k *a
 | 
					 | 
				
			||||||
 		band = &ar->mac.sbands[NL80211_BAND_2GHZ];
 | 
					 | 
				
			||||||
 		band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
 | 
					 | 
				
			||||||
 		band->channels = channels;
 | 
					 | 
				
			||||||
-		band->n_bitrates = ath10k_g_rates_size;
 | 
					 | 
				
			||||||
-		band->bitrates = ath10k_g_rates;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+		if (ar->hw_params.cck_rate_map_rev2) {
 | 
					 | 
				
			||||||
+			band->n_bitrates = ath10k_g_rates_rev2_size;
 | 
					 | 
				
			||||||
+			band->bitrates = ath10k_g_rates_rev2;
 | 
					 | 
				
			||||||
+		} else {
 | 
					 | 
				
			||||||
+			band->n_bitrates = ath10k_g_rates_size;
 | 
					 | 
				
			||||||
+			band->bitrates = ath10k_g_rates;
 | 
					 | 
				
			||||||
+		}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 		ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					From: Felix Fietkau <nbd@nbd.name>
 | 
				
			||||||
 | 
					Date: Wed, 29 Jun 2016 10:02:32 +0200
 | 
				
			||||||
 | 
					Subject: [PATCH] cfg80211: fix proto in ieee80211_data_to_8023 for frames
 | 
				
			||||||
 | 
					 without LLC header
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The PDU length of incoming LLC frames is set to the total skb payload size
 | 
				
			||||||
 | 
					in __ieee80211_data_to_8023() of net/wireless/util.c which incorrectly
 | 
				
			||||||
 | 
					includes the length of the IEEE 802.11 header.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The resulting LLC frame header has a too large PDU length, causing the
 | 
				
			||||||
 | 
					llc_fixup_skb() function of net/llc/llc_input.c to reject the incoming
 | 
				
			||||||
 | 
					skb, effectively breaking STP.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Solve the problem by properly substracting the IEEE 802.11 frame header size
 | 
				
			||||||
 | 
					from the PDU length, allowing the LLC processor to pick up the incoming
 | 
				
			||||||
 | 
					control messages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Special thanks to Gerry Rozema for tracking down the regression and proposing
 | 
				
			||||||
 | 
					a suitable patch.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixes: 2d1c304cb2d5 ("cfg80211: add function for 802.3 conversion with separate output buffer")
 | 
				
			||||||
 | 
					Cc: stable@vger.kernel.org
 | 
				
			||||||
 | 
					Reported-by: Gerry Rozema <gerryr@rozeware.com>
 | 
				
			||||||
 | 
					Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- a/net/wireless/util.c
 | 
				
			||||||
 | 
					+++ b/net/wireless/util.c
 | 
				
			||||||
 | 
					@@ -509,7 +509,7 @@ static int __ieee80211_data_to_8023(stru
 | 
				
			||||||
 | 
					 		 * replace EtherType */
 | 
				
			||||||
 | 
					 		hdrlen += ETH_ALEN + 2;
 | 
				
			||||||
 | 
					 	else
 | 
				
			||||||
 | 
					-		tmp.h_proto = htons(skb->len);
 | 
				
			||||||
 | 
					+		tmp.h_proto = htons(skb->len - hdrlen);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	pskb_pull(skb, hdrlen);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
@@ -1,67 +0,0 @@
 | 
				
			|||||||
From: Michal Kazior <michal.kazior@tieto.com>
 | 
					 | 
				
			||||||
Date: Mon, 23 May 2016 23:12:45 +0300
 | 
					 | 
				
			||||||
Subject: [PATCH] ath10k: improve tx scheduling
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Recent changes revolving around implementing
 | 
					 | 
				
			||||||
wake_tx_queue support introduced a significant
 | 
					 | 
				
			||||||
performance regressions on some (slower, uni-proc)
 | 
					 | 
				
			||||||
systems.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
 | 
					 | 
				
			||||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
 | 
					 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
 | 
					 | 
				
			||||||
@@ -2291,7 +2291,6 @@ bool ath10k_htt_t2h_msg_handler(struct a
 | 
					 | 
				
			||||||
 			ath10k_htt_tx_mgmt_dec_pending(htt);
 | 
					 | 
				
			||||||
 			spin_unlock_bh(&htt->tx_lock);
 | 
					 | 
				
			||||||
 		}
 | 
					 | 
				
			||||||
-		ath10k_mac_tx_push_pending(ar);
 | 
					 | 
				
			||||||
 		break;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
 	case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
 | 
					 | 
				
			||||||
@@ -2442,8 +2441,6 @@ static void ath10k_htt_txrx_compl_task(u
 | 
					 | 
				
			||||||
 		dev_kfree_skb_any(skb);
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	ath10k_mac_tx_push_pending(ar);
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
 	num_mpdus = atomic_read(&htt->num_mpdus_ready);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	while (num_mpdus) {
 | 
					 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
					 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
					 | 
				
			||||||
@@ -3827,6 +3827,9 @@ void ath10k_mac_tx_push_pending(struct a
 | 
					 | 
				
			||||||
 	int ret;
 | 
					 | 
				
			||||||
 	int max;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+	if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
 | 
					 | 
				
			||||||
+		return;
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 	spin_lock_bh(&ar->txqs_lock);
 | 
					 | 
				
			||||||
 	rcu_read_lock();
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
@@ -4097,9 +4100,7 @@ static void ath10k_mac_op_wake_tx_queue(
 | 
					 | 
				
			||||||
 		list_add_tail(&artxq->list, &ar->txqs);
 | 
					 | 
				
			||||||
 	spin_unlock_bh(&ar->txqs_lock);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
-	if (ath10k_mac_tx_can_push(hw, txq))
 | 
					 | 
				
			||||||
-		tasklet_schedule(&ar->htt.txrx_compl_task);
 | 
					 | 
				
			||||||
-
 | 
					 | 
				
			||||||
+	ath10k_mac_tx_push_pending(ar);
 | 
					 | 
				
			||||||
 	ath10k_htt_tx_txq_update(hw, txq);
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/txrx.c
 | 
					 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
 | 
					 | 
				
			||||||
@@ -117,6 +117,9 @@ int ath10k_txrx_tx_unref(struct ath10k_h
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	ieee80211_tx_status(htt->ar->hw, msdu);
 | 
					 | 
				
			||||||
 	/* we do not own the msdu anymore */
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	ath10k_mac_tx_push_pending(ar);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 	return 0;
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
@@ -1,59 +0,0 @@
 | 
				
			|||||||
From: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
 | 
					 | 
				
			||||||
Date: Thu, 9 Jun 2016 11:33:55 +0530
 | 
					 | 
				
			||||||
Subject: [PATCH] ath10k: fix deadlock while processing rx_in_ord_ind
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
commit 5c86d97bcc1d ("ath10k: combine txrx and replenish task")
 | 
					 | 
				
			||||||
introduced deadlock while processing rx in order indication message
 | 
					 | 
				
			||||||
for qca6174 based devices. While merging replenish and txrx tasklets,
 | 
					 | 
				
			||||||
replenish task should be called out of htt rx ring locking since it
 | 
					 | 
				
			||||||
is also try to acquire the same lock.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unfortunately this issue is not exposed by other solutions (qca988x,
 | 
					 | 
				
			||||||
qca99x0 & qca4019), as rx_in_ord_ind message is specific to qca6174
 | 
					 | 
				
			||||||
based devices. This patch fixes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
=============================================
 | 
					 | 
				
			||||||
[ INFO: possible recursive locking detected ]
 | 
					 | 
				
			||||||
4.7.0-rc2-wt-ath+ #1353 Tainted: G            E
 | 
					 | 
				
			||||||
---------------------------------------------
 | 
					 | 
				
			||||||
swapper/3/0 is trying to acquire lock:
 | 
					 | 
				
			||||||
 (&(&htt->rx_ring.lock)->rlock){+.-...}, at: [<f8d7ef19>]
 | 
					 | 
				
			||||||
ath10k_htt_rx_msdu_buff_replenish+0x29/0x90 [ath10k_core]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
but task is already holding lock:
 | 
					 | 
				
			||||||
 (&(&htt->rx_ring.lock)->rlock){+.-...}, at: [<f8d82cab>]
 | 
					 | 
				
			||||||
ath10k_htt_txrx_compl_task+0x21b/0x250 [ath10k_core]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
other info that might help us debug this:
 | 
					 | 
				
			||||||
 Possible unsafe locking scenario:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
       CPU0
 | 
					 | 
				
			||||||
       ----
 | 
					 | 
				
			||||||
  lock(&(&htt->rx_ring.lock)->rlock);
 | 
					 | 
				
			||||||
  lock(&(&htt->rx_ring.lock)->rlock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 *** DEADLOCK ***
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 May be due to missing lock nesting notation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1 lock held by swapper/3/0:
 | 
					 | 
				
			||||||
 #0:  (&(&htt->rx_ring.lock)->rlock){+.-...}, at: [<f8d82cab>]
 | 
					 | 
				
			||||||
ath10k_htt_txrx_compl_task+0x21b/0x250 [ath10k_core]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=119151
 | 
					 | 
				
			||||||
Fixes: 5c86d97bcc1d ("ath10k: combine txrx and replenish task")
 | 
					 | 
				
			||||||
Reported-by: Mike Lothian <mike@fireburn.co.uk>
 | 
					 | 
				
			||||||
Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
 | 
					 | 
				
			||||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
 | 
					 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
 | 
					 | 
				
			||||||
@@ -1904,7 +1904,6 @@ static void ath10k_htt_rx_in_ord_ind(str
 | 
					 | 
				
			||||||
 			return;
 | 
					 | 
				
			||||||
 		}
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
-	ath10k_htt_rx_msdu_buff_replenish(htt);
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 static void ath10k_htt_rx_tx_fetch_resp_id_confirm(struct ath10k *ar,
 | 
					 | 
				
			||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/include/net/cfg80211.h
 | 
					--- a/include/net/cfg80211.h
 | 
				
			||||||
+++ b/include/net/cfg80211.h
 | 
					+++ b/include/net/cfg80211.h
 | 
				
			||||||
@@ -2406,6 +2406,7 @@ struct cfg80211_qos_map {
 | 
					@@ -2410,6 +2410,7 @@ struct cfg80211_qos_map {
 | 
				
			||||||
  *	(as advertised by the nl80211 feature flag.)
 | 
					  *	(as advertised by the nl80211 feature flag.)
 | 
				
			||||||
  * @get_tx_power: store the current TX power into the dbm variable;
 | 
					  * @get_tx_power: store the current TX power into the dbm variable;
 | 
				
			||||||
  *	return 0 if successful
 | 
					  *	return 0 if successful
 | 
				
			||||||
@@ -8,7 +8,7 @@
 | 
				
			|||||||
  *
 | 
					  *
 | 
				
			||||||
  * @set_wds_peer: set the WDS peer for a WDS interface
 | 
					  * @set_wds_peer: set the WDS peer for a WDS interface
 | 
				
			||||||
  *
 | 
					  *
 | 
				
			||||||
@@ -2667,6 +2668,7 @@ struct cfg80211_ops {
 | 
					@@ -2671,6 +2672,7 @@ struct cfg80211_ops {
 | 
				
			||||||
 				enum nl80211_tx_power_setting type, int mbm);
 | 
					 				enum nl80211_tx_power_setting type, int mbm);
 | 
				
			||||||
 	int	(*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
 | 
					 	int	(*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
 | 
				
			||||||
 				int *dbm);
 | 
					 				int *dbm);
 | 
				
			||||||
@@ -18,7 +18,7 @@
 | 
				
			|||||||
 				const u8 *addr);
 | 
					 				const u8 *addr);
 | 
				
			||||||
--- a/include/net/mac80211.h
 | 
					--- a/include/net/mac80211.h
 | 
				
			||||||
+++ b/include/net/mac80211.h
 | 
					+++ b/include/net/mac80211.h
 | 
				
			||||||
@@ -1305,6 +1305,7 @@ enum ieee80211_smps_mode {
 | 
					@@ -1317,6 +1317,7 @@ enum ieee80211_smps_mode {
 | 
				
			||||||
  *
 | 
					  *
 | 
				
			||||||
  * @power_level: requested transmit power (in dBm), backward compatibility
 | 
					  * @power_level: requested transmit power (in dBm), backward compatibility
 | 
				
			||||||
  *	value only that is set to the minimum of all interfaces
 | 
					  *	value only that is set to the minimum of all interfaces
 | 
				
			||||||
@@ -26,7 +26,7 @@
 | 
				
			|||||||
  *
 | 
					  *
 | 
				
			||||||
  * @chandef: the channel definition to tune to
 | 
					  * @chandef: the channel definition to tune to
 | 
				
			||||||
  * @radar_enabled: whether radar detection is enabled
 | 
					  * @radar_enabled: whether radar detection is enabled
 | 
				
			||||||
@@ -1325,6 +1326,7 @@ enum ieee80211_smps_mode {
 | 
					@@ -1337,6 +1338,7 @@ enum ieee80211_smps_mode {
 | 
				
			||||||
 struct ieee80211_conf {
 | 
					 struct ieee80211_conf {
 | 
				
			||||||
 	u32 flags;
 | 
					 	u32 flags;
 | 
				
			||||||
 	int power_level, dynamic_ps_timeout;
 | 
					 	int power_level, dynamic_ps_timeout;
 | 
				
			||||||
@@ -36,9 +36,9 @@
 | 
				
			|||||||
 	u8 ps_dtim_period;
 | 
					 	u8 ps_dtim_period;
 | 
				
			||||||
--- a/include/uapi/linux/nl80211.h
 | 
					--- a/include/uapi/linux/nl80211.h
 | 
				
			||||||
+++ b/include/uapi/linux/nl80211.h
 | 
					+++ b/include/uapi/linux/nl80211.h
 | 
				
			||||||
@@ -1819,6 +1819,9 @@ enum nl80211_commands {
 | 
					@@ -1829,6 +1829,9 @@ enum nl80211_commands {
 | 
				
			||||||
  *
 | 
					  *	%NL80211_ATTR_EXT_CAPA_MASK, to specify the extended capabilities per
 | 
				
			||||||
  * @NL80211_ATTR_PAD: attribute used for padding for 64-bit alignment
 | 
					  *	interface type.
 | 
				
			||||||
  *
 | 
					  *
 | 
				
			||||||
+ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
 | 
					+ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
 | 
				
			||||||
+ *	transmit power to stay within regulatory limits. u32, dBi.
 | 
					+ *	transmit power to stay within regulatory limits. u32, dBi.
 | 
				
			||||||
@@ -46,9 +46,9 @@
 | 
				
			|||||||
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
 | 
					  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
 | 
				
			||||||
  * @NL80211_ATTR_MAX: highest attribute number currently defined
 | 
					  * @NL80211_ATTR_MAX: highest attribute number currently defined
 | 
				
			||||||
  * @__NL80211_ATTR_AFTER_LAST: internal use
 | 
					  * @__NL80211_ATTR_AFTER_LAST: internal use
 | 
				
			||||||
@@ -2201,6 +2204,8 @@ enum nl80211_attrs {
 | 
					@@ -2213,6 +2216,8 @@ enum nl80211_attrs {
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	NL80211_ATTR_PAD,
 | 
					 	NL80211_ATTR_IFTYPE_EXT_CAPA,
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
+	NL80211_ATTR_WIPHY_ANTENNA_GAIN,
 | 
					+	NL80211_ATTR_WIPHY_ANTENNA_GAIN,
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
@@ -87,7 +87,7 @@
 | 
				
			|||||||
 	CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
 | 
					 	CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
 | 
				
			||||||
--- a/net/mac80211/ieee80211_i.h
 | 
					--- a/net/mac80211/ieee80211_i.h
 | 
				
			||||||
+++ b/net/mac80211/ieee80211_i.h
 | 
					+++ b/net/mac80211/ieee80211_i.h
 | 
				
			||||||
@@ -1322,6 +1322,7 @@ struct ieee80211_local {
 | 
					@@ -1338,6 +1338,7 @@ struct ieee80211_local {
 | 
				
			||||||
 	int dynamic_ps_forced_timeout;
 | 
					 	int dynamic_ps_forced_timeout;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	int user_power_level; /* in dBm, for all interfaces */
 | 
					 	int user_power_level; /* in dBm, for all interfaces */
 | 
				
			||||||
@@ -129,7 +129,7 @@
 | 
				
			|||||||
 	local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
 | 
					 	local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
 | 
				
			||||||
--- a/net/wireless/nl80211.c
 | 
					--- a/net/wireless/nl80211.c
 | 
				
			||||||
+++ b/net/wireless/nl80211.c
 | 
					+++ b/net/wireless/nl80211.c
 | 
				
			||||||
@@ -406,6 +406,7 @@ static const struct nla_policy nl80211_p
 | 
					@@ -407,6 +407,7 @@ static const struct nla_policy nl80211_p
 | 
				
			||||||
 	[NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
 | 
					 	[NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
 | 
				
			||||||
 	[NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
 | 
					 	[NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
 | 
				
			||||||
 	[NL80211_ATTR_STA_SUPPORT_P2P_PS] = { .type = NLA_U8 },
 | 
					 	[NL80211_ATTR_STA_SUPPORT_P2P_PS] = { .type = NLA_U8 },
 | 
				
			||||||
@@ -137,7 +137,7 @@
 | 
				
			|||||||
 };
 | 
					 };
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 /* policy for the key attributes */
 | 
					 /* policy for the key attributes */
 | 
				
			||||||
@@ -2251,6 +2252,20 @@ static int nl80211_set_wiphy(struct sk_b
 | 
					@@ -2294,6 +2295,20 @@ static int nl80211_set_wiphy(struct sk_b
 | 
				
			||||||
 		if (result)
 | 
					 		if (result)
 | 
				
			||||||
 			return result;
 | 
					 			return result;
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +0,0 @@
 | 
				
			|||||||
--- a/net/wireless/util.c
 | 
					 | 
				
			||||||
+++ b/net/wireless/util.c
 | 
					 | 
				
			||||||
@@ -509,7 +509,7 @@ static int __ieee80211_data_to_8023(stru
 | 
					 | 
				
			||||||
 		 * replace EtherType */
 | 
					 | 
				
			||||||
 		hdrlen += ETH_ALEN + 2;
 | 
					 | 
				
			||||||
 	else
 | 
					 | 
				
			||||||
-		tmp.h_proto = htons(skb->len);
 | 
					 | 
				
			||||||
+		tmp.h_proto = htons(skb->len - hdrlen);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	pskb_pull(skb, hdrlen);
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/drivers/net/wireless/ath/ath9k/mac.c
 | 
					--- a/drivers/net/wireless/ath/ath9k/mac.c
 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath9k/mac.c
 | 
					+++ b/drivers/net/wireless/ath/ath9k/mac.c
 | 
				
			||||||
@@ -695,7 +695,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
 | 
					@@ -698,7 +698,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
 #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
 | 
					 #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
 | 
				
			||||||
 	struct ath_common *common = ath9k_hw_common(ah);
 | 
					 	struct ath_common *common = ath9k_hw_common(ah);
 | 
				
			||||||
@@ -9,7 +9,7 @@
 | 
				
			|||||||
 	int i;
 | 
					 	int i;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	/* Enable access to the DMA observation bus */
 | 
					 	/* Enable access to the DMA observation bus */
 | 
				
			||||||
@@ -725,6 +725,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
 | 
					@@ -728,6 +728,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	if (i == 0) {
 | 
					 	if (i == 0) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@
 | 
				
			|||||||
 	antenna = b43_antenna_to_phyctl(antenna);
 | 
					 	antenna = b43_antenna_to_phyctl(antenna);
 | 
				
			||||||
 	ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
 | 
					 	ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
 | 
				
			||||||
 	/* We can't send beacons with short preamble. Would get PHY errors. */
 | 
					 	/* We can't send beacons with short preamble. Would get PHY errors. */
 | 
				
			||||||
@@ -3300,8 +3300,8 @@ static int b43_chip_init(struct b43_wlde
 | 
					@@ -3297,8 +3297,8 @@ static int b43_chip_init(struct b43_wlde
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	/* Select the antennae */
 | 
					 	/* Select the antennae */
 | 
				
			||||||
 	if (phy->ops->set_rx_antenna)
 | 
					 	if (phy->ops->set_rx_antenna)
 | 
				
			||||||
@@ -20,7 +20,7 @@
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
 	if (phy->type == B43_PHYTYPE_B) {
 | 
					 	if (phy->type == B43_PHYTYPE_B) {
 | 
				
			||||||
 		value16 = b43_read16(dev, 0x005E);
 | 
					 		value16 = b43_read16(dev, 0x005E);
 | 
				
			||||||
@@ -4001,7 +4001,6 @@ static int b43_op_config(struct ieee8021
 | 
					@@ -3998,7 +3998,6 @@ static int b43_op_config(struct ieee8021
 | 
				
			||||||
 	struct b43_wldev *dev = wl->current_dev;
 | 
					 	struct b43_wldev *dev = wl->current_dev;
 | 
				
			||||||
 	struct b43_phy *phy = &dev->phy;
 | 
					 	struct b43_phy *phy = &dev->phy;
 | 
				
			||||||
 	struct ieee80211_conf *conf = &hw->conf;
 | 
					 	struct ieee80211_conf *conf = &hw->conf;
 | 
				
			||||||
@@ -28,7 +28,7 @@
 | 
				
			|||||||
 	int err = 0;
 | 
					 	int err = 0;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	mutex_lock(&wl->mutex);
 | 
					 	mutex_lock(&wl->mutex);
 | 
				
			||||||
@@ -4044,11 +4043,9 @@ static int b43_op_config(struct ieee8021
 | 
					@@ -4041,11 +4040,9 @@ static int b43_op_config(struct ieee8021
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	/* Antennas for RX and management frame TX. */
 | 
					 	/* Antennas for RX and management frame TX. */
 | 
				
			||||||
@@ -42,7 +42,7 @@
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
 	if (wl->radio_enabled != phy->radio_on) {
 | 
					 	if (wl->radio_enabled != phy->radio_on) {
 | 
				
			||||||
 		if (wl->radio_enabled) {
 | 
					 		if (wl->radio_enabled) {
 | 
				
			||||||
@@ -5207,6 +5204,47 @@ static int b43_op_get_survey(struct ieee
 | 
					@@ -5189,6 +5186,47 @@ static int b43_op_get_survey(struct ieee
 | 
				
			||||||
 	return 0;
 | 
					 	return 0;
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -90,7 +90,7 @@
 | 
				
			|||||||
 static const struct ieee80211_ops b43_hw_ops = {
 | 
					 static const struct ieee80211_ops b43_hw_ops = {
 | 
				
			||||||
 	.tx			= b43_op_tx,
 | 
					 	.tx			= b43_op_tx,
 | 
				
			||||||
 	.conf_tx		= b43_op_conf_tx,
 | 
					 	.conf_tx		= b43_op_conf_tx,
 | 
				
			||||||
@@ -5228,6 +5266,8 @@ static const struct ieee80211_ops b43_hw
 | 
					@@ -5210,6 +5248,8 @@ static const struct ieee80211_ops b43_hw
 | 
				
			||||||
 	.sw_scan_complete	= b43_op_sw_scan_complete_notifier,
 | 
					 	.sw_scan_complete	= b43_op_sw_scan_complete_notifier,
 | 
				
			||||||
 	.get_survey		= b43_op_get_survey,
 | 
					 	.get_survey		= b43_op_get_survey,
 | 
				
			||||||
 	.rfkill_poll		= b43_rfkill_poll,
 | 
					 	.rfkill_poll		= b43_rfkill_poll,
 | 
				
			||||||
@@ -99,7 +99,7 @@
 | 
				
			|||||||
 };
 | 
					 };
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 /* Hard-reset the chip. Do not call this directly.
 | 
					 /* Hard-reset the chip. Do not call this directly.
 | 
				
			||||||
@@ -5536,6 +5576,8 @@ static int b43_one_core_attach(struct b4
 | 
					@@ -5513,6 +5553,8 @@ static int b43_one_core_attach(struct b4
 | 
				
			||||||
 	if (!wldev)
 | 
					 	if (!wldev)
 | 
				
			||||||
 		goto out;
 | 
					 		goto out;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -108,7 +108,7 @@
 | 
				
			|||||||
 	wldev->use_pio = b43_modparam_pio;
 | 
					 	wldev->use_pio = b43_modparam_pio;
 | 
				
			||||||
 	wldev->dev = dev;
 | 
					 	wldev->dev = dev;
 | 
				
			||||||
 	wldev->wl = wl;
 | 
					 	wldev->wl = wl;
 | 
				
			||||||
@@ -5626,6 +5668,9 @@ static struct b43_wl *b43_wireless_init(
 | 
					@@ -5603,6 +5645,9 @@ static struct b43_wl *b43_wireless_init(
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
 | 
					 	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
 | 
					 | 
				
			||||||
Subject: [PATCH] brcmfmac: add missing eth_type_trans call
 | 
					 | 
				
			||||||
MIME-Version: 1.0
 | 
					 | 
				
			||||||
Content-Type: text/plain; charset=UTF-8
 | 
					 | 
				
			||||||
Content-Transfer-Encoding: 8bit
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
There are 2 protocols supported by brcmfmac and msgbuf one was missing a
 | 
					 | 
				
			||||||
proper skb setup before passing it to the netif. This was triggering
 | 
					 | 
				
			||||||
"NULL pointer dereference".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Fixes: 9c349892ccc9 ("brcmfmac: revise handling events in receive path")
 | 
					 | 
				
			||||||
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
 | 
					 | 
				
			||||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
 | 
					 | 
				
			||||||
@@ -1157,6 +1157,9 @@ brcmf_msgbuf_process_rx_complete(struct
 | 
					 | 
				
			||||||
 		brcmu_pkt_buf_free_skb(skb);
 | 
					 | 
				
			||||||
 		return;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	skb->protocol = eth_type_trans(skb, ifp->ndev);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
 	brcmf_netif_rx(ifp, skb);
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
@@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
 | 
					--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
 | 
				
			||||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
 | 
					+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
 | 
				
			||||||
@@ -1232,6 +1232,7 @@ int __init brcmf_core_init(void)
 | 
					@@ -1208,6 +1208,7 @@ int __init brcmf_core_init(void)
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
 	if (!schedule_work(&brcmf_driver_work))
 | 
					 	if (!schedule_work(&brcmf_driver_work))
 | 
				
			||||||
 		return -EBUSY;
 | 
					 		return -EBUSY;
 | 
				
			||||||
@@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 | 
					--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 | 
				
			||||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 | 
					+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 | 
				
			||||||
@@ -650,9 +650,37 @@ static struct wireless_dev *brcmf_cfg802
 | 
					@@ -665,9 +665,37 @@ static struct wireless_dev *brcmf_cfg802
 | 
				
			||||||
 						     u32 *flags,
 | 
					 						     u32 *flags,
 | 
				
			||||||
 						     struct vif_params *params)
 | 
					 						     struct vif_params *params)
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
@@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 | 
					--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 | 
				
			||||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 | 
					+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 | 
				
			||||||
@@ -2711,6 +2711,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
 | 
					@@ -2746,6 +2746,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
 | 
				
			||||||
 	 * preference in cfg struct to apply this to
 | 
					 	 * preference in cfg struct to apply this to
 | 
				
			||||||
 	 * FW later while initializing the dongle
 | 
					 	 * FW later while initializing the dongle
 | 
				
			||||||
 	 */
 | 
					 	 */
 | 
				
			||||||
@@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
--- a/drivers/net/wireless/ath/ath10k/core.c
 | 
					--- a/drivers/net/wireless/ath/ath10k/core.c
 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
 | 
					+++ b/drivers/net/wireless/ath/ath10k/core.c
 | 
				
			||||||
@@ -2012,6 +2012,16 @@ int ath10k_core_register(struct ath10k *
 | 
					@@ -2107,6 +2107,16 @@ int ath10k_core_register(struct ath10k *
 | 
				
			||||||
 	ar->chip_id = chip_id;
 | 
					 	ar->chip_id = chip_id;
 | 
				
			||||||
 	queue_work(ar->workqueue, &ar->register_work);
 | 
					 	queue_work(ar->workqueue, &ar->register_work);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
					--- a/drivers/net/wireless/ath/ath10k/mac.c
 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
					+++ b/drivers/net/wireless/ath/ath10k/mac.c
 | 
				
			||||||
@@ -7717,6 +7717,21 @@ struct ath10k_vif *ath10k_get_arvif(stru
 | 
					@@ -7731,6 +7731,21 @@ struct ath10k_vif *ath10k_get_arvif(stru
 | 
				
			||||||
 	return arvif_iter.arvif;
 | 
					 	return arvif_iter.arvif;
 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -22,7 +22,7 @@
 | 
				
			|||||||
 int ath10k_mac_register(struct ath10k *ar)
 | 
					 int ath10k_mac_register(struct ath10k *ar)
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
 	static const u32 cipher_suites[] = {
 | 
					 	static const u32 cipher_suites[] = {
 | 
				
			||||||
@@ -7941,6 +7956,12 @@ int ath10k_mac_register(struct ath10k *a
 | 
					@@ -7955,6 +7970,12 @@ int ath10k_mac_register(struct ath10k *a
 | 
				
			||||||
 	ar->hw->wiphy->cipher_suites = cipher_suites;
 | 
					 	ar->hw->wiphy->cipher_suites = cipher_suites;
 | 
				
			||||||
 	ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
 | 
					 	ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
--- a/drivers/net/wireless/ath/ath10k/core.c
 | 
					--- a/drivers/net/wireless/ath/ath10k/core.c
 | 
				
			||||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
 | 
					+++ b/drivers/net/wireless/ath/ath10k/core.c
 | 
				
			||||||
@@ -1168,9 +1168,6 @@ static int ath10k_core_fetch_firmware_fi
 | 
					@@ -1243,9 +1243,6 @@ static int ath10k_core_fetch_firmware_fi
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
 	int ret;
 | 
					 	int ret;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -10,7 +10,7 @@
 | 
				
			|||||||
 	ar->fw_api = 5;
 | 
					 	ar->fw_api = 5;
 | 
				
			||||||
 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
 | 
					 	ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -1873,6 +1870,9 @@ static int ath10k_core_probe_fw(struct a
 | 
					@@ -1968,6 +1965,9 @@ static int ath10k_core_probe_fw(struct a
 | 
				
			||||||
 		goto err_power_down;
 | 
					 		goto err_power_down;
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -20,7 +20,7 @@
 | 
				
			|||||||
 	ret = ath10k_core_fetch_firmware_files(ar);
 | 
					 	ret = ath10k_core_fetch_firmware_files(ar);
 | 
				
			||||||
 	if (ret) {
 | 
					 	if (ret) {
 | 
				
			||||||
 		ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
 | 
					 		ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
 | 
				
			||||||
@@ -1895,11 +1895,14 @@ static int ath10k_core_probe_fw(struct a
 | 
					@@ -1990,11 +1990,14 @@ static int ath10k_core_probe_fw(struct a
 | 
				
			||||||
 			   "could not load pre cal data: %d\n", ret);
 | 
					 			   "could not load pre cal data: %d\n", ret);
 | 
				
			||||||
 	}
 | 
					 	}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user