mac80211: update to wireless-testing 2013-04-16 + backports
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 36448
This commit is contained in:
		@@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
 | 
			
		||||
 | 
			
		||||
PKG_NAME:=mac80211
 | 
			
		||||
 | 
			
		||||
PKG_VERSION:=2013-02-22
 | 
			
		||||
PKG_VERSION:=2013-04-16
 | 
			
		||||
PKG_RELEASE:=1
 | 
			
		||||
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 | 
			
		||||
PKG_MD5SUM:=de1a03ca1f72748d4523672c8facbf7e
 | 
			
		||||
PKG_MD5SUM:=ec4cd40f0a8838aeea2ccff3ec5deb1a
 | 
			
		||||
 | 
			
		||||
PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
 | 
			
		||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
 | 
			
		||||
@@ -212,7 +212,7 @@ $(call KernelPackage/rt2x00/Default)
 | 
			
		||||
  DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-mac80211 +kmod-lib-crc-itu-t
 | 
			
		||||
  TITLE+= (LIB)
 | 
			
		||||
  FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00lib.ko
 | 
			
		||||
  AUTOLOAD:=$(call AutoLoad,25,rt2x00lib)
 | 
			
		||||
  AUTOLOAD:=$(call AutoLoad,24,rt2x00lib)
 | 
			
		||||
  MENU:=1
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
@@ -239,8 +239,10 @@ define KernelPackage/rt2x00-pci
 | 
			
		||||
$(call KernelPackage/rt2x00/Default)
 | 
			
		||||
  DEPENDS+= @(PCI_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib +kmod-eeprom-93cx6
 | 
			
		||||
  TITLE+= (PCI)
 | 
			
		||||
  FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00pci.ko
 | 
			
		||||
  AUTOLOAD:=$(call AutoLoad,26,rt2x00pci)
 | 
			
		||||
  FILES:= \
 | 
			
		||||
	$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00pci.ko \
 | 
			
		||||
	$(PKG_BUILD_DIR)/drivers/net/wireless/rt2x00/rt2x00mmio.ko
 | 
			
		||||
  AUTOLOAD:=$(call AutoLoad,25,rt2x00mmio rt2x00pci)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define KernelPackage/rt2x00-usb
 | 
			
		||||
@@ -1269,6 +1271,7 @@ MAKE_OPTS:= \
 | 
			
		||||
	CONFIG_P54_SPI_DEFAULT_EEPROM=n \
 | 
			
		||||
	CONFIG_RT2X00=$(if $(CONFIG_PACKAGE_kmod-rt2x00-lib),m) \
 | 
			
		||||
	CONFIG_RT2X00_LIB=$(if $(CONFIG_PACKAGE_kmod-rt2x00-lib),m) \
 | 
			
		||||
	CONFIG_RT2X00_LIB_MMIO=$(if $(CONFIG_PACKAGE_kmod-rt2x00-pci),m) \
 | 
			
		||||
	CONFIG_RT2X00_LIB_PCI=$(if $(CONFIG_PACKAGE_kmod-rt2x00-pci),m) \
 | 
			
		||||
	CONFIG_RT2X00_LIB_USB=$(if $(CONFIG_PACKAGE_kmod-rt2x00-usb),m) \
 | 
			
		||||
	CONFIG_RT2X00_LIB_SOC=$(if $(CONFIG_PACKAGE_kmod-rt2x00-soc),m) \
 | 
			
		||||
@@ -1290,7 +1293,7 @@ MAKE_OPTS:= \
 | 
			
		||||
	CONFIG_RTL8187=$(if $(CONFIG_PACKAGE_kmod-rtl8187),m) \
 | 
			
		||||
	CONFIG_RTL8192CE= \
 | 
			
		||||
	CONFIG_RTLWIFI= \
 | 
			
		||||
	CONFIG_MAC80211_HWSIM=$(if $(CONFIG_PACKAGE_kmod-mac80211-hwsim),m) \
 | 
			
		||||
	CONFIG_COMPAT_MAC80211_HWSIM=$(if $(CONFIG_PACKAGE_kmod-mac80211-hwsim),m) \
 | 
			
		||||
	CONFIG_PCMCIA= \
 | 
			
		||||
	CONFIG_LIBIPW=$(if $(CONFIG_PACKAGE_kmod-net-libipw),m) \
 | 
			
		||||
	CONFIG_LIBERTAS=$(if $(CONFIG_PACKAGE_kmod-libertas-sd)$(CONFIG_PACKAGE_kmod-libertas-usb),m) \
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								package/mac80211/patches/000-disable_drivers.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								package/mac80211/patches/000-disable_drivers.patch
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
--- a/config.mk
 | 
			
		||||
+++ b/config.mk
 | 
			
		||||
@@ -724,34 +724,3 @@ endif #CONFIG_LEDS_TRIGGERS
 | 
			
		||||
 # export CONFIG_RFKILL_BACKPORT_INPUT=y
 | 
			
		||||
 endif #CONFIG_COMPAT_KERNEL_2_6_31
 | 
			
		||||
 
 | 
			
		||||
-# compilation has been tested down to 3.0 but run time
 | 
			
		||||
-# tests have only started on 3.2.
 | 
			
		||||
-ifndef CONFIG_COMPAT_KERNEL_3_2
 | 
			
		||||
-# Basic DRM support
 | 
			
		||||
-export CONFIG_COMPAT_VIDEO_MODULES=y
 | 
			
		||||
-export CONFIG_COMPAT_DRM=m
 | 
			
		||||
-export CONFIG_COMPAT_DRM_TTM=m
 | 
			
		||||
-export CONFIG_COMPAT_DRM_KMS_HELPER=m
 | 
			
		||||
-export CONFIG_COMPAT_DRM_LOAD_EDID_FIRMWARE=y
 | 
			
		||||
-# Intel i915
 | 
			
		||||
-export CONFIG_COMPAT_DRM_I915=m
 | 
			
		||||
-# ATI/AMD Radeon
 | 
			
		||||
-export CONFIG_COMPAT_DRM_RADEON=m
 | 
			
		||||
-export CONFIG_COMPAT_DRM_RADEON_KMS=y
 | 
			
		||||
-export CONFIG_COMPAT_DRM_NOUVEAU=m
 | 
			
		||||
-export CONFIG_COMPAT_DRM_NOUVEAU_BACKLIGHT=y
 | 
			
		||||
-export CONFIG_COMPAT_NOUVEAU_DEBUG=5
 | 
			
		||||
-export CONFIG_COMPAT_NOUVEAU_DEBUG_DEFAULT=3
 | 
			
		||||
-ifdef CONFIG_MEDIA_CONTROLLER
 | 
			
		||||
-export CONFIG_COMPAT_USB_VIDEO_CLASS=m
 | 
			
		||||
-endif #CONFIG_MEDIA_CONTROLLER
 | 
			
		||||
-export CONFIG_USB_VIDEO_CLASS=y
 | 
			
		||||
-endif #CONFIG_COMPAT_KERNEL_3_2
 | 
			
		||||
-
 | 
			
		||||
-ifndef CONFIG_COMPAT_KERNEL_3_2
 | 
			
		||||
-export CONFIG_COMPAT_MEDIA_MODULES=y
 | 
			
		||||
-export CONFIG_COMPAT_VIDEO_V4L2=m
 | 
			
		||||
-export CONFIG_COMPAT_VIDEOBUF2_CORE=m
 | 
			
		||||
-export CONFIG_COMPAT_VIDEOBUF2_VMALLOC=m
 | 
			
		||||
-export CONFIG_COMPAT_VIDEOBUF2_MEMOPS=m
 | 
			
		||||
-endif #CONFIG_COMPAT_KERNEL_3_2
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/config.mk
 | 
			
		||||
+++ b/config.mk
 | 
			
		||||
@@ -364,7 +364,8 @@ export CONFIG_IPW2200_QOS=y
 | 
			
		||||
@@ -371,7 +371,8 @@ export CONFIG_IPW2200_QOS=y
 | 
			
		||||
 # % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
 | 
			
		||||
 endif #CONFIG_WIRELESS_EXT
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
 # Sonics Silicon Backplane
 | 
			
		||||
 export CONFIG_SSB_SPROM=y
 | 
			
		||||
 
 | 
			
		||||
@@ -377,7 +378,7 @@ endif #CONFIG_PCMCIA
 | 
			
		||||
@@ -384,7 +385,7 @@ endif #CONFIG_PCMCIA
 | 
			
		||||
 # export CONFIG_SSB_DEBUG=y
 | 
			
		||||
 export CONFIG_SSB_DRIVER_PCICORE=y
 | 
			
		||||
 export CONFIG_B43_SSB=y
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/include/linux/compat-3.0.h
 | 
			
		||||
+++ b/include/linux/compat-3.0.h
 | 
			
		||||
@@ -36,6 +36,8 @@ static inline struct page *shmem_read_ma
 | 
			
		||||
@@ -38,6 +38,8 @@ static inline struct page *shmem_read_ma
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/net/wireless/core.c
 | 
			
		||||
+++ b/net/wireless/core.c
 | 
			
		||||
@@ -884,6 +884,15 @@ static int cfg80211_netdev_notifier_call
 | 
			
		||||
@@ -951,6 +951,15 @@ static int cfg80211_netdev_notifier_call
 | 
			
		||||
 		wdev->sme_state = CFG80211_SME_IDLE;
 | 
			
		||||
 		mutex_unlock(&rdev->devlist_mtx);
 | 
			
		||||
 #ifdef CONFIG_CFG80211_WEXT
 | 
			
		||||
 
 | 
			
		||||
@@ -1,153 +0,0 @@
 | 
			
		||||
--- a/include/linux/compat-2.6.h
 | 
			
		||||
+++ b/include/linux/compat-2.6.h
 | 
			
		||||
@@ -69,6 +69,7 @@ void compat_dependency_symbol(void);
 | 
			
		||||
 #include <linux/compat-3.6.h>
 | 
			
		||||
 #include <linux/compat-3.7.h>
 | 
			
		||||
 #include <linux/compat-3.8.h>
 | 
			
		||||
+#include <linux/compat-3.9.h>
 | 
			
		||||
 
 | 
			
		||||
 #endif /* __ASSEMBLY__ */
 | 
			
		||||
 
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/include/linux/compat-3.9.h
 | 
			
		||||
@@ -0,0 +1,140 @@
 | 
			
		||||
+#ifndef LINUX_3_9_COMPAT_H
 | 
			
		||||
+#define LINUX_3_9_COMPAT_H
 | 
			
		||||
+
 | 
			
		||||
+#include <linux/version.h>
 | 
			
		||||
+
 | 
			
		||||
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
 | 
			
		||||
+
 | 
			
		||||
+#include <linux/idr.h>
 | 
			
		||||
+#include <linux/list.h>
 | 
			
		||||
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25))
 | 
			
		||||
+#include <linux/rculist.h>
 | 
			
		||||
+#endif
 | 
			
		||||
+#include <net/sock.h>
 | 
			
		||||
+#include <linux/tty.h>
 | 
			
		||||
+#include <linux/tty_flip.h>
 | 
			
		||||
+
 | 
			
		||||
+/* include this before changing hlist_for_each_* to use the old versions. */
 | 
			
		||||
+#include <net/sch_generic.h>
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
+/**
 | 
			
		||||
+ * backport of idr idr_alloc() usage
 | 
			
		||||
+ * 
 | 
			
		||||
+ * This backports a patch series send by Tejun Heo:
 | 
			
		||||
+ * https://lkml.org/lkml/2013/2/2/159
 | 
			
		||||
+ */
 | 
			
		||||
+static inline void compat_idr_destroy(struct idr *idp)
 | 
			
		||||
+{
 | 
			
		||||
+	idr_remove_all(idp);
 | 
			
		||||
+	idr_destroy(idp);
 | 
			
		||||
+}
 | 
			
		||||
+#define idr_destroy(idp) compat_idr_destroy(idp)
 | 
			
		||||
+
 | 
			
		||||
+static inline int idr_alloc(struct idr *idr, void *ptr, int start, int end,
 | 
			
		||||
+			    gfp_t gfp_mask)
 | 
			
		||||
+{
 | 
			
		||||
+	int id, ret;
 | 
			
		||||
+
 | 
			
		||||
+	do {
 | 
			
		||||
+		if (!idr_pre_get(idr, gfp_mask))
 | 
			
		||||
+			return -ENOMEM;
 | 
			
		||||
+		ret = idr_get_new_above(idr, ptr, start, &id);
 | 
			
		||||
+		if (!ret && id > end) {
 | 
			
		||||
+			idr_remove(idr, id);
 | 
			
		||||
+			ret = -ENOSPC;
 | 
			
		||||
+		}
 | 
			
		||||
+	} while (ret == -EAGAIN);
 | 
			
		||||
+
 | 
			
		||||
+	return ret ? ret : id;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static inline void idr_preload(gfp_t gfp_mask)
 | 
			
		||||
+{
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static inline void idr_preload_end(void)
 | 
			
		||||
+{
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
+/**
 | 
			
		||||
+ * backport:
 | 
			
		||||
+ *
 | 
			
		||||
+ * commit 0bbacca7c3911451cea923b0ad6389d58e3d9ce9
 | 
			
		||||
+ * Author: Sasha Levin <sasha.levin@oracle.com>
 | 
			
		||||
+ * Date:   Thu Feb 7 12:32:18 2013 +1100
 | 
			
		||||
+ *
 | 
			
		||||
+ *     hlist: drop the node parameter from iterators
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+#define hlist_entry_safe(ptr, type, member) \
 | 
			
		||||
+	(ptr) ? hlist_entry(ptr, type, member) : NULL
 | 
			
		||||
+
 | 
			
		||||
+#undef hlist_for_each_entry
 | 
			
		||||
+/**
 | 
			
		||||
+ * hlist_for_each_entry	- iterate over list of given type
 | 
			
		||||
+ * @pos:	the type * to use as a loop cursor.
 | 
			
		||||
+ * @head:	the head for your list.
 | 
			
		||||
+ * @member:	the name of the hlist_node within the struct.
 | 
			
		||||
+ */
 | 
			
		||||
+#define hlist_for_each_entry(pos, head, member)					\
 | 
			
		||||
+	for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);	\
 | 
			
		||||
+	     pos;								\
 | 
			
		||||
+	     pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
 | 
			
		||||
+
 | 
			
		||||
+#undef hlist_for_each_entry_safe
 | 
			
		||||
+/**
 | 
			
		||||
+ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
 | 
			
		||||
+ * @pos:	the type * to use as a loop cursor.
 | 
			
		||||
+ * @n:		another &struct hlist_node to use as temporary storage
 | 
			
		||||
+ * @head:	the head for your list.
 | 
			
		||||
+ * @member:	the name of the hlist_node within the struct.
 | 
			
		||||
+ */
 | 
			
		||||
+#define hlist_for_each_entry_safe(pos, n, head, member) 			\
 | 
			
		||||
+	for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);	\
 | 
			
		||||
+	     pos && ({ n = pos->member.next; 1; });				\
 | 
			
		||||
+	     pos = hlist_entry_safe(n, typeof(*pos), member))
 | 
			
		||||
+
 | 
			
		||||
+#undef hlist_for_each_entry_rcu
 | 
			
		||||
+/**
 | 
			
		||||
+ * hlist_for_each_entry_rcu - iterate over rcu list of given type
 | 
			
		||||
+ * @pos:	the type * to use as a loop cursor.
 | 
			
		||||
+ * @head:	the head for your list.
 | 
			
		||||
+ * @member:	the name of the hlist_node within the struct.
 | 
			
		||||
+ *
 | 
			
		||||
+ * This list-traversal primitive may safely run concurrently with
 | 
			
		||||
+ * the _rcu list-mutation primitives such as hlist_add_head_rcu()
 | 
			
		||||
+ * as long as the traversal is guarded by rcu_read_lock().
 | 
			
		||||
+ */
 | 
			
		||||
+#define hlist_for_each_entry_rcu(pos, head, member)				\
 | 
			
		||||
+	for (pos = hlist_entry_safe (rcu_dereference_raw(hlist_first_rcu(head)),\
 | 
			
		||||
+			typeof(*(pos)), member);				\
 | 
			
		||||
+		pos;								\
 | 
			
		||||
+		pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(	\
 | 
			
		||||
+			&(pos)->member)), typeof(*(pos)), member))
 | 
			
		||||
+
 | 
			
		||||
+#undef sk_for_each
 | 
			
		||||
+#define sk_for_each(__sk, list) \
 | 
			
		||||
+	hlist_for_each_entry(__sk, list, sk_node)
 | 
			
		||||
+
 | 
			
		||||
+#define tty_flip_buffer_push(port) tty_flip_buffer_push((port)->tty)
 | 
			
		||||
+#define tty_insert_flip_string(port, chars, size) tty_insert_flip_string((port)->tty, chars, size)
 | 
			
		||||
+
 | 
			
		||||
+/**
 | 
			
		||||
+ * backport of:
 | 
			
		||||
+ *
 | 
			
		||||
+ * commit 496ad9aa8ef448058e36ca7a787c61f2e63f0f54
 | 
			
		||||
+ * Author: Al Viro <viro@zeniv.linux.org.uk>
 | 
			
		||||
+ * Date:   Wed Jan 23 17:07:38 2013 -0500
 | 
			
		||||
+ *
 | 
			
		||||
+ *     new helper: file_inode(file)
 | 
			
		||||
+ */
 | 
			
		||||
+static inline struct inode *file_inode(struct file *f)
 | 
			
		||||
+{
 | 
			
		||||
+	return f->f_path.dentry->d_inode;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) */
 | 
			
		||||
+
 | 
			
		||||
+#endif /* LINUX_3_9_COMPAT_H */
 | 
			
		||||
@@ -1,212 +0,0 @@
 | 
			
		||||
--- a/net/mac80211/mesh_pathtbl.c
 | 
			
		||||
+++ b/net/mac80211/mesh_pathtbl.c
 | 
			
		||||
@@ -72,9 +72,9 @@ static inline struct mesh_table *resize_
 | 
			
		||||
  * it's used twice. So it is illegal to do
 | 
			
		||||
  *	for_each_mesh_entry(rcu_dereference(...), ...)
 | 
			
		||||
  */
 | 
			
		||||
-#define for_each_mesh_entry(tbl, p, node, i) \
 | 
			
		||||
+#define for_each_mesh_entry(tbl, node, i) \
 | 
			
		||||
 	for (i = 0; i <= tbl->hash_mask; i++) \
 | 
			
		||||
-		hlist_for_each_entry_rcu(node, p, &tbl->hash_buckets[i], list)
 | 
			
		||||
+		hlist_for_each_entry_rcu(node, &tbl->hash_buckets[i], list)
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
 static struct mesh_table *mesh_table_alloc(int size_order)
 | 
			
		||||
@@ -139,7 +139,7 @@ static void mesh_table_free(struct mesh_
 | 
			
		||||
 	}
 | 
			
		||||
 	if (free_leafs) {
 | 
			
		||||
 		spin_lock_bh(&tbl->gates_lock);
 | 
			
		||||
-		hlist_for_each_entry_safe(gate, p, q,
 | 
			
		||||
+		hlist_for_each_entry_safe(gate, q,
 | 
			
		||||
 					 tbl->known_gates, list) {
 | 
			
		||||
 			hlist_del(&gate->list);
 | 
			
		||||
 			kfree(gate);
 | 
			
		||||
@@ -333,12 +333,11 @@ static struct mesh_path *mpath_lookup(st
 | 
			
		||||
 				      struct ieee80211_sub_if_data *sdata)
 | 
			
		||||
 {
 | 
			
		||||
 	struct mesh_path *mpath;
 | 
			
		||||
-	struct hlist_node *n;
 | 
			
		||||
 	struct hlist_head *bucket;
 | 
			
		||||
 	struct mpath_node *node;
 | 
			
		||||
 
 | 
			
		||||
 	bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)];
 | 
			
		||||
-	hlist_for_each_entry_rcu(node, n, bucket, list) {
 | 
			
		||||
+	hlist_for_each_entry_rcu(node, bucket, list) {
 | 
			
		||||
 		mpath = node->mpath;
 | 
			
		||||
 		if (mpath->sdata == sdata &&
 | 
			
		||||
 		    ether_addr_equal(dst, mpath->dst)) {
 | 
			
		||||
@@ -389,11 +388,10 @@ mesh_path_lookup_by_idx(struct ieee80211
 | 
			
		||||
 {
 | 
			
		||||
 	struct mesh_table *tbl = rcu_dereference(mesh_paths);
 | 
			
		||||
 	struct mpath_node *node;
 | 
			
		||||
-	struct hlist_node *p;
 | 
			
		||||
 	int i;
 | 
			
		||||
 	int j = 0;
 | 
			
		||||
 
 | 
			
		||||
-	for_each_mesh_entry(tbl, p, node, i) {
 | 
			
		||||
+	for_each_mesh_entry(tbl, node, i) {
 | 
			
		||||
 		if (sdata && node->mpath->sdata != sdata)
 | 
			
		||||
 			continue;
 | 
			
		||||
 		if (j++ == idx) {
 | 
			
		||||
@@ -417,13 +415,12 @@ int mesh_path_add_gate(struct mesh_path
 | 
			
		||||
 {
 | 
			
		||||
 	struct mesh_table *tbl;
 | 
			
		||||
 	struct mpath_node *gate, *new_gate;
 | 
			
		||||
-	struct hlist_node *n;
 | 
			
		||||
 	int err;
 | 
			
		||||
 
 | 
			
		||||
 	rcu_read_lock();
 | 
			
		||||
 	tbl = rcu_dereference(mesh_paths);
 | 
			
		||||
 
 | 
			
		||||
-	hlist_for_each_entry_rcu(gate, n, tbl->known_gates, list)
 | 
			
		||||
+	hlist_for_each_entry_rcu(gate, tbl->known_gates, list)
 | 
			
		||||
 		if (gate->mpath == mpath) {
 | 
			
		||||
 			err = -EEXIST;
 | 
			
		||||
 			goto err_rcu;
 | 
			
		||||
@@ -460,9 +457,9 @@ err_rcu:
 | 
			
		||||
 static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath)
 | 
			
		||||
 {
 | 
			
		||||
 	struct mpath_node *gate;
 | 
			
		||||
-	struct hlist_node *p, *q;
 | 
			
		||||
+	struct hlist_node *q;
 | 
			
		||||
 
 | 
			
		||||
-	hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list) {
 | 
			
		||||
+	hlist_for_each_entry_safe(gate, q, tbl->known_gates, list) {
 | 
			
		||||
 		if (gate->mpath != mpath)
 | 
			
		||||
 			continue;
 | 
			
		||||
 		spin_lock_bh(&tbl->gates_lock);
 | 
			
		||||
@@ -504,7 +501,6 @@ int mesh_path_add(struct ieee80211_sub_i
 | 
			
		||||
 	struct mesh_path *mpath, *new_mpath;
 | 
			
		||||
 	struct mpath_node *node, *new_node;
 | 
			
		||||
 	struct hlist_head *bucket;
 | 
			
		||||
-	struct hlist_node *n;
 | 
			
		||||
 	int grow = 0;
 | 
			
		||||
 	int err = 0;
 | 
			
		||||
 	u32 hash_idx;
 | 
			
		||||
@@ -550,7 +546,7 @@ int mesh_path_add(struct ieee80211_sub_i
 | 
			
		||||
 	spin_lock(&tbl->hashwlock[hash_idx]);
 | 
			
		||||
 
 | 
			
		||||
 	err = -EEXIST;
 | 
			
		||||
-	hlist_for_each_entry(node, n, bucket, list) {
 | 
			
		||||
+	hlist_for_each_entry(node, bucket, list) {
 | 
			
		||||
 		mpath = node->mpath;
 | 
			
		||||
 		if (mpath->sdata == sdata &&
 | 
			
		||||
 		    ether_addr_equal(dst, mpath->dst))
 | 
			
		||||
@@ -640,7 +636,6 @@ int mpp_path_add(struct ieee80211_sub_if
 | 
			
		||||
 	struct mesh_path *mpath, *new_mpath;
 | 
			
		||||
 	struct mpath_node *node, *new_node;
 | 
			
		||||
 	struct hlist_head *bucket;
 | 
			
		||||
-	struct hlist_node *n;
 | 
			
		||||
 	int grow = 0;
 | 
			
		||||
 	int err = 0;
 | 
			
		||||
 	u32 hash_idx;
 | 
			
		||||
@@ -680,7 +675,7 @@ int mpp_path_add(struct ieee80211_sub_if
 | 
			
		||||
 	spin_lock(&tbl->hashwlock[hash_idx]);
 | 
			
		||||
 
 | 
			
		||||
 	err = -EEXIST;
 | 
			
		||||
-	hlist_for_each_entry(node, n, bucket, list) {
 | 
			
		||||
+	hlist_for_each_entry(node, bucket, list) {
 | 
			
		||||
 		mpath = node->mpath;
 | 
			
		||||
 		if (mpath->sdata == sdata &&
 | 
			
		||||
 		    ether_addr_equal(dst, mpath->dst))
 | 
			
		||||
@@ -725,14 +720,13 @@ void mesh_plink_broken(struct sta_info *
 | 
			
		||||
 	static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 | 
			
		||||
 	struct mesh_path *mpath;
 | 
			
		||||
 	struct mpath_node *node;
 | 
			
		||||
-	struct hlist_node *p;
 | 
			
		||||
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 | 
			
		||||
 	int i;
 | 
			
		||||
 	__le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE);
 | 
			
		||||
 
 | 
			
		||||
 	rcu_read_lock();
 | 
			
		||||
 	tbl = rcu_dereference(mesh_paths);
 | 
			
		||||
-	for_each_mesh_entry(tbl, p, node, i) {
 | 
			
		||||
+	for_each_mesh_entry(tbl, node, i) {
 | 
			
		||||
 		mpath = node->mpath;
 | 
			
		||||
 		if (rcu_dereference(mpath->next_hop) == sta &&
 | 
			
		||||
 		    mpath->flags & MESH_PATH_ACTIVE &&
 | 
			
		||||
@@ -792,13 +786,12 @@ void mesh_path_flush_by_nexthop(struct s
 | 
			
		||||
 	struct mesh_table *tbl;
 | 
			
		||||
 	struct mesh_path *mpath;
 | 
			
		||||
 	struct mpath_node *node;
 | 
			
		||||
-	struct hlist_node *p;
 | 
			
		||||
 	int i;
 | 
			
		||||
 
 | 
			
		||||
 	rcu_read_lock();
 | 
			
		||||
 	read_lock_bh(&pathtbl_resize_lock);
 | 
			
		||||
 	tbl = resize_dereference_mesh_paths();
 | 
			
		||||
-	for_each_mesh_entry(tbl, p, node, i) {
 | 
			
		||||
+	for_each_mesh_entry(tbl, node, i) {
 | 
			
		||||
 		mpath = node->mpath;
 | 
			
		||||
 		if (rcu_dereference(mpath->next_hop) == sta) {
 | 
			
		||||
 			spin_lock(&tbl->hashwlock[i]);
 | 
			
		||||
@@ -815,11 +808,9 @@ static void table_flush_by_iface(struct
 | 
			
		||||
 {
 | 
			
		||||
 	struct mesh_path *mpath;
 | 
			
		||||
 	struct mpath_node *node;
 | 
			
		||||
-	struct hlist_node *p;
 | 
			
		||||
 	int i;
 | 
			
		||||
 
 | 
			
		||||
-	WARN_ON(!rcu_read_lock_held());
 | 
			
		||||
-	for_each_mesh_entry(tbl, p, node, i) {
 | 
			
		||||
+	for_each_mesh_entry(tbl, node, i) {
 | 
			
		||||
 		mpath = node->mpath;
 | 
			
		||||
 		if (mpath->sdata != sdata)
 | 
			
		||||
 			continue;
 | 
			
		||||
@@ -865,7 +856,6 @@ int mesh_path_del(struct ieee80211_sub_i
 | 
			
		||||
 	struct mesh_path *mpath;
 | 
			
		||||
 	struct mpath_node *node;
 | 
			
		||||
 	struct hlist_head *bucket;
 | 
			
		||||
-	struct hlist_node *n;
 | 
			
		||||
 	int hash_idx;
 | 
			
		||||
 	int err = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -875,7 +865,7 @@ int mesh_path_del(struct ieee80211_sub_i
 | 
			
		||||
 	bucket = &tbl->hash_buckets[hash_idx];
 | 
			
		||||
 
 | 
			
		||||
 	spin_lock(&tbl->hashwlock[hash_idx]);
 | 
			
		||||
-	hlist_for_each_entry(node, n, bucket, list) {
 | 
			
		||||
+	hlist_for_each_entry(node, bucket, list) {
 | 
			
		||||
 		mpath = node->mpath;
 | 
			
		||||
 		if (mpath->sdata == sdata &&
 | 
			
		||||
 		    ether_addr_equal(addr, mpath->dst)) {
 | 
			
		||||
@@ -920,7 +910,6 @@ void mesh_path_tx_pending(struct mesh_pa
 | 
			
		||||
 int mesh_path_send_to_gates(struct mesh_path *mpath)
 | 
			
		||||
 {
 | 
			
		||||
 	struct ieee80211_sub_if_data *sdata = mpath->sdata;
 | 
			
		||||
-	struct hlist_node *n;
 | 
			
		||||
 	struct mesh_table *tbl;
 | 
			
		||||
 	struct mesh_path *from_mpath = mpath;
 | 
			
		||||
 	struct mpath_node *gate = NULL;
 | 
			
		||||
@@ -935,7 +924,7 @@ int mesh_path_send_to_gates(struct mesh_
 | 
			
		||||
 	if (!known_gates)
 | 
			
		||||
 		return -EHOSTUNREACH;
 | 
			
		||||
 
 | 
			
		||||
-	hlist_for_each_entry_rcu(gate, n, known_gates, list) {
 | 
			
		||||
+	hlist_for_each_entry_rcu(gate, known_gates, list) {
 | 
			
		||||
 		if (gate->mpath->sdata != sdata)
 | 
			
		||||
 			continue;
 | 
			
		||||
 
 | 
			
		||||
@@ -951,7 +940,7 @@ int mesh_path_send_to_gates(struct mesh_
 | 
			
		||||
 		}
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	hlist_for_each_entry_rcu(gate, n, known_gates, list)
 | 
			
		||||
+	hlist_for_each_entry_rcu(gate, known_gates, list)
 | 
			
		||||
 		if (gate->mpath->sdata == sdata) {
 | 
			
		||||
 			mpath_dbg(sdata, "Sending to %pM\n", gate->mpath->dst);
 | 
			
		||||
 			mesh_path_tx_pending(gate->mpath);
 | 
			
		||||
@@ -1096,12 +1085,11 @@ void mesh_path_expire(struct ieee80211_s
 | 
			
		||||
 	struct mesh_table *tbl;
 | 
			
		||||
 	struct mesh_path *mpath;
 | 
			
		||||
 	struct mpath_node *node;
 | 
			
		||||
-	struct hlist_node *p;
 | 
			
		||||
 	int i;
 | 
			
		||||
 
 | 
			
		||||
 	rcu_read_lock();
 | 
			
		||||
 	tbl = rcu_dereference(mesh_paths);
 | 
			
		||||
-	for_each_mesh_entry(tbl, p, node, i) {
 | 
			
		||||
+	for_each_mesh_entry(tbl, node, i) {
 | 
			
		||||
 		if (node->mpath->sdata != sdata)
 | 
			
		||||
 			continue;
 | 
			
		||||
 		mpath = node->mpath;
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/net/mac80211/main.c
 | 
			
		||||
+++ b/net/mac80211/main.c
 | 
			
		||||
@@ -313,7 +313,7 @@ void ieee80211_restart_hw(struct ieee802
 | 
			
		||||
@@ -300,7 +300,7 @@ void ieee80211_restart_hw(struct ieee802
 | 
			
		||||
 }
 | 
			
		||||
 EXPORT_SYMBOL(ieee80211_restart_hw);
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
 static int ieee80211_ifa_changed(struct notifier_block *nb,
 | 
			
		||||
 				 unsigned long data, void *arg)
 | 
			
		||||
 {
 | 
			
		||||
@@ -372,7 +372,7 @@ static int ieee80211_ifa_changed(struct
 | 
			
		||||
@@ -359,7 +359,7 @@ static int ieee80211_ifa_changed(struct 
 | 
			
		||||
 }
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
 static int ieee80211_ifa6_changed(struct notifier_block *nb,
 | 
			
		||||
 				  unsigned long data, void *arg)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1015,14 +1015,14 @@ int ieee80211_register_hw(struct ieee802
 | 
			
		||||
@@ -990,14 +990,14 @@ int ieee80211_register_hw(struct ieee802
 | 
			
		||||
 		goto fail_pm_qos;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@
 | 
			
		||||
 	local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
 | 
			
		||||
 	result = register_inet6addr_notifier(&local->ifa6_notifier);
 | 
			
		||||
 	if (result)
 | 
			
		||||
@@ -1034,13 +1034,13 @@ int ieee80211_register_hw(struct ieee802
 | 
			
		||||
@@ -1006,13 +1006,13 @@ int ieee80211_register_hw(struct ieee802
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,7 @@
 | 
			
		||||
  fail_ifa:
 | 
			
		||||
 	pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
 | 
			
		||||
 			       &local->network_latency_notifier);
 | 
			
		||||
@@ -1073,10 +1073,10 @@ void ieee80211_unregister_hw(struct ieee
 | 
			
		||||
@@ -1045,10 +1045,10 @@ void ieee80211_unregister_hw(struct ieee
 | 
			
		||||
 
 | 
			
		||||
 	pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
 | 
			
		||||
 			       &local->network_latency_notifier);
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/net/mac80211/cfg.c
 | 
			
		||||
+++ b/net/mac80211/cfg.c
 | 
			
		||||
@@ -2009,7 +2009,7 @@ static int ieee80211_scan(struct wiphy *
 | 
			
		||||
@@ -2078,7 +2078,7 @@ static int ieee80211_scan(struct wiphy *
 | 
			
		||||
 		 * the  frames sent while scanning on other channel will be
 | 
			
		||||
 		 * lost)
 | 
			
		||||
 		 */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/init.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
 | 
			
		||||
@@ -727,6 +727,7 @@ static const struct ieee80211_iface_limi
 | 
			
		||||
@@ -731,6 +731,7 @@ static const struct ieee80211_iface_limi
 | 
			
		||||
 #endif
 | 
			
		||||
 				 BIT(NL80211_IFTYPE_AP) |
 | 
			
		||||
 				 BIT(NL80211_IFTYPE_P2P_GO) },
 | 
			
		||||
+	{ .max = 1,	.types = BIT(NL80211_IFTYPE_ADHOC) },
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct ieee80211_iface_combination if_comb = {
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath5k/reset.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath5k/reset.c
 | 
			
		||||
@@ -1158,6 +1158,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
 | 
			
		||||
@@ -1156,6 +1156,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
 | 
			
		||||
 	tsf_lo = 0;
 | 
			
		||||
 	mode = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * Sanity check for fast flag
 | 
			
		||||
 	 * Fast channel change only available
 | 
			
		||||
@@ -1165,6 +1166,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
 | 
			
		||||
@@ -1163,6 +1164,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
 | 
			
		||||
 	 */
 | 
			
		||||
 	if (fast && (ah->ah_radio != AR5K_RF2413) &&
 | 
			
		||||
 	(ah->ah_radio != AR5K_RF5413))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
 | 
			
		||||
@@ -2003,6 +2003,53 @@ void ath9k_get_et_stats(struct ieee80211
 | 
			
		||||
@@ -2012,6 +2012,53 @@ void ath9k_get_et_stats(struct ieee80211
 | 
			
		||||
 	WARN_ON(i != ATH9K_SSTATS_LEN);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,7 @@
 | 
			
		||||
 int ath9k_init_debug(struct ath_hw *ah)
 | 
			
		||||
 {
 | 
			
		||||
 	struct ath_common *common = ath9k_hw_common(ah);
 | 
			
		||||
@@ -2020,6 +2067,8 @@ int ath9k_init_debug(struct ath_hw *ah)
 | 
			
		||||
@@ -2029,6 +2076,8 @@ int ath9k_init_debug(struct ath_hw *ah)
 | 
			
		||||
 
 | 
			
		||||
 	ath9k_dfs_init_debug(sc);
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/hw.h
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/hw.h
 | 
			
		||||
@@ -740,6 +740,7 @@ enum ath_cal_list {
 | 
			
		||||
@@ -739,6 +739,7 @@ enum ath_cal_list {
 | 
			
		||||
 #define AH_USE_EEPROM   0x1
 | 
			
		||||
 #define AH_UNPLUGGED    0x2 /* The card has been physically removed. */
 | 
			
		||||
 #define AH_FASTCC       0x4
 | 
			
		||||
@@ -81,7 +81,7 @@
 | 
			
		||||
 	struct ath_ops reg_ops;
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/init.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
 | 
			
		||||
@@ -587,6 +587,8 @@ static int ath9k_init_softc(u16 devid, s
 | 
			
		||||
@@ -591,6 +591,8 @@ static int ath9k_init_softc(u16 devid, s
 | 
			
		||||
 		ah->is_clk_25mhz = pdata->is_clk_25mhz;
 | 
			
		||||
 		ah->get_mac_revision = pdata->get_mac_revision;
 | 
			
		||||
 		ah->external_reset = pdata->external_reset;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/init.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
 | 
			
		||||
@@ -965,23 +965,23 @@ static int __init ath9k_init(void)
 | 
			
		||||
@@ -986,23 +986,23 @@ static int __init ath9k_init(void)
 | 
			
		||||
 		goto err_out;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
 | 
			
		||||
@@ -1946,8 +1946,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 | 
			
		||||
@@ -2001,8 +2001,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 | 
			
		||||
 		REG_WRITE(ah, AR_OBS, 8);
 | 
			
		||||
 
 | 
			
		||||
 	if (ah->config.rx_intr_mitigation) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
 | 
			
		||||
@@ -689,6 +689,7 @@ struct ath_softc {
 | 
			
		||||
@@ -691,6 +691,7 @@ struct ath_softc {
 | 
			
		||||
 	struct ieee80211_hw *hw;
 | 
			
		||||
 	struct device *dev;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 	struct survey_info *cur_survey;
 | 
			
		||||
 	struct survey_info survey[ATH9K_NUM_CHANNELS];
 | 
			
		||||
 
 | 
			
		||||
@@ -893,6 +894,7 @@ struct fft_sample_ht20 {
 | 
			
		||||
@@ -895,6 +896,7 @@ struct fft_sample_ht20 {
 | 
			
		||||
 	u8 data[SPECTRAL_HT20_NUM_BINS];
 | 
			
		||||
 } __packed;
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
 | 
			
		||||
@@ -2050,6 +2050,50 @@ static const struct file_operations fops
 | 
			
		||||
@@ -2059,6 +2059,50 @@ static const struct file_operations fops
 | 
			
		||||
 	.owner = THIS_MODULE
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,7 @@
 | 
			
		||||
 int ath9k_init_debug(struct ath_hw *ah)
 | 
			
		||||
 {
 | 
			
		||||
 	struct ath_common *common = ath9k_hw_common(ah);
 | 
			
		||||
@@ -2069,6 +2113,8 @@ int ath9k_init_debug(struct ath_hw *ah)
 | 
			
		||||
@@ -2078,6 +2122,8 @@ int ath9k_init_debug(struct ath_hw *ah)
 | 
			
		||||
 
 | 
			
		||||
 	debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
 | 
			
		||||
 			    &fops_eeprom);
 | 
			
		||||
@@ -80,7 +80,7 @@
 | 
			
		||||
 	debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
 | 
			
		||||
@@ -1136,7 +1136,7 @@ int ath9k_spectral_scan_config(struct ie
 | 
			
		||||
@@ -1140,7 +1140,7 @@ int ath9k_spectral_scan_config(struct ie
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -89,10 +89,10 @@
 | 
			
		||||
 {
 | 
			
		||||
 	struct ath_softc *sc = hw->priv;
 | 
			
		||||
 	struct ath_hw *ah = sc->sc_ah;
 | 
			
		||||
@@ -1190,9 +1190,11 @@ static int ath9k_config(struct ieee80211
 | 
			
		||||
 
 | 
			
		||||
 	if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
 | 
			
		||||
 		struct ieee80211_channel *curchan = hw->conf.channel;
 | 
			
		||||
@@ -1196,9 +1196,11 @@ static int ath9k_config(struct ieee80211
 | 
			
		||||
 		struct ieee80211_channel *curchan = hw->conf.chandef.chan;
 | 
			
		||||
 		enum nl80211_channel_type channel_type =
 | 
			
		||||
 			cfg80211_get_chandef_type(&conf->chandef);
 | 
			
		||||
+		struct ath9k_channel *hchan;
 | 
			
		||||
 		int pos = curchan->hw_value;
 | 
			
		||||
 		int old_pos = -1;
 | 
			
		||||
@@ -101,7 +101,7 @@
 | 
			
		||||
 
 | 
			
		||||
 		if (ah->curchan)
 | 
			
		||||
 			old_pos = ah->curchan - &ah->channels[0];
 | 
			
		||||
@@ -1235,7 +1237,23 @@ static int ath9k_config(struct ieee80211
 | 
			
		||||
@@ -1241,7 +1243,23 @@ static int ath9k_config(struct ieee80211
 | 
			
		||||
 			memset(&sc->survey[pos], 0, sizeof(struct survey_info));
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,16 @@
 | 
			
		||||
--- a/include/net/mac80211.h
 | 
			
		||||
+++ b/include/net/mac80211.h
 | 
			
		||||
@@ -1554,6 +1554,7 @@ struct ieee80211_hw {
 | 
			
		||||
@@ -1605,6 +1605,7 @@ struct ieee80211_hw {
 | 
			
		||||
 	u8 max_tx_aggregation_subframes;
 | 
			
		||||
 	u8 offchannel_tx_hw_queue;
 | 
			
		||||
 	u8 radiotap_mcs_details;
 | 
			
		||||
+	s8 cur_power_level;
 | 
			
		||||
 	u16 radiotap_vht_details;
 | 
			
		||||
 	netdev_features_t netdev_features;
 | 
			
		||||
 };
 | 
			
		||||
 	u8 uapsd_queues;
 | 
			
		||||
--- a/net/mac80211/cfg.c
 | 
			
		||||
+++ b/net/mac80211/cfg.c
 | 
			
		||||
@@ -2190,7 +2190,9 @@ static int ieee80211_get_tx_power(struct
 | 
			
		||||
@@ -2259,7 +2259,9 @@ static int ieee80211_get_tx_power(struct
 | 
			
		||||
 	struct ieee80211_local *local = wiphy_priv(wiphy);
 | 
			
		||||
 	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
 		*dbm = sdata->vif.bss_conf.txpower;
 | 
			
		||||
--- a/net/mac80211/main.c
 | 
			
		||||
+++ b/net/mac80211/main.c
 | 
			
		||||
@@ -166,6 +166,7 @@ static u32 ieee80211_hw_conf_chan(struct
 | 
			
		||||
@@ -167,6 +167,7 @@ static u32 ieee80211_hw_conf_chan(struct
 | 
			
		||||
 
 | 
			
		||||
 	if (local->hw.conf.power_level != power) {
 | 
			
		||||
 		changed |= IEEE80211_CONF_CHANGE_POWER;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
 | 
			
		||||
@@ -1260,6 +1260,8 @@ int ath9k_config(struct ieee80211_hw *hw
 | 
			
		||||
@@ -1266,6 +1266,8 @@ int ath9k_config(struct ieee80211_hw *hw
 | 
			
		||||
 			return -EINVAL;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
 		/*
 | 
			
		||||
 		 * The most recent snapshot of channel->noisefloor for the old
 | 
			
		||||
 		 * channel is only available after the hardware reset. Copy it to
 | 
			
		||||
@@ -1279,6 +1281,7 @@ int ath9k_config(struct ieee80211_hw *hw
 | 
			
		||||
@@ -1302,6 +1304,7 @@ int ath9k_config(struct ieee80211_hw *hw
 | 
			
		||||
 		sc->config.txpowlimit = 2 * conf->power_level;
 | 
			
		||||
 		ath9k_cmn_update_txpow(ah, sc->curtxpow,
 | 
			
		||||
 				       sc->config.txpowlimit, &sc->curtxpow);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,121 +1,3 @@
 | 
			
		||||
--- a/include/net/mac80211.h
 | 
			
		||||
+++ b/include/net/mac80211.h
 | 
			
		||||
@@ -839,6 +839,9 @@ enum mac80211_rx_flags {
 | 
			
		||||
  * @signal: signal strength when receiving this frame, either in dBm, in dB or
 | 
			
		||||
  *	unspecified depending on the hardware capabilities flags
 | 
			
		||||
  *	@IEEE80211_HW_SIGNAL_*
 | 
			
		||||
+ * @chains: bitmask of receive chains for which separate signal strength
 | 
			
		||||
+ *	values were filled.
 | 
			
		||||
+ * @chain_signal: per-chain signal strength, same format as @signal
 | 
			
		||||
  * @antenna: antenna used
 | 
			
		||||
  * @rate_idx: index of data rate into band's supported rates or MCS index if
 | 
			
		||||
  *	HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
 | 
			
		||||
@@ -870,6 +873,8 @@ struct ieee80211_rx_status {
 | 
			
		||||
 	u8 band;
 | 
			
		||||
 	u8 antenna;
 | 
			
		||||
 	s8 signal;
 | 
			
		||||
+	u8 chains;
 | 
			
		||||
+	s8 chain_signal[4];
 | 
			
		||||
 	u8 ampdu_delimiter_crc;
 | 
			
		||||
 	u8 vendor_radiotap_align;
 | 
			
		||||
 	u8 vendor_radiotap_oui[3];
 | 
			
		||||
--- a/net/mac80211/sta_info.h
 | 
			
		||||
+++ b/net/mac80211/sta_info.h
 | 
			
		||||
@@ -342,6 +342,11 @@ struct sta_info {
 | 
			
		||||
 	int last_signal;
 | 
			
		||||
 	struct ewma avg_signal;
 | 
			
		||||
 	int last_ack_signal;
 | 
			
		||||
+
 | 
			
		||||
+	u8 chains;
 | 
			
		||||
+	s8 chain_signal_last[4];
 | 
			
		||||
+	struct ewma chain_signal_avg[4];
 | 
			
		||||
+
 | 
			
		||||
 	/* Plus 1 for non-QoS frames */
 | 
			
		||||
 	__le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];
 | 
			
		||||
 
 | 
			
		||||
--- a/net/mac80211/rx.c
 | 
			
		||||
+++ b/net/mac80211/rx.c
 | 
			
		||||
@@ -1383,6 +1383,7 @@ ieee80211_rx_h_sta_process(struct ieee80
 | 
			
		||||
 	struct sk_buff *skb = rx->skb;
 | 
			
		||||
 	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 | 
			
		||||
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 | 
			
		||||
+	int i;
 | 
			
		||||
 
 | 
			
		||||
 	if (!sta)
 | 
			
		||||
 		return RX_CONTINUE;
 | 
			
		||||
@@ -1433,6 +1434,19 @@ ieee80211_rx_h_sta_process(struct ieee80
 | 
			
		||||
 		ewma_add(&sta->avg_signal, -status->signal);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	if (status->chains) {
 | 
			
		||||
+		sta->chains = status->chains;
 | 
			
		||||
+		for (i = 0; i < 4; i++) {
 | 
			
		||||
+			int signal = status->chain_signal[i];
 | 
			
		||||
+
 | 
			
		||||
+			if (!(status->chains & BIT(i)))
 | 
			
		||||
+				continue;
 | 
			
		||||
+
 | 
			
		||||
+			sta->chain_signal_last[i] = signal;
 | 
			
		||||
+			ewma_add(&sta->chain_signal_avg[i], -signal);
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * Change STA power saving mode only at the end of a frame
 | 
			
		||||
 	 * exchange sequence.
 | 
			
		||||
--- a/net/mac80211/sta_info.c
 | 
			
		||||
+++ b/net/mac80211/sta_info.c
 | 
			
		||||
@@ -353,6 +353,8 @@ struct sta_info *sta_info_alloc(struct i
 | 
			
		||||
 	do_posix_clock_monotonic_gettime(&uptime);
 | 
			
		||||
 	sta->last_connected = uptime.tv_sec;
 | 
			
		||||
 	ewma_init(&sta->avg_signal, 1024, 8);
 | 
			
		||||
+	for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
 | 
			
		||||
+		ewma_init(&sta->chain_signal_avg[i], 1024, 8);
 | 
			
		||||
 
 | 
			
		||||
 	if (sta_prepare_rate_control(local, sta, gfp)) {
 | 
			
		||||
 		kfree(sta);
 | 
			
		||||
--- a/include/net/cfg80211.h
 | 
			
		||||
+++ b/include/net/cfg80211.h
 | 
			
		||||
@@ -721,6 +721,8 @@ struct station_parameters {
 | 
			
		||||
  * @STATION_INFO_LOCAL_PM: @local_pm filled
 | 
			
		||||
  * @STATION_INFO_PEER_PM: @peer_pm filled
 | 
			
		||||
  * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled
 | 
			
		||||
+ * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled
 | 
			
		||||
+ * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled
 | 
			
		||||
  */
 | 
			
		||||
 enum station_info_flags {
 | 
			
		||||
 	STATION_INFO_INACTIVE_TIME	= 1<<0,
 | 
			
		||||
@@ -749,6 +751,8 @@ enum station_info_flags {
 | 
			
		||||
 	STATION_INFO_NONPEER_PM		= 1<<23,
 | 
			
		||||
 	STATION_INFO_RX_BYTES64		= 1<<24,
 | 
			
		||||
 	STATION_INFO_TX_BYTES64		= 1<<25,
 | 
			
		||||
+	STATION_INFO_CHAIN_SIGNAL	= 1<<26,
 | 
			
		||||
+	STATION_INFO_CHAIN_SIGNAL_AVG	= 1<<27,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 /**
 | 
			
		||||
@@ -842,6 +846,9 @@ struct sta_bss_parameters {
 | 
			
		||||
  *	For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
 | 
			
		||||
  * @signal_avg: Average signal strength, type depends on the wiphy's signal_type.
 | 
			
		||||
  *	For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
 | 
			
		||||
+ * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg
 | 
			
		||||
+ * @chain_signal: per-chain signal strength of last received packet in dBm
 | 
			
		||||
+ * @chain_signal_avg: per-chain signal strength average in dBm
 | 
			
		||||
  * @txrate: current unicast bitrate from this station
 | 
			
		||||
  * @rxrate: current unicast bitrate to this station
 | 
			
		||||
  * @rx_packets: packets received from this station
 | 
			
		||||
@@ -877,6 +884,11 @@ struct station_info {
 | 
			
		||||
 	u8 plink_state;
 | 
			
		||||
 	s8 signal;
 | 
			
		||||
 	s8 signal_avg;
 | 
			
		||||
+
 | 
			
		||||
+	u8 chains;
 | 
			
		||||
+	s8 chain_signal[4];
 | 
			
		||||
+	s8 chain_signal_avg[4];
 | 
			
		||||
+
 | 
			
		||||
 	struct rate_info txrate;
 | 
			
		||||
 	struct rate_info rxrate;
 | 
			
		||||
 	u32 rx_packets;
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/mac.h
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/mac.h
 | 
			
		||||
@@ -133,12 +133,8 @@ struct ath_rx_status {
 | 
			
		||||
@@ -135,15 +17,15 @@
 | 
			
		||||
 	u8 rs_num_delims;
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/recv.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/recv.c
 | 
			
		||||
@@ -937,6 +937,7 @@ static int ath9k_rx_skb_preprocess(struc
 | 
			
		||||
 				   bool *decrypt_error)
 | 
			
		||||
 {
 | 
			
		||||
 	struct ath_hw *ah = common->ah;
 | 
			
		||||
@@ -950,6 +950,7 @@ static int ath9k_rx_skb_preprocess(struc
 | 
			
		||||
 	struct ath_hw *ah = sc->sc_ah;
 | 
			
		||||
 	struct ath_common *common = ath9k_hw_common(ah);
 | 
			
		||||
 	bool discard_current = sc->rx.discard_next;
 | 
			
		||||
+	int i, j;
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * everything but the rate is checked here, the rate check is done
 | 
			
		||||
@@ -962,6 +963,20 @@ static int ath9k_rx_skb_preprocess(struc
 | 
			
		||||
 	sc->rx.discard_next = rx_stats->rs_more;
 | 
			
		||||
 	if (discard_current)
 | 
			
		||||
@@ -979,6 +980,21 @@ static int ath9k_rx_skb_preprocess(struc
 | 
			
		||||
 	if (rx_stats->rs_moreaggr)
 | 
			
		||||
 		rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
 | 
			
		||||
 
 | 
			
		||||
@@ -161,10 +43,11 @@
 | 
			
		||||
+		j++;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
 	sc->rx.discard_next = false;
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -1070,7 +1085,7 @@ static int ath_process_fft(struct ath_so
 | 
			
		||||
@@ -1088,7 +1104,7 @@ static int ath_process_fft(struct ath_so
 | 
			
		||||
 	fft_sample.tlv.length = __cpu_to_be16(length);
 | 
			
		||||
 
 | 
			
		||||
 	fft_sample.freq = __cpu_to_be16(ah->curchan->chan->center_freq);
 | 
			
		||||
@@ -236,7 +119,7 @@
 | 
			
		||||
 	if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
 | 
			
		||||
@@ -940,12 +940,12 @@ void ath_debug_stat_rx(struct ath_softc 
 | 
			
		||||
@@ -943,12 +943,12 @@ void ath_debug_stat_rx(struct ath_softc 
 | 
			
		||||
 #ifdef CONFIG_ATH9K_MAC_DEBUG
 | 
			
		||||
 	spin_lock(&sc->debug.samp_lock);
 | 
			
		||||
 	RX_SAMP_DBG(jiffies) = jiffies;
 | 
			
		||||
@@ -255,108 +138,6 @@
 | 
			
		||||
 	RX_SAMP_DBG(antenna) = rs->rs_antenna;
 | 
			
		||||
 	RX_SAMP_DBG(rssi) = rs->rs_rssi;
 | 
			
		||||
 	RX_SAMP_DBG(rate) = rs->rs_rate;
 | 
			
		||||
--- a/include/uapi/linux/nl80211.h
 | 
			
		||||
+++ b/include/uapi/linux/nl80211.h
 | 
			
		||||
@@ -1918,6 +1918,8 @@ enum nl80211_sta_bss_param {
 | 
			
		||||
  * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode
 | 
			
		||||
  * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards
 | 
			
		||||
  *	non-peer STA
 | 
			
		||||
+ * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
 | 
			
		||||
+ * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
 | 
			
		||||
  * @__NL80211_STA_INFO_AFTER_LAST: internal
 | 
			
		||||
  * @NL80211_STA_INFO_MAX: highest possible station info attribute
 | 
			
		||||
  */
 | 
			
		||||
@@ -1947,6 +1949,8 @@ enum nl80211_sta_info {
 | 
			
		||||
 	NL80211_STA_INFO_NONPEER_PM,
 | 
			
		||||
 	NL80211_STA_INFO_RX_BYTES64,
 | 
			
		||||
 	NL80211_STA_INFO_TX_BYTES64,
 | 
			
		||||
+	NL80211_STA_INFO_CHAIN_SIGNAL,
 | 
			
		||||
+	NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
 | 
			
		||||
 
 | 
			
		||||
 	/* keep last */
 | 
			
		||||
 	__NL80211_STA_INFO_AFTER_LAST,
 | 
			
		||||
--- a/net/wireless/nl80211.c
 | 
			
		||||
+++ b/net/wireless/nl80211.c
 | 
			
		||||
@@ -3082,6 +3082,32 @@ static bool nl80211_put_sta_rate(struct 
 | 
			
		||||
 	return true;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
 | 
			
		||||
+			       int id)
 | 
			
		||||
+{
 | 
			
		||||
+	void *attr;
 | 
			
		||||
+	int i = 0;
 | 
			
		||||
+
 | 
			
		||||
+	if (!mask)
 | 
			
		||||
+		return true;
 | 
			
		||||
+
 | 
			
		||||
+	attr = nla_nest_start(msg, id);
 | 
			
		||||
+	if (!attr)
 | 
			
		||||
+		return false;
 | 
			
		||||
+
 | 
			
		||||
+	for (i = 0; i < 4; i++) {
 | 
			
		||||
+		if (!(mask & BIT(i)))
 | 
			
		||||
+			continue;
 | 
			
		||||
+
 | 
			
		||||
+		if (nla_put_u8(msg, i, signal[i]))
 | 
			
		||||
+			return false;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	nla_nest_end(msg, attr);
 | 
			
		||||
+
 | 
			
		||||
+	return true;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
 | 
			
		||||
 				int flags,
 | 
			
		||||
 				struct cfg80211_registered_device *rdev,
 | 
			
		||||
@@ -3153,6 +3179,18 @@ static int nl80211_send_station(struct s
 | 
			
		||||
 	default:
 | 
			
		||||
 		break;
 | 
			
		||||
 	}
 | 
			
		||||
+	if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) {
 | 
			
		||||
+		if (!nl80211_put_signal(msg, sinfo->chains,
 | 
			
		||||
+					sinfo->chain_signal,
 | 
			
		||||
+					NL80211_STA_INFO_CHAIN_SIGNAL))
 | 
			
		||||
+			goto nla_put_failure;
 | 
			
		||||
+	}
 | 
			
		||||
+	if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) {
 | 
			
		||||
+		if (!nl80211_put_signal(msg, sinfo->chains,
 | 
			
		||||
+					sinfo->chain_signal_avg,
 | 
			
		||||
+					NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
 | 
			
		||||
+			goto nla_put_failure;
 | 
			
		||||
+	}
 | 
			
		||||
 	if (sinfo->filled & STATION_INFO_TX_BITRATE) {
 | 
			
		||||
 		if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
 | 
			
		||||
 					  NL80211_STA_INFO_TX_BITRATE))
 | 
			
		||||
--- a/net/mac80211/cfg.c
 | 
			
		||||
+++ b/net/mac80211/cfg.c
 | 
			
		||||
@@ -445,6 +445,7 @@ static void sta_set_sinfo(struct sta_inf
 | 
			
		||||
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 | 
			
		||||
 	struct ieee80211_local *local = sdata->local;
 | 
			
		||||
 	struct timespec uptime;
 | 
			
		||||
+	int i;
 | 
			
		||||
 
 | 
			
		||||
 	sinfo->generation = sdata->local->sta_generation;
 | 
			
		||||
 
 | 
			
		||||
@@ -484,6 +485,17 @@ static void sta_set_sinfo(struct sta_inf
 | 
			
		||||
 			sinfo->signal = (s8)sta->last_signal;
 | 
			
		||||
 		sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
 | 
			
		||||
 	}
 | 
			
		||||
+	if (sta->chains) {
 | 
			
		||||
+		sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
 | 
			
		||||
+				 STATION_INFO_CHAIN_SIGNAL_AVG;
 | 
			
		||||
+
 | 
			
		||||
+		sinfo->chains = sta->chains;
 | 
			
		||||
+		for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
 | 
			
		||||
+			sinfo->chain_signal[i] = sta->chain_signal_last[i];
 | 
			
		||||
+			sinfo->chain_signal_avg[i] =
 | 
			
		||||
+				(s8) -ewma_read(&sta->chain_signal_avg[i]);
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
 | 
			
		||||
 	sta_set_rate_info_rx(sta, &sinfo->rxrate);
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/dfs.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
 | 
			
		||||
@@ -164,8 +164,8 @@ void ath9k_dfs_process_phyerr(struct ath
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
--- a/include/net/mac80211.h
 | 
			
		||||
+++ b/include/net/mac80211.h
 | 
			
		||||
@@ -978,6 +978,7 @@ enum ieee80211_smps_mode {
 | 
			
		||||
@@ -988,6 +988,7 @@ enum ieee80211_smps_mode {
 | 
			
		||||
  *
 | 
			
		||||
  * @power_level: requested transmit power (in dBm), backward compatibility
 | 
			
		||||
  *	value only that is set to the minimum of all interfaces
 | 
			
		||||
+ * @max_antenna_gain: maximum antenna gain adjusted by user config (in dBi)
 | 
			
		||||
  *
 | 
			
		||||
  * @channel: the channel to tune to
 | 
			
		||||
  * @channel_type: the channel (HT) type
 | 
			
		||||
@@ -1000,6 +1001,7 @@ struct ieee80211_conf {
 | 
			
		||||
  * @chandef: the channel definition to tune to
 | 
			
		||||
  * @radar_enabled: whether radar detection is enabled
 | 
			
		||||
@@ -1009,6 +1010,7 @@ struct ieee80211_conf {
 | 
			
		||||
 	u32 flags;
 | 
			
		||||
 	int power_level, dynamic_ps_timeout;
 | 
			
		||||
 	int max_sleep_period;
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
 	u8 ps_dtim_period;
 | 
			
		||||
--- a/net/mac80211/ieee80211_i.h
 | 
			
		||||
+++ b/net/mac80211/ieee80211_i.h
 | 
			
		||||
@@ -1116,6 +1116,7 @@ struct ieee80211_local {
 | 
			
		||||
@@ -1110,6 +1110,7 @@ struct ieee80211_local {
 | 
			
		||||
 	int dynamic_ps_forced_timeout;
 | 
			
		||||
 
 | 
			
		||||
 	int user_power_level; /* in dBm, for all interfaces */
 | 
			
		||||
@@ -28,9 +28,9 @@
 | 
			
		||||
 
 | 
			
		||||
--- a/include/uapi/linux/nl80211.h
 | 
			
		||||
+++ b/include/uapi/linux/nl80211.h
 | 
			
		||||
@@ -1654,6 +1654,8 @@ enum nl80211_attrs {
 | 
			
		||||
 	NL80211_ATTR_STA_CAPABILITY,
 | 
			
		||||
 	NL80211_ATTR_STA_EXT_CAPABILITY,
 | 
			
		||||
@@ -1709,6 +1709,8 @@ enum nl80211_attrs {
 | 
			
		||||
 	NL80211_ATTR_MDID,
 | 
			
		||||
 	NL80211_ATTR_IE_RIC,
 | 
			
		||||
 
 | 
			
		||||
+	NL80211_ATTR_WIPHY_ANTENNA_GAIN,
 | 
			
		||||
+
 | 
			
		||||
@@ -39,15 +39,15 @@
 | 
			
		||||
 	__NL80211_ATTR_AFTER_LAST,
 | 
			
		||||
--- a/net/wireless/nl80211.c
 | 
			
		||||
+++ b/net/wireless/nl80211.c
 | 
			
		||||
@@ -370,6 +370,7 @@ static const struct nla_policy nl80211_p
 | 
			
		||||
 	[NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
 | 
			
		||||
 	[NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
 | 
			
		||||
 	[NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
 | 
			
		||||
@@ -378,6 +378,7 @@ static const struct nla_policy nl80211_p
 | 
			
		||||
 	[NL80211_ATTR_MDID] = { .type = NLA_U16 },
 | 
			
		||||
 	[NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
 | 
			
		||||
 				  .len = IEEE80211_MAX_DATA_LEN },
 | 
			
		||||
+	[NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 /* policy for the key attributes */
 | 
			
		||||
@@ -1706,6 +1707,22 @@ static int nl80211_set_wiphy(struct sk_b
 | 
			
		||||
@@ -1990,6 +1991,22 @@ static int nl80211_set_wiphy(struct sk_b
 | 
			
		||||
 			goto bad_res;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -72,7 +72,7 @@
 | 
			
		||||
 		u32 tx_ant, rx_ant;
 | 
			
		||||
--- a/net/mac80211/cfg.c
 | 
			
		||||
+++ b/net/mac80211/cfg.c
 | 
			
		||||
@@ -2212,6 +2212,19 @@ static int ieee80211_get_tx_power(struct
 | 
			
		||||
@@ -2269,6 +2269,19 @@ static int ieee80211_get_tx_power(struct
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -92,7 +92,7 @@
 | 
			
		||||
 static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
 | 
			
		||||
 				  const u8 *addr)
 | 
			
		||||
 {
 | 
			
		||||
@@ -3375,6 +3388,7 @@ struct cfg80211_ops mac80211_config_ops 
 | 
			
		||||
@@ -3459,6 +3472,7 @@ struct cfg80211_ops mac80211_config_ops 
 | 
			
		||||
 	.set_wiphy_params = ieee80211_set_wiphy_params,
 | 
			
		||||
 	.set_tx_power = ieee80211_set_tx_power,
 | 
			
		||||
 	.get_tx_power = ieee80211_get_tx_power,
 | 
			
		||||
@@ -102,7 +102,7 @@
 | 
			
		||||
 	CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
 | 
			
		||||
--- a/include/net/cfg80211.h
 | 
			
		||||
+++ b/include/net/cfg80211.h
 | 
			
		||||
@@ -1862,6 +1862,7 @@ struct cfg80211_gtk_rekey_data {
 | 
			
		||||
@@ -1921,6 +1921,7 @@ struct cfg80211_update_ft_ies_params {
 | 
			
		||||
  *	(as advertised by the nl80211 feature flag.)
 | 
			
		||||
  * @get_tx_power: store the current TX power into the dbm variable;
 | 
			
		||||
  *	return 0 if successful
 | 
			
		||||
@@ -110,7 +110,7 @@
 | 
			
		||||
  *
 | 
			
		||||
  * @set_wds_peer: set the WDS peer for a WDS interface
 | 
			
		||||
  *
 | 
			
		||||
@@ -2071,6 +2072,7 @@ struct cfg80211_ops {
 | 
			
		||||
@@ -2134,6 +2135,7 @@ struct cfg80211_ops {
 | 
			
		||||
 				enum nl80211_tx_power_setting type, int mbm);
 | 
			
		||||
 	int	(*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
 | 
			
		||||
 				int *dbm);
 | 
			
		||||
@@ -122,20 +122,20 @@
 | 
			
		||||
+++ b/net/mac80211/main.c
 | 
			
		||||
@@ -101,7 +101,7 @@ static u32 ieee80211_hw_conf_chan(struct
 | 
			
		||||
 	struct ieee80211_sub_if_data *sdata;
 | 
			
		||||
 	struct ieee80211_channel *chan;
 | 
			
		||||
 	struct cfg80211_chan_def chandef = {};
 | 
			
		||||
 	u32 changed = 0;
 | 
			
		||||
-	int power;
 | 
			
		||||
+	int power, ant_gain, max_power;
 | 
			
		||||
 	enum nl80211_channel_type channel_type;
 | 
			
		||||
 	u32 offchannel_flag;
 | 
			
		||||
 	bool scanning = false;
 | 
			
		||||
@@ -164,8 +164,21 @@ static u32 ieee80211_hw_conf_chan(struct
 | 
			
		||||
 
 | 
			
		||||
 	offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
 | 
			
		||||
@@ -165,8 +165,21 @@ static u32 ieee80211_hw_conf_chan(struct
 | 
			
		||||
 	}
 | 
			
		||||
 	rcu_read_unlock();
 | 
			
		||||
 
 | 
			
		||||
-	if (local->hw.conf.power_level != power) {
 | 
			
		||||
+	max_power = chan->max_reg_power;
 | 
			
		||||
+	ant_gain = chan->max_antenna_gain;
 | 
			
		||||
+	max_power = chandef.chan->max_reg_power;
 | 
			
		||||
+	ant_gain = chandef.chan->max_antenna_gain;
 | 
			
		||||
+	if (local->user_antenna_gain > 0) {
 | 
			
		||||
+		if (local->user_antenna_gain > ant_gain) {
 | 
			
		||||
+			max_power -= local->user_antenna_gain - ant_gain;
 | 
			
		||||
@@ -152,11 +152,11 @@
 | 
			
		||||
 		local->hw.cur_power_level = power;
 | 
			
		||||
 		local->hw.conf.power_level = power;
 | 
			
		||||
 	}
 | 
			
		||||
@@ -612,6 +625,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(
 | 
			
		||||
@@ -597,6 +610,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(
 | 
			
		||||
 					 IEEE80211_RADIOTAP_MCS_HAVE_BW;
 | 
			
		||||
 	local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
 | 
			
		||||
 					 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
 | 
			
		||||
+	local->user_antenna_gain = 0;
 | 
			
		||||
 	local->hw.uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
 | 
			
		||||
 	local->hw.uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
 | 
			
		||||
 	local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
 | 
			
		||||
 	wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
 | 
			
		||||
@@ -2817,7 +2817,7 @@ void ath9k_hw_apply_txpower(struct ath_h
 | 
			
		||||
@@ -2843,7 +2843,7 @@ void ath9k_hw_apply_txpower(struct ath_h
 | 
			
		||||
 	channel = chan->chan;
 | 
			
		||||
 	chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
 | 
			
		||||
 	new_pwr = min_t(int, chan_pwr, reg->power_limit);
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
 	if (ant_gain > max_gain)
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
 | 
			
		||||
@@ -1277,7 +1277,10 @@ int ath9k_config(struct ieee80211_hw *hw
 | 
			
		||||
@@ -1300,7 +1300,10 @@ int ath9k_config(struct ieee80211_hw *hw
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	if (changed & IEEE80211_CONF_CHANGE_POWER) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
 | 
			
		||||
@@ -551,6 +551,9 @@ struct ath9k_wow_pattern {
 | 
			
		||||
@@ -553,6 +553,9 @@ struct ath9k_wow_pattern {
 | 
			
		||||
 void ath_init_leds(struct ath_softc *sc);
 | 
			
		||||
 void ath_deinit_leds(struct ath_softc *sc);
 | 
			
		||||
 void ath_fill_led_pin(struct ath_softc *sc);
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
 #else
 | 
			
		||||
 static inline void ath_init_leds(struct ath_softc *sc)
 | 
			
		||||
 {
 | 
			
		||||
@@ -685,6 +688,13 @@ enum spectral_mode {
 | 
			
		||||
@@ -687,6 +690,13 @@ enum spectral_mode {
 | 
			
		||||
 	SPECTRAL_CHANSCAN,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
 struct ath_softc {
 | 
			
		||||
 	struct ieee80211_hw *hw;
 | 
			
		||||
 	struct device *dev;
 | 
			
		||||
@@ -726,9 +736,8 @@ struct ath_softc {
 | 
			
		||||
@@ -728,9 +738,8 @@ struct ath_softc {
 | 
			
		||||
 	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
 | 
			
		||||
 
 | 
			
		||||
 #ifdef CONFIG_MAC80211_LEDS
 | 
			
		||||
@@ -162,7 +162,7 @@
 | 
			
		||||
 void ath_fill_led_pin(struct ath_softc *sc)
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/init.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
 | 
			
		||||
@@ -870,7 +870,7 @@ int ath9k_init_device(u16 devid, struct 
 | 
			
		||||
@@ -891,7 +891,7 @@ int ath9k_init_device(u16 devid, struct 
 | 
			
		||||
 
 | 
			
		||||
 #ifdef CONFIG_MAC80211_LEDS
 | 
			
		||||
 	/* must be initialized before ieee80211_register_hw */
 | 
			
		||||
@@ -173,7 +173,7 @@
 | 
			
		||||
 #endif
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
 | 
			
		||||
@@ -1482,6 +1482,61 @@ static const struct file_operations fops
 | 
			
		||||
@@ -1489,6 +1489,61 @@ static const struct file_operations fops
 | 
			
		||||
 	.llseek = default_llseek,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@@ -235,7 +235,7 @@
 | 
			
		||||
 #ifdef CONFIG_ATH9K_MAC_DEBUG
 | 
			
		||||
 
 | 
			
		||||
 void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
 | 
			
		||||
@@ -2115,6 +2170,10 @@ int ath9k_init_debug(struct ath_hw *ah)
 | 
			
		||||
@@ -2124,6 +2179,10 @@ int ath9k_init_debug(struct ath_hw *ah)
 | 
			
		||||
 			    &fops_eeprom);
 | 
			
		||||
 	debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
 | 
			
		||||
 			    sc, &fops_chanbw);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,98 +0,0 @@
 | 
			
		||||
--- a/net/mac80211/ieee80211_i.h
 | 
			
		||||
+++ b/net/mac80211/ieee80211_i.h
 | 
			
		||||
@@ -739,6 +739,8 @@ struct ieee80211_sub_if_data {
 | 
			
		||||
 
 | 
			
		||||
 	/* bitmap of allowed (non-MCS) rate indexes for rate control */
 | 
			
		||||
 	u32 rc_rateidx_mask[IEEE80211_NUM_BANDS];
 | 
			
		||||
+
 | 
			
		||||
+	bool rc_has_mcs_mask[IEEE80211_NUM_BANDS];
 | 
			
		||||
 	u8  rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN];
 | 
			
		||||
 
 | 
			
		||||
 	union {
 | 
			
		||||
--- a/net/mac80211/cfg.c
 | 
			
		||||
+++ b/net/mac80211/cfg.c
 | 
			
		||||
@@ -2386,9 +2386,20 @@ static int ieee80211_set_bitrate_mask(st
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
 | 
			
		||||
+		struct ieee80211_supported_band *sband = wiphy->bands[i];
 | 
			
		||||
+
 | 
			
		||||
 		sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
 | 
			
		||||
 		memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs,
 | 
			
		||||
 		       sizeof(mask->control[i].mcs));
 | 
			
		||||
+
 | 
			
		||||
+		sdata->rc_has_mcs_mask[i] = false;
 | 
			
		||||
+		if (!sband)
 | 
			
		||||
+			continue;
 | 
			
		||||
+
 | 
			
		||||
+		if (memcmp(sdata->rc_rateidx_mcs_mask[i],
 | 
			
		||||
+			   sband->ht_cap.mcs.rx_mask,
 | 
			
		||||
+			   sizeof(sband->ht_cap.mcs.rx_mask)) != 0)
 | 
			
		||||
+			sdata->rc_has_mcs_mask[i] = true;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
--- a/include/net/mac80211.h
 | 
			
		||||
+++ b/include/net/mac80211.h
 | 
			
		||||
@@ -4091,7 +4091,7 @@ void ieee80211_send_bar(struct ieee80211
 | 
			
		||||
  *	(deprecated; this will be removed once drivers get updated to use
 | 
			
		||||
  *	rate_idx_mask)
 | 
			
		||||
  * @rate_idx_mask: user-requested (legacy) rate mask
 | 
			
		||||
- * @rate_idx_mcs_mask: user-requested MCS rate mask
 | 
			
		||||
+ * @rate_idx_mcs_mask: user-requested MCS rate mask (NULL if not in use)
 | 
			
		||||
  * @bss: whether this frame is sent out in AP or IBSS mode
 | 
			
		||||
  */
 | 
			
		||||
 struct ieee80211_tx_rate_control {
 | 
			
		||||
@@ -4103,7 +4103,7 @@ struct ieee80211_tx_rate_control {
 | 
			
		||||
 	bool rts, short_preamble;
 | 
			
		||||
 	u8 max_rate_idx;
 | 
			
		||||
 	u32 rate_idx_mask;
 | 
			
		||||
-	u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
 | 
			
		||||
+	u8 *rate_idx_mcs_mask;
 | 
			
		||||
 	bool bss;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
--- a/net/mac80211/tx.c
 | 
			
		||||
+++ b/net/mac80211/tx.c
 | 
			
		||||
@@ -641,9 +641,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
 | 
			
		||||
 		txrc.max_rate_idx = -1;
 | 
			
		||||
 	else
 | 
			
		||||
 		txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
 | 
			
		||||
-	memcpy(txrc.rate_idx_mcs_mask,
 | 
			
		||||
-	       tx->sdata->rc_rateidx_mcs_mask[info->band],
 | 
			
		||||
-	       sizeof(txrc.rate_idx_mcs_mask));
 | 
			
		||||
+
 | 
			
		||||
+	if (tx->sdata->rc_has_mcs_mask[info->band])
 | 
			
		||||
+		txrc.rate_idx_mcs_mask =
 | 
			
		||||
+			tx->sdata->rc_rateidx_mcs_mask[info->band];
 | 
			
		||||
+
 | 
			
		||||
 	txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
 | 
			
		||||
 		    tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
 | 
			
		||||
 		    tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
 | 
			
		||||
@@ -2511,8 +2513,6 @@ struct sk_buff *ieee80211_beacon_get_tim
 | 
			
		||||
 		txrc.max_rate_idx = -1;
 | 
			
		||||
 	else
 | 
			
		||||
 		txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
 | 
			
		||||
-	memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band],
 | 
			
		||||
-	       sizeof(txrc.rate_idx_mcs_mask));
 | 
			
		||||
 	txrc.bss = true;
 | 
			
		||||
 	rate_control_get_rate(sdata, NULL, &txrc);
 | 
			
		||||
 
 | 
			
		||||
--- a/net/mac80211/rate.c
 | 
			
		||||
+++ b/net/mac80211/rate.c
 | 
			
		||||
@@ -460,9 +460,12 @@ void rate_control_get_rate(struct ieee80
 | 
			
		||||
 	 * the common case.
 | 
			
		||||
 	 */
 | 
			
		||||
 	mask = sdata->rc_rateidx_mask[info->band];
 | 
			
		||||
-	memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band],
 | 
			
		||||
-	       sizeof(mcs_mask));
 | 
			
		||||
-	if (mask != (1 << txrc->sband->n_bitrates) - 1) {
 | 
			
		||||
+	if (mask != (1 << txrc->sband->n_bitrates) - 1 || txrc->rate_idx_mcs_mask) {
 | 
			
		||||
+		if (txrc->rate_idx_mcs_mask)
 | 
			
		||||
+			memcpy(mcs_mask, txrc->rate_idx_mcs_mask, sizeof(mcs_mask));
 | 
			
		||||
+		else
 | 
			
		||||
+			memset(mcs_mask, 0xff, sizeof(mcs_mask));
 | 
			
		||||
+
 | 
			
		||||
 		if (sta) {
 | 
			
		||||
 			/* Filter out rates that the STA does not support */
 | 
			
		||||
 			mask &= sta->sta.supp_rates[info->band];
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/mac.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/mac.c
 | 
			
		||||
@@ -689,7 +689,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw 
 | 
			
		||||
@@ -697,7 +697,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw 
 | 
			
		||||
 {
 | 
			
		||||
 #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
 | 
			
		||||
 	struct ath_common *common = ath9k_hw_common(ah);
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
 	int i;
 | 
			
		||||
 
 | 
			
		||||
 	/* Enable access to the DMA observation bus */
 | 
			
		||||
@@ -719,6 +719,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw 
 | 
			
		||||
@@ -727,6 +727,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw 
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	if (i == 0) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
 | 
			
		||||
@@ -2149,6 +2149,50 @@ static const struct file_operations fops
 | 
			
		||||
@@ -2158,6 +2158,50 @@ static const struct file_operations fops
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,7 @@
 | 
			
		||||
 int ath9k_init_debug(struct ath_hw *ah)
 | 
			
		||||
 {
 | 
			
		||||
 	struct ath_common *common = ath9k_hw_common(ah);
 | 
			
		||||
@@ -2174,6 +2218,8 @@ int ath9k_init_debug(struct ath_hw *ah)
 | 
			
		||||
@@ -2183,6 +2227,8 @@ int ath9k_init_debug(struct ath_hw *ah)
 | 
			
		||||
 	debugfs_create_file("gpio_led", S_IWUSR,
 | 
			
		||||
 			   sc->debug.debugfs_phy, sc, &fops_gpio_led);
 | 
			
		||||
 #endif
 | 
			
		||||
@@ -62,7 +62,7 @@
 | 
			
		||||
 	debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/hw.h
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/hw.h
 | 
			
		||||
@@ -500,6 +500,12 @@ enum {
 | 
			
		||||
@@ -499,6 +499,12 @@ enum {
 | 
			
		||||
 	ATH9K_RESET_COLD,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@
 | 
			
		||||
 struct ath9k_hw_version {
 | 
			
		||||
 	u32 magic;
 | 
			
		||||
 	u16 devid;
 | 
			
		||||
@@ -778,6 +784,8 @@ struct ath_hw {
 | 
			
		||||
@@ -777,6 +783,8 @@ struct ath_hw {
 | 
			
		||||
 	u32 rfkill_polarity;
 | 
			
		||||
 	u32 ah_flags;
 | 
			
		||||
 
 | 
			
		||||
@@ -84,7 +84,7 @@
 | 
			
		||||
 	bool reset_power_on;
 | 
			
		||||
 	bool htc_reset_init;
 | 
			
		||||
 
 | 
			
		||||
@@ -1041,6 +1049,7 @@ void ath9k_hw_set_sta_beacon_timers(stru
 | 
			
		||||
@@ -1027,6 +1035,7 @@ void ath9k_hw_set_sta_beacon_timers(stru
 | 
			
		||||
 bool ath9k_hw_check_alive(struct ath_hw *ah);
 | 
			
		||||
 
 | 
			
		||||
 bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
 | 
			
		||||
@@ -94,7 +94,7 @@
 | 
			
		||||
 void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause);
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
 | 
			
		||||
@@ -1747,6 +1747,20 @@ fail:
 | 
			
		||||
@@ -1845,6 +1845,20 @@ fail:
 | 
			
		||||
 	return -EINVAL;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -115,7 +115,7 @@
 | 
			
		||||
 int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 | 
			
		||||
 		   struct ath9k_hw_cal_data *caldata, bool fastcc)
 | 
			
		||||
 {
 | 
			
		||||
@@ -2023,6 +2037,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 | 
			
		||||
@@ -2046,6 +2060,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	ath9k_hw_apply_gpio_override(ah);
 | 
			
		||||
@@ -125,7 +125,7 @@
 | 
			
		||||
 		REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
 | 
			
		||||
@@ -459,6 +459,11 @@ irqreturn_t ath_isr(int irq, void *dev)
 | 
			
		||||
@@ -463,6 +463,11 @@ irqreturn_t ath_isr(int irq, void *dev)
 | 
			
		||||
 	ath9k_hw_getisr(ah, &status);	/* NB: clears ISR too */
 | 
			
		||||
 	status &= ah->imask;	/* discard unasked-for bits */
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
 | 
			
		||||
@@ -2413,17 +2413,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
 | 
			
		||||
@@ -2439,17 +2439,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
 | 
			
		||||
@@ -48,7 +48,7 @@
 | 
			
		||||
 	    AR_SREV_9285(ah) ||
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/hw.h
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/hw.h
 | 
			
		||||
@@ -961,6 +961,8 @@ struct ath_hw {
 | 
			
		||||
@@ -947,6 +947,8 @@ struct ath_hw {
 | 
			
		||||
 	bool is_clk_25mhz;
 | 
			
		||||
 	int (*get_mac_revision)(void);
 | 
			
		||||
 	int (*external_reset)(void);
 | 
			
		||||
@@ -59,7 +59,7 @@
 | 
			
		||||
 };
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath9k/init.c
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
 | 
			
		||||
@@ -587,6 +587,8 @@ static int ath9k_init_softc(u16 devid, s
 | 
			
		||||
@@ -591,6 +591,8 @@ static int ath9k_init_softc(u16 devid, s
 | 
			
		||||
 		ah->is_clk_25mhz = pdata->is_clk_25mhz;
 | 
			
		||||
 		ah->get_mac_revision = pdata->get_mac_revision;
 | 
			
		||||
 		ah->external_reset = pdata->external_reset;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
 | 
			
		||||
@@ -208,6 +208,7 @@ void rt2x00pci_uninitialize(struct rt2x0
 | 
			
		||||
 }
 | 
			
		||||
 EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize);
 | 
			
		||||
 
 | 
			
		||||
+#ifdef CONFIG_PCI
 | 
			
		||||
 /*
 | 
			
		||||
  * PCI driver handlers.
 | 
			
		||||
  */
 | 
			
		||||
@@ -392,6 +393,7 @@ int rt2x00pci_resume(struct pci_dev *pci
 | 
			
		||||
 }
 | 
			
		||||
 EXPORT_SYMBOL_GPL(rt2x00pci_resume);
 | 
			
		||||
 #endif /* CONFIG_PM */
 | 
			
		||||
+#endif /* CONFIG_PCI */
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
  * rt2x00pci module information.
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
 | 
			
		||||
@@ -273,8 +273,10 @@ int rt2x00pci_probe(struct pci_dev *pci_
 | 
			
		||||
@@ -96,8 +96,10 @@ int rt2x00pci_probe(struct pci_dev *pci_
 | 
			
		||||
 
 | 
			
		||||
 	pci_set_master(pci_dev);
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -101,7 +101,7 @@
 | 
			
		||||
+}
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2x00.h
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
 | 
			
		||||
@@ -559,6 +559,7 @@ struct rt2x00lib_ops {
 | 
			
		||||
@@ -560,6 +560,7 @@ struct rt2x00lib_ops {
 | 
			
		||||
 			       const u8 *data, const size_t len);
 | 
			
		||||
 	int (*load_firmware) (struct rt2x00_dev *rt2x00dev,
 | 
			
		||||
 			      const u8 *data, const size_t len);
 | 
			
		||||
@@ -109,7 +109,7 @@
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * Device initialization/deinitialization handlers.
 | 
			
		||||
@@ -719,6 +720,7 @@ enum rt2x00_capability_flags {
 | 
			
		||||
@@ -720,6 +721,7 @@ enum rt2x00_capability_flags {
 | 
			
		||||
 	REQUIRE_SW_SEQNO,
 | 
			
		||||
 	REQUIRE_HT_TX_DESC,
 | 
			
		||||
 	REQUIRE_PS_AUTOWAKE,
 | 
			
		||||
@@ -117,7 +117,7 @@
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * Capabilities
 | 
			
		||||
@@ -988,6 +990,11 @@ struct rt2x00_dev {
 | 
			
		||||
@@ -989,6 +991,11 @@ struct rt2x00_dev {
 | 
			
		||||
 	const struct firmware *fw;
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
@@ -156,15 +156,15 @@
 | 
			
		||||
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/Kconfig
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/Kconfig
 | 
			
		||||
@@ -60,6 +60,7 @@ config RT2800PCI
 | 
			
		||||
@@ -64,6 +64,7 @@ config RT2800PCI
 | 
			
		||||
 	select RT2X00_LIB_PCI if PCI
 | 
			
		||||
 	select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X
 | 
			
		||||
 	select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X
 | 
			
		||||
 	select RT2X00_LIB_FIRMWARE
 | 
			
		||||
+	select RT2X00_LIB_EEPROM
 | 
			
		||||
 	select RT2X00_LIB_CRYPTO
 | 
			
		||||
 	select CRC_CCITT
 | 
			
		||||
 	select EEPROM_93CX6
 | 
			
		||||
@@ -212,6 +213,9 @@ config RT2X00_LIB_FIRMWARE
 | 
			
		||||
@@ -221,6 +222,9 @@ config RT2X00_LIB_FIRMWARE
 | 
			
		||||
 config RT2X00_LIB_CRYPTO
 | 
			
		||||
 	boolean
 | 
			
		||||
 
 | 
			
		||||
@@ -183,14 +183,14 @@
 | 
			
		||||
+rt2x00lib-$(CONFIG_RT2X00_LIB_EEPROM)	+= rt2x00eeprom.o
 | 
			
		||||
 
 | 
			
		||||
 obj-$(CONFIG_RT2X00_LIB)		+= rt2x00lib.o
 | 
			
		||||
 obj-$(CONFIG_RT2X00_LIB_PCI)		+= rt2x00pci.o
 | 
			
		||||
 obj-$(CONFIG_RT2X00_LIB_MMIO)		+= rt2x00mmio.o
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
 | 
			
		||||
@@ -89,25 +89,11 @@ static void rt2800pci_mcu_status(struct 
 | 
			
		||||
 	rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
 | 
			
		||||
@@ -90,25 +90,11 @@ static void rt2800pci_mcu_status(struct 
 | 
			
		||||
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
 | 
			
		||||
-#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
 | 
			
		||||
 static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
 | 
			
		||||
 {
 | 
			
		||||
-	void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
 | 
			
		||||
@@ -209,11 +209,11 @@
 | 
			
		||||
-{
 | 
			
		||||
-	return -ENOMEM;
 | 
			
		||||
-}
 | 
			
		||||
-#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
 | 
			
		||||
-#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
 | 
			
		||||
 
 | 
			
		||||
 #ifdef CONFIG_PCI
 | 
			
		||||
 static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
 | 
			
		||||
@@ -331,6 +317,20 @@ static int rt2800pci_write_firmware(stru
 | 
			
		||||
@@ -332,6 +318,20 @@ static int rt2800pci_write_firmware(stru
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
@@ -234,13 +234,13 @@
 | 
			
		||||
  * Initialization functions.
 | 
			
		||||
  */
 | 
			
		||||
 static bool rt2800pci_get_entry_state(struct queue_entry *entry)
 | 
			
		||||
@@ -1046,6 +1046,7 @@ static const struct rt2x00lib_ops rt2800
 | 
			
		||||
@@ -1162,6 +1162,7 @@ static const struct rt2x00lib_ops rt2800
 | 
			
		||||
 	.get_firmware_name	= rt2800pci_get_firmware_name,
 | 
			
		||||
 	.check_firmware		= rt2800_check_firmware,
 | 
			
		||||
 	.load_firmware		= rt2800_load_firmware,
 | 
			
		||||
+	.get_eeprom_file_name   = rt2800pci_get_eeprom_file_name,
 | 
			
		||||
 	.initialize		= rt2x00pci_initialize,
 | 
			
		||||
 	.uninitialize		= rt2x00pci_uninitialize,
 | 
			
		||||
+	.get_eeprom_file_name	= rt2800pci_get_eeprom_file_name,
 | 
			
		||||
 	.initialize		= rt2x00mmio_initialize,
 | 
			
		||||
 	.uninitialize		= rt2x00mmio_uninitialize,
 | 
			
		||||
 	.get_entry_state	= rt2800pci_get_entry_state,
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/config.mk
 | 
			
		||||
+++ b/config.mk
 | 
			
		||||
@@ -640,6 +640,7 @@ export CONFIG_RT2X00=y
 | 
			
		||||
@@ -647,6 +647,7 @@ export CONFIG_RT2X00=y
 | 
			
		||||
 export CONFIG_RT2X00_LIB=m
 | 
			
		||||
 export CONFIG_RT2800_LIB=m
 | 
			
		||||
 export CONFIG_RT2X00_LIB_FIRMWARE=y
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,15 @@
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
 | 
			
		||||
@@ -89,7 +89,7 @@ static void rt2800pci_mcu_status(struct 
 | 
			
		||||
 	rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
 | 
			
		||||
@@ -90,7 +90,7 @@ static void rt2800pci_mcu_status(struct 
 | 
			
		||||
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
 | 
			
		||||
+static int rt2800pci_read_eeprom_file(struct rt2x00_dev *rt2x00dev)
 | 
			
		||||
 {
 | 
			
		||||
 	memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE);
 | 
			
		||||
 	return 0;
 | 
			
		||||
@@ -983,8 +983,9 @@ static int rt2800pci_read_eeprom(struct 
 | 
			
		||||
 	return -ENOMEM;
 | 
			
		||||
@@ -1099,8 +1099,9 @@ static int rt2800pci_read_eeprom(struct 
 | 
			
		||||
 {
 | 
			
		||||
 	int retval;
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
 	else
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
 | 
			
		||||
@@ -255,6 +255,7 @@ exit:
 | 
			
		||||
@@ -78,6 +78,7 @@ exit:
 | 
			
		||||
 int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
 | 
			
		||||
 {
 | 
			
		||||
 	struct ieee80211_hw *hw;
 | 
			
		||||
@@ -31,7 +31,7 @@
 | 
			
		||||
 	struct rt2x00_dev *rt2x00dev;
 | 
			
		||||
 	int retval;
 | 
			
		||||
 	u16 chip;
 | 
			
		||||
@@ -300,6 +301,12 @@ int rt2x00pci_probe(struct pci_dev *pci_
 | 
			
		||||
@@ -123,6 +124,12 @@ int rt2x00pci_probe(struct pci_dev *pci_
 | 
			
		||||
 	rt2x00dev->irq = pci_dev->irq;
 | 
			
		||||
 	rt2x00dev->name = pci_name(pci_dev);
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@
 | 
			
		||||
 		num_rates += 4;
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2x00.h
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
 | 
			
		||||
@@ -424,6 +424,7 @@ struct hw_mode_spec {
 | 
			
		||||
@@ -425,6 +425,7 @@ struct hw_mode_spec {
 | 
			
		||||
 	unsigned int supported_bands;
 | 
			
		||||
 #define SUPPORT_BAND_2GHZ	0x00000001
 | 
			
		||||
 #define SUPPORT_BAND_5GHZ	0x00000002
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@
 | 
			
		||||
 {
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2x00.h
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
 | 
			
		||||
@@ -1314,6 +1314,7 @@ static inline void rt2x00debug_dump_fram
 | 
			
		||||
@@ -1337,6 +1337,7 @@ static inline void rt2x00debug_dump_fram
 | 
			
		||||
  */
 | 
			
		||||
 u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev,
 | 
			
		||||
 			 struct ieee80211_vif *vif);
 | 
			
		||||
@@ -41,15 +41,15 @@
 | 
			
		||||
  * Interrupt context handlers.
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt61pci.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
 | 
			
		||||
@@ -2392,6 +2392,7 @@ static int rt61pci_validate_eeprom(struc
 | 
			
		||||
@@ -2396,6 +2396,7 @@ static int rt61pci_validate_eeprom(struc
 | 
			
		||||
 	u32 reg;
 | 
			
		||||
 	u16 word;
 | 
			
		||||
 	u8 *mac;
 | 
			
		||||
+	const u8 *pdata_mac;
 | 
			
		||||
 	s8 value;
 | 
			
		||||
 
 | 
			
		||||
 	rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®);
 | 
			
		||||
@@ -2412,7 +2413,11 @@ static int rt61pci_validate_eeprom(struc
 | 
			
		||||
 	rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR, ®);
 | 
			
		||||
@@ -2416,7 +2417,11 @@ static int rt61pci_validate_eeprom(struc
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * Start validation of the data that has been read.
 | 
			
		||||
 	 */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
 | 
			
		||||
@@ -2249,15 +2249,18 @@ static void rt2800_config_channel(struct
 | 
			
		||||
@@ -2622,15 +2622,18 @@ static void rt2800_config_channel(struct
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * Change BBP settings
 | 
			
		||||
 	 */
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 86, 0);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -3670,6 +3673,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4203,6 +4206,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 120, 0x50);
 | 
			
		||||
 
 | 
			
		||||
 	if (rt2x00_rt(rt2x00dev, RT3290) ||
 | 
			
		||||
@@ -30,7 +30,7 @@
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392))
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 128, 0x12);
 | 
			
		||||
@@ -3976,6 +3980,12 @@ static void rt2800_init_rfcsr_3290(struc
 | 
			
		||||
@@ -4507,6 +4511,12 @@ static void rt2800_init_rfcsr_3290(struc
 | 
			
		||||
 
 | 
			
		||||
 static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
 | 
			
		||||
 {
 | 
			
		||||
@@ -43,7 +43,7 @@
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 1, 0x23);
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
 | 
			
		||||
@@ -4009,15 +4019,30 @@ static void rt2800_init_rfcsr_3352(struc
 | 
			
		||||
@@ -4540,15 +4550,30 @@ static void rt2800_init_rfcsr_3352(struc
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
 | 
			
		||||
@@ -77,7 +77,7 @@
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
 | 
			
		||||
@@ -4025,15 +4050,20 @@ static void rt2800_init_rfcsr_3352(struc
 | 
			
		||||
@@ -4556,15 +4581,20 @@ static void rt2800_init_rfcsr_3352(struc
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
 | 
			
		||||
@@ -107,7 +107,7 @@
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
 | 
			
		||||
@@ -4949,7 +4979,8 @@ static int rt2800_init_eeprom(struct rt2
 | 
			
		||||
@@ -5534,7 +5564,8 @@ static int rt2800_init_eeprom(struct rt2
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * Detect if this device has Bluetooth co-existence.
 | 
			
		||||
 	 */
 | 
			
		||||
@@ -117,7 +117,7 @@
 | 
			
		||||
 		__set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
@@ -4978,6 +5009,22 @@ static int rt2800_init_eeprom(struct rt2
 | 
			
		||||
@@ -5563,6 +5594,22 @@ static int rt2800_init_eeprom(struct rt2
 | 
			
		||||
 					EIRP_MAX_TX_POWER_LIMIT)
 | 
			
		||||
 		__set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
 | 
			
		||||
 
 | 
			
		||||
@@ -142,7 +142,7 @@
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2800.h
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2800.h
 | 
			
		||||
@@ -2117,6 +2117,12 @@ struct mac_iveiv_entry {
 | 
			
		||||
@@ -2153,6 +2153,12 @@ struct mac_iveiv_entry {
 | 
			
		||||
 #define RFCSR31_RX_CALIB		FIELD8(0x7f)
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
@@ -155,7 +155,7 @@
 | 
			
		||||
  * RFCSR 38:
 | 
			
		||||
  */
 | 
			
		||||
 #define RFCSR38_RX_LO1_EN		FIELD8(0x20)
 | 
			
		||||
@@ -2127,6 +2133,18 @@ struct mac_iveiv_entry {
 | 
			
		||||
@@ -2163,6 +2169,18 @@ struct mac_iveiv_entry {
 | 
			
		||||
 #define RFCSR39_RX_LO2_EN		FIELD8(0x80)
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
@@ -174,16 +174,16 @@
 | 
			
		||||
  * RFCSR 49:
 | 
			
		||||
  */
 | 
			
		||||
 #define RFCSR49_TX			FIELD8(0x3f)
 | 
			
		||||
@@ -2135,6 +2153,8 @@ struct mac_iveiv_entry {
 | 
			
		||||
@@ -2172,6 +2190,8 @@ struct mac_iveiv_entry {
 | 
			
		||||
  * RFCSR 50:
 | 
			
		||||
  */
 | 
			
		||||
 #define RFCSR50_TX			FIELD8(0x3f)
 | 
			
		||||
+#define RFCSR50_TX0_EXT_PA		FIELD8(0x02)
 | 
			
		||||
+#define RFCSR50_TX1_EXT_PA		FIELD8(0x10)
 | 
			
		||||
 #define RFCSR50_EP			FIELD8(0xc0)
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
  * RF registers
 | 
			
		||||
@@ -2222,6 +2242,8 @@ struct mac_iveiv_entry {
 | 
			
		||||
@@ -2260,6 +2280,8 @@ struct mac_iveiv_entry {
 | 
			
		||||
  * INTERNAL_TX_ALC: 0: disable, 1: enable
 | 
			
		||||
  * BT_COEXIST: 0: disable, 1: enable
 | 
			
		||||
  * DAC_TEST: 0: disable, 1: enable
 | 
			
		||||
@@ -192,7 +192,7 @@
 | 
			
		||||
  */
 | 
			
		||||
 #define	EEPROM_NIC_CONF1		0x001b
 | 
			
		||||
 #define EEPROM_NIC_CONF1_HW_RADIO		FIELD16(0x0001)
 | 
			
		||||
@@ -2239,6 +2261,8 @@ struct mac_iveiv_entry {
 | 
			
		||||
@@ -2277,6 +2299,8 @@ struct mac_iveiv_entry {
 | 
			
		||||
 #define EEPROM_NIC_CONF1_INTERNAL_TX_ALC		FIELD16(0x2000)
 | 
			
		||||
 #define EEPROM_NIC_CONF1_BT_COEXIST		FIELD16(0x4000)
 | 
			
		||||
 #define EEPROM_NIC_CONF1_DAC_TEST		FIELD16(0x8000)
 | 
			
		||||
@@ -203,7 +203,7 @@
 | 
			
		||||
  * EEPROM frequency
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2x00.h
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
 | 
			
		||||
@@ -740,6 +740,8 @@ enum rt2x00_capability_flags {
 | 
			
		||||
@@ -741,6 +741,8 @@ enum rt2x00_capability_flags {
 | 
			
		||||
 	CAPABILITY_DOUBLE_ANTENNA,
 | 
			
		||||
 	CAPABILITY_BT_COEXIST,
 | 
			
		||||
 	CAPABILITY_VCO_RECALIBRATION,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
 | 
			
		||||
@@ -5169,6 +5169,27 @@ static const struct rf_channel rf_vals_3
 | 
			
		||||
 	{173, 0x61, 0, 9},
 | 
			
		||||
@@ -5886,6 +5886,27 @@ static const struct rf_channel rf_vals_5
 | 
			
		||||
 	{196, 83, 0, 12, 1},
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+/*
 | 
			
		||||
@@ -28,7 +28,7 @@
 | 
			
		||||
 static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 | 
			
		||||
 {
 | 
			
		||||
 	struct hw_mode_spec *spec = &rt2x00dev->spec;
 | 
			
		||||
@@ -5246,7 +5267,6 @@ static int rt2800_probe_hw_mode(struct r
 | 
			
		||||
@@ -5964,7 +5985,6 @@ static int rt2800_probe_hw_mode(struct r
 | 
			
		||||
 		   rt2x00_rf(rt2x00dev, RF3022) ||
 | 
			
		||||
 		   rt2x00_rf(rt2x00dev, RF3290) ||
 | 
			
		||||
 		   rt2x00_rf(rt2x00dev, RF3320) ||
 | 
			
		||||
@@ -36,7 +36,7 @@
 | 
			
		||||
 		   rt2x00_rf(rt2x00dev, RF5360) ||
 | 
			
		||||
 		   rt2x00_rf(rt2x00dev, RF5370) ||
 | 
			
		||||
 		   rt2x00_rf(rt2x00dev, RF5372) ||
 | 
			
		||||
@@ -5254,6 +5274,12 @@ static int rt2800_probe_hw_mode(struct r
 | 
			
		||||
@@ -5972,6 +5992,12 @@ static int rt2800_probe_hw_mode(struct r
 | 
			
		||||
 		   rt2x00_rf(rt2x00dev, RF5392)) {
 | 
			
		||||
 		spec->num_channels = 14;
 | 
			
		||||
 		spec->channels = rf_vals_3x;
 | 
			
		||||
@@ -49,7 +49,7 @@
 | 
			
		||||
 	} else if (rt2x00_rf(rt2x00dev, RF3052)) {
 | 
			
		||||
 		spec->supported_bands |= SUPPORT_BAND_5GHZ;
 | 
			
		||||
 		spec->num_channels = ARRAY_SIZE(rf_vals_3x);
 | 
			
		||||
@@ -5347,6 +5373,19 @@ static int rt2800_probe_hw_mode(struct r
 | 
			
		||||
@@ -6120,6 +6146,19 @@ static int rt2800_probe_rt(struct rt2x00
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,7 @@
 | 
			
		||||
 int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
 | 
			
		||||
 {
 | 
			
		||||
 	int retval;
 | 
			
		||||
@@ -5372,6 +5411,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
 | 
			
		||||
@@ -6149,6 +6188,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
 | 
			
		||||
 	rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
@@ -87,7 +87,7 @@
 | 
			
		||||
 	retval = rt2800_probe_hw_mode(rt2x00dev);
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2x00.h
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
 | 
			
		||||
@@ -419,6 +419,7 @@ static inline struct rt2x00_intf* vif_to
 | 
			
		||||
@@ -420,6 +420,7 @@ static inline struct rt2x00_intf* vif_to
 | 
			
		||||
  * @channels: Device/chipset specific channel values (See &struct rf_channel).
 | 
			
		||||
  * @channels_info: Additional information for channels (See &struct channel_info).
 | 
			
		||||
  * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap).
 | 
			
		||||
@@ -95,7 +95,7 @@
 | 
			
		||||
  */
 | 
			
		||||
 struct hw_mode_spec {
 | 
			
		||||
 	unsigned int supported_bands;
 | 
			
		||||
@@ -435,6 +436,7 @@ struct hw_mode_spec {
 | 
			
		||||
@@ -436,6 +437,7 @@ struct hw_mode_spec {
 | 
			
		||||
 	const struct channel_info *channels_info;
 | 
			
		||||
 
 | 
			
		||||
 	struct ieee80211_sta_ht_cap ht;
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
 | 
			
		||||
@@ -1185,11 +1185,18 @@ static int rt2800soc_probe(struct platfo
 | 
			
		||||
@@ -1301,11 +1301,18 @@ static int rt2800soc_probe(struct platfo
 | 
			
		||||
 	return rt2x00soc_probe(pdev, &rt2800pci_ops);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -1,47 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
 | 
			
		||||
@@ -1179,7 +1179,7 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_devic
 | 
			
		||||
 #endif /* CONFIG_PCI */
 | 
			
		||||
 MODULE_LICENSE("GPL");
 | 
			
		||||
 
 | 
			
		||||
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
 | 
			
		||||
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
 | 
			
		||||
 static int rt2800soc_probe(struct platform_device *pdev)
 | 
			
		||||
 {
 | 
			
		||||
 	return rt2x00soc_probe(pdev, &rt2800pci_ops);
 | 
			
		||||
@@ -1203,7 +1203,7 @@ static struct platform_driver rt2800soc_
 | 
			
		||||
 	.suspend	= rt2x00soc_suspend,
 | 
			
		||||
 	.resume		= rt2x00soc_resume,
 | 
			
		||||
 };
 | 
			
		||||
-#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
 | 
			
		||||
+#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
 | 
			
		||||
 
 | 
			
		||||
 #ifdef CONFIG_PCI
 | 
			
		||||
 static int rt2800pci_probe(struct pci_dev *pci_dev,
 | 
			
		||||
@@ -1226,7 +1226,7 @@ static int __init rt2800pci_init(void)
 | 
			
		||||
 {
 | 
			
		||||
 	int ret = 0;
 | 
			
		||||
 
 | 
			
		||||
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
 | 
			
		||||
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
 | 
			
		||||
 	ret = platform_driver_register(&rt2800soc_driver);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
@@ -1234,7 +1234,7 @@ static int __init rt2800pci_init(void)
 | 
			
		||||
 #ifdef CONFIG_PCI
 | 
			
		||||
 	ret = pci_register_driver(&rt2800pci_driver);
 | 
			
		||||
 	if (ret) {
 | 
			
		||||
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
 | 
			
		||||
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
 | 
			
		||||
 		platform_driver_unregister(&rt2800soc_driver);
 | 
			
		||||
 #endif
 | 
			
		||||
 		return ret;
 | 
			
		||||
@@ -1249,7 +1249,7 @@ static void __exit rt2800pci_exit(void)
 | 
			
		||||
 #ifdef CONFIG_PCI
 | 
			
		||||
 	pci_unregister_driver(&rt2800pci_driver);
 | 
			
		||||
 #endif
 | 
			
		||||
-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
 | 
			
		||||
+#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
 | 
			
		||||
 	platform_driver_unregister(&rt2800soc_driver);
 | 
			
		||||
 #endif
 | 
			
		||||
 }
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
 | 
			
		||||
@@ -322,11 +322,17 @@ static int rt2800pci_write_firmware(stru
 | 
			
		||||
@@ -323,11 +323,17 @@ static int rt2800pci_write_firmware(stru
 | 
			
		||||
 static char *rt2800pci_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
 | 
			
		||||
 {
 | 
			
		||||
 	struct rt2x00_platform_data *pdata;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 
 | 
			
		||||
 #include "rt2x00.h"
 | 
			
		||||
 #include "rt2800lib.h"
 | 
			
		||||
@@ -5375,13 +5376,14 @@ static int rt2800_probe_hw_mode(struct r
 | 
			
		||||
@@ -6148,13 +6149,14 @@ static int rt2800_probe_rt(struct rt2x00
 | 
			
		||||
 
 | 
			
		||||
 int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev)
 | 
			
		||||
 {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2800.h
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2800.h
 | 
			
		||||
@@ -69,6 +69,7 @@
 | 
			
		||||
 #define RF3322				0x000c
 | 
			
		||||
@@ -71,6 +71,7 @@
 | 
			
		||||
 #define RF3053				0x000d
 | 
			
		||||
 #define RF5592				0x000f
 | 
			
		||||
 #define RF3290				0x3290
 | 
			
		||||
+#define RF5350				0x5350
 | 
			
		||||
 #define RF5360				0x5360
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
 #define RF5372				0x5372
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
 | 
			
		||||
@@ -2138,6 +2138,15 @@ static void rt2800_config_channel_rf53xx
 | 
			
		||||
@@ -2132,6 +2132,15 @@ static void rt2800_config_channel_rf53xx
 | 
			
		||||
 	if (rf->channel <= 14) {
 | 
			
		||||
 		int idx = rf->channel-1;
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@
 | 
			
		||||
 		if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
 | 
			
		||||
 			if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
 | 
			
		||||
 				/* r55/r59 value array of channel 1~14 */
 | 
			
		||||
@@ -2219,6 +2228,7 @@ static void rt2800_config_channel(struct
 | 
			
		||||
@@ -2589,6 +2598,7 @@ static void rt2800_config_channel(struct
 | 
			
		||||
 	case RF3322:
 | 
			
		||||
 		rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
 | 
			
		||||
 		break;
 | 
			
		||||
@@ -34,7 +34,7 @@
 | 
			
		||||
 	case RF5360:
 | 
			
		||||
 	case RF5370:
 | 
			
		||||
 	case RF5372:
 | 
			
		||||
@@ -2232,6 +2242,7 @@ static void rt2800_config_channel(struct
 | 
			
		||||
@@ -2605,6 +2615,7 @@ static void rt2800_config_channel(struct
 | 
			
		||||
 
 | 
			
		||||
 	if (rt2x00_rf(rt2x00dev, RF3290) ||
 | 
			
		||||
 	    rt2x00_rf(rt2x00dev, RF3322) ||
 | 
			
		||||
@@ -42,7 +42,7 @@
 | 
			
		||||
 	    rt2x00_rf(rt2x00dev, RF5360) ||
 | 
			
		||||
 	    rt2x00_rf(rt2x00dev, RF5370) ||
 | 
			
		||||
 	    rt2x00_rf(rt2x00dev, RF5372) ||
 | 
			
		||||
@@ -2362,7 +2373,8 @@ static void rt2800_config_channel(struct
 | 
			
		||||
@@ -2746,7 +2757,8 @@ static void rt2800_config_channel(struct
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * Clear update flag
 | 
			
		||||
 	 */
 | 
			
		||||
@@ -52,7 +52,7 @@
 | 
			
		||||
 		rt2800_bbp_read(rt2x00dev, 49, &bbp);
 | 
			
		||||
 		rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 49, bbp);
 | 
			
		||||
@@ -2801,6 +2813,7 @@ void rt2800_vco_calibration(struct rt2x0
 | 
			
		||||
@@ -3185,6 +3197,7 @@ void rt2800_vco_calibration(struct rt2x0
 | 
			
		||||
 		rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
 | 
			
		||||
 		break;
 | 
			
		||||
 	case RF3290:
 | 
			
		||||
@@ -60,17 +60,17 @@
 | 
			
		||||
 	case RF5360:
 | 
			
		||||
 	case RF5370:
 | 
			
		||||
 	case RF5372:
 | 
			
		||||
@@ -3125,7 +3138,8 @@ static int rt2800_init_registers(struct 
 | 
			
		||||
@@ -3524,7 +3537,8 @@ static int rt2800_init_registers(struct 
 | 
			
		||||
 	} else if (rt2x00_rt(rt2x00dev, RT3572)) {
 | 
			
		||||
 		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
 | 
			
		||||
 		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
 | 
			
		||||
-	} else if (rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
+	} else if (rt2x00_rt(rt2x00dev, RT5350) ||
 | 
			
		||||
+		   rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 		   rt2x00_rt(rt2x00dev, RT5392)) {
 | 
			
		||||
 		   rt2x00_rt(rt2x00dev, RT5392) ||
 | 
			
		||||
 		   rt2x00_rt(rt2x00dev, RT5592)) {
 | 
			
		||||
 		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
 | 
			
		||||
 		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
 | 
			
		||||
@@ -3507,6 +3521,10 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4043,6 +4057,10 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 4, 0x50);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -80,8 +80,8 @@
 | 
			
		||||
+
 | 
			
		||||
 	if (rt2x00_rt(rt2x00dev, RT3290) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392)) {
 | 
			
		||||
@@ -3519,11 +3537,13 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392))
 | 
			
		||||
@@ -4052,11 +4070,13 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT3290) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT3352) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT3572) ||
 | 
			
		||||
@@ -96,7 +96,7 @@
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 47, 0x48);
 | 
			
		||||
 
 | 
			
		||||
 	rt2800_bbp_write(rt2x00dev, 65, 0x2c);
 | 
			
		||||
@@ -3531,6 +3551,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4064,6 +4084,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 
 | 
			
		||||
 	if (rt2x00_rt(rt2x00dev, RT3290) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT3352) ||
 | 
			
		||||
@@ -104,7 +104,7 @@
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392))
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 68, 0x0b);
 | 
			
		||||
@@ -3540,6 +3561,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4073,6 +4094,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 73, 0x12);
 | 
			
		||||
 	} else if (rt2x00_rt(rt2x00dev, RT3290) ||
 | 
			
		||||
 		   rt2x00_rt(rt2x00dev, RT3352) ||
 | 
			
		||||
@@ -112,7 +112,7 @@
 | 
			
		||||
 		   rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 		   rt2x00_rt(rt2x00dev, RT5392)) {
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 69, 0x12);
 | 
			
		||||
@@ -3576,7 +3598,8 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4109,7 +4131,8 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 79, 0x18);
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 80, 0x09);
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 81, 0x33);
 | 
			
		||||
@@ -122,7 +122,7 @@
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 78, 0x0e);
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 80, 0x08);
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 81, 0x37);
 | 
			
		||||
@@ -3586,6 +3609,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4119,6 +4142,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 
 | 
			
		||||
 	rt2800_bbp_write(rt2x00dev, 82, 0x62);
 | 
			
		||||
 	if (rt2x00_rt(rt2x00dev, RT3290) ||
 | 
			
		||||
@@ -130,7 +130,7 @@
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392))
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 83, 0x7a);
 | 
			
		||||
@@ -3595,6 +3619,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4128,6 +4152,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 	if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 84, 0x19);
 | 
			
		||||
 	else if (rt2x00_rt(rt2x00dev, RT3290) ||
 | 
			
		||||
@@ -138,7 +138,7 @@
 | 
			
		||||
 		 rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 		 rt2x00_rt(rt2x00dev, RT5392))
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 84, 0x9a);
 | 
			
		||||
@@ -3603,6 +3628,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4136,6 +4161,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 
 | 
			
		||||
 	if (rt2x00_rt(rt2x00dev, RT3290) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT3352) ||
 | 
			
		||||
@@ -146,7 +146,7 @@
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392))
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 86, 0x38);
 | 
			
		||||
@@ -3617,6 +3643,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4150,6 +4176,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 
 | 
			
		||||
 	if (rt2x00_rt(rt2x00dev, RT3290) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT3352) ||
 | 
			
		||||
@@ -154,7 +154,7 @@
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392))
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 92, 0x02);
 | 
			
		||||
@@ -3635,6 +3662,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4168,6 +4195,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT3290) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT3352) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT3572) ||
 | 
			
		||||
@@ -162,7 +162,7 @@
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392) ||
 | 
			
		||||
 	    rt2800_is_305x_soc(rt2x00dev))
 | 
			
		||||
@@ -3644,6 +3672,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4177,6 +4205,7 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 
 | 
			
		||||
 	if (rt2x00_rt(rt2x00dev, RT3290) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT3352) ||
 | 
			
		||||
@@ -170,7 +170,7 @@
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392))
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 104, 0x92);
 | 
			
		||||
@@ -3654,13 +3683,15 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4187,13 +4216,15 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 105, 0x1c);
 | 
			
		||||
 	else if (rt2x00_rt(rt2x00dev, RT3352))
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 105, 0x34);
 | 
			
		||||
@@ -187,7 +187,7 @@
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5390))
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 106, 0x03);
 | 
			
		||||
 	else if (rt2x00_rt(rt2x00dev, RT3352))
 | 
			
		||||
@@ -3670,11 +3701,13 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4203,11 +4234,13 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 	else
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 106, 0x35);
 | 
			
		||||
 
 | 
			
		||||
@@ -202,7 +202,7 @@
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392))
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 128, 0x12);
 | 
			
		||||
@@ -3684,13 +3717,15 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4217,13 +4250,15 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 135, 0xf6);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -219,7 +219,7 @@
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392)) {
 | 
			
		||||
 		rt2800_bbp_read(rt2x00dev, 138, &value);
 | 
			
		||||
@@ -3727,7 +3762,8 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4260,7 +4295,8 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 3, value);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -229,7 +229,7 @@
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 163, 0xbd);
 | 
			
		||||
 		/* Set ITxBF timeout to 0x9c40=1000msec */
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 179, 0x02);
 | 
			
		||||
@@ -3749,6 +3785,14 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
@@ -4282,6 +4318,14 @@ static int rt2800_init_bbp(struct rt2x00
 | 
			
		||||
 		rt2800_bbp_write(rt2x00dev, 148, 0xc8);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -244,7 +244,7 @@
 | 
			
		||||
 	if (rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392)) {
 | 
			
		||||
 		int ant, div_mode;
 | 
			
		||||
@@ -4143,6 +4187,76 @@ static void rt2800_init_rfcsr_3572(struc
 | 
			
		||||
@@ -4674,6 +4718,76 @@ static void rt2800_init_rfcsr_3572(struc
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 31, 0x10);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -321,15 +321,15 @@
 | 
			
		||||
 static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
 | 
			
		||||
 {
 | 
			
		||||
 	rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
 | 
			
		||||
@@ -4305,6 +4419,7 @@ static int rt2800_init_rfcsr(struct rt2x
 | 
			
		||||
@@ -4899,6 +5013,7 @@ static int rt2800_init_rfcsr(struct rt2x
 | 
			
		||||
 	    !rt2x00_rt(rt2x00dev, RT3352) &&
 | 
			
		||||
 	    !rt2x00_rt(rt2x00dev, RT3390) &&
 | 
			
		||||
 	    !rt2x00_rt(rt2x00dev, RT3572) &&
 | 
			
		||||
+	    !rt2x00_rt(rt2x00dev, RT5350) &&
 | 
			
		||||
 	    !rt2x00_rt(rt2x00dev, RT5390) &&
 | 
			
		||||
 	    !rt2x00_rt(rt2x00dev, RT5392) &&
 | 
			
		||||
 	    !rt2800_is_305x_soc(rt2x00dev))
 | 
			
		||||
@@ -4355,6 +4470,9 @@ static int rt2800_init_rfcsr(struct rt2x
 | 
			
		||||
 	    !rt2x00_rt(rt2x00dev, RT5392) &&
 | 
			
		||||
@@ -4951,6 +5066,9 @@ static int rt2800_init_rfcsr(struct rt2x
 | 
			
		||||
 	case RT3572:
 | 
			
		||||
 		rt2800_init_rfcsr_3572(rt2x00dev);
 | 
			
		||||
 		break;
 | 
			
		||||
@@ -339,7 +339,7 @@
 | 
			
		||||
 	case RT5390:
 | 
			
		||||
 		rt2800_init_rfcsr_5390(rt2x00dev);
 | 
			
		||||
 		break;
 | 
			
		||||
@@ -4751,6 +4869,12 @@ static int rt2800_validate_eeprom(struct
 | 
			
		||||
@@ -5361,6 +5479,12 @@ static int rt2800_validate_eeprom(struct
 | 
			
		||||
 		if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2)
 | 
			
		||||
 			rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
 | 
			
		||||
 		rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
 | 
			
		||||
@@ -352,24 +352,16 @@
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
 | 
			
		||||
@@ -4875,6 +4999,8 @@ static int rt2800_init_eeprom(struct rt2
 | 
			
		||||
 	    rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 ||
 | 
			
		||||
 	    rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392)
 | 
			
		||||
 		rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value);
 | 
			
		||||
+	else if(rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5350)
 | 
			
		||||
+		value = RF5350;
 | 
			
		||||
@@ -5480,6 +5604,8 @@ static int rt2800_init_eeprom(struct rt2
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5390) ||
 | 
			
		||||
 	    rt2x00_rt(rt2x00dev, RT5392))
 | 
			
		||||
 		rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
 | 
			
		||||
+	else if (rt2x00_rt(rt2x00dev, RT5350))
 | 
			
		||||
+		rf = RF5350;
 | 
			
		||||
 	else
 | 
			
		||||
 		value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
 | 
			
		||||
 		rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
 | 
			
		||||
 
 | 
			
		||||
@@ -4892,6 +5018,7 @@ static int rt2800_init_eeprom(struct rt2
 | 
			
		||||
 	case RT3352:
 | 
			
		||||
 	case RT3390:
 | 
			
		||||
 	case RT3572:
 | 
			
		||||
+	case RT5350:
 | 
			
		||||
 	case RT5390:
 | 
			
		||||
 	case RT5392:
 | 
			
		||||
 		break;
 | 
			
		||||
@@ -4913,6 +5040,7 @@ static int rt2800_init_eeprom(struct rt2
 | 
			
		||||
@@ -5496,6 +5622,7 @@ static int rt2800_init_eeprom(struct rt2
 | 
			
		||||
 	case RF3290:
 | 
			
		||||
 	case RF3320:
 | 
			
		||||
 	case RF3322:
 | 
			
		||||
@@ -377,7 +369,7 @@
 | 
			
		||||
 	case RF5360:
 | 
			
		||||
 	case RF5370:
 | 
			
		||||
 	case RF5372:
 | 
			
		||||
@@ -5275,7 +5403,8 @@ static int rt2800_probe_hw_mode(struct r
 | 
			
		||||
@@ -5993,7 +6120,8 @@ static int rt2800_probe_hw_mode(struct r
 | 
			
		||||
 		   rt2x00_rf(rt2x00dev, RF5392)) {
 | 
			
		||||
 		spec->num_channels = 14;
 | 
			
		||||
 		spec->channels = rf_vals_3x;
 | 
			
		||||
@@ -387,14 +379,22 @@
 | 
			
		||||
 		spec->num_channels = 14;
 | 
			
		||||
 		if (spec->clk_is_20mhz)
 | 
			
		||||
 			spec->channels = rf_vals_xtal20mhz_3x;
 | 
			
		||||
@@ -5364,6 +5493,7 @@ static int rt2800_probe_hw_mode(struct r
 | 
			
		||||
@@ -6094,6 +6222,7 @@ static int rt2800_probe_hw_mode(struct r
 | 
			
		||||
 	case RF3320:
 | 
			
		||||
 	case RF3052:
 | 
			
		||||
 	case RF3290:
 | 
			
		||||
+	case RF5350:
 | 
			
		||||
 	case RF5360:
 | 
			
		||||
 	case RF5370:
 | 
			
		||||
+	case RF5350:
 | 
			
		||||
 	case RF5372:
 | 
			
		||||
 	case RF5390:
 | 
			
		||||
 	case RF5392:
 | 
			
		||||
@@ -6131,6 +6260,7 @@ static int rt2800_probe_rt(struct rt2x00
 | 
			
		||||
 	case RT3352:
 | 
			
		||||
 	case RT3390:
 | 
			
		||||
 	case RT3572:
 | 
			
		||||
+	case RT5350:
 | 
			
		||||
 	case RT5390:
 | 
			
		||||
 	case RT5392:
 | 
			
		||||
 	case RT5592:
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/rt2x00.h
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
 | 
			
		||||
@@ -192,6 +192,7 @@ struct rt2x00_chip {
 | 
			
		||||
@@ -404,4 +404,4 @@
 | 
			
		||||
+#define RT5350		0x5350  /* WSOC 2.4GHz */
 | 
			
		||||
 #define RT5390		0x5390  /* 2.4GHz */
 | 
			
		||||
 #define RT5392		0x5392  /* 2.4GHz */
 | 
			
		||||
 
 | 
			
		||||
 #define RT5592		0x5592
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/wireless/rt2x00/Kconfig
 | 
			
		||||
+++ b/drivers/net/wireless/rt2x00/Kconfig
 | 
			
		||||
@@ -64,6 +64,7 @@ config RT2800PCI
 | 
			
		||||
@@ -68,6 +68,7 @@ config RT2800PCI
 | 
			
		||||
 	select RT2X00_LIB_CRYPTO
 | 
			
		||||
 	select CRC_CCITT
 | 
			
		||||
 	select EEPROM_93CX6
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/mwl8k.c
 | 
			
		||||
+++ b/drivers/net/wireless/mwl8k.c
 | 
			
		||||
@@ -5497,6 +5497,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
 | 
			
		||||
@@ -5525,6 +5525,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
 | 
			
		||||
 MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
 | 
			
		||||
 
 | 
			
		||||
 static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,70 +0,0 @@
 | 
			
		||||
From f340b99171e923eb6b54c1d0c22c15b45df40647 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Jonas Gorski <jogo@openwrt.org>
 | 
			
		||||
Date: Mon, 11 Mar 2013 17:17:28 +0100
 | 
			
		||||
Subject: [PATCH] mwl8k: don't overwrite regulatory settings
 | 
			
		||||
 | 
			
		||||
Currently the caps are parsed on every firmware reload, causing any
 | 
			
		||||
channel flags to be cleared.
 | 
			
		||||
When there is a firmware to interface mode mismatch, the triggered
 | 
			
		||||
firmware reload causes a reset of the regulatory settings, causing all
 | 
			
		||||
channels to become available:
 | 
			
		||||
 | 
			
		||||
root@openrouter:/# iw phy phy0 info
 | 
			
		||||
Wiphy phy0
 | 
			
		||||
        Band 1:
 | 
			
		||||
		(...)
 | 
			
		||||
                Frequencies:
 | 
			
		||||
                        * 2412 MHz [1] (0.0 dBm)
 | 
			
		||||
                        * 2417 MHz [2] (0.0 dBm)
 | 
			
		||||
                        * 2422 MHz [3] (0.0 dBm)
 | 
			
		||||
                        * 2427 MHz [4] (0.0 dBm)
 | 
			
		||||
                        * 2432 MHz [5] (0.0 dBm)
 | 
			
		||||
                        * 2437 MHz [6] (0.0 dBm)
 | 
			
		||||
                        * 2442 MHz [7] (0.0 dBm)
 | 
			
		||||
                        * 2447 MHz [8] (0.0 dBm)
 | 
			
		||||
                        * 2452 MHz [9] (0.0 dBm)
 | 
			
		||||
                        * 2457 MHz [10] (0.0 dBm)
 | 
			
		||||
                        * 2462 MHz [11] (0.0 dBm)
 | 
			
		||||
                        * 2467 MHz [12] (0.0 dBm)
 | 
			
		||||
                        * 2472 MHz [13] (0.0 dBm)
 | 
			
		||||
                        * 2484 MHz [14] (0.0 dBm)
 | 
			
		||||
		(...)
 | 
			
		||||
 | 
			
		||||
To prevent this, only parse the caps on the first firmware load during
 | 
			
		||||
hardware probe, and store them locally to know we have already parsed
 | 
			
		||||
them.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/wireless/mwl8k.c |    6 ++++++
 | 
			
		||||
 1 file changed, 6 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/wireless/mwl8k.c
 | 
			
		||||
+++ b/drivers/net/wireless/mwl8k.c
 | 
			
		||||
@@ -232,6 +232,7 @@ struct mwl8k_priv {
 | 
			
		||||
 	u16 num_mcaddrs;
 | 
			
		||||
 	u8 hw_rev;
 | 
			
		||||
 	u32 fw_rev;
 | 
			
		||||
+	u32 caps;
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * Running count of TX packets in flight, to avoid
 | 
			
		||||
@@ -2401,6 +2402,9 @@ mwl8k_set_caps(struct ieee80211_hw *hw, 
 | 
			
		||||
 {
 | 
			
		||||
 	struct mwl8k_priv *priv = hw->priv;
 | 
			
		||||
 
 | 
			
		||||
+	if (priv->caps)
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
 	if ((caps & MWL8K_CAP_2GHZ4) || !(caps & MWL8K_CAP_BAND_MASK)) {
 | 
			
		||||
 		mwl8k_setup_2ghz_band(hw);
 | 
			
		||||
 		if (caps & MWL8K_CAP_MIMO)
 | 
			
		||||
@@ -2412,6 +2416,8 @@ mwl8k_set_caps(struct ieee80211_hw *hw, 
 | 
			
		||||
 		if (caps & MWL8K_CAP_MIMO)
 | 
			
		||||
 			mwl8k_set_ht_caps(hw, &priv->band_50, caps);
 | 
			
		||||
 	}
 | 
			
		||||
+
 | 
			
		||||
+	priv->caps = caps;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
 | 
			
		||||
@@ -1,44 +0,0 @@
 | 
			
		||||
From 5d1ed64614ccb21c26bc0ee321e9c51b6359ceb8 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Jonas Gorski <jogo@openwrt.org>
 | 
			
		||||
Date: Mon, 25 Mar 2013 15:37:42 +0100
 | 
			
		||||
Subject: [PATCH] mwl8k: always apply configuration even when device is idle
 | 
			
		||||
 | 
			
		||||
Fix settings not being applied when the device is idle and the firmware
 | 
			
		||||
gets reloaded (because of changing from STA to AP mode). This caused
 | 
			
		||||
the device using the wrong channel (and likely band), e.g. a 5 GHz only
 | 
			
		||||
card still defaulted to channel 6 in the 2.4 GHz band when left
 | 
			
		||||
unconfigured.
 | 
			
		||||
 | 
			
		||||
This issue was always present, but only made visible with "mwl8k: Do not
 | 
			
		||||
call mwl8k_cmd_set_rf_channel unconditionally" (0f4316b9), since before
 | 
			
		||||
that the channel was (re-)configured at the next _config call even when
 | 
			
		||||
it did not change from the mac80211 perspective.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/wireless/mwl8k.c |   10 ++++------
 | 
			
		||||
 1 file changed, 4 insertions(+), 6 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/wireless/mwl8k.c
 | 
			
		||||
+++ b/drivers/net/wireless/mwl8k.c
 | 
			
		||||
@@ -4818,16 +4818,14 @@ static int mwl8k_config(struct ieee80211
 | 
			
		||||
 	struct mwl8k_priv *priv = hw->priv;
 | 
			
		||||
 	int rc;
 | 
			
		||||
 
 | 
			
		||||
-	if (conf->flags & IEEE80211_CONF_IDLE) {
 | 
			
		||||
-		mwl8k_cmd_radio_disable(hw);
 | 
			
		||||
-		return 0;
 | 
			
		||||
-	}
 | 
			
		||||
-
 | 
			
		||||
 	rc = mwl8k_fw_lock(hw);
 | 
			
		||||
 	if (rc)
 | 
			
		||||
 		return rc;
 | 
			
		||||
 
 | 
			
		||||
-	rc = mwl8k_cmd_radio_enable(hw);
 | 
			
		||||
+	if (conf->flags & IEEE80211_CONF_IDLE)
 | 
			
		||||
+		rc = mwl8k_cmd_radio_disable(hw);
 | 
			
		||||
+	else
 | 
			
		||||
+		rc = mwl8k_cmd_radio_enable(hw);
 | 
			
		||||
 	if (rc)
 | 
			
		||||
 		goto out;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/b43/b43.h
 | 
			
		||||
+++ b/drivers/net/wireless/b43/b43.h
 | 
			
		||||
@@ -812,6 +812,7 @@ struct b43_wldev {
 | 
			
		||||
@@ -820,6 +820,7 @@ struct b43_wldev {
 | 
			
		||||
 	bool qos_enabled;		/* TRUE, if QoS is used. */
 | 
			
		||||
 	bool hwcrypto_enabled;		/* TRUE, if HW crypto acceleration is enabled. */
 | 
			
		||||
 	bool use_pio;			/* TRUE if next init should use PIO */
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
 static int modparam_bad_frames_preempt;
 | 
			
		||||
 module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
 | 
			
		||||
 MODULE_PARM_DESC(bad_frames_preempt,
 | 
			
		||||
@@ -2740,10 +2745,10 @@ static int b43_gpio_init(struct b43_wlde
 | 
			
		||||
@@ -2747,10 +2752,10 @@ static int b43_gpio_init(struct b43_wlde
 | 
			
		||||
 	u32 mask, set;
 | 
			
		||||
 
 | 
			
		||||
 	b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
 b43-$(CONFIG_B43_PCMCIA)	+= pcmcia.o
 | 
			
		||||
--- a/drivers/net/wireless/b43/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/b43/main.c
 | 
			
		||||
@@ -1909,10 +1909,12 @@ static void b43_do_interrupt_thread(stru
 | 
			
		||||
@@ -1916,10 +1916,12 @@ static void b43_do_interrupt_thread(stru
 | 
			
		||||
 			       dma_reason[0], dma_reason[1],
 | 
			
		||||
 			       dma_reason[2], dma_reason[3],
 | 
			
		||||
 			       dma_reason[4], dma_reason[5]);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/b43/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/b43/main.c
 | 
			
		||||
@@ -1553,7 +1553,7 @@ static void b43_write_beacon_template(st
 | 
			
		||||
@@ -1560,7 +1560,7 @@ static void b43_write_beacon_template(st
 | 
			
		||||
 				  len, ram_offset, shm_size_offset, rate);
 | 
			
		||||
 
 | 
			
		||||
 	/* Write the PHY TX control parameters. */
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
 	antenna = b43_antenna_to_phyctl(antenna);
 | 
			
		||||
 	ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
 | 
			
		||||
 	/* We can't send beacons with short preamble. Would get PHY errors. */
 | 
			
		||||
@@ -3101,8 +3101,8 @@ static int b43_chip_init(struct b43_wlde
 | 
			
		||||
@@ -3105,8 +3105,8 @@ static int b43_chip_init(struct b43_wlde
 | 
			
		||||
 
 | 
			
		||||
 	/* Select the antennae */
 | 
			
		||||
 	if (phy->ops->set_rx_antenna)
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
 
 | 
			
		||||
 	if (phy->type == B43_PHYTYPE_B) {
 | 
			
		||||
 		value16 = b43_read16(dev, 0x005E);
 | 
			
		||||
@@ -3846,7 +3846,6 @@ static int b43_op_config(struct ieee8021
 | 
			
		||||
@@ -3850,7 +3850,6 @@ static int b43_op_config(struct ieee8021
 | 
			
		||||
 	struct b43_wldev *dev;
 | 
			
		||||
 	struct b43_phy *phy;
 | 
			
		||||
 	struct ieee80211_conf *conf = &hw->conf;
 | 
			
		||||
@@ -28,7 +28,7 @@
 | 
			
		||||
 	int err = 0;
 | 
			
		||||
 	bool reload_bss = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -3900,11 +3899,9 @@ static int b43_op_config(struct ieee8021
 | 
			
		||||
@@ -3904,11 +3903,9 @@ static int b43_op_config(struct ieee8021
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	/* Antennas for RX and management frame TX. */
 | 
			
		||||
@@ -42,7 +42,7 @@
 | 
			
		||||
 
 | 
			
		||||
 	if (wl->radio_enabled != phy->radio_on) {
 | 
			
		||||
 		if (wl->radio_enabled) {
 | 
			
		||||
@@ -5030,6 +5027,47 @@ static int b43_op_get_survey(struct ieee
 | 
			
		||||
@@ -5033,6 +5030,47 @@ static int b43_op_get_survey(struct ieee
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -90,7 +90,7 @@
 | 
			
		||||
 static const struct ieee80211_ops b43_hw_ops = {
 | 
			
		||||
 	.tx			= b43_op_tx,
 | 
			
		||||
 	.conf_tx		= b43_op_conf_tx,
 | 
			
		||||
@@ -5051,6 +5089,8 @@ static const struct ieee80211_ops b43_hw
 | 
			
		||||
@@ -5054,6 +5092,8 @@ static const struct ieee80211_ops b43_hw
 | 
			
		||||
 	.sw_scan_complete	= b43_op_sw_scan_complete_notifier,
 | 
			
		||||
 	.get_survey		= b43_op_get_survey,
 | 
			
		||||
 	.rfkill_poll		= b43_rfkill_poll,
 | 
			
		||||
@@ -99,7 +99,7 @@
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 /* Hard-reset the chip. Do not call this directly.
 | 
			
		||||
@@ -5297,6 +5337,8 @@ static int b43_one_core_attach(struct b4
 | 
			
		||||
@@ -5300,6 +5340,8 @@ static int b43_one_core_attach(struct b4
 | 
			
		||||
 	if (!wldev)
 | 
			
		||||
 		goto out;
 | 
			
		||||
 
 | 
			
		||||
@@ -108,7 +108,7 @@
 | 
			
		||||
 	wldev->use_pio = b43_modparam_pio;
 | 
			
		||||
 	wldev->dev = dev;
 | 
			
		||||
 	wldev->wl = wl;
 | 
			
		||||
@@ -5387,6 +5429,9 @@ static struct b43_wl *b43_wireless_init(
 | 
			
		||||
@@ -5390,6 +5432,9 @@ static struct b43_wl *b43_wireless_init(
 | 
			
		||||
 
 | 
			
		||||
 	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
 | 
			
		||||
 
 | 
			
		||||
@@ -120,7 +120,7 @@
 | 
			
		||||
 	SET_IEEE80211_DEV(hw, dev->dev);
 | 
			
		||||
--- a/drivers/net/wireless/b43/b43.h
 | 
			
		||||
+++ b/drivers/net/wireless/b43/b43.h
 | 
			
		||||
@@ -813,6 +813,8 @@ struct b43_wldev {
 | 
			
		||||
@@ -821,6 +821,8 @@ struct b43_wldev {
 | 
			
		||||
 	bool hwcrypto_enabled;		/* TRUE, if HW crypto acceleration is enabled. */
 | 
			
		||||
 	bool use_pio;			/* TRUE if next init should use PIO */
 | 
			
		||||
 	int gpiomask;			/* GPIO LED mask as a module parameter */
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/wireless/b43/b43.h
 | 
			
		||||
+++ b/drivers/net/wireless/b43/b43.h
 | 
			
		||||
@@ -1053,6 +1053,32 @@ static inline bool b43_using_pio_transfe
 | 
			
		||||
@@ -1061,6 +1061,32 @@ static inline bool b43_using_pio_transfe
 | 
			
		||||
 	return dev->__using_pio_transfers;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -88,7 +88,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 		dev->phy.writes_counter = 0;
 | 
			
		||||
--- a/drivers/net/wireless/b43/phy_n.c
 | 
			
		||||
+++ b/drivers/net/wireless/b43/phy_n.c
 | 
			
		||||
@@ -5423,14 +5423,14 @@ static inline void check_phyreg(struct b
 | 
			
		||||
@@ -5368,14 +5368,14 @@ static inline void check_phyreg(struct b
 | 
			
		||||
 static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg)
 | 
			
		||||
 {
 | 
			
		||||
 	check_phyreg(dev, reg);
 | 
			
		||||
@@ -105,7 +105,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -5438,7 +5438,7 @@ static void b43_nphy_op_maskset(struct b
 | 
			
		||||
@@ -5383,7 +5383,7 @@ static void b43_nphy_op_maskset(struct b
 | 
			
		||||
 				 u16 set)
 | 
			
		||||
 {
 | 
			
		||||
 	check_phyreg(dev, reg);
 | 
			
		||||
@@ -114,7 +114,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 	b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -5449,7 +5449,7 @@ static u16 b43_nphy_op_radio_read(struct
 | 
			
		||||
@@ -5394,7 +5394,7 @@ static u16 b43_nphy_op_radio_read(struct
 | 
			
		||||
 	/* N-PHY needs 0x100 for read access */
 | 
			
		||||
 	reg |= 0x100;
 | 
			
		||||
 
 | 
			
		||||
@@ -123,7 +123,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -5458,7 +5458,7 @@ static void b43_nphy_op_radio_write(stru
 | 
			
		||||
@@ -5403,7 +5403,7 @@ static void b43_nphy_op_radio_write(stru
 | 
			
		||||
 	/* Register 1 is a 32-bit register. */
 | 
			
		||||
 	B43_WARN_ON(reg == 1);
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/b43/dma.h
 | 
			
		||||
+++ b/drivers/net/wireless/b43/dma.h
 | 
			
		||||
@@ -169,7 +169,7 @@ struct b43_dmadesc_generic {
 | 
			
		||||
 
 | 
			
		||||
 /* DMA engine tuning knobs */
 | 
			
		||||
 #define B43_TXRING_SLOTS		256
 | 
			
		||||
-#define B43_RXRING_SLOTS		64
 | 
			
		||||
+#define B43_RXRING_SLOTS		256
 | 
			
		||||
 #define B43_DMA0_RX_FW598_BUFSIZE	(B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN)
 | 
			
		||||
 #define B43_DMA0_RX_FW351_BUFSIZE	(B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
@@ -99,6 +99,7 @@ static struct bcma_device_id brcms_corei
 | 
			
		||||
@@ -101,6 +101,7 @@ static struct bcma_device_id brcms_corei
 | 
			
		||||
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 17, BCMA_ANY_CLASS),
 | 
			
		||||
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS),
 | 
			
		||||
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS),
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
 MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -717,7 +717,7 @@ static void brcms_c_ucode_bsinit(struct 
 | 
			
		||||
@@ -722,7 +722,7 @@ static void brcms_c_ucode_bsinit(struct 
 | 
			
		||||
 	brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs);
 | 
			
		||||
 
 | 
			
		||||
 	/* do band-specific ucode IHR, SHM, and SCR inits */
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
 		if (BRCMS_ISNPHY(wlc_hw->band))
 | 
			
		||||
 			brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16);
 | 
			
		||||
 		else
 | 
			
		||||
@@ -2257,7 +2257,7 @@ static void brcms_ucode_download(struct 
 | 
			
		||||
@@ -2288,7 +2288,7 @@ static void brcms_ucode_download(struct 
 | 
			
		||||
 	if (wlc_hw->ucode_loaded)
 | 
			
		||||
 		return;
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@
 | 
			
		||||
 		if (BRCMS_ISNPHY(wlc_hw->band)) {
 | 
			
		||||
 			brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo,
 | 
			
		||||
 					  ucode->bcm43xx_16_mimosz);
 | 
			
		||||
@@ -3207,7 +3207,7 @@ static void brcms_b_coreinit(struct brcm
 | 
			
		||||
@@ -3231,7 +3231,7 @@ static void brcms_b_coreinit(struct brcm
 | 
			
		||||
 
 | 
			
		||||
 	sflags = bcma_aread32(core, BCMA_IOST);
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@
 | 
			
		||||
 		if (BRCMS_ISNPHY(wlc_hw->band))
 | 
			
		||||
 			brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16);
 | 
			
		||||
 		else
 | 
			
		||||
@@ -5663,6 +5663,8 @@ static bool brcms_c_chipmatch_soc(struct
 | 
			
		||||
@@ -5723,6 +5723,8 @@ static bool brcms_c_chipmatch_soc(struct
 | 
			
		||||
 
 | 
			
		||||
 	if (chipinfo->id == BCMA_CHIP_ID_BCM4716)
 | 
			
		||||
 		return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,121 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/d11.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
 | 
			
		||||
@@ -457,6 +457,7 @@ struct d11regs {
 | 
			
		||||
 /*== maccontrol register ==*/
 | 
			
		||||
 #define	MCTL_GMODE		(1U << 31)
 | 
			
		||||
 #define	MCTL_DISCARD_PMQ	(1 << 30)
 | 
			
		||||
+#define	MCTL_TBTTHOLD		(1 << 28)
 | 
			
		||||
 #define	MCTL_WAKE		(1 << 26)
 | 
			
		||||
 #define	MCTL_HPS		(1 << 25)
 | 
			
		||||
 #define	MCTL_PROMISC		(1 << 24)
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
@@ -741,6 +741,28 @@ static void brcms_ops_flush(struct ieee8
 | 
			
		||||
 			   "ret=%d\n", jiffies_to_msecs(ret));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 | 
			
		||||
+{
 | 
			
		||||
+	struct brcms_info *wl = hw->priv;
 | 
			
		||||
+	u64 tsf;
 | 
			
		||||
+
 | 
			
		||||
+	spin_lock_bh(&wl->lock);
 | 
			
		||||
+	tsf = brcms_c_tsf_get(wl->wlc);
 | 
			
		||||
+	spin_unlock_bh(&wl->lock);
 | 
			
		||||
+
 | 
			
		||||
+	return tsf;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void brcms_ops_set_tsf(struct ieee80211_hw *hw,
 | 
			
		||||
+			   struct ieee80211_vif *vif, u64 tsf)
 | 
			
		||||
+{
 | 
			
		||||
+	struct brcms_info *wl = hw->priv;
 | 
			
		||||
+
 | 
			
		||||
+	spin_lock_bh(&wl->lock);
 | 
			
		||||
+	brcms_c_tsf_set(wl->wlc, tsf);
 | 
			
		||||
+	spin_unlock_bh(&wl->lock);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static const struct ieee80211_ops brcms_ops = {
 | 
			
		||||
 	.tx = brcms_ops_tx,
 | 
			
		||||
 	.start = brcms_ops_start,
 | 
			
		||||
@@ -757,6 +779,8 @@ static const struct ieee80211_ops brcms_
 | 
			
		||||
 	.ampdu_action = brcms_ops_ampdu_action,
 | 
			
		||||
 	.rfkill_poll = brcms_ops_rfkill_poll,
 | 
			
		||||
 	.flush = brcms_ops_flush,
 | 
			
		||||
+	.get_tsf = brcms_ops_get_tsf,
 | 
			
		||||
+	.set_tsf = brcms_ops_set_tsf,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 void brcms_dpc(unsigned long data)
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -5545,6 +5545,20 @@ int brcms_c_set_rateset(struct brcms_c_i
 | 
			
		||||
 	return bcmerror;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void brcms_c_time_lock(struct brcms_c_info *wlc)
 | 
			
		||||
+{
 | 
			
		||||
+	bcma_set32(wlc->hw->d11core, D11REGOFFS(maccontrol), MCTL_TBTTHOLD);
 | 
			
		||||
+	/* Commit the write */
 | 
			
		||||
+	bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void brcms_c_time_unlock(struct brcms_c_info *wlc)
 | 
			
		||||
+{
 | 
			
		||||
+	bcma_mask32(wlc->hw->d11core, D11REGOFFS(maccontrol), ~MCTL_TBTTHOLD);
 | 
			
		||||
+	/* Commit the write */
 | 
			
		||||
+	bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
 | 
			
		||||
 {
 | 
			
		||||
 	if (period == 0)
 | 
			
		||||
@@ -7530,6 +7544,36 @@ void brcms_c_set_beacon_listen_interval(
 | 
			
		||||
 		brcms_c_bcn_li_upd(wlc);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+u64 brcms_c_tsf_get(struct brcms_c_info *wlc)
 | 
			
		||||
+{
 | 
			
		||||
+	u32 tsf_h, tsf_l;
 | 
			
		||||
+	u64 tsf;
 | 
			
		||||
+
 | 
			
		||||
+	brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
 | 
			
		||||
+
 | 
			
		||||
+	tsf = tsf_h;
 | 
			
		||||
+	tsf <<= 32;
 | 
			
		||||
+	tsf |= tsf_l;
 | 
			
		||||
+
 | 
			
		||||
+	return tsf;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf)
 | 
			
		||||
+{
 | 
			
		||||
+	u32 tsf_h, tsf_l;
 | 
			
		||||
+
 | 
			
		||||
+	brcms_c_time_lock(wlc);
 | 
			
		||||
+
 | 
			
		||||
+	tsf_l = tsf;
 | 
			
		||||
+	tsf_h = (tsf >> 32);
 | 
			
		||||
+
 | 
			
		||||
+	/* read the tsf timer low, then high to get an atomic read */
 | 
			
		||||
+	bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerlow), tsf_l);
 | 
			
		||||
+	bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerhigh), tsf_h);
 | 
			
		||||
+
 | 
			
		||||
+	brcms_c_time_unlock(wlc);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
 | 
			
		||||
 {
 | 
			
		||||
 	uint qdbm;
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
@@ -326,6 +326,8 @@ extern void brcms_c_set_shortslot_overri
 | 
			
		||||
 				    s8 sslot_override);
 | 
			
		||||
 extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
 | 
			
		||||
 					u8 interval);
 | 
			
		||||
+extern u64 brcms_c_tsf_get(struct brcms_c_info *wlc);
 | 
			
		||||
+extern void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf);
 | 
			
		||||
 extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
 | 
			
		||||
 extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
 | 
			
		||||
 extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
 | 
			
		||||
@@ -1,66 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
@@ -367,9 +367,10 @@ brcms_ops_add_interface(struct ieee80211
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	spin_lock_bh(&wl->lock);
 | 
			
		||||
-	memcpy(wl->pub->cur_etheraddr, vif->addr, sizeof(vif->addr));
 | 
			
		||||
 	wl->mute_tx = false;
 | 
			
		||||
 	brcms_c_mute(wl->wlc, false);
 | 
			
		||||
+	if (vif->type == NL80211_IFTYPE_STATION)
 | 
			
		||||
+		brcms_c_start_station(wl->wlc, vif->addr);
 | 
			
		||||
 	spin_unlock_bh(&wl->lock);
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -2165,6 +2165,12 @@ void brcms_b_switch_macfreq(struct brcms
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr)
 | 
			
		||||
+{
 | 
			
		||||
+	memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr));
 | 
			
		||||
+	wlc->bsscfg->type = BRCMS_TYPE_STATION;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /* Initialize GPIOs that are controlled by D11 core */
 | 
			
		||||
 static void brcms_c_gpio_init(struct brcms_c_info *wlc)
 | 
			
		||||
 {
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
@@ -576,10 +576,17 @@ struct antsel_info {
 | 
			
		||||
 	struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+enum brcms_bss_type {
 | 
			
		||||
+	BRCMS_TYPE_STATION,
 | 
			
		||||
+	BRCMS_TYPE_AP,
 | 
			
		||||
+	BRCMS_TYPE_ADHOC,
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
 /*
 | 
			
		||||
  * BSS configuration state
 | 
			
		||||
  *
 | 
			
		||||
  * wlc: wlc to which this bsscfg belongs to.
 | 
			
		||||
+ * type: interface type
 | 
			
		||||
  * up: is this configuration up operational
 | 
			
		||||
  * enable: is this configuration enabled
 | 
			
		||||
  * associated: is BSS in ASSOCIATED state
 | 
			
		||||
@@ -599,6 +606,7 @@ struct antsel_info {
 | 
			
		||||
  */
 | 
			
		||||
 struct brcms_bss_cfg {
 | 
			
		||||
 	struct brcms_c_info *wlc;
 | 
			
		||||
+	enum brcms_bss_type type;
 | 
			
		||||
 	bool up;
 | 
			
		||||
 	bool enable;
 | 
			
		||||
 	bool associated;
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
@@ -333,5 +333,6 @@ extern int brcms_c_get_tx_power(struct b
 | 
			
		||||
 extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
 | 
			
		||||
 extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
 | 
			
		||||
 extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc);
 | 
			
		||||
+extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr);
 | 
			
		||||
 
 | 
			
		||||
 #endif				/* _BRCM_PUB_H_ */
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -1071,7 +1071,7 @@ brcms_b_txstatus(struct brcms_hardware *
 | 
			
		||||
 
 | 
			
		||||
 static void brcms_c_tbtt(struct brcms_c_info *wlc)
 | 
			
		||||
 {
 | 
			
		||||
-	if (!wlc->bsscfg->BSS)
 | 
			
		||||
+	if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC)
 | 
			
		||||
 		/*
 | 
			
		||||
 		 * DirFrmQ is now valid...defer setting until end
 | 
			
		||||
 		 * of ATIM window
 | 
			
		||||
@@ -3061,16 +3061,8 @@ static bool brcms_c_ps_allowed(struct br
 | 
			
		||||
 	if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
 | 
			
		||||
 		return false;
 | 
			
		||||
 
 | 
			
		||||
-	if (cfg->associated) {
 | 
			
		||||
-		/*
 | 
			
		||||
-		 * disallow PS when one of the following
 | 
			
		||||
-		 * bsscfg specific conditions meets
 | 
			
		||||
-		 */
 | 
			
		||||
-		if (!cfg->BSS)
 | 
			
		||||
-			return false;
 | 
			
		||||
-
 | 
			
		||||
+	if (cfg->associated)
 | 
			
		||||
 		return false;
 | 
			
		||||
-	}
 | 
			
		||||
 
 | 
			
		||||
 	return true;
 | 
			
		||||
 }
 | 
			
		||||
@@ -5080,8 +5072,9 @@ int brcms_c_up(struct brcms_c_info *wlc)
 | 
			
		||||
 				struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
 | 
			
		||||
 				mboolset(wlc->pub->radio_disabled,
 | 
			
		||||
 					 WL_RADIO_HW_DISABLE);
 | 
			
		||||
-
 | 
			
		||||
-				if (bsscfg->enable && bsscfg->BSS)
 | 
			
		||||
+				if (bsscfg->enable &&
 | 
			
		||||
+				    (bsscfg->type == BRCMS_TYPE_STATION ||
 | 
			
		||||
+				     bsscfg->type == BRCMS_TYPE_ADHOC))
 | 
			
		||||
 					brcms_err(wlc->hw->d11core,
 | 
			
		||||
 						  "wl%d: up: rfdisable -> "
 | 
			
		||||
 						  "bsscfg_disable()\n",
 | 
			
		||||
@@ -7390,7 +7383,8 @@ void brcms_c_update_beacon(struct brcms_
 | 
			
		||||
 {
 | 
			
		||||
 	struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
 | 
			
		||||
 
 | 
			
		||||
-	if (bsscfg->up && !bsscfg->BSS)
 | 
			
		||||
+	if (bsscfg->up && (bsscfg->type == BRCMS_TYPE_AP ||
 | 
			
		||||
+			   bsscfg->type == BRCMS_TYPE_ADHOC))
 | 
			
		||||
 		/* Clear the soft intmask */
 | 
			
		||||
 		wlc->defmacintmask &= ~MI_BCNTPL;
 | 
			
		||||
 }
 | 
			
		||||
@@ -7465,7 +7459,8 @@ void brcms_c_update_probe_resp(struct br
 | 
			
		||||
 	struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
 | 
			
		||||
 
 | 
			
		||||
 	/* update AP or IBSS probe responses */
 | 
			
		||||
-	if (bsscfg->up && !bsscfg->BSS)
 | 
			
		||||
+	if (bsscfg->up && (bsscfg->type == BRCMS_TYPE_AP ||
 | 
			
		||||
+			   bsscfg->type == BRCMS_TYPE_ADHOC))
 | 
			
		||||
 		brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
@@ -590,7 +590,6 @@ enum brcms_bss_type {
 | 
			
		||||
  * up: is this configuration up operational
 | 
			
		||||
  * enable: is this configuration enabled
 | 
			
		||||
  * associated: is BSS in ASSOCIATED state
 | 
			
		||||
- * BSS: infraustructure or adhoc
 | 
			
		||||
  * SSID_len: the length of SSID
 | 
			
		||||
  * SSID: SSID string
 | 
			
		||||
  *
 | 
			
		||||
@@ -610,7 +609,6 @@ struct brcms_bss_cfg {
 | 
			
		||||
 	bool up;
 | 
			
		||||
 	bool enable;
 | 
			
		||||
 	bool associated;
 | 
			
		||||
-	bool BSS;
 | 
			
		||||
 	u8 SSID_len;
 | 
			
		||||
 	u8 SSID[IEEE80211_MAX_SSID_LEN];
 | 
			
		||||
 	u8 BSSID[ETH_ALEN];
 | 
			
		||||
@@ -1,74 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -3051,8 +3051,6 @@ static void brcms_b_antsel_set(struct br
 | 
			
		||||
  */
 | 
			
		||||
 static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
 | 
			
		||||
 {
 | 
			
		||||
-	struct brcms_bss_cfg *cfg = wlc->bsscfg;
 | 
			
		||||
-
 | 
			
		||||
 	/* disallow PS when one of the following global conditions meets */
 | 
			
		||||
 	if (!wlc->pub->associated)
 | 
			
		||||
 		return false;
 | 
			
		||||
@@ -3061,9 +3059,6 @@ static bool brcms_c_ps_allowed(struct br
 | 
			
		||||
 	if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
 | 
			
		||||
 		return false;
 | 
			
		||||
 
 | 
			
		||||
-	if (cfg->associated)
 | 
			
		||||
-		return false;
 | 
			
		||||
-
 | 
			
		||||
 	return true;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -3821,7 +3816,7 @@ static void brcms_c_set_home_chanspec(st
 | 
			
		||||
 	if (wlc->home_chanspec != chanspec) {
 | 
			
		||||
 		wlc->home_chanspec = chanspec;
 | 
			
		||||
 
 | 
			
		||||
-		if (wlc->bsscfg->associated)
 | 
			
		||||
+		if (wlc->pub->associated)
 | 
			
		||||
 			wlc->bsscfg->current_bss->chanspec = chanspec;
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
@@ -5435,7 +5430,7 @@ static void brcms_c_ofdm_rateset_war(str
 | 
			
		||||
 	u8 r;
 | 
			
		||||
 	bool war = false;
 | 
			
		||||
 
 | 
			
		||||
-	if (wlc->bsscfg->associated)
 | 
			
		||||
+	if (wlc->pub->associated)
 | 
			
		||||
 		r = wlc->bsscfg->current_bss->rateset.rates[0];
 | 
			
		||||
 	else
 | 
			
		||||
 		r = wlc->default_bss->rateset.rates[0];
 | 
			
		||||
@@ -5529,7 +5524,7 @@ int brcms_c_set_rateset(struct brcms_c_i
 | 
			
		||||
 	/* merge rateset coming in with the current mcsset */
 | 
			
		||||
 	if (wlc->pub->_n_enab & SUPPORT_11N) {
 | 
			
		||||
 		struct brcms_bss_info *mcsset_bss;
 | 
			
		||||
-		if (wlc->bsscfg->associated)
 | 
			
		||||
+		if (wlc->pub->associated)
 | 
			
		||||
 			mcsset_bss = wlc->bsscfg->current_bss;
 | 
			
		||||
 		else
 | 
			
		||||
 			mcsset_bss = wlc->default_bss;
 | 
			
		||||
@@ -7500,7 +7495,6 @@ void brcms_c_scan_stop(struct brcms_c_in
 | 
			
		||||
 void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
 | 
			
		||||
 {
 | 
			
		||||
 	wlc->pub->associated = state;
 | 
			
		||||
-	wlc->bsscfg->associated = state;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
@@ -589,7 +589,6 @@ enum brcms_bss_type {
 | 
			
		||||
  * type: interface type
 | 
			
		||||
  * up: is this configuration up operational
 | 
			
		||||
  * enable: is this configuration enabled
 | 
			
		||||
- * associated: is BSS in ASSOCIATED state
 | 
			
		||||
  * SSID_len: the length of SSID
 | 
			
		||||
  * SSID: SSID string
 | 
			
		||||
  *
 | 
			
		||||
@@ -608,7 +607,6 @@ struct brcms_bss_cfg {
 | 
			
		||||
 	enum brcms_bss_type type;
 | 
			
		||||
 	bool up;
 | 
			
		||||
 	bool enable;
 | 
			
		||||
-	bool associated;
 | 
			
		||||
 	u8 SSID_len;
 | 
			
		||||
 	u8 SSID[IEEE80211_MAX_SSID_LEN];
 | 
			
		||||
 	u8 BSSID[ETH_ALEN];
 | 
			
		||||
@@ -1,32 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -5067,9 +5067,8 @@ int brcms_c_up(struct brcms_c_info *wlc)
 | 
			
		||||
 				struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
 | 
			
		||||
 				mboolset(wlc->pub->radio_disabled,
 | 
			
		||||
 					 WL_RADIO_HW_DISABLE);
 | 
			
		||||
-				if (bsscfg->enable &&
 | 
			
		||||
-				    (bsscfg->type == BRCMS_TYPE_STATION ||
 | 
			
		||||
-				     bsscfg->type == BRCMS_TYPE_ADHOC))
 | 
			
		||||
+				if (bsscfg->type == BRCMS_TYPE_STATION ||
 | 
			
		||||
+				    bsscfg->type == BRCMS_TYPE_ADHOC)
 | 
			
		||||
 					brcms_err(wlc->hw->d11core,
 | 
			
		||||
 						  "wl%d: up: rfdisable -> "
 | 
			
		||||
 						  "bsscfg_disable()\n",
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
@@ -588,7 +588,6 @@ enum brcms_bss_type {
 | 
			
		||||
  * wlc: wlc to which this bsscfg belongs to.
 | 
			
		||||
  * type: interface type
 | 
			
		||||
  * up: is this configuration up operational
 | 
			
		||||
- * enable: is this configuration enabled
 | 
			
		||||
  * SSID_len: the length of SSID
 | 
			
		||||
  * SSID: SSID string
 | 
			
		||||
  *
 | 
			
		||||
@@ -606,7 +605,6 @@ struct brcms_bss_cfg {
 | 
			
		||||
 	struct brcms_c_info *wlc;
 | 
			
		||||
 	enum brcms_bss_type type;
 | 
			
		||||
 	bool up;
 | 
			
		||||
-	bool enable;
 | 
			
		||||
 	u8 SSID_len;
 | 
			
		||||
 	u8 SSID[IEEE80211_MAX_SSID_LEN];
 | 
			
		||||
 	u8 BSSID[ETH_ALEN];
 | 
			
		||||
@@ -1,51 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -7377,8 +7377,8 @@ void brcms_c_update_beacon(struct brcms_
 | 
			
		||||
 {
 | 
			
		||||
 	struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
 | 
			
		||||
 
 | 
			
		||||
-	if (bsscfg->up && (bsscfg->type == BRCMS_TYPE_AP ||
 | 
			
		||||
-			   bsscfg->type == BRCMS_TYPE_ADHOC))
 | 
			
		||||
+	if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
 | 
			
		||||
+			     bsscfg->type == BRCMS_TYPE_ADHOC))
 | 
			
		||||
 		/* Clear the soft intmask */
 | 
			
		||||
 		wlc->defmacintmask &= ~MI_BCNTPL;
 | 
			
		||||
 }
 | 
			
		||||
@@ -7453,8 +7453,8 @@ void brcms_c_update_probe_resp(struct br
 | 
			
		||||
 	struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
 | 
			
		||||
 
 | 
			
		||||
 	/* update AP or IBSS probe responses */
 | 
			
		||||
-	if (bsscfg->up && (bsscfg->type == BRCMS_TYPE_AP ||
 | 
			
		||||
-			   bsscfg->type == BRCMS_TYPE_ADHOC))
 | 
			
		||||
+	if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
 | 
			
		||||
+			     bsscfg->type == BRCMS_TYPE_ADHOC))
 | 
			
		||||
 		brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -7807,7 +7807,7 @@ void brcms_c_init(struct brcms_c_info *w
 | 
			
		||||
 	brcms_c_set_bssid(wlc->bsscfg);
 | 
			
		||||
 
 | 
			
		||||
 	/* Update tsf_cfprep if associated and up */
 | 
			
		||||
-	if (wlc->pub->associated && wlc->bsscfg->up) {
 | 
			
		||||
+	if (wlc->pub->associated && wlc->pub->up) {
 | 
			
		||||
 		u32 bi;
 | 
			
		||||
 
 | 
			
		||||
 		/* get beacon period and convert to uS */
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
@@ -587,7 +587,6 @@ enum brcms_bss_type {
 | 
			
		||||
  *
 | 
			
		||||
  * wlc: wlc to which this bsscfg belongs to.
 | 
			
		||||
  * type: interface type
 | 
			
		||||
- * up: is this configuration up operational
 | 
			
		||||
  * SSID_len: the length of SSID
 | 
			
		||||
  * SSID: SSID string
 | 
			
		||||
  *
 | 
			
		||||
@@ -604,7 +603,6 @@ enum brcms_bss_type {
 | 
			
		||||
 struct brcms_bss_cfg {
 | 
			
		||||
 	struct brcms_c_info *wlc;
 | 
			
		||||
 	enum brcms_bss_type type;
 | 
			
		||||
-	bool up;
 | 
			
		||||
 	u8 SSID_len;
 | 
			
		||||
 	u8 SSID[IEEE80211_MAX_SSID_LEN];
 | 
			
		||||
 	u8 BSSID[ETH_ALEN];
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -3766,7 +3766,7 @@ static int brcms_c_set_mac(struct brcms_
 | 
			
		||||
 	struct brcms_c_info *wlc = bsscfg->wlc;
 | 
			
		||||
 
 | 
			
		||||
 	/* enter the MAC addr into the RXE match registers */
 | 
			
		||||
-	brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, bsscfg->cur_etheraddr);
 | 
			
		||||
+	brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, wlc->pub->cur_etheraddr);
 | 
			
		||||
 
 | 
			
		||||
 	brcms_c_ampdu_macaddr_upd(wlc);
 | 
			
		||||
 
 | 
			
		||||
@@ -7359,7 +7359,7 @@ brcms_c_bcn_prb_template(struct brcms_c_
 | 
			
		||||
 	/* A1 filled in by MAC for prb resp, broadcast for bcn */
 | 
			
		||||
 	if (type == IEEE80211_STYPE_BEACON)
 | 
			
		||||
 		memcpy(&h->da, ðer_bcast, ETH_ALEN);
 | 
			
		||||
-	memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
 | 
			
		||||
+	memcpy(&h->sa, &wlc->pub->cur_etheraddr, ETH_ALEN);
 | 
			
		||||
 	memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
 | 
			
		||||
 
 | 
			
		||||
 	/* SEQ filled in by MAC */
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
@@ -606,7 +606,6 @@ struct brcms_bss_cfg {
 | 
			
		||||
 	u8 SSID_len;
 | 
			
		||||
 	u8 SSID[IEEE80211_MAX_SSID_LEN];
 | 
			
		||||
 	u8 BSSID[ETH_ALEN];
 | 
			
		||||
-	u8 cur_etheraddr[ETH_ALEN];
 | 
			
		||||
 	struct brcms_bss_info *current_bss;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@@ -1,21 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -4327,7 +4327,6 @@ static void brcms_c_info_init(struct brc
 | 
			
		||||
 
 | 
			
		||||
 	/* WME QoS mode is Auto by default */
 | 
			
		||||
 	wlc->pub->_ampdu = AMPDU_AGG_HOST;
 | 
			
		||||
-	wlc->pub->bcmerror = 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static uint brcms_c_attach_module(struct brcms_c_info *wlc)
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
@@ -164,8 +164,6 @@ struct brcms_pub {
 | 
			
		||||
 
 | 
			
		||||
 	u8 cur_etheraddr[ETH_ALEN];	/* our local ethernet address */
 | 
			
		||||
 
 | 
			
		||||
-	int bcmerror;		/* last bcm error */
 | 
			
		||||
-
 | 
			
		||||
 	u32 radio_disabled;	/* bit vector for radio disabled reasons */
 | 
			
		||||
 
 | 
			
		||||
 	u16 boardrev;	/* version # of particular board */
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -5553,10 +5553,20 @@ static void brcms_c_time_unlock(struct b
 | 
			
		||||
 
 | 
			
		||||
 int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
 | 
			
		||||
 {
 | 
			
		||||
+	u32 bcnint_us;
 | 
			
		||||
+
 | 
			
		||||
 	if (period == 0)
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 
 | 
			
		||||
 	wlc->default_bss->beacon_period = period;
 | 
			
		||||
+
 | 
			
		||||
+	bcnint_us = period << 10;
 | 
			
		||||
+	brcms_c_time_lock(wlc);
 | 
			
		||||
+	bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_cfprep),
 | 
			
		||||
+		     (bcnint_us << CFPREP_CBI_SHIFT));
 | 
			
		||||
+	bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_cfpstart), bcnint_us);
 | 
			
		||||
+	brcms_c_time_unlock(wlc);
 | 
			
		||||
+
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,266 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
 /*
 | 
			
		||||
  * Copyright (c) 2010 Broadcom Corporation
 | 
			
		||||
+ * Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
  *
 | 
			
		||||
  * Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
  * purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
@@ -522,9 +523,17 @@ brcms_ops_bss_info_changed(struct ieee80
 | 
			
		||||
 		brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid);
 | 
			
		||||
 		spin_unlock_bh(&wl->lock);
 | 
			
		||||
 	}
 | 
			
		||||
-	if (changed & BSS_CHANGED_BEACON)
 | 
			
		||||
+	if (changed & BSS_CHANGED_BEACON) {
 | 
			
		||||
 		/* Beacon data changed, retrieve new beacon (beaconing modes) */
 | 
			
		||||
-		brcms_err(core, "%s: beacon changed\n", __func__);
 | 
			
		||||
+		struct sk_buff *beacon;
 | 
			
		||||
+		u16 tim_offset = 0;
 | 
			
		||||
+
 | 
			
		||||
+		spin_lock_bh(&wl->lock);
 | 
			
		||||
+		beacon = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL);
 | 
			
		||||
+		brcms_c_set_new_beacon(wl->wlc, beacon, tim_offset,
 | 
			
		||||
+				       info->dtim_period);
 | 
			
		||||
+		spin_unlock_bh(&wl->lock);
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	if (changed & BSS_CHANGED_BEACON_ENABLED) {
 | 
			
		||||
 		/* Beaconing should be enabled/disabled (beaconing modes) */
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
 /*
 | 
			
		||||
  * Copyright (c) 2010 Broadcom Corporation
 | 
			
		||||
+ * Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de>
 | 
			
		||||
  *
 | 
			
		||||
  * Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
  * purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
@@ -450,6 +451,8 @@ static void brcms_c_detach_mfree(struct 
 | 
			
		||||
 	kfree(wlc->corestate);
 | 
			
		||||
 	kfree(wlc->hw->bandstate[0]);
 | 
			
		||||
 	kfree(wlc->hw);
 | 
			
		||||
+	if (wlc->beacon)
 | 
			
		||||
+		dev_kfree_skb_any(wlc->beacon);
 | 
			
		||||
 
 | 
			
		||||
 	/* free the wlc */
 | 
			
		||||
 	kfree(wlc);
 | 
			
		||||
@@ -4086,10 +4089,14 @@ void brcms_c_wme_setparams(struct brcms_
 | 
			
		||||
 					  *shm_entry++);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	if (suspend) {
 | 
			
		||||
+	if (suspend)
 | 
			
		||||
 		brcms_c_suspend_mac_and_wait(wlc);
 | 
			
		||||
+
 | 
			
		||||
+	brcms_c_update_beacon(wlc);
 | 
			
		||||
+	brcms_c_update_probe_resp(wlc, false);
 | 
			
		||||
+
 | 
			
		||||
+	if (suspend)
 | 
			
		||||
 		brcms_c_enable_mac(wlc);
 | 
			
		||||
-	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
 | 
			
		||||
@@ -7379,6 +7386,107 @@ int brcms_c_get_header_len(void)
 | 
			
		||||
 	return TXOFF;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void brcms_c_beacon_write(struct brcms_c_info *wlc,
 | 
			
		||||
+				 struct sk_buff *beacon, u16 tim_offset,
 | 
			
		||||
+				 u16 dtim_period, bool bcn0, bool bcn1)
 | 
			
		||||
+{
 | 
			
		||||
+	size_t len;
 | 
			
		||||
+	struct ieee80211_tx_info *tx_info;
 | 
			
		||||
+	struct brcms_hardware *wlc_hw = wlc->hw;
 | 
			
		||||
+	struct ieee80211_hw *ieee_hw = brcms_c_pub(wlc)->ieee_hw;
 | 
			
		||||
+
 | 
			
		||||
+	/* Get tx_info */
 | 
			
		||||
+	tx_info = IEEE80211_SKB_CB(beacon);
 | 
			
		||||
+
 | 
			
		||||
+	len = min_t(size_t, beacon->len, BCN_TMPL_LEN);
 | 
			
		||||
+	wlc->bcn_rspec = ieee80211_get_tx_rate(ieee_hw, tx_info)->hw_value;
 | 
			
		||||
+
 | 
			
		||||
+	brcms_c_compute_plcp(wlc, wlc->bcn_rspec,
 | 
			
		||||
+			     len + FCS_LEN - D11_PHY_HDR_LEN, beacon->data);
 | 
			
		||||
+
 | 
			
		||||
+	/* "Regular" and 16 MBSS but not for 4 MBSS */
 | 
			
		||||
+	/* Update the phytxctl for the beacon based on the rspec */
 | 
			
		||||
+	brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
 | 
			
		||||
+
 | 
			
		||||
+	if (bcn0) {
 | 
			
		||||
+		/* write the probe response into the template region */
 | 
			
		||||
+		brcms_b_write_template_ram(wlc_hw, T_BCN0_TPL_BASE,
 | 
			
		||||
+					    (len + 3) & ~3, beacon->data);
 | 
			
		||||
+
 | 
			
		||||
+		/* write beacon length to SCR */
 | 
			
		||||
+		brcms_b_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len);
 | 
			
		||||
+	}
 | 
			
		||||
+	if (bcn1) {
 | 
			
		||||
+		/* write the probe response into the template region */
 | 
			
		||||
+		brcms_b_write_template_ram(wlc_hw, T_BCN1_TPL_BASE,
 | 
			
		||||
+					    (len + 3) & ~3, beacon->data);
 | 
			
		||||
+
 | 
			
		||||
+		/* write beacon length to SCR */
 | 
			
		||||
+		brcms_b_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	if (tim_offset != 0) {
 | 
			
		||||
+		brcms_b_write_shm(wlc_hw, M_TIMBPOS_INBEACON,
 | 
			
		||||
+				  tim_offset + D11B_PHY_HDR_LEN);
 | 
			
		||||
+		brcms_b_write_shm(wlc_hw, M_DOT11_DTIMPERIOD, dtim_period);
 | 
			
		||||
+	} else {
 | 
			
		||||
+		brcms_b_write_shm(wlc_hw, M_TIMBPOS_INBEACON,
 | 
			
		||||
+				  len + D11B_PHY_HDR_LEN);
 | 
			
		||||
+		brcms_b_write_shm(wlc_hw, M_DOT11_DTIMPERIOD, 0);
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void brcms_c_update_beacon_hw(struct brcms_c_info *wlc,
 | 
			
		||||
+				     struct sk_buff *beacon, u16 tim_offset,
 | 
			
		||||
+				     u16 dtim_period)
 | 
			
		||||
+{
 | 
			
		||||
+	struct brcms_hardware *wlc_hw = wlc->hw;
 | 
			
		||||
+	struct bcma_device *core = wlc_hw->d11core;
 | 
			
		||||
+
 | 
			
		||||
+	/* Hardware beaconing for this config */
 | 
			
		||||
+	u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD;
 | 
			
		||||
+
 | 
			
		||||
+	/* Check if both templates are in use, if so sched. an interrupt
 | 
			
		||||
+	 *      that will call back into this routine
 | 
			
		||||
+	 */
 | 
			
		||||
+	if ((bcma_read32(core, D11REGOFFS(maccommand)) & both_valid) == both_valid)
 | 
			
		||||
+		/* clear any previous status */
 | 
			
		||||
+		bcma_write32(core, D11REGOFFS(macintstatus), MI_BCNTPL);
 | 
			
		||||
+
 | 
			
		||||
+	if (wlc->beacon_template_virgin) {
 | 
			
		||||
+		wlc->beacon_template_virgin = false;
 | 
			
		||||
+		brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, true,
 | 
			
		||||
+				     true);
 | 
			
		||||
+		/* mark beacon0 valid */
 | 
			
		||||
+		bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN0VLD);
 | 
			
		||||
+		return;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	/* Check that after scheduling the interrupt both of the
 | 
			
		||||
+	 *      templates are still busy. if not clear the int. & remask
 | 
			
		||||
+	 */
 | 
			
		||||
+	if ((bcma_read32(core, D11REGOFFS(maccommand)) & both_valid) == both_valid) {
 | 
			
		||||
+		wlc->defmacintmask |= MI_BCNTPL;
 | 
			
		||||
+		return;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	if (!(bcma_read32(core, D11REGOFFS(maccommand)) & MCMD_BCN0VLD)) {
 | 
			
		||||
+		brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, true,
 | 
			
		||||
+				     false);
 | 
			
		||||
+		/* mark beacon0 valid */
 | 
			
		||||
+		bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN0VLD);
 | 
			
		||||
+		return;
 | 
			
		||||
+	}
 | 
			
		||||
+	if (!(bcma_read32(core, D11REGOFFS(maccommand)) & MCMD_BCN1VLD)) {
 | 
			
		||||
+		brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period,
 | 
			
		||||
+				     false, true);
 | 
			
		||||
+		/* mark beacon0 valid */
 | 
			
		||||
+		bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN1VLD);
 | 
			
		||||
+		return;
 | 
			
		||||
+	}
 | 
			
		||||
+	return;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /*
 | 
			
		||||
  * Update all beacons for the system.
 | 
			
		||||
  */
 | 
			
		||||
@@ -7387,9 +7495,31 @@ void brcms_c_update_beacon(struct brcms_
 | 
			
		||||
 	struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
 | 
			
		||||
 
 | 
			
		||||
 	if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
 | 
			
		||||
-			     bsscfg->type == BRCMS_TYPE_ADHOC))
 | 
			
		||||
+			     bsscfg->type == BRCMS_TYPE_ADHOC)) {
 | 
			
		||||
 		/* Clear the soft intmask */
 | 
			
		||||
 		wlc->defmacintmask &= ~MI_BCNTPL;
 | 
			
		||||
+		if (!wlc->beacon)
 | 
			
		||||
+			return;
 | 
			
		||||
+		brcms_c_update_beacon_hw(wlc, wlc->beacon,
 | 
			
		||||
+					 wlc->beacon_tim_offset,
 | 
			
		||||
+					 wlc->beacon_dtim_period);
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+void brcms_c_set_new_beacon(struct brcms_c_info *wlc, struct sk_buff *beacon,
 | 
			
		||||
+			    u16 tim_offset, u16 dtim_period)
 | 
			
		||||
+{
 | 
			
		||||
+	if (!beacon)
 | 
			
		||||
+		return;
 | 
			
		||||
+	if (wlc->beacon)
 | 
			
		||||
+		dev_kfree_skb_any(wlc->beacon);
 | 
			
		||||
+	wlc->beacon = beacon;
 | 
			
		||||
+
 | 
			
		||||
+	/* add PLCP */
 | 
			
		||||
+	skb_push(wlc->beacon, D11_PHY_HDR_LEN);
 | 
			
		||||
+	wlc->beacon_tim_offset = tim_offset;
 | 
			
		||||
+	wlc->beacon_dtim_period = dtim_period;
 | 
			
		||||
+	brcms_c_update_beacon(wlc);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 /* Write ssid into shared memory */
 | 
			
		||||
@@ -7788,6 +7918,10 @@ bool brcms_c_dpc(struct brcms_c_info *wl
 | 
			
		||||
 		brcms_rfkill_set_hw_state(wlc->wl);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	/* BCN template is available */
 | 
			
		||||
+	if (macintstatus & MI_BCNTPL)
 | 
			
		||||
+		brcms_c_update_beacon(wlc);
 | 
			
		||||
+
 | 
			
		||||
 	/* it isn't done and needs to be resched if macintstatus is non-zero */
 | 
			
		||||
 	return wlc->macintstatus != 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -7919,6 +8053,7 @@ brcms_c_attach(struct brcms_info *wl, st
 | 
			
		||||
 	pub->unit = unit;
 | 
			
		||||
 	pub->_piomode = piomode;
 | 
			
		||||
 	wlc->bandinit_pending = false;
 | 
			
		||||
+	wlc->beacon_template_virgin = true;
 | 
			
		||||
 
 | 
			
		||||
 	/* populate struct brcms_c_info with default values  */
 | 
			
		||||
 	brcms_c_info_init(wlc, unit);
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
@@ -492,6 +492,8 @@ struct brcms_c_info {
 | 
			
		||||
 	bool radio_monitor;
 | 
			
		||||
 	bool going_down;
 | 
			
		||||
 
 | 
			
		||||
+	bool beacon_template_virgin;
 | 
			
		||||
+
 | 
			
		||||
 	struct brcms_timer *wdtimer;
 | 
			
		||||
 	struct brcms_timer *radio_timer;
 | 
			
		||||
 
 | 
			
		||||
@@ -561,6 +563,10 @@ struct brcms_c_info {
 | 
			
		||||
 
 | 
			
		||||
 	struct wiphy *wiphy;
 | 
			
		||||
 	struct scb pri_scb;
 | 
			
		||||
+
 | 
			
		||||
+	struct sk_buff *beacon;
 | 
			
		||||
+	u16 beacon_tim_offset;
 | 
			
		||||
+	u16 beacon_dtim_period;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 /* antsel module specific state */
 | 
			
		||||
@@ -630,7 +636,6 @@ extern u16 brcms_c_compute_rtscts_dur(st
 | 
			
		||||
 extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
 | 
			
		||||
 			       struct ieee80211_sta *sta,
 | 
			
		||||
 			       void (*dma_callback_fn));
 | 
			
		||||
-extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
 | 
			
		||||
 extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend);
 | 
			
		||||
 extern int brcms_c_set_nmode(struct brcms_c_info *wlc);
 | 
			
		||||
 extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
@@ -332,5 +332,9 @@ extern bool brcms_c_check_radio_disabled
 | 
			
		||||
 extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
 | 
			
		||||
 extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc);
 | 
			
		||||
 extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr);
 | 
			
		||||
+extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
 | 
			
		||||
+extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
 | 
			
		||||
+				   struct sk_buff *beacon, u16 tim_offset,
 | 
			
		||||
+				   u16 dtim_period);
 | 
			
		||||
 
 | 
			
		||||
 #endif				/* _BRCM_PUB_H_ */
 | 
			
		||||
@@ -1,43 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
@@ -523,6 +523,12 @@ brcms_ops_bss_info_changed(struct ieee80
 | 
			
		||||
 		brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid);
 | 
			
		||||
 		spin_unlock_bh(&wl->lock);
 | 
			
		||||
 	}
 | 
			
		||||
+	if (changed & BSS_CHANGED_SSID) {
 | 
			
		||||
+		/* BSSID changed, for whatever reason (IBSS and managed mode) */
 | 
			
		||||
+		spin_lock_bh(&wl->lock);
 | 
			
		||||
+		brcms_c_set_ssid(wl->wlc, info->ssid, info->ssid_len);
 | 
			
		||||
+		spin_unlock_bh(&wl->lock);
 | 
			
		||||
+	}
 | 
			
		||||
 	if (changed & BSS_CHANGED_BEACON) {
 | 
			
		||||
 		/* Beacon data changed, retrieve new beacon (beaconing modes) */
 | 
			
		||||
 		struct sk_buff *beacon;
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -3785,6 +3785,15 @@ static void brcms_c_set_bssid(struct brc
 | 
			
		||||
 	brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, size_t ssid_len)
 | 
			
		||||
+{
 | 
			
		||||
+	u8 len = min_t(u8, sizeof(wlc->bsscfg->SSID), ssid_len);
 | 
			
		||||
+	memset(wlc->bsscfg->SSID, 0, sizeof(wlc->bsscfg->SSID));
 | 
			
		||||
+
 | 
			
		||||
+	memcpy(wlc->bsscfg->SSID, ssid, len);
 | 
			
		||||
+	wlc->bsscfg->SSID_len = len;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot)
 | 
			
		||||
 {
 | 
			
		||||
 	wlc_hw->shortslot = shortslot;
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
@@ -336,5 +336,7 @@ extern void brcms_c_update_beacon(struct
 | 
			
		||||
 extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
 | 
			
		||||
 				   struct sk_buff *beacon, u16 tim_offset,
 | 
			
		||||
 				   u16 dtim_period);
 | 
			
		||||
+extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid,
 | 
			
		||||
+			     size_t ssid_len);
 | 
			
		||||
 
 | 
			
		||||
 #endif				/* _BRCM_PUB_H_ */
 | 
			
		||||
@@ -1,216 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
@@ -541,6 +541,15 @@ brcms_ops_bss_info_changed(struct ieee80
 | 
			
		||||
 		spin_unlock_bh(&wl->lock);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	if (changed & BSS_CHANGED_AP_PROBE_RESP) {
 | 
			
		||||
+		struct sk_buff *probe_resp;
 | 
			
		||||
+
 | 
			
		||||
+		spin_lock_bh(&wl->lock);
 | 
			
		||||
+		probe_resp = ieee80211_proberesp_get(hw, vif);
 | 
			
		||||
+		brcms_c_set_new_probe_resp(wl->wlc, probe_resp);
 | 
			
		||||
+		spin_unlock_bh(&wl->lock);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	if (changed & BSS_CHANGED_BEACON_ENABLED) {
 | 
			
		||||
 		/* Beaconing should be enabled/disabled (beaconing modes) */
 | 
			
		||||
 		brcms_err(core, "%s: Beacon enabled: %s\n", __func__,
 | 
			
		||||
@@ -1039,6 +1048,8 @@ static int ieee_hw_init(struct ieee80211
 | 
			
		||||
 	hw->channel_change_time = 7 * 1000;
 | 
			
		||||
 	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
 | 
			
		||||
 
 | 
			
		||||
+	hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
 | 
			
		||||
+
 | 
			
		||||
 	hw->rate_control_algorithm = "minstrel_ht";
 | 
			
		||||
 
 | 
			
		||||
 	hw->sta_data_size = 0;
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -453,6 +453,8 @@ static void brcms_c_detach_mfree(struct 
 | 
			
		||||
 	kfree(wlc->hw);
 | 
			
		||||
 	if (wlc->beacon)
 | 
			
		||||
 		dev_kfree_skb_any(wlc->beacon);
 | 
			
		||||
+	if (wlc->probe_resp)
 | 
			
		||||
+		dev_kfree_skb_any(wlc->probe_resp);
 | 
			
		||||
 
 | 
			
		||||
 	/* free the wlc */
 | 
			
		||||
 	kfree(wlc);
 | 
			
		||||
@@ -7327,69 +7329,6 @@ brcms_c_mod_prb_rsp_rate_table(struct br
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-/*	Max buffering needed for beacon template/prb resp template is 142 bytes.
 | 
			
		||||
- *
 | 
			
		||||
- *	PLCP header is 6 bytes.
 | 
			
		||||
- *	802.11 A3 header is 24 bytes.
 | 
			
		||||
- *	Max beacon frame body template length is 112 bytes.
 | 
			
		||||
- *	Max probe resp frame body template length is 110 bytes.
 | 
			
		||||
- *
 | 
			
		||||
- *      *len on input contains the max length of the packet available.
 | 
			
		||||
- *
 | 
			
		||||
- *	The *len value is set to the number of bytes in buf used, and starts
 | 
			
		||||
- *	with the PLCP and included up to, but not including, the 4 byte FCS.
 | 
			
		||||
- */
 | 
			
		||||
-static void
 | 
			
		||||
-brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
 | 
			
		||||
-			 u32 bcn_rspec,
 | 
			
		||||
-			 struct brcms_bss_cfg *cfg, u16 *buf, int *len)
 | 
			
		||||
-{
 | 
			
		||||
-	static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
 | 
			
		||||
-	struct cck_phy_hdr *plcp;
 | 
			
		||||
-	struct ieee80211_mgmt *h;
 | 
			
		||||
-	int hdr_len, body_len;
 | 
			
		||||
-
 | 
			
		||||
-	hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
 | 
			
		||||
-
 | 
			
		||||
-	/* calc buffer size provided for frame body */
 | 
			
		||||
-	body_len = *len - hdr_len;
 | 
			
		||||
-	/* return actual size */
 | 
			
		||||
-	*len = hdr_len + body_len;
 | 
			
		||||
-
 | 
			
		||||
-	/* format PHY and MAC headers */
 | 
			
		||||
-	memset(buf, 0, hdr_len);
 | 
			
		||||
-
 | 
			
		||||
-	plcp = (struct cck_phy_hdr *) buf;
 | 
			
		||||
-
 | 
			
		||||
-	/*
 | 
			
		||||
-	 * PLCP for Probe Response frames are filled in from
 | 
			
		||||
-	 * core's rate table
 | 
			
		||||
-	 */
 | 
			
		||||
-	if (type == IEEE80211_STYPE_BEACON)
 | 
			
		||||
-		/* fill in PLCP */
 | 
			
		||||
-		brcms_c_compute_plcp(wlc, bcn_rspec,
 | 
			
		||||
-				 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
 | 
			
		||||
-				 (u8 *) plcp);
 | 
			
		||||
-
 | 
			
		||||
-	/* "Regular" and 16 MBSS but not for 4 MBSS */
 | 
			
		||||
-	/* Update the phytxctl for the beacon based on the rspec */
 | 
			
		||||
-	brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
 | 
			
		||||
-
 | 
			
		||||
-	h = (struct ieee80211_mgmt *)&plcp[1];
 | 
			
		||||
-
 | 
			
		||||
-	/* fill in 802.11 header */
 | 
			
		||||
-	h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
 | 
			
		||||
-
 | 
			
		||||
-	/* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
 | 
			
		||||
-	/* A1 filled in by MAC for prb resp, broadcast for bcn */
 | 
			
		||||
-	if (type == IEEE80211_STYPE_BEACON)
 | 
			
		||||
-		memcpy(&h->da, ðer_bcast, ETH_ALEN);
 | 
			
		||||
-	memcpy(&h->sa, &wlc->pub->cur_etheraddr, ETH_ALEN);
 | 
			
		||||
-	memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
 | 
			
		||||
-
 | 
			
		||||
-	/* SEQ filled in by MAC */
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
 int brcms_c_get_header_len(void)
 | 
			
		||||
 {
 | 
			
		||||
 	return TXOFF;
 | 
			
		||||
@@ -7531,6 +7470,20 @@ void brcms_c_set_new_beacon(struct brcms
 | 
			
		||||
 	brcms_c_update_beacon(wlc);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
 | 
			
		||||
+				struct sk_buff *probe_resp)
 | 
			
		||||
+{
 | 
			
		||||
+	if (!probe_resp)
 | 
			
		||||
+		return;
 | 
			
		||||
+	if (wlc->probe_resp)
 | 
			
		||||
+		dev_kfree_skb_any(wlc->probe_resp);
 | 
			
		||||
+	wlc->probe_resp = probe_resp;
 | 
			
		||||
+
 | 
			
		||||
+	/* add PLCP */
 | 
			
		||||
+	skb_push(wlc->probe_resp, D11_PHY_HDR_LEN);
 | 
			
		||||
+	brcms_c_update_probe_resp(wlc, false);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /* Write ssid into shared memory */
 | 
			
		||||
 static void
 | 
			
		||||
 brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
 | 
			
		||||
@@ -7550,30 +7503,19 @@ brcms_c_shm_ssid_upd(struct brcms_c_info
 | 
			
		||||
 static void
 | 
			
		||||
 brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
 | 
			
		||||
 			      struct brcms_bss_cfg *cfg,
 | 
			
		||||
+			      struct sk_buff *probe_resp,
 | 
			
		||||
 			      bool suspend)
 | 
			
		||||
 {
 | 
			
		||||
-	u16 *prb_resp;
 | 
			
		||||
-	int len = BCN_TMPL_LEN;
 | 
			
		||||
+	int len;
 | 
			
		||||
 
 | 
			
		||||
-	prb_resp = kmalloc(BCN_TMPL_LEN, GFP_ATOMIC);
 | 
			
		||||
-	if (!prb_resp)
 | 
			
		||||
-		return;
 | 
			
		||||
-
 | 
			
		||||
-	/*
 | 
			
		||||
-	 * write the probe response to hardware, or save in
 | 
			
		||||
-	 * the config structure
 | 
			
		||||
-	 */
 | 
			
		||||
-
 | 
			
		||||
-	/* create the probe response template */
 | 
			
		||||
-	brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
 | 
			
		||||
-				 cfg, prb_resp, &len);
 | 
			
		||||
+	len = min_t(size_t, probe_resp->len, BCN_TMPL_LEN);
 | 
			
		||||
 
 | 
			
		||||
 	if (suspend)
 | 
			
		||||
 		brcms_c_suspend_mac_and_wait(wlc);
 | 
			
		||||
 
 | 
			
		||||
 	/* write the probe response into the template region */
 | 
			
		||||
 	brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
 | 
			
		||||
-				    (len + 3) & ~3, prb_resp);
 | 
			
		||||
+				    (len + 3) & ~3, probe_resp->data);
 | 
			
		||||
 
 | 
			
		||||
 	/* write the length of the probe response frame (+PLCP/-FCS) */
 | 
			
		||||
 	brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len);
 | 
			
		||||
@@ -7587,13 +7529,11 @@ brcms_c_bss_update_probe_resp(struct brc
 | 
			
		||||
 	 * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
 | 
			
		||||
 	 * by subtracting the PLCP len and adding the FCS.
 | 
			
		||||
 	 */
 | 
			
		||||
-	len += (-D11_PHY_HDR_LEN + FCS_LEN);
 | 
			
		||||
-	brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
 | 
			
		||||
+	brcms_c_mod_prb_rsp_rate_table(wlc,
 | 
			
		||||
+				      (u16)len + FCS_LEN - D11_PHY_HDR_LEN);
 | 
			
		||||
 
 | 
			
		||||
 	if (suspend)
 | 
			
		||||
 		brcms_c_enable_mac(wlc);
 | 
			
		||||
-
 | 
			
		||||
-	kfree(prb_resp);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
 | 
			
		||||
@@ -7602,8 +7542,12 @@ void brcms_c_update_probe_resp(struct br
 | 
			
		||||
 
 | 
			
		||||
 	/* update AP or IBSS probe responses */
 | 
			
		||||
 	if (wlc->pub->up && (bsscfg->type == BRCMS_TYPE_AP ||
 | 
			
		||||
-			     bsscfg->type == BRCMS_TYPE_ADHOC))
 | 
			
		||||
-		brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
 | 
			
		||||
+			     bsscfg->type == BRCMS_TYPE_ADHOC)) {
 | 
			
		||||
+		if (!wlc->probe_resp)
 | 
			
		||||
+			return;
 | 
			
		||||
+		brcms_c_bss_update_probe_resp(wlc, bsscfg, wlc->probe_resp,
 | 
			
		||||
+					      suspend);
 | 
			
		||||
+	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
 | 
			
		||||
@@ -567,6 +567,7 @@ struct brcms_c_info {
 | 
			
		||||
 	struct sk_buff *beacon;
 | 
			
		||||
 	u16 beacon_tim_offset;
 | 
			
		||||
 	u16 beacon_dtim_period;
 | 
			
		||||
+	struct sk_buff *probe_resp;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 /* antsel module specific state */
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
@@ -336,6 +336,8 @@ extern void brcms_c_update_beacon(struct
 | 
			
		||||
 extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
 | 
			
		||||
 				   struct sk_buff *beacon, u16 tim_offset,
 | 
			
		||||
 				   u16 dtim_period);
 | 
			
		||||
+extern void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
 | 
			
		||||
+				       struct sk_buff *probe_resp);
 | 
			
		||||
 extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid,
 | 
			
		||||
 			     size_t ssid_len);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,59 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
@@ -554,6 +554,12 @@ brcms_ops_bss_info_changed(struct ieee80
 | 
			
		||||
 		/* Beaconing should be enabled/disabled (beaconing modes) */
 | 
			
		||||
 		brcms_err(core, "%s: Beacon enabled: %s\n", __func__,
 | 
			
		||||
 			  info->enable_beacon ? "true" : "false");
 | 
			
		||||
+		if (info->enable_beacon &&
 | 
			
		||||
+		    hw->wiphy->flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) {
 | 
			
		||||
+			brcms_c_enable_probe_resp(wl->wlc, true);
 | 
			
		||||
+		} else {
 | 
			
		||||
+			brcms_c_enable_probe_resp(wl->wlc, false);
 | 
			
		||||
+		}
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	if (changed & BSS_CHANGED_CQM) {
 | 
			
		||||
@@ -1048,7 +1054,12 @@ static int ieee_hw_init(struct ieee80211
 | 
			
		||||
 	hw->channel_change_time = 7 * 1000;
 | 
			
		||||
 	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
 | 
			
		||||
 
 | 
			
		||||
-	hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * deactivate sending probe responses by ucude, because this will
 | 
			
		||||
+	 * cause problems when WPS is used.
 | 
			
		||||
+	 *
 | 
			
		||||
+	 * hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
 | 
			
		||||
+	 */
 | 
			
		||||
 
 | 
			
		||||
 	hw->rate_control_algorithm = "minstrel_ht";
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -7484,6 +7484,17 @@ void brcms_c_set_new_probe_resp(struct b
 | 
			
		||||
 	brcms_c_update_probe_resp(wlc, false);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable)
 | 
			
		||||
+{
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * prevent ucode from sending probe responses by setting the timeout
 | 
			
		||||
+	 * to 1, it can not send it in that time frame.
 | 
			
		||||
+	 */
 | 
			
		||||
+	wlc->prb_resp_timeout = enable ? BRCMS_PRB_RESP_TIMEOUT : 1;
 | 
			
		||||
+	brcms_b_write_shm(wlc->hw, M_PRS_MAXTIME, wlc->prb_resp_timeout);
 | 
			
		||||
+	/* TODO: if (enable) => also deactivate receiving of probe request */
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /* Write ssid into shared memory */
 | 
			
		||||
 static void
 | 
			
		||||
 brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
@@ -338,6 +338,7 @@ extern void brcms_c_set_new_beacon(struc
 | 
			
		||||
 				   u16 dtim_period);
 | 
			
		||||
 extern void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
 | 
			
		||||
 				       struct sk_buff *probe_resp);
 | 
			
		||||
+extern void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable);
 | 
			
		||||
 extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid,
 | 
			
		||||
 			     size_t ssid_len);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
@@ -359,10 +359,11 @@ brcms_ops_add_interface(struct ieee80211
 | 
			
		||||
 {
 | 
			
		||||
 	struct brcms_info *wl = hw->priv;
 | 
			
		||||
 
 | 
			
		||||
-	/* Just STA for now */
 | 
			
		||||
-	if (vif->type != NL80211_IFTYPE_STATION) {
 | 
			
		||||
+	/* Just STA and AP for now */
 | 
			
		||||
+	if (vif->type != NL80211_IFTYPE_STATION &&
 | 
			
		||||
+	    vif->type != NL80211_IFTYPE_AP) {
 | 
			
		||||
 		brcms_err(wl->wlc->hw->d11core,
 | 
			
		||||
-			  "%s: Attempt to add type %d, only STA for now\n",
 | 
			
		||||
+			  "%s: Attempt to add type %d, only STA and AP for now\n",
 | 
			
		||||
 			  __func__, vif->type);
 | 
			
		||||
 		return -EOPNOTSUPP;
 | 
			
		||||
 	}
 | 
			
		||||
@@ -372,6 +373,9 @@ brcms_ops_add_interface(struct ieee80211
 | 
			
		||||
 	brcms_c_mute(wl->wlc, false);
 | 
			
		||||
 	if (vif->type == NL80211_IFTYPE_STATION)
 | 
			
		||||
 		brcms_c_start_station(wl->wlc, vif->addr);
 | 
			
		||||
+	else if (vif->type == NL80211_IFTYPE_AP)
 | 
			
		||||
+		brcms_c_start_ap(wl->wlc, vif->addr, vif->bss_conf.bssid,
 | 
			
		||||
+				 vif->bss_conf.ssid, vif->bss_conf.ssid_len);
 | 
			
		||||
 	spin_unlock_bh(&wl->lock);
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
@@ -1052,7 +1056,8 @@ static int ieee_hw_init(struct ieee80211
 | 
			
		||||
 
 | 
			
		||||
 	/* channel change time is dependent on chip and band  */
 | 
			
		||||
 	hw->channel_change_time = 7 * 1000;
 | 
			
		||||
-	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
 | 
			
		||||
+	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
 | 
			
		||||
+				     BIT(NL80211_IFTYPE_AP);
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * deactivate sending probe responses by ucude, because this will
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -2176,6 +2176,18 @@ void brcms_c_start_station(struct brcms_
 | 
			
		||||
 	wlc->bsscfg->type = BRCMS_TYPE_STATION;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr, const u8 *bssid,
 | 
			
		||||
+		      u8 *ssid, size_t ssid_len)
 | 
			
		||||
+{
 | 
			
		||||
+	brcms_c_set_ssid(wlc, ssid, ssid_len);
 | 
			
		||||
+
 | 
			
		||||
+	memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr));
 | 
			
		||||
+	memcpy(wlc->bsscfg->BSSID, bssid, sizeof(wlc->bsscfg->BSSID));
 | 
			
		||||
+	wlc->bsscfg->type = BRCMS_TYPE_AP;
 | 
			
		||||
+
 | 
			
		||||
+	brcms_b_mctrl(wlc->hw, MCTL_AP | MCTL_INFRA, MCTL_AP | MCTL_INFRA);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /* Initialize GPIOs that are controlled by D11 core */
 | 
			
		||||
 static void brcms_c_gpio_init(struct brcms_c_info *wlc)
 | 
			
		||||
 {
 | 
			
		||||
@@ -3064,6 +3076,9 @@ static bool brcms_c_ps_allowed(struct br
 | 
			
		||||
 	if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
 | 
			
		||||
 		return false;
 | 
			
		||||
 
 | 
			
		||||
+	if (wlc->bsscfg->type == BRCMS_TYPE_AP)
 | 
			
		||||
+		return false;
 | 
			
		||||
+
 | 
			
		||||
 	return true;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
@@ -332,6 +332,8 @@ extern bool brcms_c_check_radio_disabled
 | 
			
		||||
 extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
 | 
			
		||||
 extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc);
 | 
			
		||||
 extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr);
 | 
			
		||||
+extern void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr,
 | 
			
		||||
+			     const u8 *bssid, u8 *ssid, size_t ssid_len);
 | 
			
		||||
 extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
 | 
			
		||||
 extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
 | 
			
		||||
 				   struct sk_buff *beacon, u16 tim_offset,
 | 
			
		||||
@@ -1,74 +0,0 @@
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
 | 
			
		||||
@@ -359,11 +359,12 @@ brcms_ops_add_interface(struct ieee80211
 | 
			
		||||
 {
 | 
			
		||||
 	struct brcms_info *wl = hw->priv;
 | 
			
		||||
 
 | 
			
		||||
-	/* Just STA and AP for now */
 | 
			
		||||
+	/* Just STA, AP and ADHOC for now */
 | 
			
		||||
 	if (vif->type != NL80211_IFTYPE_STATION &&
 | 
			
		||||
-	    vif->type != NL80211_IFTYPE_AP) {
 | 
			
		||||
+	    vif->type != NL80211_IFTYPE_AP &&
 | 
			
		||||
+	    vif->type != NL80211_IFTYPE_ADHOC) {
 | 
			
		||||
 		brcms_err(wl->wlc->hw->d11core,
 | 
			
		||||
-			  "%s: Attempt to add type %d, only STA and AP for now\n",
 | 
			
		||||
+			  "%s: Attempt to add type %d, only STA, AP and AdHoc for now\n",
 | 
			
		||||
 			  __func__, vif->type);
 | 
			
		||||
 		return -EOPNOTSUPP;
 | 
			
		||||
 	}
 | 
			
		||||
@@ -376,6 +377,8 @@ brcms_ops_add_interface(struct ieee80211
 | 
			
		||||
 	else if (vif->type == NL80211_IFTYPE_AP)
 | 
			
		||||
 		brcms_c_start_ap(wl->wlc, vif->addr, vif->bss_conf.bssid,
 | 
			
		||||
 				 vif->bss_conf.ssid, vif->bss_conf.ssid_len);
 | 
			
		||||
+	else if (vif->type == NL80211_IFTYPE_ADHOC)
 | 
			
		||||
+		brcms_c_start_adhoc(wl->wlc, vif->addr);
 | 
			
		||||
 	spin_unlock_bh(&wl->lock);
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
@@ -1057,7 +1060,8 @@ static int ieee_hw_init(struct ieee80211
 | 
			
		||||
 	/* channel change time is dependent on chip and band  */
 | 
			
		||||
 	hw->channel_change_time = 7 * 1000;
 | 
			
		||||
 	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
 | 
			
		||||
-				     BIT(NL80211_IFTYPE_AP);
 | 
			
		||||
+				     BIT(NL80211_IFTYPE_AP) |
 | 
			
		||||
+				     BIT(NL80211_IFTYPE_ADHOC);
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * deactivate sending probe responses by ucude, because this will
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
 | 
			
		||||
@@ -2188,6 +2188,14 @@ void brcms_c_start_ap(struct brcms_c_inf
 | 
			
		||||
 	brcms_b_mctrl(wlc->hw, MCTL_AP | MCTL_INFRA, MCTL_AP | MCTL_INFRA);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr)
 | 
			
		||||
+{
 | 
			
		||||
+	memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr));
 | 
			
		||||
+	wlc->bsscfg->type = BRCMS_TYPE_ADHOC;
 | 
			
		||||
+
 | 
			
		||||
+	brcms_b_mctrl(wlc->hw, MCTL_AP | MCTL_INFRA, 0);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /* Initialize GPIOs that are controlled by D11 core */
 | 
			
		||||
 static void brcms_c_gpio_init(struct brcms_c_info *wlc)
 | 
			
		||||
 {
 | 
			
		||||
@@ -3079,6 +3087,9 @@ static bool brcms_c_ps_allowed(struct br
 | 
			
		||||
 	if (wlc->bsscfg->type == BRCMS_TYPE_AP)
 | 
			
		||||
 		return false;
 | 
			
		||||
 
 | 
			
		||||
+	if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC)
 | 
			
		||||
+		return false;
 | 
			
		||||
+
 | 
			
		||||
 	return true;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
 | 
			
		||||
@@ -334,6 +334,7 @@ extern bool brcms_c_tx_flush_completed(s
 | 
			
		||||
 extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr);
 | 
			
		||||
 extern void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr,
 | 
			
		||||
 			     const u8 *bssid, u8 *ssid, size_t ssid_len);
 | 
			
		||||
+extern void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr);
 | 
			
		||||
 extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
 | 
			
		||||
 extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
 | 
			
		||||
 				   struct sk_buff *beacon, u16 tim_offset,
 | 
			
		||||
		Reference in New Issue
	
	Block a user