diff --git a/patches/openwrt/0019-Backport-hostapd-and-mac80211-from-Barrier-Breaker.patch b/patches/openwrt/0019-Backport-hostapd-and-mac80211-from-Barrier-Breaker.patch
new file mode 100644
index 0000000000000000000000000000000000000000..fd103ad0d03763c06aa4235515563b9b3b0f8945
--- /dev/null
+++ b/patches/openwrt/0019-Backport-hostapd-and-mac80211-from-Barrier-Breaker.patch
@@ -0,0 +1,13412 @@
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Mon, 28 Apr 2014 21:44:58 +0200
+Subject: Backport hostapd and mac80211 from Barrier Breaker
+
+diff --git a/package/hostapd/Makefile b/package/hostapd/Makefile
+index b4dc242..ecf9e4b 100644
+--- a/package/hostapd/Makefile
++++ b/package/hostapd/Makefile
+@@ -8,9 +8,9 @@
+ include $(TOPDIR)/rules.mk
+ 
+ PKG_NAME:=hostapd
+-PKG_VERSION:=20131120
++PKG_VERSION:=2014-04-24
+ PKG_RELEASE:=1
+-PKG_REV:=594516b4c28a94ca686b17f1e463dfd6712b75a7
++PKG_REV:=3cf48c4f2e2d558130253457fea02ef4047cf8e1
+ 
+ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+ PKG_SOURCE_URL:=git://w1.fi/srv/git/hostap.git
+diff --git a/package/hostapd/patches/100-madwifi_key_fixes.patch b/package/hostapd/patches/100-madwifi_key_fixes.patch
+index dcd6d10..a46943b 100644
+--- a/package/hostapd/patches/100-madwifi_key_fixes.patch
++++ b/package/hostapd/patches/100-madwifi_key_fixes.patch
+@@ -1,6 +1,6 @@
+ --- a/src/drivers/driver_madwifi.c
+ +++ b/src/drivers/driver_madwifi.c
+-@@ -450,7 +450,9 @@ wpa_driver_madwifi_set_key(const char *i
++@@ -449,7 +449,9 @@ wpa_driver_madwifi_set_key(const char *i
+  
+  	memset(&wk, 0, sizeof(wk));
+  	wk.ik_type = cipher;
+@@ -11,7 +11,7 @@
+  	if (addr == NULL || is_broadcast_ether_addr(addr)) {
+  		memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
+  		wk.ik_keyix = key_idx;
+-@@ -462,6 +464,20 @@ wpa_driver_madwifi_set_key(const char *i
++@@ -461,6 +463,20 @@ wpa_driver_madwifi_set_key(const char *i
+  	wk.ik_keylen = key_len;
+  	memcpy(wk.ik_keydata, key, key_len);
+  
+diff --git a/package/hostapd/patches/110-bool_fix.patch b/package/hostapd/patches/110-bool_fix.patch
+index 9f82b0b..1ad84bf 100644
+--- a/package/hostapd/patches/110-bool_fix.patch
++++ b/package/hostapd/patches/110-bool_fix.patch
+@@ -1,6 +1,6 @@
+ --- a/src/ap/ieee802_1x.c
+ +++ b/src/ap/ieee802_1x.c
+-@@ -1933,9 +1933,9 @@ void ieee802_1x_notify_pre_auth(struct e
++@@ -2119,9 +2119,9 @@ void ieee802_1x_notify_pre_auth(struct e
+  }
+  
+  
+diff --git a/package/hostapd/patches/130-wds_sta_del_fix.patch b/package/hostapd/patches/130-wds_sta_del_fix.patch
+deleted file mode 100644
+index 06b6906..0000000
+--- a/package/hostapd/patches/130-wds_sta_del_fix.patch
++++ /dev/null
+@@ -1,13 +0,0 @@
+---- a/src/drivers/driver_nl80211.c
+-+++ b/src/drivers/driver_nl80211.c
+-@@ -9083,8 +9083,8 @@ static int i802_set_wds_sta(void *priv, 
+- 					name);
+- 
+- 		i802_set_sta_vlan(priv, addr, bss->ifname, 0);
+--		return wpa_driver_nl80211_if_remove(priv, WPA_IF_AP_VLAN,
+--						    name);
+-+		nl80211_remove_iface(drv, if_nametoindex(name));
+-+		return 0;
+- 	}
+- }
+- 
+diff --git a/package/hostapd/patches/200-multicall.patch b/package/hostapd/patches/200-multicall.patch
+index 2289f51..1511b19 100644
+--- a/package/hostapd/patches/200-multicall.patch
++++ b/package/hostapd/patches/200-multicall.patch
+@@ -1,14 +1,14 @@
+ --- a/hostapd/Makefile
+ +++ b/hostapd/Makefile
+-@@ -14,6 +14,7 @@ CFLAGS += -I../src/utils
++@@ -14,6 +14,7 @@ CFLAGS += -I$(abspath ../src/utils)
+  # CFLAGS += -DUSE_KERNEL_HEADERS -I/usr/src/linux/include
+  
+  -include .config
+ +-include $(if $(MULTICALL), ../wpa_supplicant/.config)
+  
+- ifndef CONFIG_OS
+- ifdef CONFIG_NATIVE_WINDOWS
+-@@ -200,10 +201,14 @@ ifdef CONFIG_IEEE80211AC
++ ifdef CONFIG_TESTING_OPTIONS
++ CFLAGS += -DCONFIG_TESTING_OPTIONS
++@@ -223,10 +224,14 @@ ifdef CONFIG_IEEE80211AC
+  CFLAGS += -DCONFIG_IEEE80211AC
+  endif
+  
+@@ -26,7 +26,7 @@
+  LIBS += $(DRV_AP_LIBS)
+  
+  ifdef CONFIG_L2_PACKET
+-@@ -890,6 +895,12 @@ install: all
++@@ -913,6 +918,12 @@ install: all
+  
+  BCHECK=../src/drivers/build.hostapd
+  
+@@ -39,7 +39,7 @@
+  hostapd: $(BCHECK) $(OBJS)
+  	$(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
+  	@$(E) "  LD " $@
+-@@ -928,6 +939,12 @@ HOBJS += ../src/crypto/aes-internal.o
++@@ -951,6 +962,12 @@ HOBJS += ../src/crypto/aes-internal.o
+  HOBJS += ../src/crypto/aes-internal-enc.o
+  endif
+  
+@@ -54,15 +54,15 @@
+  	@$(E) "  LD " $@
+ --- a/wpa_supplicant/Makefile
+ +++ b/wpa_supplicant/Makefile
+-@@ -14,6 +14,7 @@ CFLAGS += -I../src
+- CFLAGS += -I../src/utils
++@@ -14,6 +14,7 @@ CFLAGS += -I$(abspath ../src)
++ CFLAGS += -I$(abspath ../src/utils)
+  
+  -include .config
+ +-include $(if $(MULTICALL),../hostapd/.config)
+  
+- BINALL=wpa_supplicant wpa_cli
+- 
+-@@ -727,6 +728,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS
++ ifdef CONFIG_TESTING_OPTIONS
++ CFLAGS += -DCONFIG_TESTING_OPTIONS
++@@ -746,6 +747,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS
+  CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS
+  LIBS += -ldl -rdynamic
+  endif
+@@ -73,7 +73,7 @@
+  endif
+  
+  ifdef CONFIG_AP
+-@@ -735,9 +740,11 @@ NEED_EAP_COMMON=y
++@@ -754,9 +759,11 @@ NEED_EAP_COMMON=y
+  NEED_RSN_AUTHENTICATOR=y
+  CFLAGS += -DCONFIG_AP
+  OBJS += ap.o
+@@ -85,7 +85,7 @@
+  OBJS += ../src/ap/hostapd.o
+  OBJS += ../src/ap/wpa_auth_glue.o
+  OBJS += ../src/ap/utils.o
+-@@ -799,10 +806,18 @@ endif
++@@ -818,10 +825,18 @@ endif
+  ifdef CONFIG_HS20
+  OBJS += ../src/ap/hs20.o
+  endif
+@@ -104,7 +104,7 @@
+  NEED_AES_WRAP=y
+  OBJS += ../src/ap/wpa_auth.o
+  OBJS += ../src/ap/wpa_auth_ie.o
+-@@ -1551,6 +1566,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
++@@ -1584,6 +1599,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
+  
+  $(OBJS_c) $(OBJS_t) $(OBJS_t2) $(OBJS) $(BCHECK) $(EXTRA_progs): .config
+  
+@@ -117,7 +117,7 @@
+  wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
+  	$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS)
+  	@$(E) "  LD " $@
+-@@ -1625,6 +1646,12 @@ eap_eke.so: ../src/eap_peer/eap_eke.c ..
++@@ -1664,6 +1685,12 @@ endif
+  %@.service: %.service.arg.in
+  	sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
+  
+@@ -132,7 +132,7 @@
+  wpa_cli.exe: wpa_cli
+ --- a/src/drivers/driver.h
+ +++ b/src/drivers/driver.h
+-@@ -4079,8 +4079,8 @@ union wpa_event_data {
++@@ -3886,8 +3886,8 @@ union wpa_event_data {
+   * Driver wrapper code should call this function whenever an event is received
+   * from the driver.
+   */
+@@ -145,7 +145,7 @@
+  /*
+ --- a/src/ap/drv_callbacks.c
+ +++ b/src/ap/drv_callbacks.c
+-@@ -844,8 +844,8 @@ static void hostapd_event_dfs_nop_finish
++@@ -906,8 +906,8 @@ static void hostapd_event_dfs_nop_finish
+  #endif /* NEED_AP_MLME */
+  
+  
+@@ -158,7 +158,7 @@
+  #ifndef CONFIG_NO_STDOUT_DEBUG
+ --- a/wpa_supplicant/wpa_priv.c
+ +++ b/wpa_supplicant/wpa_priv.c
+-@@ -817,8 +817,8 @@ static void wpa_priv_send_ft_response(st
++@@ -815,8 +815,8 @@ static void wpa_priv_send_ft_response(st
+  }
+  
+  
+@@ -169,7 +169,7 @@
+  {
+  	struct wpa_priv_interface *iface = ctx;
+  
+-@@ -960,6 +960,7 @@ int main(int argc, char *argv[])
++@@ -956,6 +956,7 @@ int main(int argc, char *argv[])
+  	if (os_program_init())
+  		return -1;
+  
+@@ -179,7 +179,7 @@
+  	for (;;) {
+ --- a/wpa_supplicant/events.c
+ +++ b/wpa_supplicant/events.c
+-@@ -2710,8 +2710,8 @@ static void wpa_supplicant_update_channe
++@@ -2929,8 +2929,8 @@ static void wpa_supplicant_notify_avoid_
+  }
+  
+  
+@@ -192,7 +192,7 @@
+  
+ --- a/wpa_supplicant/wpa_supplicant.c
+ +++ b/wpa_supplicant/wpa_supplicant.c
+-@@ -3138,6 +3138,9 @@ static void wpa_supplicant_deinit_iface(
++@@ -3724,6 +3724,9 @@ static void wpa_supplicant_deinit_iface(
+  	os_free(wpa_s);
+  }
+  
+@@ -202,7 +202,7 @@
+  
+  /**
+   * wpa_supplicant_add_iface - Add a new network interface
+-@@ -3329,6 +3332,7 @@ struct wpa_global * wpa_supplicant_init(
++@@ -3915,6 +3918,7 @@ struct wpa_global * wpa_supplicant_init(
+  	wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
+  #endif /* CONFIG_NO_WPA_MSG */
+  
+@@ -212,7 +212,7 @@
+  		wpa_debug_open_syslog();
+ --- a/hostapd/main.c
+ +++ b/hostapd/main.c
+-@@ -511,6 +511,9 @@ static int hostapd_get_ctrl_iface_group(
++@@ -502,6 +502,9 @@ static int hostapd_get_ctrl_iface_group(
+  	return 0;
+  }
+  
+@@ -220,27 +220,25 @@
+ +                       union wpa_event_data *data);
+ +
+  
+- int main(int argc, char *argv[])
+- {
+-@@ -541,6 +544,7 @@ int main(int argc, char *argv[])
++ #ifdef CONFIG_WPS
++ static int gen_uuid(const char *txt_addr)
++@@ -553,6 +556,7 @@ int main(int argc, char *argv[])
+  	interfaces.global_iface_name = NULL;
+  	interfaces.global_ctrl_sock = -1;
+  
+ +	wpa_supplicant_event = hostapd_wpa_event;
+  	for (;;) {
+- 		c = getopt(argc, argv, "b:Bde:f:hKP:Ttvg:G:");
++ 		c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:vg:G:");
+  		if (c < 0)
+ --- a/src/drivers/drivers.c
+ +++ b/src/drivers/drivers.c
+-@@ -7,7 +7,11 @@
+-  */
+- 
+- #include "includes.h"
+-+#include "common.h"
+-+#include "driver.h"
++@@ -10,6 +10,9 @@
++ #include "utils/common.h"
++ #include "driver.h"
+  
+ +void (*wpa_supplicant_event)(void *ctx, enum wpa_event_type event,
+ +			     union wpa_event_data *data);
+- 
+++
+  #ifdef CONFIG_DRIVER_WEXT
+  extern struct wpa_driver_ops wpa_driver_wext_ops; /* driver_wext.c */
++ #endif /* CONFIG_DRIVER_WEXT */
+diff --git a/package/hostapd/patches/300-noscan.patch b/package/hostapd/patches/300-noscan.patch
+index 17e7661..50b70b7 100644
+--- a/package/hostapd/patches/300-noscan.patch
++++ b/package/hostapd/patches/300-noscan.patch
+@@ -1,17 +1,17 @@
+ --- a/hostapd/config_file.c
+ +++ b/hostapd/config_file.c
+-@@ -2412,6 +2412,8 @@ static int hostapd_config_fill(struct ho
+- 			}
++@@ -2638,6 +2638,8 @@ static int hostapd_config_fill(struct ho
++ 		}
+  #endif /* CONFIG_IEEE80211W */
+  #ifdef CONFIG_IEEE80211N
+-+		} else if (os_strcmp(buf, "noscan") == 0) {
+-+			conf->noscan = atoi(pos);
+- 		} else if (os_strcmp(buf, "ieee80211n") == 0) {
+- 			conf->ieee80211n = atoi(pos);
+- 		} else if (os_strcmp(buf, "ht_capab") == 0) {
+++	} else if (os_strcmp(buf, "noscan") == 0) {
+++		conf->noscan = atoi(pos);
++ 	} else if (os_strcmp(buf, "ieee80211n") == 0) {
++ 		conf->ieee80211n = atoi(pos);
++ 	} else if (os_strcmp(buf, "ht_capab") == 0) {
+ --- a/src/ap/ap_config.h
+ +++ b/src/ap/ap_config.h
+-@@ -527,6 +527,7 @@ struct hostapd_config {
++@@ -576,6 +576,7 @@ struct hostapd_config {
+  
+  	int ht_op_mode_fixed;
+  	u16 ht_capab;
+@@ -21,7 +21,7 @@
+  	int require_ht;
+ --- a/src/ap/hw_features.c
+ +++ b/src/ap/hw_features.c
+-@@ -577,7 +577,7 @@ static int ieee80211n_check_40mhz(struct
++@@ -574,7 +574,7 @@ static int ieee80211n_check_40mhz(struct
+  {
+  	struct wpa_driver_scan_params params;
+  
+diff --git a/package/hostapd/patches/310-rescan_immediately.patch b/package/hostapd/patches/310-rescan_immediately.patch
+index 043f07c..f96c7e6 100644
+--- a/package/hostapd/patches/310-rescan_immediately.patch
++++ b/package/hostapd/patches/310-rescan_immediately.patch
+@@ -1,6 +1,6 @@
+ --- a/wpa_supplicant/wpa_supplicant.c
+ +++ b/wpa_supplicant/wpa_supplicant.c
+-@@ -2488,7 +2488,7 @@ static struct wpa_supplicant * wpa_suppl
++@@ -2746,7 +2746,7 @@ static struct wpa_supplicant * wpa_suppl
+  	if (wpa_s == NULL)
+  		return NULL;
+  	wpa_s->scan_req = INITIAL_SCAN_REQ;
+diff --git a/package/hostapd/patches/320-optional_rfkill.patch b/package/hostapd/patches/320-optional_rfkill.patch
+index 7ec51b1..b0ea38f 100644
+--- a/package/hostapd/patches/320-optional_rfkill.patch
++++ b/package/hostapd/patches/320-optional_rfkill.patch
+@@ -1,218 +1,3 @@
+---- a/src/drivers/driver_nl80211.c
+-+++ b/src/drivers/driver_nl80211.c
+-@@ -254,7 +254,9 @@ struct wpa_driver_nl80211_data {
+- 	int if_removed;
+- 	int if_disabled;
+- 	int ignore_if_down_event;
+-+#ifdef CONFIG_RFKILL
+- 	struct rfkill_data *rfkill;
+-+#endif
+- 	struct wpa_driver_capa capa;
+- 	u8 *extended_capa, *extended_capa_mask;
+- 	unsigned int extended_capa_len;
+-@@ -3630,7 +3632,7 @@ static int wpa_driver_nl80211_init_nl(st
+- 	return 0;
+- }
+- 
+--
+-+#ifdef CONFIG_RFKILL
+- static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
+- {
+- 	wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
+-@@ -3652,6 +3654,7 @@ static void wpa_driver_nl80211_rfkill_un
+- 	}
+- 	/* rtnetlink ifup handler will report interface as enabled */
+- }
+-+#endif /* CONFIG_RFKILL */
+- 
+- 
+- static void wpa_driver_nl80211_handle_eapol_tx_status(int sock,
+-@@ -3740,7 +3743,9 @@ static void * wpa_driver_nl80211_drv_ini
+- 					  const u8 *set_addr)
+- {
+- 	struct wpa_driver_nl80211_data *drv;
+-+#ifdef CONFIG_RFKILL
+- 	struct rfkill_config *rcfg;
+-+#endif
+- 	struct i802_bss *bss;
+- 
+- 	if (global_priv == NULL)
+-@@ -3778,6 +3783,7 @@ static void * wpa_driver_nl80211_drv_ini
+- 	if (nl80211_init_bss(bss))
+- 		goto failed;
+- 
+-+#ifdef CONFIG_RFKILL
+- 	rcfg = os_zalloc(sizeof(*rcfg));
+- 	if (rcfg == NULL)
+- 		goto failed;
+-@@ -3790,6 +3796,7 @@ static void * wpa_driver_nl80211_drv_ini
+- 		wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available");
+- 		os_free(rcfg);
+- 	}
+-+#endif /* CONFIG_RFKILL */
+- 
+- 	if (linux_iface_up(drv->global->ioctl_sock, ifname) > 0)
+- 		drv->start_iface_up = 1;
+-@@ -4116,10 +4123,12 @@ static void nl80211_mgmt_unsubscribe(str
+- }
+- 
+- 
+-+#ifdef CONFIG_RFKILL
+- static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx, void *timeout_ctx)
+- {
+- 	wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL);
+- }
+-+#endif /* CONFIG_RFKILL */
+- 
+- 
+- static void nl80211_del_p2pdev(struct i802_bss *bss)
+-@@ -4246,13 +4255,16 @@ wpa_driver_nl80211_finish_drv_init(struc
+- 	}
+- 
+- 	if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1)) {
+-+#ifdef CONFIG_RFKILL
+- 		if (rfkill_is_blocked(drv->rfkill)) {
+- 			wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
+- 				   "interface '%s' due to rfkill",
+- 				   bss->ifname);
+- 			drv->if_disabled = 1;
+- 			send_rfkill_event = 1;
+--		} else {
+-+		} else
+-+#endif
+-+		{
+- 			wpa_printf(MSG_ERROR, "nl80211: Could not set "
+- 				   "interface '%s' UP", bss->ifname);
+- 			return -1;
+-@@ -4268,8 +4280,10 @@ wpa_driver_nl80211_finish_drv_init(struc
+- 		return -1;
+- 
+- 	if (send_rfkill_event) {
+-+#ifdef CONFIG_RFKILL
+- 		eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill,
+- 				       drv, drv->ctx);
+-+#endif
+- 	}
+- 
+- 	return 0;
+-@@ -4347,7 +4361,9 @@ static void wpa_driver_nl80211_deinit(st
+- 
+- 	netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0,
+- 			       IF_OPER_UP);
+-+#ifdef CONFIG_RFKILL
+- 	rfkill_deinit(drv->rfkill);
+-+#endif
+- 
+- 	eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
+- 
+---- a/src/drivers/driver_wext.c
+-+++ b/src/drivers/driver_wext.c
+-@@ -740,7 +740,7 @@ static void wpa_driver_wext_event_rtm_de
+- 	}
+- }
+- 
+--
+-+#ifdef CONFIG_RFKILL
+- static void wpa_driver_wext_rfkill_blocked(void *ctx)
+- {
+- 	wpa_printf(MSG_DEBUG, "WEXT: RFKILL blocked");
+-@@ -762,7 +762,7 @@ static void wpa_driver_wext_rfkill_unblo
+- 	}
+- 	/* rtnetlink ifup handler will report interface as enabled */
+- }
+--
+-+#endif /* CONFIG_RFKILL */
+- 
+- static void wext_get_phy_name(struct wpa_driver_wext_data *drv)
+- {
+-@@ -808,7 +808,9 @@ void * wpa_driver_wext_init(void *ctx, c
+- {
+- 	struct wpa_driver_wext_data *drv;
+- 	struct netlink_config *cfg;
+-+#ifdef CONFIG_RFKILL
+- 	struct rfkill_config *rcfg;
+-+#endif
+- 	char path[128];
+- 	struct stat buf;
+- 
+-@@ -843,6 +845,7 @@ void * wpa_driver_wext_init(void *ctx, c
+- 		goto err2;
+- 	}
+- 
+-+#ifdef CONFIG_RFKILL
+- 	rcfg = os_zalloc(sizeof(*rcfg));
+- 	if (rcfg == NULL)
+- 		goto err3;
+-@@ -855,6 +858,7 @@ void * wpa_driver_wext_init(void *ctx, c
+- 		wpa_printf(MSG_DEBUG, "WEXT: RFKILL status not available");
+- 		os_free(rcfg);
+- 	}
+-+#endif /* CONFIG_RFKILL */
+- 
+- 	drv->mlme_sock = -1;
+- 
+-@@ -872,7 +876,9 @@ void * wpa_driver_wext_init(void *ctx, c
+- 	return drv;
+- 
+- err3:
+-+#ifdef CONFIG_RFKILL
+- 	rfkill_deinit(drv->rfkill);
+-+#endif
+- 	netlink_deinit(drv->netlink);
+- err2:
+- 	close(drv->ioctl_sock);
+-@@ -882,10 +888,12 @@ err1:
+- }
+- 
+- 
+-+#ifdef CONFIG_RFKILL
+- static void wpa_driver_wext_send_rfkill(void *eloop_ctx, void *timeout_ctx)
+- {
+- 	wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL);
+- }
+-+#endif /* CONFIG_RFKILL */
+- 
+- 
+- static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
+-@@ -893,13 +901,16 @@ static int wpa_driver_wext_finish_drv_in
+- 	int send_rfkill_event = 0;
+- 
+- 	if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1) < 0) {
+-+#ifdef CONFIG_RFKILL
+- 		if (rfkill_is_blocked(drv->rfkill)) {
+- 			wpa_printf(MSG_DEBUG, "WEXT: Could not yet enable "
+- 				   "interface '%s' due to rfkill",
+- 				   drv->ifname);
+- 			drv->if_disabled = 1;
+- 			send_rfkill_event = 1;
+--		} else {
+-+		} else
+-+#endif
+-+		{
+- 			wpa_printf(MSG_ERROR, "WEXT: Could not set "
+- 				   "interface '%s' UP", drv->ifname);
+- 			return -1;
+-@@ -947,8 +958,10 @@ static int wpa_driver_wext_finish_drv_in
+- 			       1, IF_OPER_DORMANT);
+- 
+- 	if (send_rfkill_event) {
+-+#ifdef CONFIG_RFKILL
+- 		eloop_register_timeout(0, 0, wpa_driver_wext_send_rfkill,
+- 				       drv, drv->ctx);
+-+#endif
+- 	}
+- 
+- 	return 0;
+-@@ -978,7 +991,9 @@ void wpa_driver_wext_deinit(void *priv)
+- 
+- 	netlink_send_oper_ifla(drv->netlink, drv->ifindex, 0, IF_OPER_UP);
+- 	netlink_deinit(drv->netlink);
+-+#ifdef CONFIG_RFKILL
+- 	rfkill_deinit(drv->rfkill);
+-+#endif
+- 
+- 	if (drv->mlme_sock >= 0)
+- 		eloop_unregister_read_sock(drv->mlme_sock);
+ --- a/src/drivers/drivers.mak
+ +++ b/src/drivers/drivers.mak
+ @@ -25,7 +25,6 @@ NEED_SME=y
+@@ -247,15 +32,30 @@
+  endif
+  
+  ifdef CONFIG_VLAN_NETLINK
+---- a/src/drivers/driver_wext.h
+-+++ b/src/drivers/driver_wext.h
+-@@ -22,7 +22,9 @@ struct wpa_driver_wext_data {
+- 	int ifindex2;
+- 	int if_removed;
+- 	int if_disabled;
+-+#ifdef CONFIG_RFKILL
+- 	struct rfkill_data *rfkill;
+-+#endif
+- 	u8 *assoc_req_ies;
+- 	size_t assoc_req_ies_len;
+- 	u8 *assoc_resp_ies;
++--- a/src/drivers/rfkill.h
+++++ b/src/drivers/rfkill.h
++@@ -18,8 +18,24 @@ struct rfkill_config {
++ 	void (*unblocked_cb)(void *ctx);
++ };
++ 
+++#ifdef CONFIG_RFKILL
++ struct rfkill_data * rfkill_init(struct rfkill_config *cfg);
++ void rfkill_deinit(struct rfkill_data *rfkill);
++ int rfkill_is_blocked(struct rfkill_data *rfkill);
+++#else
+++static inline struct rfkill_data * rfkill_init(struct rfkill_config *cfg)
+++{
+++	return (void *) 1;
+++}
+++
+++static inline void rfkill_deinit(struct rfkill_data *rfkill)
+++{
+++}
+++
+++static inline int rfkill_is_blocked(struct rfkill_data *rfkill)
+++{
+++	return 0;
+++}
+++#endif
++ 
++ #endif /* RFKILL_H */
+diff --git a/package/hostapd/patches/330-nl80211_fix_set_freq.patch b/package/hostapd/patches/330-nl80211_fix_set_freq.patch
+index a505a60..864ac5e 100644
+--- a/package/hostapd/patches/330-nl80211_fix_set_freq.patch
++++ b/package/hostapd/patches/330-nl80211_fix_set_freq.patch
+@@ -1,6 +1,6 @@
+ --- a/src/drivers/driver_nl80211.c
+ +++ b/src/drivers/driver_nl80211.c
+-@@ -6860,7 +6860,7 @@ static int wpa_driver_nl80211_set_freq(s
++@@ -7380,7 +7380,7 @@ static int wpa_driver_nl80211_set_freq(s
+  
+  	nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
+  
+@@ -9,7 +9,7 @@
+  	if (nl80211_put_freq_params(msg, freq) < 0)
+  		goto nla_put_failure;
+  
+-@@ -11322,7 +11322,7 @@ static int nl80211_switch_channel(void *
++@@ -11905,7 +11905,7 @@ static int nl80211_switch_channel(void *
+  		return -ENOMEM;
+  
+  	nl80211_cmd(drv, msg, 0, NL80211_CMD_CHANNEL_SWITCH);
+diff --git a/package/hostapd/patches/340-reload_freq_change.patch b/package/hostapd/patches/340-reload_freq_change.patch
+index 9316794..d76f9de 100644
+--- a/package/hostapd/patches/340-reload_freq_change.patch
++++ b/package/hostapd/patches/340-reload_freq_change.patch
+@@ -1,6 +1,6 @@
+ --- a/src/ap/hostapd.c
+ +++ b/src/ap/hostapd.c
+-@@ -72,6 +72,16 @@ static void hostapd_reload_bss(struct ho
++@@ -68,6 +68,16 @@ static void hostapd_reload_bss(struct ho
+  #endif /* CONFIG_NO_RADIUS */
+  
+  	ssid = &hapd->conf->ssid;
+@@ -17,7 +17,7 @@
+  	if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next &&
+  	    ssid->wpa_passphrase_set && ssid->wpa_passphrase) {
+  		/*
+-@@ -172,6 +182,9 @@ int hostapd_reload_config(struct hostapd
++@@ -168,20 +178,12 @@ int hostapd_reload_config(struct hostapd
+  	oldconf = hapd->iconf;
+  	iface->conf = newconf;
+  
+@@ -27,3 +27,17 @@
+  	for (j = 0; j < iface->num_bss; j++) {
+  		hapd = iface->bss[j];
+  		hapd->iconf = newconf;
++-		hapd->iconf->channel = oldconf->channel;
++-		hapd->iconf->secondary_channel = oldconf->secondary_channel;
++-		hapd->iconf->ieee80211n = oldconf->ieee80211n;
++-		hapd->iconf->ieee80211ac = oldconf->ieee80211ac;
++-		hapd->iconf->ht_capab = oldconf->ht_capab;
++-		hapd->iconf->vht_capab = oldconf->vht_capab;
++-		hapd->iconf->vht_oper_chwidth = oldconf->vht_oper_chwidth;
++-		hapd->iconf->vht_oper_centr_freq_seg0_idx =
++-			oldconf->vht_oper_centr_freq_seg0_idx;
++-		hapd->iconf->vht_oper_centr_freq_seg1_idx =
++-			oldconf->vht_oper_centr_freq_seg1_idx;
++ 		hapd->conf = newconf->bss[j];
++ 		hostapd_reload_bss(hapd);
++ 	}
+diff --git a/package/hostapd/patches/350-nl80211_del_beacon_bss.patch b/package/hostapd/patches/350-nl80211_del_beacon_bss.patch
+index 885922c..8da6372 100644
+--- a/package/hostapd/patches/350-nl80211_del_beacon_bss.patch
++++ b/package/hostapd/patches/350-nl80211_del_beacon_bss.patch
+@@ -1,6 +1,6 @@
+ --- a/src/drivers/driver_nl80211.c
+ +++ b/src/drivers/driver_nl80211.c
+-@@ -4290,18 +4290,20 @@ wpa_driver_nl80211_finish_drv_init(struc
++@@ -4748,18 +4748,20 @@ wpa_driver_nl80211_finish_drv_init(struc
+  }
+  
+  
+@@ -24,7 +24,7 @@
+  
+  	return send_and_recv_msgs(drv, msg, NULL, NULL);
+   nla_put_failure:
+-@@ -4309,6 +4311,15 @@ static int wpa_driver_nl80211_del_beacon
++@@ -4767,6 +4769,15 @@ static int wpa_driver_nl80211_del_beacon
+  	return -ENOBUFS;
+  }
+  
+@@ -40,7 +40,7 @@
+  
+  /**
+   * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
+-@@ -9911,7 +9922,6 @@ static int wpa_driver_nl80211_stop_ap(vo
++@@ -10475,7 +10486,6 @@ static int wpa_driver_nl80211_stop_ap(vo
+  	if (!is_ap_interface(drv->nlmode))
+  		return -1;
+  	wpa_driver_nl80211_del_beacon(drv);
+diff --git a/package/hostapd/patches/360-ctrl_iface_reload.patch b/package/hostapd/patches/360-ctrl_iface_reload.patch
+index 170d4f2..e69c3d3 100644
+--- a/package/hostapd/patches/360-ctrl_iface_reload.patch
++++ b/package/hostapd/patches/360-ctrl_iface_reload.patch
+@@ -1,6 +1,6 @@
+ --- a/hostapd/ctrl_iface.c
+ +++ b/hostapd/ctrl_iface.c
+-@@ -34,6 +34,7 @@
++@@ -37,6 +37,7 @@
+  #include "wps/wps.h"
+  #include "config_file.h"
+  #include "ctrl_iface.h"
+@@ -8,7 +8,7 @@
+  
+  
+  struct wpa_ctrl_dst {
+-@@ -44,6 +45,7 @@ struct wpa_ctrl_dst {
++@@ -47,6 +48,7 @@ struct wpa_ctrl_dst {
+  	int errors;
+  };
+  
+@@ -16,7 +16,7 @@
+  
+  static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
+  				    const char *buf, size_t len);
+-@@ -153,6 +155,68 @@ static int hostapd_ctrl_iface_new_sta(st
++@@ -156,6 +158,68 @@ static int hostapd_ctrl_iface_new_sta(st
+  	return 0;
+  }
+  
+@@ -85,14 +85,14 @@
+  
+  #ifdef CONFIG_IEEE80211W
+  #ifdef NEED_AP_MLME
+-@@ -1199,6 +1263,10 @@ static void hostapd_ctrl_iface_receive(i
+- 				reply_len += res;
+- 		}
+- #endif /* CONFIG_NO_RADIUS */
++@@ -1546,6 +1610,10 @@ static void hostapd_ctrl_iface_receive(i
++ 	} else if (os_strncmp(buf, "VENDOR ", 7) == 0) {
++ 		reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply,
++ 						      reply_size);
+ +	} else if (os_strcmp(buf, "DOWN") == 0) {
+ +		hostapd_ctrl_iface_set_down(hapd);
+ +	} else if (os_strncmp(buf, "UPDATE ", 7) == 0) {
+ +		hostapd_ctrl_iface_update(hapd, buf + 7);
+- 	} else if (os_strcmp(buf, "STA-FIRST") == 0) {
+- 		reply_len = hostapd_ctrl_iface_sta_first(hapd, reply,
+- 							 reply_size);
++ 
++ 	} else {
++ 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
+diff --git a/package/hostapd/patches/370-ap_sta_support.patch b/package/hostapd/patches/370-ap_sta_support.patch
+index a3d0572..5e82252 100644
+--- a/package/hostapd/patches/370-ap_sta_support.patch
++++ b/package/hostapd/patches/370-ap_sta_support.patch
+@@ -1,6 +1,6 @@
+ --- a/wpa_supplicant/wpa_supplicant_i.h
+ +++ b/wpa_supplicant/wpa_supplicant_i.h
+-@@ -96,6 +96,11 @@ struct wpa_interface {
++@@ -108,6 +108,11 @@ struct wpa_interface {
+  	const char *ifname;
+  
+  	/**
+@@ -12,7 +12,7 @@
+  	 * bridge_ifname - Optional bridge interface name
+  	 *
+  	 * If the driver interface (ifname) is included in a Linux bridge
+-@@ -325,6 +330,8 @@ struct wpa_supplicant {
++@@ -395,6 +400,8 @@ struct wpa_supplicant {
+  #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
+  	char bridge_ifname[16];
+  
+@@ -20,12 +20,12 @@
+ +
+  	char *confname;
+  	char *confanother;
+- 	struct wpa_config *conf;
++ 
+ --- a/wpa_supplicant/Makefile
+ +++ b/wpa_supplicant/Makefile
+ @@ -13,6 +13,10 @@ PKG_CONFIG ?= pkg-config
+- CFLAGS += -I../src
+- CFLAGS += -I../src/utils
++ CFLAGS += -I$(abspath ../src)
++ CFLAGS += -I$(abspath ../src/utils)
+  
+ +ifdef MULTICALL
+ +CFLAGS += -DMULTICALL
+@@ -34,7 +34,7 @@
+  -include .config
+  -include $(if $(MULTICALL),../hostapd/.config)
+  
+-@@ -76,6 +80,8 @@ OBJS_c = wpa_cli.o ../src/common/wpa_ctr
++@@ -82,6 +86,8 @@ OBJS_c = wpa_cli.o ../src/common/wpa_ctr
+  OBJS_c += ../src/utils/wpa_debug.o
+  OBJS_c += ../src/utils/common.o
+  
+@@ -45,9 +45,9 @@
+  CONFIG_OS=win32
+ --- a/wpa_supplicant/wpa_supplicant.c
+ +++ b/wpa_supplicant/wpa_supplicant.c
+-@@ -109,6 +109,46 @@ extern int wpa_debug_show_keys;
+- extern int wpa_debug_timestamp;
+- extern struct wpa_driver_ops *wpa_drivers[];
++@@ -104,6 +104,46 @@ const char *wpa_supplicant_full_license5
++ "\n";
++ #endif /* CONFIG_NO_STDOUT_DEBUG */
+  
+ +static int hostapd_stop(struct wpa_supplicant *wpa_s)
+ +{
+@@ -92,7 +92,7 @@
+  /* Configure default/group WEP keys for static WEP */
+  int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+  {
+-@@ -685,8 +725,12 @@ void wpa_supplicant_set_state(struct wpa
++@@ -705,8 +745,12 @@ void wpa_supplicant_set_state(struct wpa
+  #endif /* CONFIG_P2P */
+  
+  		sme_sched_obss_scan(wpa_s, 1);
+@@ -105,7 +105,7 @@
+  		wpa_s->new_connection = 1;
+  		wpa_drv_set_operstate(wpa_s, 0);
+  #ifndef IEEE8021X_EAPOL
+-@@ -2906,6 +2950,20 @@ static int wpa_supplicant_init_iface(str
++@@ -3516,6 +3560,20 @@ static int wpa_supplicant_init_iface(str
+  			   sizeof(wpa_s->bridge_ifname));
+  	}
+  
+@@ -126,7 +126,7 @@
+  	/* RSNA Supplicant Key Management - INITIALIZE */
+  	eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
+  	eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
+-@@ -3125,6 +3183,11 @@ static void wpa_supplicant_deinit_iface(
++@@ -3711,6 +3769,11 @@ static void wpa_supplicant_deinit_iface(
+  	if (terminate)
+  		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
+  
+@@ -148,9 +148,9 @@
+  #include "drivers/driver.h"
+  #include "wpa_supplicant_i.h"
+  #include "config.h"
+-@@ -245,6 +246,9 @@ static void calculate_update_time(const 
++@@ -247,6 +248,9 @@ static void calculate_update_time(const 
+  static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src,
+- 			     struct os_time *fetch_time)
++ 			     struct os_reltime *fetch_time)
+  {
+ +	struct ieee80211_ht_capabilities *capab;
+ +	struct ieee802_11_elems elems;
+@@ -158,7 +158,7 @@
+  	dst->flags = src->flags;
+  	os_memcpy(dst->bssid, src->bssid, ETH_ALEN);
+  	dst->freq = src->freq;
+-@@ -255,6 +259,12 @@ static void wpa_bss_copy_res(struct wpa_
++@@ -257,6 +261,12 @@ static void wpa_bss_copy_res(struct wpa_
+  	dst->level = src->level;
+  	dst->tsf = src->tsf;
+  
+@@ -173,16 +173,16 @@
+  
+ --- a/wpa_supplicant/main.c
+ +++ b/wpa_supplicant/main.c
+-@@ -27,7 +27,7 @@ static void usage(void)
+- 	       "  wpa_supplicant [-BddhKLqqstuvW] [-P<pid file>] "
++@@ -33,7 +33,7 @@ static void usage(void)
++ 	       "vW] [-P<pid file>] "
+  	       "[-g<global ctrl>] \\\n"
+  	       "        [-G<group>] \\\n"
+ -	       "        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] "
+ +	       "        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] [-H<hostapd path>] "
+  	       "[-p<driver_param>] \\\n"
+- 	       "        [-b<br_ifname>] [-f<debug file>] [-e<entropy file>] "
+- 	       "\\\n"
+-@@ -72,6 +72,7 @@ static void usage(void)
++ 	       "        [-b<br_ifname>] [-e<entropy file>]"
++ #ifdef CONFIG_DEBUG_FILE
++@@ -84,6 +84,7 @@ static void usage(void)
+  #endif /* CONFIG_DEBUG_LINUX_TRACING */
+  	printf("  -t = include timestamp in debug messages\n"
+  	       "  -h = show this help text\n"
+@@ -190,16 +190,16 @@
+  	       "  -L = show license (BSD)\n"
+  	       "  -o = override driver parameter for new interfaces\n"
+  	       "  -O = override ctrl_interface parameter for new interfaces\n"
+-@@ -160,7 +161,7 @@ int main(int argc, char *argv[])
++@@ -175,7 +176,7 @@ int main(int argc, char *argv[])
+  
+  	for (;;) {
+  		c = getopt(argc, argv,
+--			   "b:Bc:C:D:de:f:g:G:hi:I:KLNo:O:p:P:qsTtuvW");
+-+			   "b:Bc:C:D:de:f:g:G:hH:i:I:KLNo:O:p:P:qsTtuvW");
++-			   "b:Bc:C:D:de:f:g:G:hi:I:KLm:No:O:p:P:qsTtuvW");
+++			   "b:Bc:C:D:de:f:g:G:hH:i:I:KLm:No:O:p:P:qsTtuvW");
+  		if (c < 0)
+  			break;
+  		switch (c) {
+-@@ -207,6 +208,9 @@ int main(int argc, char *argv[])
++@@ -222,6 +223,9 @@ int main(int argc, char *argv[])
+  			usage();
+  			exitcode = 0;
+  			goto out;
+@@ -211,7 +211,7 @@
+  			break;
+ --- a/wpa_supplicant/bss.h
+ +++ b/wpa_supplicant/bss.h
+-@@ -69,6 +69,8 @@ struct wpa_bss {
++@@ -70,6 +70,8 @@ struct wpa_bss {
+  	u8 ssid[32];
+  	/** Length of SSID */
+  	size_t ssid_len;
+diff --git a/package/hostapd/patches/380-disable_ctrl_iface_mib.patch b/package/hostapd/patches/380-disable_ctrl_iface_mib.patch
+index 27f21bd..d39ba2e 100644
+--- a/package/hostapd/patches/380-disable_ctrl_iface_mib.patch
++++ b/package/hostapd/patches/380-disable_ctrl_iface_mib.patch
+@@ -1,6 +1,6 @@
+ --- a/hostapd/Makefile
+ +++ b/hostapd/Makefile
+-@@ -144,6 +144,9 @@ endif
++@@ -163,6 +163,9 @@ endif
+  ifdef CONFIG_NO_CTRL_IFACE
+  CFLAGS += -DCONFIG_NO_CTRL_IFACE
+  else
+@@ -12,28 +12,15 @@
+  endif
+ --- a/hostapd/ctrl_iface.c
+ +++ b/hostapd/ctrl_iface.c
+-@@ -1234,6 +1234,7 @@ static void hostapd_ctrl_iface_receive(i
+- 	} else if (os_strcmp(buf, "STATUS") == 0) {
+- 		reply_len = hostapd_ctrl_iface_status(hapd, reply,
++@@ -1447,6 +1447,7 @@ static void hostapd_ctrl_iface_receive(i
+  						      reply_size);
++ 	} else if (os_strcmp(buf, "STATUS-DRIVER") == 0) {
++ 		reply_len = hostapd_drv_status(hapd, reply, reply_size);
+ +#ifdef CONFIG_CTRL_IFACE_MIB
+  	} else if (os_strcmp(buf, "MIB") == 0) {
+  		reply_len = ieee802_11_get_mib(hapd, reply, reply_size);
+  		if (reply_len >= 0) {
+-@@ -1263,10 +1264,12 @@ static void hostapd_ctrl_iface_receive(i
+- 				reply_len += res;
+- 		}
+- #endif /* CONFIG_NO_RADIUS */
+-+#endif
+- 	} else if (os_strcmp(buf, "DOWN") == 0) {
+- 		hostapd_ctrl_iface_set_down(hapd);
+- 	} else if (os_strncmp(buf, "UPDATE ", 7) == 0) {
+- 		hostapd_ctrl_iface_update(hapd, buf + 7);
+-+#ifdef CONFIG_CTRL_IFACE_MIB
+- 	} else if (os_strcmp(buf, "STA-FIRST") == 0) {
+- 		reply_len = hostapd_ctrl_iface_sta_first(hapd, reply,
+- 							 reply_size);
+-@@ -1276,6 +1279,7 @@ static void hostapd_ctrl_iface_receive(i
++@@ -1488,6 +1489,7 @@ static void hostapd_ctrl_iface_receive(i
+  	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
+  		reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply,
+  							reply_size);
+@@ -43,7 +30,7 @@
+  			reply_len = -1;
+ --- a/wpa_supplicant/Makefile
+ +++ b/wpa_supplicant/Makefile
+-@@ -778,6 +778,9 @@ ifdef CONFIG_WNM
++@@ -797,6 +797,9 @@ ifdef CONFIG_WNM
+  OBJS += ../src/ap/wnm_ap.o
+  endif
+  ifdef CONFIG_CTRL_IFACE
+@@ -55,7 +42,7 @@
+  
+ --- a/wpa_supplicant/ctrl_iface.c
+ +++ b/wpa_supplicant/ctrl_iface.c
+-@@ -5262,6 +5262,7 @@ char * wpa_supplicant_ctrl_iface_process
++@@ -6075,6 +6075,7 @@ char * wpa_supplicant_ctrl_iface_process
+  			reply_len = -1;
+  	} else if (os_strncmp(buf, "NOTE ", 5) == 0) {
+  		wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
+@@ -63,7 +50,7 @@
+  	} else if (os_strcmp(buf, "MIB") == 0) {
+  		reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
+  		if (reply_len >= 0) {
+-@@ -5273,6 +5274,7 @@ char * wpa_supplicant_ctrl_iface_process
++@@ -6086,6 +6087,7 @@ char * wpa_supplicant_ctrl_iface_process
+  			else
+  				reply_len += res;
+  		}
+@@ -71,7 +58,7 @@
+  	} else if (os_strncmp(buf, "STATUS", 6) == 0) {
+  		reply_len = wpa_supplicant_ctrl_iface_status(
+  			wpa_s, buf + 6, reply, reply_size);
+-@@ -5687,6 +5689,7 @@ char * wpa_supplicant_ctrl_iface_process
++@@ -6490,6 +6492,7 @@ char * wpa_supplicant_ctrl_iface_process
+  		reply_len = wpa_supplicant_ctrl_iface_bss(
+  			wpa_s, buf + 4, reply, reply_size);
+  #ifdef CONFIG_AP
+@@ -79,7 +66,7 @@
+  	} else if (os_strcmp(buf, "STA-FIRST") == 0) {
+  		reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
+  	} else if (os_strncmp(buf, "STA ", 4) == 0) {
+-@@ -5695,6 +5698,7 @@ char * wpa_supplicant_ctrl_iface_process
++@@ -6498,6 +6501,7 @@ char * wpa_supplicant_ctrl_iface_process
+  	} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
+  		reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
+  						   reply_size);
+@@ -89,15 +76,15 @@
+  			reply_len = -1;
+ --- a/src/ap/ctrl_iface_ap.c
+ +++ b/src/ap/ctrl_iface_ap.c
+-@@ -20,6 +20,7 @@
++@@ -21,6 +21,7 @@
+  #include "ctrl_iface_ap.h"
+  #include "ap_drv_ops.h"
+  
+ +#ifdef CONFIG_CTRL_IFACE_MIB
+  
+- static int hostapd_get_sta_conn_time(struct sta_info *sta,
+- 				     char *buf, size_t buflen)
+-@@ -129,6 +130,7 @@ int hostapd_ctrl_iface_sta_next(struct h
++ static int hostapd_get_sta_tx_rx(struct hostapd_data *hapd,
++ 				 struct sta_info *sta,
++@@ -214,6 +215,7 @@ int hostapd_ctrl_iface_sta_next(struct h
+  	return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen);
+  }
+  
+@@ -105,14 +92,14 @@
+  
+  #ifdef CONFIG_P2P_MANAGER
+  static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype,
+-@@ -423,3 +425,4 @@ int hostapd_parse_csa_settings(const cha
++@@ -524,3 +526,4 @@ int hostapd_parse_csa_settings(const cha
+  
+  	return 0;
+  }
+ +
+ --- a/src/ap/ieee802_1x.c
+ +++ b/src/ap/ieee802_1x.c
+-@@ -1938,6 +1938,7 @@ static const char * bool_txt(Boolean boo
++@@ -2124,6 +2124,7 @@ static const char * bool_txt(Boolean boo
+  	return bool_val ? "TRUE" : "FALSE";
+  }
+  
+@@ -120,17 +107,17 @@
+  
+  int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
+  {
+-@@ -2090,6 +2091,7 @@ int ieee802_1x_get_mib_sta(struct hostap
++@@ -2291,6 +2292,7 @@ int ieee802_1x_get_mib_sta(struct hostap
+  	return len;
+  }
+  
+ +#endif
+  
+  static void ieee802_1x_finished(struct hostapd_data *hapd,
+- 				struct sta_info *sta, int success)
++ 				struct sta_info *sta, int success,
+ --- a/src/ap/wpa_auth.c
+ +++ b/src/ap/wpa_auth.c
+-@@ -2708,6 +2708,7 @@ static const char * wpa_bool_txt(int boo
++@@ -2830,6 +2830,7 @@ static const char * wpa_bool_txt(int boo
+  	return bool ? "TRUE" : "FALSE";
+  }
+  
+@@ -138,7 +125,7 @@
+  
+  #define RSN_SUITE "%02x-%02x-%02x-%d"
+  #define RSN_SUITE_ARG(s) \
+-@@ -2852,7 +2853,7 @@ int wpa_get_mib_sta(struct wpa_state_mac
++@@ -2974,7 +2975,7 @@ int wpa_get_mib_sta(struct wpa_state_mac
+  
+  	return len;
+  }
+@@ -149,7 +136,7 @@
+  {
+ --- a/src/rsn_supp/wpa.c
+ +++ b/src/rsn_supp/wpa.c
+-@@ -1844,6 +1844,8 @@ static u32 wpa_key_mgmt_suite(struct wpa
++@@ -1912,6 +1912,8 @@ static u32 wpa_key_mgmt_suite(struct wpa
+  }
+  
+  
+@@ -158,7 +145,7 @@
+  #define RSN_SUITE "%02x-%02x-%02x-%d"
+  #define RSN_SUITE_ARG(s) \
+  ((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
+-@@ -1927,6 +1929,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch
++@@ -1995,6 +1997,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch
+  
+  	return (int) len;
+  }
+diff --git a/package/hostapd/patches/390-wpa_ie_cap_workaround.patch b/package/hostapd/patches/390-wpa_ie_cap_workaround.patch
+index 00a3222..40148fc 100644
+--- a/package/hostapd/patches/390-wpa_ie_cap_workaround.patch
++++ b/package/hostapd/patches/390-wpa_ie_cap_workaround.patch
+@@ -1,6 +1,6 @@
+ --- a/src/common/wpa_common.c
+ +++ b/src/common/wpa_common.c
+-@@ -959,6 +959,31 @@ const char * wpa_key_mgmt_txt(int key_mg
++@@ -1002,6 +1002,31 @@ const char * wpa_key_mgmt_txt(int key_mg
+  }
+  
+  
+@@ -32,7 +32,7 @@
+  int wpa_compare_rsn_ie(int ft_initial_assoc,
+  		       const u8 *ie1, size_t ie1len,
+  		       const u8 *ie2, size_t ie2len)
+-@@ -966,8 +991,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
++@@ -1009,8 +1034,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
+  	if (ie1 == NULL || ie2 == NULL)
+  		return -1;
+  
+diff --git a/package/hostapd/patches/400-terminate_on_setup_failure.patch b/package/hostapd/patches/400-terminate_on_setup_failure.patch
+deleted file mode 100644
+index 0d9065a..0000000
+--- a/package/hostapd/patches/400-terminate_on_setup_failure.patch
++++ /dev/null
+@@ -1,85 +0,0 @@
+---- a/src/ap/hostapd.c
+-+++ b/src/ap/hostapd.c
+-@@ -1103,13 +1103,8 @@ int hostapd_setup_interface_complete(str
+- 	size_t j;
+- 	u8 *prev_addr;
+- 
+--	if (err) {
+--		wpa_printf(MSG_ERROR, "Interface initialization failed");
+--		hostapd_set_state(iface, HAPD_IFACE_DISABLED);
+--		if (iface->interfaces && iface->interfaces->terminate_on_error)
+--			eloop_terminate();
+--		return -1;
+--	}
+-+	if (err)
+-+		goto error;
+- 
+- 	wpa_printf(MSG_DEBUG, "Completing interface initialization");
+- 	if (iface->conf->channel) {
+-@@ -1140,7 +1135,7 @@ int hostapd_setup_interface_complete(str
+- 				     hapd->iconf->vht_oper_centr_freq_seg1_idx)) {
+- 			wpa_printf(MSG_ERROR, "Could not set channel for "
+- 				   "kernel driver");
+--			return -1;
+-+			goto error;
+- 		}
+- 	}
+- 
+-@@ -1151,7 +1146,7 @@ int hostapd_setup_interface_complete(str
+- 			hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
+- 				       HOSTAPD_LEVEL_WARNING,
+- 				       "Failed to prepare rates table.");
+--			return -1;
+-+			goto error;
+- 		}
+- 	}
+- 
+-@@ -1159,14 +1154,14 @@ int hostapd_setup_interface_complete(str
+- 	    hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) {
+- 		wpa_printf(MSG_ERROR, "Could not set RTS threshold for "
+- 			   "kernel driver");
+--		return -1;
+-+		goto error;
+- 	}
+- 
+- 	if (hapd->iconf->fragm_threshold > -1 &&
+- 	    hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) {
+- 		wpa_printf(MSG_ERROR, "Could not set fragmentation threshold "
+- 			   "for kernel driver");
+--		return -1;
+-+		goto error;
+- 	}
+- 
+- 	prev_addr = hapd->own_addr;
+-@@ -1176,7 +1171,7 @@ int hostapd_setup_interface_complete(str
+- 		if (j)
+- 			os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
+- 		if (hostapd_setup_bss(hapd, j == 0))
+--			return -1;
+-+			goto error;
+- 		if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0)
+- 			prev_addr = hapd->own_addr;
+- 	}
+-@@ -1191,7 +1186,7 @@ int hostapd_setup_interface_complete(str
+- 	if (hostapd_driver_commit(hapd) < 0) {
+- 		wpa_printf(MSG_ERROR, "%s: Failed to commit driver "
+- 			   "configuration", __func__);
+--		return -1;
+-+		goto error;
+- 	}
+- 
+- 	/*
+-@@ -1216,6 +1211,13 @@ int hostapd_setup_interface_complete(str
+- 		iface->interfaces->terminate_on_error--;
+- 
+- 	return 0;
+-+
+-+error:
+-+	wpa_printf(MSG_ERROR, "Interface initialization failed");
+-+	hostapd_set_state(iface, HAPD_IFACE_DISABLED);
+-+	if (iface->interfaces && iface->interfaces->terminate_on_error)
+-+		eloop_terminate();
+-+	return -1;
+- }
+- 
+- 
+diff --git a/package/hostapd/patches/410-bring_down_interface.patch b/package/hostapd/patches/410-bring_down_interface.patch
+index 31033a0..5a57249 100644
+--- a/package/hostapd/patches/410-bring_down_interface.patch
++++ b/package/hostapd/patches/410-bring_down_interface.patch
+@@ -1,6 +1,6 @@
+ --- a/src/drivers/driver_nl80211.c
+ +++ b/src/drivers/driver_nl80211.c
+-@@ -8480,12 +8480,7 @@ static int wpa_driver_nl80211_set_mode(s
++@@ -8936,12 +8936,7 @@ static int wpa_driver_nl80211_set_mode(s
+  			/* Try to set the mode again while the interface is
+  			 * down */
+  			ret = nl80211_set_mode(drv, drv->ifindex, nlmode);
+@@ -14,7 +14,7 @@
+  				break;
+  		} else
+  			wpa_printf(MSG_DEBUG, "nl80211: Failed to set "
+-@@ -8498,6 +8493,8 @@ static int wpa_driver_nl80211_set_mode(s
++@@ -8954,6 +8949,8 @@ static int wpa_driver_nl80211_set_mode(s
+  			   "interface is down");
+  		drv->nlmode = nlmode;
+  		drv->ignore_if_down_event = 1;
+diff --git a/package/hostapd/patches/420-fix_wps_pin_crash.patch b/package/hostapd/patches/420-fix_wps_pin_crash.patch
+index 130bd53..31995c4 100644
+--- a/package/hostapd/patches/420-fix_wps_pin_crash.patch
++++ b/package/hostapd/patches/420-fix_wps_pin_crash.patch
+@@ -1,6 +1,6 @@
+ --- a/hostapd/ctrl_iface.c
+ +++ b/hostapd/ctrl_iface.c
+-@@ -480,6 +480,9 @@ static int hostapd_ctrl_iface_wps_ap_pin
++@@ -540,6 +540,9 @@ static int hostapd_ctrl_iface_wps_ap_pin
+  	char *pos;
+  	const char *pin_txt;
+  
+diff --git a/package/hostapd/patches/430-wps_single_auth_enc_type.patch b/package/hostapd/patches/430-wps_single_auth_enc_type.patch
+index 6e86658..8dae52b 100644
+--- a/package/hostapd/patches/430-wps_single_auth_enc_type.patch
++++ b/package/hostapd/patches/430-wps_single_auth_enc_type.patch
+@@ -1,6 +1,6 @@
+ --- a/src/ap/wps_hostapd.c
+ +++ b/src/ap/wps_hostapd.c
+-@@ -1069,11 +1069,9 @@ int hostapd_init_wps(struct hostapd_data
++@@ -1051,11 +1051,9 @@ int hostapd_init_wps(struct hostapd_data
+  
+  		if (conf->rsn_pairwise & WPA_CIPHER_CCMP)
+  			wps->encr_types |= WPS_ENCR_AES;
+@@ -14,7 +14,7 @@
+  		if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK)
+  			wps->auth_types |= WPS_AUTH_WPAPSK;
+  		if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
+-@@ -1081,7 +1079,7 @@ int hostapd_init_wps(struct hostapd_data
++@@ -1063,7 +1061,7 @@ int hostapd_init_wps(struct hostapd_data
+  
+  		if (conf->wpa_pairwise & WPA_CIPHER_CCMP)
+  			wps->encr_types |= WPS_ENCR_AES;
+diff --git a/package/hostapd/patches/440-dynamic_20_40_mhz.patch b/package/hostapd/patches/440-dynamic_20_40_mhz.patch
+index 905ec2c..af2fb26 100644
+--- a/package/hostapd/patches/440-dynamic_20_40_mhz.patch
++++ b/package/hostapd/patches/440-dynamic_20_40_mhz.patch
+@@ -1,19 +1,19 @@
+ --- a/hostapd/config_file.c
+ +++ b/hostapd/config_file.c
+-@@ -2422,6 +2422,10 @@ static int hostapd_config_fill(struct ho
+- 					   "ht_capab", line);
+- 				errors++;
+- 			}
+-+		} else if (os_strcmp(buf, "dynamic_ht40") == 0) {
+-+			conf->dynamic_ht40 = atoi(pos);
+-+			if (conf->dynamic_ht40 == 1)
+-+				conf->dynamic_ht40 = 1500;
+- 		} else if (os_strcmp(buf, "require_ht") == 0) {
+- 			conf->require_ht = atoi(pos);
+- 		} else if (os_strcmp(buf, "obss_interval") == 0) {
++@@ -2648,6 +2648,10 @@ static int hostapd_config_fill(struct ho
++ 				   line);
++ 			return 1;
++ 		}
+++	} else if (os_strcmp(buf, "dynamic_ht40") == 0) {
+++		conf->dynamic_ht40 = atoi(pos);
+++		if (conf->dynamic_ht40 == 1)
+++			conf->dynamic_ht40 = 1500;
++ 	} else if (os_strcmp(buf, "require_ht") == 0) {
++ 		conf->require_ht = atoi(pos);
++ 	} else if (os_strcmp(buf, "obss_interval") == 0) {
+ --- a/src/ap/ap_config.h
+ +++ b/src/ap/ap_config.h
+-@@ -531,6 +531,7 @@ struct hostapd_config {
++@@ -580,6 +580,7 @@ struct hostapd_config {
+  	int ieee80211n;
+  	int secondary_channel;
+  	int require_ht;
+@@ -23,7 +23,7 @@
+  	int ieee80211ac;
+ --- a/src/ap/hostapd.c
+ +++ b/src/ap/hostapd.c
+-@@ -23,6 +23,7 @@
++@@ -22,6 +22,7 @@
+  #include "beacon.h"
+  #include "iapp.h"
+  #include "ieee802_1x.h"
+@@ -31,7 +31,7 @@
+  #include "ieee802_11_auth.h"
+  #include "vlan_init.h"
+  #include "wpa_auth.h"
+-@@ -332,6 +333,7 @@ static void hostapd_cleanup(struct hosta
++@@ -328,6 +329,7 @@ static void hostapd_cleanup(struct hosta
+  static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
+  {
+  	wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
+@@ -41,7 +41,7 @@
+  	os_free(iface->current_rates);
+ --- a/src/ap/hostapd.h
+ +++ b/src/ap/hostapd.h
+-@@ -326,6 +326,9 @@ struct hostapd_iface {
++@@ -330,6 +330,9 @@ struct hostapd_iface {
+  	/* Overlapping BSS information */
+  	int olbc_ht;
+  
+@@ -53,7 +53,7 @@
+  	/* surveying helpers */
+ --- a/src/ap/ieee802_11.c
+ +++ b/src/ap/ieee802_11.c
+-@@ -1538,6 +1538,9 @@ static void handle_beacon(struct hostapd
++@@ -1556,6 +1556,9 @@ static void handle_beacon(struct hostapd
+  					     sizeof(mgmt->u.beacon)), &elems,
+  				      0);
+  
+@@ -65,7 +65,7 @@
+  
+ --- a/src/ap/ieee802_11.h
+ +++ b/src/ap/ieee802_11.h
+-@@ -82,4 +82,17 @@ int hostapd_update_time_adv(struct hosta
++@@ -83,4 +83,17 @@ int hostapd_update_time_adv(struct hosta
+  void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr);
+  u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid);
+  
+@@ -85,8 +85,8 @@
+  #endif /* IEEE802_11_H */
+ --- a/src/ap/ieee802_11_ht.c
+ +++ b/src/ap/ieee802_11_ht.c
+-@@ -20,9 +20,11 @@
+- #include "drivers/driver.h"
++@@ -13,9 +13,11 @@
++ #include "common/ieee802_11_defs.h"
+  #include "hostapd.h"
+  #include "ap_config.h"
+ +#include "ap_drv_ops.h"
+@@ -97,29 +97,25 @@
+  
+  
+  u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid)
+-@@ -86,12 +88,15 @@ u8 * hostapd_eid_ht_operation(struct hos
++@@ -92,6 +94,9 @@ u8 * hostapd_eid_ht_operation(struct hos
+  
+- 	oper->control_chan = hapd->iconf->channel;
++ 	oper->primary_chan = hapd->iconf->channel;
+  	oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode);
+--	if (hapd->iconf->secondary_channel == 1)
+--		oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |
+--			HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
+--	if (hapd->iconf->secondary_channel == -1)
+--		oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |
+--			HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
+-+
+-+	if (!hapd->iface->force_20mhz) {
+-+		if (hapd->iconf->secondary_channel == 1)
+-+			oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |
+-+				HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
+-+		if (hapd->iconf->secondary_channel == -1)
+-+			oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |
+-+				HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;
+-+	}
+++	if (hapd->iface->force_20mhz)
+++		goto skip;
+++
++ 	if (hapd->iconf->secondary_channel == 1)
++ 		oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |
++ 			HT_INFO_HT_PARAM_STA_CHNL_WIDTH;
++@@ -99,6 +104,7 @@ u8 * hostapd_eid_ht_operation(struct hos
++ 		oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |
++ 			HT_INFO_HT_PARAM_STA_CHNL_WIDTH;
+  
+++skip:
+  	pos += sizeof(*oper);
+  
+-@@ -286,3 +291,84 @@ void hostapd_get_ht_capab(struct hostapd
++ 	return pos;
++@@ -288,3 +294,84 @@ void hostapd_get_ht_capab(struct hostapd
+  
+  	neg_ht_cap->ht_capabilities_info = host_to_le16(cap);
+  }
+diff --git a/package/hostapd/patches/450-limit_debug_messages.patch b/package/hostapd/patches/450-limit_debug_messages.patch
+index aaea941..08f17dc 100644
+--- a/package/hostapd/patches/450-limit_debug_messages.patch
++++ b/package/hostapd/patches/450-limit_debug_messages.patch
+@@ -20,40 +20,41 @@
+  {
+  	size_t i;
+  
+-@@ -375,20 +375,9 @@ static void _wpa_hexdump(int level, cons
++@@ -375,20 +375,8 @@ static void _wpa_hexdump(int level, cons
+  #endif /* CONFIG_ANDROID_LOG */
+  }
+  
+--void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
++-void wpa_hexdump(int level, const char *title, const void *buf, size_t len)
+ -{
+ -	_wpa_hexdump(level, title, buf, len, 1);
+ -}
+ -
+ -
+--void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
++-void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len)
+ -{
+ -	_wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
+ -}
+- 
+ -
+--static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
++-
++-static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
+ -			       size_t len, int show)
+-+void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
+++void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
+ +			size_t len, int show)
+  {
+  	size_t i, llen;
+  	const u8 *pos = buf;
+-@@ -495,19 +484,6 @@ static void _wpa_hexdump_ascii(int level
++@@ -495,20 +483,6 @@ static void _wpa_hexdump_ascii(int level
+  }
+  
+  
+--void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len)
++-void wpa_hexdump_ascii(int level, const char *title, const void *buf,
++-		       size_t len)
+ -{
+ -	_wpa_hexdump_ascii(level, title, buf, len, 1);
+ -}
+ -
+ -
+--void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
++-void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
+ -			   size_t len)
+ -{
+ -	_wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
+@@ -63,7 +64,7 @@
+  #ifdef CONFIG_DEBUG_FILE
+  static char *last_path = NULL;
+  #endif /* CONFIG_DEBUG_FILE */
+-@@ -591,7 +567,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_
++@@ -592,7 +566,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_
+  }
+  
+  
+@@ -72,7 +73,7 @@
+  {
+  	va_list ap;
+  	char *buf;
+-@@ -625,7 +601,7 @@ void wpa_msg(void *ctx, int level, const
++@@ -630,7 +604,7 @@ void wpa_msg(void *ctx, int level, const
+  }
+  
+  
+@@ -83,14 +84,14 @@
+  	char *buf;
+ --- a/src/utils/wpa_debug.h
+ +++ b/src/utils/wpa_debug.h
+-@@ -43,6 +43,17 @@ int wpa_debug_open_file(const char *path
++@@ -47,6 +47,17 @@ int wpa_debug_open_file(const char *path
+  int wpa_debug_reopen_file(void);
+  void wpa_debug_close_file(void);
+  
+ +/* internal */
+ +void _wpa_hexdump(int level, const char *title, const u8 *buf,
+ +		  size_t len, int show);
+-+void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
+++void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
+ +			size_t len, int show);
+ +extern int wpa_debug_show_keys;
+ +
+@@ -101,7 +102,7 @@
+  /**
+   * wpa_debug_printf_timestamp - Print timestamp for debug output
+   *
+-@@ -63,9 +74,15 @@ void wpa_debug_print_timestamp(void);
++@@ -67,9 +78,15 @@ void wpa_debug_print_timestamp(void);
+   *
+   * Note: New line '\n' is added to the end of the text when printing to stdout.
+   */
+@@ -118,11 +119,11 @@
+  /**
+   * wpa_hexdump - conditional hex dump
+   * @level: priority level (MSG_*) of the message
+-@@ -77,7 +94,13 @@ PRINTF_FORMAT(2, 3);
++@@ -81,7 +98,13 @@ PRINTF_FORMAT(2, 3);
+   * output may be directed to stdout, stderr, and/or syslog based on
+   * configuration. The contents of buf is printed out has hex dump.
+   */
+--void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len);
++-void wpa_hexdump(int level, const char *title, const void *buf, size_t len);
+ +static inline void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
+ +{
+ +	if (level < CONFIG_MSG_MIN_PRIORITY)
+@@ -133,11 +134,11 @@
+  
+  static inline void wpa_hexdump_buf(int level, const char *title,
+  				   const struct wpabuf *buf)
+-@@ -99,7 +122,13 @@ static inline void wpa_hexdump_buf(int l
++@@ -103,7 +126,13 @@ static inline void wpa_hexdump_buf(int l
+   * like wpa_hexdump(), but by default, does not include secret keys (passwords,
+   * etc.) in debug output.
+   */
+--void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len);
++-void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len);
+ +static inline void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
+ +{
+ +	if (level < CONFIG_MSG_MIN_PRIORITY)
+@@ -148,11 +149,11 @@
+  
+  static inline void wpa_hexdump_buf_key(int level, const char *title,
+  				       const struct wpabuf *buf)
+-@@ -121,8 +150,14 @@ static inline void wpa_hexdump_buf_key(i
++@@ -125,8 +154,14 @@ static inline void wpa_hexdump_buf_key(i
+   * the hex numbers and ASCII characters (for printable range) are shown. 16
+   * bytes per line will be shown.
+   */
+--void wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
++-void wpa_hexdump_ascii(int level, const char *title, const void *buf,
+ -		       size_t len);
+ +static inline void wpa_hexdump_ascii(int level, const char *title,
+ +				     const u8 *buf, size_t len)
+@@ -165,11 +166,11 @@
+  
+  /**
+   * wpa_hexdump_ascii_key - conditional hex dump, hide keys
+-@@ -138,8 +173,14 @@ void wpa_hexdump_ascii(int level, const 
++@@ -142,8 +177,14 @@ void wpa_hexdump_ascii(int level, const 
+   * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by
+   * default, does not include secret keys (passwords, etc.) in debug output.
+   */
+--void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
++-void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
+ -			   size_t len);
+ +static inline void wpa_hexdump_ascii_key(int level, const char *title,
+ +					 const u8 *buf, size_t len)
+@@ -182,7 +183,7 @@
+  
+  /*
+   * wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce
+-@@ -174,7 +215,12 @@ void wpa_hexdump_ascii_key(int level, co
++@@ -178,7 +219,12 @@ void wpa_hexdump_ascii_key(int level, co
+   *
+   * Note: New line '\n' is added to the end of the text when printing to stdout.
+   */
+@@ -196,7 +197,7 @@
+  
+  /**
+   * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors
+-@@ -188,8 +234,13 @@ void wpa_msg(void *ctx, int level, const
++@@ -192,8 +238,13 @@ void wpa_msg(void *ctx, int level, const
+   * attached ctrl_iface monitors. In other words, it can be used for frequent
+   * events that do not need to be sent to syslog.
+   */
+diff --git a/package/hostapd/patches/460-indicate-features.patch b/package/hostapd/patches/460-indicate-features.patch
+index 7a44da1..cee3e76 100644
+--- a/package/hostapd/patches/460-indicate-features.patch
++++ b/package/hostapd/patches/460-indicate-features.patch
+@@ -1,23 +1,23 @@
+ --- a/hostapd/main.c
+ +++ b/hostapd/main.c
+-@@ -14,6 +14,7 @@
+- 
++@@ -15,6 +15,7 @@
+  #include "utils/common.h"
+  #include "utils/eloop.h"
++ #include "utils/uuid.h"
+ +#include "utils/build_features.h"
+  #include "crypto/random.h"
+  #include "crypto/tls.h"
+  #include "common/version.h"
+-@@ -546,7 +547,7 @@ int main(int argc, char *argv[])
++@@ -558,7 +559,7 @@ int main(int argc, char *argv[])
+  
+  	wpa_supplicant_event = hostapd_wpa_event;
+  	for (;;) {
+--		c = getopt(argc, argv, "b:Bde:f:hKP:Ttvg:G:");
+-+		c = getopt(argc, argv, "b:Bde:f:hKP:Ttg:G:v::");
++-		c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:vg:G:");
+++		c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:g:G:v::");
+  		if (c < 0)
+  			break;
+  		switch (c) {
+-@@ -583,6 +584,8 @@ int main(int argc, char *argv[])
++@@ -595,6 +596,8 @@ int main(int argc, char *argv[])
+  			break;
+  #endif /* CONFIG_DEBUG_LINUX_TRACING */
+  		case 'v':
+@@ -36,16 +36,16 @@
+  #include "wpa_supplicant_i.h"
+  #include "driver_i.h"
+  #include "p2p_supplicant.h"
+-@@ -161,7 +162,7 @@ int main(int argc, char *argv[])
++@@ -176,7 +177,7 @@ int main(int argc, char *argv[])
+  
+  	for (;;) {
+  		c = getopt(argc, argv,
+--			   "b:Bc:C:D:de:f:g:G:hH:i:I:KLNo:O:p:P:qsTtuvW");
+-+			   "b:Bc:C:D:de:f:g:G:hH:i:I:KLNo:O:p:P:qsTtuv::W");
++-			   "b:Bc:C:D:de:f:g:G:hH:i:I:KLm:No:O:p:P:qsTtuvW");
+++			   "b:Bc:C:D:de:f:g:G:hH:i:I:KLm:No:O:p:P:qsTtuv::W");
+  		if (c < 0)
+  			break;
+  		switch (c) {
+-@@ -259,8 +260,12 @@ int main(int argc, char *argv[])
++@@ -279,8 +280,12 @@ int main(int argc, char *argv[])
+  			break;
+  #endif /* CONFIG_DBUS */
+  		case 'v':
+diff --git a/package/hostapd/patches/470-hostapd_cli_ifdef.patch b/package/hostapd/patches/470-hostapd_cli_ifdef.patch
+index 5ac0fdd..d4a0f12 100644
+--- a/package/hostapd/patches/470-hostapd_cli_ifdef.patch
++++ b/package/hostapd/patches/470-hostapd_cli_ifdef.patch
+@@ -16,7 +16,7 @@
+  "   get_config           show current configuration\n"
+  "   help                 show this usage help\n"
+  "   interface [ifname]   show interfaces/select interface\n"
+-@@ -352,7 +350,6 @@ static int hostapd_cli_cmd_sa_query(stru
++@@ -362,7 +360,6 @@ static int hostapd_cli_cmd_sa_query(stru
+  #endif /* CONFIG_IEEE80211W */
+  
+  
+@@ -24,7 +24,7 @@
+  static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
+  				   char *argv[])
+  {
+-@@ -578,7 +575,6 @@ static int hostapd_cli_cmd_wps_config(st
++@@ -588,7 +585,6 @@ static int hostapd_cli_cmd_wps_config(st
+  			 ssid_hex, argv[1]);
+  	return wpa_ctrl_command(ctrl, buf);
+  }
+@@ -32,7 +32,7 @@
+  
+  
+  static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc,
+-@@ -903,7 +899,6 @@ static struct hostapd_cli_cmd hostapd_cl
++@@ -979,7 +975,6 @@ static struct hostapd_cli_cmd hostapd_cl
+  #ifdef CONFIG_IEEE80211W
+  	{ "sa_query", hostapd_cli_cmd_sa_query },
+  #endif /* CONFIG_IEEE80211W */
+@@ -40,7 +40,7 @@
+  	{ "wps_pin", hostapd_cli_cmd_wps_pin },
+  	{ "wps_check_pin", hostapd_cli_cmd_wps_check_pin },
+  	{ "wps_pbc", hostapd_cli_cmd_wps_pbc },
+-@@ -917,7 +912,6 @@ static struct hostapd_cli_cmd hostapd_cl
++@@ -993,7 +988,6 @@ static struct hostapd_cli_cmd hostapd_cl
+  	{ "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
+  	{ "wps_config", hostapd_cli_cmd_wps_config },
+  	{ "wps_get_status", hostapd_cli_cmd_wps_get_status },
+diff --git a/package/hostapd/patches/471-wpa_cli_ifdef.patch b/package/hostapd/patches/471-wpa_cli_ifdef.patch
+index cc84444..36b5a44 100644
+--- a/package/hostapd/patches/471-wpa_cli_ifdef.patch
++++ b/package/hostapd/patches/471-wpa_cli_ifdef.patch
+@@ -10,4 +10,4 @@
+ +
+  static const char *wpa_cli_version =
+  "wpa_cli v" VERSION_STR "\n"
+- "Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi> and contributors";
++ "Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi> and contributors";
+diff --git a/package/hostapd/patches/480-max_num_sta_probe.patch b/package/hostapd/patches/480-max_num_sta_probe.patch
+index e5ca8b4..e238bf4 100644
+--- a/package/hostapd/patches/480-max_num_sta_probe.patch
++++ b/package/hostapd/patches/480-max_num_sta_probe.patch
+@@ -1,6 +1,6 @@
+ --- a/src/ap/beacon.c
+ +++ b/src/ap/beacon.c
+-@@ -501,6 +501,10 @@ void handle_probe_req(struct hostapd_dat
++@@ -599,6 +599,10 @@ void handle_probe_req(struct hostapd_dat
+  		return;
+  	}
+  
+@@ -9,5 +9,5 @@
+ +			   " too many connected stations.", MAC2STR(mgmt->sa));
+ +
+  #ifdef CONFIG_INTERWORKING
+- 	if (elems.interworking && elems.interworking_len >= 1) {
+- 		u8 ant = elems.interworking[0] & 0x0f;
++ 	if (hapd->conf->interworking &&
++ 	    elems.interworking && elems.interworking_len >= 1) {
+diff --git a/package/hostapd/patches/490-scan_wait.patch b/package/hostapd/patches/490-scan_wait.patch
+index 61715d6..3459a61 100644
+--- a/package/hostapd/patches/490-scan_wait.patch
++++ b/package/hostapd/patches/490-scan_wait.patch
+@@ -1,15 +1,15 @@
+ --- a/hostapd/main.c
+ +++ b/hostapd/main.c
+-@@ -33,6 +33,8 @@
+- extern int wpa_debug_level;
+- extern int wpa_debug_show_keys;
+- extern int wpa_debug_timestamp;
++@@ -36,6 +36,8 @@ struct hapd_global {
++ };
++ 
++ static struct hapd_global global;
+ +static int daemonize = 0;
+ +static char *pid_file = NULL;
+  
+- extern struct wpa_driver_ops *wpa_drivers[];
+  
+-@@ -147,6 +149,14 @@ static void hostapd_logger_cb(void *ctx,
++ #ifndef CONFIG_NO_HOSTAPD_LOGGER
++@@ -141,6 +143,14 @@ static void hostapd_logger_cb(void *ctx,
+  }
+  #endif /* CONFIG_NO_HOSTAPD_LOGGER */
+  
+@@ -24,7 +24,7 @@
+  
+  /**
+   * hostapd_driver_init - Preparate driver interface
+-@@ -165,6 +175,8 @@ static int hostapd_driver_init(struct ho
++@@ -159,6 +169,8 @@ static int hostapd_driver_init(struct ho
+  		return -1;
+  	}
+  
+@@ -33,7 +33,7 @@
+  	/* Initialize the driver interface */
+  	if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))
+  		b = NULL;
+-@@ -381,8 +393,6 @@ static void hostapd_global_deinit(const 
++@@ -372,8 +384,6 @@ static void hostapd_global_deinit(const 
+  #endif /* CONFIG_NATIVE_WINDOWS */
+  
+  	eap_server_unregister_methods();
+@@ -42,7 +42,7 @@
+  }
+  
+  
+-@@ -408,11 +418,6 @@ static int hostapd_global_run(struct hap
++@@ -399,11 +409,6 @@ static int hostapd_global_run(struct hap
+  	}
+  #endif /* EAP_SERVER_TNC */
+  
+@@ -54,7 +54,7 @@
+  	eloop_run();
+  
+  	return 0;
+-@@ -521,8 +526,7 @@ int main(int argc, char *argv[])
++@@ -533,8 +538,7 @@ int main(int argc, char *argv[])
+  	struct hapd_interfaces interfaces;
+  	int ret = 1;
+  	size_t i, j;
+diff --git a/package/hostapd/patches/500-wpa_supplicant-add-new-config-params-to-be-used-with.patch b/package/hostapd/patches/500-wpa_supplicant-add-new-config-params-to-be-used-with.patch
+index 544151e..5656970 100644
+--- a/package/hostapd/patches/500-wpa_supplicant-add-new-config-params-to-be-used-with.patch
++++ b/package/hostapd/patches/500-wpa_supplicant-add-new-config-params-to-be-used-with.patch
+@@ -22,9 +22,9 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
+  #include "common/defs.h"
+  #include "utils/list.h"
+  
+-@@ -404,6 +405,11 @@ struct wpa_driver_associate_params {
+- 	 */
+- 	int freq;
++@@ -414,6 +415,11 @@ struct wpa_driver_associate_params {
++ 	 * responsible for selecting with which BSS to associate. */
++ 	const u8 *bssid;
+  
+ +	int beacon_interval;
+ +	int fixed_freq;
+@@ -32,11 +32,11 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
+ +	int mcast_rate;
+ +
+  	/**
+- 	 * bg_scan_period - Background scan period in seconds, 0 to disable
+- 	 * background scan, or -1 to indicate no change to default driver
++ 	 * bssid_hint - BSSID of a proposed AP
++ 	 *
+ --- a/wpa_supplicant/config.c
+ +++ b/wpa_supplicant/config.c
+-@@ -14,6 +14,7 @@
++@@ -15,6 +15,7 @@
+  #include "rsn_supp/wpa.h"
+  #include "eap_peer/eap.h"
+  #include "p2p/p2p.h"
+@@ -44,7 +44,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
+  #include "config.h"
+  
+  
+-@@ -1512,6 +1513,97 @@ static char * wpa_config_write_psk_list(
++@@ -1527,6 +1528,97 @@ static char * wpa_config_write_psk_list(
+  
+  #endif /* CONFIG_P2P */
+  
+@@ -142,7 +142,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
+  /* Helper macros for network block parser */
+  
+  #ifdef OFFSET
+-@@ -1715,6 +1807,9 @@ static const struct parse_data ssid_fiel
++@@ -1733,6 +1825,9 @@ static const struct parse_data ssid_fiel
+  	{ INT(ap_max_inactivity) },
+  	{ INT(dtim_period) },
+  	{ INT(beacon_int) },
+@@ -162,7 +162,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
+  
+  #define MAX_SSID_LEN 32
+  
+-@@ -620,6 +621,10 @@ struct wpa_ssid {
++@@ -636,6 +637,10 @@ struct wpa_ssid {
+  	 * dereferences since it may not be updated in all cases.
+  	 */
+  	void *parent_cred;
+@@ -175,24 +175,11 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
+  #endif /* CONFIG_SSID_H */
+ --- a/wpa_supplicant/wpa_supplicant.c
+ +++ b/wpa_supplicant/wpa_supplicant.c
+-@@ -1623,15 +1623,24 @@ void wpa_supplicant_associate(struct wpa
+- 		params.ssid_len = ssid->ssid_len;
+- 	}
+- 
+--	if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
+--	    wpa_s->conf->ap_scan == 2) {
+--		params.bssid = ssid->bssid;
+--		params.fixed_bssid = 1;
+-+	if (ssid->mode == WPAS_MODE_IBSS) {
+-+		if (ssid->bssid_set && wpa_s->conf->ap_scan == 2) {
+-+			params.bssid = ssid->bssid;
+-+			params.fixed_bssid = 1;
+-+		}
+-+		if (ssid->frequency > 0 && params.freq == 0)
+-+			/* Initial channel for IBSS */
+-+			params.freq = ssid->frequency;
++@@ -1791,6 +1791,13 @@ static void wpas_start_assoc_cb(struct w
++ 			params.beacon_int = ssid->beacon_int;
++ 		else
++ 			params.beacon_int = wpa_s->conf->beacon_int;
+ +		params.fixed_freq = ssid->fixed_freq;
+-+		params.beacon_interval = ssid->beacon_int;
+ +		i = 0;
+ +		while (i < NL80211_MAX_SUPP_RATES) {
+ +			params.rates[i] = ssid->rates[i];
+@@ -201,9 +188,4 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
+ +		params.mcast_rate = ssid->mcast_rate;
+  	}
+  
+--	if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
+--	    params.freq == 0)
+--		params.freq = ssid->frequency; /* Initial channel for IBSS */
+  	params.wpa_ie = wpa_ie;
+- 	params.wpa_ie_len = wpa_ie_len;
+- 	params.pairwise_suite = cipher_pairwise;
+diff --git a/package/hostapd/patches/501-driver_nl80211-use-new-parameters-during-ibss-join.patch b/package/hostapd/patches/501-driver_nl80211-use-new-parameters-during-ibss-join.patch
+index 565bbc9..c774682 100644
+--- a/package/hostapd/patches/501-driver_nl80211-use-new-parameters-during-ibss-join.patch
++++ b/package/hostapd/patches/501-driver_nl80211-use-new-parameters-during-ibss-join.patch
+@@ -10,7 +10,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
+ 
+ --- a/src/drivers/driver_nl80211.c
+ +++ b/src/drivers/driver_nl80211.c
+-@@ -7903,7 +7903,7 @@ static int wpa_driver_nl80211_ibss(struc
++@@ -8455,7 +8455,7 @@ static int wpa_driver_nl80211_ibss(struc
+  				   struct wpa_driver_associate_params *params)
+  {
+  	struct nl_msg *msg;
+@@ -19,9 +19,9 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
+  	int count = 0;
+  
+  	wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
+-@@ -7936,6 +7936,37 @@ retry:
+- 	wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq);
+- 	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
++@@ -8494,6 +8494,37 @@ retry:
++ 			    params->beacon_int);
++ 	}
+  
+ +	if (params->fixed_freq) {
+ +		wpa_printf(MSG_DEBUG, "  * fixed_freq");
+diff --git a/package/hostapd/patches/502-wpa_s-support-htmode-param.patch b/package/hostapd/patches/502-wpa_s-support-htmode-param.patch
+index adb20a2..fdba6d7 100644
+--- a/package/hostapd/patches/502-wpa_s-support-htmode-param.patch
++++ b/package/hostapd/patches/502-wpa_s-support-htmode-param.patch
+@@ -16,7 +16,7 @@ Signed-off-by: Antonio Quartulli <ordex@autistici.org>
+ 
+ --- a/src/drivers/driver.h
+ +++ b/src/drivers/driver.h
+-@@ -409,6 +409,8 @@ struct wpa_driver_associate_params {
++@@ -419,6 +419,8 @@ struct wpa_driver_associate_params {
+  	int fixed_freq;
+  	unsigned char rates[NL80211_MAX_SUPP_RATES];
+  	int mcast_rate;
+@@ -24,10 +24,10 @@ Signed-off-by: Antonio Quartulli <ordex@autistici.org>
+ +	unsigned int htmode;
+  
+  	/**
+- 	 * bg_scan_period - Background scan period in seconds, 0 to disable
++ 	 * bssid_hint - BSSID of a proposed AP
+ --- a/src/drivers/driver_nl80211.c
+ +++ b/src/drivers/driver_nl80211.c
+-@@ -7967,6 +7967,22 @@ retry:
++@@ -8525,6 +8525,22 @@ retry:
+  		NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, params->mcast_rate);
+  	}
+  
+@@ -52,7 +52,7 @@ Signed-off-by: Antonio Quartulli <ordex@autistici.org>
+  		goto nla_put_failure;
+ --- a/wpa_supplicant/config.c
+ +++ b/wpa_supplicant/config.c
+-@@ -1544,6 +1544,71 @@ static char * wpa_config_write_mcast_rat
++@@ -1559,6 +1559,71 @@ static char * wpa_config_write_mcast_rat
+  }
+  #endif /* NO_CONFIG_WRITE */
+  
+@@ -124,7 +124,7 @@ Signed-off-by: Antonio Quartulli <ordex@autistici.org>
+  static int wpa_config_parse_rates(const struct parse_data *data,
+  				  struct wpa_ssid *ssid, int line,
+  				  const char *value)
+-@@ -1810,6 +1875,7 @@ static const struct parse_data ssid_fiel
++@@ -1828,6 +1893,7 @@ static const struct parse_data ssid_fiel
+  	{ INT_RANGE(fixed_freq, 0, 1) },
+  	{ FUNC(rates) },
+  	{ FUNC(mcast_rate) },
+@@ -134,7 +134,7 @@ Signed-off-by: Antonio Quartulli <ordex@autistici.org>
+  #undef OFFSET
+ --- a/wpa_supplicant/config_ssid.h
+ +++ b/wpa_supplicant/config_ssid.h
+-@@ -625,6 +625,8 @@ struct wpa_ssid {
++@@ -641,6 +641,8 @@ struct wpa_ssid {
+  	int fixed_freq;
+  	unsigned char rates[NL80211_MAX_SUPP_RATES];
+  	double mcast_rate;
+@@ -145,7 +145,7 @@ Signed-off-by: Antonio Quartulli <ordex@autistici.org>
+  #endif /* CONFIG_SSID_H */
+ --- a/wpa_supplicant/wpa_supplicant.c
+ +++ b/wpa_supplicant/wpa_supplicant.c
+-@@ -1639,6 +1639,8 @@ void wpa_supplicant_associate(struct wpa
++@@ -1798,6 +1798,8 @@ static void wpas_start_assoc_cb(struct w
+  			i++;
+  		}
+  		params.mcast_rate = ssid->mcast_rate;
+diff --git a/package/hostapd/patches/510-wpa_supplicant_p2p_parse_ifcomb.patch b/package/hostapd/patches/510-wpa_supplicant_p2p_parse_ifcomb.patch
+deleted file mode 100644
+index fe72ee2..0000000
+--- a/package/hostapd/patches/510-wpa_supplicant_p2p_parse_ifcomb.patch
++++ /dev/null
+@@ -1,18 +0,0 @@
+---- a/src/drivers/driver_nl80211.c
+-+++ b/src/drivers/driver_nl80211.c
+-@@ -3157,10 +3157,12 @@ static int wiphy_info_iface_comb_process
+- 	}
+- 
+- 	if (combination_has_p2p && combination_has_mgd) {
+--		info->p2p_concurrent = 1;
+--		info->num_multichan_concurrent =
+-+		int num_channels =
+- 			nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]);
+--		return 1;
+-+
+-+		info->p2p_concurrent = 1;
+-+		if (info->num_multichan_concurrent < num_channels)
+-+			info->num_multichan_concurrent = num_channels;
+- 	}
+- 
+- 	return 0;
+diff --git a/package/mac80211/Makefile b/package/mac80211/Makefile
+index 9a7093c..e19f30e 100644
+--- a/package/mac80211/Makefile
++++ b/package/mac80211/Makefile
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2007-2013 OpenWrt.org
++# Copyright (C) 2007-2014 OpenWrt.org
+ #
+ # This is free software, licensed under the GNU General Public License v2.
+ # See /LICENSE for more information.
+@@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk
+ 
+ PKG_NAME:=mac80211
+ 
+-PKG_VERSION:=2014-01-23.1
++PKG_VERSION:=2014-03-31
+ PKG_RELEASE:=1
+ PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
+ PKG_BACKPORT_VERSION:=
+-PKG_MD5SUM:=8db16edbdaf4abc2e9c2f3b6c86736a6
++PKG_MD5SUM:=8b5cf82d6defc5867511014af4afc0b6
+ 
+ PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
+ PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
+@@ -105,12 +105,12 @@ Generic IEEE 802.11 Networking Stack (mac80211)
+ endef
+ 
+ PKG_LINUX_FIRMWARE_NAME:=linux-firmware
+-PKG_LINUX_FIRMWARE_VERSION:=7d0c7a8cfd78388d90cc784a185b19dcbdbce824
++PKG_LINUX_FIRMWARE_VERSION:=f8c22c692bdee57a20b092e647464ff6176df3ed
+ PKG_LINUX_FIRMWARE_SOURCE:=$(PKG_LINUX_FIRMWARE_NAME)-$(PKG_LINUX_FIRMWARE_VERSION).tar.bz2
+ PKG_LINUX_FIRMWARE_PROTO:=git
+ PKG_LINUX_FIRMWARE_SOURCE_URL:=git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
+ PKG_LINUX_FIRMWARE_SUBDIR:=$(PKG_LINUX_FIRMWARE_NAME)-$(PKG_LINUX_FIRMWARE_VERSION)
+-PKG_LINUX_FIRMWARE_MIRROR_MD5SUM:=837a1a9456c1ec8b428cc0b2b08a331b
++PKG_LINUX_FIRMWARE_MIRROR_MD5SUM:=e219333f01835c6e556875a9e0deb3f9
+ 
+ define Download/linux-firmware
+   FILE:=$(PKG_LINUX_FIRMWARE_SOURCE)
+@@ -124,7 +124,7 @@ endef
+ $(eval $(call Download,linux-firmware))
+ 
+ PKG_ATH10K_LINUX_FIRMWARE_NAME:=ath10k-firmware
+-PKG_ATH10K_LINUX_FIRMWARE_VERSION:=d86e78e5c6be34329936c8bd73a212700437be2e
++PKG_ATH10K_LINUX_FIRMWARE_VERSION:=38eeda3ae6f90fde5546bdd48ee4ff3090f238c0
+ PKG_ATH10K_LINUX_FIRMWARE_SOURCE:=$(PKG_ATH10K_LINUX_FIRMWARE_NAME)-$(PKG_ATH10K_LINUX_FIRMWARE_VERSION).tar.bz2
+ PKG_ATH10K_LINUX_FIRMWARE_PROTO:=git
+ PKG_ATH10K_LINUX_FIRMWARE_SOURCE_URL:=https://github.com/kvalo/ath10k-firmware.git
+@@ -606,6 +606,19 @@ Atheros IEEE 802.11ac family of chipsets. For now only
+ PCI is supported.
+ endef
+ 
++define KernelPackage/ath10k/config
++  if PACKAGE_kmod-ath10k
++
++	config ATH10K_STA_FW
++		bool "Firmware optimized for STA operation"
++		default n
++		help
++		  Use the ath10k firmware optimized for wireless client instead
++		  of access point operation.
++
++  endif
++endef
++
+ define KernelPackage/carl9170
+   $(call KernelPackage/mac80211/Default)
+   TITLE:=Driver for Atheros AR9170 USB sticks
+@@ -844,6 +857,13 @@ define KernelPackage/iwlagn/config
+ 		  Download and install firmware for:
+ 		    Intel Centrino Advanced-N 6230, Wireless-N 1030, Wireless-N 130 and Advanced-N 6235
+ 
++	config IWL7260_FW
++		bool "Intel 7260 Firmware"
++		default y
++		help
++		  Download and install firmware for:
++		    Intel Dual Band Wireless-N 7260 and Intel Dual Band Wireless-AC 7260
++
+ 	config IWL100_FW
+ 		bool "Intel 100 Firmware"
+ 		default y
+@@ -1639,8 +1659,7 @@ define KernelPackage/wl18xx/install
+ 	$(INSTALL_DIR) $(1)/lib/firmware/ti-connectivity
+ 	$(INSTALL_DATA) \
+ 		$(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-conf.bin \
+-		$(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-fw.bin \
+-		$(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-fw-2.bin \
++		$(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/ti-connectivity/wl18xx-fw-3.bin \
+ 		$(1)/lib/firmware/ti-connectivity
+ endef
+ 
+@@ -1664,10 +1683,19 @@ endef
+ 
+ define KernelPackage/ath10k/install
+ 	$(INSTALL_DIR) $(1)/lib/firmware/ath10k/QCA988X/hw2.0
++ifeq ($(CONFIG_ATH10K_STA_FW),y)
++	$(INSTALL_DATA) \
++		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/board.bin \
++		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/
++	$(INSTALL_DATA) \
++		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/main/firmware-2.bin_999.999.0.636 \
++		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-2.bin
++else
+ 	$(INSTALL_DATA) \
+ 		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/board.bin \
+ 		$(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/firmware-2.bin \
+ 		$(1)/lib/firmware/ath10k/QCA988X/hw2.0/
++endif
+ endef
+ 
+ define KernelPackage/mwl8k/install
+@@ -1714,6 +1742,9 @@ endif
+ ifneq ($(CONFIG_IWL6030_FW),)
+ 	$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-6000g2b-6.ucode $(1)/lib/firmware
+ endif
++ifneq ($(CONFIG_IWL7260_FW),)
++	$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-7260-7.ucode $(1)/lib/firmware
++endif
+ ifneq ($(CONFIG_IWL100_FW),)
+ 	$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/iwlwifi-100-5.ucode $(1)/lib/firmware
+ endif
+diff --git a/package/mac80211/files/regdb.txt b/package/mac80211/files/regdb.txt
+index 2badb21..fcab208 100644
+--- a/package/mac80211/files/regdb.txt
++++ b/package/mac80211/files/regdb.txt
+@@ -1,211 +1,216 @@
+ # This is the world regulatory domain
+ country 00:
+-	(2402 - 2472 @ 40), (3, 20)
++	(2402 - 2472 @ 40), (20)
+ 	# Channel 12 - 13.
+-	(2457 - 2482 @ 40), (3, 20), PASSIVE-SCAN, NO-IBSS
++	(2457 - 2482 @ 40), (20), NO-IR
+ 	# Channel 14. Only JP enables this and for 802.11b only
+-	(2474 - 2494 @ 20), (3, 20), PASSIVE-SCAN, NO-IBSS, NO-OFDM
++	(2474 - 2494 @ 20), (20), NO-IR
+ 	# Channel 36 - 48
+-	(5170 - 5250 @ 80), (3, 20)
++	(5170 - 5250 @ 80), (20), NO-IR
+ 	# NB: 5260 MHz - 5700 MHz requies DFS
+ 	# Channel 149 - 165
+-	(5735 - 5835 @ 80), (3, 20), PASSIVE-SCAN, NO-IBSS
++	(5735 - 5835 @ 80), (20), NO-IR
+ 	# IEEE 802.11ad (60GHz), channels 1..3
+-	(57240 - 63720 @ 2160), (N/A, 0)
++	(57240 - 63720 @ 2160), (0)
+ 
+ 
+ country AD:
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
+-
+-country AE:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
+-
+-country AL:
+-	(2402 - 2482 @ 20), (N/A, 20)
+-
+-country AM:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 20), (N/A, 18)
+-	(5250 - 5330 @ 20), (N/A, 18), DFS
+-
+-country AN:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
+-
+-country AR:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
++
++country AE: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country AL: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20.00)
++	(5250 - 5330 @ 80), (20.00), DFS
++	(5490 - 5710 @ 80), (27.00), DFS
++
++country AM: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (18)
++	(5250 - 5330 @ 80), (18), DFS
++
++country AN: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++
++country AR: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country AT: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country AU:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
+-
+-country AW:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
+-
+-country AZ:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 18)
+-	(5250 - 5330 @ 40), (N/A, 18), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5710 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country AW: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++
++country AZ: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (18)
++	(5250 - 5330 @ 80), (18), DFS
+ 
+ country BA: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+-country BB:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (3, 23)
+-	(5250 - 5330 @ 40), (3, 23), DFS
+-	(5735 - 5835 @ 40), (3, 30)
++country BB: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (23)
++	(5250 - 5330 @ 80), (23), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+-country BD:
+-	(2402 - 2482 @ 40), (N/A, 20)
++country BD: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5735 - 5835 @ 80), (30)
+ 
+ country BE: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country BG: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 23)
+-	(5250 - 5290 @ 40), (N/A, 23), DFS
+-	(5490 - 5710 @ 40), (N/A, 30), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+-country BH:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 20), (N/A, 20)
+-	(5250 - 5330 @ 20), (N/A, 20), DFS
+-	(5735 - 5835 @ 20), (N/A, 20)
++country BH: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5735 - 5835 @ 80), (20)
+ 
+ country BL:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 18)
+-	(5250 - 5330 @ 40), (N/A, 18), DFS
+-
+-country BN:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5735 - 5835 @ 40), (N/A, 30)
+-
+-country BO:
+-	(2402 - 2482 @ 40), (N/A, 30)
+-	(5735 - 5835 @ 40), (N/A, 30)
+-
+-country BR:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
+-
+-country BY:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
+-
+-country BZ:
+-	(2402 - 2482 @ 40), (N/A, 30)
+-	(5735 - 5835 @ 40), (N/A, 30)
+-
+-country CA:
+-	(2402 - 2472 @ 40), (3, 27)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 40), (18)
++	(5250 - 5330 @ 40), (18), DFS
++
++country BN: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5735 - 5835 @ 80), (20)
++
++country BO: DFS-JP
++	(2402 - 2482 @ 40), (30)
++	(5735 - 5835 @ 80), (30)
++
++country BR: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country BY: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++
++country BZ: DFS-JP
++	(2402 - 2482 @ 40), (30)
++	(5735 - 5835 @ 80), (30)
++
++country CA: DFS-FCC
++	(2402 - 2472 @ 40), (30)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country CH: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
+-	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
+-
+-country CL:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5735 - 5835 @ 40), (N/A, 20)
+-
+-country CN:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5735 - 5835 @ 80), (N/A, 30)
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++	# 60 gHz band channels 1-4, ref: Etsi En 302 567
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
++
++country CL: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5735 - 5835 @ 80), (20)
++
++country CN: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (23)
++	(5250 - 5330 @ 80), (23), DFS
++	(5735 - 5835 @ 80), (30)
+ 	# 60 gHz band channels 1,4: 28dBm, channels 2,3: 44dBm
+ 	# ref: http://www.miit.gov.cn/n11293472/n11505629/n11506593/n11960250/n11960606/n11960700/n12330791.files/n12330790.pdf
+-	(57240 - 59400 @ 2160), (N/A, 28)
+-	(59400 - 63720 @ 2160), (N/A, 44)
+-	(63720 - 65880 @ 2160), (N/A, 28)
+-
+-country CO:
+-	(2402 - 2472 @ 40), (3, 27)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
+-
+-country CR:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
++	(57240 - 59400 @ 2160), (28)
++	(59400 - 63720 @ 2160), (44)
++	(63720 - 65880 @ 2160), (28)
++
++country CO: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country CR: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country CY: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ # Data from http://www.ctu.eu/164/download/VOR/VOR-12-08-2005-34.pdf
+ # and http://www.ctu.eu/164/download/VOR/VOR-12-05-2007-6-AN.pdf
+ # Power at 5250 - 5350 MHz and 5470 - 5725 MHz can be doubled if TPC is
+ # implemented.
+ country CZ: DFS-ETSI
+-	(2400 - 2483.5 @ 40), (N/A, 100 mW)
+-	(5150 - 5250 @ 80), (N/A, 200 mW), NO-OUTDOOR
+-	(5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS
+-	(5470 - 5725 @ 80), (N/A, 500 mW), DFS
++	(2400 - 2483.5 @ 40), (100 mW)
++	(5150 - 5250 @ 80), (200 mW), NO-OUTDOOR
++	(5250 - 5350 @ 80), (100 mW), NO-OUTDOOR
++	(5470 - 5725 @ 80), (500 mW), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ # Data from "Frequenznutzungsplan" (as published in April 2008), downloaded from
+ # http://www.bundesnetzagentur.de/cae/servlet/contentblob/38448/publicationFile/2659/Frequenznutzungsplan2008_Id17448pdf.pdf
+@@ -221,542 +226,555 @@ country CZ: DFS-ETSI
+ 
+ country DE: DFS-ETSI
+ 	# entries 279004 and 280006
+-	(2400 - 2483.5 @ 40), (N/A, 100 mW)
+-	# entry 303005
+-	(5150 - 5250 @ 80), (N/A, 100 mW), NO-OUTDOOR
+-	# entries 304002 and 305002
+-	(5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS
++	(2400 - 2483.5 @ 40), (100 mW)
++	# entry 303005, 304002 and 305002
++	(5150 - 5350 @ 80), (100 mW), NO-OUTDOOR
+ 	# entries 308002, 309001 and 310003
+-	(5470 - 5725 @ 80), (N/A, 500 mW), DFS
++	(5470 - 5725 @ 80), (500 mW), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country DK: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
+-	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
+-
+-country DO:
+-	(2402 - 2472 @ 40), (3, 27)
+-	(5170 - 5250 @ 40), (3, 17)
+-	(5250 - 5330 @ 40), (3, 23), DFS
+-	(5735 - 5835 @ 40), (3, 30)
+-
+-country DZ:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-
+-country EC:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++	# 60 gHz band channels 1-4, ref: Etsi En 302 567
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
++
++country DO: DFS-FCC
++	(2402 - 2472 @ 40), (30)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (23), DFS
++	(5735 - 5835 @ 80), (30)
++
++country DZ: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5170.000 - 5250.000 @ 80.000), (23.00)
++	(5250.000 - 5330.000 @ 80.000), (23.00), DFS
++	(5490.000 - 5670.000 @ 80.000), (23.00), DFS
++
++country EC: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country EE: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+-country EG:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 20), (N/A, 20)
+-	(5250 - 5330 @ 20), (N/A, 20), DFS
++country EG: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
+ 
+ country ES: DFS-ETSI
+-	(2400 - 2483.5 @ 40), (N/A, 100 mW)
+-	(5150 - 5250 @ 80), (N/A, 100 mW), NO-OUTDOOR
+-	(5250 - 5350 @ 80), (N/A, 100 mW), NO-OUTDOOR, DFS
+-	(5470 - 5725 @ 80), (N/A, 500 mW), DFS
++	(2400 - 2483.5 @ 40), (100 mW)
++	(5150 - 5250 @ 80), (100 mW), NO-OUTDOOR
++	(5250 - 5350 @ 80), (100 mW), NO-OUTDOOR
++	(5470 - 5725 @ 80), (500 mW), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country FI: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country FR: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+-country GE:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 18)
+-	(5250 - 5330 @ 40), (N/A, 18), DFS
++country GE: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (18)
++	(5250 - 5330 @ 80), (18), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country GB: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+-country GD:
+-	(2402 - 2472 @ 40), (3, 27)
+-	(5170 - 5250 @ 40), (3, 17)
+-	(5250 - 5330 @ 40), (3, 20), DFS
+-	(5490 - 5710 @ 40), (3, 20), DFS
+-	(5735 - 5835 @ 40), (3, 30)
++country GD: DFS-FCC
++	(2402 - 2472 @ 40), (30)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country GR: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country GL: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 20), (N/A, 20)
+-	(5250 - 5330 @ 20), (N/A, 20), DFS
+-	(5490 - 5710 @ 20), (N/A, 27), DFS
+-
+-country GT:
+-	(2402 - 2472 @ 40), (3, 27)
+-	(5170 - 5250 @ 40), (3, 17)
+-	(5250 - 5330 @ 40), (3, 23), DFS
+-	(5735 - 5835 @ 40), (3, 30)
+-
+-country GU:
+-	(2402 - 2472 @ 40), (3, 27)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
+-
+-country HN:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (3, 17)
+-	(5250 - 5330 @ 40), (3, 20), DFS
+-	(5490 - 5710 @ 40), (3, 20), DFS
+-	(5735 - 5835 @ 40), (3, 30)
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++
++country GT: DFS-FCC
++	(2402 - 2472 @ 40), (30)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (23), DFS
++	(5735 - 5835 @ 80), (30)
++
++country GU: DFS-FCC
++	(2402 - 2472 @ 40), (30)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country HN: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country HK:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5710 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country HR: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+-country HT:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
++country HT: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 
+ country HU: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+-country ID:
++country ID: DFS-JP
+ 	# ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5735 - 5815 @ 80), (N/A, 20)
++	(2402 - 2482 @ 40), (20)
++	(5735 - 5815 @ 80), (23)
+ 
+ country IE: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+-country IL:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5150 - 5250 @ 80), (N/A, 200 mW), NO-OUTDOOR
+-	(5250 - 5350 @ 80), (N/A, 200 mW), NO-OUTDOOR, DFS
++country IL: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5150 - 5350 @ 80), (200 mW), NO-OUTDOOR
+ 
+-country IN:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5735 - 5835 @ 40), (N/A, 20)
++country IN: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5735 - 5835 @ 80), (20)
+ 
+ country IS: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+-country IR:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5735 - 5835 @ 40), (N/A, 30)
++country IR: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5735 - 5835 @ 80), (30)
+ 
+ country IT: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
+-	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
+-
+-country JM:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (3, 17)
+-	(5250 - 5330 @ 40), (3, 20), DFS
+-	(5490 - 5710 @ 40), (3, 20), DFS
+-	(5735 - 5835 @ 40), (3, 30)
+-
+-country JP:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(2474 - 2494 @ 20), (N/A, 20), NO-OFDM
+-	(4910 - 4990 @ 40), (N/A, 23)
+-	(5030 - 5090 @ 40), (N/A, 23)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 160), (N/A, 23), DFS
+-
+-country JO:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 18)
+-
+-country KE:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5735 - 5835 @ 40), (N/A, 30)
+-
+-country KH:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
+-
+-country KP:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5330 @ 40), (3, 20)
+-	(5160 - 5250 @ 40), (3, 20), DFS
+-	(5490 - 5630 @ 40), (3, 30), DFS
+-	(5735 - 5815 @ 40), (3, 30)
+-
+-country KR:
+-	(2402 - 2482 @ 20), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 20)
+-	(5250 - 5330 @ 80), (3, 20), DFS
+-	(5490 - 5630 @ 80), (3, 30), DFS
+-	(5735 - 5815 @ 80), (3, 30)
+-
+-country KW:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++	# 60 gHz band channels 1-4, ref: Etsi En 302 567
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
++
++country JM: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country JP: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(2474 - 2494 @ 20), (20), NO-OFDM
++	(4910 - 4990 @ 40), (23)
++	(5030 - 5090 @ 40), (23)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 160), (23), DFS
++
++country JO: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (23)
++	(5735 - 5835 @ 80), (23)
++
++country KE: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (23)
++	(5490 - 5570 @ 80), (30), DFS
++	(5735 - 5775 @ 40), (23)
++
++country KH: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++
++country KP: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5630 @ 80), (30), DFS
++	(5735 - 5815 @ 80), (30)
++
++country KR: DFS-JP
++	(2402 - 2482 @ 20), (20)
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (30), DFS
++	(5735 - 5815 @ 80), (30)
++
++country KW: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
+ 
+ country KZ:
+-	(2402 - 2482 @ 40), (N/A, 20)
++	(2402 - 2482 @ 40), (20)
+ 
+-country LB:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5735 - 5835 @ 40), (N/A, 30)
++country LB: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country LI: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
+-
+-country LK:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 20), (3, 17)
+-	(5250 - 5330 @ 20), (3, 20), DFS
+-	(5490 - 5710 @ 20), (3, 20), DFS
+-	(5735 - 5835 @ 20), (3, 30)
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++
++country LK: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country LT: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country LU: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country LV: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country MC: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 18)
+-	(5250 - 5330 @ 40), (N/A, 18), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 
+-country MA:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 23)
+-	(5735 - 5835 @ 80), (N/A, 23)
++country MA: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
+ 
+ country MO:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (3, 23)
+-	(5250 - 5330 @ 40), (3, 23), DFS
+-	(5735 - 5835 @ 40), (3, 30)
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 40), (23)
++	(5250 - 5330 @ 40), (23), DFS
++	(5735 - 5835 @ 40), (30)
+ 
+ country MK: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country MT: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
+-	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
+-
+-country MY:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 17)
+-	(5250 - 5330 @ 80), (N/A, 23), DFS
+-	(5735 - 5835 @ 80), (N/A, 30)
+-
+-country MX:
+-	(2402 - 2472 @ 40), (3, 27)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++	# 60 gHz band channels 1-4, ref: Etsi En 302 567
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
++
++country MY: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (23), DFS
++	(5735 - 5835 @ 80), (30)
++
++country MX: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country NL: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20), NO-OUTDOOR
+-	(5250 - 5330 @ 80), (N/A, 20), NO-OUTDOOR, DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5330 @ 80), (20), NO-OUTDOOR
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country NO: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
+-	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
+-
+-country NP:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5735 - 5835 @ 40), (N/A, 30)
+-
+-country NZ:
+-	(2402 - 2482 @ 40), (N/A, 30)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
+-
+-country OM:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (3, 17)
+-	(5250 - 5330 @ 40), (3, 20), DFS
+-	(5490 - 5710 @ 40), (3, 20), DFS
+-	(5735 - 5835 @ 40), (3, 30)
+-
+-country PA:
+-	(2402 - 2472 @ 40), (3, 27)
+-	(5170 - 5250 @ 40), (3, 17)
+-	(5250 - 5330 @ 40), (3, 23), DFS
+-	(5735 - 5835 @ 40), (3, 30)
+-
+-country PE:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
+-
+-country PG:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (3, 17)
+-	(5250 - 5330 @ 40), (3, 23), DFS
+-	(5735 - 5835 @ 40), (3, 30)
+-
+-country PH:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
+-
+-country PK:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5735 - 5835 @ 40), (N/A, 30)
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++	# 60 gHz band channels 1-4, ref: Etsi En 302 567
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
++
++country NP: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5735 - 5835 @ 80), (20)
++
++country NZ: DFS-FCC
++	(2402 - 2482 @ 40), (30)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country OM: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++
++country PA: DFS-FCC
++	(2402 - 2472 @ 40), (30)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (23), DFS
++	(5735 - 5835 @ 80), (30)
++
++country PE: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country PG: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country PH: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country PK: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5735 - 5835 @ 80), (30)
+ 
+ country PL: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country PT: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+-country PR:
+-	(2402 - 2472 @ 40), (3, 27)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
++country PR: DFS-FCC
++	(2402 - 2472 @ 40), (30)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+-country QA:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5735 - 5835 @ 40), (N/A, 30)
++country QA: DFS-JP
++	(2402 - 2482 @ 40), (20)
++	(5735 - 5835 @ 80), (30)
+ 
+ country RO: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ 
+ # Source:
+ # http://www.ratel.rs/upload/documents/Plan_namene/Plan_namene-sl_glasnik.pdf
+-country RS:
+-	(2400 - 2483.5 @ 40), (N/A, 100 mW)
+-	(5150 - 5350 @ 40), (N/A, 200 mW), NO-OUTDOOR
+-	(5470 - 5725 @ 20), (3, 1000 mW), DFS
+-	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
+-
+-country RU:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5330 @ 40), (N/A, 20)
+-	(5650 - 5710 @ 40), (N/A, 30)
+-	(5735 - 5835 @ 40), (N/A, 30)
+-
+-country RW:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5735 - 5835 @ 40), (N/A, 30)
+-
+-country SA:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
++country RS: DFS-ETSI
++	(2400 - 2483.5 @ 40), (100 mW)
++	(5150 - 5350 @ 40), (200 mW), NO-OUTDOOR
++	(5470 - 5725 @ 20), (1000 mW), DFS
++	# 60 gHz band channels 1-4, ref: Etsi En 302 567
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
++
++country RU: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5650 - 5730 @ 80), (30), DFS
++	(5735 - 5835 @ 80), (30)
++
++country RW: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country SA: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 
+ country SE: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+-country SG:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
++country SG: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country SI: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (N/A, 20)
+-	(5250 - 5330 @ 40), (N/A, 20), DFS
+-	(5490 - 5710 @ 40), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country SK: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+-country SV:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 20), (3, 17)
+-	(5250 - 5330 @ 20), (3, 23), DFS
+-	(5735 - 5835 @ 20), (3, 30)
++country SV: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (23), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country SY:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-
+-country TW:
+-	(2402 - 2472 @ 40), (3, 27)
+-	(5270 - 5330 @ 40), (3, 17), DFS
+-	(5490 - 5710 @ 80), (3, 30), DFS
+-	(5735 - 5815 @ 80), (3, 30)
+-
+-country TH:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
+-
+-country TT:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (3, 17)
+-	(5250 - 5330 @ 40), (3, 20), DFS
+-	(5490 - 5710 @ 40), (3, 20), DFS
+-	(5735 - 5835 @ 40), (3, 30)
+-
+-country TN:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 20), (N/A, 20)
+-	(5250 - 5330 @ 20), (N/A, 20), DFS
++	(2402 - 2482 @ 40), (20)
++
++country TW: DFS-JP
++	(2402 - 2472 @ 40), (30)
++	(5270 - 5330 @ 40), (17), DFS
++	(5490 - 5590 @ 80), (30), DFS
++	(5650 - 5710 @ 40), (30), DFS
++	(5735 - 5835 @ 80), (30)
++
++country TH: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country TT: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country TN: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
+ 
+ country TR: DFS-ETSI
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (N/A, 20)
+-	(5250 - 5330 @ 80), (N/A, 20), DFS
+-	(5490 - 5710 @ 80), (N/A, 27), DFS
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+  
+ # Source:
+ # #914 / 06 Sep 2007: http://www.ucrf.gov.ua/uk/doc/nkrz/1196068874
+@@ -765,59 +783,63 @@ country TR: DFS-ETSI
+ # Listed 5GHz range is a lowest common denominator for all related
+ # rules in the referenced laws. Such a range is used because of
+ # disputable definitions there.
+-country UA:
+-	(2400 - 2483.5 @ 40), (N/A, 20), NO-OUTDOOR
+-	(5150 - 5350 @ 40), (N/A, 20), NO-OUTDOOR
++country UA: DFS-ETSI
++	(2400 - 2483.5 @ 40), (20), NO-OUTDOOR
++	(5150 - 5350 @ 40), (20), NO-OUTDOOR
++	(5490 - 5670 @ 80), (20), DFS
++	(5735 - 5835 @ 80), (20)
+ 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
+-	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++	(57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ 
+ country US: DFS-FCC
+-	(2402 - 2472 @ 40), (3, 27)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5600 @ 80), (3, 24), DFS
+-	(5650 - 5710 @ 40), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
++	(2402 - 2472 @ 40), (30)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (23), DFS
++	(5735 - 5835 @ 80), (30)
+ 	# 60g band
+ 	# reference: http://cfr.regstoday.com/47cfr15.aspx#47_CFR_15p255
+ 	# channels 1,2,3, EIRP=40dBm(43dBm peak)
+-	(57240 - 63720 @ 2160), (N/A, 40)
+-
+-country UY:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 40), (3, 17)
+-	(5250 - 5330 @ 40), (3, 20), DFS
+-	(5490 - 5710 @ 40), (3, 20), DFS
+-	(5735 - 5835 @ 40), (3, 30)
+-
+-country UZ:
+-	(2402 - 2472 @ 40), (3, 27)
+-	(5170 - 5250 @ 40), (3, 17)
+-	(5250 - 5330 @ 40), (3, 20), DFS
+-	(5490 - 5710 @ 40), (3, 20), DFS
+-	(5735 - 5835 @ 40), (3, 30)
+-
+-country VE:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5735 - 5815 @ 40), (N/A, 23)
+-
+-country VN:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
++	(57240 - 63720 @ 2160), (40)
++
++country UY: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country UZ: DFS-FCC
++	(2402 - 2472 @ 40), (30)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
++
++country VE: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (23), DFS
++	(5735 - 5835 @ 80), (30)
++
++country VN: DFS-FCC
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (17)
++	(5250 - 5330 @ 80), (24), DFS
++	(5490 - 5730 @ 80), (24), DFS
++	(5735 - 5835 @ 80), (30)
+ 
+ country YE:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-
+-country ZA:
+-	(2402 - 2482 @ 40), (N/A, 20)
+-	(5170 - 5250 @ 80), (3, 17)
+-	(5250 - 5330 @ 80), (3, 24), DFS
+-	(5490 - 5710 @ 80), (3, 24), DFS
+-	(5735 - 5835 @ 80), (3, 30)
+-
+-country ZW:
+-	(2402 - 2482 @ 40), (N/A, 20)
++	(2402 - 2482 @ 40), (20)
++
++country ZA: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
++
++country ZW: DFS-ETSI
++	(2402 - 2482 @ 40), (20)
++	(5170 - 5250 @ 80), (20)
++	(5250 - 5330 @ 80), (20), DFS
++	(5490 - 5710 @ 80), (27), DFS
+ 
+diff --git a/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch b/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch
+index 584fb05..8d97224 100644
+--- a/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch
++++ b/package/mac80211/patches/004-backports-add-led_trigger_blink-_oneshot.patch
+@@ -18,8 +18,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ 
+ --- a/backport-include/backport/leds-disabled.h
+ +++ b/backport-include/backport/leds-disabled.h
+-@@ -163,6 +163,19 @@ static inline void led_trigger_event(str
+- 				     enum led_brightness event)
++@@ -176,6 +176,19 @@ static inline void led_trigger_blink_one
++ 					     int invert)
+  {
+  }
+ +
+diff --git a/package/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch b/package/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch
+new file mode 100644
+index 0000000..55bffbc
+--- /dev/null
++++ b/package/mac80211/patches/005-make-genregdb.awk-skip-antenna-gain.patch
+@@ -0,0 +1,44 @@
++From: Luis R. Rodriguez <mcgrof@do-not-panic.com>
++Date: Wed, 23 Oct 2013 14:55:36 -0400
++Subject: [RFC] cfg80211: make genregdb.awk skip antenna gain
++
++Now that wireless-regdb doesn't include
++antenna gain lets skip parsing it completely
++for when CONFIG_CFG80211_INTERNAL_REGDB is
++enabled.
++
++Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com>
++---
++ net/wireless/genregdb.awk | 11 ++++-------
++ 1 file changed, 4 insertions(+), 7 deletions(-)
++ mode change 100644 => 100755 net/wireless/genregdb.awk
++
++--- a/net/wireless/genregdb.awk
+++++ b/net/wireless/genregdb.awk
++@@ -56,14 +56,11 @@ function parse_reg_rule()
++ 	end = $3
++ 	bw = $5
++ 	sub(/\),/, "", bw)
++-	gain = $6
++-	sub(/\(/, "", gain)
++-	sub(/,/, "", gain)
++-	power = $7
++-	sub(/\)/, "", power)
+++	power = $6
+++	sub(/\(/, "", power)
++ 	sub(/,/, "", power)
++ 	# power might be in mW...
++-	units = $8
+++	units = $7
++ 	sub(/\)/, "", units)
++ 	sub(/,/, "", units)
++ 	dfs_cac = $9
++@@ -86,7 +83,7 @@ function parse_reg_rule()
++ 	sub(/\(/, "", dfs_cac)
++ 	sub(/\)/, "", dfs_cac)
++ 	flagstr = ""
++-	for (i=8; i<=NF; i++)
+++	for (i=7; i<=NF; i++)
++ 		flagstr = flagstr $i
++ 	split(flagstr, flagarray, ",")
++ 	flags = ""
+diff --git a/package/mac80211/patches/060-no_local_ssb_bcma.patch b/package/mac80211/patches/060-no_local_ssb_bcma.patch
+index f4b9470..95f14f4 100644
+--- a/package/mac80211/patches/060-no_local_ssb_bcma.patch
++++ b/package/mac80211/patches/060-no_local_ssb_bcma.patch
+@@ -1,6 +1,6 @@
+ --- a/.local-symbols
+ +++ b/.local-symbols
+-@@ -379,42 +379,6 @@ USB_CDC_PHONET=
++@@ -402,42 +402,6 @@ USB_CDC_PHONET=
+  USB_IPHETH=
+  USB_SIERRA_NET=
+  USB_VL600=
+diff --git a/package/mac80211/patches/070-add-missing-header.patch b/package/mac80211/patches/070-add-missing-header.patch
+new file mode 100644
+index 0000000..9307804
+--- /dev/null
++++ b/package/mac80211/patches/070-add-missing-header.patch
+@@ -0,0 +1,10 @@
++--- a/compat/backport-3.15.c
+++++ b/compat/backport-3.15.c
++@@ -11,6 +11,7 @@
++ #include <linux/kernel.h>
++ #include <linux/device.h>
++ #include <linux/of.h>
+++#include <linux/string.h>
++ 
++ /**
++  * devm_kstrdup - Allocate resource managed space and
+diff --git a/package/mac80211/patches/100-revert_aes_ccm_port.patch b/package/mac80211/patches/100-revert_aes_ccm_port.patch
+index 4654bc8..ac7d6b3 100644
+--- a/package/mac80211/patches/100-revert_aes_ccm_port.patch
++++ b/package/mac80211/patches/100-revert_aes_ccm_port.patch
+@@ -1,3 +1,104 @@
++--- a/net/mac80211/wpa.c
+++++ b/net/mac80211/wpa.c
++@@ -301,15 +301,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
++ }
++ 
++ 
++-static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
+++static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
+++				int encrypted)
++ {
++ 	__le16 mask_fc;
++ 	int a4_included, mgmt;
++ 	u8 qos_tid;
++-	u16 len_a;
+++	u8 *b_0, *aad;
+++	u16 data_len, len_a;
++ 	unsigned int hdrlen;
++ 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
++ 
+++	memset(scratch, 0, 6 * AES_BLOCK_SIZE);
+++
+++	b_0 = scratch + 3 * AES_BLOCK_SIZE;
+++	aad = scratch + 4 * AES_BLOCK_SIZE;
+++
++ 	/*
++ 	 * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
++ 	 * Retry, PwrMgt, MoreData; set Protected
++@@ -331,21 +338,20 @@ static void ccmp_special_blocks(struct s
++ 	else
++ 		qos_tid = 0;
++ 
++-	/* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
++-	 * mode authentication are not allowed to collide, yet both are derived
++-	 * from this vector b_0. We only set L := 1 here to indicate that the
++-	 * data size can be represented in (L+1) bytes. The CCM layer will take
++-	 * care of storing the data length in the top (L+1) bytes and setting
++-	 * and clearing the other bits as is required to derive the two IVs.
++-	 */
++-	b_0[0] = 0x1;
+++	data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN;
+++	if (encrypted)
+++		data_len -= IEEE80211_CCMP_MIC_LEN;
++ 
+++	/* First block, b_0 */
+++	b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
++ 	/* Nonce: Nonce Flags | A2 | PN
++ 	 * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
++ 	 */
++ 	b_0[1] = qos_tid | (mgmt << 4);
++ 	memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
++ 	memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
+++	/* l(m) */
+++	put_unaligned_be16(data_len, &b_0[14]);
++ 
++ 	/* AAD (extra authenticate-only data) / masked 802.11 header
++ 	 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
++@@ -401,8 +407,7 @@ static int ccmp_encrypt_skb(struct ieee8
++ 	u8 *pos;
++ 	u8 pn[6];
++ 	u64 pn64;
++-	u8 aad[2 * AES_BLOCK_SIZE];
++-	u8 b_0[AES_BLOCK_SIZE];
+++	u8 scratch[6 * AES_BLOCK_SIZE];
++ 
++ 	if (info->control.hw_key &&
++ 	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
++@@ -455,9 +460,9 @@ static int ccmp_encrypt_skb(struct ieee8
++ 		return 0;
++ 
++ 	pos += IEEE80211_CCMP_HDR_LEN;
++-	ccmp_special_blocks(skb, pn, b_0, aad);
++-	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
++-				  skb_put(skb, IEEE80211_CCMP_MIC_LEN));
+++	ccmp_special_blocks(skb, pn, scratch, 0);
+++	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
+++				  pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN));
++ 
++ 	return 0;
++ }
++@@ -520,16 +525,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
++ 	}
++ 
++ 	if (!(status->flag & RX_FLAG_DECRYPTED)) {
++-		u8 aad[2 * AES_BLOCK_SIZE];
++-		u8 b_0[AES_BLOCK_SIZE];
+++		u8 scratch[6 * AES_BLOCK_SIZE];
++ 		/* hardware didn't decrypt/verify MIC */
++-		ccmp_special_blocks(skb, pn, b_0, aad);
+++		ccmp_special_blocks(skb, pn, scratch, 1);
++ 
++ 		if (ieee80211_aes_ccm_decrypt(
++-			    key->u.ccmp.tfm, b_0, aad,
+++			    key->u.ccmp.tfm, scratch,
++ 			    skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
++ 			    data_len,
++-			    skb->data + skb->len - IEEE80211_CCMP_MIC_LEN))
+++			    skb->data + skb->len - IEEE80211_CCMP_MIC_LEN,
+++			    skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN))
++ 			return RX_DROP_UNUSABLE;
++ 	}
++ 
+ --- a/net/mac80211/Kconfig
+ +++ b/net/mac80211/Kconfig
+ @@ -5,7 +5,6 @@ config MAC80211
+@@ -244,104 +345,3 @@
+  			u32 replays; /* dot11RSNAStatsCCMPReplays */
+  		} ccmp;
+  		struct {
+---- a/net/mac80211/wpa.c
+-+++ b/net/mac80211/wpa.c
+-@@ -301,16 +301,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
+- }
+- 
+- 
+--static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad,
+-+static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
+- 				int encrypted)
+- {
+- 	__le16 mask_fc;
+- 	int a4_included, mgmt;
+- 	u8 qos_tid;
+--	u16 len_a;
+-+	u8 *b_0, *aad;
+-+	u16 data_len, len_a;
+- 	unsigned int hdrlen;
+- 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+- 
+-+	memset(scratch, 0, 6 * AES_BLOCK_SIZE);
+-+
+-+	b_0 = scratch + 3 * AES_BLOCK_SIZE;
+-+	aad = scratch + 4 * AES_BLOCK_SIZE;
+-+
+- 	/*
+- 	 * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
+- 	 * Retry, PwrMgt, MoreData; set Protected
+-@@ -332,21 +338,20 @@ static void ccmp_special_blocks(struct s
+- 	else
+- 		qos_tid = 0;
+- 
+--	/* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
+--	 * mode authentication are not allowed to collide, yet both are derived
+--	 * from this vector b_0. We only set L := 1 here to indicate that the
+--	 * data size can be represented in (L+1) bytes. The CCM layer will take
+--	 * care of storing the data length in the top (L+1) bytes and setting
+--	 * and clearing the other bits as is required to derive the two IVs.
+--	 */
+--	b_0[0] = 0x1;
+-+	data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN;
+-+	if (encrypted)
+-+		data_len -= IEEE80211_CCMP_MIC_LEN;
+- 
+-+	/* First block, b_0 */
+-+	b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
+- 	/* Nonce: Nonce Flags | A2 | PN
+- 	 * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
+- 	 */
+- 	b_0[1] = qos_tid | (mgmt << 4);
+- 	memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
+- 	memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
+-+	/* l(m) */
+-+	put_unaligned_be16(data_len, &b_0[14]);
+- 
+- 	/* AAD (extra authenticate-only data) / masked 802.11 header
+- 	 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
+-@@ -402,8 +407,7 @@ static int ccmp_encrypt_skb(struct ieee8
+- 	u8 *pos;
+- 	u8 pn[6];
+- 	u64 pn64;
+--	u8 aad[2 * AES_BLOCK_SIZE];
+--	u8 b_0[AES_BLOCK_SIZE];
+-+	u8 scratch[6 * AES_BLOCK_SIZE];
+- 
+- 	if (info->control.hw_key &&
+- 	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
+-@@ -456,9 +460,9 @@ static int ccmp_encrypt_skb(struct ieee8
+- 		return 0;
+- 
+- 	pos += IEEE80211_CCMP_HDR_LEN;
+--	ccmp_special_blocks(skb, pn, b_0, aad, 0);
+--	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
+--				  skb_put(skb, IEEE80211_CCMP_MIC_LEN));
+-+	ccmp_special_blocks(skb, pn, scratch, 0);
+-+	ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
+-+				  pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN));
+- 
+- 	return 0;
+- }
+-@@ -521,16 +525,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+- 	}
+- 
+- 	if (!(status->flag & RX_FLAG_DECRYPTED)) {
+--		u8 aad[2 * AES_BLOCK_SIZE];
+--		u8 b_0[AES_BLOCK_SIZE];
+-+		u8 scratch[6 * AES_BLOCK_SIZE];
+- 		/* hardware didn't decrypt/verify MIC */
+--		ccmp_special_blocks(skb, pn, b_0, aad, 1);
+-+		ccmp_special_blocks(skb, pn, scratch, 1);
+- 
+- 		if (ieee80211_aes_ccm_decrypt(
+--			    key->u.ccmp.tfm, b_0, aad,
+-+			    key->u.ccmp.tfm, scratch,
+- 			    skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
+- 			    data_len,
+--			    skb->data + skb->len - IEEE80211_CCMP_MIC_LEN))
+-+			    skb->data + skb->len - IEEE80211_CCMP_MIC_LEN,
+-+			    skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN))
+- 			return RX_DROP_UNUSABLE;
+- 	}
+- 
+diff --git a/package/mac80211/patches/150-disable_addr_notifier.patch b/package/mac80211/patches/150-disable_addr_notifier.patch
+index 7b50154..3f749e9 100644
+--- a/package/mac80211/patches/150-disable_addr_notifier.patch
++++ b/package/mac80211/patches/150-disable_addr_notifier.patch
+@@ -18,7 +18,7 @@
+  static int ieee80211_ifa6_changed(struct notifier_block *nb,
+  				  unsigned long data, void *arg)
+  {
+-@@ -1031,14 +1031,14 @@ int ieee80211_register_hw(struct ieee802
++@@ -1036,14 +1036,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)
+-@@ -1047,13 +1047,13 @@ int ieee80211_register_hw(struct ieee802
++@@ -1052,13 +1052,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);
+-@@ -1086,10 +1086,10 @@ void ieee80211_unregister_hw(struct ieee
++@@ -1103,10 +1103,10 @@ void ieee80211_unregister_hw(struct ieee
+  
+  	pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
+  			       &local->network_latency_notifier);
+diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch
+index a1af6c2..90dd5e7 100644
+--- a/package/mac80211/patches/300-pending_work.patch
++++ b/package/mac80211/patches/300-pending_work.patch
+@@ -1,4153 +1,239 @@
+-commit 93f310a38a1d81a4bc8fcd9bf29628bd721cf2ef
+-Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Sun Apr 6 23:35:28 2014 +0200
+-
+-    ath9k_hw: reduce ANI firstep range for older chips
+-    
+-    Use 0-8 instead of 0-16, which is closer to the old implementation.
+-    Also drop the overwrite of the firstep_low parameter to improve
+-    stability.
+-    
+-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+-
+-commit 584d297fd29fb39c76af25ae74ff9d5fe74c8a14
+-Author: Helmut Schaa <helmut.schaa@googlemail.com>
+-Date:   Wed Mar 12 10:37:55 2014 +0100
+-
+-    ath9k: Fix sequence number assignment for non-data frames
+-    
+-    Since commit 558ff225de80ac95b132d3a115ddadcd64498b4f (ath9k: fix
+-    ps-poll responses under a-mpdu sessions) non-data frames would have
+-    gotten a sequence number from a TIDs sequence counter instead of
+-    using the global sequence counter.
+-    
+-    This can lead to instable connections.
+-    
+-    To fix this only select the correct TID if we are processing a
+-    data frame. Furthermore, prevent non-data frames to get a sequence
+-    number from a TID sequence counter by adding a check to
+-    ath_tx_setup_buffer.
+-    
+-    Cc: Felix Fietkau <nbd@openwrt.org>
+-    Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
+-
+-commit 3a0f984b1cdcd6a9f8c441635ef3b05d58547f4e
+-Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Tue Mar 11 14:03:32 2014 +0100
+-
+-    ath9k_hw: set ANI firstep as absolute values instead of relative
+-    
+-    On older chips, the INI value differ in similar ways as cycpwr_thr1, so
+-    convert it to absolute values as well.
+-    
+-    Since the ANI algorithm is different here compared to the old
+-    implementation (fewer steps, controlled at a different point in time),
+-    it makes sense to use values similar to what would be applied for newer
+-    chips, just without relying on INI defaults.
+-    
+-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+-
+-commit 91d70d40400c569b49605b78fd7c43e9405694f4
+-Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Tue Mar 11 14:00:37 2014 +0100
+-
+-    ath9k_hw: set ANI cycpwr_thr1 as absolute values instead of relative
+-    
+-    The table was copied from the ANI implementation of AR9300. It assumes
+-    that the INI values contain a baseline value that is usable as reference
+-    from which to increase/decrease based on the noise immunity value.
+-    
+-    On older chips, the differences are bigger and especially AR5008/AR9001
+-    are configured to much more sensitive values than what is useful.
+-    
+-    Improve ANI behavior by reverting to the absolute values used in the
+-    previous implementation (expressed as a simple formula instead of the
+-    old table).
+-    
+-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+-
+-commit c977493766310a825f406836636ffd66e1447783
+-Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Mon Mar 10 19:52:56 2014 +0100
+-
+-    ath9k_hw: remove ANI function restrictions for AP mode
+-    
+-    The primary purpose of this piece of code was to selectively disable
+-    OFDM weak signal detection. The checks for this are elsewhere, and an
+-    earlier commit relaxed the restrictions for older chips, which are more
+-    sensitive to interference.
+-    
+-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+-
+-commit 8d804f1af11e4e058b1e8453327777d73a585cb8
+-Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Sun Mar 9 11:25:43 2014 +0100
+-
+-    ath9k: clean up and enhance ANI debugfs file
+-    
+-    Unify scnprintf calls and include the current OFDM/CCK immunity level.
+-    
+-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+-
+-commit 22e298b5a3a8a49e33805d4e351965123dede35b
+-Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Sun Mar 9 10:58:47 2014 +0100
+-
+-    ath9k: fix ready time of the multicast buffer queue
+-    
+-    qi->tqi_readyTime is written directly to registers that expect
+-    microseconds as unit instead of TU.
+-    When setting the CABQ ready time, cur_conf->beacon_interval is in TU, so
+-    convert it to microseconds before passing it to ath9k_hw.
+-    
+-    This should hopefully fix some Tx DMA issues with buffered multicast
+-    frames in AP mode.
+-    
+-    Cc: stable@vger.kernel.org
+-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+-
+-commit fcb064fdd5a27bec8d24099bc0172468f34c97cb
++commit eefb1d6adc4c60d219182b8917e4567484ce07fc
+ Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Sun Mar 9 09:43:09 2014 +0100
+-
+-    ath9k_hw: fix unreachable code in baseband hang detection code
+-    
+-    The commit "ath9k: reduce baseband hang detection false positive rate"
+-    added a delay in the loop checking the baseband state, however it was
+-    unreachable due to previous 'continue' statements.
+-    
+-    Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+-
+-commit 31959d8df39319e32c6d5ba9c135727be90cfad7
+-Author: Michal Kazior <michal.kazior@tieto.com>
+-Date:   Fri Mar 7 08:09:38 2014 +0100
+-
+-    mac80211: fix possible NULL dereference
+-    
+-    If chanctx is missing on a given vif then the band
+-    is assumed to be 2GHz. However if hw doesn't
+-    support 2GHz band then mac80211 ended up with a
+-    NULL dereference.
+-    
+-    This fixes a splat:
+-    
+-    [ 4605.207223] BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
+-    [ 4605.210789] IP: [<ffffffffa07b5635>] ieee80211_parse_bitrates+0x65/0x110 [mac80211]
+-    
+-    The splat was preceeded by WARN_ON(!chanctx_conf)
+-    in ieee80211_get_sdata_band().
+-    
+-    Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
++Date:   Mon Apr 28 18:27:41 2014 +0200
+ 
+-commit 6c5a3ffa0a2d22c091a2717f427259bacf77ac5e
+-Author: Michael Braun <michael-dev@fami-braun.de>
+-Date:   Thu Mar 6 15:08:43 2014 +0100
+-
+-    mac80211: fix WPA with VLAN on AP side with ps-sta again
+-    
+-    commit de74a1d9032f4d37ea453ad2a647e1aff4cd2591
+-      "mac80211: fix WPA with VLAN on AP side with ps-sta"
+-    fixed an issue where queued multicast packets would
+-    be sent out encrypted with the key of an other bss.
+-    
+-    commit "7cbf9d017dbb5e3276de7d527925d42d4c11e732"
+-      "mac80211: fix oops on mesh PS broadcast forwarding"
+-    essentially reverted it, because vif.type cannot be AP_VLAN
+-    due to the check to vif.type in ieee80211_get_buffered_bc before.
+-    
+-    As the later commit intended to fix the MESH case, fix it
+-    by checking for IFTYPE_AP instead of IFTYPE_AP_VLAN.
+-    
+-    Fixes: 7cbf9d017dbb
+-    Cc: <stable@vger.kernel.org> # 3.10.x
+-    Cc: <stable@vger.kernel.org> # 3.11.x
+-    Cc: <stable@vger.kernel.org> # 3.12.x
+-    Cc: <stable@vger.kernel.org> # 3.13.x
+-    Cc: <linux-wireless@vger.kernel.org>
+-    Cc: <projekt-wlan@fem.tu-ilmenau.de>
+-    Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
+-
+-commit 9d6ab9bdb9b368a6cf9519f0f92509b5b2c297ec
+-Author: Johannes Berg <johannes.berg@intel.com>
+-Date:   Mon Mar 3 14:19:08 2014 +0100
+-
+-    cfg80211: remove racy beacon_interval assignment
+-    
+-    In case of AP mode, the beacon interval is already reset to
+-    zero inside cfg80211_stop_ap(), and in the other modes it
+-    isn't relevant. Remove the assignment to remove a potential
+-    race since the assignment isn't properly locked.
++    ath9k: remove tid->paused flag
+     
+-    Reported-by: Michal Kazior <michal.kazior@tieto.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit 1abdeca3c6fb9cf1f84f85e78ed8d1c33bd69db0
+-Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Fri Feb 28 18:52:56 2014 +0100
+-
+-    ath9k_hw: tweak noise immunity thresholds for older chipsets
++    There are some corner cases where the driver could get stuck with a full
++    tid queue that is paused, leading to a software tx queue hang.
+     
+-    Older chipsets are more sensitive to high PHY error counts, and the
+-    current noise immunity thresholds were based on tests run at QCA with
+-    newer chipsets.
++    Since the tx queueing rework, pausing per-tid queues on aggregation
++    session setup is no longer necessary. The driver will assign sequence
++    numbers to buffered frames when a new session is established, in order
++    to get the correct starting sequence number.
+     
+-    This patch brings back the values from the old ANI implementation for
+-    old chipsets, and it also disables weak signal detection on an earlier
+-    noise immunity level, to improve overall radio stability on affected
+-    devices.
++    mac80211 prevents new frames from entering the queue during setup.
+     
+     Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ 
+-commit 431e506da5953adc3b65af25f4b90873d528c115
++commit 98a713933d8495f4078f561c1e651b738dd5b531
+ Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Fri Feb 28 18:44:13 2014 +0100
++Date:   Sun Apr 27 14:49:03 2014 +0200
+ 
+-    ath9k_hw: toggle weak signal detection in AP mode on older chipsets
+-    
+-    The commit 80b4205b "ath9k: Fix OFDM weak signal detection for AP mode"
+-    prevented weak signal detection changes from taking effect in AP mode on
+-    all chipsets, claiming it is "not allowed".
++    ath9k_hw: do not lower ANI setting below default on AR913x
+     
+-    The main reason for not disabling weak signal detection in AP mode is
+-    that typically beacon RSSI is used to track whether it is needed to
+-    boost range, and this is unavailable in AP mode for obvious reasons.
++    When the amount of noise fluctuates strongly, low immunity settings
++    can sometimes disrupt signal detection on AR913x chips. When that
++    happens, no OFDM/CCK errors are reported anymore, and ANI tunes the
++    radio to the lowest immunity settings.
++    Usually rx/tx fails as well in that case.
+     
+-    The problem with not disabling weak signal detection is that older
+-    chipsets are very sensitive to high PHY error counts. When faced with
+-    heavy noise, this can lead to an excessive amount of "Failed to stop
+-    TX DMA" errors in the field.
++    To fix this, keep noise immunity settings at or above ANI default level,
++    which will keep radio parameters at or above INI values.
+     
+     Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ 
+-commit 98d1a6c5b14688ed030e81b889f607be308e0df9
++commit 7cbb4c021bfd1e656f5b9953a947ab3c64e4e3b0
+ Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Mon Feb 24 22:20:32 2014 +0100
++Date:   Thu Apr 10 10:49:01 2014 +0200
+ 
+-    ath9k: fix invalid descriptor discarding
++    mac80211: exclude AP_VLAN interfaces from tx power calculation
+     
+-    Only set sc->rx.discard_next to rx_stats->rs_more when actually
+-    discarding the current descriptor.
+-    
+-    Also, fix a detection of broken descriptors:
+-    First the code checks if the current descriptor is not done.
+-    Then it checks if the next descriptor is done.
+-    Add a check that afterwards checks the first descriptor again, because
+-    it might have been completed in the mean time.
+-    
+-    This fixes a regression introduced in
+-    commit 723e711356b5a8a95728a890e254e8b0d47b55cf
+-    "ath9k: fix handling of broken descriptors"
++    Their power value is initialized to zero. This patch fixes an issue
++    where the configured power drops to the minimum value when AP_VLAN
++    interfaces are created/removed.
+     
+     Cc: stable@vger.kernel.org
+-    Reported-by: Marco André Dinis <marcoandredinis@gmail.com>
+-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+-
+-commit 52a46300e782fe6994466523eb2b0b59091ea59f
+-Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Mon Feb 24 11:43:50 2014 +0100
+-
+-    ath9k: reduce baseband hang detection false positive rate
+-    
+-    Check if the baseband state remains stable, and add a small delay
+-    between register reads.
+-    
+-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+-
+-commit 118945bb12082e9d4edddc868d88143164e0f440
+-Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Sat Feb 22 14:55:23 2014 +0100
+-
+-    ath5k: set SURVEY_INFO_IN_USE on get_survey
+-    
+-    Only one channel is returned - the one currently being used.
+-    
+-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+-
+-commit ee41f72476e1ea44283dfe1cbf75b9543a1e15c8
+-Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Sat Feb 22 14:44:52 2014 +0100
+-
+-    ath9k: make some hardware reset log messages debug-only
+-    
+-    On some chips, baseband watchdog hangs are more common than others, and
+-    the driver has support for handling them.
+-    Interrupts even after a watchdog hang are also quite common, so there's
+-    not much point in spamming the user's logfiles.
+-    
+     Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ 
+-commit b14fbb554fc65a2e0b5c41a319269b0350f187e7
++commit 0ca13e26341733bf9577287fb04a3bef0d2f5cc9
+ Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Sat Feb 22 14:35:25 2014 +0100
++Date:   Wed Apr 9 00:07:01 2014 +0200
+ 
+-    ath9k: do not set half/quarter channel flags in AR_PHY_MODE
++    mac80211: suppress BSS info change notifications for AP_VLAN
+     
+-    5/10 MHz channel bandwidth is configured via the PLL clock, instead of
+-    the AR_PHY_MODE register. Using that register is AR93xx specific, and
+-    makes the mode incompatible with earlier chipsets.
++    Fixes warnings on tx power changes
+     
+-    In some early versions, these flags were apparently applied at the wrong
+-    point in time and thus did not cause connectivity issues, however now
+-    they are causing problems, as pointed out in this OpenWrt ticket:
+-    
+-    https://dev.openwrt.org/ticket/14916
+-    
+-    Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+-
+-commit 0f1cb7be2551b30b02cd54c897e0e29e483cfda5
+-Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Sat Feb 22 13:43:29 2014 +0100
+-
+-    ath9k: fix ps-poll responses under a-mpdu sessions
+-    
+-    When passing tx frames to the U-APSD queue for powersave poll responses,
+-    the ath_atx_tid pointer needs to be passed to ath_tx_setup_buffer for
+-    proper sequence number accounting.
+-    
+-    This fixes high latency and connection stability issues with ath9k
+-    running as AP and a few kinds of mobile phones as client, when PS-Poll
+-    is heavily used
+-    
+-    Cc: stable@vger.kernel.org
+     Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ 
+-commit d5d87a37bbd6066b2c3c5d0bd0fe2a6e2ea45cc5
++commit ec998e5991781ecdaad0911dc64f1c8d3749c308
+ Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Fri Feb 21 11:39:59 2014 +0100
++Date:   Tue Apr 8 23:42:17 2014 +0200
+ 
+-    ath9k: list more reset causes in debugfs
++    ath9k: fix a scheduling while atomic bug in CSA handling
+     
+-    Number of MAC hangs and stuck beacons were missing
++    Commit "ath9k: prepare for multi-interface CSA support" added a call to
++    ieee80211_iterate_active_interfaces in atomic context (beacon tasklet),
++    which is crashing.
++    Use ieee80211_iterate_active_interfaces_atomic instead.
+     
+     Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ 
+-commit d84856012e0f10fe598a5ad3b7b869397a089e07
+-Author: Johannes Berg <johannes.berg@intel.com>
+-Date:   Thu Feb 20 11:19:58 2014 +0100
+-
+-    mac80211: fix station wakeup powersave race
+-    
+-    Consider the following (relatively unlikely) scenario:
+-     1) station goes to sleep while frames are buffered in driver
+-     2) driver blocks wakeup (until no more frames are buffered)
+-     3) station wakes up again
+-     4) driver unblocks wakeup
+-    
+-    In this case, the current mac80211 code will do the following:
+-     1) WLAN_STA_PS_STA set
+-     2) WLAN_STA_PS_DRIVER set
+-     3) - nothing -
+-     4) WLAN_STA_PS_DRIVER cleared
+-    
+-    As a result, no frames will be delivered to the client, even
+-    though it is awake, until it sends another frame to us that
+-    triggers ieee80211_sta_ps_deliver_wakeup() in sta_ps_end().
+-    
+-    Since we now take the PS spinlock, we can fix this while at
+-    the same time removing the complexity with the pending skb
+-    queue function. This was broken since my commit 50a9432daeec
+-    ("mac80211: fix powersaving clients races") due to removing
+-    the clearing of WLAN_STA_PS_STA in the RX path.
+-    
+-    While at it, fix a cleanup path issue when a station is
+-    removed while the driver is still blocking its wakeup.
+-    
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit 798f2786602cbe93e6b928299614aa36ebf50692
+-Author: Johannes Berg <johannes.berg@intel.com>
+-Date:   Mon Feb 17 20:49:03 2014 +0100
+-
+-    mac80211: insert stations before adding to driver
+-    
+-    There's a race condition in mac80211 because we add stations
+-    to the internal lists after adding them to the driver, which
+-    means that (for example) the following can happen:
+-     1. a station connects and is added
+-     2. first, it is added to the driver
+-     3. then, it is added to the mac80211 lists
+-    
+-    If the station goes to sleep between steps 2 and 3, and the
+-    firmware/hardware records it as being asleep, mac80211 will
+-    never instruct the driver to wake it up again as it never
+-    realized it went to sleep since the RX path discarded the
+-    frame as a "spurious class 3 frame", no station entry was
+-    present yet.
+-    
+-    Fix this by adding the station in software first, and only
+-    then adding it to the driver. That way, any state that the
+-    driver changes will be reflected properly in mac80211's
+-    station state. The problematic part is the roll-back if the
+-    driver fails to add the station, in that case a bit more is
+-    needed. To not make that overly complex prevent starting BA
+-    sessions in the meantime.
+-    
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit b9ba6a520cb07ab3aa7aaaf9ce4a0bc7a6bc06fe
+-Author: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+-Date:   Thu Feb 20 09:22:11 2014 +0200
+-
+-    mac80211: fix AP powersave TX vs. wakeup race
+-    
+-    There is a race between the TX path and the STA wakeup: while
+-    a station is sleeping, mac80211 buffers frames until it wakes
+-    up, then the frames are transmitted. However, the RX and TX
+-    path are concurrent, so the packet indicating wakeup can be
+-    processed while a packet is being transmitted.
+-    
+-    This can lead to a situation where the buffered frames list
+-    is emptied on the one side, while a frame is being added on
+-    the other side, as the station is still seen as sleeping in
+-    the TX path.
+-    
+-    As a result, the newly added frame will not be send anytime
+-    soon. It might be sent much later (and out of order) when the
+-    station goes to sleep and wakes up the next time.
+-    
+-    Additionally, it can lead to the crash below.
+-    
+-    Fix all this by synchronising both paths with a new lock.
+-    Both path are not fastpath since they handle PS situations.
+-    
+-    In a later patch we'll remove the extra skb queue locks to
+-    reduce locking overhead.
+-    
+-    BUG: unable to handle kernel
+-    NULL pointer dereference at 000000b0
+-    IP: [<ff6f1791>] ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
+-    *pde = 00000000
+-    Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
+-    EIP: 0060:[<ff6f1791>] EFLAGS: 00210282 CPU: 1
+-    EIP is at ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
+-    EAX: e5900da0 EBX: 00000000 ECX: 00000001 EDX: 00000000
+-    ESI: e41d00c0 EDI: e5900da0 EBP: ebe458e4 ESP: ebe458b0
+-     DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
+-    CR0: 8005003b CR2: 000000b0 CR3: 25a78000 CR4: 000407d0
+-    DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
+-    DR6: ffff0ff0 DR7: 00000400
+-    Process iperf (pid: 3934, ti=ebe44000 task=e757c0b0 task.ti=ebe44000)
+-    iwlwifi 0000:02:00.0: I iwl_pcie_enqueue_hcmd Sending command LQ_CMD (#4e), seq: 0x0903, 92 bytes at 3[3]:9
+-    Stack:
+-     e403b32c ebe458c4 00200002 00200286 e403b338 ebe458cc c10960bb e5900da0
+-     ff76a6ec ebe458d8 00000000 e41d00c0 e5900da0 ebe458f0 ff6f1b75 e403b210
+-     ebe4598c ff723dc1 00000000 ff76a6ec e597c978 e403b758 00000002 00000002
+-    Call Trace:
+-     [<ff6f1b75>] ieee80211_free_txskb+0x15/0x20 [mac80211]
+-     [<ff723dc1>] invoke_tx_handlers+0x1661/0x1780 [mac80211]
+-     [<ff7248a5>] ieee80211_tx+0x75/0x100 [mac80211]
+-     [<ff7249bf>] ieee80211_xmit+0x8f/0xc0 [mac80211]
+-     [<ff72550e>] ieee80211_subif_start_xmit+0x4fe/0xe20 [mac80211]
+-     [<c149ef70>] dev_hard_start_xmit+0x450/0x950
+-     [<c14b9aa9>] sch_direct_xmit+0xa9/0x250
+-     [<c14b9c9b>] __qdisc_run+0x4b/0x150
+-     [<c149f732>] dev_queue_xmit+0x2c2/0xca0
+-    
+-    Cc: stable@vger.kernel.org
+-    Reported-by: Yaara Rozenblum <yaara.rozenblum@intel.com>
+-    Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+-    Reviewed-by: Stanislaw Gruszka <sgruszka@redhat.com>
+-    [reword commit log, use a separate lock]
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit 80e419de0dff38436b30d363311c625766193f86
+-Author: Inbal Hacohen <Inbal.Hacohen@intel.com>
+-Date:   Wed Feb 12 09:32:27 2014 +0200
+-
+-    cfg80211: bugfix in regulatory user hint process
+-    
+-    After processing hint_user, we would want to schedule the
+-    timeout work only if we are actually waiting to CRDA. This happens
+-    when the status is not "IGNORE" nor "ALREADY_SET".
+-    
+-    Signed-off-by: Inbal Hacohen <Inbal.Hacohen@intel.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit 6514c93afede55284e2cb63359aadedb85884c80
+-Author: Jouni Malinen <jouni@qca.qualcomm.com>
+-Date:   Tue Feb 18 20:41:08 2014 +0200
+-
+-    ath9k: Enable U-APSD AP mode support
+-    
+-    mac80211 handles the actual operations, so ath9k can just indicate
+-    support for this. Based on initial tests, this combination seems to
+-    work fine.
+-    
+-    Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
+-
+-commit a63caf0a357ad5c1f08d6b7827dc76c451445017
+-Author: Stanislaw Gruszka <sgruszka@redhat.com>
+-Date:   Wed Feb 19 13:15:17 2014 +0100
+-
+-    ath9k: protect tid->sched check
+-    
+-    We check tid->sched without a lock taken on ath_tx_aggr_sleep(). That
+-    is race condition which can result of doing list_del(&tid->list) twice
+-    (second time with poisoned list node) and cause crash like shown below:
+-    
+-    [424271.637220] BUG: unable to handle kernel paging request at 00100104
+-    [424271.637328] IP: [<f90fc072>] ath_tx_aggr_sleep+0x62/0xe0 [ath9k]
+-    ...
+-    [424271.639953] Call Trace:
+-    [424271.639998]  [<f90f6900>] ? ath9k_get_survey+0x110/0x110 [ath9k]
+-    [424271.640083]  [<f90f6942>] ath9k_sta_notify+0x42/0x50 [ath9k]
+-    [424271.640177]  [<f809cfef>] sta_ps_start+0x8f/0x1c0 [mac80211]
+-    [424271.640258]  [<c10f730e>] ? free_compound_page+0x2e/0x40
+-    [424271.640346]  [<f809e915>] ieee80211_rx_handlers+0x9d5/0x2340 [mac80211]
+-    [424271.640437]  [<c112f048>] ? kmem_cache_free+0x1d8/0x1f0
+-    [424271.640510]  [<c1345a84>] ? kfree_skbmem+0x34/0x90
+-    [424271.640578]  [<c10fc23c>] ? put_page+0x2c/0x40
+-    [424271.640640]  [<c1345a84>] ? kfree_skbmem+0x34/0x90
+-    [424271.640706]  [<c1345a84>] ? kfree_skbmem+0x34/0x90
+-    [424271.640787]  [<f809dde3>] ? ieee80211_rx_handlers_result+0x73/0x1d0 [mac80211]
+-    [424271.640897]  [<f80a07a0>] ieee80211_prepare_and_rx_handle+0x520/0xad0 [mac80211]
+-    [424271.641009]  [<f809e22d>] ? ieee80211_rx_handlers+0x2ed/0x2340 [mac80211]
+-    [424271.641104]  [<c13846ce>] ? ip_output+0x7e/0xd0
+-    [424271.641182]  [<f80a1057>] ieee80211_rx+0x307/0x7c0 [mac80211]
+-    [424271.641266]  [<f90fa6ee>] ath_rx_tasklet+0x88e/0xf70 [ath9k]
+-    [424271.641358]  [<f80a0f2c>] ? ieee80211_rx+0x1dc/0x7c0 [mac80211]
+-    [424271.641445]  [<f90f82db>] ath9k_tasklet+0xcb/0x130 [ath9k]
+-    
+-    Bug report:
+-    https://bugzilla.kernel.org/show_bug.cgi?id=70551
+-    
+-    Reported-and-tested-by: Max Sydorenko <maxim.stargazer@gmail.com>
+-    Cc: stable@vger.kernel.org
+-    Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+-
+-commit 82ed9e3ccc02797df2ffe4b78127c4cd5f799a41
++commit 93f310a38a1d81a4bc8fcd9bf29628bd721cf2ef
+ Author: Felix Fietkau <nbd@openwrt.org>
+-Date:   Tue Feb 11 15:54:13 2014 +0100
++Date:   Sun Apr 6 23:35:28 2014 +0200
+ 
+-    mac80211: send control port protocol frames to the VO queue
++    ath9k_hw: reduce ANI firstep range for older chips
+     
+-    Improves reliability of wifi connections with WPA, since authentication
+-    frames are prioritized over normal traffic and also typically exempt
+-    from aggregation.
++    Use 0-8 instead of 0-16, which is closer to the old implementation.
++    Also drop the overwrite of the firstep_low parameter to improve
++    stability.
+     
+-    Cc: stable@vger.kernel.org
+     Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ 
+-commit d4426800f71e972feaa33e04c5801fc730627bdd
+-Author: Stanislaw Gruszka <stf_xl@wp.pl>
+-Date:   Mon Feb 10 22:38:28 2014 +0100
+-
+-    rtl8187: fix regression on MIPS without coherent DMA
+-    
+-    This patch fixes regression caused by commit a16dad77634 "MIPS: Fix
+-    potencial corruption". That commit fixes one corruption scenario in
+-    cost of adding another one, which actually start to cause crashes
+-    on Yeeloong laptop when rtl8187 driver is used.
+-    
+-    For correct DMA read operation on machines without DMA coherence, kernel
+-    have to invalidate cache, such it will refill later with new data that
+-    device wrote to memory, when that data is needed to process. We can only
+-    invalidate full cache line. Hence when cache line includes both dma
+-    buffer and some other data (written in cache, but not yet in main
+-    memory), the other data can not hit memory due to invalidation. That
+-    happen on rtl8187 where struct rtl8187_priv fields are located just
+-    before and after small buffers that are passed to USB layer and DMA
+-    is performed on them.
+-    
+-    To fix the problem we align buffers and reserve space after them to make
+-    them match cache line.
+-    
+-    This patch does not resolve all possible MIPS problems entirely, for
+-    that we have to assure that we always map cache aligned buffers for DMA,
+-    what can be complex or even not possible. But patch fixes visible and
+-    reproducible regression and seems other possible corruptions do not
+-    happen in practice, since Yeeloong laptop works stable without rtl8187
+-    driver.
+-    
+-    Bug report:
+-    https://bugzilla.kernel.org/show_bug.cgi?id=54391
+-    
+-    Reported-by: Petr Pisar <petr.pisar@atlas.cz>
+-    Bisected-by: Tom Li <biergaizi2009@gmail.com>
+-    Reported-and-tested-by: Tom Li <biergaizi2009@gmail.com>
+-    Cc: stable@vger.kernel.org
+-    Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
+-
+-commit e2f141d67ad1e7fe10aaab61811e8a409dfb2442
+-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-Date:   Fri Feb 7 10:29:55 2014 +0530
+-
+-    ath9k: Calculate IQ-CAL median
+-    
+-    This patch adds a routine to calculate the median IQ correction
+-    values for AR955x, which is used for outlier detection.
+-    The normal method which is used for all other chips is
+-    bypassed for AR955x.
+-    
+-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-
+-commit c52a6fce0820c8d0687443ab86058ae03b478c8f
+-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-Date:   Fri Feb 7 10:29:54 2014 +0530
+-
+-    ath9k: Expand the IQ coefficient array
+-    
+-    This will be used for storing data for mutiple
+-    IQ calibration runs, for AR955x.
+-    
+-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-
+-commit 034969ff5c2b6431d10e07c1938f0b916da85cc3
+-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-Date:   Fri Feb 7 10:29:53 2014 +0530
+-
+-    ath9k: Modify IQ calibration for AR955x
+-    
+-    IQ calibration post-processing for AR955x is different
+-    from other chips - instead of just doing it as part
+-    of AGC calibration once, it is triggered 3 times and
+-    a median is determined. This patch adds initial support
+-    for changing the calibration behavior for AR955x.
+-    
+-    Also, to simplify things, a helper routine to issue/poll
+-    AGC calibration is used.
+-    
+-    For non-AR955x chips, the iqcal_idx (which will be used
+-    in subsequent patches) is set to zero.
+-    
+-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-
+-commit 9b1ed6454e6f3511f24266be99b4e403f243f6a8
+-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-Date:   Fri Feb 7 10:29:52 2014 +0530
+-
+-    ath9k: Fix magnitude/phase calculation
+-    
+-    Incorrect values are programmed in the registers
+-    containing the IQ correction coefficients by the IQ-CAL
+-    post-processing code. Fix this.
+-    
+-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-
+-commit 36f93484f96f79171dcecb67c5ef0c3de22531a6
+-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-Date:   Fri Feb 7 10:29:51 2014 +0530
+-
+-    ath9k: Rename ar9003_hw_tx_iqcal_load_avg_2_passes
+-    
+-    Use ar9003_hw_tx_iq_cal_outlier_detection instead.
+-    
+-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-
+-commit 3af09a7f5d21dd5fd15b973ce6a91a575da30417
+-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-Date:   Fri Feb 7 10:29:50 2014 +0530
+-
+-    ath9k: Check explicitly for IQ calibration
+-    
+-    In chips like AR955x, the initvals contain the information
+-    whether IQ calibration is to be done in the HW when an
+-    AGC calibration is triggered. Check if IQ-CAL is enabled
+-    in the initvals before flagging 'txiqcal_done' as true.
+-    
+-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-
+-commit cb4969634b93c4643a32cc3fbd27d2b288b25771
+-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-Date:   Fri Feb 7 10:29:49 2014 +0530
+-
+-    ath9k: Fix IQ cal post processing for SoC
+-    
+-    Calibration data is not reused for SoC chips, so
+-    call ar9003_hw_tx_iq_cal_post_proc() with the correct
+-    argument. The 'is_reusable' flag is currently used
+-    only for PC-OEM chips, but it makes things clearer to
+-    specify it explicity.
+-    
+-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-
+-commit e138e0ef9560c46ce93dbb22a728a57888e94d1c
+-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-Date:   Mon Feb 3 13:31:37 2014 +0530
+ 
+-    ath9k: Fix TX power calculation
+-    
+-    The commit, "ath9k_hw: Fix incorrect Tx control power in AR9003 template"
+-    fixed the incorrect values in the eeprom templates, but if
+-    boards have already been calibrated with incorrect values,
+-    they would still be using the wrong TX power. Fix this by assigning
+-    a default value in such cases.
+-    
+-    Cc: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
+-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-
+-commit b9f268b5b01331c3c82179abca551429450e9417
+-Author: Michal Kazior <michal.kazior@tieto.com>
+-Date:   Wed Jan 29 14:22:27 2014 +0100
+-
+-    cfg80211: consider existing DFS interfaces
+-    
+-    It was possible to break interface combinations in
+-    the following way:
+-    
+-     combo 1: iftype = AP, num_ifaces = 2, num_chans = 2,
+-     combo 2: iftype = AP, num_ifaces = 1, num_chans = 1, radar = HT20
+-    
+-    With the above interface combinations it was
+-    possible to:
+-    
+-     step 1. start AP on DFS channel by matching combo 2
+-     step 2. start AP on non-DFS channel by matching combo 1
+-    
+-    This was possible beacuse (step 2) did not consider
+-    if other interfaces require radar detection.
+-    
+-    The patch changes how cfg80211 tracks channels -
+-    instead of channel itself now a complete chandef
+-    is stored.
+-    
+-    Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit bc9c62f5f511cc395c62dbf4cdd437f23db53b28
+-Author: Antonio Quartulli <antonio@open-mesh.com>
+-Date:   Wed Jan 29 17:53:43 2014 +0100
+-
+-    cfg80211: fix channel configuration in IBSS join
+-    
+-    When receiving an IBSS_JOINED event select the BSS object
+-    based on the {bssid, channel} couple rather than the bssid
+-    only.
+-    With the current approach if another cell having the same
+-    BSSID (but using a different channel) exists then cfg80211
+-    picks up the wrong BSS object.
+-    The result is a mismatching channel configuration between
+-    cfg80211 and the driver, that can lead to any sort of
+-    problem.
+-    
+-    The issue can be triggered by having an IBSS sitting on
+-    given channel and then asking the driver to create a new
+-    cell using the same BSSID but with a different frequency.
+-    By passing the channel to cfg80211_get_bss() we can solve
+-    this ambiguity and retrieve/create the correct BSS object.
+-    All the users of cfg80211_ibss_joined() have been changed
+-    accordingly.
+-    
+-    Moreover WARN when cfg80211_ibss_joined() gets a NULL
+-    channel as argument and remove a bogus call of the same
+-    function in ath6kl (it does not make sense to call
+-    cfg80211_ibss_joined() with a zero BSSID on ibss-leave).
+-    
+-    Cc: Kalle Valo <kvalo@qca.qualcomm.com>
+-    Cc: Arend van Spriel <arend@broadcom.com>
+-    Cc: Bing Zhao <bzhao@marvell.com>
+-    Cc: Jussi Kivilinna <jussi.kivilinna@iki.fi>
+-    Cc: libertas-dev@lists.infradead.org
+-    Acked-by: Kalle Valo <kvalo@qca.qualcomm.com>
+-    Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
+-    [minor code cleanup in ath6kl]
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit 7e0c41cb41f215aba2c39b1c237bb4d42ec49a85
+-Author: Johannes Berg <johannes.berg@intel.com>
+-Date:   Fri Jan 24 14:41:44 2014 +0100
+-
+-    mac80211: fix bufferable MMPDU RX handling
+-    
+-    Action, disassoc and deauth frames are bufferable, and as such don't
+-    have the PM bit in the frame control field reserved which means we
+-    need to react to the bit when receiving in such a frame.
+-    
+-    Fix this by introducing a new helper ieee80211_is_bufferable_mmpdu()
+-    and using it for the RX path that currently ignores the PM bit in
+-    any non-data frames for doze->wake transitions, but listens to it in
+-    all frames for wake->doze transitions, both of which are wrong.
+-    
+-    Also use the new helper in the TX path to clean up the code.
+-    
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit fc0df6d2343636e3f48a069330d5b972e3d8659d
+-Author: Janusz Dziedzic <janusz.dziedzic@tieto.com>
+-Date:   Fri Jan 24 14:29:21 2014 +0100
+-
+-    cfg80211: set preset_chandef after channel switch
+-    
+-    Set preset_chandef in channel switch notification.
+-    In other case we will have old preset_chandef.
+-    
+-    Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit cdec895e2344987ff171cece96e25d7407a3ebf6
+-Author: Simon Wunderlich <simon@open-mesh.com>
+-Date:   Fri Jan 24 23:48:29 2014 +0100
+-
+-    mac80211: send ibss probe responses with noack flag
+-    
+-    Responding to probe requests for scanning clients will often create
+-    excessive retries, as it happens quite often that the scanning client
+-    already left the channel. Therefore do it like hostapd and send probe
+-    responses for wildcard SSID only once by using the noack flag.
+-    
+-    Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
+-    [fix typo & 'wildcard SSID' in commit log]
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit 0b865d1e6b9c05052adae9315df7cb195dc60c3b
+-Author: Luciano Coelho <luciano.coelho@intel.com>
+-Date:   Tue Jan 28 17:09:08 2014 +0200
+-
+-    mac80211: ibss: remove unnecessary call to release channel
+-    
+-    The ieee80211_vif_use_channel() function calls
+-    ieee80211_vif_release_channel(), so there's no need to call it
+-    explicitly in __ieee80211_sta_join_ibss().
+-    
+-    Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit e1b6c17e971f0a51ff86c2dac2584c63cd999cd7
+-Author: Michal Kazior <michal.kazior@tieto.com>
+-Date:   Wed Jan 29 07:56:21 2014 +0100
+-
+-    mac80211: add missing CSA locking
+-    
+-    The patch adds a missing sdata lock and adds a few
+-    lockdeps for easier maintenance.
+-    
+-    Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit ad17ba7d14d225b109b73c177cd446afb8050598
+-Author: Michal Kazior <michal.kazior@tieto.com>
+-Date:   Wed Jan 29 07:56:20 2014 +0100
+-
+-    mac80211: fix sdata->radar_required locking
+-    
+-    radar_required setting wasn't protected by
+-    local->mtx in some places. This should prevent
+-    from scanning/radar detection/roc colliding.
+-    
+-    Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit 5fcd5f1808813a3d9e502fd756e01bee8a79c85d
+-Author: Michal Kazior <michal.kazior@tieto.com>
+-Date:   Wed Jan 29 07:56:19 2014 +0100
+-
+-    mac80211: move csa_active setting in STA CSA
+-    
+-    The sdata->vif.csa_active could be left set after,
+-    e.g. channel context constraints check fail in STA
+-    mode leaving the interface in a strange state for
+-    a brief period of time until it is disconnected.
+-    This was harmless but ugly.
+-    
+-    Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
+-    Reviewed-by: Luciano Coelho <luciano.coelho@intel.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit e486da4b7eed71821c6b4c1bb9ac62ffd3ab13e9
+-Author: Michal Kazior <michal.kazior@tieto.com>
+-Date:   Wed Jan 29 07:56:18 2014 +0100
+-
+-    mac80211: fix possible memory leak on AP CSA failure
+-    
+-    If CSA for AP interface failed and the interface
+-    was not stopped afterwards another CSA request
+-    would leak sdata->u.ap.next_beacon.
+-    
+-    Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
+-    Reviewed-by: Luciano Coelho <luciano.coelho@intel.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit 3a77ba08940682bf3d52cf14f980337324af9d4a
+-Author: Johannes Berg <johannes.berg@intel.com>
+-Date:   Sat Feb 1 00:33:29 2014 +0100
+-
+-    mac80211: fix fragmentation code, particularly for encryption
+-    
+-    The "new" fragmentation code (since my rewrite almost 5 years ago)
+-    erroneously sets skb->len rather than using skb_trim() to adjust
+-    the length of the first fragment after copying out all the others.
+-    This leaves the skb tail pointer pointing to after where the data
+-    originally ended, and thus causes the encryption MIC to be written
+-    at that point, rather than where it belongs: immediately after the
+-    data.
+-    
+-    The impact of this is that if software encryption is done, then
+-     a) encryption doesn't work for the first fragment, the connection
+-        becomes unusable as the first fragment will never be properly
+-        verified at the receiver, the MIC is practically guaranteed to
+-        be wrong
+-     b) we leak up to 8 bytes of plaintext (!) of the packet out into
+-        the air
+-    
+-    This is only mitigated by the fact that many devices are capable
+-    of doing encryption in hardware, in which case this can't happen
+-    as the tail pointer is irrelevant in that case. Additionally,
+-    fragmentation is not used very frequently and would normally have
+-    to be configured manually.
+-    
+-    Fix this by using skb_trim() properly.
+-    
+-    Cc: stable@vger.kernel.org
+-    Fixes: 2de8e0d999b8 ("mac80211: rewrite fragmentation")
+-    Reported-by: Jouni Malinen <j@w1.fi>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit de5f242e0c10e841017e37eb8c38974a642dbca8
+-Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-Date:   Tue Jan 28 06:21:59 2014 +0530
+-
+-    ath9k: Fix build error on ARM
+-    
+-    Use mdelay instead of udelay to fix this error:
+-    
+-    ERROR: "__bad_udelay" [drivers/net/wireless/ath/ath9k/ath9k_hw.ko] undefined!
+-    make[1]: *** [__modpost] Error 1
+-    make: *** [modules] Error 2
+-    
+-    Reported-by: Josh Boyer <jwboyer@fedoraproject.org>
+-    Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+-
+-commit 8e3ea7a51dfc61810fcefd947f6edcf61125252a
+-Author: Geert Uytterhoeven <geert@linux-m68k.org>
+-Date:   Sun Jan 26 11:53:21 2014 +0100
+-
+-    ath9k: Fix uninitialized variable in ath9k_has_tx_pending()
+-    
+-    drivers/net/wireless/ath/ath9k/main.c: In function ‘ath9k_has_tx_pending’:
+-    drivers/net/wireless/ath/ath9k/main.c:1869: warning: ‘npend’ may be used uninitialized in this function
+-    
+-    Introduced by commit 10e2318103f5941aa70c318afe34bc41f1b98529 ("ath9k:
+-    optimize ath9k_flush").
+-    
+-    Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+-
+-commit a4a634a6937ebdd827fa58e8fcdb8ca49a3769f6
+-Author: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+-Date:   Mon Jan 27 11:07:42 2014 +0200
+-
+-    mac80211: release the channel in error path in start_ap
+-    
+-    When the driver cannot start the AP or when the assignement
+-    of the beacon goes wrong, we need to unassign the vif.
+-    
+-    Cc: stable@vger.kernel.org
+-    Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit dfb6889a75c601aedb7450b7e606668e77da6679
+-Author: Johannes Berg <johannes.berg@intel.com>
+-Date:   Wed Jan 22 11:14:19 2014 +0200
+-
+-    cfg80211: send scan results from work queue
+-    
+-    Due to the previous commit, when a scan finishes, it is in theory
+-    possible to hit the following sequence:
+-     1. interface starts being removed
+-     2. scan is cancelled by driver and cfg80211 is notified
+-     3. scan done work is scheduled
+-     4. interface is removed completely, rdev->scan_req is freed,
+-        event sent to userspace but scan done work remains pending
+-     5. new scan is requested on another virtual interface
+-     6. scan done work runs, freeing the still-running scan
+-    
+-    To fix this situation, hang on to the scan done message and block
+-    new scans while that is the case, and only send the message from
+-    the work function, regardless of whether the scan_req is already
+-    freed from interface removal. This makes step 5 above impossible
+-    and changes step 6 to be
+-     5. scan done work runs, sending the scan done message
+-    
+-    As this can't work for wext, so we send the message immediately,
+-    but this shouldn't be an issue since we still return -EBUSY.
+-    
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit 45b7ab41fc08627d9a8428cb413d5d84662a9707
+-Author: Johannes Berg <johannes.berg@intel.com>
+-Date:   Wed Jan 22 11:14:18 2014 +0200
+-
+-    cfg80211: fix scan done race
+-    
+-    When an interface/wdev is removed, any ongoing scan should be
+-    cancelled by the driver. This will make it call cfg80211, which
+-    only queues a work struct. If interface/wdev removal is quick
+-    enough, this can leave the scan request pending and processed
+-    only after the interface is gone, causing a use-after-free.
+-    
+-    Fix this by making sure the scan request is not pending after
+-    the interface is destroyed. We can't flush or cancel the work
+-    item due to locking concerns, but when it'll run it shouldn't
+-    find anything to do. This leaves a potential issue, if a new
+-    scan gets requested before the work runs, it prematurely stops
+-    the running scan, potentially causing another crash. I'll fix
+-    that in the next patch.
+-    
+-    This was particularly observed with P2P_DEVICE wdevs, likely
+-    because freeing them is quicker than freeing netdevs.
+-    
+-    Reported-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
+-    Fixes: 4a58e7c38443 ("cfg80211: don't "leak" uncompleted scans")
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit ae04fa489ab31b5a10d3cc8399f52761175d4321
+-Author: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+-Date:   Thu Jan 23 14:28:16 2014 +0200
+-
+-    mac80211: avoid deadlock revealed by lockdep
+-    
+-    sdata->u.ap.request_smps_work can’t be flushed synchronously
+-    under wdev_lock(wdev) since ieee80211_request_smps_ap_work
+-    itself locks the same lock.
+-    While at it, reset the driver_smps_mode when the ap is
+-    stopped to its default: OFF.
+-    
+-    This solves:
+-    
+-    ======================================================
+-    [ INFO: possible circular locking dependency detected ]
+-    3.12.0-ipeer+ #2 Tainted: G           O
+-    -------------------------------------------------------
+-    rmmod/2867 is trying to acquire lock:
+-      ((&sdata->u.ap.request_smps_work)){+.+...}, at: [<c105b8d0>] flush_work+0x0/0x90
+-    
+-    but task is already holding lock:
+-      (&wdev->mtx){+.+.+.}, at: [<f9b32626>] cfg80211_stop_ap+0x26/0x230 [cfg80211]
+-    
+-    which lock already depends on the new lock.
+-    
+-    the existing dependency chain (in reverse order) is:
+-    
+-    -> #1 (&wdev->mtx){+.+.+.}:
+-            [<c10aefa9>] lock_acquire+0x79/0xe0
+-            [<c1607a1a>] mutex_lock_nested+0x4a/0x360
+-            [<fb06288b>] ieee80211_request_smps_ap_work+0x2b/0x50 [mac80211]
+-            [<c105cdd8>] process_one_work+0x198/0x450
+-            [<c105d469>] worker_thread+0xf9/0x320
+-            [<c10669ff>] kthread+0x9f/0xb0
+-            [<c1613397>] ret_from_kernel_thread+0x1b/0x28
+-    
+-    -> #0 ((&sdata->u.ap.request_smps_work)){+.+...}:
+-            [<c10ae9df>] __lock_acquire+0x183f/0x1910
+-            [<c10aefa9>] lock_acquire+0x79/0xe0
+-            [<c105b917>] flush_work+0x47/0x90
+-            [<c105d867>] __cancel_work_timer+0x67/0xe0
+-            [<c105d90f>] cancel_work_sync+0xf/0x20
+-            [<fb0765cc>] ieee80211_stop_ap+0x8c/0x340 [mac80211]
+-            [<f9b3268c>] cfg80211_stop_ap+0x8c/0x230 [cfg80211]
+-            [<f9b0d8f9>] cfg80211_leave+0x79/0x100 [cfg80211]
+-            [<f9b0da72>] cfg80211_netdev_notifier_call+0xf2/0x4f0 [cfg80211]
+-            [<c160f2c9>] notifier_call_chain+0x59/0x130
+-            [<c106c6de>] __raw_notifier_call_chain+0x1e/0x30
+-            [<c106c70f>] raw_notifier_call_chain+0x1f/0x30
+-            [<c14f8213>] call_netdevice_notifiers_info+0x33/0x70
+-            [<c14f8263>] call_netdevice_notifiers+0x13/0x20
+-            [<c14f82a4>] __dev_close_many+0x34/0xb0
+-            [<c14f83fe>] dev_close_many+0x6e/0xc0
+-            [<c14f9c77>] rollback_registered_many+0xa7/0x1f0
+-            [<c14f9dd4>] unregister_netdevice_many+0x14/0x60
+-            [<fb06f4d9>] ieee80211_remove_interfaces+0xe9/0x170 [mac80211]
+-            [<fb055116>] ieee80211_unregister_hw+0x56/0x110 [mac80211]
+-            [<fa3e9396>] iwl_op_mode_mvm_stop+0x26/0xe0 [iwlmvm]
+-            [<f9b9d8ca>] _iwl_op_mode_stop+0x3a/0x70 [iwlwifi]
+-            [<f9b9d96f>] iwl_opmode_deregister+0x6f/0x90 [iwlwifi]
+-            [<fa405179>] __exit_compat+0xd/0x19 [iwlmvm]
+-            [<c10b8bf9>] SyS_delete_module+0x179/0x2b0
+-            [<c1613421>] sysenter_do_call+0x12/0x32
+-    
+-    Fixes: 687da132234f ("mac80211: implement SMPS for AP")
+-    Cc: <stable@vger.kernel.org> [3.13]
+-    Reported-by: Ilan Peer <ilan.peer@intel.com>
+-    Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit 178b205e96217164fd7c30113464250d0b6f5eca
+-Author: Johannes Berg <johannes.berg@intel.com>
+-Date:   Thu Jan 23 16:32:29 2014 +0100
+-
+-    cfg80211: re-enable 5/10 MHz support
+-    
+-    Unfortunately I forgot this during the merge window, but the
+-    patch seems small enough to go in as a fix. The userspace API
+-    bug that was the reason for disabling it has long been fixed.
+-    
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit 110a1c79acda14edc83b7c8dc5af9c7ddd23eb61
+-Author: Pontus Fuchs <pontus.fuchs@gmail.com>
+-Date:   Thu Jan 16 15:00:40 2014 +0100
+-
+-    nl80211: Reset split_start when netlink skb is exhausted
+-    
+-    When the netlink skb is exhausted split_start is left set. In the
+-    subsequent retry, with a larger buffer, the dump is continued from the
+-    failing point instead of from the beginning.
+-    
+-    This was causing my rt28xx based USB dongle to now show up when
+-    running "iw list" with an old iw version without split dump support.
+-    
+-    Cc: stable@vger.kernel.org
+-    Fixes: 3713b4e364ef ("nl80211: allow splitting wiphy information in dumps")
+-    Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
+-    [avoid the entire workaround when state->split is set]
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit b4c31b45ffc7ef110fa9ecc34d7878fe7c5b9da4
+-Author: Eliad Peller <eliad@wizery.com>
+-Date:   Sun Jan 12 11:06:37 2014 +0200
+-
+-    mac80211: move roc cookie assignment earlier
+-    
+-    ieee80211_start_roc_work() might add a new roc
+-    to existing roc, and tell cfg80211 it has already
+-    started.
+-    
+-    However, this might happen before the roc cookie
+-    was set, resulting in REMAIN_ON_CHANNEL (started)
+-    event with null cookie. Consequently, it can make
+-    wpa_supplicant go out of sync.
+-    
+-    Fix it by setting the roc cookie earlier.
+-    
+-    Cc: stable@vger.kernel.org
+-    Signed-off-by: Eliad Peller <eliad@wizery.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit cfdc9157bfd7bcf88ab4dae08873a9907eba984c
+-Author: Johannes Berg <johannes.berg@intel.com>
+-Date:   Fri Jan 24 14:06:29 2014 +0100
+-
+-    nl80211: send event when AP operation is stopped
+-    
+-    There are a few cases, e.g. suspend, where an AP interface is
+-    stopped by the kernel rather than by userspace request, most
+-    commonly when suspending. To let userspace know about this,
+-    send the NL80211_CMD_STOP_AP command as an event every time
+-    an AP interface is stopped. This also happens when userspace
+-    did in fact request the AP stop, but that's not a problem.
+-    
+-    For full-MAC drivers this may need to be extended to also
+-    cover cases where the device stopped the AP operation for
+-    some reason, this a bit more complicated because then all
+-    cfg80211 state also needs to be reset; such API is not part
+-    of this patch.
+-    
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit d5d567eda7704f190379ca852a8f9a4112e3eee3
+-Author: Johannes Berg <johannes.berg@intel.com>
+-Date:   Thu Jan 23 16:20:29 2014 +0100
+-
+-    mac80211: add length check in ieee80211_is_robust_mgmt_frame()
+-    
+-    A few places weren't checking that the frame passed to the
+-    function actually has enough data even though the function
+-    clearly documents it must have a payload byte. Make this
+-    safer by changing the function to take an skb and checking
+-    the length inside. The old version is preserved for now as
+-    the rtl* drivers use it and don't have a correct skb.
+-    
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit f8f6d212a047fc65c7d3442dfc038f65517236fc
+-Author: Johannes Berg <johannes.berg@intel.com>
+-Date:   Fri Jan 24 10:53:53 2014 +0100
+-
+-    nl80211: fix scheduled scan RSSI matchset attribute confusion
+-    
+-    The scheduled scan matchsets were intended to be a list of filters,
+-    with the found BSS having to pass at least one of them to be passed
+-    to the host. When the RSSI attribute was added, however, this was
+-    broken and currently wpa_supplicant adds that attribute in its own
+-    matchset; however, it doesn't intend that to mean that anything
+-    that passes the RSSI filter should be passed to the host, instead
+-    it wants it to mean that everything needs to also have higher RSSI.
+-    
+-    This is semantically problematic because we have a list of filters
+-    like [ SSID1, SSID2, SSID3, RSSI ] with no real indication which
+-    one should be OR'ed and which one AND'ed.
+-    
+-    To fix this, move the RSSI filter attribute into each matchset. As
+-    we need to stay backward compatible, treat a matchset with only the
+-    RSSI attribute as a "default RSSI filter" for all other matchsets,
+-    but only if there are other matchsets (an RSSI-only matchset by
+-    itself is still desirable.)
+-    
+-    To make driver implementation easier, keep a global min_rssi_thold
+-    for the entire request as well. The only affected driver is ath6kl.
+-    
+-    I found this when I looked into the code after Raja Mani submitted
+-    a patch fixing the n_match_sets calculation to disregard the RSSI,
+-    but that patch didn't address the semantic issue.
+-    
+-    Reported-by: Raja Mani <rmani@qti.qualcomm.com>
+-    Acked-by: Luciano Coelho <luciano.coelho@intel.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit de553e8545e65a6dc4e45f43df7e1443d4291922
+-Author: Johannes Berg <johannes.berg@intel.com>
+-Date:   Fri Jan 24 10:17:47 2014 +0100
+-
+-    nl80211: check nla_parse() return values
+-    
+-    If there's a policy, then nla_parse() return values must be
+-    checked, otherwise the policy is useless and there's nothing
+-    that ensures the attributes are actually what we expect them
+-    to be.
+-    
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+-
+-commit 652204a0733e9e1c54661d6f9d36e2e1e3b22bb1
+-Author: Karl Beldan <karl.beldan@rivierawaves.com>
+-Date:   Thu Jan 23 20:06:34 2014 +0100
+-
+-    mac80211: send {ADD,DEL}BA on AC_VO like other mgmt frames, as per spec
+-    
+-    ATM, {ADD,DEL}BA and BAR frames are sent on the AC matching the TID of
+-    the BA parameters. In the discussion [1] about this patch, Johannes
+-    recalled that it fixed some races with the DELBA and indeed this
+-    behavior was introduced in [2].
+-    While [2] is right for the BARs, the part queueing the {ADD,DEL}BAs on
+-    their BA params TID AC violates the spec and is more a workaround for
+-    some drivers. Helmut expressed some concerns wrt such drivers, in
+-    particular DELBAs in rt2x00.
+-    
+-    ATM, DELBAs are sent after a driver has called (hence "purposely")
+-    ieee80211_start_tx_ba_cb_irqsafe and Johannes and Emmanuel gave some
+-    details wrt intentions behind the split of the IEEE80211_AMPDU_TX_STOP_*
+-    given to the driver ampdu_action supposed to call this function, which
+-    could prove handy to people trying to do the right thing in faulty
+-    drivers (if their fw/hw don't get in their way).
+-    
+-    [1] http://mid.gmane.org/1390391564-18481-1-git-send-email-karl.beldan@gmail.com
+-    [2] Commit: cf6bb79ad828 ("mac80211: Use appropriate TID for sending BAR, ADDBA and DELBA frames")
+-    
+-    Signed-off-by: Karl Beldan <karl.beldan@rivierawaves.com>
+-    Cc: Helmut Schaa <helmut.schaa@googlemail.com>
+-    Cc: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+-    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+-+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
+-@@ -790,7 +790,7 @@ void ath6kl_cfg80211_connect_event(struc
+- 	if (nw_type & ADHOC_NETWORK) {
+- 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
+- 			   nw_type & ADHOC_CREATOR ? "creator" : "joiner");
+--		cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
+-+		cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
+- 		cfg80211_put_bss(ar->wiphy, bss);
+- 		return;
+- 	}
+-@@ -861,13 +861,9 @@ void ath6kl_cfg80211_disconnect_event(st
+- 	}
+- 
+- 	if (vif->nw_type & ADHOC_NETWORK) {
+--		if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
+-+		if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
+- 			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+- 				   "%s: ath6k not in ibss mode\n", __func__);
+--			return;
+--		}
+--		memset(bssid, 0, ETH_ALEN);
+--		cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
+- 		return;
+- 	}
+- 
+-@@ -3256,6 +3252,15 @@ static int ath6kl_cfg80211_sscan_start(s
+- 	struct ath6kl_vif *vif = netdev_priv(dev);
+- 	u16 interval;
+- 	int ret, rssi_thold;
+-+	int n_match_sets = request->n_match_sets;
+-+
+-+	/*
+-+	 * If there's a matchset w/o an SSID, then assume it's just for
+-+	 * the RSSI (nothing else is currently supported) and ignore it.
+-+	 * The device only supports a global RSSI filter that we set below.
+-+	 */
+-+	if (n_match_sets == 1 && !request->match_sets[0].ssid.ssid_len)
+-+		n_match_sets = 0;
+- 
+- 	if (ar->state != ATH6KL_STATE_ON)
+- 		return -EIO;
+-@@ -3268,11 +3273,11 @@ static int ath6kl_cfg80211_sscan_start(s
+- 	ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
+- 				      request->n_ssids,
+- 				      request->match_sets,
+--				      request->n_match_sets);
+-+				      n_match_sets);
+- 	if (ret < 0)
+- 		return ret;
+- 
+--	if (!request->n_match_sets) {
+-+	if (!n_match_sets) {
+- 		ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
+- 					       ALL_BSS_FILTER, 0);
+- 		if (ret < 0)
+-@@ -3286,12 +3291,12 @@ static int ath6kl_cfg80211_sscan_start(s
+- 
+- 	if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
+- 		     ar->fw_capabilities)) {
+--		if (request->rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
+-+		if (request->min_rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
+- 			rssi_thold = 0;
+--		else if (request->rssi_thold < -127)
+-+		else if (request->min_rssi_thold < -127)
+- 			rssi_thold = -127;
+- 		else
+--			rssi_thold = request->rssi_thold;
+-+			rssi_thold = request->min_rssi_thold;
+- 
+- 		ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
+- 						     rssi_thold);
+---- a/drivers/net/wireless/ath/ath9k/hw.c
+-+++ b/drivers/net/wireless/ath/ath9k/hw.c
+-@@ -1316,7 +1316,7 @@ static bool ath9k_hw_set_reset(struct at
+- 	if (AR_SREV_9300_20_OR_LATER(ah))
+- 		udelay(50);
+- 	else if (AR_SREV_9100(ah))
+--		udelay(10000);
+-+		mdelay(10);
+- 	else
+- 		udelay(100);
+- 
+-@@ -1534,7 +1534,7 @@ EXPORT_SYMBOL(ath9k_hw_check_nav);
+- bool ath9k_hw_check_alive(struct ath_hw *ah)
+- {
+- 	int count = 50;
+--	u32 reg;
+-+	u32 reg, last_val;
+- 
+- 	if (AR_SREV_9300(ah))
+- 		return !ath9k_hw_detect_mac_hang(ah);
+-@@ -1542,9 +1542,14 @@ bool ath9k_hw_check_alive(struct ath_hw 
+- 	if (AR_SREV_9285_12_OR_LATER(ah))
+- 		return true;
+- 
+-+	last_val = REG_READ(ah, AR_OBS_BUS_1);
+- 	do {
+- 		reg = REG_READ(ah, AR_OBS_BUS_1);
+-+		if (reg != last_val)
+-+			return true;
+- 
+-+		udelay(1);
+-+		last_val = reg;
+- 		if ((reg & 0x7E7FFFEF) == 0x00702400)
+- 			continue;
+- 
+-@@ -2051,9 +2056,8 @@ static bool ath9k_hw_set_power_awake(str
+- 
+- 	REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
+- 		    AR_RTC_FORCE_WAKE_EN);
+--
+- 	if (AR_SREV_9100(ah))
+--		udelay(10000);
+-+		mdelay(10);
+- 	else
+- 		udelay(50);
+- 
+---- a/drivers/net/wireless/ath/ath9k/main.c
+-+++ b/drivers/net/wireless/ath/ath9k/main.c
+-@@ -451,7 +451,7 @@ void ath9k_tasklet(unsigned long data)
+- 		 * interrupts are enabled in the reset routine.
+- 		 */
+- 		atomic_inc(&ah->intr_ref_cnt);
+--		ath_dbg(common, ANY, "FATAL: Skipping interrupts\n");
+-+		ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
+- 		goto out;
+- 	}
+- 
+-@@ -471,7 +471,7 @@ void ath9k_tasklet(unsigned long data)
+- 			 * interrupts are enabled in the reset routine.
+- 			 */
+- 			atomic_inc(&ah->intr_ref_cnt);
+--			ath_dbg(common, ANY,
+-+			ath_dbg(common, RESET,
+- 				"BB_WATCHDOG: Skipping interrupts\n");
+- 			goto out;
+- 		}
+-@@ -484,7 +484,7 @@ void ath9k_tasklet(unsigned long data)
+- 			type = RESET_TYPE_TX_GTT;
+- 			ath9k_queue_reset(sc, type);
+- 			atomic_inc(&ah->intr_ref_cnt);
+--			ath_dbg(common, ANY,
+-+			ath_dbg(common, RESET,
+- 				"GTT: Skipping interrupts\n");
+- 			goto out;
+- 		}
+-@@ -1866,7 +1866,7 @@ static void ath9k_set_coverage_class(str
+- 
+- static bool ath9k_has_tx_pending(struct ath_softc *sc)
+- {
+--	int i, npend;
+-+	int i, npend = 0;
+- 
+- 	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+- 		if (!ATH_TXQ_SETUP(sc, i))
+---- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+-+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
+-@@ -595,6 +595,9 @@ static void iwl_scan_offload_build_ssid(
+- 	 * config match list.
+- 	 */
+- 	for (i = 0; i < req->n_match_sets && i < PROBE_OPTION_MAX; i++) {
+-+		/* skip empty SSID matchsets */
+-+		if (!req->match_sets[i].ssid.ssid_len)
+-+			continue;
+- 		scan->direct_scan[i].id = WLAN_EID_SSID;
+- 		scan->direct_scan[i].len = req->match_sets[i].ssid.ssid_len;
+- 		memcpy(scan->direct_scan[i].ssid, req->match_sets[i].ssid.ssid,
+---- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
+-+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
+-@@ -452,7 +452,7 @@ bool rtl88ee_rx_query_desc(struct ieee80
+- 			/* During testing, hdr was NULL */
+- 			return false;
+- 		}
+--		if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
+-+		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
+- 		    (ieee80211_has_protected(hdr->frame_control)))
+- 			rx_status->flag &= ~RX_FLAG_DECRYPTED;
+- 		else
+---- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+-+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+-@@ -393,7 +393,7 @@ bool rtl92ce_rx_query_desc(struct ieee80
+- 			/* In testing, hdr was NULL here */
+- 			return false;
+- 		}
+--		if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
+-+		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
+- 		    (ieee80211_has_protected(hdr->frame_control)))
+- 			rx_status->flag &= ~RX_FLAG_DECRYPTED;
+- 		else
+---- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+-+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+-@@ -310,7 +310,7 @@ bool rtl92se_rx_query_desc(struct ieee80
+- 			/* during testing, hdr was NULL here */
+- 			return false;
+- 		}
+--		if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
+-+		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
+- 			(ieee80211_has_protected(hdr->frame_control)))
+- 			rx_status->flag &= ~RX_FLAG_DECRYPTED;
+- 		else
+---- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
+-+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
+-@@ -334,7 +334,7 @@ bool rtl8723ae_rx_query_desc(struct ieee
+- 			/* during testing, hdr could be NULL here */
+- 			return false;
+- 		}
+--		if ((ieee80211_is_robust_mgmt_frame(hdr)) &&
+-+		if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
+- 			(ieee80211_has_protected(hdr->frame_control)))
+- 			rx_status->flag &= ~RX_FLAG_DECRYPTED;
+- 		else
+---- a/include/linux/ieee80211.h
+-+++ b/include/linux/ieee80211.h
+-@@ -597,6 +597,20 @@ static inline int ieee80211_is_qos_nullf
+- }
+- 
+- /**
+-+ * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU
+-+ * @fc: frame control field in little-endian byteorder
+-+ */
+-+static inline bool ieee80211_is_bufferable_mmpdu(__le16 fc)
+-+{
+-+	/* IEEE 802.11-2012, definition of "bufferable management frame";
+-+	 * note that this ignores the IBSS special case. */
+-+	return ieee80211_is_mgmt(fc) &&
+-+	       (ieee80211_is_action(fc) ||
+-+		ieee80211_is_disassoc(fc) ||
+-+		ieee80211_is_deauth(fc));
+-+}
+-+
+-+/**
+-  * ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set
+-  * @seq_ctrl: frame sequence control bytes in little-endian byteorder
+-  */
+-@@ -2192,10 +2206,10 @@ static inline u8 *ieee80211_get_DA(struc
+- }
+- 
+- /**
+-- * ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame
+-+ * _ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame
+-  * @hdr: the frame (buffer must include at least the first octet of payload)
+-  */
+--static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
+-+static inline bool _ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
+- {
+- 	if (ieee80211_is_disassoc(hdr->frame_control) ||
+- 	    ieee80211_is_deauth(hdr->frame_control))
+-@@ -2224,6 +2238,17 @@ static inline bool ieee80211_is_robust_m
+- }
+- 
+- /**
+-+ * ieee80211_is_robust_mgmt_frame - check if skb contains a robust mgmt frame
+-+ * @skb: the skb containing the frame, length will be checked
+-+ */
+-+static inline bool ieee80211_is_robust_mgmt_frame(struct sk_buff *skb)
+-+{
+-+	if (skb->len < 25)
+-+		return false;
+-+	return _ieee80211_is_robust_mgmt_frame((void *)skb->data);
+-+}
+-+
+-+/**
+-  * ieee80211_is_public_action - check if frame is a public action frame
+-  * @hdr: the frame
+-  * @len: length of the frame
+---- a/include/net/cfg80211.h
+-+++ b/include/net/cfg80211.h
+-@@ -1395,9 +1395,11 @@ struct cfg80211_scan_request {
+-  * struct cfg80211_match_set - sets of attributes to match
+-  *
+-  * @ssid: SSID to be matched
+-+ * @rssi_thold: don't report scan results below this threshold (in s32 dBm)
+-  */
+- struct cfg80211_match_set {
+- 	struct cfg80211_ssid ssid;
+-+	s32 rssi_thold;
+- };
+- 
+- /**
+-@@ -1420,7 +1422,8 @@ struct cfg80211_match_set {
+-  * @dev: the interface
+-  * @scan_start: start time of the scheduled scan
+-  * @channels: channels to scan
+-- * @rssi_thold: don't report scan results below this threshold (in s32 dBm)
+-+ * @min_rssi_thold: for drivers only supporting a single threshold, this
+-+ *	contains the minimum over all matchsets
+-  */
+- struct cfg80211_sched_scan_request {
+- 	struct cfg80211_ssid *ssids;
+-@@ -1433,7 +1436,7 @@ struct cfg80211_sched_scan_request {
+- 	u32 flags;
+- 	struct cfg80211_match_set *match_sets;
+- 	int n_match_sets;
+--	s32 rssi_thold;
+-+	s32 min_rssi_thold;
+- 
+- 	/* internal */
+- 	struct wiphy *wiphy;
+-@@ -3130,8 +3133,8 @@ struct cfg80211_cached_keys;
+-  * @identifier: (private) Identifier used in nl80211 to identify this
+-  *	wireless device if it has no netdev
+-  * @current_bss: (private) Used by the internal configuration code
+-- * @channel: (private) Used by the internal configuration code to track
+-- *	the user-set AP, monitor and WDS channel
+-+ * @chandef: (private) Used by the internal configuration code to track
+-+ *	the user-set channel definition.
+-  * @preset_chandef: (private) Used by the internal configuration code to
+-  *	track the channel to be used for AP later
+-  * @bssid: (private) Used by the internal configuration code
+-@@ -3195,9 +3198,7 @@ struct wireless_dev {
+- 
+- 	struct cfg80211_internal_bss *current_bss; /* associated / joined */
+- 	struct cfg80211_chan_def preset_chandef;
+--
+--	/* for AP and mesh channel tracking */
+--	struct ieee80211_channel *channel;
+-+	struct cfg80211_chan_def chandef;
+- 
+- 	bool ibss_fixed;
+- 	bool ibss_dfs_possible;
+-@@ -3879,6 +3880,7 @@ void cfg80211_michael_mic_failure(struct
+-  *
+-  * @dev: network device
+-  * @bssid: the BSSID of the IBSS joined
+-+ * @channel: the channel of the IBSS joined
+-  * @gfp: allocation flags
+-  *
+-  * This function notifies cfg80211 that the device joined an IBSS or
+-@@ -3888,7 +3890,8 @@ void cfg80211_michael_mic_failure(struct
+-  * with the locally generated beacon -- this guarantees that there is
+-  * always a scan result for this IBSS. cfg80211 will handle the rest.
+-  */
+--void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
+-+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
+-+			  struct ieee80211_channel *channel, gfp_t gfp);
+- 
+- /**
+-  * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
+---- a/include/uapi/linux/nl80211.h
+-+++ b/include/uapi/linux/nl80211.h
+-@@ -2442,9 +2442,15 @@ enum nl80211_reg_rule_attr {
+-  * enum nl80211_sched_scan_match_attr - scheduled scan match attributes
+-  * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved
+-  * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching,
+-- * only report BSS with matching SSID.
+-+ *	only report BSS with matching SSID.
+-  * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a
+-- *	BSS in scan results. Filtering is turned off if not specified.
+-+ *	BSS in scan results. Filtering is turned off if not specified. Note that
+-+ *	if this attribute is in a match set of its own, then it is treated as
+-+ *	the default value for all matchsets with an SSID, rather than being a
+-+ *	matchset of its own without an RSSI filter. This is due to problems with
+-+ *	how this API was implemented in the past. Also, due to the same problem,
+-+ *	the only way to create a matchset with only an RSSI filter (with this
+-+ *	attribute) is if there's only a single matchset with the RSSI attribute.
+-  * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
+-  *	attribute number currently defined
+-  * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
+---- a/net/mac80211/agg-tx.c
+-+++ b/net/mac80211/agg-tx.c
+-@@ -107,7 +107,7 @@ static void ieee80211_send_addba_request
+- 	mgmt->u.action.u.addba_req.start_seq_num =
+- 					cpu_to_le16(start_seq_num << 4);
+- 
+--	ieee80211_tx_skb_tid(sdata, skb, tid);
+-+	ieee80211_tx_skb(sdata, skb);
+- }
+- 
+- void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
+---- a/net/mac80211/cfg.c
+-+++ b/net/mac80211/cfg.c
+-@@ -970,9 +970,9 @@ static int ieee80211_start_ap(struct wip
+- 	/* TODO: make hostapd tell us what it wants */
+- 	sdata->smps_mode = IEEE80211_SMPS_OFF;
+- 	sdata->needed_rx_chains = sdata->local->rx_chains;
+--	sdata->radar_required = params->radar_required;
+- 
+- 	mutex_lock(&local->mtx);
+-+	sdata->radar_required = params->radar_required;
+- 	err = ieee80211_vif_use_channel(sdata, &params->chandef,
+- 					IEEE80211_CHANCTX_SHARED);
+- 	mutex_unlock(&local->mtx);
+-@@ -1021,8 +1021,10 @@ static int ieee80211_start_ap(struct wip
+- 					IEEE80211_P2P_OPPPS_ENABLE_BIT;
+- 
+- 	err = ieee80211_assign_beacon(sdata, &params->beacon);
+--	if (err < 0)
+-+	if (err < 0) {
+-+		ieee80211_vif_release_channel(sdata);
+- 		return err;
+-+	}
+- 	changed |= err;
+- 
+- 	err = drv_start_ap(sdata->local, sdata);
+-@@ -1032,6 +1034,7 @@ static int ieee80211_start_ap(struct wip
+- 		if (old)
+- 			kfree_rcu(old, rcu_head);
+- 		RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
+-+		ieee80211_vif_release_channel(sdata);
+- 		return err;
+- 	}
+- 
+-@@ -1053,6 +1056,7 @@ static int ieee80211_change_beacon(struc
+- 	int err;
+- 
+- 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+-+	sdata_assert_lock(sdata);
+- 
+- 	/* don't allow changing the beacon while CSA is in place - offset
+- 	 * of channel switch counter may change
+-@@ -1080,6 +1084,8 @@ static int ieee80211_stop_ap(struct wiph
+- 	struct probe_resp *old_probe_resp;
+- 	struct cfg80211_chan_def chandef;
+- 
+-+	sdata_assert_lock(sdata);
+-+
+- 	old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata);
+- 	if (!old_beacon)
+- 		return -ENOENT;
+-@@ -1090,8 +1096,6 @@ static int ieee80211_stop_ap(struct wiph
+- 	kfree(sdata->u.ap.next_beacon);
+- 	sdata->u.ap.next_beacon = NULL;
+- 
+--	cancel_work_sync(&sdata->u.ap.request_smps_work);
+--
+- 	/* turn off carrier for this interface and dependent VLANs */
+- 	list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
+- 		netif_carrier_off(vlan->dev);
+-@@ -1103,6 +1107,7 @@ static int ieee80211_stop_ap(struct wiph
+- 	kfree_rcu(old_beacon, rcu_head);
+- 	if (old_probe_resp)
+- 		kfree_rcu(old_probe_resp, rcu_head);
+-+	sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
+- 
+- 	__sta_info_flush(sdata, true);
+- 	ieee80211_free_keys(sdata, true);
+-@@ -1988,6 +1993,9 @@ static int ieee80211_change_bss(struct w
+- 
+- 	band = ieee80211_get_sdata_band(sdata);
+- 
+-+	if (WARN_ON(!wiphy->bands[band]))
+-+		return -EINVAL;
+-+
+- 	if (params->use_cts_prot >= 0) {
+- 		sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
+- 		changed |= BSS_CHANGED_ERP_CTS_PROT;
+-@@ -2638,6 +2646,24 @@ static int ieee80211_start_roc_work(stru
+- 	INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work);
+- 	INIT_LIST_HEAD(&roc->dependents);
+- 
+-+	/*
+-+	 * cookie is either the roc cookie (for normal roc)
+-+	 * or the SKB (for mgmt TX)
+-+	 */
+-+	if (!txskb) {
+-+		/* local->mtx protects this */
+-+		local->roc_cookie_counter++;
+-+		roc->cookie = local->roc_cookie_counter;
+-+		/* wow, you wrapped 64 bits ... more likely a bug */
+-+		if (WARN_ON(roc->cookie == 0)) {
+-+			roc->cookie = 1;
+-+			local->roc_cookie_counter++;
+-+		}
+-+		*cookie = roc->cookie;
+-+	} else {
+-+		*cookie = (unsigned long)txskb;
+-+	}
+-+
+- 	/* if there's one pending or we're scanning, queue this one */
+- 	if (!list_empty(&local->roc_list) ||
+- 	    local->scanning || local->radar_detect_enabled)
+-@@ -2772,24 +2798,6 @@ static int ieee80211_start_roc_work(stru
+- 	if (!queued)
+- 		list_add_tail(&roc->list, &local->roc_list);
+- 
+--	/*
+--	 * cookie is either the roc cookie (for normal roc)
+--	 * or the SKB (for mgmt TX)
+--	 */
+--	if (!txskb) {
+--		/* local->mtx protects this */
+--		local->roc_cookie_counter++;
+--		roc->cookie = local->roc_cookie_counter;
+--		/* wow, you wrapped 64 bits ... more likely a bug */
+--		if (WARN_ON(roc->cookie == 0)) {
+--			roc->cookie = 1;
+--			local->roc_cookie_counter++;
+--		}
+--		*cookie = roc->cookie;
+--	} else {
+--		*cookie = (unsigned long)txskb;
+--	}
+--
+- 	return 0;
+- }
+- 
+-@@ -3004,8 +3012,10 @@ void ieee80211_csa_finalize_work(struct 
+- 	if (!ieee80211_sdata_running(sdata))
+- 		goto unlock;
+- 
+--	sdata->radar_required = sdata->csa_radar_required;
+-+	sdata_assert_lock(sdata);
+-+
+- 	mutex_lock(&local->mtx);
+-+	sdata->radar_required = sdata->csa_radar_required;
+- 	err = ieee80211_vif_change_channel(sdata, &changed);
+- 	mutex_unlock(&local->mtx);
+- 	if (WARN_ON(err < 0))
+-@@ -3022,13 +3032,13 @@ void ieee80211_csa_finalize_work(struct 
+- 	switch (sdata->vif.type) {
+- 	case NL80211_IFTYPE_AP:
+- 		err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
+-+		kfree(sdata->u.ap.next_beacon);
+-+		sdata->u.ap.next_beacon = NULL;
+-+
+- 		if (err < 0)
+- 			goto unlock;
+- 
+- 		changed |= err;
+--		kfree(sdata->u.ap.next_beacon);
+--		sdata->u.ap.next_beacon = NULL;
+--
+- 		ieee80211_bss_info_change_notify(sdata, err);
+- 		break;
+- 	case NL80211_IFTYPE_ADHOC:
+-@@ -3066,7 +3076,7 @@ int ieee80211_channel_switch(struct wiph
+- 	struct ieee80211_if_mesh __maybe_unused *ifmsh;
+- 	int err, num_chanctx;
+- 
+--	lockdep_assert_held(&sdata->wdev.mtx);
+-+	sdata_assert_lock(sdata);
+- 
+- 	if (!list_empty(&local->roc_list) || local->scanning)
+- 		return -EBUSY;
+---- a/net/mac80211/ht.c
+-+++ b/net/mac80211/ht.c
+-@@ -375,7 +375,7 @@ void ieee80211_send_delba(struct ieee802
+- 	mgmt->u.action.u.delba.params = cpu_to_le16(params);
+- 	mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
+- 
+--	ieee80211_tx_skb_tid(sdata, skb, tid);
+-+	ieee80211_tx_skb(sdata, skb);
+- }
+- 
+- void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
+-@@ -466,7 +466,9 @@ void ieee80211_request_smps_ap_work(stru
+- 			     u.ap.request_smps_work);
+- 
+- 	sdata_lock(sdata);
+--	__ieee80211_request_smps_ap(sdata, sdata->u.ap.driver_smps_mode);
+-+	if (sdata_dereference(sdata->u.ap.beacon, sdata))
+-+		__ieee80211_request_smps_ap(sdata,
+-+					    sdata->u.ap.driver_smps_mode);
+- 	sdata_unlock(sdata);
+- }
+- 
+---- a/net/mac80211/iface.c
+-+++ b/net/mac80211/iface.c
+-@@ -770,12 +770,19 @@ static void ieee80211_do_stop(struct iee
+- 
+- 	ieee80211_roc_purge(local, sdata);
+- 
+--	if (sdata->vif.type == NL80211_IFTYPE_STATION)
+-+	switch (sdata->vif.type) {
+-+	case NL80211_IFTYPE_STATION:
+- 		ieee80211_mgd_stop(sdata);
+--
+--	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+-+		break;
+-+	case NL80211_IFTYPE_ADHOC:
+- 		ieee80211_ibss_stop(sdata);
+--
+-+		break;
+-+	case NL80211_IFTYPE_AP:
+-+		cancel_work_sync(&sdata->u.ap.request_smps_work);
+-+		break;
+-+	default:
+-+		break;
+-+	}
+- 
+- 	/*
+- 	 * Remove all stations associated with this interface.
+-@@ -827,7 +834,9 @@ static void ieee80211_do_stop(struct iee
+- 	cancel_work_sync(&local->dynamic_ps_enable_work);
+- 
+- 	cancel_work_sync(&sdata->recalc_smps);
+-+	sdata_lock(sdata);
+- 	sdata->vif.csa_active = false;
+-+	sdata_unlock(sdata);
+- 	cancel_work_sync(&sdata->csa_finalize_work);
+- 
+- 	cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
+---- a/net/mac80211/rx.c
+-+++ b/net/mac80211/rx.c
+-@@ -599,10 +599,10 @@ static int ieee80211_is_unicast_robust_m
+- {
+- 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+- 
+--	if (skb->len < 24 || is_multicast_ether_addr(hdr->addr1))
+-+	if (is_multicast_ether_addr(hdr->addr1))
+- 		return 0;
+- 
+--	return ieee80211_is_robust_mgmt_frame(hdr);
+-+	return ieee80211_is_robust_mgmt_frame(skb);
+- }
+- 
+- 
+-@@ -610,10 +610,10 @@ static int ieee80211_is_multicast_robust
+- {
+- 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+- 
+--	if (skb->len < 24 || !is_multicast_ether_addr(hdr->addr1))
+-+	if (!is_multicast_ether_addr(hdr->addr1))
+- 		return 0;
+- 
+--	return ieee80211_is_robust_mgmt_frame(hdr);
+-+	return ieee80211_is_robust_mgmt_frame(skb);
+- }
+- 
+- 
+-@@ -626,7 +626,7 @@ static int ieee80211_get_mmie_keyidx(str
+- 	if (skb->len < 24 + sizeof(*mmie) || !is_multicast_ether_addr(hdr->da))
+- 		return -1;
+- 
+--	if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) hdr))
+-+	if (!ieee80211_is_robust_mgmt_frame(skb))
+- 		return -1; /* not a robust management frame */
+- 
+- 	mmie = (struct ieee80211_mmie *)
+-@@ -1128,6 +1128,13 @@ static void sta_ps_end(struct sta_info *
+- 	       sta->sta.addr, sta->sta.aid);
+- 
+- 	if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
+-+		/*
+-+		 * Clear the flag only if the other one is still set
+-+		 * so that the TX path won't start TX'ing new frames
+-+		 * directly ... In the case that the driver flag isn't
+-+		 * set ieee80211_sta_ps_deliver_wakeup() will clear it.
+-+		 */
+-+		clear_sta_flag(sta, WLAN_STA_PS_STA);
+- 		ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n",
+- 		       sta->sta.addr, sta->sta.aid);
+- 		return;
+-@@ -1311,18 +1318,15 @@ ieee80211_rx_h_sta_process(struct ieee80
+- 	    !ieee80211_has_morefrags(hdr->frame_control) &&
+- 	    !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
+- 	    (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
+--	     rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
+-+	     rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
+-+	    /* PM bit is only checked in frames where it isn't reserved,
+-+	     * in AP mode it's reserved in non-bufferable management frames
+-+	     * (cf. IEEE 802.11-2012 8.2.4.1.7 Power Management field)
+-+	     */
+-+	    (!ieee80211_is_mgmt(hdr->frame_control) ||
+-+	     ieee80211_is_bufferable_mmpdu(hdr->frame_control))) {
+- 		if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
+--			/*
+--			 * Ignore doze->wake transitions that are
+--			 * indicated by non-data frames, the standard
+--			 * is unclear here, but for example going to
+--			 * PS mode and then scanning would cause a
+--			 * doze->wake transition for the probe request,
+--			 * and that is clearly undesirable.
+--			 */
+--			if (ieee80211_is_data(hdr->frame_control) &&
+--			    !ieee80211_has_pm(hdr->frame_control))
+-+			if (!ieee80211_has_pm(hdr->frame_control))
+- 				sta_ps_end(sta);
+- 		} else {
+- 			if (ieee80211_has_pm(hdr->frame_control))
+-@@ -1845,8 +1849,7 @@ static int ieee80211_drop_unencrypted_mg
+- 		 * having configured keys.
+- 		 */
+- 		if (unlikely(ieee80211_is_action(fc) && !rx->key &&
+--			     ieee80211_is_robust_mgmt_frame(
+--				     (struct ieee80211_hdr *) rx->skb->data)))
+-+			     ieee80211_is_robust_mgmt_frame(rx->skb)))
+- 			return -EACCES;
+- 	}
+- 
+---- a/net/mac80211/tx.c
+-+++ b/net/mac80211/tx.c
+-@@ -452,8 +452,7 @@ static int ieee80211_use_mfp(__le16 fc, 
+- 	if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP))
+- 		return 0;
+- 
+--	if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *)
+--					    skb->data))
+-+	if (!ieee80211_is_robust_mgmt_frame(skb))
+- 		return 0;
+- 
+- 	return 1;
+-@@ -478,6 +477,20 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
+- 		       sta->sta.addr, sta->sta.aid, ac);
+- 		if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
+- 			purge_old_ps_buffers(tx->local);
+-+
+-+		/* sync with ieee80211_sta_ps_deliver_wakeup */
+-+		spin_lock(&sta->ps_lock);
+-+		/*
+-+		 * STA woke up the meantime and all the frames on ps_tx_buf have
+-+		 * been queued to pending queue. No reordering can happen, go
+-+		 * ahead and Tx the packet.
+-+		 */
+-+		if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
+-+		    !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
+-+			spin_unlock(&sta->ps_lock);
+-+			return TX_CONTINUE;
+-+		}
+-+
+- 		if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) {
+- 			struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]);
+- 			ps_dbg(tx->sdata,
+-@@ -492,6 +505,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
+- 		info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
+- 		info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
+- 		skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb);
+-+		spin_unlock(&sta->ps_lock);
+- 
+- 		if (!timer_pending(&local->sta_cleanup))
+- 			mod_timer(&local->sta_cleanup,
+-@@ -525,9 +539,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_t
+- 
+- 	/* only deauth, disassoc and action are bufferable MMPDUs */
+- 	if (ieee80211_is_mgmt(hdr->frame_control) &&
+--	    !ieee80211_is_deauth(hdr->frame_control) &&
+--	    !ieee80211_is_disassoc(hdr->frame_control) &&
+--	    !ieee80211_is_action(hdr->frame_control)) {
+-+	    !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) {
+- 		if (tx->flags & IEEE80211_TX_UNICAST)
+- 			info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
+- 		return TX_CONTINUE;
+-@@ -567,7 +579,7 @@ ieee80211_tx_h_select_key(struct ieee802
+- 		tx->key = key;
+- 	else if (ieee80211_is_mgmt(hdr->frame_control) &&
+- 		 is_multicast_ether_addr(hdr->addr1) &&
+--		 ieee80211_is_robust_mgmt_frame(hdr) &&
+-+		 ieee80211_is_robust_mgmt_frame(tx->skb) &&
+- 		 (key = rcu_dereference(tx->sdata->default_mgmt_key)))
+- 		tx->key = key;
+- 	else if (is_multicast_ether_addr(hdr->addr1) &&
+-@@ -582,12 +594,12 @@ ieee80211_tx_h_select_key(struct ieee802
+- 		tx->key = NULL;
+- 	else if (tx->skb->protocol == tx->sdata->control_port_protocol)
+- 		tx->key = NULL;
+--	else if (ieee80211_is_robust_mgmt_frame(hdr) &&
+-+	else if (ieee80211_is_robust_mgmt_frame(tx->skb) &&
+- 		 !(ieee80211_is_action(hdr->frame_control) &&
+- 		   tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))
+- 		tx->key = NULL;
+- 	else if (ieee80211_is_mgmt(hdr->frame_control) &&
+--		 !ieee80211_is_robust_mgmt_frame(hdr))
+-+		 !ieee80211_is_robust_mgmt_frame(tx->skb))
+- 		tx->key = NULL;
+- 	else {
+- 		I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
+-@@ -878,7 +890,7 @@ static int ieee80211_fragment(struct iee
+- 	}
+- 
+- 	/* adjust first fragment's length */
+--	skb->len = hdrlen + per_fragm;
+-+	skb_trim(skb, hdrlen + per_fragm);
+- 	return 0;
+- }
+- 
+-@@ -2900,7 +2912,7 @@ ieee80211_get_buffered_bc(struct ieee802
+- 				cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+- 		}
+- 
+--		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+-+		if (sdata->vif.type == NL80211_IFTYPE_AP)
+- 			sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
+- 		if (!ieee80211_tx_prepare(sdata, &tx, skb))
+- 			break;
+---- a/net/mac80211/wpa.c
+-+++ b/net/mac80211/wpa.c
+-@@ -499,7 +499,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+- 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
+- 
+- 	if (!ieee80211_is_data(hdr->frame_control) &&
+--	    !ieee80211_is_robust_mgmt_frame(hdr))
+-+	    !ieee80211_is_robust_mgmt_frame(skb))
+- 		return RX_CONTINUE;
+- 
+- 	data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN -
+---- a/net/wireless/ap.c
+-+++ b/net/wireless/ap.c
+-@@ -27,9 +27,10 @@ static int __cfg80211_stop_ap(struct cfg
+- 	err = rdev_stop_ap(rdev, dev);
+- 	if (!err) {
+- 		wdev->beacon_interval = 0;
+--		wdev->channel = NULL;
+-+		memset(&wdev->chandef, 0, sizeof(wdev->chandef));
+- 		wdev->ssid_len = 0;
+- 		rdev_set_qos_map(rdev, dev, NULL);
+-+		nl80211_send_ap_stopped(wdev);
+- 	}
+- 
+- 	return err;
+---- a/net/wireless/core.c
+-+++ b/net/wireless/core.c
+-@@ -203,8 +203,11 @@ void cfg80211_stop_p2p_device(struct cfg
+- 
+- 	rdev->opencount--;
+- 
+--	WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev &&
+--		!rdev->scan_req->notified);
+-+	if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
+-+		if (WARN_ON(!rdev->scan_req->notified))
+-+			rdev->scan_req->aborted = true;
+-+		___cfg80211_scan_done(rdev, false);
+-+	}
+- }
+- 
+- static int cfg80211_rfkill_set_block(void *data, bool blocked)
+-@@ -447,9 +450,6 @@ int wiphy_register(struct wiphy *wiphy)
+- 	int i;
+- 	u16 ifmodes = wiphy->interface_modes;
+- 
+--	/* support for 5/10 MHz is broken due to nl80211 API mess - disable */
+--	wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ;
+--
+- 	/*
+- 	 * There are major locking problems in nl80211/mac80211 for CSA,
+- 	 * disable for all drivers until this has been reworked.
+-@@ -795,8 +795,6 @@ void cfg80211_leave(struct cfg80211_regi
+- 	default:
+- 		break;
+- 	}
+--
+--	wdev->beacon_interval = 0;
+- }
+- 
+- static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
+-@@ -875,8 +873,11 @@ static int cfg80211_netdev_notifier_call
+- 		break;
+- 	case NETDEV_DOWN:
+- 		cfg80211_update_iface_num(rdev, wdev->iftype, -1);
+--		WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev &&
+--			!rdev->scan_req->notified);
+-+		if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
+-+			if (WARN_ON(!rdev->scan_req->notified))
+-+				rdev->scan_req->aborted = true;
+-+			___cfg80211_scan_done(rdev, false);
+-+		}
+- 
+- 		if (WARN_ON(rdev->sched_scan_req &&
+- 			    rdev->sched_scan_req->dev == wdev->netdev)) {
+---- a/net/wireless/core.h
+-+++ b/net/wireless/core.h
+-@@ -62,6 +62,7 @@ struct cfg80211_registered_device {
+- 	struct rb_root bss_tree;
+- 	u32 bss_generation;
+- 	struct cfg80211_scan_request *scan_req; /* protected by RTNL */
+-+	struct sk_buff *scan_msg;
+- 	struct cfg80211_sched_scan_request *sched_scan_req;
+- 	unsigned long suspend_at;
+- 	struct work_struct scan_done_wk;
+-@@ -210,6 +211,7 @@ struct cfg80211_event {
+- 		} dc;
+- 		struct {
+- 			u8 bssid[ETH_ALEN];
+-+			struct ieee80211_channel *channel;
+- 		} ij;
+- 	};
+- };
+-@@ -257,7 +259,8 @@ int __cfg80211_leave_ibss(struct cfg8021
+- 			  struct net_device *dev, bool nowext);
+- int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+- 			struct net_device *dev, bool nowext);
+--void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid);
+-+void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
+-+			    struct ieee80211_channel *channel);
+- int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
+- 			    struct wireless_dev *wdev);
+- 
+-@@ -361,7 +364,8 @@ int cfg80211_validate_key_settings(struc
+- 				   struct key_params *params, int key_idx,
+- 				   bool pairwise, const u8 *mac_addr);
+- void __cfg80211_scan_done(struct work_struct *wk);
+--void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev);
+-+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
+-+			   bool send_message);
+- void __cfg80211_sched_scan_results(struct work_struct *wk);
+- int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
+- 			       bool driver_initiated);
+-@@ -441,7 +445,8 @@ static inline unsigned int elapsed_jiffi
+- void
+- cfg80211_get_chan_state(struct wireless_dev *wdev,
+- 		        struct ieee80211_channel **chan,
+--		        enum cfg80211_chan_mode *chanmode);
+-+		        enum cfg80211_chan_mode *chanmode,
+-+		        u8 *radar_detect);
+- 
+- int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
+- 				 struct cfg80211_chan_def *chandef);
+---- a/net/wireless/nl80211.c
+-+++ b/net/wireless/nl80211.c
+-@@ -1723,9 +1723,10 @@ static int nl80211_dump_wiphy(struct sk_
+- 				 * We can then retry with the larger buffer.
+- 				 */
+- 				if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
+--				    !skb->len &&
+-+				    !skb->len && !state->split &&
+- 				    cb->min_dump_alloc < 4096) {
+- 					cb->min_dump_alloc = 4096;
+-+					state->split_start = 0;
+- 					rtnl_unlock();
+- 					return 1;
+- 				}
+-@@ -2047,10 +2048,12 @@ static int nl80211_set_wiphy(struct sk_b
+- 		nla_for_each_nested(nl_txq_params,
+- 				    info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
+- 				    rem_txq_params) {
+--			nla_parse(tb, NL80211_TXQ_ATTR_MAX,
+--				  nla_data(nl_txq_params),
+--				  nla_len(nl_txq_params),
+--				  txq_params_policy);
+-+			result = nla_parse(tb, NL80211_TXQ_ATTR_MAX,
+-+					   nla_data(nl_txq_params),
+-+					   nla_len(nl_txq_params),
+-+					   txq_params_policy);
+-+			if (result)
+-+				goto bad_res;
+- 			result = parse_txq_params(tb, &txq_params);
+- 			if (result)
+- 				goto bad_res;
+-@@ -3289,7 +3292,7 @@ static int nl80211_start_ap(struct sk_bu
+- 	if (!err) {
+- 		wdev->preset_chandef = params.chandef;
+- 		wdev->beacon_interval = params.beacon_interval;
+--		wdev->channel = params.chandef.chan;
+-+		wdev->chandef = params.chandef;
+- 		wdev->ssid_len = params.ssid_len;
+- 		memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
+- 	}
+-@@ -5210,9 +5213,11 @@ static int nl80211_set_reg(struct sk_buf
+- 
+- 	nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
+- 			    rem_reg_rules) {
+--		nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
+--			  nla_data(nl_reg_rule), nla_len(nl_reg_rule),
+--			  reg_rule_policy);
+-+		r = nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
+-+			      nla_data(nl_reg_rule), nla_len(nl_reg_rule),
+-+			      reg_rule_policy);
+-+		if (r)
+-+			goto bad_reg;
+- 		r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
+- 		if (r)
+- 			goto bad_reg;
+-@@ -5277,7 +5282,7 @@ static int nl80211_trigger_scan(struct s
+- 	if (!rdev->ops->scan)
+- 		return -EOPNOTSUPP;
+- 
+--	if (rdev->scan_req) {
+-+	if (rdev->scan_req || rdev->scan_msg) {
+- 		err = -EBUSY;
+- 		goto unlock;
+- 	}
+-@@ -5475,6 +5480,7 @@ static int nl80211_start_sched_scan(stru
+- 	enum ieee80211_band band;
+- 	size_t ie_len;
+- 	struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
+-+	s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
+- 
+- 	if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
+- 	    !rdev->ops->sched_scan_start)
+-@@ -5509,11 +5515,40 @@ static int nl80211_start_sched_scan(stru
+- 	if (n_ssids > wiphy->max_sched_scan_ssids)
+- 		return -EINVAL;
+- 
+--	if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH])
+-+	/*
+-+	 * First, count the number of 'real' matchsets. Due to an issue with
+-+	 * the old implementation, matchsets containing only the RSSI attribute
+-+	 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
+-+	 * RSSI for all matchsets, rather than their own matchset for reporting
+-+	 * all APs with a strong RSSI. This is needed to be compatible with
+-+	 * older userspace that treated a matchset with only the RSSI as the
+-+	 * global RSSI for all other matchsets - if there are other matchsets.
+-+	 */
+-+	if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
+- 		nla_for_each_nested(attr,
+- 				    info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
+--				    tmp)
+--			n_match_sets++;
+-+				    tmp) {
+-+			struct nlattr *rssi;
+-+
+-+			err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
+-+					nla_data(attr), nla_len(attr),
+-+					nl80211_match_policy);
+-+			if (err)
+-+				return err;
+-+			/* add other standalone attributes here */
+-+			if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) {
+-+				n_match_sets++;
+-+				continue;
+-+			}
+-+			rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
+-+			if (rssi)
+-+				default_match_rssi = nla_get_s32(rssi);
+-+		}
+-+	}
+-+
+-+	/* However, if there's no other matchset, add the RSSI one */
+-+	if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
+-+		n_match_sets = 1;
+- 
+- 	if (n_match_sets > wiphy->max_match_sets)
+- 		return -EINVAL;
+-@@ -5634,11 +5669,22 @@ static int nl80211_start_sched_scan(stru
+- 				    tmp) {
+- 			struct nlattr *ssid, *rssi;
+- 
+--			nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
+--				  nla_data(attr), nla_len(attr),
+--				  nl80211_match_policy);
+-+			err = nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
+-+					nla_data(attr), nla_len(attr),
+-+					nl80211_match_policy);
+-+			if (err)
+-+				goto out_free;
+- 			ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
+- 			if (ssid) {
+-+				if (WARN_ON(i >= n_match_sets)) {
+-+					/* this indicates a programming error,
+-+					 * the loop above should have verified
+-+					 * things properly
+-+					 */
+-+					err = -EINVAL;
+-+					goto out_free;
+-+				}
+-+
+- 				if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
+- 					err = -EINVAL;
+- 					goto out_free;
+-@@ -5647,15 +5693,28 @@ static int nl80211_start_sched_scan(stru
+- 				       nla_data(ssid), nla_len(ssid));
+- 				request->match_sets[i].ssid.ssid_len =
+- 					nla_len(ssid);
+-+				/* special attribute - old implemenation w/a */
+-+				request->match_sets[i].rssi_thold =
+-+					default_match_rssi;
+-+				rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
+-+				if (rssi)
+-+					request->match_sets[i].rssi_thold =
+-+						nla_get_s32(rssi);
+- 			}
+--			rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
+--			if (rssi)
+--				request->rssi_thold = nla_get_u32(rssi);
+--			else
+--				request->rssi_thold =
+--						   NL80211_SCAN_RSSI_THOLD_OFF;
+- 			i++;
+- 		}
+-+
+-+		/* there was no other matchset, so the RSSI one is alone */
+-+		if (i == 0)
+-+			request->match_sets[0].rssi_thold = default_match_rssi;
+-+
+-+		request->min_rssi_thold = INT_MAX;
+-+		for (i = 0; i < n_match_sets; i++)
+-+			request->min_rssi_thold =
+-+				min(request->match_sets[i].rssi_thold,
+-+				    request->min_rssi_thold);
+-+	} else {
+-+		request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
+- 	}
+- 
+- 	if (info->attrs[NL80211_ATTR_IE]) {
+-@@ -5751,7 +5810,7 @@ static int nl80211_start_radar_detection
+- 
+- 	err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
+- 	if (!err) {
+--		wdev->channel = chandef.chan;
+-+		wdev->chandef = chandef;
+- 		wdev->cac_started = true;
+- 		wdev->cac_start_time = jiffies;
+- 	}
+-@@ -7502,16 +7561,19 @@ static int nl80211_set_tx_bitrate_mask(s
+- 	 * directly to the enum ieee80211_band values used in cfg80211.
+- 	 */
+- 	BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
+--	nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
+--	{
+-+	nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
+- 		enum ieee80211_band band = nla_type(tx_rates);
+-+		int err;
+-+
+- 		if (band < 0 || band >= IEEE80211_NUM_BANDS)
+- 			return -EINVAL;
+- 		sband = rdev->wiphy.bands[band];
+- 		if (sband == NULL)
+- 			return -EINVAL;
+--		nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
+--			  nla_len(tx_rates), nl80211_txattr_policy);
+-+		err = nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
+-+				nla_len(tx_rates), nl80211_txattr_policy);
+-+		if (err)
+-+			return err;
+- 		if (tb[NL80211_TXRATE_LEGACY]) {
+- 			mask.control[band].legacy = rateset_to_mask(
+- 				sband,
+-@@ -10054,40 +10116,31 @@ void nl80211_send_scan_start(struct cfg8
+- 				NL80211_MCGRP_SCAN, GFP_KERNEL);
+- }
+- 
+--void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
+--			    struct wireless_dev *wdev)
+-+struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
+-+				       struct wireless_dev *wdev, bool aborted)
+- {
+- 	struct sk_buff *msg;
+- 
+- 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+- 	if (!msg)
+--		return;
+-+		return NULL;
+- 
+- 	if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
+--				  NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
+-+				  aborted ? NL80211_CMD_SCAN_ABORTED :
+-+					    NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
+- 		nlmsg_free(msg);
+--		return;
+-+		return NULL;
+- 	}
+- 
+--	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+--				NL80211_MCGRP_SCAN, GFP_KERNEL);
+-+	return msg;
+- }
+- 
+--void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
+--			       struct wireless_dev *wdev)
+-+void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
+-+			      struct sk_buff *msg)
+- {
+--	struct sk_buff *msg;
+--
+--	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+- 	if (!msg)
+- 		return;
+- 
+--	if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
+--				  NL80211_CMD_SCAN_ABORTED) < 0) {
+--		nlmsg_free(msg);
+--		return;
+--	}
+--
+- 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+- 				NL80211_MCGRP_SCAN, GFP_KERNEL);
+- }
+-@@ -11158,7 +11211,8 @@ void cfg80211_ch_switch_notify(struct ne
+- 		    wdev->iftype != NL80211_IFTYPE_MESH_POINT))
+- 		return;
+- 
+--	wdev->channel = chandef->chan;
+-+	wdev->chandef = *chandef;
+-+	wdev->preset_chandef = *chandef;
+- 	nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
+- }
+- EXPORT_SYMBOL(cfg80211_ch_switch_notify);
+-@@ -11673,6 +11727,35 @@ void cfg80211_crit_proto_stopped(struct 
+- }
+- EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
+- 
+-+void nl80211_send_ap_stopped(struct wireless_dev *wdev)
+-+{
+-+	struct wiphy *wiphy = wdev->wiphy;
+-+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+-+	struct sk_buff *msg;
+-+	void *hdr;
+-+
+-+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+-+	if (!msg)
+-+		return;
+-+
+-+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
+-+	if (!hdr)
+-+		goto out;
+-+
+-+	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+-+	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
+-+	    nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
+-+		goto out;
+-+
+-+	genlmsg_end(msg, hdr);
+-+
+-+	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
+-+				NL80211_MCGRP_MLME, GFP_KERNEL);
+-+	return;
+-+ out:
+-+	nlmsg_free(msg);
+-+}
+-+
+- /* initialisation/exit functions */
+- 
+- int nl80211_init(void)
+---- a/net/wireless/nl80211.h
+-+++ b/net/wireless/nl80211.h
+-@@ -8,10 +8,10 @@ void nl80211_exit(void);
+- void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
+- void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
+- 			     struct wireless_dev *wdev);
+--void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
+--			    struct wireless_dev *wdev);
+--void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
+--			       struct wireless_dev *wdev);
+-+struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
+-+				       struct wireless_dev *wdev, bool aborted);
+-+void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
+-+			      struct sk_buff *msg);
+- void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
+- 			     struct net_device *netdev, u32 cmd);
+- void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
+-@@ -74,6 +74,8 @@ nl80211_radar_notify(struct cfg80211_reg
+- 		     enum nl80211_radar_event event,
+- 		     struct net_device *netdev, gfp_t gfp);
+- 
+-+void nl80211_send_ap_stopped(struct wireless_dev *wdev);
+-+
+- void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev);
+- 
+- #endif /* __NET_WIRELESS_NL80211_H */
+---- a/net/wireless/scan.c
+-+++ b/net/wireless/scan.c
+-@@ -161,18 +161,25 @@ static void __cfg80211_bss_expire(struct
+- 		dev->bss_generation++;
+- }
+- 
+--void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev)
+-+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
+-+			   bool send_message)
+- {
+- 	struct cfg80211_scan_request *request;
+- 	struct wireless_dev *wdev;
+-+	struct sk_buff *msg;
+- #ifdef CPTCFG_CFG80211_WEXT
+- 	union iwreq_data wrqu;
+- #endif
+- 
+- 	ASSERT_RTNL();
+- 
+--	request = rdev->scan_req;
+-+	if (rdev->scan_msg) {
+-+		nl80211_send_scan_result(rdev, rdev->scan_msg);
+-+		rdev->scan_msg = NULL;
+-+		return;
+-+	}
+- 
+-+	request = rdev->scan_req;
+- 	if (!request)
+- 		return;
+- 
+-@@ -186,18 +193,16 @@ void ___cfg80211_scan_done(struct cfg802
+- 	if (wdev->netdev)
+- 		cfg80211_sme_scan_done(wdev->netdev);
+- 
+--	if (request->aborted) {
+--		nl80211_send_scan_aborted(rdev, wdev);
+--	} else {
+--		if (request->flags & NL80211_SCAN_FLAG_FLUSH) {
+--			/* flush entries from previous scans */
+--			spin_lock_bh(&rdev->bss_lock);
+--			__cfg80211_bss_expire(rdev, request->scan_start);
+--			spin_unlock_bh(&rdev->bss_lock);
+--		}
+--		nl80211_send_scan_done(rdev, wdev);
+-+	if (!request->aborted &&
+-+	    request->flags & NL80211_SCAN_FLAG_FLUSH) {
+-+		/* flush entries from previous scans */
+-+		spin_lock_bh(&rdev->bss_lock);
+-+		__cfg80211_bss_expire(rdev, request->scan_start);
+-+		spin_unlock_bh(&rdev->bss_lock);
+- 	}
+- 
+-+	msg = nl80211_build_scan_msg(rdev, wdev, request->aborted);
+-+
+- #ifdef CPTCFG_CFG80211_WEXT
+- 	if (wdev->netdev && !request->aborted) {
+- 		memset(&wrqu, 0, sizeof(wrqu));
+-@@ -211,6 +216,11 @@ void ___cfg80211_scan_done(struct cfg802
+- 
+- 	rdev->scan_req = NULL;
+- 	kfree(request);
+-+
+-+	if (!send_message)
+-+		rdev->scan_msg = msg;
+-+	else
+-+		nl80211_send_scan_result(rdev, msg);
+- }
+- 
+- void __cfg80211_scan_done(struct work_struct *wk)
+-@@ -221,7 +231,7 @@ void __cfg80211_scan_done(struct work_st
+- 			    scan_done_wk);
+- 
+- 	rtnl_lock();
+--	___cfg80211_scan_done(rdev);
+-+	___cfg80211_scan_done(rdev, true);
+- 	rtnl_unlock();
+- }
+- 
+-@@ -1079,7 +1089,7 @@ int cfg80211_wext_siwscan(struct net_dev
+- 	if (IS_ERR(rdev))
+- 		return PTR_ERR(rdev);
+- 
+--	if (rdev->scan_req) {
+-+	if (rdev->scan_req || rdev->scan_msg) {
+- 		err = -EBUSY;
+- 		goto out;
+- 	}
+-@@ -1481,7 +1491,7 @@ int cfg80211_wext_giwscan(struct net_dev
+- 	if (IS_ERR(rdev))
+- 		return PTR_ERR(rdev);
+- 
+--	if (rdev->scan_req)
+-+	if (rdev->scan_req || rdev->scan_msg)
+- 		return -EAGAIN;
+- 
+- 	res = ieee80211_scan_results(rdev, info, extra, data->length);
+---- a/net/wireless/sme.c
+-+++ b/net/wireless/sme.c
+-@@ -67,7 +67,7 @@ static int cfg80211_conn_scan(struct wir
+- 	ASSERT_RDEV_LOCK(rdev);
+- 	ASSERT_WDEV_LOCK(wdev);
+- 
+--	if (rdev->scan_req)
+-+	if (rdev->scan_req || rdev->scan_msg)
+- 		return -EBUSY;
+- 
+- 	if (wdev->conn->params.channel)
+---- a/net/mac80211/mlme.c
+-+++ b/net/mac80211/mlme.c
+-@@ -1001,7 +1001,6 @@ ieee80211_sta_process_chanswitch(struct 
+- 	}
+- 
+- 	ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
+--	sdata->vif.csa_active = true;
+- 
+- 	mutex_lock(&local->chanctx_mtx);
+- 	if (local->use_chanctx) {
+-@@ -1039,6 +1038,7 @@ ieee80211_sta_process_chanswitch(struct 
+- 	mutex_unlock(&local->chanctx_mtx);
+- 
+- 	sdata->csa_chandef = csa_ie.chandef;
+-+	sdata->vif.csa_active = true;
+- 
+- 	if (csa_ie.mode)
+- 		ieee80211_stop_queues_by_reason(&local->hw,
+---- a/net/mac80211/chan.c
+-+++ b/net/mac80211/chan.c
+-@@ -196,6 +196,8 @@ static bool ieee80211_is_radar_required(
+- {
+- 	struct ieee80211_sub_if_data *sdata;
+- 
+-+	lockdep_assert_held(&local->mtx);
+-+
+- 	rcu_read_lock();
+- 	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+- 		if (sdata->radar_required) {
+---- a/net/mac80211/ibss.c
+-+++ b/net/mac80211/ibss.c
+-@@ -294,7 +294,6 @@ static void __ieee80211_sta_join_ibss(st
+- 	}
+- 
+- 	mutex_lock(&local->mtx);
+--	ieee80211_vif_release_channel(sdata);
+- 	if (ieee80211_vif_use_channel(sdata, &chandef,
+- 				      ifibss->fixed_channel ?
+- 					IEEE80211_CHANCTX_SHARED :
+-@@ -303,6 +302,7 @@ static void __ieee80211_sta_join_ibss(st
+- 		mutex_unlock(&local->mtx);
+- 		return;
+- 	}
+-+	sdata->radar_required = radar_required;
+- 	mutex_unlock(&local->mtx);
+- 
+- 	memcpy(ifibss->bssid, bssid, ETH_ALEN);
+-@@ -318,7 +318,6 @@ static void __ieee80211_sta_join_ibss(st
+- 	rcu_assign_pointer(ifibss->presp, presp);
+- 	mgmt = (void *)presp->head;
+- 
+--	sdata->radar_required = radar_required;
+- 	sdata->vif.bss_conf.enable_beacon = true;
+- 	sdata->vif.bss_conf.beacon_int = beacon_int;
+- 	sdata->vif.bss_conf.basic_rates = basic_rates;
+-@@ -386,7 +385,7 @@ static void __ieee80211_sta_join_ibss(st
+- 					      presp->head_len, 0, GFP_KERNEL);
+- 	cfg80211_put_bss(local->hw.wiphy, bss);
+- 	netif_carrier_on(sdata->dev);
+--	cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
+-+	cfg80211_ibss_joined(sdata->dev, ifibss->bssid, chan, GFP_KERNEL);
+- }
+- 
+- static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
+-@@ -802,6 +801,8 @@ ieee80211_ibss_process_chanswitch(struct
+- 	int err;
+- 	u32 sta_flags;
+- 
+-+	sdata_assert_lock(sdata);
+-+
+- 	sta_flags = IEEE80211_STA_DISABLE_VHT;
+- 	switch (ifibss->chandef.width) {
+- 	case NL80211_CHAN_WIDTH_5:
+-@@ -1471,6 +1472,11 @@ static void ieee80211_rx_mgmt_probe_req(
+- 	memcpy(((struct ieee80211_mgmt *) skb->data)->da, mgmt->sa, ETH_ALEN);
+- 	ibss_dbg(sdata, "Sending ProbeResp to %pM\n", mgmt->sa);
+- 	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+-+
+-+	/* avoid excessive retries for probe request to wildcard SSIDs */
+-+	if (pos[1] == 0)
+-+		IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_NO_ACK;
+-+
+- 	ieee80211_tx_skb(sdata, skb);
+- }
+- 
+---- a/net/mac80211/mesh.c
+-+++ b/net/mac80211/mesh.c
+-@@ -872,6 +872,8 @@ ieee80211_mesh_process_chnswitch(struct 
+- 	if (!ifmsh->mesh_id)
+- 		return false;
+- 
+-+	sdata_assert_lock(sdata);
+-+
+- 	sta_flags = IEEE80211_STA_DISABLE_VHT;
+- 	switch (sdata->vif.bss_conf.chandef.width) {
+- 	case NL80211_CHAN_WIDTH_20_NOHT:
+---- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+-+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+-@@ -4658,6 +4658,7 @@ brcmf_notify_connect_status(struct brcmf
+- 	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
+- 	struct net_device *ndev = ifp->ndev;
+- 	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
+-+	struct ieee80211_channel *chan;
+- 	s32 err = 0;
+- 
+- 	if (ifp->vif->mode == WL_MODE_AP) {
+-@@ -4665,9 +4666,10 @@ brcmf_notify_connect_status(struct brcmf
+- 	} else if (brcmf_is_linkup(e)) {
+- 		brcmf_dbg(CONN, "Linkup\n");
+- 		if (brcmf_is_ibssmode(ifp->vif)) {
+-+			chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
+- 			memcpy(profile->bssid, e->addr, ETH_ALEN);
+- 			wl_inform_ibss(cfg, ndev, e->addr);
+--			cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
+-+			cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
+- 			clear_bit(BRCMF_VIF_STATUS_CONNECTING,
+- 				  &ifp->vif->sme_state);
+- 			set_bit(BRCMF_VIF_STATUS_CONNECTED,
+---- a/drivers/net/wireless/libertas/cfg.c
+-+++ b/drivers/net/wireless/libertas/cfg.c
+-@@ -1766,7 +1766,8 @@ static void lbs_join_post(struct lbs_pri
+- 	memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
+- 	priv->wdev->ssid_len = params->ssid_len;
+- 
+--	cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL);
+-+	cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan,
+-+			     GFP_KERNEL);
+- 
+- 	/* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
+- 	priv->connect_status = LBS_CONNECTED;
+---- a/drivers/net/wireless/mwifiex/cfg80211.c
+-+++ b/drivers/net/wireless/mwifiex/cfg80211.c
+-@@ -1881,7 +1881,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy 
+- 				     params->privacy);
+- done:
+- 	if (!ret) {
+--		cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
+-+		cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
+-+				     params->chandef.chan, GFP_KERNEL);
+- 		dev_dbg(priv->adapter->dev,
+- 			"info: joined/created adhoc network with bssid"
+- 			" %pM successfully\n", priv->cfg_bssid);
+---- a/drivers/net/wireless/rndis_wlan.c
+-+++ b/drivers/net/wireless/rndis_wlan.c
+-@@ -2835,7 +2835,9 @@ static void rndis_wlan_do_link_up_work(s
+- 					bssid, req_ie, req_ie_len,
+- 					resp_ie, resp_ie_len, GFP_KERNEL);
+- 	} else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
+--		cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
+-+		cfg80211_ibss_joined(usbdev->net, bssid,
+-+				     get_current_channel(usbdev, NULL),
+-+				     GFP_KERNEL);
+- 
+- 	kfree(info);
+- 
+---- a/net/wireless/ibss.c
+-+++ b/net/wireless/ibss.c
+-@@ -14,7 +14,8 @@
+- #include "rdev-ops.h"
+- 
+- 
+--void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
+-+void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
+-+			    struct ieee80211_channel *channel)
+- {
+- 	struct wireless_dev *wdev = dev->ieee80211_ptr;
+- 	struct cfg80211_bss *bss;
+-@@ -28,8 +29,7 @@ void __cfg80211_ibss_joined(struct net_d
+- 	if (!wdev->ssid_len)
+- 		return;
+- 
+--	bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
+--			       wdev->ssid, wdev->ssid_len,
+-+	bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0,
+- 			       WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
+- 
+- 	if (WARN_ON(!bss))
+-@@ -54,21 +54,26 @@ void __cfg80211_ibss_joined(struct net_d
+- #endif
+- }
+- 
+--void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
+-+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
+-+			  struct ieee80211_channel *channel, gfp_t gfp)
+- {
+- 	struct wireless_dev *wdev = dev->ieee80211_ptr;
+- 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+- 	struct cfg80211_event *ev;
+- 	unsigned long flags;
+- 
+--	trace_cfg80211_ibss_joined(dev, bssid);
+-+	trace_cfg80211_ibss_joined(dev, bssid, channel);
+-+
+-+	if (WARN_ON(!channel))
+-+		return;
+- 
+- 	ev = kzalloc(sizeof(*ev), gfp);
+- 	if (!ev)
+- 		return;
+- 
+- 	ev->type = EVENT_IBSS_JOINED;
+--	memcpy(ev->cr.bssid, bssid, ETH_ALEN);
+-+	memcpy(ev->ij.bssid, bssid, ETH_ALEN);
+-+	ev->ij.channel = channel;
+- 
+- 	spin_lock_irqsave(&wdev->event_lock, flags);
+- 	list_add_tail(&ev->list, &wdev->event_list);
+-@@ -117,6 +122,7 @@ int __cfg80211_join_ibss(struct cfg80211
+- 
+- 	wdev->ibss_fixed = params->channel_fixed;
+- 	wdev->ibss_dfs_possible = params->userspace_handles_dfs;
+-+	wdev->chandef = params->chandef;
+- #ifdef CPTCFG_CFG80211_WEXT
+- 	wdev->wext.ibss.chandef = params->chandef;
+- #endif
+-@@ -200,6 +206,7 @@ static void __cfg80211_clear_ibss(struct
+- 
+- 	wdev->current_bss = NULL;
+- 	wdev->ssid_len = 0;
+-+	memset(&wdev->chandef, 0, sizeof(wdev->chandef));
+- #ifdef CPTCFG_CFG80211_WEXT
+- 	if (!nowext)
+- 		wdev->wext.ibss.ssid_len = 0;
+---- a/net/wireless/trace.h
+-+++ b/net/wireless/trace.h
+-@@ -2278,11 +2278,6 @@ DECLARE_EVENT_CLASS(cfg80211_rx_evt,
+- 	TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr))
+- );
++--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
++@@ -1004,11 +1004,9 @@ static bool ar5008_hw_ani_control_new(st
++ 	case ATH9K_ANI_FIRSTEP_LEVEL:{
++ 		u32 level = param;
+  
+--DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined,
+--	TP_PROTO(struct net_device *netdev, const u8 *addr),
+--	TP_ARGS(netdev, addr)
+--);
+--
+- DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_spurious_frame,
+- 	TP_PROTO(struct net_device *netdev, const u8 *addr),
+- 	TP_ARGS(netdev, addr)
+-@@ -2293,6 +2288,24 @@ DEFINE_EVENT(cfg80211_rx_evt, cfg80211_r
+- 	TP_ARGS(netdev, addr)
+- );
++-		value = level * 2;
+++		value = level;
++ 		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
++ 			      AR_PHY_FIND_SIG_FIRSTEP, value);
++-		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
++-			      AR_PHY_FIND_SIG_FIRSTEP_LOW, value);
+  
+-+TRACE_EVENT(cfg80211_ibss_joined,
+-+	TP_PROTO(struct net_device *netdev, const u8 *bssid,
+-+		 struct ieee80211_channel *channel),
+-+	TP_ARGS(netdev, bssid, channel),
+-+	TP_STRUCT__entry(
+-+		NETDEV_ENTRY
+-+		MAC_ENTRY(bssid)
+-+		CHAN_ENTRY
+-+	),
+-+	TP_fast_assign(
+-+		NETDEV_ASSIGN;
+-+		MAC_ASSIGN(bssid, bssid);
+-+		CHAN_ASSIGN(channel);
+-+	),
+-+	TP_printk(NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", " CHAN_PR_FMT,
+-+		  NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
+-+);
+-+
+- TRACE_EVENT(cfg80211_probe_status,
+- 	TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie,
+- 		 bool acked),
+---- a/net/wireless/util.c
+-+++ b/net/wireless/util.c
+-@@ -820,7 +820,8 @@ void cfg80211_process_wdev_events(struct
+- 						ev->dc.reason, true);
+- 			break;
+- 		case EVENT_IBSS_JOINED:
+--			__cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
+-+			__cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid,
+-+					       ev->ij.channel);
+- 			break;
+- 		}
+- 		wdev_unlock(wdev);
+-@@ -1356,7 +1357,7 @@ int cfg80211_can_use_iftype_chan(struct 
+- 		 */
+- 		mutex_lock_nested(&wdev_iter->mtx, 1);
+- 		__acquire(wdev_iter->mtx);
+--		cfg80211_get_chan_state(wdev_iter, &ch, &chmode);
+-+		cfg80211_get_chan_state(wdev_iter, &ch, &chmode, &radar_detect);
+- 		wdev_unlock(wdev_iter);
++ 		if (level != aniState->firstepLevel) {
++ 			ath_dbg(common, ANI,
++--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++++ b/drivers/net/wireless/ath/ath9k/beacon.c
++@@ -312,10 +312,9 @@ static void ath9k_csa_update_vif(void *d
+  
+- 		switch (chmode) {
+---- a/net/wireless/chan.c
+-+++ b/net/wireless/chan.c
+-@@ -642,7 +642,8 @@ int cfg80211_set_monitor_channel(struct 
+- void
+- cfg80211_get_chan_state(struct wireless_dev *wdev,
+- 		        struct ieee80211_channel **chan,
+--		        enum cfg80211_chan_mode *chanmode)
+-+		        enum cfg80211_chan_mode *chanmode,
+-+		        u8 *radar_detect)
++ void ath9k_csa_update(struct ath_softc *sc)
+  {
+- 	*chan = NULL;
+- 	*chanmode = CHAN_MODE_UNDEFINED;
+-@@ -660,6 +661,11 @@ cfg80211_get_chan_state(struct wireless_
+- 				     !wdev->ibss_dfs_possible)
+- 				  ? CHAN_MODE_SHARED
+- 				  : CHAN_MODE_EXCLUSIVE;
+-+
+-+			/* consider worst-case - IBSS can try to return to the
+-+			 * original user-specified channel as creator */
+-+			if (wdev->ibss_dfs_possible)
+-+				*radar_detect |= BIT(wdev->chandef.width);
+- 			return;
+- 		}
+- 		break;
+-@@ -674,17 +680,26 @@ cfg80211_get_chan_state(struct wireless_
+- 	case NL80211_IFTYPE_AP:
+- 	case NL80211_IFTYPE_P2P_GO:
+- 		if (wdev->cac_started) {
+--			*chan = wdev->channel;
+-+			*chan = wdev->chandef.chan;
+- 			*chanmode = CHAN_MODE_SHARED;
+-+			*radar_detect |= BIT(wdev->chandef.width);
+- 		} else if (wdev->beacon_interval) {
+--			*chan = wdev->channel;
+-+			*chan = wdev->chandef.chan;
+- 			*chanmode = CHAN_MODE_SHARED;
+-+
+-+			if (cfg80211_chandef_dfs_required(wdev->wiphy,
+-+							  &wdev->chandef))
+-+				*radar_detect |= BIT(wdev->chandef.width);
+- 		}
+- 		return;
+- 	case NL80211_IFTYPE_MESH_POINT:
+- 		if (wdev->mesh_id_len) {
+--			*chan = wdev->channel;
+-+			*chan = wdev->chandef.chan;
+- 			*chanmode = CHAN_MODE_SHARED;
+-+
+-+			if (cfg80211_chandef_dfs_required(wdev->wiphy,
+-+							  &wdev->chandef))
+-+				*radar_detect |= BIT(wdev->chandef.width);
+- 		}
+- 		return;
+- 	case NL80211_IFTYPE_MONITOR:
+---- a/net/wireless/mesh.c
+-+++ b/net/wireless/mesh.c
+-@@ -195,7 +195,7 @@ int __cfg80211_join_mesh(struct cfg80211
+- 	if (!err) {
+- 		memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
+- 		wdev->mesh_id_len = setup->mesh_id_len;
+--		wdev->channel = setup->chandef.chan;
+-+		wdev->chandef = setup->chandef;
+- 	}
+- 
+- 	return err;
+-@@ -244,7 +244,7 @@ int cfg80211_set_mesh_channel(struct cfg
+- 		err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev,
+- 						     chandef->chan);
+- 		if (!err)
+--			wdev->channel = chandef->chan;
+-+			wdev->chandef = *chandef;
+- 
+- 		return err;
+- 	}
+-@@ -276,7 +276,7 @@ static int __cfg80211_leave_mesh(struct 
+- 	err = rdev_leave_mesh(rdev, dev);
+- 	if (!err) {
+- 		wdev->mesh_id_len = 0;
+--		wdev->channel = NULL;
+-+		memset(&wdev->chandef, 0, sizeof(wdev->chandef));
+- 		rdev_set_qos_map(rdev, dev, NULL);
+- 	}
+- 
+---- a/net/wireless/mlme.c
+-+++ b/net/wireless/mlme.c
+-@@ -772,7 +772,7 @@ void cfg80211_cac_event(struct net_devic
+- 	if (WARN_ON(!wdev->cac_started))
+- 		return;
+- 
+--	if (WARN_ON(!wdev->channel))
+-+	if (WARN_ON(!wdev->chandef.chan))
+- 		return;
+- 
+- 	switch (event) {
+---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+-+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+-@@ -5065,6 +5065,10 @@ static u16 ar9003_hw_get_max_edge_power(
+- 			break;
+- 		}
+- 	}
+-+
+-+	if (is2GHz && !twiceMaxEdgePower)
+-+		twiceMaxEdgePower = 60;
+-+
+- 	return twiceMaxEdgePower;
+- }
+- 
+---- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+-+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+-@@ -23,10 +23,11 @@
+- #define MAX_MEASUREMENT	MAX_IQCAL_MEASUREMENT
+- #define MAX_MAG_DELTA	11
+- #define MAX_PHS_DELTA	10
+-+#define MAXIQCAL        3
+- 
+- struct coeff {
+--	int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
+--	int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
+-+	int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
+-+	int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
+- 	int iqc_coeff[2];
+- };
+- 
+-@@ -800,7 +801,7 @@ static bool ar9003_hw_calc_iq_corr(struc
+- 	if (q_q_coff > 63)
+- 		q_q_coff = 63;
+- 
+--	iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
+-+	iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
+- 
+- 	ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n",
+- 		chain_idx, iqc_coeff[0]);
+-@@ -831,7 +832,7 @@ static bool ar9003_hw_calc_iq_corr(struc
+- 	if (q_q_coff > 63)
+- 		q_q_coff = 63;
+- 
+--	iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
+-+	iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
+- 
+- 	ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n",
+- 		chain_idx, iqc_coeff[1]);
+-@@ -839,7 +840,8 @@ static bool ar9003_hw_calc_iq_corr(struc
+- 	return true;
++-	ieee80211_iterate_active_interfaces(sc->hw,
++-					    IEEE80211_IFACE_ITER_NORMAL,
++-					    ath9k_csa_update_vif,
++-					    sc);
+++	ieee80211_iterate_active_interfaces_atomic(sc->hw,
+++						   IEEE80211_IFACE_ITER_NORMAL,
+++						   ath9k_csa_update_vif, sc);
+  }
+  
+--static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
+-+static void ar9003_hw_detect_outlier(int mp_coeff[][MAXIQCAL],
+-+				     int nmeasurement,
+- 				     int max_delta)
+- {
+- 	int mp_max = -64, max_idx = 0;
+-@@ -848,20 +850,20 @@ static void ar9003_hw_detect_outlier(int
+- 
+- 	/* find min/max mismatch across all calibrated gains */
+- 	for (i = 0; i < nmeasurement; i++) {
+--		if (mp_coeff[i] > mp_max) {
+--			mp_max = mp_coeff[i];
+-+		if (mp_coeff[i][0] > mp_max) {
+-+			mp_max = mp_coeff[i][0];
+- 			max_idx = i;
+--		} else if (mp_coeff[i] < mp_min) {
+--			mp_min = mp_coeff[i];
+-+		} else if (mp_coeff[i][0] < mp_min) {
+-+			mp_min = mp_coeff[i][0];
+- 			min_idx = i;
+- 		}
+- 	}
+- 
+- 	/* find average (exclude max abs value) */
+- 	for (i = 0; i < nmeasurement; i++) {
+--		if ((abs(mp_coeff[i]) < abs(mp_max)) ||
+--		    (abs(mp_coeff[i]) < abs(mp_min))) {
+--			mp_avg += mp_coeff[i];
+-+		if ((abs(mp_coeff[i][0]) < abs(mp_max)) ||
+-+		    (abs(mp_coeff[i][0]) < abs(mp_min))) {
+-+			mp_avg += mp_coeff[i][0];
+- 			mp_count++;
+- 		}
+- 	}
+-@@ -873,7 +875,7 @@ static void ar9003_hw_detect_outlier(int
+- 	if (mp_count)
+- 		mp_avg /= mp_count;
+- 	else
+--		mp_avg = mp_coeff[nmeasurement - 1];
+-+		mp_avg = mp_coeff[nmeasurement - 1][0];
+- 
+- 	/* detect outlier */
+- 	if (abs(mp_max - mp_min) > max_delta) {
+-@@ -882,15 +884,16 @@ static void ar9003_hw_detect_outlier(int
+- 		else
+- 			outlier_idx = min_idx;
+- 
+--		mp_coeff[outlier_idx] = mp_avg;
+-+		mp_coeff[outlier_idx][0] = mp_avg;
++ void ath9k_beacon_tasklet(unsigned long data)
++--- a/net/mac80211/main.c
+++++ b/net/mac80211/main.c
++@@ -152,6 +152,8 @@ static u32 ieee80211_hw_conf_chan(struct
++ 	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
++ 		if (!rcu_access_pointer(sdata->vif.chanctx_conf))
++ 			continue;
+++		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+++			continue;
++ 		power = min(power, sdata->vif.bss_conf.txpower);
+  	}
+- }
+- 
+--static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
+--						 struct coeff *coeff,
+--						 bool is_reusable)
+-+static void ar9003_hw_tx_iq_cal_outlier_detection(struct ath_hw *ah,
+-+						  struct coeff *coeff,
+-+						  bool is_reusable)
+- {
+- 	int i, im, nmeasurement;
+-+	int magnitude, phase;
+- 	u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
+- 	struct ath9k_hw_cal_data *caldata = ah->caldata;
+- 
+-@@ -920,21 +923,30 @@ static void ar9003_hw_tx_iqcal_load_avg_
+- 		if (nmeasurement > MAX_MEASUREMENT)
+- 			nmeasurement = MAX_MEASUREMENT;
+- 
+--		/* detect outlier only if nmeasurement > 1 */
+--		if (nmeasurement > 1) {
+--			/* Detect magnitude outlier */
+--			ar9003_hw_detect_outlier(coeff->mag_coeff[i],
+--					nmeasurement, MAX_MAG_DELTA);
+--
+--			/* Detect phase outlier */
+--			ar9003_hw_detect_outlier(coeff->phs_coeff[i],
+--					nmeasurement, MAX_PHS_DELTA);
+-+		/*
+-+		 * Skip normal outlier detection for AR9550.
+-+		 */
+-+		if (!AR_SREV_9550(ah)) {
+-+			/* detect outlier only if nmeasurement > 1 */
+-+			if (nmeasurement > 1) {
+-+				/* Detect magnitude outlier */
+-+				ar9003_hw_detect_outlier(coeff->mag_coeff[i],
+-+							 nmeasurement,
+-+							 MAX_MAG_DELTA);
+-+
+-+				/* Detect phase outlier */
+-+				ar9003_hw_detect_outlier(coeff->phs_coeff[i],
+-+							 nmeasurement,
+-+							 MAX_PHS_DELTA);
+-+			}
+- 		}
+- 
+- 		for (im = 0; im < nmeasurement; im++) {
+-+			magnitude = coeff->mag_coeff[i][im][0];
+-+			phase = coeff->phs_coeff[i][im][0];
+- 
+--			coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
+--				((coeff->phs_coeff[i][im] & 0x7f) << 7);
+-+			coeff->iqc_coeff[0] =
+-+				(phase & 0x7f) | ((magnitude & 0x7f) << 7);
+- 
+- 			if ((im % 2) == 0)
+- 				REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
+-@@ -991,7 +1003,63 @@ static bool ar9003_hw_tx_iq_cal_run(stru
+- 	return true;
+- }
+- 
+--static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable)
+-+static void __ar955x_tx_iq_cal_sort(struct ath_hw *ah,
+-+				    struct coeff *coeff,
+-+				    int i, int nmeasurement)
+-+{
+-+	struct ath_common *common = ath9k_hw_common(ah);
+-+	int im, ix, iy, temp;
+-+
+-+	for (im = 0; im < nmeasurement; im++) {
+-+		for (ix = 0; ix < MAXIQCAL - 1; ix++) {
+-+			for (iy = ix + 1; iy <= MAXIQCAL - 1; iy++) {
+-+				if (coeff->mag_coeff[i][im][iy] <
+-+				    coeff->mag_coeff[i][im][ix]) {
+-+					temp = coeff->mag_coeff[i][im][ix];
+-+					coeff->mag_coeff[i][im][ix] =
+-+						coeff->mag_coeff[i][im][iy];
+-+					coeff->mag_coeff[i][im][iy] = temp;
+-+				}
+-+				if (coeff->phs_coeff[i][im][iy] <
+-+				    coeff->phs_coeff[i][im][ix]) {
+-+					temp = coeff->phs_coeff[i][im][ix];
+-+					coeff->phs_coeff[i][im][ix] =
+-+						coeff->phs_coeff[i][im][iy];
+-+					coeff->phs_coeff[i][im][iy] = temp;
+-+				}
+-+			}
+-+		}
+-+		coeff->mag_coeff[i][im][0] = coeff->mag_coeff[i][im][MAXIQCAL / 2];
+-+		coeff->phs_coeff[i][im][0] = coeff->phs_coeff[i][im][MAXIQCAL / 2];
+-+
+-+		ath_dbg(common, CALIBRATE,
+-+			"IQCAL: Median [ch%d][gain%d]: mag = %d phase = %d\n",
+-+			i, im,
+-+			coeff->mag_coeff[i][im][0],
+-+			coeff->phs_coeff[i][im][0]);
+-+	}
+-+}
+-+
+-+static bool ar955x_tx_iq_cal_median(struct ath_hw *ah,
+-+				    struct coeff *coeff,
+-+				    int iqcal_idx,
+-+				    int nmeasurement)
+-+{
+-+	int i;
+-+
+-+	if ((iqcal_idx + 1) != MAXIQCAL)
+-+		return false;
+-+
+-+	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+-+		__ar955x_tx_iq_cal_sort(ah, coeff, i, nmeasurement);
+-+	}
+-+
+-+	return true;
+-+}
+-+
+-+static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah,
+-+					  int iqcal_idx,
+-+					  bool is_reusable)
++ 	rcu_read_unlock();
++@@ -203,7 +205,7 @@ void ieee80211_bss_info_change_notify(st
+  {
+- 	struct ath_common *common = ath9k_hw_common(ah);
+- 	const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
+-@@ -1004,10 +1072,11 @@ static void ar9003_hw_tx_iq_cal_post_pro
+- 		AR_PHY_CHAN_INFO_TAB_1,
+- 		AR_PHY_CHAN_INFO_TAB_2,
+- 	};
+--	struct coeff coeff;
+-+	static struct coeff coeff;
+- 	s32 iq_res[6];
+- 	int i, im, j;
+--	int nmeasurement;
+-+	int nmeasurement = 0;
+-+	bool outlier_detect = true;
+- 
+- 	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
+- 		if (!(ah->txchainmask & (1 << i)))
+-@@ -1065,17 +1134,23 @@ static void ar9003_hw_tx_iq_cal_post_pro
+- 				goto tx_iqcal_fail;
+- 			}
+- 
+--			coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
+--			coeff.phs_coeff[i][im] =
+-+			coeff.phs_coeff[i][im][iqcal_idx] =
+-+				coeff.iqc_coeff[0] & 0x7f;
+-+			coeff.mag_coeff[i][im][iqcal_idx] =
+- 				(coeff.iqc_coeff[0] >> 7) & 0x7f;
+- 
+--			if (coeff.mag_coeff[i][im] > 63)
+--				coeff.mag_coeff[i][im] -= 128;
+--			if (coeff.phs_coeff[i][im] > 63)
+--				coeff.phs_coeff[i][im] -= 128;
+-+			if (coeff.mag_coeff[i][im][iqcal_idx] > 63)
+-+				coeff.mag_coeff[i][im][iqcal_idx] -= 128;
+-+			if (coeff.phs_coeff[i][im][iqcal_idx] > 63)
+-+				coeff.phs_coeff[i][im][iqcal_idx] -= 128;
+- 		}
+- 	}
+--	ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable);
+-+
+-+	if (AR_SREV_9550(ah))
+-+		outlier_detect = ar955x_tx_iq_cal_median(ah, &coeff,
+-+							 iqcal_idx, nmeasurement);
+-+	if (outlier_detect)
+-+		ar9003_hw_tx_iq_cal_outlier_detection(ah, &coeff, is_reusable);
+- 
+- 	return;
+- 
+-@@ -1409,7 +1484,7 @@ skip_tx_iqcal:
+- 	}
++ 	struct ieee80211_local *local = sdata->local;
+  
+- 	if (txiqcal_done)
+--		ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
+-+		ar9003_hw_tx_iq_cal_post_proc(ah, 0, is_reusable);
+- 	else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags))
+- 		ar9003_hw_tx_iq_cal_reload(ah);
++-	if (!changed)
+++	if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
++ 		return;
+  
+-@@ -1455,14 +1530,38 @@ skip_tx_iqcal:
+- 	return true;
+- }
++ 	drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed);
++--- a/drivers/net/wireless/ath/ath9k/ani.c
+++++ b/drivers/net/wireless/ath/ath9k/ani.c
++@@ -155,6 +155,9 @@ static void ath9k_hw_set_ofdm_nil(struct
++ 		ATH9K_ANI_RSSI_THR_LOW,
++ 		ATH9K_ANI_RSSI_THR_HIGH);
+  
+-+static bool do_ar9003_agc_cal(struct ath_hw *ah)
+-+{
+-+	struct ath_common *common = ath9k_hw_common(ah);
+-+	bool status;
+++	if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_OFDM_DEF_LEVEL)
+++		immunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
+ +
+-+	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+-+		  REG_READ(ah, AR_PHY_AGC_CONTROL) |
+-+		  AR_PHY_AGC_CONTROL_CAL);
+-+
+-+	status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+-+			       AR_PHY_AGC_CONTROL_CAL,
+-+			       0, AH_WAIT_TIMEOUT);
+-+	if (!status) {
+-+		ath_dbg(common, CALIBRATE,
+-+			"offset calibration failed to complete in %d ms,"
+-+			"noisy environment?\n",
+-+			AH_WAIT_TIMEOUT / 1000);
+-+		return false;
+-+	}
+-+
+-+	return true;
+-+}
+-+
+- static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
+- 				   struct ath9k_channel *chan)
+- {
+- 	struct ath_common *common = ath9k_hw_common(ah);
+- 	struct ath9k_hw_cal_data *caldata = ah->caldata;
+- 	bool txiqcal_done = false;
+--	bool is_reusable = true, status = true;
+-+	bool status = true;
+- 	bool run_agc_cal = false, sep_iq_cal = false;
+-+	int i = 0;
+- 
+- 	/* Use chip chainmask only for calibration */
+- 	ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
+-@@ -1485,7 +1584,12 @@ static bool ar9003_hw_init_cal_soc(struc
+- 	 * AGC calibration. Specifically, AR9550 in SoC chips.
+- 	 */
+- 	if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
+--		txiqcal_done = true;
+-+		if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
+-+				   AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) {
+-+				txiqcal_done = true;
+-+		} else {
+-+			txiqcal_done = false;
+-+		}
+- 		run_agc_cal = true;
+- 	} else {
+- 		sep_iq_cal = true;
+-@@ -1512,27 +1616,37 @@ skip_tx_iqcal:
+- 		if (AR_SREV_9330_11(ah))
+- 			ar9003_hw_manual_peak_cal(ah, 0, IS_CHAN_2GHZ(chan));
+- 
+--		/* Calibrate the AGC */
+--		REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+--			  REG_READ(ah, AR_PHY_AGC_CONTROL) |
+--			  AR_PHY_AGC_CONTROL_CAL);
+--
+--		/* Poll for offset calibration complete */
+--		status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+--				       AR_PHY_AGC_CONTROL_CAL,
+--				       0, AH_WAIT_TIMEOUT);
+--	}
+-+		/*
+-+		 * For non-AR9550 chips, we just trigger AGC calibration
+-+		 * in the HW, poll for completion and then process
+-+		 * the results.
+-+		 *
+-+		 * For AR955x, we run it multiple times and use
+-+		 * median IQ correction.
+-+		 */
+-+		if (!AR_SREV_9550(ah)) {
+-+			status = do_ar9003_agc_cal(ah);
+-+			if (!status)
+-+				return false;
+- 
+--	if (!status) {
+--		ath_dbg(common, CALIBRATE,
+--			"offset calibration failed to complete in %d ms; noisy environment?\n",
+--			AH_WAIT_TIMEOUT / 1000);
+--		return false;
+-+			if (txiqcal_done)
+-+				ar9003_hw_tx_iq_cal_post_proc(ah, 0, false);
+-+		} else {
+-+			if (!txiqcal_done) {
+-+				status = do_ar9003_agc_cal(ah);
+-+				if (!status)
+-+					return false;
+-+			} else {
+-+				for (i = 0; i < MAXIQCAL; i++) {
+-+					status = do_ar9003_agc_cal(ah);
+-+					if (!status)
+-+						return false;
+-+					ar9003_hw_tx_iq_cal_post_proc(ah, i, false);
+-+				}
+-+			}
+-+		}
+- 	}
+- 
+--	if (txiqcal_done)
+--		ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
+--
+- 	/* Revert chainmask to runtime parameters */
+- 	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
++ 	if (!scan)
++ 		aniState->ofdmNoiseImmunityLevel = immunityLevel;
+  
+---- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
+-+++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h
+-@@ -15,6 +15,8 @@
+- #ifndef RTL8187_H
+- #define RTL8187_H
++@@ -235,6 +238,9 @@ static void ath9k_hw_set_cck_nil(struct 
++ 		BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW,
++ 		ATH9K_ANI_RSSI_THR_HIGH);
+  
+-+#include <linux/cache.h>
+++	if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_CCK_DEF_LEVEL)
+++		immunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
+ +
+- #include "rtl818x.h"
+- #include "leds.h"
+- 
+-@@ -139,7 +141,10 @@ struct rtl8187_priv {
+- 	u8 aifsn[4];
+- 	u8 rfkill_mask;
+- 	struct {
+--		__le64 buf;
+-+		union {
+-+			__le64 buf;
+-+			u8 dummy1[L1_CACHE_BYTES];
+-+		} ____cacheline_aligned;
+- 		struct sk_buff_head queue;
+- 	} b_tx_status; /* This queue is used by both -b and non-b devices */
+- 	struct mutex io_mutex;
+-@@ -147,7 +152,8 @@ struct rtl8187_priv {
+- 		u8 bits8;
+- 		__le16 bits16;
+- 		__le32 bits32;
+--	} *io_dmabuf;
+-+		u8 dummy2[L1_CACHE_BYTES];
+-+	} *io_dmabuf ____cacheline_aligned;
+- 	bool rfkill_off;
+- 	u16 seqno;
++ 	if (ah->opmode == NL80211_IFTYPE_STATION &&
++ 	    BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW &&
++ 	    immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
++--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
++@@ -251,7 +251,6 @@ struct ath_atx_tid {
++ 
++ 	s8 bar_index;
++ 	bool sched;
++-	bool paused;
++ 	bool active;
+  };
+---- a/net/mac80211/wme.c
+-+++ b/net/mac80211/wme.c
+-@@ -154,6 +154,11 @@ u16 ieee80211_select_queue(struct ieee80
+- 		return IEEE80211_AC_BE;
+- 	}
+  
+-+	if (skb->protocol == sdata->control_port_protocol) {
+-+		skb->priority = 7;
+-+		return ieee80211_downgrade_queue(sdata, skb);
+-+	}
+-+
+- 	/* use the data classifier to determine what 802.1d tag the
+- 	 * data frame has */
+- 	rcu_read_lock();
+ --- a/drivers/net/wireless/ath/ath9k/xmit.c
+ +++ b/drivers/net/wireless/ath/ath9k/xmit.c
+-@@ -1444,14 +1444,16 @@ void ath_tx_aggr_sleep(struct ieee80211_
+- 	for (tidno = 0, tid = &an->tid[tidno];
+- 	     tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
+- 
+--		if (!tid->sched)
+--			continue;
+--
+- 		ac = tid->ac;
+- 		txq = ac->txq;
+- 
+- 		ath_txq_lock(sc, txq);
+- 
+-+		if (!tid->sched) {
+-+			ath_txq_unlock(sc, txq);
+-+			continue;
+-+		}
+-+
+- 		buffered = ath_tid_has_buffered(tid);
+- 
+- 		tid->sched = false;
+-@@ -1696,7 +1698,7 @@ int ath_cabq_update(struct ath_softc *sc
+- 
+- 	ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
+- 
+--	qi.tqi_readyTime = (cur_conf->beacon_interval *
+-+	qi.tqi_readyTime = (TU_TO_USEC(cur_conf->beacon_interval) *
+- 			    ATH_CABQ_READY_TIME) / 100;
+- 	ath_txq_update(sc, qnum, &qi);
+- 
+-@@ -2061,7 +2063,7 @@ static struct ath_buf *ath_tx_setup_buff
+- 
+- 	ATH_TXBUF_RESET(bf);
+- 
+--	if (tid) {
+-+	if (tid && ieee80211_is_data_present(hdr->frame_control)) {
+- 		fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
+- 		seqno = tid->seq_next;
+- 		hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT);
+-@@ -2184,14 +2186,15 @@ int ath_tx_start(struct ieee80211_hw *hw
+- 		txq->stopped = true;
+- 	}
+- 
+-+	if (txctl->an && ieee80211_is_data_present(hdr->frame_control))
+-+		tid = ath_get_skb_tid(sc, txctl->an, skb);
+-+
+- 	if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) {
+- 		ath_txq_unlock(sc, txq);
+- 		txq = sc->tx.uapsdq;
+- 		ath_txq_lock(sc, txq);
+- 	} else if (txctl->an &&
+- 		   ieee80211_is_data_present(hdr->frame_control)) {
+--		tid = ath_get_skb_tid(sc, txctl->an, skb);
+--
+- 		WARN_ON(tid->ac->txq != txctl->txq);
+- 
+- 		if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
+---- a/drivers/net/wireless/ath/ath9k/init.c
+-+++ b/drivers/net/wireless/ath/ath9k/init.c
+-@@ -943,6 +943,7 @@ static void ath9k_set_hw_capab(struct at
+- 	hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+- 	hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
+- 	hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
+-+	hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
+- 
+- 	hw->queues = 4;
+- 	hw->max_rates = 4;
+---- a/net/mac80211/ieee80211_i.h
+-+++ b/net/mac80211/ieee80211_i.h
+-@@ -1700,14 +1700,8 @@ void ieee80211_stop_queue_by_reason(stru
+- void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue);
+- void ieee80211_add_pending_skb(struct ieee80211_local *local,
+- 			       struct sk_buff *skb);
+--void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
+--				   struct sk_buff_head *skbs,
+--				   void (*fn)(void *data), void *data);
+--static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local,
+--					      struct sk_buff_head *skbs)
+--{
+--	ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
+--}
+-+void ieee80211_add_pending_skbs(struct ieee80211_local *local,
+-+				struct sk_buff_head *skbs);
+- void ieee80211_flush_queues(struct ieee80211_local *local,
+- 			    struct ieee80211_sub_if_data *sdata);
+- 
+---- a/net/mac80211/sta_info.c
+-+++ b/net/mac80211/sta_info.c
+-@@ -91,7 +91,7 @@ static int sta_info_hash_del(struct ieee
+- 	return -ENOENT;
+- }
+- 
+--static void cleanup_single_sta(struct sta_info *sta)
+-+static void __cleanup_single_sta(struct sta_info *sta)
+- {
+- 	int ac, i;
+- 	struct tid_ampdu_tx *tid_tx;
+-@@ -99,7 +99,8 @@ static void cleanup_single_sta(struct st
+- 	struct ieee80211_local *local = sdata->local;
+- 	struct ps_data *ps;
+- 
+--	if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
+-+	if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
+-+	    test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
+- 		if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
+- 		    sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+- 			ps = &sdata->bss->ps;
+-@@ -109,6 +110,7 @@ static void cleanup_single_sta(struct st
+- 			return;
+- 
+- 		clear_sta_flag(sta, WLAN_STA_PS_STA);
+-+		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
+- 
+- 		atomic_dec(&ps->num_sta_ps);
+- 		sta_info_recalc_tim(sta);
+-@@ -139,7 +141,14 @@ static void cleanup_single_sta(struct st
+- 		ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending);
+- 		kfree(tid_tx);
+- 	}
+-+}
+- 
+-+static void cleanup_single_sta(struct sta_info *sta)
+-+{
+-+	struct ieee80211_sub_if_data *sdata = sta->sdata;
+-+	struct ieee80211_local *local = sdata->local;
+-+
+-+	__cleanup_single_sta(sta);
+- 	sta_info_free(local, sta);
+- }
+- 
+-@@ -330,6 +339,7 @@ struct sta_info *sta_info_alloc(struct i
+- 	rcu_read_unlock();
+- 
+- 	spin_lock_init(&sta->lock);
+-+	spin_lock_init(&sta->ps_lock);
+- 	INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
+- 	INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
+- 	mutex_init(&sta->ampdu_mlme.mtx);
+-@@ -487,21 +497,26 @@ static int sta_info_insert_finish(struct
+- 		goto out_err;
+- 	}
+- 
+--	/* notify driver */
+--	err = sta_info_insert_drv_state(local, sdata, sta);
+--	if (err)
+--		goto out_err;
+--
+- 	local->num_sta++;
+- 	local->sta_generation++;
+- 	smp_mb();
+- 
+-+	/* simplify things and don't accept BA sessions yet */
+-+	set_sta_flag(sta, WLAN_STA_BLOCK_BA);
+-+
+- 	/* make the station visible */
+- 	sta_info_hash_add(local, sta);
+- 
+- 	list_add_rcu(&sta->list, &local->sta_list);
+- 
+-+	/* notify driver */
+-+	err = sta_info_insert_drv_state(local, sdata, sta);
+-+	if (err)
+-+		goto out_remove;
+-+
+- 	set_sta_flag(sta, WLAN_STA_INSERTED);
+-+	/* accept BA sessions now */
+-+	clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
+- 
+- 	ieee80211_recalc_min_chandef(sdata);
+- 	ieee80211_sta_debugfs_add(sta);
+-@@ -522,6 +537,12 @@ static int sta_info_insert_finish(struct
+- 		mesh_accept_plinks_update(sdata);
+- 
+- 	return 0;
+-+ out_remove:
+-+	sta_info_hash_del(local, sta);
+-+	list_del_rcu(&sta->list);
+-+	local->num_sta--;
+-+	synchronize_net();
+-+	__cleanup_single_sta(sta);
+-  out_err:
+- 	mutex_unlock(&local->sta_mtx);
+- 	rcu_read_lock();
+-@@ -1071,10 +1092,14 @@ struct ieee80211_sta *ieee80211_find_sta
+- }
+- EXPORT_SYMBOL(ieee80211_find_sta);
+- 
+--static void clear_sta_ps_flags(void *_sta)
+-+/* powersave support code */
+-+void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
+- {
+--	struct sta_info *sta = _sta;
+- 	struct ieee80211_sub_if_data *sdata = sta->sdata;
+-+	struct ieee80211_local *local = sdata->local;
+-+	struct sk_buff_head pending;
+-+	int filtered = 0, buffered = 0, ac;
+-+	unsigned long flags;
+- 	struct ps_data *ps;
+- 
+- 	if (sdata->vif.type == NL80211_IFTYPE_AP ||
+-@@ -1085,20 +1110,6 @@ static void clear_sta_ps_flags(void *_st
+- 	else
+- 		return;
+- 
+--	clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
+--	if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA))
+--		atomic_dec(&ps->num_sta_ps);
+--}
+--
+--/* powersave support code */
+--void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
+--{
+--	struct ieee80211_sub_if_data *sdata = sta->sdata;
+--	struct ieee80211_local *local = sdata->local;
+--	struct sk_buff_head pending;
+--	int filtered = 0, buffered = 0, ac;
+--	unsigned long flags;
+--
+- 	clear_sta_flag(sta, WLAN_STA_SP);
+- 
+- 	BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1);
+-@@ -1109,6 +1120,8 @@ void ieee80211_sta_ps_deliver_wakeup(str
+- 
+- 	skb_queue_head_init(&pending);
+- 
+-+	/* sync with ieee80211_tx_h_unicast_ps_buf */
+-+	spin_lock(&sta->ps_lock);
+- 	/* Send all buffered frames to the station */
+- 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+- 		int count = skb_queue_len(&pending), tmp;
+-@@ -1127,7 +1140,12 @@ void ieee80211_sta_ps_deliver_wakeup(str
+- 		buffered += tmp - count;
+- 	}
+- 
+--	ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta);
+-+	ieee80211_add_pending_skbs(local, &pending);
+-+	clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
+-+	clear_sta_flag(sta, WLAN_STA_PS_STA);
+-+	spin_unlock(&sta->ps_lock);
+-+
+-+	atomic_dec(&ps->num_sta_ps);
+- 
+- 	/* This station just woke up and isn't aware of our SMPS state */
+- 	if (!ieee80211_smps_is_restrictive(sta->known_smps_mode,
+---- a/net/mac80211/sta_info.h
+-+++ b/net/mac80211/sta_info.h
+-@@ -267,6 +267,7 @@ struct ieee80211_tx_latency_stat {
+-  * @drv_unblock_wk: used for driver PS unblocking
+-  * @listen_interval: listen interval of this station, when we're acting as AP
+-  * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly
+-+ * @ps_lock: used for powersave (when mac80211 is the AP) related locking
+-  * @ps_tx_buf: buffers (per AC) of frames to transmit to this station
+-  *	when it leaves power saving state or polls
+-  * @tx_filtered: buffers (per AC) of frames we already tried to
+-@@ -356,10 +357,8 @@ struct sta_info {
+- 	/* use the accessors defined below */
+- 	unsigned long _flags;
+- 
+--	/*
+--	 * STA powersave frame queues, no more than the internal
+--	 * locking required.
+--	 */
+-+	/* STA powersave lock and frame queues */
+-+	spinlock_t ps_lock;
+- 	struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
+- 	struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
+- 	unsigned long driver_buffered_tids;
+---- a/net/mac80211/util.c
+-+++ b/net/mac80211/util.c
+-@@ -435,9 +435,8 @@ void ieee80211_add_pending_skb(struct ie
+- 	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+- }
+- 
+--void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
+--				   struct sk_buff_head *skbs,
+--				   void (*fn)(void *data), void *data)
+-+void ieee80211_add_pending_skbs(struct ieee80211_local *local,
+-+				struct sk_buff_head *skbs)
++@@ -107,9 +107,6 @@ static void ath_tx_queue_tid(struct ath_
+  {
+- 	struct ieee80211_hw *hw = &local->hw;
+- 	struct sk_buff *skb;
+-@@ -461,9 +460,6 @@ void ieee80211_add_pending_skbs_fn(struc
+- 		__skb_queue_tail(&local->pending[queue], skb);
+- 	}
++ 	struct ath_atx_ac *ac = tid->ac;
+  
+--	if (fn)
+--		fn(data);
++-	if (tid->paused)
++-		return;
+ -
+- 	for (i = 0; i < hw->queues; i++)
+- 		__ieee80211_wake_queue(hw, i,
+- 			IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
+---- a/net/wireless/reg.c
+-+++ b/net/wireless/reg.c
+-@@ -1700,7 +1700,7 @@ static void reg_process_hint(struct regu
++ 	if (tid->sched)
+  		return;
+- 	case NL80211_REGDOM_SET_BY_USER:
+- 		treatment = reg_process_hint_user(reg_request);
+--		if (treatment == REG_REQ_OK ||
+-+		if (treatment == REG_REQ_IGNORE ||
+- 		    treatment == REG_REQ_ALREADY_SET)
+- 			return;
+- 		schedule_delayed_work(&reg_timeout, msecs_to_jiffies(3142));
+---- a/drivers/net/wireless/ath/ath9k/debug.c
+-+++ b/drivers/net/wireless/ath/ath9k/debug.c
+-@@ -138,43 +138,41 @@ static ssize_t read_file_ani(struct file
+- 	unsigned int len = 0, size = 1024;
+- 	ssize_t retval = 0;
+- 	char *buf;
+-+	int i;
+-+	struct {
+-+		const char *name;
+-+		unsigned int val;
+-+	} ani_info[] = {
+-+		{ "ANI RESET", ah->stats.ast_ani_reset },
+-+		{ "OFDM LEVEL", ah->ani.ofdmNoiseImmunityLevel },
+-+		{ "CCK LEVEL", ah->ani.cckNoiseImmunityLevel },
+-+		{ "SPUR UP", ah->stats.ast_ani_spurup },
+-+		{ "SPUR DOWN", ah->stats.ast_ani_spurup },
+-+		{ "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon },
+-+		{ "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff },
+-+		{ "MRC-CCK ON", ah->stats.ast_ani_ccklow },
+-+		{ "MRC-CCK OFF", ah->stats.ast_ani_cckhigh },
+-+		{ "FIR-STEP UP", ah->stats.ast_ani_stepup },
+-+		{ "FIR-STEP DOWN", ah->stats.ast_ani_stepdown },
+-+		{ "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero },
+-+		{ "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs },
+-+		{ "CCK ERRORS", ah->stats.ast_ani_cckerrs },
+-+	};
+- 
+- 	buf = kzalloc(size, GFP_KERNEL);
+- 	if (buf == NULL)
+- 		return -ENOMEM;
+- 
+--	if (common->disable_ani) {
+--		len += scnprintf(buf + len, size - len, "%s: %s\n",
+--				 "ANI", "DISABLED");
+-+	len += scnprintf(buf + len, size - len, "%15s: %s\n", "ANI",
+-+			 common->disable_ani ? "DISABLED" : "ENABLED");
+-+
+-+	if (common->disable_ani)
+- 		goto exit;
+--	}
+- 
+--	len += scnprintf(buf + len, size - len, "%15s: %s\n",
+--			 "ANI", "ENABLED");
+--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
+--			 "ANI RESET", ah->stats.ast_ani_reset);
+--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
+--			 "SPUR UP", ah->stats.ast_ani_spurup);
+--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
+--			 "SPUR DOWN", ah->stats.ast_ani_spurup);
+--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
+--			 "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon);
+--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
+--			 "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff);
+--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
+--			 "MRC-CCK ON", ah->stats.ast_ani_ccklow);
+--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
+--			 "MRC-CCK OFF", ah->stats.ast_ani_cckhigh);
+--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
+--			 "FIR-STEP UP", ah->stats.ast_ani_stepup);
+--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
+--			 "FIR-STEP DOWN", ah->stats.ast_ani_stepdown);
+--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
+--			 "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero);
+--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
+--			 "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs);
+--	len += scnprintf(buf + len, size - len, "%15s: %u\n",
+--			 "CCK ERRORS", ah->stats.ast_ani_cckerrs);
+-+	for (i = 0; i < ARRAY_SIZE(ani_info); i++)
+-+		len += scnprintf(buf + len, size - len, "%15s: %u\n",
+-+				 ani_info[i].name, ani_info[i].val);
+-+
+- exit:
+- 	if (len > size)
+- 		len = size;
+-@@ -866,6 +864,12 @@ static ssize_t read_file_reset(struct fi
+- 			 "%17s: %2d\n", "PLL RX Hang",
+- 			 sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
+- 	len += scnprintf(buf + len, sizeof(buf) - len,
+-+			 "%17s: %2d\n", "MAC Hang",
+-+			 sc->debug.stats.reset[RESET_TYPE_MAC_HANG]);
+-+	len += scnprintf(buf + len, sizeof(buf) - len,
+-+			 "%17s: %2d\n", "Stuck Beacon",
+-+			 sc->debug.stats.reset[RESET_TYPE_BEACON_STUCK]);
+-+	len += scnprintf(buf + len, sizeof(buf) - len,
+- 			 "%17s: %2d\n", "MCI Reset",
+- 			 sc->debug.stats.reset[RESET_TYPE_MCI]);
+- 
+---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+-+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+-@@ -868,10 +868,6 @@ static void ar9003_hw_set_rfmode(struct 
+- 
+- 	if (IS_CHAN_A_FAST_CLOCK(ah, chan))
+- 		rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
+--	if (IS_CHAN_QUARTER_RATE(chan))
+--		rfMode |= AR_PHY_MODE_QUARTER;
+--	if (IS_CHAN_HALF_RATE(chan))
+--		rfMode |= AR_PHY_MODE_HALF;
+- 
+- 	if (rfMode & (AR_PHY_MODE_QUARTER | AR_PHY_MODE_HALF))
+- 		REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
+---- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+-+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+-@@ -706,6 +706,7 @@ ath5k_get_survey(struct ieee80211_hw *hw
+- 	survey->channel = conf->chandef.chan;
+- 	survey->noise = ah->ah_noise_floor;
+- 	survey->filled = SURVEY_INFO_NOISE_DBM |
+-+			SURVEY_INFO_IN_USE |
+- 			SURVEY_INFO_CHANNEL_TIME |
+- 			SURVEY_INFO_CHANNEL_TIME_BUSY |
+- 			SURVEY_INFO_CHANNEL_TIME_RX |
+---- a/drivers/net/wireless/ath/ath9k/recv.c
+-+++ b/drivers/net/wireless/ath/ath9k/recv.c
+-@@ -732,11 +732,18 @@ static struct ath_rxbuf *ath_get_next_rx
+- 			return NULL;
+- 
+- 		/*
+--		 * mark descriptor as zero-length and set the 'more'
+--		 * flag to ensure that both buffers get discarded
+-+		 * Re-check previous descriptor, in case it has been filled
+-+		 * in the mean time.
+- 		 */
+--		rs->rs_datalen = 0;
+--		rs->rs_more = true;
+-+		ret = ath9k_hw_rxprocdesc(ah, ds, rs);
+-+		if (ret == -EINPROGRESS) {
+-+			/*
+-+			 * mark descriptor as zero-length and set the 'more'
+-+			 * flag to ensure that both buffers get discarded
+-+			 */
+-+			rs->rs_datalen = 0;
+-+			rs->rs_more = true;
+-+		}
+- 	}
+- 
+- 	list_del(&bf->list);
+-@@ -985,32 +992,32 @@ static int ath9k_rx_skb_preprocess(struc
+- 	struct ath_common *common = ath9k_hw_common(ah);
+- 	struct ieee80211_hdr *hdr;
+- 	bool discard_current = sc->rx.discard_next;
+--	int ret = 0;
+- 
+- 	/*
+- 	 * Discard corrupt descriptors which are marked in
+- 	 * ath_get_next_rx_buf().
+- 	 */
+--	sc->rx.discard_next = rx_stats->rs_more;
+- 	if (discard_current)
+--		return -EINVAL;
+-+		goto corrupt;
+-+
+-+	sc->rx.discard_next = false;
+- 
+- 	/*
+- 	 * Discard zero-length packets.
+- 	 */
+- 	if (!rx_stats->rs_datalen) {
+- 		RX_STAT_INC(rx_len_err);
+--		return -EINVAL;
+-+		goto corrupt;
+- 	}
+- 
+--        /*
+--         * rs_status follows rs_datalen so if rs_datalen is too large
+--         * we can take a hint that hardware corrupted it, so ignore
+--         * those frames.
+--         */
+-+	/*
+-+	 * rs_status follows rs_datalen so if rs_datalen is too large
+-+	 * we can take a hint that hardware corrupted it, so ignore
+-+	 * those frames.
+-+	 */
+- 	if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) {
+- 		RX_STAT_INC(rx_len_err);
+--		return -EINVAL;
+-+		goto corrupt;
+- 	}
+- 
+- 	/* Only use status info from the last fragment */
+-@@ -1024,10 +1031,8 @@ static int ath9k_rx_skb_preprocess(struc
+- 	 * This is different from the other corrupt descriptor
+- 	 * condition handled above.
+- 	 */
+--	if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) {
+--		ret = -EINVAL;
+--		goto exit;
+--	}
+-+	if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC)
+-+		goto corrupt;
+- 
+- 	hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len);
+- 
+-@@ -1043,18 +1048,15 @@ static int ath9k_rx_skb_preprocess(struc
+- 		if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime))
+- 			RX_STAT_INC(rx_spectral);
+- 
+--		ret = -EINVAL;
+--		goto exit;
+-+		return -EINVAL;
+- 	}
+- 
+- 	/*
+- 	 * everything but the rate is checked here, the rate check is done
+- 	 * separately to avoid doing two lookups for a rate for each frame.
+- 	 */
+--	if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) {
+--		ret = -EINVAL;
+--		goto exit;
+--	}
+-+	if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error))
+-+		return -EINVAL;
+- 
+- 	if (ath_is_mybeacon(common, hdr)) {
+- 		RX_STAT_INC(rx_beacons);
+-@@ -1064,15 +1066,11 @@ static int ath9k_rx_skb_preprocess(struc
+- 	/*
+- 	 * This shouldn't happen, but have a safety check anyway.
+- 	 */
+--	if (WARN_ON(!ah->curchan)) {
+--		ret = -EINVAL;
+--		goto exit;
+--	}
+-+	if (WARN_ON(!ah->curchan))
+-+		return -EINVAL;
+- 
+--	if (ath9k_process_rate(common, hw, rx_stats, rx_status)) {
+--		ret =-EINVAL;
+--		goto exit;
+--	}
+-+	if (ath9k_process_rate(common, hw, rx_stats, rx_status))
+-+		return -EINVAL;
+- 
+- 	ath9k_process_rssi(common, hw, rx_stats, rx_status);
+- 
+-@@ -1087,9 +1085,11 @@ static int ath9k_rx_skb_preprocess(struc
+- 		sc->rx.num_pkts++;
+- #endif
+- 
+--exit:
+--	sc->rx.discard_next = false;
+--	return ret;
+-+	return 0;
+-+
+-+corrupt:
+-+	sc->rx.discard_next = rx_stats->rs_more;
+-+	return -EINVAL;
+- }
+- 
+- static void ath9k_rx_skb_postprocess(struct ath_common *common,
+---- a/drivers/net/wireless/ath/ath9k/ani.c
+-+++ b/drivers/net/wireless/ath/ath9k/ani.c
+-@@ -176,16 +176,26 @@ static void ath9k_hw_set_ofdm_nil(struct
+- 	if (ah->opmode == NL80211_IFTYPE_STATION &&
+- 	    BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH)
+- 		weak_sig = true;
+--
+- 	/*
+--	 * OFDM Weak signal detection is always enabled for AP mode.
+-+	 * Newer chipsets are better at dealing with high PHY error counts -
+-+	 * keep weak signal detection enabled when no RSSI threshold is
+-+	 * available to determine if it is needed (mode != STA)
+- 	 */
+--	if (ah->opmode != NL80211_IFTYPE_AP &&
+--	    aniState->ofdmWeakSigDetect != weak_sig) {
+--		ath9k_hw_ani_control(ah,
+--				     ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+--				     entry_ofdm->ofdm_weak_signal_on);
+--	}
+-+	else if (AR_SREV_9300_20_OR_LATER(ah) &&
+-+		 ah->opmode != NL80211_IFTYPE_STATION)
+-+		weak_sig = true;
+-+
+-+	/* Older chipsets are more sensitive to high PHY error counts */
+-+	else if (!AR_SREV_9300_20_OR_LATER(ah) &&
+-+		 aniState->ofdmNoiseImmunityLevel >= 8)
+-+		weak_sig = false;
+-+
+-+	if (aniState->ofdmWeakSigDetect != weak_sig)
+-+		ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+-+				     weak_sig);
+-+
+-+	if (!AR_SREV_9300_20_OR_LATER(ah))
+-+		return;
+- 
+- 	if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
+- 		ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
+-@@ -308,17 +318,6 @@ void ath9k_ani_reset(struct ath_hw *ah, 
+- 	BUG_ON(aniState == NULL);
+- 	ah->stats.ast_ani_reset++;
+  
+--	/* only allow a subset of functions in AP mode */
+--	if (ah->opmode == NL80211_IFTYPE_AP) {
+--		if (IS_CHAN_2GHZ(chan)) {
+--			ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
+--					    ATH9K_ANI_FIRSTEP_LEVEL);
+--			if (AR_SREV_9300_20_OR_LATER(ah))
+--				ah->ani_function |= ATH9K_ANI_MRC_CCK;
+--		} else
+--			ah->ani_function = 0;
+--	}
+--
+- 	ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL,
+- 			 aniState->ofdmNoiseImmunityLevel);
+- 	cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL,
+-@@ -483,10 +482,17 @@ void ath9k_hw_ani_init(struct ath_hw *ah
+- 
+- 	ath_dbg(common, ANI, "Initialize ANI\n");
+- 
+--	ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
+--	ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
+--	ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
+--	ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
+-+	if (AR_SREV_9300_20_OR_LATER(ah)) {
+-+		ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
+-+		ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
+-+		ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
+-+		ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
+-+	} else {
+-+		ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
+-+		ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
+-+		ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
+-+		ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
+-+	}
+- 
+- 	ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+- 	ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+---- a/drivers/net/wireless/ath/ath9k/ani.h
+-+++ b/drivers/net/wireless/ath/ath9k/ani.h
+-@@ -22,12 +22,16 @@
+- /* units are errors per second */
+- #define ATH9K_ANI_OFDM_TRIG_HIGH           3500
+- #define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
+-+#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD       500
++@@ -1407,7 +1404,6 @@ int ath_tx_aggr_start(struct ath_softc *
++ 	ath_tx_tid_change_state(sc, txtid);
+  
+- #define ATH9K_ANI_OFDM_TRIG_LOW           400
+- #define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
+-+#define ATH9K_ANI_OFDM_TRIG_LOW_OLD       200
+- 
+- #define ATH9K_ANI_CCK_TRIG_HIGH           600
+-+#define ATH9K_ANI_CCK_TRIG_HIGH_OLD       200
+- #define ATH9K_ANI_CCK_TRIG_LOW            300
+-+#define ATH9K_ANI_CCK_TRIG_LOW_OLD        100
+- 
+- #define ATH9K_ANI_SPUR_IMMUNE_LVL         3
+- #define ATH9K_ANI_FIRSTEP_LVL             2
+---- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+-+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+-@@ -26,10 +26,6 @@ static const int firstep_table[] =
+- /* level:  0   1   2   3   4   5   6   7   8  */
+- 	{ -4, -2,  0,  2,  4,  6,  8, 10, 12 }; /* lvl 0-8, default 2 */
++ 	txtid->active = true;
++-	txtid->paused = true;
++ 	*ssn = txtid->seq_start = txtid->seq_next;
++ 	txtid->bar_index = -1;
+  
+--static const int cycpwrThr1_table[] =
+--/* level:  0   1   2   3   4   5   6   7   8  */
+--	{ -6, -4, -2,  0,  2,  4,  6,  8 };     /* lvl 0-7, default 3 */
+--
+- /*
+-  * register values to turn OFDM weak signal detection OFF
+-  */
+-@@ -921,7 +917,7 @@ static bool ar5008_hw_ani_control_new(st
+- 	struct ath_common *common = ath9k_hw_common(ah);
+- 	struct ath9k_channel *chan = ah->curchan;
+- 	struct ar5416AniState *aniState = &ah->ani;
+--	s32 value, value2;
+-+	s32 value;
++@@ -1427,7 +1423,6 @@ void ath_tx_aggr_stop(struct ath_softc *
+  
+- 	switch (cmd & ah->ani_function) {
+- 	case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
+-@@ -1008,42 +1004,9 @@ static bool ar5008_hw_ani_control_new(st
+- 	case ATH9K_ANI_FIRSTEP_LEVEL:{
+- 		u32 level = param;
++ 	ath_txq_lock(sc, txq);
++ 	txtid->active = false;
++-	txtid->paused = false;
++ 	ath_tx_flush_tid(sc, txtid);
++ 	ath_tx_tid_change_state(sc, txtid);
++ 	ath_txq_unlock_complete(sc, txq);
++@@ -1487,7 +1482,7 @@ void ath_tx_aggr_wakeup(struct ath_softc
++ 		ath_txq_lock(sc, txq);
++ 		ac->clear_ps_filter = true;
+  
+--		if (level >= ARRAY_SIZE(firstep_table)) {
+--			ath_dbg(common, ANI,
+--				"ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n",
+--				level, ARRAY_SIZE(firstep_table));
+--			return false;
+--		}
+--
+--		/*
+--		 * make register setting relative to default
+--		 * from INI file & cap value
+--		 */
+--		value = firstep_table[level] -
+--			firstep_table[ATH9K_ANI_FIRSTEP_LVL] +
+--			aniState->iniDef.firstep;
+--		if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
+--			value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
+--		if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX)
+--			value = ATH9K_SIG_FIRSTEP_SETTING_MAX;
+-+		value = level;
+- 		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+--			      AR_PHY_FIND_SIG_FIRSTEP,
+--			      value);
+--		/*
+--		 * we need to set first step low register too
+--		 * make register setting relative to default
+--		 * from INI file & cap value
+--		 */
+--		value2 = firstep_table[level] -
+--			 firstep_table[ATH9K_ANI_FIRSTEP_LVL] +
+--			 aniState->iniDef.firstepLow;
+--		if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
+--			value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
+--		if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX)
+--			value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX;
+--
+--		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
+--			      AR_PHY_FIND_SIG_FIRSTEP_LOW, value2);
+-+			      AR_PHY_FIND_SIG_FIRSTEP, value);
++-		if (!tid->paused && ath_tid_has_buffered(tid)) {
+++		if (ath_tid_has_buffered(tid)) {
++ 			ath_tx_queue_tid(txq, tid);
++ 			ath_txq_schedule(sc, txq);
++ 		}
++@@ -1510,7 +1505,6 @@ void ath_tx_aggr_resume(struct ath_softc
++ 	ath_txq_lock(sc, txq);
+  
+- 		if (level != aniState->firstepLevel) {
+- 			ath_dbg(common, ANI,
+-@@ -1060,7 +1023,7 @@ static bool ar5008_hw_ani_control_new(st
+- 				aniState->firstepLevel,
+- 				level,
+- 				ATH9K_ANI_FIRSTEP_LVL,
+--				value2,
+-+				value,
+- 				aniState->iniDef.firstepLow);
+- 			if (level > aniState->firstepLevel)
+- 				ah->stats.ast_ani_stepup++;
+-@@ -1073,41 +1036,13 @@ static bool ar5008_hw_ani_control_new(st
+- 	case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
+- 		u32 level = param;
++ 	tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
++-	tid->paused = false;
+  
+--		if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
+--			ath_dbg(common, ANI,
+--				"ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n",
+--				level, ARRAY_SIZE(cycpwrThr1_table));
+--			return false;
+--		}
+--		/*
+--		 * make register setting relative to default
+--		 * from INI file & cap value
+--		 */
+--		value = cycpwrThr1_table[level] -
+--			cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] +
+--			aniState->iniDef.cycpwrThr1;
+--		if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
+--			value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
+--		if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
+--			value = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
+-+		value = (level + 1) * 2;
+- 		REG_RMW_FIELD(ah, AR_PHY_TIMING5,
+--			      AR_PHY_TIMING5_CYCPWR_THR1,
+--			      value);
+-+			      AR_PHY_TIMING5_CYCPWR_THR1, value);
++ 	if (ath_tid_has_buffered(tid)) {
++ 		ath_tx_queue_tid(txq, tid);
++@@ -1544,8 +1538,6 @@ void ath9k_release_buffered_frames(struc
++ 			continue;
+  
+--		/*
+--		 * set AR_PHY_EXT_CCA for extension channel
+--		 * make register setting relative to default
+--		 * from INI file & cap value
+--		 */
+--		value2 = cycpwrThr1_table[level] -
+--			 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] +
+--			 aniState->iniDef.cycpwrThr1Ext;
+--		if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
+--			value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
+--		if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
+--			value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
+--		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
+--			      AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2);
+-+		if (IS_CHAN_HT40(ah->curchan))
+-+			REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
+-+				      AR_PHY_EXT_TIMING5_CYCPWR_THR1, value);
++ 		tid = ATH_AN_2_TID(an, i);
++-		if (tid->paused)
++-			continue;
+  
+- 		if (level != aniState->spurImmunityLevel) {
+- 			ath_dbg(common, ANI,
+-@@ -1124,7 +1059,7 @@ static bool ar5008_hw_ani_control_new(st
+- 				aniState->spurImmunityLevel,
+- 				level,
+- 				ATH9K_ANI_SPUR_IMMUNE_LVL,
+--				value2,
+-+				value,
+- 				aniState->iniDef.cycpwrThr1Ext);
+- 			if (level > aniState->spurImmunityLevel)
+- 				ah->stats.ast_ani_spurup++;
++ 		ath_txq_lock(sc, tid->ac->txq);
++ 		while (nframes > 0) {
++@@ -1844,9 +1836,6 @@ void ath_txq_schedule(struct ath_softc *
++ 			list_del(&tid->list);
++ 			tid->sched = false;
++ 
++-			if (tid->paused)
++-				continue;
++-
++ 			if (ath_tx_sched_aggr(sc, txq, tid, &stop))
++ 				sent = true;
++ 
++@@ -2698,7 +2687,6 @@ void ath_tx_node_init(struct ath_softc *
++ 		tid->baw_size  = WME_MAX_BA;
++ 		tid->baw_head  = tid->baw_tail = 0;
++ 		tid->sched     = false;
++-		tid->paused    = false;
++ 		tid->active	   = false;
++ 		__skb_queue_head_init(&tid->buf_q);
++ 		__skb_queue_head_init(&tid->retry_q);
+diff --git a/package/mac80211/patches/310-ap_scan.patch b/package/mac80211/patches/310-ap_scan.patch
+index 389a003..87f165a 100644
+--- a/package/mac80211/patches/310-ap_scan.patch
++++ b/package/mac80211/patches/310-ap_scan.patch
+@@ -1,6 +1,6 @@
+ --- a/net/mac80211/cfg.c
+ +++ b/net/mac80211/cfg.c
+-@@ -2148,7 +2148,7 @@ static int ieee80211_scan(struct wiphy *
++@@ -2154,7 +2154,7 @@ static int ieee80211_scan(struct wiphy *
+  		 * the  frames sent while scanning on other channel will be
+  		 * lost)
+  		 */
+diff --git a/package/mac80211/patches/400-ath_move_debug_code.patch b/package/mac80211/patches/400-ath_move_debug_code.patch
+index 0dba7ac..4cc77af 100644
+--- a/package/mac80211/patches/400-ath_move_debug_code.patch
++++ b/package/mac80211/patches/400-ath_move_debug_code.patch
+@@ -12,7 +12,7 @@
+  ccflags-y += -D__CHECK_ENDIAN__
+ --- a/drivers/net/wireless/ath/ath.h
+ +++ b/drivers/net/wireless/ath/ath.h
+-@@ -282,13 +282,6 @@ void _ath_dbg(struct ath_common *common,
++@@ -295,13 +295,6 @@ void _ath_dbg(struct ath_common *common,
+  #endif /* CPTCFG_ATH_DEBUG */
+  
+  /** Returns string describing opmode, or NULL if unknown mode. */
+diff --git a/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch b/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch
+index 63ab0db..acaa317 100644
+--- a/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch
++++ b/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch
+@@ -8,7 +8,7 @@
+  #include <asm/unaligned.h>
+  
+  #include "hw.h"
+-@@ -449,8 +450,16 @@ static int ath9k_hw_init_macaddr(struct 
++@@ -448,8 +449,16 @@ static int ath9k_hw_init_macaddr(struct 
+  		common->macaddr[2 * i] = eeval >> 8;
+  		common->macaddr[2 * i + 1] = eeval & 0xff;
+  	}
+diff --git a/package/mac80211/patches/403-ath_regd_optional.patch b/package/mac80211/patches/403-ath_regd_optional.patch
+index 07c54cc..4a9b7e4 100644
+--- a/package/mac80211/patches/403-ath_regd_optional.patch
++++ b/package/mac80211/patches/403-ath_regd_optional.patch
+@@ -58,7 +58,7 @@
+  	---help---
+ --- a/.local-symbols
+ +++ b/.local-symbols
+-@@ -119,6 +119,7 @@ RTL8187_LEDS=
++@@ -120,6 +120,7 @@ RTL8187_LEDS=
+  ATH_COMMON=
+  ATH_CARDS=
+  ATH_DEBUG=
+diff --git a/package/mac80211/patches/405-regd_no_assoc_hints.patch b/package/mac80211/patches/405-regd_no_assoc_hints.patch
+index 6ad4fda..4fa611f 100644
+--- a/package/mac80211/patches/405-regd_no_assoc_hints.patch
++++ b/package/mac80211/patches/405-regd_no_assoc_hints.patch
+@@ -1,6 +1,6 @@
+ --- a/net/wireless/reg.c
+ +++ b/net/wireless/reg.c
+-@@ -1878,6 +1878,8 @@ void regulatory_hint_country_ie(struct w
++@@ -2000,6 +2000,8 @@ void regulatory_hint_country_ie(struct w
+  	enum environment_cap env = ENVIRON_ANY;
+  	struct regulatory_request *request = NULL, *lr;
+  
+@@ -9,7 +9,7 @@
+  	/* IE len must be evenly divisible by 2 */
+  	if (country_ie_len & 0x01)
+  		return;
+-@@ -2072,6 +2074,7 @@ static void restore_regulatory_settings(
++@@ -2194,6 +2196,7 @@ static void restore_regulatory_settings(
+  
+  void regulatory_hint_disconnect(void)
+  {
+diff --git a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
+index 1f71e0b..909a5f1 100644
+--- a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
++++ b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
+@@ -1,6 +1,6 @@
+ --- a/drivers/net/wireless/ath/ath9k/init.c
+ +++ b/drivers/net/wireless/ath/ath9k/init.c
+-@@ -866,6 +866,7 @@ static const struct ieee80211_iface_limi
++@@ -652,6 +652,7 @@ static const struct ieee80211_iface_limi
+  #endif
+  				 BIT(NL80211_IFTYPE_AP) |
+  				 BIT(NL80211_IFTYPE_P2P_GO) },
+diff --git a/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch b/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
+index 3487ab2..1f06994 100644
+--- a/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
++++ b/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
+@@ -18,7 +18,7 @@
+  		goto end;
+ --- a/drivers/net/wireless/ath/ath5k/base.c
+ +++ b/drivers/net/wireless/ath/ath5k/base.c
+-@@ -1934,7 +1934,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
++@@ -1937,7 +1937,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
+  	}
+  
+  	if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +
+@@ -27,7 +27,7 @@
+  			ah->opmode == NL80211_IFTYPE_MESH_POINT) {
+  		u64 tsf = ath5k_hw_get_tsf64(ah);
+  		u32 tsftu = TSF_TO_TU(tsf);
+-@@ -2020,7 +2020,7 @@ ath5k_beacon_update_timers(struct ath5k_
++@@ -2023,7 +2023,7 @@ ath5k_beacon_update_timers(struct ath5k_
+  
+  	intval = ah->bintval & AR5K_BEACON_PERIOD;
+  	if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
+@@ -36,7 +36,7 @@
+  		intval /= ATH_BCBUF;	/* staggered multi-bss beacons */
+  		if (intval < 15)
+  			ATH5K_WARN(ah, "intval %u is too low, min 15\n",
+-@@ -2487,6 +2487,7 @@ static const struct ieee80211_iface_limi
++@@ -2490,6 +2490,7 @@ static const struct ieee80211_iface_limi
+  				 BIT(NL80211_IFTYPE_MESH_POINT) |
+  #endif
+  				 BIT(NL80211_IFTYPE_AP) },
+diff --git a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
+index 664cf45..36e0151 100644
+--- a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
++++ b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
+@@ -1,6 +1,6 @@
+ --- a/drivers/net/wireless/ath/ath9k/debug.c
+ +++ b/drivers/net/wireless/ath/ath9k/debug.c
+-@@ -1481,6 +1481,53 @@ void ath9k_deinit_debug(struct ath_softc
++@@ -1485,6 +1485,53 @@ void ath9k_deinit_debug(struct ath_softc
+  	ath9k_spectral_deinit_debug(sc);
+  }
+  
+@@ -54,7 +54,7 @@
+  int ath9k_init_debug(struct ath_hw *ah)
+  {
+  	struct ath_common *common = ath9k_hw_common(ah);
+-@@ -1500,6 +1547,8 @@ int ath9k_init_debug(struct ath_hw *ah)
++@@ -1504,6 +1551,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+  	ath9k_tx99_init_debug(sc);
+  	ath9k_spectral_init_debug(sc);
+  
+diff --git a/package/mac80211/patches/501-ath9k-eeprom_endianess.patch b/package/mac80211/patches/501-ath9k-eeprom_endianess.patch
+index 96e7c6d..169eb9a 100644
+--- a/package/mac80211/patches/501-ath9k-eeprom_endianess.patch
++++ b/package/mac80211/patches/501-ath9k-eeprom_endianess.patch
+@@ -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
+-@@ -722,6 +722,8 @@ static int ath9k_init_softc(u16 devid, s
++@@ -518,6 +518,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;
+diff --git a/package/mac80211/patches/502-ath9k_ahb_init.patch b/package/mac80211/patches/502-ath9k_ahb_init.patch
+index 4edc63b..43c3260 100644
+--- a/package/mac80211/patches/502-ath9k_ahb_init.patch
++++ b/package/mac80211/patches/502-ath9k_ahb_init.patch
+@@ -1,15 +1,15 @@
+ --- a/drivers/net/wireless/ath/ath9k/init.c
+ +++ b/drivers/net/wireless/ath/ath9k/init.c
+-@@ -1112,23 +1112,23 @@ static int __init ath9k_init(void)
+- 		goto err_out;
+- 	}
++@@ -892,23 +892,23 @@ static int __init ath9k_init(void)
++ {
++ 	int error;
+  
+ -	error = ath_pci_init();
+ +	error = ath_ahb_init();
+  	if (error < 0) {
+ -		pr_err("No PCI devices found, driver not installed\n");
+  		error = -ENODEV;
+- 		goto err_rate_unregister;
++ 		goto err_out;
+  	}
+  
+ -	error = ath_ahb_init();
+@@ -27,6 +27,6 @@
+ -	ath_pci_exit();
+ + err_ahb_exit:
+ +	ath_ahb_exit();
+- 
+-  err_rate_unregister:
+- 	ath_rate_control_unregister();
++  err_out:
++ 	return error;
++ }
+diff --git a/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
+index d7478ff..c818933 100644
+--- a/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
++++ b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
+@@ -1,6 +1,6 @@
+ --- a/drivers/net/wireless/ath/ath9k/hw.c
+ +++ b/drivers/net/wireless/ath/ath9k/hw.c
+-@@ -359,13 +359,8 @@ static void ath9k_hw_init_config(struct 
++@@ -358,13 +358,8 @@ static void ath9k_hw_init_config(struct 
+  
+  	ah->config.rx_intr_mitigation = true;
+  
+diff --git a/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch b/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch
+index ef0b9a1..e457267 100644
+--- a/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch
++++ b/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch
+@@ -1,6 +1,6 @@
+ --- a/drivers/net/wireless/ath/ath9k/ath9k.h
+ +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+-@@ -90,7 +90,7 @@ int ath_descdma_setup(struct ath_softc *
++@@ -89,7 +89,7 @@ int ath_descdma_setup(struct ath_softc *
+  		(_l) &= ((_sz) - 1);		\
+  	} while (0)
+  
+diff --git a/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch
+index 8f3cc03..665d8aa 100644
+--- a/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch
++++ b/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch
+@@ -1,6 +1,6 @@
+ --- a/drivers/net/wireless/ath/ath9k/debug.c
+ +++ b/drivers/net/wireless/ath/ath9k/debug.c
+-@@ -1528,6 +1528,52 @@ static const struct file_operations fops
++@@ -1532,6 +1532,52 @@ static const struct file_operations fops
+  	.owner = THIS_MODULE
+  };
+  
+@@ -35,7 +35,7 @@
+ +		return -EINVAL;
+ +
+ +	common->chan_bw = chan_bw;
+-+	if (!test_bit(SC_OP_INVALID, &sc->sc_flags))
+++	if (!test_bit(ATH_OP_INVALID, &common->op_flags))
+ +		ath9k_ops.config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL);
+ +
+ +	return count;
+@@ -53,7 +53,7 @@
+  int ath9k_init_debug(struct ath_hw *ah)
+  {
+  	struct ath_common *common = ath9k_hw_common(ah);
+-@@ -1549,6 +1595,8 @@ int ath9k_init_debug(struct ath_hw *ah)
++@@ -1553,6 +1599,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+  
+  	debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
+  			    &fops_eeprom);
+@@ -64,17 +64,17 @@
+  	debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
+ --- a/drivers/net/wireless/ath/ath.h
+ +++ b/drivers/net/wireless/ath/ath.h
+-@@ -130,6 +130,7 @@ struct ath_common {
+- 	struct ieee80211_hw *hw;
++@@ -140,6 +140,7 @@ struct ath_common {
+  	int debug_mask;
+  	enum ath_device_state state;
++ 	unsigned long op_flags;
+ +	u32 chan_bw;
+  
+  	struct ath_ani ani;
+  
+ --- a/drivers/net/wireless/ath/ath9k/common.c
+ +++ b/drivers/net/wireless/ath/ath9k/common.c
+-@@ -52,11 +52,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke
++@@ -296,11 +296,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke
+  /*
+   * Update internal channel flags.
+   */
+@@ -89,7 +89,7 @@
+  
+  	ichan->channel = chan->center_freq;
+  	ichan->chan = chan;
+-@@ -64,7 +66,19 @@ static void ath9k_cmn_update_ichannel(st
++@@ -308,7 +310,19 @@ static void ath9k_cmn_update_ichannel(st
+  	if (chan->band == IEEE80211_BAND_5GHZ)
+  		flags |= CHANNEL_5GHZ;
+  
+@@ -110,7 +110,7 @@
+  	case NL80211_CHAN_WIDTH_5:
+  		flags |= CHANNEL_QUARTER;
+  		break;
+-@@ -97,10 +111,11 @@ struct ath9k_channel *ath9k_cmn_get_chan
++@@ -341,10 +355,11 @@ struct ath9k_channel *ath9k_cmn_get_chan
+  					    struct cfg80211_chan_def *chandef)
+  {
+  	struct ieee80211_channel *curchan = chandef->chan;
+diff --git a/package/mac80211/patches/513-ath9k_add_pci_ids.patch b/package/mac80211/patches/513-ath9k_add_pci_ids.patch
+index db4e6a1..540198f 100644
+--- a/package/mac80211/patches/513-ath9k_add_pci_ids.patch
++++ b/package/mac80211/patches/513-ath9k_add_pci_ids.patch
+@@ -1,6 +1,6 @@
+ --- a/drivers/net/wireless/ath/ath9k/hw.c
+ +++ b/drivers/net/wireless/ath/ath9k/hw.c
+-@@ -614,6 +614,7 @@ int ath9k_hw_init(struct ath_hw *ah)
++@@ -613,6 +613,7 @@ int ath9k_hw_init(struct ath_hw *ah)
+  
+  	/* These are all the AR5008/AR9001/AR9002/AR9003 hardware family of chipsets */
+  	switch (ah->hw_version.devid) {
+diff --git a/package/mac80211/patches/520-mac80211_cur_txpower.patch b/package/mac80211/patches/520-mac80211_cur_txpower.patch
+index 6df95bc..cb3f852 100644
+--- a/package/mac80211/patches/520-mac80211_cur_txpower.patch
++++ b/package/mac80211/patches/520-mac80211_cur_txpower.patch
+@@ -1,6 +1,6 @@
+ --- a/include/net/mac80211.h
+ +++ b/include/net/mac80211.h
+-@@ -1711,6 +1711,7 @@ struct ieee80211_hw {
++@@ -1703,6 +1703,7 @@ struct ieee80211_hw {
+  	u8 max_tx_aggregation_subframes;
+  	u8 offchannel_tx_hw_queue;
+  	u8 radiotap_mcs_details;
+@@ -10,7 +10,7 @@
+  	u8 uapsd_queues;
+ --- a/net/mac80211/cfg.c
+ +++ b/net/mac80211/cfg.c
+-@@ -2329,7 +2329,9 @@ static int ieee80211_get_tx_power(struct
++@@ -2335,7 +2335,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
+-@@ -158,6 +158,7 @@ static u32 ieee80211_hw_conf_chan(struct
++@@ -160,6 +160,7 @@ static u32 ieee80211_hw_conf_chan(struct
+  
+  	if (local->hw.conf.power_level != power) {
+  		changed |= IEEE80211_CONF_CHANGE_POWER;
+diff --git a/package/mac80211/patches/521-ath9k_cur_txpower.patch b/package/mac80211/patches/521-ath9k_cur_txpower.patch
+index 0d6c360..24bc062 100644
+--- a/package/mac80211/patches/521-ath9k_cur_txpower.patch
++++ b/package/mac80211/patches/521-ath9k_cur_txpower.patch
+@@ -14,7 +14,7 @@
+  
+  out:
+  	spin_unlock_bh(&sc->sc_pcu_lock);
+-@@ -1371,6 +1375,7 @@ static int ath9k_config(struct ieee80211
++@@ -1370,6 +1374,7 @@ static int ath9k_config(struct ieee80211
+  		sc->config.txpowlimit = 2 * conf->power_level;
+  		ath9k_cmn_update_txpow(ah, sc->curtxpow,
+  				       sc->config.txpowlimit, &sc->curtxpow);
+diff --git a/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch
+index 308ee6e..611f763 100644
+--- a/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch
++++ b/package/mac80211/patches/522-mac80211_configure_antenna_gain.patch
+@@ -1,6 +1,6 @@
+ --- a/include/net/cfg80211.h
+ +++ b/include/net/cfg80211.h
+-@@ -2156,6 +2156,7 @@ struct cfg80211_qos_map {
++@@ -2167,6 +2167,7 @@ struct cfg80211_qos_map {
+   *	(as advertised by the nl80211 feature flag.)
+   * @get_tx_power: store the current TX power into the dbm variable;
+   *	return 0 if successful
+@@ -8,7 +8,7 @@
+   *
+   * @set_wds_peer: set the WDS peer for a WDS interface
+   *
+-@@ -2380,6 +2381,7 @@ struct cfg80211_ops {
++@@ -2396,6 +2397,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);
+@@ -18,7 +18,7 @@
+  				const u8 *addr);
+ --- a/include/net/mac80211.h
+ +++ b/include/net/mac80211.h
+-@@ -1033,6 +1033,7 @@ enum ieee80211_smps_mode {
++@@ -1032,6 +1032,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
+@@ -26,7 +26,7 @@
+   *
+   * @chandef: the channel definition to tune to
+   * @radar_enabled: whether radar detection is enabled
+-@@ -1054,6 +1055,7 @@ struct ieee80211_conf {
++@@ -1053,6 +1054,7 @@ struct ieee80211_conf {
+  	u32 flags;
+  	int power_level, dynamic_ps_timeout;
+  	int max_sleep_period;
+@@ -36,9 +36,9 @@
+  	u8 ps_dtim_period;
+ --- a/include/uapi/linux/nl80211.h
+ +++ b/include/uapi/linux/nl80211.h
+-@@ -1555,6 +1555,9 @@ enum nl80211_commands {
+-  *	data is in the format defined for the payload of the QoS Map Set element
+-  *	in IEEE Std 802.11-2012, 8.4.2.97.
++@@ -1579,6 +1579,9 @@ enum nl80211_commands {
++  * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32.
++  *	As specified in the &enum nl80211_tdls_peer_capability.
+   *
+ + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
+ + *	transmit power to stay within regulatory limits. u32, dBi.
+@@ -46,9 +46,9 @@
+   * @NL80211_ATTR_MAX: highest attribute number currently defined
+   * @__NL80211_ATTR_AFTER_LAST: internal use
+   */
+-@@ -1883,6 +1886,8 @@ enum nl80211_attrs {
++@@ -1914,6 +1917,8 @@ enum nl80211_attrs {
+  
+- 	NL80211_ATTR_QOS_MAP,
++ 	NL80211_ATTR_TDLS_PEER_CAPABILITY,
+  
+ +	NL80211_ATTR_WIPHY_ANTENNA_GAIN,
+ +
+@@ -57,7 +57,7 @@
+  	__NL80211_ATTR_AFTER_LAST,
+ --- a/net/mac80211/cfg.c
+ +++ b/net/mac80211/cfg.c
+-@@ -2339,6 +2339,19 @@ static int ieee80211_get_tx_power(struct
++@@ -2345,6 +2345,19 @@ static int ieee80211_get_tx_power(struct
+  	return 0;
+  }
+  
+@@ -77,7 +77,7 @@
+  static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
+  				  const u8 *addr)
+  {
+-@@ -3924,6 +3937,7 @@ struct cfg80211_ops mac80211_config_ops 
++@@ -4000,6 +4013,7 @@ const struct cfg80211_ops mac80211_confi
+  	.set_wiphy_params = ieee80211_set_wiphy_params,
+  	.set_tx_power = ieee80211_set_tx_power,
+  	.get_tx_power = ieee80211_get_tx_power,
+@@ -87,7 +87,7 @@
+  	CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
+ --- a/net/mac80211/ieee80211_i.h
+ +++ b/net/mac80211/ieee80211_i.h
+-@@ -1221,6 +1221,7 @@ struct ieee80211_local {
++@@ -1225,6 +1225,7 @@ struct ieee80211_local {
+  	int dynamic_ps_forced_timeout;
+  
+  	int user_power_level; /* in dBm, for all interfaces */
+@@ -102,34 +102,24 @@
+  	struct cfg80211_chan_def chandef = {};
+  	u32 changed = 0;
+ -	int power;
+-+	int power, ant_gain, max_power;
+++	int power, max_power;
+  	u32 offchannel_flag;
+  
+  	offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
+-@@ -156,8 +156,21 @@ static u32 ieee80211_hw_conf_chan(struct
++@@ -158,6 +158,12 @@ static u32 ieee80211_hw_conf_chan(struct
+  	}
+  	rcu_read_unlock();
+  
+--	if (local->hw.conf.power_level != power) {
+ +	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;
+-+			ant_gain = 0;
+-+		} else
+-+			ant_gain -= local->user_antenna_gain;
+++		max_power -= local->user_antenna_gain;
+ +		power = min(power, max_power);
+ +	}
+ +
+-+	if (local->hw.conf.power_level != power ||
+-+	    local->hw.conf.max_antenna_gain != ant_gain) {
++ 	if (local->hw.conf.power_level != power) {
+  		changed |= IEEE80211_CONF_CHANGE_POWER;
+-+		local->hw.conf.max_antenna_gain = ant_gain;
+  		local->hw.cur_power_level = power;
+- 		local->hw.conf.power_level = power;
+- 	}
+-@@ -584,6 +597,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(
++@@ -586,6 +592,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;
+@@ -139,32 +129,30 @@
+  	local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
+ --- a/net/wireless/nl80211.c
+ +++ b/net/wireless/nl80211.c
+-@@ -384,6 +384,7 @@ static const struct nla_policy nl80211_p
+- 	[NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
+- 	[NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY,
+- 				   .len = IEEE80211_QOS_MAP_LEN_MAX },
++@@ -385,6 +385,7 @@ static const struct nla_policy nl80211_p
++ 	[NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
++ 	[NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
++ 	[NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
+ +	[NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
+  };
+  
+  /* policy for the key attributes */
+-@@ -2105,6 +2106,22 @@ static int nl80211_set_wiphy(struct sk_b
+- 			goto bad_res;
++@@ -2116,6 +2117,20 @@ static int nl80211_set_wiphy(struct sk_b
++ 			return result;
+  	}
+  
+ +	if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) {
+ +		int idx, dbi = 0;
+ +
+-+		if (!rdev->ops->set_antenna_gain) {
+-+			result = -EOPNOTSUPP;
+-+			goto bad_res;
+-+		}
+++		if (!rdev->ops->set_antenna_gain)
+++			return -EOPNOTSUPP;
+ +
+ +		idx = NL80211_ATTR_WIPHY_ANTENNA_GAIN;
+ +		dbi = nla_get_u32(info->attrs[idx]);
+ +
+ +		result = rdev->ops->set_antenna_gain(&rdev->wiphy, dbi);
+ +		if (result)
+-+			goto bad_res;
+++			return result;
+ +	}
+ +
+  	if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
+diff --git a/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch b/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch
+index 30aa9ee..b84a991 100644
+--- a/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch
++++ b/package/mac80211/patches/523-ath9k_use_configured_antenna_gain.patch
+@@ -1,6 +1,6 @@
+ --- a/drivers/net/wireless/ath/ath.h
+ +++ b/drivers/net/wireless/ath/ath.h
+-@@ -74,6 +74,7 @@ struct ath_regulatory {
++@@ -83,6 +83,7 @@ struct ath_regulatory {
+  	u16 max_power_level;
+  	u16 current_rd;
+  	int16_t power_limit;
+@@ -10,7 +10,7 @@
+  
+ --- a/drivers/net/wireless/ath/ath9k/hw.c
+ +++ b/drivers/net/wireless/ath/ath9k/hw.c
+-@@ -2721,7 +2721,7 @@ void ath9k_hw_apply_txpower(struct ath_h
++@@ -2720,7 +2720,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
+-@@ -1371,7 +1371,10 @@ static int ath9k_config(struct ieee80211
++@@ -1370,7 +1370,10 @@ static int ath9k_config(struct ieee80211
+  	}
+  
+  	if (changed & IEEE80211_CONF_CHANGE_POWER) {
+diff --git a/package/mac80211/patches/530-ath9k_extra_leds.patch b/package/mac80211/patches/530-ath9k_extra_leds.patch
+index 59f78d9..fb24f03 100644
+--- a/package/mac80211/patches/530-ath9k_extra_leds.patch
++++ b/package/mac80211/patches/530-ath9k_extra_leds.patch
+@@ -1,6 +1,6 @@
+ --- a/drivers/net/wireless/ath/ath9k/ath9k.h
+ +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+-@@ -563,6 +563,9 @@ static inline int ath9k_dump_btcoex(stru
++@@ -554,6 +554,9 @@ static inline int ath9k_dump_btcoex(stru
+  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)
+  {
+-@@ -710,6 +713,13 @@ enum sc_op_flags {
++@@ -692,6 +695,13 @@ void ath_ant_comb_scan(struct ath_softc 
+  #define PS_BEACON_SYNC            BIT(4)
+  #define PS_WAIT_FOR_ANI           BIT(5)
+  
+@@ -24,8 +24,8 @@
+  struct ath_softc {
+  	struct ieee80211_hw *hw;
+  	struct device *dev;
+-@@ -751,9 +761,8 @@ struct ath_softc {
+- 	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
++@@ -731,9 +741,8 @@ struct ath_softc {
++ 	struct ath_beacon beacon;
+  
+  #ifdef CPTCFG_MAC80211_LEDS
+ -	bool led_registered;
+@@ -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
+-@@ -1018,7 +1018,7 @@ int ath9k_init_device(u16 devid, struct 
++@@ -806,7 +806,7 @@ int ath9k_init_device(u16 devid, struct 
+  
+  #ifdef CPTCFG_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
+-@@ -1573,6 +1573,61 @@ static const struct file_operations fops
++@@ -1577,6 +1577,61 @@ static const struct file_operations fops
+  	.llseek = default_llseek,
+  };
+  
+@@ -235,7 +235,7 @@
+  
+  int ath9k_init_debug(struct ath_hw *ah)
+  {
+-@@ -1597,6 +1652,10 @@ int ath9k_init_debug(struct ath_hw *ah)
++@@ -1601,6 +1656,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);
+diff --git a/package/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/mac80211/patches/542-ath9k_debugfs_diag.patch
+index e1b6ff1..44aa905 100644
+--- a/package/mac80211/patches/542-ath9k_debugfs_diag.patch
++++ b/package/mac80211/patches/542-ath9k_debugfs_diag.patch
+@@ -1,6 +1,6 @@
+ --- a/drivers/net/wireless/ath/ath9k/debug.c
+ +++ b/drivers/net/wireless/ath/ath9k/debug.c
+-@@ -1629,6 +1629,50 @@ static const struct file_operations fops
++@@ -1633,6 +1633,50 @@ static const struct file_operations fops
+  #endif
+  
+  
+@@ -51,7 +51,7 @@
+  int ath9k_init_debug(struct ath_hw *ah)
+  {
+  	struct ath_common *common = ath9k_hw_common(ah);
+-@@ -1656,6 +1700,8 @@ int ath9k_init_debug(struct ath_hw *ah)
++@@ -1660,6 +1704,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
+@@ -94,7 +94,7 @@
+  struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
+ --- a/drivers/net/wireless/ath/ath9k/hw.c
+ +++ b/drivers/net/wireless/ath/ath9k/hw.c
+-@@ -1735,6 +1735,20 @@ fail:
++@@ -1734,6 +1734,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)
+  {
+-@@ -1940,6 +1954,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
++@@ -1939,6 +1953,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+  		ar9003_hw_disable_phy_restart(ah);
+  
+  	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
+-@@ -602,6 +602,11 @@ irqreturn_t ath_isr(int irq, void *dev)
++@@ -603,6 +603,11 @@ irqreturn_t ath_isr(int irq, void *dev)
+  	ath9k_debug_sync_cause(sc, sync_cause);
+  	status &= ah->imask;	/* discard unasked-for bits */
+  
+diff --git a/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch b/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch
+index d26a5af..e2e18c9 100644
+--- a/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch
++++ b/package/mac80211/patches/543-ath9k-allow-to-disable-bands-via-platform-data.patch
+@@ -11,7 +11,7 @@
+  	int (*external_reset)(void);
+ --- a/drivers/net/wireless/ath/ath9k/hw.c
+ +++ b/drivers/net/wireless/ath/ath9k/hw.c
+-@@ -2328,17 +2328,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
++@@ -2327,17 +2327,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
+  	}
+  
+  	eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
+@@ -58,7 +58,7 @@
+  };
+ --- a/drivers/net/wireless/ath/ath9k/init.c
+ +++ b/drivers/net/wireless/ath/ath9k/init.c
+-@@ -722,6 +722,8 @@ static int ath9k_init_softc(u16 devid, s
++@@ -518,6 +518,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;
+diff --git a/package/mac80211/patches/550-ath9k_entropy_from_adc.patch b/package/mac80211/patches/550-ath9k_entropy_from_adc.patch
+index b59c362..54f5ced 100644
+--- a/package/mac80211/patches/550-ath9k_entropy_from_adc.patch
++++ b/package/mac80211/patches/550-ath9k_entropy_from_adc.patch
+@@ -55,7 +55,7 @@
+  	ops->spectral_scan_config = ar9003_hw_spectral_scan_config;
+ --- a/drivers/net/wireless/ath/ath9k/init.c
+ +++ b/drivers/net/wireless/ath/ath9k/init.c
+-@@ -846,7 +846,8 @@ static void ath9k_init_txpower_limits(st
++@@ -643,7 +643,8 @@ static void ath9k_init_txpower_limits(st
+  	if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
+  		ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
+  
+@@ -64,8 +64,8 @@
+ +		ah->curchan = curchan;
+  }
+  
+- void ath9k_reload_chainmask_settings(struct ath_softc *sc)
+-@@ -980,6 +981,18 @@ static void ath9k_set_hw_capab(struct at
++ static const struct ieee80211_iface_limit if_limits[] = {
++@@ -768,6 +769,18 @@ static void ath9k_set_hw_capab(struct at
+  	SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
+  }
+  
+@@ -84,7 +84,7 @@
+  int ath9k_init_device(u16 devid, struct ath_softc *sc,
+  		    const struct ath_bus_ops *bus_ops)
+  {
+-@@ -1025,6 +1038,8 @@ int ath9k_init_device(u16 devid, struct 
++@@ -813,6 +826,8 @@ int ath9k_init_device(u16 devid, struct 
+  		ARRAY_SIZE(ath9k_tpt_blink));
+  #endif
+  
+@@ -110,7 +110,7 @@
+  static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
+ --- a/drivers/net/wireless/ath/ath9k/link.c
+ +++ b/drivers/net/wireless/ath/ath9k/link.c
+-@@ -307,6 +307,11 @@ void ath_ani_calibrate(unsigned long dat
++@@ -308,6 +308,11 @@ void ath_ani_calibrate(unsigned long dat
+  	unsigned int timestamp = jiffies_to_msecs(jiffies);
+  	u32 cal_interval, short_cal_interval, long_cal_interval;
+  	unsigned long flags;
+diff --git a/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch b/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch
+index ffffe0c..579a633 100644
+--- a/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch
++++ b/package/mac80211/patches/551-ath9k_p2p_ifcomb.patch
+@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ 
+ --- a/drivers/net/wireless/ath/ath9k/init.c
+ +++ b/drivers/net/wireless/ath/ath9k/init.c
+-@@ -863,15 +863,15 @@ void ath9k_reload_chainmask_settings(str
++@@ -649,15 +649,15 @@ static void ath9k_init_txpower_limits(st
+  
+  static const struct ieee80211_iface_limit if_limits[] = {
+  	{ .max = 2048,	.types = BIT(NL80211_IFTYPE_STATION) |
+diff --git a/package/mac80211/patches/552-ath9k_p2p_ps_support.patch b/package/mac80211/patches/552-ath9k_p2p_ps_support.patch
+index 4a61db3..1bd0a54 100644
+--- a/package/mac80211/patches/552-ath9k_p2p_ps_support.patch
++++ b/package/mac80211/patches/552-ath9k_p2p_ps_support.patch
+@@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+  	return true;
+  }
+  
+-@@ -1126,6 +1128,8 @@ static int ath9k_add_interface(struct ie
++@@ -1128,6 +1130,8 @@ static int ath9k_add_interface(struct ie
+  	if (ath9k_uses_beacons(vif->type))
+  		ath9k_beacon_assign_slot(sc, vif);
+  
+@@ -36,7 +36,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+  	an->sc = sc;
+  	an->sta = NULL;
+  	an->vif = vif;
+-@@ -1170,6 +1174,29 @@ static int ath9k_change_interface(struct
++@@ -1172,6 +1176,29 @@ static int ath9k_change_interface(struct
+  	return 0;
+  }
+  
+@@ -66,7 +66,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+  static void ath9k_remove_interface(struct ieee80211_hw *hw,
+  				   struct ieee80211_vif *vif)
+  {
+-@@ -1181,6 +1208,13 @@ static void ath9k_remove_interface(struc
++@@ -1183,6 +1210,13 @@ static void ath9k_remove_interface(struc
+  
+  	mutex_lock(&sc->mutex);
+  
+@@ -80,7 +80,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+  	sc->nvifs--;
+  	sc->tx99_vif = NULL;
+  
+-@@ -1649,6 +1683,70 @@ static void ath9k_bss_assoc_iter(void *d
++@@ -1649,6 +1683,72 @@ static void ath9k_bss_assoc_iter(void *d
+  		ath9k_set_assoc_state(sc, vif);
+  }
+  
+@@ -130,6 +130,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ +void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
+ +{
+ +	struct ath_vif *avp = (void *)vif->drv_priv;
+++	unsigned long flags;
+ +	u32 tsf;
+ +
+ +	if (!sc->p2p_ps_timer)
+@@ -140,18 +141,19 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ +
+ +	sc->p2p_ps_vif = avp;
+ +
+-+	if (sc->ps_flags & PS_BEACON_SYNC)
+-+		return;
+-+
+-+	tsf = ath9k_hw_gettsf32(sc->sc_ah);
+-+	ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
+-+	ath9k_update_p2p_ps_timer(sc, avp);
+++	spin_lock_irqsave(&sc->sc_pm_lock, flags);
+++	if (!(sc->ps_flags & PS_BEACON_SYNC)) {
+++		tsf = ath9k_hw_gettsf32(sc->sc_ah);
+++		ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
+++		ath9k_update_p2p_ps_timer(sc, avp);
+++	}
+++	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+ +}
+ +
+  static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
+  				   struct ieee80211_vif *vif,
+  				   struct ieee80211_bss_conf *bss_conf,
+-@@ -1723,6 +1821,12 @@ static void ath9k_bss_info_changed(struc
++@@ -1723,6 +1823,12 @@ static void ath9k_bss_info_changed(struc
+  		}
+  	}
+  
+@@ -166,7 +168,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+  
+ --- a/drivers/net/wireless/ath/ath9k/ath9k.h
+ +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+-@@ -115,6 +115,9 @@ int ath_descdma_setup(struct ath_softc *
++@@ -114,6 +114,9 @@ int ath_descdma_setup(struct ath_softc *
+  #define ATH_TXFIFO_DEPTH           8
+  #define ATH_TX_ERROR               0x01
+  
+@@ -176,7 +178,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+  #define IEEE80211_SEQ_SEQ_SHIFT    4
+  #define IEEE80211_SEQ_MAX          4096
+  #define IEEE80211_WEP_IVLEN        3
+-@@ -363,11 +366,15 @@ void ath9k_release_buffered_frames(struc
++@@ -366,11 +369,15 @@ void ath9k_release_buffered_frames(struc
+  /********/
+  
+  struct ath_vif {
+@@ -192,7 +194,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+  };
+  
+  struct ath9k_vif_iter_data {
+-@@ -472,6 +479,8 @@ int ath_update_survey_stats(struct ath_s
++@@ -463,6 +470,8 @@ int ath_update_survey_stats(struct ath_s
+  void ath_update_survey_nf(struct ath_softc *sc, int channel);
+  void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
+  void ath_ps_full_sleep(unsigned long data);
+@@ -201,19 +203,19 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+  
+  /**********/
+  /* BTCOEX */
+-@@ -741,6 +750,9 @@ struct ath_softc {
++@@ -723,6 +732,9 @@ struct ath_softc {
+  	struct completion paprd_complete;
+  	wait_queue_head_t tx_wait;
+  
+ +	struct ath_gen_timer *p2p_ps_timer;
+ +	struct ath_vif *p2p_ps_vif;
+ +
+- 	unsigned long sc_flags;
+  	unsigned long driver_data;
+  
++ 	u8 gtt_cnt;
+ --- a/drivers/net/wireless/ath/ath9k/init.c
+ +++ b/drivers/net/wireless/ath/ath9k/init.c
+-@@ -797,6 +797,9 @@ static int ath9k_init_softc(u16 devid, s
++@@ -593,6 +593,9 @@ static int ath9k_init_softc(u16 devid, s
+  	if (ret)
+  		goto err_btcoex;
+  
+@@ -223,7 +225,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+  	ath9k_cmn_init_crypto(sc->sc_ah);
+  	ath9k_init_misc(sc);
+  	ath_fill_led_pin(sc);
+-@@ -1082,6 +1085,9 @@ static void ath9k_deinit_softc(struct at
++@@ -870,6 +873,9 @@ static void ath9k_deinit_softc(struct at
+  {
+  	int i = 0;
+  
+diff --git a/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch b/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch
+index af94c9e..eddbc6c 100644
+--- a/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch
++++ b/package/mac80211/patches/566-ath9k-ar933x-usb-hang-workaround.patch
+@@ -1,6 +1,6 @@
+ --- a/drivers/net/wireless/ath/ath9k/hw.c
+ +++ b/drivers/net/wireless/ath/ath9k/hw.c
+-@@ -217,6 +217,19 @@ void ath9k_hw_get_channel_centers(struct
++@@ -216,6 +216,19 @@ void ath9k_hw_get_channel_centers(struct
+  		centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT);
+  }
+  
+@@ -20,7 +20,7 @@
+  /******************/
+  /* Chip Revisions */
+  /******************/
+-@@ -1337,6 +1350,9 @@ static bool ath9k_hw_set_reset(struct at
++@@ -1336,6 +1349,9 @@ static bool ath9k_hw_set_reset(struct at
+  	if (AR_SREV_9100(ah))
+  		udelay(50);
+  
+@@ -30,7 +30,7 @@
+  	return true;
+  }
+  
+-@@ -1436,6 +1452,9 @@ static bool ath9k_hw_chip_reset(struct a
++@@ -1435,6 +1451,9 @@ static bool ath9k_hw_chip_reset(struct a
+  		ar9003_hw_internal_regulator_apply(ah);
+  	ath9k_hw_init_pll(ah, chan);
+  
+@@ -40,7 +40,7 @@
+  	return true;
+  }
+  
+-@@ -1730,8 +1749,14 @@ static int ath9k_hw_do_fastcc(struct ath
++@@ -1729,8 +1748,14 @@ static int ath9k_hw_do_fastcc(struct ath
+  	if (AR_SREV_9271(ah))
+  		ar9002_hw_load_ani_reg(ah, chan);
+  
+@@ -55,7 +55,7 @@
+  	return -EINVAL;
+  }
+  
+-@@ -1959,6 +1984,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
++@@ -1958,6 +1983,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+  	if (AR_SREV_9565(ah) && common->bt_ant_diversity)
+  		REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
+  
+diff --git a/package/mac80211/patches/567-ath9k-qca953x-support.patch b/package/mac80211/patches/567-ath9k-qca953x-support.patch
+deleted file mode 100644
+index e73083a..0000000
+--- a/package/mac80211/patches/567-ath9k-qca953x-support.patch
++++ /dev/null
+@@ -1,124 +0,0 @@
+---- a/drivers/net/wireless/ath/ath9k/ahb.c
+-+++ b/drivers/net/wireless/ath/ath9k/ahb.c
+-@@ -39,6 +39,10 @@ static const struct platform_device_id a
+- 		.name = "qca955x_wmac",
+- 		.driver_data = AR9300_DEVID_QCA955X,
+- 	},
+-+	{
+-+		.name = "qca953x_wmac",
+-+		.driver_data = AR9300_DEVID_AR953X,
+-+	},
+- 	{},
+- };
+- 
+---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+-+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+-@@ -4792,43 +4792,54 @@ static void ar9003_hw_power_control_over
+- 
+- tempslope:
+- 	if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) {
+-+		u8 txmask = (eep->baseEepHeader.txrxMask & 0xf0) >> 4;
+-+
+- 		/*
+- 		 * AR955x has tempSlope register for each chain.
+- 		 * Check whether temp_compensation feature is enabled or not.
+- 		 */
+- 		if (eep->baseEepHeader.featureEnable & 0x1) {
+- 			if (frequency < 4000) {
+--				REG_RMW_FIELD(ah, AR_PHY_TPC_19,
+--					      AR_PHY_TPC_19_ALPHA_THERM,
+--					      eep->base_ext2.tempSlopeLow);
+--				REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
+--					      AR_PHY_TPC_19_ALPHA_THERM,
+--					      temp_slope);
+--				REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
+--					      AR_PHY_TPC_19_ALPHA_THERM,
+--					      eep->base_ext2.tempSlopeHigh);
+-+				if (txmask & BIT(0))
+-+					REG_RMW_FIELD(ah, AR_PHY_TPC_19,
+-+						      AR_PHY_TPC_19_ALPHA_THERM,
+-+						      eep->base_ext2.tempSlopeLow);
+-+				if (txmask & BIT(1))
+-+					REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
+-+						      AR_PHY_TPC_19_ALPHA_THERM,
+-+						      temp_slope);
+-+				if (txmask & BIT(2))
+-+					REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
+-+						      AR_PHY_TPC_19_ALPHA_THERM,
+-+						      eep->base_ext2.tempSlopeHigh);
+- 			} else {
+--				REG_RMW_FIELD(ah, AR_PHY_TPC_19,
+--					      AR_PHY_TPC_19_ALPHA_THERM,
+--					      temp_slope);
+--				REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
+--					      AR_PHY_TPC_19_ALPHA_THERM,
+--					      temp_slope1);
+--				REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
+--					      AR_PHY_TPC_19_ALPHA_THERM,
+--					      temp_slope2);
+-+				if (txmask & BIT(0))
+-+					REG_RMW_FIELD(ah, AR_PHY_TPC_19,
+-+						      AR_PHY_TPC_19_ALPHA_THERM,
+-+						      temp_slope);
+-+				if (txmask & BIT(1))
+-+					REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
+-+						      AR_PHY_TPC_19_ALPHA_THERM,
+-+						      temp_slope1);
+-+				if (txmask & BIT(2))
+-+					REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
+-+						      AR_PHY_TPC_19_ALPHA_THERM,
+-+						      temp_slope2);
+- 			}
+- 		} else {
+- 			/*
+- 			 * If temp compensation is not enabled,
+- 			 * set all registers to 0.
+- 			 */
+--			REG_RMW_FIELD(ah, AR_PHY_TPC_19,
+--				      AR_PHY_TPC_19_ALPHA_THERM, 0);
+--			REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
+--				      AR_PHY_TPC_19_ALPHA_THERM, 0);
+--			REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
+--				      AR_PHY_TPC_19_ALPHA_THERM, 0);
+-+			if (txmask & BIT(0))
+-+				REG_RMW_FIELD(ah, AR_PHY_TPC_19,
+-+					      AR_PHY_TPC_19_ALPHA_THERM, 0);
+-+			if (txmask & BIT(1))
+-+				REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
+-+					      AR_PHY_TPC_19_ALPHA_THERM, 0);
+-+			if (txmask & BIT(2))
+-+				REG_RMW_FIELD(ah, AR_PHY_TPC_19_B2,
+-+					      AR_PHY_TPC_19_ALPHA_THERM, 0);
+- 		}
+- 	} else {
+- 		REG_RMW_FIELD(ah, AR_PHY_TPC_19,
+---- a/drivers/net/wireless/ath/ath9k/hw.c
+-+++ b/drivers/net/wireless/ath/ath9k/hw.c
+-@@ -901,7 +901,7 @@ static void ath9k_hw_init_interrupt_mask
+- 		AR_IMR_RXORN |
+- 		AR_IMR_BCNMISC;
+- 
+--	if (AR_SREV_9340(ah) || AR_SREV_9550(ah))
+-+	if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah))
+- 		sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+- 
+- 	if (AR_SREV_9300_20_OR_LATER(ah)) {
+-@@ -3104,6 +3104,7 @@ static struct {
+- 	{ AR_SREV_VERSION_9462,         "9462" },
+- 	{ AR_SREV_VERSION_9550,         "9550" },
+- 	{ AR_SREV_VERSION_9565,         "9565" },
+-+	{ AR_SREV_VERSION_9531,         "9531" },
+- };
+- 
+- /* For devices with external radios */
+---- a/drivers/net/wireless/ath/ath9k/mac.c
+-+++ b/drivers/net/wireless/ath/ath9k/mac.c
+-@@ -837,7 +837,7 @@ void ath9k_hw_enable_interrupts(struct a
+- 		return;
+- 	}
+- 
+--	if (AR_SREV_9340(ah) || AR_SREV_9550(ah))
+-+	if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah))
+- 		sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+- 
+- 	async_mask = AR_INTR_MAC_IRQ;
+diff --git a/package/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch b/package/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch
+new file mode 100644
+index 0000000..d344957
+--- /dev/null
++++ b/package/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch
+@@ -0,0 +1,62 @@
++From 7a69da907de668fb22a30ae218062d6f081864ea Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sat, 17 Aug 2013 19:31:41 +0200
++Subject: [PATCH] rt2x00: rt2800lib: move rt2800_drv_data declaration into
++ rt2800lib.h
++
++The rt2800_drv_data structure contains driver specific
++information. Move the declaration into the rt2800lib.h
++header which is a more logical place for it. Also fix
++the comment style to avoid checkpatch warning.
++
++The patch contains no functional changes, it is in
++preparation for the next patch.
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++Changes since v1: ---
++---
++ drivers/net/wireless/rt2x00/rt2800.h    |   13 -------------
++ drivers/net/wireless/rt2x00/rt2800lib.h |   11 +++++++++++
++ 2 files changed, 11 insertions(+), 13 deletions(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800.h
+++++ b/drivers/net/wireless/rt2x00/rt2800.h
++@@ -2958,17 +2958,4 @@ enum rt2800_eeprom_word {
++  */
++ #define BCN_TBTT_OFFSET 64
++ 
++-/*
++- * RT2800 driver data structure
++- */
++-struct rt2800_drv_data {
++-	u8 calibration_bw20;
++-	u8 calibration_bw40;
++-	u8 bbp25;
++-	u8 bbp26;
++-	u8 txmixer_gain_24g;
++-	u8 txmixer_gain_5g;
++-	unsigned int tbtt_tick;
++-};
++-
++ #endif /* RT2800_H */
++--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
++@@ -20,6 +20,17 @@
++ #ifndef RT2800LIB_H
++ #define RT2800LIB_H
++ 
+++/* RT2800 driver data structure */
+++struct rt2800_drv_data {
+++	u8 calibration_bw20;
+++	u8 calibration_bw40;
+++	u8 bbp25;
+++	u8 bbp26;
+++	u8 txmixer_gain_24g;
+++	u8 txmixer_gain_5g;
+++	unsigned int tbtt_tick;
+++};
+++
++ struct rt2800_ops {
++ 	void (*register_read)(struct rt2x00_dev *rt2x00dev,
++ 			      const unsigned int offset, u32 *value);
+diff --git a/package/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch b/package/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch
+new file mode 100644
+index 0000000..3b11b15
+--- /dev/null
++++ b/package/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch
+@@ -0,0 +1,80 @@
++From a7f268af31dddf763fe3dbe9cbf96ea77e0540e0 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sat, 17 Aug 2013 19:31:41 +0200
++Subject: [PATCH] rt2x00: rt2800lib: introduce RT2800_HAS_HIGH_SHARED_MEM flag
++
++Some chipsets have more than 16KB of shared memory.
++Introduce a new rt2800 specific flag to indicate that
++and add a helper function which helps to check the
++presence of the new flag.
++
++Also enable the new flag for the RT3593 chipset which
++has 24KB of shared memory. The flag can also be used
++for other chipsets, but none of those has been tested
++yet.
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++Changes since v1:
++  - don't enable the new flag for RT3071 and RT5592
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    4 ++++
++ drivers/net/wireless/rt2x00/rt2800lib.h |   13 +++++++++++++
++ 2 files changed, 17 insertions(+)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -7712,6 +7712,7 @@ static int rt2800_probe_rt(struct rt2x00
++ 
++ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
++ {
+++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++ 	int retval;
++ 	u32 reg;
++ 
++@@ -7719,6 +7720,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r
++ 	if (retval)
++ 		return retval;
++ 
+++	if (rt2x00_rt(rt2x00dev, RT3593))
+++		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
+++
++ 	/*
++ 	 * Allocate eeprom data.
++ 	 */
++--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
++@@ -20,6 +20,10 @@
++ #ifndef RT2800LIB_H
++ #define RT2800LIB_H
++ 
+++enum rt2800_flag {
+++	RT2800_HAS_HIGH_SHARED_MEM,
+++};
+++
++ /* RT2800 driver data structure */
++ struct rt2800_drv_data {
++ 	u8 calibration_bw20;
++@@ -29,6 +33,8 @@ struct rt2800_drv_data {
++ 	u8 txmixer_gain_24g;
++ 	u8 txmixer_gain_5g;
++ 	unsigned int tbtt_tick;
+++
+++	unsigned long rt2800_flags;
++ };
++ 
++ struct rt2800_ops {
++@@ -61,6 +67,13 @@ struct rt2800_ops {
++ 	__le32 *(*drv_get_txwi)(struct queue_entry *entry);
++ };
++ 
+++static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
+++{
+++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+++
+++	return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
+++}
+++
++ static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
++ 					const unsigned int offset,
++ 					u32 *value)
+diff --git a/package/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch b/package/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch
+new file mode 100644
+index 0000000..879b4cc
+--- /dev/null
++++ b/package/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch
+@@ -0,0 +1,531 @@
++From 250a1b520cd7fdc0df4fc3fedea9066913f49ecf Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sat, 17 Aug 2013 19:31:42 +0200
++Subject: [PATCH] rt2x00: rt2800: serialize shared memory access
++
++The shared memory of the rt2800 devices is accessible
++through the register offset range between 0x4000 and
++0x8000. The size of this range is 16KB only and on
++devices which have more than 16KB of shared memory either
++the low or the high part of the memory is accessible at a
++time.
++
++Serialize all accesses to the shared memory by a mutex,
++in order to avoid concurrent use of that.
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++Changes since v1: ---
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c  |   55 +++++++++++++++++++++++++++++-
++ drivers/net/wireless/rt2x00/rt2800lib.h  |   32 +++++++++++++++++
++ drivers/net/wireless/rt2x00/rt2800mmio.c |   26 ++++++++++++++
++ drivers/net/wireless/rt2x00/rt2800mmio.h |    4 +++
++ drivers/net/wireless/rt2x00/rt2800pci.c  |   14 ++++++++
++ drivers/net/wireless/rt2x00/rt2800soc.c  |    3 ++
++ drivers/net/wireless/rt2x00/rt2800usb.c  |   31 +++++++++++++++++
++ 7 files changed, 164 insertions(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -451,11 +451,13 @@ void rt2800_mcu_request(struct rt2x00_de
++ 		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
++ 		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG0, arg0);
++ 		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG1, arg1);
+++		rt2800_shared_mem_lock(rt2x00dev);
++ 		rt2800_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg);
++ 
++ 		reg = 0;
++ 		rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
++ 		rt2800_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg);
+++		rt2800_shared_mem_unlock(rt2x00dev);
++ 	}
++ 
++ 	mutex_unlock(&rt2x00dev->csr_mutex);
++@@ -674,7 +676,9 @@ int rt2800_load_firmware(struct rt2x00_d
++ 	 * Wait for device to stabilize.
++ 	 */
++ 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+++		rt2800_shared_mem_lock(rt2x00dev);
++ 		rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+++		rt2800_shared_mem_unlock(rt2x00dev);
++ 		if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
++ 			break;
++ 		msleep(1);
++@@ -694,10 +698,16 @@ int rt2800_load_firmware(struct rt2x00_d
++ 	/*
++ 	 * Initialize firmware.
++ 	 */
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
++ 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+++	rt2800_shared_mem_unlock(rt2x00dev);
+++
++ 	if (rt2x00_is_usb(rt2x00dev)) {
+++		rt2800_shared_mem_lock(rt2x00dev);
++ 		rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
+++		rt2800_shared_mem_unlock(rt2x00dev);
+++
++ 		rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
++ 	}
++ 	msleep(1);
++@@ -1001,8 +1011,10 @@ void rt2800_write_beacon(struct queue_en
++ 
++ 	beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
++ 
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
++ 				   entry->skb->len + padding_len);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 	/*
++ 	 * Enable beaconing again.
++@@ -1027,6 +1039,8 @@ static inline void rt2800_clear_beacon_r
++ 
++ 	beacon_base = rt2800_hw_beacon_base(rt2x00dev, index);
++ 
+++	rt2800_shared_mem_lock(rt2x00dev);
+++
++ 	/*
++ 	 * For the Beacon base registers we only need to clear
++ 	 * the whole TXWI which (when set to 0) will invalidate
++@@ -1034,6 +1048,8 @@ static inline void rt2800_clear_beacon_r
++ 	 */
++ 	for (i = 0; i < txwi_desc_size; i += sizeof(__le32))
++ 		rt2800_register_write(rt2x00dev, beacon_base + i, 0);
+++
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ }
++ 
++ void rt2800_clear_beacon(struct queue_entry *entry)
++@@ -1217,7 +1233,9 @@ static void rt2800_delete_wcid_attr(stru
++ {
++ 	u32 offset;
++ 	offset = MAC_WCID_ATTR_ENTRY(wcid);
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2800_register_write(rt2x00dev, offset, 0);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ }
++ 
++ static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev,
++@@ -1230,11 +1248,13 @@ static void rt2800_config_wcid_attr_bssi
++ 	 * The BSS Idx numbers is split in a main value of 3 bits,
++ 	 * and a extended field for adding one additional bit to the value.
++ 	 */
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2800_register_read(rt2x00dev, offset, &reg);
++ 	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX, (bssidx & 0x7));
++ 	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT,
++ 			   (bssidx & 0x8) >> 3);
++ 	rt2800_register_write(rt2x00dev, offset, reg);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ }
++ 
++ static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
++@@ -1247,6 +1267,7 @@ static void rt2800_config_wcid_attr_ciph
++ 
++ 	offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
++ 
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	if (crypto->cmd == SET_KEY) {
++ 		rt2800_register_read(rt2x00dev, offset, &reg);
++ 		rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
++@@ -1271,6 +1292,7 @@ static void rt2800_config_wcid_attr_ciph
++ 		rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0);
++ 		rt2800_register_write(rt2x00dev, offset, reg);
++ 	}
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 	offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
++ 
++@@ -1280,8 +1302,11 @@ static void rt2800_config_wcid_attr_ciph
++ 	    (crypto->cipher == CIPHER_AES))
++ 		iveiv_entry.iv[3] |= 0x20;
++ 	iveiv_entry.iv[3] |= key->keyidx << 6;
+++
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2800_register_multiwrite(rt2x00dev, offset,
++ 				      &iveiv_entry, sizeof(iveiv_entry));
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ }
++ 
++ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
++@@ -1304,8 +1329,11 @@ int rt2800_config_shared_key(struct rt2x
++ 		       sizeof(key_entry.rx_mic));
++ 
++ 		offset = SHARED_KEY_ENTRY(key->hw_key_idx);
+++
+++		rt2800_shared_mem_lock(rt2x00dev);
++ 		rt2800_register_multiwrite(rt2x00dev, offset,
++ 					      &key_entry, sizeof(key_entry));
+++		rt2800_shared_mem_unlock(rt2x00dev);
++ 	}
++ 
++ 	/*
++@@ -1320,10 +1348,12 @@ int rt2800_config_shared_key(struct rt2x
++ 
++ 	offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
++ 
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2800_register_read(rt2x00dev, offset, &reg);
++ 	rt2x00_set_field32(&reg, field,
++ 			   (crypto->cmd == SET_KEY) * crypto->cipher);
++ 	rt2800_register_write(rt2x00dev, offset, reg);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 	/*
++ 	 * Update WCID information
++@@ -1393,8 +1423,11 @@ int rt2800_config_pairwise_key(struct rt
++ 		       sizeof(key_entry.rx_mic));
++ 
++ 		offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
+++
+++		rt2800_shared_mem_lock(rt2x00dev);
++ 		rt2800_register_multiwrite(rt2x00dev, offset,
++ 					      &key_entry, sizeof(key_entry));
+++		rt2800_shared_mem_unlock(rt2x00dev);
++ 	}
++ 
++ 	/*
++@@ -4876,14 +4909,19 @@ static int rt2800_init_registers(struct
++ 	/*
++ 	 * ASIC will keep garbage value after boot, clear encryption keys.
++ 	 */
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	for (i = 0; i < 4; i++)
++ 		rt2800_register_write(rt2x00dev,
++ 					 SHARED_KEY_MODE_ENTRY(i), 0);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 	for (i = 0; i < 256; i++) {
++ 		rt2800_config_wcid(rt2x00dev, NULL, i);
++ 		rt2800_delete_wcid_attr(rt2x00dev, i);
+++
+++		rt2800_shared_mem_lock(rt2x00dev);
++ 		rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
+++		rt2800_shared_mem_unlock(rt2x00dev);
++ 	}
++ 
++ 	/*
++@@ -5009,8 +5047,10 @@ static int rt2800_wait_bbp_ready(struct
++ 	 * BBP was enabled after firmware was loaded,
++ 	 * but we need to reactivate it now.
++ 	 */
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
++ 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ 	msleep(1);
++ 
++ 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
++@@ -6706,11 +6746,19 @@ int rt2800_enable_radio(struct rt2x00_de
++ 	/*
++ 	 * Send signal during boot time to initialize firmware.
++ 	 */
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
++ 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
++-	if (rt2x00_is_usb(rt2x00dev))
+++	rt2800_shared_mem_unlock(rt2x00dev);
+++
+++	if (rt2x00_is_usb(rt2x00dev)) {
+++		rt2800_shared_mem_lock(rt2x00dev);
++ 		rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
+++		rt2800_shared_mem_unlock(rt2x00dev);
+++	}
+++
++ 	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
+++
++ 	msleep(1);
++ 
++ 	/*
++@@ -7716,6 +7764,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
++ 	int retval;
++ 	u32 reg;
++ 
+++	rt2800_shared_mem_init_lock(rt2x00dev);
+++
++ 	retval = rt2800_probe_rt(rt2x00dev);
++ 	if (retval)
++ 		return retval;
++@@ -7795,8 +7845,11 @@ void rt2800_get_tkip_seq(struct ieee8021
++ 	u32 offset;
++ 
++ 	offset = MAC_IVEIV_ENTRY(hw_key_idx);
+++
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2800_register_multiread(rt2x00dev, offset,
++ 				      &iveiv_entry, sizeof(iveiv_entry));
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 	memcpy(iv16, &iveiv_entry.iv[0], sizeof(*iv16));
++ 	memcpy(iv32, &iveiv_entry.iv[4], sizeof(*iv32));
++--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
++@@ -35,6 +35,11 @@ struct rt2800_drv_data {
++ 	unsigned int tbtt_tick;
++ 
++ 	unsigned long rt2800_flags;
+++
+++	union {
+++		spinlock_t spin;
+++		struct mutex mutex;
+++	} shmem_lock;
++ };
++ 
++ struct rt2800_ops {
++@@ -65,6 +70,10 @@ struct rt2800_ops {
++ 				  const u8 *data, const size_t len);
++ 	int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
++ 	__le32 *(*drv_get_txwi)(struct queue_entry *entry);
+++
+++	void (*shmem_init_lock)(struct rt2x00_dev *rt2x00dev);
+++	void (*shmem_lock)(struct rt2x00_dev *rt2x00dev);
+++	void (*shmem_unlock)(struct rt2x00_dev *rt2x00dev);
++ };
++ 
++ static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
++@@ -74,6 +83,29 @@ static inline bool rt2800_has_high_share
++ 	return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
++ }
++ 
+++static inline void rt2800_shared_mem_init_lock(struct rt2x00_dev *rt2x00dev)
+++{
+++	const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
+++
+++	rt2800ops->shmem_init_lock(rt2x00dev);
+++}
+++
+++static inline void rt2800_shared_mem_lock(struct rt2x00_dev *rt2x00dev)
+++{
+++	const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
+++
+++	if (rt2800_has_high_shared_mem(rt2x00dev))
+++		rt2800ops->shmem_lock(rt2x00dev);
+++}
+++
+++static inline void rt2800_shared_mem_unlock(struct rt2x00_dev *rt2x00dev)
+++{
+++	const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
+++
+++	if (rt2800_has_high_shared_mem(rt2x00dev))
+++		rt2800ops->shmem_unlock(rt2x00dev);
+++}
+++
++ static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
++ 					const unsigned int offset,
++ 					u32 *value)
++--- a/drivers/net/wireless/rt2x00/rt2800mmio.c
+++++ b/drivers/net/wireless/rt2x00/rt2800mmio.c
++@@ -820,8 +820,10 @@ int rt2800mmio_init_registers(struct rt2
++ 	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
++ 	rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
++ 
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
++ 	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 	if (rt2x00_is_pcie(rt2x00dev) &&
++ 	    (rt2x00_rt(rt2x00dev, RT3090) ||
++@@ -865,6 +867,30 @@ int rt2800mmio_enable_radio(struct rt2x0
++ }
++ EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio);
++ 
+++void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev)
+++{
+++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+++
+++	spin_lock_init(&drv_data->shmem_lock.spin);
+++}
+++EXPORT_SYMBOL_GPL(rt2800mmio_shmem_init_lock);
+++
+++void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev)
+++{
+++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+++
+++	spin_lock_bh(&drv_data->shmem_lock.spin);
+++}
+++EXPORT_SYMBOL_GPL(rt2800mmio_shmem_lock);
+++
+++void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev)
+++{
+++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+++
+++	spin_unlock_bh(&drv_data->shmem_lock.spin);
+++}
+++EXPORT_SYMBOL_GPL(rt2800mmio_shmem_unlock);
+++
++ MODULE_AUTHOR(DRV_PROJECT);
++ MODULE_VERSION(DRV_VERSION);
++ MODULE_DESCRIPTION("rt2800 MMIO library");
++--- a/drivers/net/wireless/rt2x00/rt2800mmio.h
+++++ b/drivers/net/wireless/rt2x00/rt2800mmio.h
++@@ -160,4 +160,8 @@ int rt2800mmio_init_registers(struct rt2
++ /* Device state switch handlers. */
++ int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev);
++ 
+++void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev);
+++void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev);
+++void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev);
+++
++ #endif /* RT2800MMIO_H */
++--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++++ b/drivers/net/wireless/rt2x00/rt2800pci.c
++@@ -69,7 +69,9 @@ static void rt2800pci_mcu_status(struct
++ 		return;
++ 
++ 	for (i = 0; i < 200; i++) {
+++		rt2800_shared_mem_lock(rt2x00dev);
++ 		rt2x00mmio_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
+++		rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 		if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) ||
++ 		    (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) ||
++@@ -83,8 +85,10 @@ static void rt2800pci_mcu_status(struct
++ 	if (i == 200)
++ 		rt2x00_err(rt2x00dev, "MCU request failed, no response from hardware\n");
++ 
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
++ 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ }
++ 
++ static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
++@@ -184,6 +188,8 @@ static int rt2800pci_write_firmware(stru
++ 	 */
++ 	reg = 0;
++ 	rt2x00_set_field32(&reg, PBF_SYS_CTRL_HOST_RAM_WRITE, 1);
+++
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
++ 
++ 	/*
++@@ -197,6 +203,7 @@ static int rt2800pci_write_firmware(stru
++ 
++ 	rt2x00mmio_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
++ 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 	return 0;
++ }
++@@ -213,8 +220,10 @@ static int rt2800pci_enable_radio(struct
++ 		return retval;
++ 
++ 	/* After resume MCU_BOOT_SIGNAL will trash these. */
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
++ 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 	rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02);
++ 	rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF);
++@@ -233,10 +242,12 @@ static int rt2800pci_set_state(struct rt
++ 				   0, 0x02);
++ 		rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP);
++ 	} else if (state == STATE_SLEEP) {
+++		rt2800_shared_mem_lock(rt2x00dev);
++ 		rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS,
++ 					  0xffffffff);
++ 		rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID,
++ 					  0xffffffff);
+++		rt2800_shared_mem_unlock(rt2x00dev);
++ 		rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP,
++ 				   0xff, 0x01);
++ 	}
++@@ -337,6 +348,9 @@ static const struct rt2800_ops rt2800pci
++ 	.drv_write_firmware	= rt2800pci_write_firmware,
++ 	.drv_init_registers	= rt2800mmio_init_registers,
++ 	.drv_get_txwi		= rt2800mmio_get_txwi,
+++	.shmem_init_lock	= rt2800mmio_shmem_init_lock,
+++	.shmem_lock		= rt2800mmio_shmem_lock,
+++	.shmem_unlock		= rt2800mmio_shmem_unlock,
++ };
++ 
++ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
++--- a/drivers/net/wireless/rt2x00/rt2800soc.c
+++++ b/drivers/net/wireless/rt2x00/rt2800soc.c
++@@ -176,6 +176,9 @@ static const struct rt2800_ops rt2800soc
++ 	.drv_write_firmware	= rt2800soc_write_firmware,
++ 	.drv_init_registers	= rt2800mmio_init_registers,
++ 	.drv_get_txwi		= rt2800mmio_get_txwi,
+++	.shmem_init_lock	= rt2800mmio_shmem_init_lock,
+++	.shmem_lock		= rt2800mmio_shmem_lock,
+++	.shmem_unlock		= rt2800mmio_shmem_unlock,
++ };
++ 
++ static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
++--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++++ b/drivers/net/wireless/rt2x00/rt2800usb.c
++@@ -51,6 +51,27 @@ static bool rt2800usb_hwcrypt_disabled(s
++ 	return modparam_nohwcrypt;
++ }
++ 
+++static void rt2800usb_shmem_init_lock(struct rt2x00_dev *rt2x00dev)
+++{
+++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+++
+++	mutex_init(&drv_data->shmem_lock.mutex);
+++}
+++
+++static void rt2800usb_shmem_lock(struct rt2x00_dev *rt2x00dev)
+++{
+++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+++
+++	mutex_lock(&drv_data->shmem_lock.mutex);
+++}
+++
+++static void rt2800usb_shmem_unlock(struct rt2x00_dev *rt2x00dev)
+++{
+++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+++
+++	mutex_unlock(&drv_data->shmem_lock.mutex);
+++}
+++
++ /*
++  * Queue handlers.
++  */
++@@ -260,8 +281,10 @@ static int rt2800usb_write_firmware(stru
++ 	rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
++ 				      data + offset, length);
++ 
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
++ 	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 	/*
++ 	 * Send firmware request to device to load firmware,
++@@ -276,7 +299,10 @@ static int rt2800usb_write_firmware(stru
++ 	}
++ 
++ 	msleep(10);
+++
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 	return 0;
++ }
++@@ -294,8 +320,10 @@ static int rt2800usb_init_registers(stru
++ 	if (rt2800_wait_csr_ready(rt2x00dev))
++ 		return -EBUSY;
++ 
+++	rt2800_shared_mem_lock(rt2x00dev);
++ 	rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
++ 	rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
+++	rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 	reg = 0;
++ 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
++@@ -810,6 +838,9 @@ static const struct rt2800_ops rt2800usb
++ 	.drv_write_firmware	= rt2800usb_write_firmware,
++ 	.drv_init_registers	= rt2800usb_init_registers,
++ 	.drv_get_txwi		= rt2800usb_get_txwi,
+++	.shmem_init_lock	= rt2800usb_shmem_init_lock,
+++	.shmem_lock		= rt2800usb_shmem_lock,
+++	.shmem_unlock		= rt2800usb_shmem_unlock,
++ };
++ 
++ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
+diff --git a/package/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch b/package/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch
+new file mode 100644
+index 0000000..38dbb43
+--- /dev/null
++++ b/package/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch
+@@ -0,0 +1,131 @@
++From dcfe3dd46242050f100162dce2bcad24d2c942c6 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sat, 17 Aug 2013 19:31:42 +0200
++Subject: [PATCH] rt2x00: rt2800lib: fix beacon generation on RT3593
++
++On the RT3593 chipset, the beacon registers are located
++in the high 8KB part of the shared memory.
++
++The high part of the shared memory is only accessible
++if it is explicitly selected. Add a helper function
++in order to be able to control the SHR_MSEL bit in
++the PBF_SYS_CTRL register. Also add a few more helper
++functions and use those to select the correct part of
++the shared memory before and after accessing the beacon
++registers.
++
++The base addresses of the beacon registers are also
++different from the actually used values, so fix the
++'rt2800_hw_beacon_base' function to return the correct
++values.
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++Changes since v1: ---
++---
++ drivers/net/wireless/rt2x00/rt2800.h    |    3 +++
++ drivers/net/wireless/rt2x00/rt2800lib.c |   44 +++++++++++++++++++++++++++++++
++ 2 files changed, 47 insertions(+)
++
++--- a/drivers/net/wireless/rt2x00/rt2800.h
+++++ b/drivers/net/wireless/rt2x00/rt2800.h
++@@ -572,6 +572,7 @@
++ #define PBF_SYS_CTRL			0x0400
++ #define PBF_SYS_CTRL_READY		FIELD32(0x00000080)
++ #define PBF_SYS_CTRL_HOST_RAM_WRITE	FIELD32(0x00010000)
+++#define PBF_SYS_CTRL_SHR_MSEL		FIELD32(0x00080000)
++ 
++ /*
++  * HOST-MCU shared memory
++@@ -2024,6 +2025,8 @@ struct mac_iveiv_entry {
++ 	  (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \
++ 	  (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))))
++ 
+++#define HW_BEACON_BASE_HIGH(__index)	(0x4000 + (__index) * 512)
+++
++ #define BEACON_BASE_TO_OFFSET(_base)	(((_base) - 0x4000) / 64)
++ 
++ /*
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -82,6 +82,39 @@ static inline bool rt2800_is_305x_soc(st
++ 	return false;
++ }
++ 
+++static inline void rt2800_shared_mem_select(struct rt2x00_dev *rt2x00dev,
+++					    bool high)
+++{
+++	u32 reg;
+++
+++	if (WARN_ON_ONCE(!rt2800_has_high_shared_mem(rt2x00dev)))
+++		return;
+++
+++	rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+++	rt2x00_set_field32(&reg, PBF_SYS_CTRL_SHR_MSEL, high);
+++	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
+++}
+++
+++static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev)
+++{
+++	if (rt2x00_rt(rt2x00dev, RT3593))
+++		return true;
+++
+++	return false;
+++}
+++
+++static inline void rt2800_select_beacon_mem(struct rt2x00_dev *rt2x00dev)
+++{
+++	if (rt2800_beacon_uses_high_mem(rt2x00dev))
+++		rt2800_shared_mem_select(rt2x00dev, true);
+++}
+++
+++static inline void rt2800_deselect_beacon_mem(struct rt2x00_dev *rt2x00dev)
+++{
+++	if (rt2800_beacon_uses_high_mem(rt2x00dev))
+++		rt2800_shared_mem_select(rt2x00dev, false);
+++}
+++
++ static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev,
++ 			     const unsigned int word, const u8 value)
++ {
++@@ -948,6 +981,9 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
++ static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
++ 					  unsigned int index)
++ {
+++	if (rt2x00_rt(rt2x00dev, RT3593))
+++		return HW_BEACON_BASE_HIGH(index);
+++
++ 	return HW_BEACON_BASE(index);
++ }
++ 
++@@ -1012,8 +1048,12 @@ void rt2800_write_beacon(struct queue_en
++ 	beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
++ 
++ 	rt2800_shared_mem_lock(rt2x00dev);
+++
+++	rt2800_select_beacon_mem(rt2x00dev);
++ 	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
++ 				   entry->skb->len + padding_len);
+++	rt2800_deselect_beacon_mem(rt2x00dev);
+++
++ 	rt2800_shared_mem_unlock(rt2x00dev);
++ 
++ 	/*
++@@ -1041,6 +1081,8 @@ static inline void rt2800_clear_beacon_r
++ 
++ 	rt2800_shared_mem_lock(rt2x00dev);
++ 
+++	rt2800_select_beacon_mem(rt2x00dev);
+++
++ 	/*
++ 	 * For the Beacon base registers we only need to clear
++ 	 * the whole TXWI which (when set to 0) will invalidate
++@@ -1049,6 +1091,8 @@ static inline void rt2800_clear_beacon_r
++ 	for (i = 0; i < txwi_desc_size; i += sizeof(__le32))
++ 		rt2800_register_write(rt2x00dev, beacon_base + i, 0);
++ 
+++	rt2800_deselect_beacon_mem(rt2x00dev);
+++
++ 	rt2800_shared_mem_unlock(rt2x00dev);
++ }
++ 
+diff --git a/package/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch b/package/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch
+new file mode 100644
+index 0000000..3d97169
+--- /dev/null
++++ b/package/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch
+@@ -0,0 +1,62 @@
++From a058825fa7b53fab3b003d8928b60e5b686b3421 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 4 Aug 2013 14:36:11 +0200
++Subject: [PATCH] rt2x00: rt2800lib: add hw_beacon_count field to struct
++ rt2800_drv_data
++
++Some chipsets can handle more than 8 beacons at once.
++Add a new field to the rt2800_drv_data structure which
++will hold the number of supported beacons of the given
++chipset.
++
++Update the rt2x00_init_registers function to get the
++beacon count from the new field instead of using a
++hardcoded value.
++
++In order to keep the current behaviour, initialize the
++new field with the actually used value.
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    5 ++++-
++ drivers/net/wireless/rt2x00/rt2800lib.h |    1 +
++ 2 files changed, 5 insertions(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -4584,6 +4584,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
++  */
++ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
++ {
+++	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++ 	u32 reg;
++ 	u16 eeprom;
++ 	unsigned int i;
++@@ -4971,7 +4972,7 @@ static int rt2800_init_registers(struct
++ 	/*
++ 	 * Clear all beacons
++ 	 */
++-	for (i = 0; i < 8; i++)
+++	for (i = 0; i < drv_data->hw_beacon_count; i++)
++ 		rt2800_clear_beacon_register(rt2x00dev, i);
++ 
++ 	if (rt2x00_is_usb(rt2x00dev)) {
++@@ -7817,6 +7818,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
++ 	if (rt2x00_rt(rt2x00dev, RT3593))
++ 		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
++ 
+++	drv_data->hw_beacon_count = 8;
+++
++ 	/*
++ 	 * Allocate eeprom data.
++ 	 */
++--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.h
++@@ -33,6 +33,7 @@ struct rt2800_drv_data {
++ 	u8 txmixer_gain_24g;
++ 	u8 txmixer_gain_5g;
++ 	unsigned int tbtt_tick;
+++	unsigned int hw_beacon_count;
++ 
++ 	unsigned long rt2800_flags;
++ 
+diff --git a/package/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch b/package/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch
+new file mode 100644
+index 0000000..8c52713
+--- /dev/null
++++ b/package/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch
+@@ -0,0 +1,67 @@
++From 1bfa43ca8f30be53ce4fa79cfc3e219642a812b6 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Mon, 2 Sep 2013 10:58:32 +0200
++Subject: [PATCH] rt2x00: rt2800lib: init additional beacon offset registers
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800.h    |   14 ++++++++++++++
++ drivers/net/wireless/rt2x00/rt2800lib.c |   24 ++++++++++++++++++++++++
++ 2 files changed, 38 insertions(+)
++
++--- a/drivers/net/wireless/rt2x00/rt2800.h
+++++ b/drivers/net/wireless/rt2x00/rt2800.h
++@@ -627,6 +627,20 @@
++  */
++ #define PBF_DBG				0x043c
++ 
+++/* BCN_OFFSET2 */
+++#define BCN_OFFSET2			0x0444
+++#define BCN_OFFSET2_BCN8		FIELD32(0x000000ff)
+++#define BCN_OFFSET2_BCN9		FIELD32(0x0000ff00)
+++#define BCN_OFFSET2_BCN10		FIELD32(0x00ff0000)
+++#define BCN_OFFSET2_BCN11		FIELD32(0xff000000)
+++
+++/* BCN_OFFSET3 */
+++#define BCN_OFFSET3			0x0448
+++#define BCN_OFFSET3_BCN12		FIELD32(0x000000ff)
+++#define BCN_OFFSET3_BCN13		FIELD32(0x0000ff00)
+++#define BCN_OFFSET3_BCN14		FIELD32(0x00ff0000)
+++#define BCN_OFFSET3_BCN15		FIELD32(0xff000000)
+++
++ /*
++  * RF registers
++  */
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -4618,6 +4618,30 @@ static int rt2800_init_registers(struct
++ 			   rt2800_get_beacon_offset(rt2x00dev, 7));
++ 	rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
++ 
+++	if (drv_data->hw_beacon_count == 16) {
+++		rt2800_register_read(rt2x00dev, BCN_OFFSET2, &reg);
+++		rt2x00_set_field32(&reg, BCN_OFFSET2_BCN8,
+++				   rt2800_get_beacon_offset(rt2x00dev, 8));
+++		rt2x00_set_field32(&reg, BCN_OFFSET2_BCN9,
+++				   rt2800_get_beacon_offset(rt2x00dev, 9));
+++		rt2x00_set_field32(&reg, BCN_OFFSET2_BCN10,
+++				   rt2800_get_beacon_offset(rt2x00dev, 10));
+++		rt2x00_set_field32(&reg, BCN_OFFSET2_BCN11,
+++				   rt2800_get_beacon_offset(rt2x00dev, 11));
+++		rt2800_register_write(rt2x00dev, BCN_OFFSET2, reg);
+++
+++		rt2800_register_read(rt2x00dev, BCN_OFFSET3, &reg);
+++		rt2x00_set_field32(&reg, BCN_OFFSET3_BCN12,
+++				   rt2800_get_beacon_offset(rt2x00dev, 12));
+++		rt2x00_set_field32(&reg, BCN_OFFSET3_BCN13,
+++				   rt2800_get_beacon_offset(rt2x00dev, 13));
+++		rt2x00_set_field32(&reg, BCN_OFFSET3_BCN14,
+++				   rt2800_get_beacon_offset(rt2x00dev, 14));
+++		rt2x00_set_field32(&reg, BCN_OFFSET3_BCN15,
+++				   rt2800_get_beacon_offset(rt2x00dev, 15));
+++		rt2800_register_write(rt2x00dev, BCN_OFFSET3, reg);
+++	}
+++
++ 	rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
++ 	rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
++ 
+diff --git a/package/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch b/package/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch
+new file mode 100644
+index 0000000..66e8245
+--- /dev/null
++++ b/package/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch
+@@ -0,0 +1,24 @@
++From 9bea8b61f6025cd633bd5ac71be258620b49bcb3 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Mon, 2 Sep 2013 11:00:06 +0200
++Subject: [PATCH] rt2x00: rt2800lib: fix max supported beacon count for RT3593
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    5 ++++-
++ 1 file changed, 4 insertions(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -7842,7 +7842,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r
++ 	if (rt2x00_rt(rt2x00dev, RT3593))
++ 		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
++ 
++-	drv_data->hw_beacon_count = 8;
+++	if (rt2x00_rt(rt2x00dev, RT3593))
+++		drv_data->hw_beacon_count = 16;
+++	else
+++		drv_data->hw_beacon_count = 8;
++ 
++ 	/*
++ 	 * Allocate eeprom data.
+diff --git a/package/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch b/package/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch
+new file mode 100644
+index 0000000..8a10c6e
+--- /dev/null
++++ b/package/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch
+@@ -0,0 +1,30 @@
++From 91094ed065f7794886b4a5490fd6de942f036bb4 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 24 Mar 2013 19:26:26 +0100
++Subject: [PATCH] rt2x00: allow to build rt2800soc module for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/Kconfig |    2 +-
++ 1 file changed, 1 insertion(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/Kconfig
+++++ b/drivers/net/wireless/rt2x00/Kconfig
++@@ -210,7 +210,7 @@ endif
++ config RT2800SOC
++ 	tristate "Ralink WiSoC support"
++ 	depends on m
++-	depends on SOC_RT288X || SOC_RT305X
+++	depends on SOC_RT288X || SOC_RT305X || SOC_RT3883
++ 	select RT2X00_LIB_SOC
++ 	select RT2X00_LIB_MMIO
++ 	select RT2X00_LIB_CRYPTO
++@@ -245,7 +245,7 @@ config RT2X00_LIB_PCI
++ 
++ config RT2X00_LIB_SOC
++ 	tristate "RT2x00 SoC support"
++-	depends on SOC_RT288X || SOC_RT305X
+++	depends on SOC_RT288X || SOC_RT305X || SOC_RT3883
++ 	depends on m
++ 	select RT2X00_LIB
++ 
+diff --git a/package/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch b/package/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch
+new file mode 100644
+index 0000000..e9d847a
+--- /dev/null
++++ b/package/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch
+@@ -0,0 +1,20 @@
++From 4f16582c93a71eba9d389e0f0a8aa9099a9587cd Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 24 Mar 2013 19:26:26 +0100
++Subject: [PATCH] rt2x00: rt2800lib: enable support for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    1 +
++ 1 file changed, 1 insertion(+)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -7812,6 +7812,7 @@ static int rt2800_probe_rt(struct rt2x00
++ 	case RT3390:
++ 	case RT3572:
++ 	case RT3593:
+++	case RT3883:
++ 	case RT5390:
++ 	case RT5392:
++ 	case RT5592:
+diff --git a/package/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch b/package/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch
+new file mode 100644
+index 0000000..b096f9f
+--- /dev/null
++++ b/package/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch
+@@ -0,0 +1,112 @@
++From ecb394ccf248d8652c463133c4f404458a57a9c1 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 24 Mar 2013 19:26:26 +0100
++Subject: [PATCH] rt2x00: rt2800lib: add rf_vals for RF3853
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800.h    |    4 +-
++ drivers/net/wireless/rt2x00/rt2800lib.c |   65 +++++++++++++++++++++++++++++++
++ 2 files changed, 68 insertions(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800.h
+++++ b/drivers/net/wireless/rt2x00/rt2800.h
++@@ -48,7 +48,8 @@
++  * RF2853 2.4G/5G 3T3R
++  * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
++  * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
++- * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
+++ * RF3053 2.4G/5G 3T3R(RT3563/RT3573/RT3593)
+++ * RF3853 2.4G/5G 3T3R(RT3883/RT3662)
++  * RF5592 2.4G/5G 2T2R
++  * RF3070 2.4G 1T1R
++  * RF5360 2.4G 1T1R
++@@ -71,6 +72,7 @@
++ #define RF5592				0x000f
++ #define RF3070				0x3070
++ #define RF3290				0x3290
+++#define RF3853				0x3853
++ #define RF5360				0x5360
++ #define RF5370				0x5370
++ #define RF5372				0x5372
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -7432,6 +7432,66 @@ static const struct rf_channel rf_vals_3
++ 	{173, 0x61, 0, 9},
++ };
++ 
+++static const struct rf_channel rf_vals_3853[] = {
+++	{1,  241, 6, 2},
+++	{2,  241, 6, 7},
+++	{3,  242, 6, 2},
+++	{4,  242, 6, 7},
+++	{5,  243, 6, 2},
+++	{6,  243, 6, 7},
+++	{7,  244, 6, 2},
+++	{8,  244, 6, 7},
+++	{9,  245, 6, 2},
+++	{10, 245, 6, 7},
+++	{11, 246, 6, 2},
+++	{12, 246, 6, 7},
+++	{13, 247, 6, 2},
+++	{14, 248, 6, 4},
+++
+++	{36, 0x56, 8, 4},
+++	{38, 0x56, 8, 6},
+++	{40, 0x56, 8, 8},
+++	{44, 0x57, 8, 0},
+++	{46, 0x57, 8, 2},
+++	{48, 0x57, 8, 4},
+++	{52, 0x57, 8, 8},
+++	{54, 0x57, 8, 10},
+++	{56, 0x58, 8, 0},
+++	{60, 0x58, 8, 4},
+++	{62, 0x58, 8, 6},
+++	{64, 0x58, 8, 8},
+++
+++	{100, 0x5b, 8, 8},
+++	{102, 0x5b, 8, 10},
+++	{104, 0x5c, 8, 0},
+++	{108, 0x5c, 8, 4},
+++	{110, 0x5c, 8, 6},
+++	{112, 0x5c, 8, 8},
+++	{114, 0x5c, 8, 10},
+++	{116, 0x5d, 8, 0},
+++	{118, 0x5d, 8, 2},
+++	{120, 0x5d, 8, 4},
+++	{124, 0x5d, 8, 8},
+++	{126, 0x5d, 8, 10},
+++	{128, 0x5e, 8, 0},
+++	{132, 0x5e, 8, 4},
+++	{134, 0x5e, 8, 6},
+++	{136, 0x5e, 8, 8},
+++	{140, 0x5f, 8, 0},
+++
+++	{149, 0x5f, 8, 9},
+++	{151, 0x5f, 8, 11},
+++	{153, 0x60, 8, 1},
+++	{157, 0x60, 8, 5},
+++	{159, 0x60, 8, 7},
+++	{161, 0x60, 8, 9},
+++	{165, 0x61, 8, 1},
+++	{167, 0x61, 8, 3},
+++	{169, 0x61, 8, 5},
+++	{171, 0x61, 8, 7},
+++	{173, 0x61, 8, 9},
+++};
+++
++ static const struct rf_channel rf_vals_5592_xtal20[] = {
++ 	/* Channel, N, K, mod, R */
++ 	{1, 482, 4, 10, 3},
++@@ -7660,6 +7720,11 @@ static int rt2800_probe_hw_mode(struct r
++ 		spec->channels = rf_vals_3x;
++ 		break;
++ 
+++	case RF3853:
+++		spec->num_channels = ARRAY_SIZE(rf_vals_3853);
+++		spec->channels = rf_vals_3853;
+++		break;
+++
++ 	case RF5592:
++ 		rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX, &reg);
++ 		if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) {
+diff --git a/package/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch b/package/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch
+new file mode 100644
+index 0000000..4c9a3b4
+--- /dev/null
++++ b/package/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch
+@@ -0,0 +1,28 @@
++From f8e3fcf18e1f2d7f9e6a9680c5452da090f33d88 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Thu, 1 Aug 2013 14:40:44 +0200
++Subject: [PATCH] rt2x00: rt2800lib: enable VCO calibration for RF3853
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    2 ++
++ 1 file changed, 2 insertions(+)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -4349,6 +4349,7 @@ void rt2800_vco_calibration(struct rt2x0
++ 	case RF3053:
++ 	case RF3070:
++ 	case RF3290:
+++	case RF3853:
++ 	case RF5360:
++ 	case RF5370:
++ 	case RF5372:
++@@ -7839,6 +7840,7 @@ static int rt2800_probe_hw_mode(struct r
++ 	case RF3053:
++ 	case RF3070:
++ 	case RF3290:
+++	case RF3853:
++ 	case RF5360:
++ 	case RF5370:
++ 	case RF5372:
+diff --git a/package/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch b/package/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch
+new file mode 100644
+index 0000000..e3460ff
+--- /dev/null
++++ b/package/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch
+@@ -0,0 +1,235 @@
++From 6e3a17190815c6aa4dc53c2cfe9125fb1154f187 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 24 Mar 2013 19:26:27 +0100
++Subject: [PATCH] rt2x00: rt2800lib: add channel configuration function for
++ RF3853
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |  208 +++++++++++++++++++++++++++++++
++ 1 file changed, 208 insertions(+)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -2605,6 +2605,211 @@ static void rt2800_config_channel_rf3053
++ 	}
++ }
++ 
+++static void rt2800_config_channel_rf3853(struct rt2x00_dev *rt2x00dev,
+++					 struct ieee80211_conf *conf,
+++					 struct rf_channel *rf,
+++					 struct channel_info *info)
+++{
+++	u8 rfcsr;
+++	u8 bbp;
+++	u8 pwr1, pwr2, pwr3;
+++
+++	const bool txbf_enabled = false; /* TODO */
+++
+++	/* TODO: add band selection */
+++
+++	if (rf->channel <= 14)
+++		rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
+++	else if (rf->channel < 132)
+++		rt2800_rfcsr_write(rt2x00dev, 6, 0x80);
+++	else
+++		rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
+++
+++	rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
+++	rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
+++
+++	if (rf->channel <= 14)
+++		rt2800_rfcsr_write(rt2x00dev, 11, 0x46);
+++	else
+++		rt2800_rfcsr_write(rt2x00dev, 11, 0x48);
+++
+++	if (rf->channel <= 14)
+++		rt2800_rfcsr_write(rt2x00dev, 12, 0x1a);
+++	else
+++		rt2800_rfcsr_write(rt2x00dev, 12, 0x52);
+++
+++	rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
+++
+++	rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
+++	rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
+++	rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
+++	rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
+++	rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
+++	rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
+++	rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
+++	rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
+++	rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1);
+++
+++	switch (rt2x00dev->default_ant.tx_chain_num) {
+++	case 3:
+++		rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
+++		/* fallthrough */
+++	case 2:
+++		rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
+++		/* fallthrough */
+++	case 1:
+++		rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
+++		break;
+++	}
+++
+++	switch (rt2x00dev->default_ant.rx_chain_num) {
+++	case 3:
+++		rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
+++		/* fallthrough */
+++	case 2:
+++		rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
+++		/* fallthrough */
+++	case 1:
+++		rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
+++		break;
+++	}
+++	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+++
+++	rt2800_adjust_freq_offset(rt2x00dev);
+++
+++	rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
+++	if (!conf_is_ht40(conf))
+++		rfcsr &= ~(0x06);
+++	else
+++		rfcsr |= 0x06;
+++	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+++
+++	if (rf->channel <= 14)
+++		rt2800_rfcsr_write(rt2x00dev, 31, 0xa0);
+++	else
+++		rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
+++
+++	if (conf_is_ht40(conf))
+++		rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
+++	else
+++		rt2800_rfcsr_write(rt2x00dev, 32, 0xd8);
+++
+++	if (rf->channel <= 14)
+++		rt2800_rfcsr_write(rt2x00dev, 34, 0x3c);
+++	else
+++		rt2800_rfcsr_write(rt2x00dev, 34, 0x20);
+++
+++	/* loopback RF_BS */
+++	rt2800_rfcsr_read(rt2x00dev, 36, &rfcsr);
+++	if (rf->channel <= 14)
+++		rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1);
+++	else
+++		rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0);
+++	rt2800_rfcsr_write(rt2x00dev, 36, rfcsr);
+++
+++	if (rf->channel <= 14)
+++		rfcsr = 0x23;
+++	else if (rf->channel < 100)
+++		rfcsr = 0x36;
+++	else if (rf->channel < 132)
+++		rfcsr = 0x32;
+++	else
+++		rfcsr = 0x30;
+++
+++	if (txbf_enabled)
+++		rfcsr |= 0x40;
+++
+++	rt2800_rfcsr_write(rt2x00dev, 39, rfcsr);
+++
+++	if (rf->channel <= 14)
+++		rt2800_rfcsr_write(rt2x00dev, 44, 0x93);
+++	else
+++		rt2800_rfcsr_write(rt2x00dev, 44, 0x9b);
+++
+++	if (rf->channel <= 14)
+++		rfcsr = 0xbb;
+++	else if (rf->channel < 100)
+++		rfcsr = 0xeb;
+++	else if (rf->channel < 132)
+++		rfcsr = 0xb3;
+++	else
+++		rfcsr = 0x9b;
+++	rt2800_rfcsr_write(rt2x00dev, 45, rfcsr);
+++
+++	if (rf->channel <= 14)
+++		rfcsr = 0x8e;
+++	else
+++		rfcsr = 0x8a;
+++
+++	if (txbf_enabled)
+++		rfcsr |= 0x20;
+++
+++	rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
+++
+++	rt2800_rfcsr_write(rt2x00dev, 50, 0x86);
+++
+++	rt2800_rfcsr_read(rt2x00dev, 51, &rfcsr);
+++	if (rf->channel <= 14)
+++		rt2800_rfcsr_write(rt2x00dev, 51, 0x75);
+++	else
+++		rt2800_rfcsr_write(rt2x00dev, 51, 0x51);
+++
+++	rt2800_rfcsr_read(rt2x00dev, 52, &rfcsr);
+++	if (rf->channel <= 14)
+++		rt2800_rfcsr_write(rt2x00dev, 52, 0x45);
+++	else
+++		rt2800_rfcsr_write(rt2x00dev, 52, 0x05);
+++
+++	if (rf->channel <= 14) {
+++		pwr1 = info->default_power1 & 0x1f;
+++		pwr2 = info->default_power2 & 0x1f;
+++		pwr3 = info->default_power3 & 0x1f;
+++	} else {
+++		pwr1 = 0x48 | ((info->default_power1 & 0x18) << 1) |
+++			(info->default_power1 & 0x7);
+++		pwr2 = 0x48 | ((info->default_power2 & 0x18) << 1) |
+++			(info->default_power2 & 0x7);
+++		pwr3 = 0x48 | ((info->default_power3 & 0x18) << 1) |
+++			(info->default_power3 & 0x7);
+++	}
+++
+++	rt2800_rfcsr_write(rt2x00dev, 53, pwr1);
+++	rt2800_rfcsr_write(rt2x00dev, 54, pwr2);
+++	rt2800_rfcsr_write(rt2x00dev, 55, pwr3);
+++
+++	rt2x00_dbg(rt2x00dev, "Channel:%d, pwr1:%02x, pwr2:%02x, pwr3:%02x\n",
+++		   rf->channel, pwr1, pwr2, pwr3);
+++
+++	bbp = (info->default_power1 >> 5) |
+++	      ((info->default_power2 & 0xe0) >> 1);
+++	rt2800_bbp_write(rt2x00dev, 109, bbp);
+++
+++	rt2800_bbp_read(rt2x00dev, 110, &bbp);
+++	bbp &= 0x0f;
+++	bbp |= (info->default_power3 & 0xe0) >> 1;
+++	rt2800_bbp_write(rt2x00dev, 110, bbp);
+++
+++	rt2800_rfcsr_read(rt2x00dev, 57, &rfcsr);
+++	if (rf->channel <= 14)
+++		rt2800_rfcsr_write(rt2x00dev, 57, 0x6e);
+++	else
+++		rt2800_rfcsr_write(rt2x00dev, 57, 0x3e);
+++
+++	/* Enable RF tuning */
+++	rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
+++	rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
+++	rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
+++
+++	udelay(2000);
+++
+++	rt2800_bbp_read(rt2x00dev, 49, &bbp);
+++	/* clear update flag */
+++	rt2800_bbp_write(rt2x00dev, 49, bbp & 0xfe);
+++	rt2800_bbp_write(rt2x00dev, 49, bbp);
+++
+++	/* TODO: add calibration for TxBF */
+++}
+++
++ #define POWER_BOUND		0x27
++ #define POWER_BOUND_5G		0x2b
++ 
++@@ -3217,6 +3422,9 @@ static void rt2800_config_channel(struct
++ 	case RF3322:
++ 		rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
++ 		break;
+++	case RF3853:
+++		rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info);
+++		break;
++ 	case RF3070:
++ 	case RF5360:
++ 	case RF5370:
+diff --git a/package/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch b/package/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch
+new file mode 100644
+index 0000000..8719425
+--- /dev/null
++++ b/package/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch
+@@ -0,0 +1,20 @@
++From afd38ae82226551bf879b6c7c4b620c271fee9d2 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Thu, 1 Aug 2013 14:42:05 +0200
++Subject: [PATCH] rt2x00: rt2800lib: enable RF3853 support
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    1 +
++ 1 file changed, 1 insertion(+)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -7398,6 +7398,7 @@ static int rt2800_init_eeprom(struct rt2
++ 	case RF3290:
++ 	case RF3320:
++ 	case RF3322:
+++	case RF3853:
++ 	case RF5360:
++ 	case RF5370:
++ 	case RF5372:
+diff --git a/package/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch b/package/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch
+new file mode 100644
+index 0000000..8632ddd
+--- /dev/null
++++ b/package/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch
+@@ -0,0 +1,77 @@
++From 0094872a5e8e4664c6ea1b2dfa487063d39ae363 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 24 Mar 2013 19:26:26 +0100
++Subject: [PATCH] rt2x00: rt2800lib: add MAC register initialization for
++ RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800.h    |   14 ++++++++++++++
++ drivers/net/wireless/rt2x00/rt2800lib.c |   19 ++++++++++++++++---
++ 2 files changed, 30 insertions(+), 3 deletions(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800.h
+++++ b/drivers/net/wireless/rt2x00/rt2800.h
++@@ -1586,6 +1586,20 @@
++ #define TX_PWR_CFG_9_STBC7_CH2		FIELD32(0x00000f00)
++ 
++ /*
+++ * TX_TXBF_CFG:
+++ */
+++#define TX_TXBF_CFG_0			0x138c
+++#define TX_TXBF_CFG_1			0x13a4
+++#define TX_TXBF_CFG_2			0x13a8
+++#define TX_TXBF_CFG_3			0x13ac
+++
+++/*
+++ * TX_FBK_CFG_3S:
+++ */
+++#define TX_FBK_CFG_3S_0			0x13c4
+++#define TX_FBK_CFG_3S_1			0x13c8
+++
+++/*
++  * RX_FILTER_CFG: RX configuration register.
++  */
++ #define RX_FILTER_CFG			0x1400
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -4973,6 +4973,12 @@ static int rt2800_init_registers(struct
++ 			rt2800_register_write(rt2x00dev, TX_SW_CFG2,
++ 					      0x00000000);
++ 		}
+++	} else if (rt2x00_rt(rt2x00dev, RT3883)) {
+++		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402);
+++		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
+++		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000);
+++		rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21);
+++		rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40);
++ 	} else if (rt2x00_rt(rt2x00dev, RT5390) ||
++ 		   rt2x00_rt(rt2x00dev, RT5392) ||
++ 		   rt2x00_rt(rt2x00dev, RT5592)) {
++@@ -5003,9 +5009,11 @@ static int rt2800_init_registers(struct
++ 
++ 	rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
++ 	rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
++-	if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) ||
++-	    rt2x00_rt(rt2x00dev, RT2883) ||
++-	    rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
+++	if (rt2x00_rt(rt2x00dev, RT3883))
+++		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 3);
+++	else if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) ||
+++		 rt2x00_rt(rt2x00dev, RT2883) ||
+++		 rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E))
++ 		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
++ 	else
++ 		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
++@@ -5158,6 +5166,11 @@ static int rt2800_init_registers(struct
++ 	reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002;
++ 	rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg);
++ 
+++	if (rt2x00_rt(rt2x00dev, RT3883)) {
+++		rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_0, 0x12111008);
+++		rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_1, 0x16151413);
+++	}
+++
++ 	rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
++ 	rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
++ 	rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES,
+diff --git a/package/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch b/package/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch
+new file mode 100644
+index 0000000..837c025
+--- /dev/null
++++ b/package/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch
+@@ -0,0 +1,30 @@
++From 6c2d32478159fffff0b85abb6817a21bb2338231 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 24 Mar 2013 19:26:27 +0100
++Subject: [PATCH] rt2x00: rt2800soc: fix rt2800soc_disable_radio for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800soc.c |    9 ++++++++-
++ 1 file changed, 8 insertions(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800soc.c
+++++ b/drivers/net/wireless/rt2x00/rt2800soc.c
++@@ -51,9 +51,16 @@ static bool rt2800soc_hwcrypt_disabled(s
++ 
++ static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev)
++ {
+++	u32 reg;
+++
++ 	rt2800_disable_radio(rt2x00dev);
++ 	rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0);
++-	rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0);
+++
+++	reg = 0;
+++	if (rt2x00_rt(rt2x00dev, RT3883))
+++		rt2x00_set_field32(&reg, TX_PIN_CFG_RFTR_EN, 1);
+++
+++	rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, reg);
++ }
++ 
++ static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev,
+diff --git a/package/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch b/package/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch
+new file mode 100644
+index 0000000..967e36a
+--- /dev/null
++++ b/package/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch
+@@ -0,0 +1,71 @@
++From 84833056aa7dd25f5b097e31c78f2a0914c5160c Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 24 Mar 2013 19:26:26 +0100
++Subject: [PATCH] rt2x00: rt2800lib: add BBP register initialization for
++ RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |   44 +++++++++++++++++++++++++++++++
++ 1 file changed, 44 insertions(+)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -5776,6 +5776,47 @@ static void rt2800_init_bbp_3593(struct
++ 		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
++ }
++ 
+++static void rt2800_init_bbp_3883(struct rt2x00_dev *rt2x00dev)
+++{
+++	rt2800_init_bbp_early(rt2x00dev);
+++
+++	rt2800_bbp_write(rt2x00dev, 4, 0x50);
+++	rt2800_bbp_write(rt2x00dev, 47, 0x48);
+++
+++	rt2800_bbp_write(rt2x00dev, 86, 0x46);
+++	rt2800_bbp_write(rt2x00dev, 88, 0x90);
+++
+++	rt2800_bbp_write(rt2x00dev, 92, 0x02);
+++
+++	rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+++	rt2800_bbp_write(rt2x00dev, 104, 0x92);
+++	rt2800_bbp_write(rt2x00dev, 105, 0x34);
+++	rt2800_bbp_write(rt2x00dev, 106, 0x12);
+++	rt2800_bbp_write(rt2x00dev, 120, 0x50);
+++	rt2800_bbp_write(rt2x00dev, 137, 0x0f);
+++	rt2800_bbp_write(rt2x00dev, 163, 0x9d);
+++
+++	/* Set ITxBF timeout to 0x9C40=1000msec */
+++	rt2800_bbp_write(rt2x00dev, 179, 0x02);
+++	rt2800_bbp_write(rt2x00dev, 180, 0x00);
+++	rt2800_bbp_write(rt2x00dev, 182, 0x40);
+++	rt2800_bbp_write(rt2x00dev, 180, 0x01);
+++	rt2800_bbp_write(rt2x00dev, 182, 0x9c);
+++
+++	rt2800_bbp_write(rt2x00dev, 179, 0x00);
+++
+++	/* Reprogram the inband interface to put right values in RXWI */
+++	rt2800_bbp_write(rt2x00dev, 142, 0x04);
+++	rt2800_bbp_write(rt2x00dev, 143, 0x3b);
+++	rt2800_bbp_write(rt2x00dev, 142, 0x06);
+++	rt2800_bbp_write(rt2x00dev, 143, 0xa0);
+++	rt2800_bbp_write(rt2x00dev, 142, 0x07);
+++	rt2800_bbp_write(rt2x00dev, 143, 0xa1);
+++	rt2800_bbp_write(rt2x00dev, 142, 0x08);
+++	rt2800_bbp_write(rt2x00dev, 143, 0xa2);
+++	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
+++}
+++
++ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
++ {
++ 	int ant, div_mode;
++@@ -5994,6 +6035,9 @@ static void rt2800_init_bbp(struct rt2x0
++ 	case RT3593:
++ 		rt2800_init_bbp_3593(rt2x00dev);
++ 		return;
+++	case RT3883:
+++		rt2800_init_bbp_3883(rt2x00dev);
+++		return;
++ 	case RT5390:
++ 	case RT5392:
++ 		rt2800_init_bbp_53xx(rt2x00dev);
+diff --git a/package/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch b/package/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch
+new file mode 100644
+index 0000000..c568b99
+--- /dev/null
++++ b/package/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch
+@@ -0,0 +1,178 @@
++From 99c659cf345640fd0f733cbcaf4583cc2c868ec0 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Mon, 29 Apr 2013 13:21:48 +0200
++Subject: [PATCH] rt2x00: rt2800lib: add RFCSR initialization for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800.h    |    1 +
++ drivers/net/wireless/rt2x00/rt2800lib.c |  141 +++++++++++++++++++++++++++++++
++ 2 files changed, 142 insertions(+)
++
++--- a/drivers/net/wireless/rt2x00/rt2800.h
+++++ b/drivers/net/wireless/rt2x00/rt2800.h
++@@ -2169,6 +2169,7 @@ struct mac_iveiv_entry {
++ /*
++  * RFCSR 2:
++  */
+++#define RFCSR2_RESCAL_BP		FIELD8(0x40)
++ #define RFCSR2_RESCAL_EN		FIELD8(0x80)
++ 
++ /*
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -6811,6 +6811,144 @@ static void rt2800_init_rfcsr_3593(struc
++ 	/* TODO: enable stream mode support */
++ }
++ 
+++static void rt2800_init_rfcsr_3883(struct rt2x00_dev *rt2x00dev)
+++{
+++	u8 rfcsr;
+++
+++	/* TODO: get the actual ECO value from the SoC */
+++	const unsigned int eco = 5;
+++
+++	rt2800_rf_init_calibration(rt2x00dev, 2);
+++
+++	rt2800_rfcsr_write(rt2x00dev, 0, 0xe0);
+++	rt2800_rfcsr_write(rt2x00dev, 1, 0x03);
+++	rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
+++	rt2800_rfcsr_write(rt2x00dev, 3, 0x20);
+++	rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 5, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 6, 0x40);
+++	rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 8, 0x5b);
+++	rt2800_rfcsr_write(rt2x00dev, 9, 0x08);
+++	rt2800_rfcsr_write(rt2x00dev, 10, 0xd3);
+++	rt2800_rfcsr_write(rt2x00dev, 11, 0x48);
+++	rt2800_rfcsr_write(rt2x00dev, 12, 0x1a);
+++	rt2800_rfcsr_write(rt2x00dev, 13, 0x12);
+++	rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
+++
+++	/* RFCSR 17 will be initialized later based on the
+++	 * frequency offset stored in the EEPROM
+++	 */
+++
+++	rt2800_rfcsr_write(rt2x00dev, 18, 0x40);
+++	rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
+++	rt2800_rfcsr_write(rt2x00dev, 23, 0xc0);
+++	rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 29, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
+++	rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
+++	rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
+++	rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 34, 0x20);
+++	rt2800_rfcsr_write(rt2x00dev, 35, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 37, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 38, 0x86);
+++	rt2800_rfcsr_write(rt2x00dev, 39, 0x23);
+++	rt2800_rfcsr_write(rt2x00dev, 40, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 41, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 42, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 43, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 44, 0x93);
+++	rt2800_rfcsr_write(rt2x00dev, 45, 0xbb);
+++	rt2800_rfcsr_write(rt2x00dev, 46, 0x60);
+++	rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 48, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 49, 0x8e);
+++	rt2800_rfcsr_write(rt2x00dev, 50, 0x86);
+++	rt2800_rfcsr_write(rt2x00dev, 51, 0x51);
+++	rt2800_rfcsr_write(rt2x00dev, 52, 0x05);
+++	rt2800_rfcsr_write(rt2x00dev, 53, 0x76);
+++	rt2800_rfcsr_write(rt2x00dev, 54, 0x76);
+++	rt2800_rfcsr_write(rt2x00dev, 55, 0x76);
+++	rt2800_rfcsr_write(rt2x00dev, 56, 0xdb);
+++	rt2800_rfcsr_write(rt2x00dev, 57, 0x3e);
+++	rt2800_rfcsr_write(rt2x00dev, 58, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
+++	rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
+++
+++	/* TODO: rx filter calibration? */
+++
+++	rt2800_bbp_write(rt2x00dev, 137, 0x0f);
+++
+++	rt2800_bbp_write(rt2x00dev, 163, 0x9d);
+++
+++	rt2800_bbp_write(rt2x00dev, 105, 0x05);
+++
+++	rt2800_bbp_write(rt2x00dev, 179, 0x02);
+++	rt2800_bbp_write(rt2x00dev, 180, 0x00);
+++	rt2800_bbp_write(rt2x00dev, 182, 0x40);
+++	rt2800_bbp_write(rt2x00dev, 180, 0x01);
+++	rt2800_bbp_write(rt2x00dev, 182, 0x9c);
+++
+++	rt2800_bbp_write(rt2x00dev, 179, 0x00);
+++
+++	rt2800_bbp_write(rt2x00dev, 142, 0x04);
+++	rt2800_bbp_write(rt2x00dev, 143, 0x3b);
+++	rt2800_bbp_write(rt2x00dev, 142, 0x06);
+++	rt2800_bbp_write(rt2x00dev, 143, 0xa0);
+++	rt2800_bbp_write(rt2x00dev, 142, 0x07);
+++	rt2800_bbp_write(rt2x00dev, 143, 0xa1);
+++	rt2800_bbp_write(rt2x00dev, 142, 0x08);
+++	rt2800_bbp_write(rt2x00dev, 143, 0xa2);
+++	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
+++
+++	if (eco == 5) {
+++		rt2800_rfcsr_write(rt2x00dev, 32, 0xd8);
+++		rt2800_rfcsr_write(rt2x00dev, 33, 0x32);
+++	}
+++
+++	rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
+++	rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_BP, 0);
+++	rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1);
+++	rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
+++	msleep(1);
+++	rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0);
+++	rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
+++
+++	rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
+++	rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
+++	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+++
+++	rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
+++	rfcsr |= 0xc0;
+++	rt2800_rfcsr_write(rt2x00dev, 6, rfcsr);
+++
+++	rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
+++	rfcsr |= 0x20;
+++	rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
+++
+++	rt2800_rfcsr_read(rt2x00dev, 46, &rfcsr);
+++	rfcsr |= 0x20;
+++	rt2800_rfcsr_write(rt2x00dev, 46, rfcsr);
+++
+++	rt2800_rfcsr_read(rt2x00dev, 20, &rfcsr);
+++	rfcsr &= ~0xee;
+++	rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
+++}
+++
++ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
++ {
++ 	rt2800_rf_init_calibration(rt2x00dev, 2);
++@@ -7042,6 +7180,9 @@ static void rt2800_init_rfcsr(struct rt2
++ 	case RT3390:
++ 		rt2800_init_rfcsr_3390(rt2x00dev);
++ 		break;
+++	case RT3883:
+++		rt2800_init_rfcsr_3883(rt2x00dev);
+++		break;
++ 	case RT3572:
++ 		rt2800_init_rfcsr_3572(rt2x00dev);
++ 		break;
+diff --git a/package/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch b/package/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch
+new file mode 100644
+index 0000000..57af961
+--- /dev/null
++++ b/package/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch
+@@ -0,0 +1,22 @@
++From 86022438ffeb1b87dfcd018bf477fdbb43076691 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Wed, 8 May 2013 19:35:33 +0200
++Subject: [PATCH] rt2x00: rt2800lib: use the extended EEPROM map for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
++ 1 file changed, 2 insertions(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -342,7 +342,8 @@ static unsigned int rt2800_eeprom_word_i
++ 		      wiphy_name(rt2x00dev->hw->wiphy), word))
++ 		return 0;
++ 
++-	if (rt2x00_rt(rt2x00dev, RT3593))
+++	if (rt2x00_rt(rt2x00dev, RT3593) ||
+++	    rt2x00_rt(rt2x00dev, RT3883))
++ 		map = rt2800_eeprom_map_ext;
++ 	else
++ 		map = rt2800_eeprom_map;
+diff --git a/package/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch b/package/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch
+new file mode 100644
+index 0000000..47eece0
+--- /dev/null
++++ b/package/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch
+@@ -0,0 +1,21 @@
++From 4cf5403f02fa65dc2207f61d223cffa9ae50e907 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Thu, 1 Aug 2013 14:48:21 +0200
++Subject: [PATCH] rt2x00: rt2800lib: force rf type to RF3853 on RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    2 ++
++ 1 file changed, 2 insertions(+)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -7579,6 +7579,8 @@ static int rt2800_init_eeprom(struct rt2
++ 	    rt2x00_rt(rt2x00dev, RT5390) ||
++ 	    rt2x00_rt(rt2x00dev, RT5392))
++ 		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
+++	else if (rt2x00_rt(rt2x00dev, RT3883))
+++		rf = RF3853;
++ 	else
++ 		rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
++ 
+diff --git a/package/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch b/package/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch
+new file mode 100644
+index 0000000..d9cbb33
+--- /dev/null
++++ b/package/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch
+@@ -0,0 +1,136 @@
++From 269f19c848a2380db03a3f207cafb88e28d71c53 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 24 Mar 2013 19:26:28 +0100
++Subject: [PATCH] rt2x00: rt2800lib: add channel configuration code for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |   72 +++++++++++++++++++++++++++++--
++ 1 file changed, 69 insertions(+), 3 deletions(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -3385,6 +3385,36 @@ static char rt2800_txpower_to_dev(struct
++ 		return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER);
++ }
++ 
+++static void rt3883_bbp_adjust(struct rt2x00_dev *rt2x00dev,
+++			      struct rf_channel *rf)
+++{
+++	u8 bbp;
+++
+++	bbp = (rf->channel > 14) ? 0x48 : 0x38;
+++	rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp);
+++
+++	rt2800_bbp_write(rt2x00dev, 69, 0x12);
+++
+++	if (rf->channel <= 14) {
+++		rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+++	} else {
+++		/* Disable CCK packet detection */
+++		rt2800_bbp_write(rt2x00dev, 70, 0x00);
+++	}
+++
+++	rt2800_bbp_write(rt2x00dev, 73, 0x10);
+++
+++	if (rf->channel > 14) {
+++		rt2800_bbp_write(rt2x00dev, 62, 0x1d);
+++		rt2800_bbp_write(rt2x00dev, 63, 0x1d);
+++		rt2800_bbp_write(rt2x00dev, 64, 0x1d);
+++	} else {
+++		rt2800_bbp_write(rt2x00dev, 62, 0x2d);
+++		rt2800_bbp_write(rt2x00dev, 63, 0x2d);
+++		rt2800_bbp_write(rt2x00dev, 64, 0x2d);
+++	}
+++}
+++
++ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
++ 				  struct ieee80211_conf *conf,
++ 				  struct rf_channel *rf,
++@@ -3403,6 +3433,12 @@ static void rt2800_config_channel(struct
++ 			rt2800_txpower_to_dev(rt2x00dev, rf->channel,
++ 					      info->default_power3);
++ 
+++	switch (rt2x00dev->chip.rt) {
+++	case RT3883:
+++		rt3883_bbp_adjust(rt2x00dev, rf);
+++		break;
+++	}
+++
++ 	switch (rt2x00dev->chip.rf) {
++ 	case RF2020:
++ 	case RF3020:
++@@ -3484,6 +3520,15 @@ static void rt2800_config_channel(struct
++ 		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
++ 		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
++ 		rt2800_bbp_write(rt2x00dev, 77, 0x98);
+++	} else if (rt2x00_rt(rt2x00dev, RT3883)) {
+++		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+++		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+++		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+++
+++		if (rt2x00dev->default_ant.rx_chain_num > 1)
+++			rt2800_bbp_write(rt2x00dev, 86, 0x46);
+++		else
+++			rt2800_bbp_write(rt2x00dev, 86, 0);
++ 	} else {
++ 		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
++ 		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
++@@ -3496,6 +3541,7 @@ static void rt2800_config_channel(struct
++ 		    !rt2x00_rt(rt2x00dev, RT5392)) {
++ 			if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
++ 				rt2800_bbp_write(rt2x00dev, 82, 0x62);
+++				rt2800_bbp_write(rt2x00dev, 82, 0x62);
++ 				rt2800_bbp_write(rt2x00dev, 75, 0x46);
++ 			} else {
++ 				if (rt2x00_rt(rt2x00dev, RT3593))
++@@ -3504,19 +3550,22 @@ static void rt2800_config_channel(struct
++ 					rt2800_bbp_write(rt2x00dev, 82, 0x84);
++ 				rt2800_bbp_write(rt2x00dev, 75, 0x50);
++ 			}
++-			if (rt2x00_rt(rt2x00dev, RT3593))
+++			if (rt2x00_rt(rt2x00dev, RT3593) ||
+++			    rt2x00_rt(rt2x00dev, RT3883))
++ 				rt2800_bbp_write(rt2x00dev, 83, 0x8a);
++ 		}
++ 
++ 	} else {
++ 		if (rt2x00_rt(rt2x00dev, RT3572))
++ 			rt2800_bbp_write(rt2x00dev, 82, 0x94);
++-		else if (rt2x00_rt(rt2x00dev, RT3593))
+++		else if (rt2x00_rt(rt2x00dev, RT3593) ||
+++			 rt2x00_rt(rt2x00dev, RT3883))
++ 			rt2800_bbp_write(rt2x00dev, 82, 0x82);
++ 		else
++ 			rt2800_bbp_write(rt2x00dev, 82, 0xf2);
++ 
++-		if (rt2x00_rt(rt2x00dev, RT3593))
+++		if (rt2x00_rt(rt2x00dev, RT3593) ||
+++		    rt2x00_rt(rt2x00dev, RT3883))
++ 			rt2800_bbp_write(rt2x00dev, 83, 0x9a);
++ 
++ 		if (rt2x00_has_cap_external_lna_a(rt2x00dev))
++@@ -3638,6 +3687,23 @@ static void rt2800_config_channel(struct
++ 
++ 		rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
++ 
+++		usleep_range(1000, 1500);
+++	}
+++
+++	if (rt2x00_rt(rt2x00dev, RT3883)) {
+++		if (!conf_is_ht40(conf))
+++			rt2800_bbp_write(rt2x00dev, 105, 0x34);
+++		else
+++			rt2800_bbp_write(rt2x00dev, 105, 0x04);
+++
+++		/* AGC init */
+++		if (rf->channel <= 14)
+++			reg = 0x2e + rt2x00dev->lna_gain;
+++		else
+++			reg = 0x20 + ((rt2x00dev->lna_gain * 5) / 3);
+++
+++		rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
+++
++ 		usleep_range(1000, 1500);
++ 	}
++ 
+diff --git a/package/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch b/package/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch
+new file mode 100644
+index 0000000..c927e45
+--- /dev/null
++++ b/package/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch
+@@ -0,0 +1,30 @@
++From e37d93abaabe3ab72b0332a18092acc162307274 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Mon, 30 Sep 2013 13:57:26 +0200
++Subject: [PATCH] rt2x00: rt2800lib: fix txpower_to_dev function for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    6 ++++--
++ 1 file changed, 4 insertions(+), 2 deletions(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -3372,13 +3372,15 @@ static char rt2800_txpower_to_dev(struct
++ 				  unsigned int channel,
++ 				  char txpower)
++ {
++-	if (rt2x00_rt(rt2x00dev, RT3593))
+++	if (rt2x00_rt(rt2x00dev, RT3593) ||
+++	    rt2x00_rt(rt2x00dev, RT3883))
++ 		txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC);
++ 
++ 	if (channel <= 14)
++ 		return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER);
++ 
++-	if (rt2x00_rt(rt2x00dev, RT3593))
+++	if (rt2x00_rt(rt2x00dev, RT3593) ||
+++	    rt2x00_rt(rt2x00dev, RT3883))
++ 		return clamp_t(char, txpower, MIN_A_TXPOWER_3593,
++ 			       MAX_A_TXPOWER_3593);
++ 	else
+diff --git a/package/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch b/package/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch
+new file mode 100644
+index 0000000..df826e5
+--- /dev/null
++++ b/package/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch
+@@ -0,0 +1,23 @@
++From c4d79e344bd580d85821390d49f92dced7d8e125 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 24 Mar 2013 19:26:29 +0100
++Subject: [PATCH] rt2x00: rt2800lib: use correct txpower calculation function
++ for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
++ 1 file changed, 2 insertions(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -4582,7 +4582,8 @@ static void rt2800_config_txpower(struct
++ 				  struct ieee80211_channel *chan,
++ 				  int power_level)
++ {
++-	if (rt2x00_rt(rt2x00dev, RT3593))
+++	if (rt2x00_rt(rt2x00dev, RT3593) ||
+++	    rt2x00_rt(rt2x00dev, RT3883))
++ 		rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level);
++ 	else
++ 		rt2800_config_txpower_rt28xx(rt2x00dev, chan, power_level);
+diff --git a/package/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch b/package/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch
+new file mode 100644
+index 0000000..8a43df2
+--- /dev/null
++++ b/package/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch
+@@ -0,0 +1,33 @@
++From caea0671cd8fd9ade4f5969cbe0ee545e94ae105 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sat, 24 Aug 2013 11:49:55 +0200
++Subject: [PATCH] rt2x00: rt2800lib: hardcode txmixer gain values to zero for
++ RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    6 ++++--
++ 1 file changed, 4 insertions(+), 2 deletions(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -7461,7 +7461,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
++ {
++ 	u16 word;
++ 
++-	if (rt2x00_rt(rt2x00dev, RT3593))
+++	if (rt2x00_rt(rt2x00dev, RT3593) ||
+++	    rt2x00_rt(rt2x00dev, RT3883))
++ 		return 0;
++ 
++ 	rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
++@@ -7475,7 +7476,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
++ {
++ 	u16 word;
++ 
++-	if (rt2x00_rt(rt2x00dev, RT3593))
+++	if (rt2x00_rt(rt2x00dev, RT3593) ||
+++	    rt2x00_rt(rt2x00dev, RT3883))
++ 		return 0;
++ 
++ 	rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
+diff --git a/package/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch b/package/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch
+new file mode 100644
+index 0000000..53435aa
+--- /dev/null
++++ b/package/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch
+@@ -0,0 +1,20 @@
++From 11c40fb47c4a4dd6ad060c2ae127ced89ffb9fe1 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Thu, 18 Apr 2013 14:33:33 +0200
++Subject: [PATCH] rt2x00: rt2800lib: use correct [RT]XWI size for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    1 +
++ 1 file changed, 1 insertion(+)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -558,6 +558,7 @@ void rt2800_get_txwi_rxwi_size(struct rt
++ {
++ 	switch (rt2x00dev->chip.rt) {
++ 	case RT3593:
+++	case RT3883:
++ 		*txwi_size = TXWI_DESC_SIZE_4WORDS;
++ 		*rxwi_size = RXWI_DESC_SIZE_5WORDS;
++ 		break;
+diff --git a/package/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch b/package/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch
+new file mode 100644
+index 0000000..08f3f88
+--- /dev/null
++++ b/package/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch
+@@ -0,0 +1,22 @@
++From b403bdfa00665ce6b53583bdb837ffad0b91c09f Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 24 Mar 2013 19:26:29 +0100
++Subject: [PATCH] rt2x00: rt2800lib: use correct beacon base for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
++ 1 file changed, 2 insertions(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -983,7 +983,8 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
++ static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
++ 					  unsigned int index)
++ {
++-	if (rt2x00_rt(rt2x00dev, RT3593))
+++	if (rt2x00_rt(rt2x00dev, RT3593) ||
+++	    rt2x00_rt(rt2x00dev, RT3883))
++ 		return HW_BEACON_BASE_HIGH(index);
++ 
++ 	return HW_BEACON_BASE(index);
+diff --git a/package/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch b/package/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch
+new file mode 100644
+index 0000000..cb7a0ae
+--- /dev/null
++++ b/package/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch
+@@ -0,0 +1,22 @@
++From 74b7eaf75fc6eb86292056ef705e543f9cd6086b Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 18 Aug 2013 09:57:58 +0200
++Subject: [PATCH] rt2x00: rt2800lib: use correct beacon count for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
++ 1 file changed, 2 insertions(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -8393,7 +8393,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
++ 	if (rt2x00_rt(rt2x00dev, RT3593))
++ 		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
++ 
++-	if (rt2x00_rt(rt2x00dev, RT3593))
+++	if (rt2x00_rt(rt2x00dev, RT3593) ||
+++	    rt2x00_rt(rt2x00dev, RT3883))
++ 		drv_data->hw_beacon_count = 16;
++ 	else
++ 		drv_data->hw_beacon_count = 8;
+diff --git a/package/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch b/package/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch
+new file mode 100644
+index 0000000..0919f90
+--- /dev/null
++++ b/package/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch
+@@ -0,0 +1,22 @@
++From fa5ad9c025610c22048add2f0ad03f62b6ca1e74 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Mon, 30 Sep 2013 16:53:33 +0200
++Subject: [PATCH] rt2x00: rt2800lib: fix antenna configuration for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
++ 1 file changed, 2 insertions(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -1917,7 +1917,8 @@ void rt2800_config_ant(struct rt2x00_dev
++ 	rt2800_bbp_write(rt2x00dev, 3, r3);
++ 	rt2800_bbp_write(rt2x00dev, 1, r1);
++ 
++-	if (rt2x00_rt(rt2x00dev, RT3593)) {
+++	if (rt2x00_rt(rt2x00dev, RT3593) ||
+++	    rt2x00_rt(rt2x00dev, RT3883)) {
++ 		if (ant->rx_chain_num == 1)
++ 			rt2800_bbp_write(rt2x00dev, 86, 0x00);
++ 		else
+diff --git a/package/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch b/package/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch
+new file mode 100644
+index 0000000..e38ba78
+--- /dev/null
++++ b/package/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch
+@@ -0,0 +1,32 @@
++From 6d668fef3a1baa60bdd715ee062ddb6333d2647c Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Mon, 30 Sep 2013 16:58:23 +0200
++Subject: [PATCH] rt2x00: rt2800lib: fix LNA gain configuration for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    6 ++++--
++ 1 file changed, 4 insertions(+), 2 deletions(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -1940,7 +1940,8 @@ static void rt2800_config_lna_gain(struc
++ 		rt2800_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
++ 		lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
++ 	} else if (libconf->rf.channel <= 128) {
++-		if (rt2x00_rt(rt2x00dev, RT3593)) {
+++		if (rt2x00_rt(rt2x00dev, RT3593) ||
+++		    rt2x00_rt(rt2x00dev, RT3883)) {
++ 			rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
++ 			lna_gain = rt2x00_get_field16(eeprom,
++ 						      EEPROM_EXT_LNA2_A1);
++@@ -1950,7 +1951,8 @@ static void rt2800_config_lna_gain(struc
++ 						      EEPROM_RSSI_BG2_LNA_A1);
++ 		}
++ 	} else {
++-		if (rt2x00_rt(rt2x00dev, RT3593)) {
+++		if (rt2x00_rt(rt2x00dev, RT3593) ||
+++		    rt2x00_rt(rt2x00dev, RT3883)) {
++ 			rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &eeprom);
++ 			lna_gain = rt2x00_get_field16(eeprom,
++ 						      EEPROM_EXT_LNA2_A2);
+diff --git a/package/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch b/package/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch
+new file mode 100644
+index 0000000..4684599
+--- /dev/null
++++ b/package/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch
+@@ -0,0 +1,44 @@
++From c49b2d829aa1c816a46a577cdec6d2ff14d9f06e Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Tue, 1 Oct 2013 15:40:08 +0200
++Subject: [PATCH] rt2x00: rt2800lib: fix VGC setup for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |   11 +++++++++--
++ 1 file changed, 9 insertions(+), 2 deletions(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -4781,7 +4781,8 @@ static u8 rt2800_get_default_vgc(struct
++ 		else
++ 			vgc = 0x2e + rt2x00dev->lna_gain;
++ 	} else { /* 5GHZ band */
++-		if (rt2x00_rt(rt2x00dev, RT3593))
+++		if (rt2x00_rt(rt2x00dev, RT3593) ||
+++		    rt2x00_rt(rt2x00dev, RT3883))
++ 			vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3;
++ 		else if (rt2x00_rt(rt2x00dev, RT5592))
++ 			vgc = 0x24 + (2 * rt2x00dev->lna_gain);
++@@ -4801,7 +4802,8 @@ static inline void rt2800_set_vgc(struct
++ {
++ 	if (qual->vgc_level != vgc_level) {
++ 		if (rt2x00_rt(rt2x00dev, RT3572) ||
++-		    rt2x00_rt(rt2x00dev, RT3593)) {
+++		    rt2x00_rt(rt2x00dev, RT3593) ||
+++		    rt2x00_rt(rt2x00dev, RT3883)) {
++ 			rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
++ 						       vgc_level);
++ 		} else if (rt2x00_rt(rt2x00dev, RT5592)) {
++@@ -4848,6 +4850,11 @@ void rt2800_link_tuner(struct rt2x00_dev
++ 		}
++ 		break;
++ 
+++	case RT3883:
+++		if (qual->rssi > -65)
+++			vgc += 0x10;
+++		break;
+++
++ 	case RT5592:
++ 		if (qual->rssi > -65)
++ 			vgc += 0x20;
+diff --git a/package/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch b/package/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch
+new file mode 100644
+index 0000000..bc1548d
+--- /dev/null
++++ b/package/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch
+@@ -0,0 +1,42 @@
++From 1616650aea676541d4dc8adc6f4219856d193c8b Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Tue, 1 Oct 2013 17:27:57 +0200
++Subject: [PATCH] rt2x00: rt2800lib: fix EEPROM LNA validation for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    9 ++++++---
++ 1 file changed, 6 insertions(+), 3 deletions(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -7598,7 +7598,8 @@ static int rt2800_validate_eeprom(struct
++ 	rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
++ 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
++ 		rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
++-	if (!rt2x00_rt(rt2x00dev, RT3593)) {
+++	if (!rt2x00_rt(rt2x00dev, RT3593) &&
+++	    !rt2x00_rt(rt2x00dev, RT3883)) {
++ 		if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
++ 		    rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
++ 			rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
++@@ -7618,7 +7619,8 @@ static int rt2800_validate_eeprom(struct
++ 	rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
++ 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
++ 		rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
++-	if (!rt2x00_rt(rt2x00dev, RT3593)) {
+++	if (!rt2x00_rt(rt2x00dev, RT3593) &&
+++	    !rt2x00_rt(rt2x00dev, RT3883)) {
++ 		if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
++ 		    rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
++ 			rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
++@@ -7626,7 +7628,8 @@ static int rt2800_validate_eeprom(struct
++ 	}
++ 	rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
++ 
++-	if (rt2x00_rt(rt2x00dev, RT3593)) {
+++	if (rt2x00_rt(rt2x00dev, RT3593) ||
+++	    rt2x00_rt(rt2x00dev, RT3883)) {
++ 		rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2, &word);
++ 		if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 ||
++ 		    rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff)
+diff --git a/package/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch b/package/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch
+new file mode 100644
+index 0000000..d6295f4
+--- /dev/null
++++ b/package/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch
+@@ -0,0 +1,22 @@
++From e3871034a0e7c8a95152dc3eafbcc4535398cbdc Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Wed, 2 Oct 2013 10:11:59 +0200
++Subject: [PATCH] rt2x00: rt2800lib: fix txpower compensation for RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    3 +++
++ 1 file changed, 3 insertions(+)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -3959,6 +3959,9 @@ static u8 rt2800_compensate_txpower(stru
++ 	if (rt2x00_rt(rt2x00dev, RT3593))
++ 		return min_t(u8, txpower, 0xc);
++ 
+++	if (rt2x00_rt(rt2x00dev, RT3883))
+++		return min_t(u8, txpower, 0xf);
+++
++ 	if (rt2x00_has_cap_power_limit(rt2x00dev)) {
++ 		/*
++ 		 * Check if eirp txpower exceed txpower_limit.
+diff --git a/package/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch b/package/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch
+new file mode 100644
+index 0000000..c5f226a
+--- /dev/null
++++ b/package/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch
+@@ -0,0 +1,23 @@
++From f6734ec72da936989a8ce4186b3ede28fbc47836 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 18 Aug 2013 21:57:34 +0200
++Subject: [PATCH] rt2x00: rt2800lib: enable RT2800_HAS_HIGH_SHARED_MEM for
++ RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
++ 1 file changed, 2 insertions(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -8406,7 +8406,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
++ 	if (retval)
++ 		return retval;
++ 
++-	if (rt2x00_rt(rt2x00dev, RT3593))
+++	if (rt2x00_rt(rt2x00dev, RT3593) ||
+++	    rt2x00_rt(rt2x00dev, RT3883))
++ 		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
++ 
++ 	if (rt2x00_rt(rt2x00dev, RT3593) ||
+diff --git a/package/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch b/package/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch
+new file mode 100644
+index 0000000..dc06e6a
+--- /dev/null
++++ b/package/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch
+@@ -0,0 +1,22 @@
++From f1acfc2f397e86548ae1b479c198d4bef57050f6 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 29 Sep 2013 18:10:34 +0200
++Subject: [PATCH] rt2x00: rt2800lib: use high memory for beacons on RT3883
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800lib.c |    3 ++-
++ 1 file changed, 2 insertions(+), 1 deletion(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
++@@ -97,7 +97,8 @@ static inline void rt2800_shared_mem_sel
++ 
++ static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev)
++ {
++-	if (rt2x00_rt(rt2x00dev, RT3593))
+++	if (rt2x00_rt(rt2x00dev, RT3593) ||
+++	    rt2x00_rt(rt2x00dev, RT3883))
++ 		return true;
++ 
++ 	return false;
+diff --git a/package/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch b/package/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch
+new file mode 100644
+index 0000000..79334dd
+--- /dev/null
++++ b/package/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch
+@@ -0,0 +1,136 @@
++From 5e67d4f8a46d19748b501c2ef86de3f50d3cfd51 Mon Sep 17 00:00:00 2001
++From: Gabor Juhos <juhosg@openwrt.org>
++Date: Sun, 24 Mar 2013 19:26:27 +0100
++Subject: [PATCH] rt2x00: rt2800mmio: add a workaround for spurious
++ TX_FIFO_STATUS interrupts
++
++Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
++---
++ drivers/net/wireless/rt2x00/rt2800mmio.c |   72 +++++++++++++++++++++++++-----
++ drivers/net/wireless/rt2x00/rt2x00.h     |    5 +++
++ 2 files changed, 65 insertions(+), 12 deletions(-)
++
++--- a/drivers/net/wireless/rt2x00/rt2800mmio.c
+++++ b/drivers/net/wireless/rt2x00/rt2800mmio.c
++@@ -415,9 +415,9 @@ void rt2800mmio_autowake_tasklet(unsigne
++ }
++ EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet);
++ 
++-static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
+++static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev,
+++					  u32 status)
++ {
++-	u32 status;
++ 	int i;
++ 
++ 	/*
++@@ -438,29 +438,77 @@ static void rt2800mmio_txstatus_interrup
++ 	 * Since we have only one producer and one consumer we don't
++ 	 * need to lock the kfifo.
++ 	 */
++-	for (i = 0; i < rt2x00dev->tx->limit; i++) {
++-		rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status);
++-
++-		if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
++-			break;
++-
+++	i = 0;
+++	do {
++ 		if (!kfifo_put(&rt2x00dev->txstatus_fifo, status)) {
++-			rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n");
+++			rt2x00_warn(rt2x00dev,
+++				    "TX status FIFO overrun, drop TX status report\n");
++ 			break;
++ 		}
++-	}
+++
+++		if (++i >= rt2x00dev->tx->limit)
+++			break;
+++
+++ 		rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status);
+++	} while (rt2x00_get_field32(status, TX_STA_FIFO_VALID));
++ 
++ 	/* Schedule the tasklet for processing the tx status. */
++ 	tasklet_schedule(&rt2x00dev->txstatus_tasklet);
++ }
++ 
+++#define RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES	4
+++
+++static bool rt2800mmio_txstatus_is_spurious(struct rt2x00_dev *rt2x00dev,
+++					   u32 txstatus)
+++{
+++	if (likely(rt2x00_get_field32(txstatus, TX_STA_FIFO_VALID))) {
+++		rt2x00dev->txstatus_irq_retries = 0;
+++		return false;
+++	}
+++
+++	rt2x00dev->txstatus_irq_retries++;
+++
+++	/* Ensure that we don't go into an infinite IRQ loop. */
+++	if (rt2x00dev->txstatus_irq_retries >=
+++	    RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES) {
+++		rt2x00_warn(rt2x00dev,
+++			    "%u spurious TX_FIFO_STATUS interrupt(s)\n",
+++			    rt2x00dev->txstatus_irq_retries);
+++		rt2x00dev->txstatus_irq_retries = 0;
+++		return false;
+++	}
+++
+++	return true;
+++}
+++
++ irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance)
++ {
++ 	struct rt2x00_dev *rt2x00dev = dev_instance;
++ 	u32 reg, mask;
+++	u32 txstatus = 0;
++ 
++-	/* Read status and ACK all interrupts */
+++	/* Read status */
++ 	rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
+++
+++	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) {
+++		/* Due to unknown reason the hardware generates a
+++		 * TX_FIFO_STATUS interrupt before the TX_STA_FIFO
+++		 * register contain valid data. Read the TX status
+++		 * here to see if we have to process the actual
+++		 * request.
+++		 */
+++		rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &txstatus);
+++		if (rt2800mmio_txstatus_is_spurious(rt2x00dev, txstatus)) {
+++			/* Remove the TX_FIFO_STATUS bit so it won't be
+++			 * processed in this turn. The hardware will
+++			 * generate another IRQ for us.
+++			 */
+++			rt2x00_set_field32(&reg,
+++					   INT_SOURCE_CSR_TX_FIFO_STATUS, 0);
+++		}
+++	}
+++
+++	/* ACK interrupts */
++ 	rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
++ 
++ 	if (!reg)
++@@ -477,7 +525,7 @@ irqreturn_t rt2800mmio_interrupt(int irq
++ 	mask = ~reg;
++ 
++ 	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) {
++-		rt2800mmio_txstatus_interrupt(rt2x00dev);
+++		rt2800mmio_txstatus_interrupt(rt2x00dev, txstatus);
++ 		/*
++ 		 * Never disable the TX_FIFO_STATUS interrupt.
++ 		 */
++--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++++ b/drivers/net/wireless/rt2x00/rt2x00.h
++@@ -986,6 +986,11 @@ struct rt2x00_dev {
++ 	int rf_channel;
++ 
++ 	/*
+++	 * Counter for tx status irq retries (rt2800pci).
+++	 */
+++	unsigned int txstatus_irq_retries;
+++
+++	/*
++ 	 * Protect the interrupt mask register.
++ 	 */
++ 	spinlock_t irqmask_lock;
+diff --git a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
+index 2bbc6f1..c7d71e2 100644
+--- a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
++++ b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
+@@ -1,6 +1,6 @@
+ --- a/.local-symbols
+ +++ b/.local-symbols
+-@@ -279,6 +279,7 @@ RT2X00_LIB_FIRMWARE=
++@@ -280,6 +280,7 @@ RT2X00_LIB_FIRMWARE=
+  RT2X00_LIB_CRYPTO=
+  RT2X00_LIB_LEDS=
+  RT2X00_LIB_DEBUGFS=
+@@ -48,16 +48,16 @@
+  obj-$(CPTCFG_RT2X00_LIB_MMIO)		+= rt2x00mmio.o
+ --- a/drivers/net/wireless/rt2x00/rt2800lib.h
+ +++ b/drivers/net/wireless/rt2x00/rt2800lib.h
+-@@ -20,6 +20,8 @@
+- #ifndef RT2800LIB_H
+- #define RT2800LIB_H
++@@ -43,6 +43,8 @@ struct rt2800_drv_data {
++ 	} shmem_lock;
++ };
+  
+ +#include "rt2800.h"
+ +
+  struct rt2800_ops {
+  	void (*register_read)(struct rt2x00_dev *rt2x00dev,
+  			      const unsigned int offset, u32 *value);
+-@@ -119,6 +121,15 @@ static inline int rt2800_read_eeprom(str
++@@ -176,6 +178,15 @@ static inline int rt2800_read_eeprom(str
+  {
+  	const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
+  
+@@ -75,7 +75,7 @@
+  
+ --- a/drivers/net/wireless/rt2x00/rt2800soc.c
+ +++ b/drivers/net/wireless/rt2x00/rt2800soc.c
+-@@ -95,19 +95,6 @@ static int rt2800soc_set_device_state(st
++@@ -102,19 +102,6 @@ static int rt2800soc_set_device_state(st
+  	return retval;
+  }
+  
+@@ -95,7 +95,7 @@
+  /* Firmware functions */
+  static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev)
+  {
+-@@ -171,7 +158,6 @@ static const struct rt2800_ops rt2800soc
++@@ -178,7 +165,6 @@ static const struct rt2800_ops rt2800soc
+  	.register_multiread	= rt2x00mmio_register_multiread,
+  	.register_multiwrite	= rt2x00mmio_register_multiwrite,
+  	.regbusy_read		= rt2x00mmio_regbusy_read,
+diff --git a/package/mac80211/patches/608-add_platform_data_mac_addr.patch b/package/mac80211/patches/608-add_platform_data_mac_addr.patch
+index a910cc3..1db09a3 100644
+--- a/package/mac80211/patches/608-add_platform_data_mac_addr.patch
++++ b/package/mac80211/patches/608-add_platform_data_mac_addr.patch
+@@ -31,7 +31,7 @@
+  {
+ --- a/drivers/net/wireless/rt2x00/rt2x00.h
+ +++ b/drivers/net/wireless/rt2x00/rt2x00.h
+-@@ -1401,6 +1401,7 @@ static inline void rt2x00debug_dump_fram
++@@ -1406,6 +1406,7 @@ static inline void rt2x00debug_dump_fram
+   */
+  u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev,
+  			 struct ieee80211_vif *vif);
+diff --git a/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch b/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
+index 83fbcd0..3d32ecc 100644
+--- a/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
++++ b/package/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch
+@@ -1,14 +1,15 @@
+ --- a/drivers/net/wireless/rt2x00/rt2800lib.c
+ +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+-@@ -3176,11 +3176,17 @@ static void rt2800_config_channel(struct
++@@ -3506,11 +3506,18 @@ static void rt2800_config_channel(struct
+  	/*
+  	 * Change BBP settings
+  	 */
+-+	rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+-+	rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+-+	rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+ +
+  	if (rt2x00_rt(rt2x00dev, RT3352)) {
+++		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+++		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+++		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+++
+  		rt2800_bbp_write(rt2x00dev, 27, 0x0);
+  		rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
+  		rt2800_bbp_write(rt2x00dev, 27, 0x20);
+@@ -18,22 +19,7 @@
+  	} else if (rt2x00_rt(rt2x00dev, RT3593)) {
+  		if (rf->channel > 14) {
+  			/* Disable CCK Packet detection on 5GHz */
+-@@ -3194,14 +3200,8 @@ static void rt2800_config_channel(struct
+- 		else
+- 			rt2800_bbp_write(rt2x00dev, 105, 0x34);
+- 
+--		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+--		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+--		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+- 		rt2800_bbp_write(rt2x00dev, 77, 0x98);
+- 	} else {
+--		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+--		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+--		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+- 		rt2800_bbp_write(rt2x00dev, 86, 0);
+- 	}
+- 
+-@@ -6125,6 +6125,12 @@ static void rt2800_init_rfcsr_3290(struc
++@@ -6586,6 +6593,12 @@ static void rt2800_init_rfcsr_3290(struc
+  
+  static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
+  {
+@@ -46,7 +32,7 @@
+  	rt2800_rf_init_calibration(rt2x00dev, 30);
+  
+  	rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
+-@@ -6160,15 +6166,30 @@ static void rt2800_init_rfcsr_3352(struc
++@@ -6621,15 +6634,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);
+@@ -80,7 +66,7 @@
+  	rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
+  	rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
+  	rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
+-@@ -6176,15 +6197,20 @@ static void rt2800_init_rfcsr_3352(struc
++@@ -6637,15 +6665,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);
+@@ -110,7 +96,7 @@
+  	rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
+  	rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
+  	rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
+-@@ -7051,6 +7077,7 @@ static int rt2800_init_eeprom(struct rt2
++@@ -7666,6 +7699,7 @@ static int rt2800_init_eeprom(struct rt2
+  	 * RT53xx: defined in "EEPROM_CHIP_ID" field
+  	 */
+  	if (rt2x00_rt(rt2x00dev, RT3290) ||
+@@ -118,7 +104,7 @@
+  	    rt2x00_rt(rt2x00dev, RT5390) ||
+  	    rt2x00_rt(rt2x00dev, RT5392))
+  		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
+-@@ -7142,7 +7169,8 @@ static int rt2800_init_eeprom(struct rt2
++@@ -7760,7 +7794,8 @@ static int rt2800_init_eeprom(struct rt2
+  	/*
+  	 * Detect if this device has Bluetooth co-existence.
+  	 */
+@@ -128,7 +114,7 @@
+  		__set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
+  
+  	/*
+-@@ -7171,6 +7199,22 @@ static int rt2800_init_eeprom(struct rt2
++@@ -7789,6 +7824,22 @@ static int rt2800_init_eeprom(struct rt2
+  					EIRP_MAX_TX_POWER_LIMIT)
+  		__set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
+  
+@@ -153,7 +139,7 @@
+  
+ --- a/drivers/net/wireless/rt2x00/rt2800.h
+ +++ b/drivers/net/wireless/rt2x00/rt2800.h
+-@@ -2299,6 +2299,12 @@ struct mac_iveiv_entry {
++@@ -2333,6 +2333,12 @@ struct mac_iveiv_entry {
+  #define RFCSR36_RF_BS			FIELD8(0x80)
+  
+  /*
+@@ -166,7 +152,7 @@
+   * RFCSR 38:
+   */
+  #define RFCSR38_RX_LO1_EN		FIELD8(0x20)
+-@@ -2310,6 +2316,18 @@ struct mac_iveiv_entry {
++@@ -2344,6 +2350,18 @@ struct mac_iveiv_entry {
+  #define RFCSR39_RX_LO2_EN		FIELD8(0x80)
+  
+  /*
+@@ -185,7 +171,7 @@
+   * RFCSR 49:
+   */
+  #define RFCSR49_TX			FIELD8(0x3f)
+-@@ -2322,6 +2340,8 @@ struct mac_iveiv_entry {
++@@ -2356,6 +2374,8 @@ struct mac_iveiv_entry {
+   * RFCSR 50:
+   */
+  #define RFCSR50_TX			FIELD8(0x3f)
+@@ -194,7 +180,7 @@
+  #define RFCSR50_EP			FIELD8(0xc0)
+  /* bits for RT3593 */
+  #define RFCSR50_TX_LO1_EN		FIELD8(0x20)
+-@@ -2469,6 +2489,8 @@ enum rt2800_eeprom_word {
++@@ -2503,6 +2523,8 @@ enum rt2800_eeprom_word {
+   * INTERNAL_TX_ALC: 0: disable, 1: enable
+   * BT_COEXIST: 0: disable, 1: enable
+   * DAC_TEST: 0: disable, 1: enable
+@@ -203,7 +189,7 @@
+   */
+  #define EEPROM_NIC_CONF1_HW_RADIO		FIELD16(0x0001)
+  #define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC	FIELD16(0x0002)
+-@@ -2485,6 +2507,8 @@ enum rt2800_eeprom_word {
++@@ -2519,6 +2541,8 @@ enum rt2800_eeprom_word {
+  #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)
+diff --git a/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch b/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
+index 478a0f2..c69344c 100644
+--- a/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
++++ b/package/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch
+@@ -1,6 +1,6 @@
+ --- a/drivers/net/wireless/rt2x00/rt2800lib.c
+ +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+-@@ -7491,6 +7491,27 @@ static const struct rf_channel rf_vals_5
++@@ -8176,6 +8176,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;
+-@@ -7579,7 +7600,10 @@ static int rt2800_probe_hw_mode(struct r
++@@ -8263,7 +8284,10 @@ static int rt2800_probe_hw_mode(struct r
+  	case RF5390:
+  	case RF5392:
+  		spec->num_channels = 14;
+@@ -40,7 +40,7 @@
+  		break;
+  
+  	case RF3052:
+-@@ -7755,6 +7779,19 @@ static int rt2800_probe_rt(struct rt2x00
++@@ -8446,6 +8470,19 @@ static int rt2800_probe_rt(struct rt2x00
+  	return 0;
+  }
+  
+@@ -59,8 +59,8 @@
+ +
+  int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
+  {
+- 	int retval;
+-@@ -7784,6 +7821,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
++ 	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
++@@ -8488,6 +8525,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
+  	rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
+  
+  	/*
+diff --git a/package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch b/package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch
+index f6b4808..119e95c 100644
+--- a/package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch
++++ b/package/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch
+@@ -13,7 +13,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ 
+ --- a/drivers/net/wireless/rt2x00/rt2800soc.c
+ +++ b/drivers/net/wireless/rt2x00/rt2800soc.c
+-@@ -227,11 +227,18 @@ static int rt2800soc_probe(struct platfo
++@@ -237,11 +237,18 @@ static int rt2800soc_probe(struct platfo
+  	return rt2x00soc_probe(pdev, &rt2800soc_ops);
+  }
+  
+diff --git a/package/mac80211/patches/616-rt2x00-support-rt5350.patch b/package/mac80211/patches/616-rt2x00-support-rt5350.patch
+index 3bafa16..2cc136c 100644
+--- a/package/mac80211/patches/616-rt2x00-support-rt5350.patch
++++ b/package/mac80211/patches/616-rt2x00-support-rt5350.patch
+@@ -1,16 +1,16 @@
+ --- a/drivers/net/wireless/rt2x00/rt2800.h
+ +++ b/drivers/net/wireless/rt2x00/rt2800.h
+-@@ -71,6 +71,7 @@
+- #define RF5592				0x000f
++@@ -73,6 +73,7 @@
+  #define RF3070				0x3070
+  #define RF3290				0x3290
++ #define RF3853				0x3853
+ +#define RF5350				0x5350
+  #define RF5360				0x5360
+  #define RF5370				0x5370
+  #define RF5372				0x5372
+ --- a/drivers/net/wireless/rt2x00/rt2800lib.c
+ +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+-@@ -2704,6 +2704,13 @@ static void rt2800_config_channel_rf53xx
++@@ -2994,6 +2994,13 @@ static void rt2800_config_channel_rf53xx
+  
+  				rt2800_rfcsr_write(rt2x00dev, 59,
+  						   r59_non_bt[idx]);
+@@ -24,15 +24,15 @@
+  			}
+  		}
+  	}
+-@@ -3141,6 +3148,7 @@ static void rt2800_config_channel(struct
+- 		rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
++@@ -3472,6 +3479,7 @@ static void rt2800_config_channel(struct
++ 		rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info);
+  		break;
+  	case RF3070:
+ +	case RF5350:
+  	case RF5360:
+  	case RF5370:
+  	case RF5372:
+-@@ -3158,6 +3166,7 @@ static void rt2800_config_channel(struct
++@@ -3489,6 +3497,7 @@ static void rt2800_config_channel(struct
+  	if (rt2x00_rf(rt2x00dev, RF3070) ||
+  	    rt2x00_rf(rt2x00dev, RF3290) ||
+  	    rt2x00_rf(rt2x00dev, RF3322) ||
+@@ -40,7 +40,7 @@
+  	    rt2x00_rf(rt2x00dev, RF5360) ||
+  	    rt2x00_rf(rt2x00dev, RF5370) ||
+  	    rt2x00_rf(rt2x00dev, RF5372) ||
+-@@ -3398,7 +3407,8 @@ static void rt2800_config_channel(struct
++@@ -3766,7 +3775,8 @@ static void rt2800_config_channel(struct
+  	/*
+  	 * Clear update flag
+  	 */
+@@ -50,15 +50,15 @@
+  		rt2800_bbp_read(rt2x00dev, 49, &bbp);
+  		rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
+  		rt2800_bbp_write(rt2x00dev, 49, bbp);
+-@@ -4272,6 +4282,7 @@ void rt2800_vco_calibration(struct rt2x0
+- 	case RF3053:
++@@ -4645,6 +4655,7 @@ void rt2800_vco_calibration(struct rt2x0
+  	case RF3070:
+  	case RF3290:
++ 	case RF3853:
+ +	case RF5350:
+  	case RF5360:
+  	case RF5370:
+  	case RF5372:
+-@@ -4668,6 +4679,8 @@ static int rt2800_init_registers(struct 
++@@ -5079,6 +5090,8 @@ static int rt2800_init_registers(struct
+  		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
+  		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+  		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+@@ -67,7 +67,7 @@
+  	} else {
+  		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
+  		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+-@@ -5309,9 +5322,13 @@ static void rt2800_init_bbp_3352(struct 
++@@ -5734,9 +5747,13 @@ static void rt2800_init_bbp_3352(struct
+  
+  	rt2800_bbp_write(rt2x00dev, 82, 0x62);
+  
+@@ -84,7 +84,7 @@
+  
+  	rt2800_bbp_write(rt2x00dev, 86, 0x38);
+  
+-@@ -5325,9 +5342,13 @@ static void rt2800_init_bbp_3352(struct 
++@@ -5750,9 +5767,13 @@ static void rt2800_init_bbp_3352(struct
+  
+  	rt2800_bbp_write(rt2x00dev, 104, 0x92);
+  
+@@ -101,7 +101,7 @@
+  
+  	rt2800_bbp_write(rt2x00dev, 120, 0x50);
+  
+-@@ -5352,6 +5373,13 @@ static void rt2800_init_bbp_3352(struct 
++@@ -5777,6 +5798,13 @@ static void rt2800_init_bbp_3352(struct
+  	rt2800_bbp_write(rt2x00dev, 143, 0xa2);
+  
+  	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
+@@ -115,7 +115,7 @@
+  }
+  
+  static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev)
+-@@ -5652,6 +5680,7 @@ static void rt2800_init_bbp(struct rt2x0
++@@ -6118,6 +6146,7 @@ static void rt2800_init_bbp(struct rt2x0
+  		rt2800_init_bbp_3290(rt2x00dev);
+  		break;
+  	case RT3352:
+@@ -123,8 +123,8 @@
+  		rt2800_init_bbp_3352(rt2x00dev);
+  		break;
+  	case RT3390:
+-@@ -6462,6 +6491,76 @@ static void rt2800_init_rfcsr_3593(struc
+- 	/* TODO: enable stream mode support */
++@@ -7069,6 +7098,76 @@ static void rt2800_init_rfcsr_3883(struc
++ 	rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
+  }
+  
+ +static void rt2800_init_rfcsr_5350(struct rt2x00_dev *rt2x00dev)
+@@ -200,7 +200,7 @@
+  static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
+  {
+  	rt2800_rf_init_calibration(rt2x00dev, 2);
+-@@ -6699,6 +6798,9 @@ static void rt2800_init_rfcsr(struct rt2
++@@ -7309,6 +7408,9 @@ static void rt2800_init_rfcsr(struct rt2
+  	case RT3593:
+  		rt2800_init_rfcsr_3593(rt2x00dev);
+  		break;
+@@ -210,7 +210,7 @@
+  	case RT5390:
+  		rt2800_init_rfcsr_5390(rt2x00dev);
+  		break;
+-@@ -6948,6 +7050,12 @@ static int rt2800_validate_eeprom(struct
++@@ -7568,6 +7670,12 @@ static int rt2800_validate_eeprom(struct
+  		rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
+  		rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
+  		rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
+@@ -223,24 +223,24 @@
+  	} else if (rt2x00_rt(rt2x00dev, RT2860) ||
+  		   rt2x00_rt(rt2x00dev, RT2872)) {
+  		/*
+-@@ -7081,6 +7189,8 @@ static int rt2800_init_eeprom(struct rt2
+- 	    rt2x00_rt(rt2x00dev, RT5390) ||
+- 	    rt2x00_rt(rt2x00dev, RT5392))
++@@ -7706,6 +7814,8 @@ static int rt2800_init_eeprom(struct rt2
+  		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
++ 	else if (rt2x00_rt(rt2x00dev, RT3883))
++ 		rf = RF3853;
+ +	else if (rt2x00_rt(rt2x00dev, RT5350))
+ +		rf = RF5350;
+  	else
+  		rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
+  
+-@@ -7099,6 +7209,7 @@ static int rt2800_init_eeprom(struct rt2
+- 	case RF3290:
++@@ -7725,6 +7835,7 @@ static int rt2800_init_eeprom(struct rt2
+  	case RF3320:
+  	case RF3322:
++ 	case RF3853:
+ +	case RF5350:
+  	case RF5360:
+  	case RF5370:
+  	case RF5372:
+-@@ -7594,6 +7705,7 @@ static int rt2800_probe_hw_mode(struct r
++@@ -8279,6 +8390,7 @@ static int rt2800_probe_hw_mode(struct r
+  	case RF3290:
+  	case RF3320:
+  	case RF3322:
+@@ -248,18 +248,18 @@
+  	case RF5360:
+  	case RF5370:
+  	case RF5372:
+-@@ -7726,6 +7838,7 @@ static int rt2800_probe_hw_mode(struct r
+- 	case RF3053:
++@@ -8417,6 +8529,7 @@ static int rt2800_probe_hw_mode(struct r
+  	case RF3070:
+  	case RF3290:
++ 	case RF3853:
+ +	case RF5350:
+  	case RF5360:
+  	case RF5370:
+  	case RF5372:
+-@@ -7764,6 +7877,7 @@ static int rt2800_probe_rt(struct rt2x00
+- 	case RT3390:
++@@ -8456,6 +8569,7 @@ static int rt2800_probe_rt(struct rt2x00
+  	case RT3572:
+  	case RT3593:
++ 	case RT3883:
+ +	case RT5350:
+  	case RT5390:
+  	case RT5392:
+diff --git a/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch b/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
+index f9186d8..fc56847 100644
+--- a/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
++++ b/package/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch
+@@ -8,7 +8,7 @@
+  
+  #include "rt2x00.h"
+  #include "rt2800lib.h"
+-@@ -7298,6 +7299,17 @@ static int rt2800_init_eeprom(struct rt2
++@@ -7924,6 +7925,17 @@ static int rt2800_init_eeprom(struct rt2
+  	rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
+  	rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
+  
+diff --git a/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch b/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch
+index 5e67344..a33c01f 100644
+--- a/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch
++++ b/package/mac80211/patches/620-rt2x00-rt3352-rf-id.patch
+@@ -1,15 +1,11 @@
+ --- a/drivers/net/wireless/rt2x00/rt2800lib.c
+ +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+-@@ -7186,10 +7186,11 @@ static int rt2800_init_eeprom(struct rt2
+- 	 * RT53xx: defined in "EEPROM_CHIP_ID" field
+- 	 */
+- 	if (rt2x00_rt(rt2x00dev, RT3290) ||
+--	    rt2x00_rt(rt2x00dev, RT3352) ||
++@@ -7813,6 +7813,8 @@ static int rt2800_init_eeprom(struct rt2
+  	    rt2x00_rt(rt2x00dev, RT5390) ||
+  	    rt2x00_rt(rt2x00dev, RT5392))
+  		rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
+ +	else if (rt2x00_rt(rt2x00dev, RT3352))
+ +		rf = RF3322;
++ 	else if (rt2x00_rt(rt2x00dev, RT3883))
++ 		rf = RF3853;
+  	else if (rt2x00_rt(rt2x00dev, RT5350))
+- 		rf = RF5350;
+- 	else
+diff --git a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
+index 484c075..752fb0e 100644
+--- a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
++++ b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
+@@ -1,6 +1,6 @@
+ --- a/drivers/net/wireless/mwl8k.c
+ +++ b/drivers/net/wireless/mwl8k.c
+-@@ -5529,6 +5529,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
++@@ -5714,6 +5714,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) = {
+diff --git a/package/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch b/package/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch
+deleted file mode 100644
+index a8af257..0000000
+--- a/package/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch
++++ /dev/null
+@@ -1,109 +0,0 @@
+-Move the wl1251 part of the wl12xx platform data structure into a new
+-structure specifically for wl1251.  Change the platform data built-in
+-block and board files accordingly.
+-
+-Cc: Tony Lindgren <tony@atomide.com>
+-Signed-off-by: Luciano Coelho <coelho@ti.com>
+-Acked-by: Tony Lindgren <tony@atomide.com>
+-Reviewed-by: Felipe Balbi <balbi@ti.com>
+-
+---- a/drivers/net/wireless/ti/wilink_platform_data.c
+-+++ b/drivers/net/wireless/ti/wilink_platform_data.c
+-@@ -23,17 +23,17 @@
+- #include <linux/err.h>
+- #include <linux/wl12xx.h>
+- 
+--static struct wl12xx_platform_data *platform_data;
+-+static struct wl12xx_platform_data *wl12xx_platform_data;
+- 
+- int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
+- {
+--	if (platform_data)
+-+	if (wl12xx_platform_data)
+- 		return -EBUSY;
+- 	if (!data)
+- 		return -EINVAL;
+- 
+--	platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+--	if (!platform_data)
+-+	wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+-+	if (!wl12xx_platform_data)
+- 		return -ENOMEM;
+- 
+- 	return 0;
+-@@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(cons
+- 
+- struct wl12xx_platform_data *wl12xx_get_platform_data(void)
+- {
+--	if (!platform_data)
+-+	if (!wl12xx_platform_data)
+- 		return ERR_PTR(-ENODEV);
+- 
+--	return platform_data;
+-+	return wl12xx_platform_data;
+- }
+- EXPORT_SYMBOL(wl12xx_get_platform_data);
+-+
+-+static struct wl1251_platform_data *wl1251_platform_data;
+-+
+-+int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
+-+{
+-+	if (wl1251_platform_data)
+-+		return -EBUSY;
+-+	if (!data)
+-+		return -EINVAL;
+-+
+-+	wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+-+	if (!wl1251_platform_data)
+-+		return -ENOMEM;
+-+
+-+	return 0;
+-+}
+-+
+-+struct wl1251_platform_data *wl1251_get_platform_data(void)
+-+{
+-+	if (!wl1251_platform_data)
+-+		return ERR_PTR(-ENODEV);
+-+
+-+	return wl1251_platform_data;
+-+}
+-+EXPORT_SYMBOL(wl1251_get_platform_data);
+---- a/drivers/net/wireless/ti/wl1251/sdio.c
+-+++ b/drivers/net/wireless/ti/wl1251/sdio.c
+-@@ -227,7 +227,7 @@ static int wl1251_sdio_probe(struct sdio
+- 	struct wl1251 *wl;
+- 	struct ieee80211_hw *hw;
+- 	struct wl1251_sdio *wl_sdio;
+--	const struct wl12xx_platform_data *wl12xx_board_data;
+-+	const struct wl1251_platform_data *wl1251_board_data;
+- 
+- 	hw = wl1251_alloc_hw();
+- 	if (IS_ERR(hw))
+-@@ -254,11 +254,11 @@ static int wl1251_sdio_probe(struct sdio
+- 	wl->if_priv = wl_sdio;
+- 	wl->if_ops = &wl1251_sdio_ops;
+- 
+--	wl12xx_board_data = wl12xx_get_platform_data();
+--	if (!IS_ERR(wl12xx_board_data)) {
+--		wl->set_power = wl12xx_board_data->set_power;
+--		wl->irq = wl12xx_board_data->irq;
+--		wl->use_eeprom = wl12xx_board_data->use_eeprom;
+-+	wl1251_board_data = wl1251_get_platform_data();
+-+	if (!IS_ERR(wl1251_board_data)) {
+-+		wl->set_power = wl1251_board_data->set_power;
+-+		wl->irq = wl1251_board_data->irq;
+-+		wl->use_eeprom = wl1251_board_data->use_eeprom;
+- 	}
+- 
+- 	if (wl->irq) {
+---- a/drivers/net/wireless/ti/wl1251/spi.c
+-+++ b/drivers/net/wireless/ti/wl1251/spi.c
+-@@ -241,7 +241,7 @@ static const struct wl1251_if_operations
+- 
+- static int wl1251_spi_probe(struct spi_device *spi)
+- {
+--	struct wl12xx_platform_data *pdata;
+-+	struct wl1251_platform_data *pdata;
+- 	struct ieee80211_hw *hw;
+- 	struct wl1251 *wl;
+- 	int ret;
+diff --git a/package/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch b/package/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch
+new file mode 100644
+index 0000000..967768a
+--- /dev/null
++++ b/package/mac80211/patches/900-wlcore-Add-support-for-DT-platform-data.patch
+@@ -0,0 +1,139 @@
++When running with DT, we no longer have a board file that can set up the
++platform data for wlcore. Allow this data to be passed from DT.
++
++Since some platforms use a gpio-irq, add support for passing either the
++irq number or the gpio number. For the latter case, the driver will
++request the gpio and convert it to the irq number. If an irq is
++specified, it'll be used as is.
++
++[Arik - the pdev_data pointer does not belong to us and is freed when
++the device is released. Dereference to our private data first.]
++
++Signed-off-by: Ido Yariv <ido@wizery.com>
++Signed-off-by: Arik Nemtsov <arik@wizery.com>
++---
++ drivers/net/wireless/ti/wlcore/sdio.c | 71 ++++++++++++++++++++++++++++++++---
++ include/linux/wl12xx.h                |  3 +-
++ 2 files changed, 67 insertions(+), 7 deletions(-)
++
++--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++++ b/drivers/net/wireless/ti/wlcore/sdio.c
++@@ -34,6 +34,7 @@
++ #include <linux/wl12xx.h>
++ #include <linux/pm_runtime.h>
++ #include <linux/printk.h>
+++#include <linux/of.h>
++ 
++ #include "wlcore.h"
++ #include "wl12xx_80211.h"
++@@ -214,6 +215,61 @@ static struct wl1271_if_operations sdio_
++ 	.set_block_size = wl1271_sdio_set_block_size,
++ };
++ 
+++static const struct of_device_id wlcore_of_match[] = {
+++	{
+++		.compatible = "wlcore",
+++	},
+++	{}
+++};
+++MODULE_DEVICE_TABLE(of, wlcore_of_match);
+++
+++static struct wl12xx_platform_data *get_platform_data(struct device *dev)
+++{
+++	struct wl12xx_platform_data *pdata;
+++	struct device_node *np;
+++	u32 gpio;
+++
+++	pdata = wl12xx_get_platform_data();
+++	if (!IS_ERR(pdata))
+++		return kmemdup(pdata, sizeof(*pdata), GFP_KERNEL);
+++
+++	np = of_find_matching_node(NULL, wlcore_of_match);
+++	if (!np) {
+++		dev_err(dev, "No platform data set\n");
+++		return NULL;
+++	}
+++
+++	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+++	if (!pdata) {
+++		dev_err(dev, "Can't allocate platform data\n");
+++		return NULL;
+++	}
+++
+++	if (of_property_read_u32(np, "irq", &pdata->irq)) {
+++		if (!of_property_read_u32(np, "gpio", &gpio) &&
+++		    !gpio_request_one(gpio, GPIOF_IN, "wlcore_irq")) {
+++			pdata->gpio = gpio;
+++			pdata->irq = gpio_to_irq(gpio);
+++		}
+++	}
+++
+++	/* Optional fields */
+++	pdata->use_eeprom = of_property_read_bool(np, "use-eeprom");
+++	of_property_read_u32(np, "board-ref-clock", &pdata->board_ref_clock);
+++	of_property_read_u32(np, "board-tcxo-clock", &pdata->board_tcxo_clock);
+++	of_property_read_u32(np, "platform-quirks", &pdata->platform_quirks);
+++
+++	return pdata;
+++}
+++
+++static void del_platform_data(struct wl12xx_platform_data *pdata)
+++{
+++	if (pdata->gpio)
+++		gpio_free(pdata->gpio);
+++
+++	kfree(pdata);
+++}
+++
++ static int wl1271_probe(struct sdio_func *func,
++ 				  const struct sdio_device_id *id)
++ {
++@@ -248,12 +304,9 @@ static int wl1271_probe(struct sdio_func
++ 	/* Use block mode for transferring over one block size of data */
++ 	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
++ 
++-	pdev_data->pdata = wl12xx_get_platform_data();
++-	if (IS_ERR(pdev_data->pdata)) {
++-		ret = PTR_ERR(pdev_data->pdata);
++-		dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
+++	pdev_data->pdata = get_platform_data(&func->dev);
+++	if (!(pdev_data->pdata))
++ 		goto out_free_glue;
++-	}
++ 
++ 	/* if sdio can keep power while host is suspended, enable wow */
++ 	mmcflags = sdio_get_host_pm_caps(func);
++@@ -282,7 +335,7 @@ static int wl1271_probe(struct sdio_func
++ 	if (!glue->core) {
++ 		dev_err(glue->dev, "can't allocate platform_device");
++ 		ret = -ENOMEM;
++-		goto out_free_glue;
+++		goto out_free_pdata;
++ 	}
++ 
++ 	glue->core->dev.parent = &func->dev;
++@@ -316,6 +369,9 @@ static int wl1271_probe(struct sdio_func
++ out_dev_put:
++ 	platform_device_put(glue->core);
++ 
+++out_free_pdata:
+++	del_platform_data(pdev_data->pdata);
+++
++ out_free_glue:
++ 	kfree(glue);
++ 
++@@ -329,11 +385,14 @@ out:
++ static void wl1271_remove(struct sdio_func *func)
++ {
++ 	struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
+++	struct wlcore_platdev_data *pdev_data = glue->core->dev.platform_data;
+++	struct wl12xx_platform_data *pdata = pdev_data->pdata;
++ 
++ 	/* Undo decrement done above in wl1271_probe */
++ 	pm_runtime_get_noresume(&func->dev);
++ 
++ 	platform_device_unregister(glue->core);
+++	del_platform_data(pdata);
++ 	kfree(glue);
++ }
++ 
+diff --git a/package/mac80211/patches/901-wl18xx-align-event-mailbox-with-current-fw.patch b/package/mac80211/patches/901-wl18xx-align-event-mailbox-with-current-fw.patch
+new file mode 100644
+index 0000000..77647bb
+--- /dev/null
++++ b/package/mac80211/patches/901-wl18xx-align-event-mailbox-with-current-fw.patch
+@@ -0,0 +1,47 @@
++From fde3f0a7f3112527a18e06e32efdd9a354c91b02 Mon Sep 17 00:00:00 2001
++From: Eliad Peller <eliad@wizery.com>
++Date: Tue, 18 Mar 2014 13:19:48 +0200
++Subject: [PATCH] wl18xx: align event mailbox with current fw
++
++Some fields are missing from the event mailbox
++struct definitions, which cause issues when
++trying to handle some events.
++
++Add the missing fields in order to align the
++struct size (without adding actual support
++for the new fields).
++
++Signed-off-by: Eliad Peller <eliad@wizery.com>
++---
++ drivers/net/wireless/ti/wl18xx/event.h | 20 ++++++++++++++++++++
++ 1 file changed, 20 insertions(+)
++
++--- a/drivers/net/wireless/ti/wl18xx/event.h
+++++ b/drivers/net/wireless/ti/wl18xx/event.h
++@@ -68,6 +68,26 @@ struct wl18xx_event_mailbox {
++ 
++ 	/* bitmap of inactive stations (by HLID) */
++ 	__le32 inactive_sta_bitmap;
+++
+++	/* rx BA win size indicated by RX_BA_WIN_SIZE_CHANGE_EVENT_ID */
+++	u8 rx_ba_role_id;
+++	u8 rx_ba_link_id;
+++	u8 rx_ba_win_size;
+++	u8 padding;
+++
+++	/* smart config */
+++	u8 sc_ssid_len;
+++	u8 sc_pwd_len;
+++	u8 sc_token_len;
+++	u8 padding1;
+++	u8 sc_ssid[32];
+++	u8 sc_pwd[32];
+++	u8 sc_token[32];
+++
+++	/* smart config sync channel */
+++	u8 sc_sync_channel;
+++	u8 sc_sync_band;
+++	u8 padding2[2];
++ } __packed;
++ 
++ int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
+diff --git a/package/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch b/package/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch
+deleted file mode 100644
+index f2789a9..0000000
+--- a/package/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch
++++ /dev/null
+@@ -1,118 +0,0 @@
+-The platform_quirk element in the platform data was used to change the
+-way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
+-the irqflags used and treat edge trigger differently from the rest.
+-
+-Instead of hiding this irq flag setting behind the quirk, have the
+-board files set the flags during initialization.  This will be more
+-meaningful than driver-specific quirks when we switch to DT.
+-
+-Additionally, fix missing gpio_request() calls in the boarding files
+-(so that setting the flags actually works).
+-
+-Cc: Tony Lindgren <tony@atomide.com>
+-Cc: Sekhar Nori <nsekhar@ti.com>
+-Signed-off-by: Luciano Coelho <coelho@ti.com>
+-Reviewed-by: Felipe Balbi <balbi@ti.com>
+-Acked-by: Sekhar Nori <nsekhar@ti.com>
+-
+---- a/drivers/net/wireless/ti/wlcore/debugfs.c
+-+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
+-@@ -502,7 +502,7 @@ static ssize_t driver_state_read(struct 
+- 	DRIVER_STATE_PRINT_HEX(irq);
+- 	/* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */
+- 	DRIVER_STATE_PRINT_HEX(hw_pg_ver);
+--	DRIVER_STATE_PRINT_HEX(platform_quirks);
+-+	DRIVER_STATE_PRINT_HEX(irq_flags);
+- 	DRIVER_STATE_PRINT_HEX(chip.id);
+- 	DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
+- 	DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
+---- a/drivers/net/wireless/ti/wlcore/main.c
+-+++ b/drivers/net/wireless/ti/wlcore/main.c
+-@@ -27,6 +27,7 @@
+- #include <linux/vmalloc.h>
+- #include <linux/wl12xx.h>
+- #include <linux/interrupt.h>
+-+#include <linux/irq.h>
+- 
+- #include "wlcore.h"
+- #include "debug.h"
+-@@ -528,7 +529,7 @@ static int wlcore_irq_locked(struct wl12
+- 	 * In case edge triggered interrupt must be used, we cannot iterate
+- 	 * more than once without introducing race conditions with the hardirq.
+- 	 */
+--	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+-+	if (wl->irq_flags & IRQF_TRIGGER_RISING)
+- 		loopcount = 1;
+- 
+- 	wl1271_debug(DEBUG_IRQ, "IRQ work");
+-@@ -5934,7 +5935,6 @@ struct ieee80211_hw *wlcore_alloc_hw(siz
+- 	wl->ap_ps_map = 0;
+- 	wl->ap_fw_ps_map = 0;
+- 	wl->quirks = 0;
+--	wl->platform_quirks = 0;
+- 	wl->system_hlid = WL12XX_SYSTEM_HLID;
+- 	wl->active_sta_count = 0;
+- 	wl->active_link_count = 0;
+-@@ -6075,7 +6075,7 @@ static void wlcore_nvs_cb(const struct f
+- 	struct platform_device *pdev = wl->pdev;
+- 	struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+- 	struct wl12xx_platform_data *pdata = pdev_data->pdata;
+--	unsigned long irqflags;
+-+
+- 	int ret;
+- 	irq_handler_t hardirq_fn = NULL;
+- 
+-@@ -6103,29 +6103,19 @@ static void wlcore_nvs_cb(const struct f
+- 	wlcore_adjust_conf(wl);
+- 
+- 	wl->irq = platform_get_irq(pdev, 0);
+--	wl->platform_quirks = pdata->platform_quirks;
+- 	wl->if_ops = pdev_data->if_ops;
+- 
+--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+--	irqflags = IRQF_TRIGGER_RISING;
+-+	wl->irq_flags = irq_get_trigger_type(wl->irq) | IRQF_ONESHOT;
+- 	hardirq_fn = wlcore_hardirq;
+--#else
+--	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) {
+--		irqflags = IRQF_TRIGGER_RISING;
+--		hardirq_fn = wlcore_hardirq;
+--	} else {
+--		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
+--	}
+--#endif
+- 
+- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
+- 	ret = compat_request_threaded_irq(&wl->irq_compat, wl->irq,
+- 					  hardirq_fn, wlcore_irq,
+--					  irqflags,
+-+					  wl->irqflags,
+- 					  pdev->name, wl);
+- #else
+- 	ret = request_threaded_irq(wl->irq, hardirq_fn, wlcore_irq,
+--				   irqflags, pdev->name, wl);
+-+				   wl->irq_flags, pdev->name, wl);
+- #endif
+- 	if (ret < 0) {
+- 		wl1271_error("request_irq() failed: %d", ret);
+---- a/drivers/net/wireless/ti/wlcore/wlcore.h
+-+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
+-@@ -188,6 +188,8 @@ struct wl1271 {
+- 
+- 	int irq;
+- 
+-+	int irq_flags;
+-+
+- 	spinlock_t wl_lock;
+- 
+- 	enum wlcore_state state;
+-@@ -395,9 +397,6 @@ struct wl1271 {
+- 	/* Quirks of specific hardware revisions */
+- 	unsigned int quirks;
+- 
+--	/* Platform limitations */
+--	unsigned int platform_quirks;
+--
+- 	/* number of currently active RX BA sessions */
+- 	int ba_rx_session_count;
+- 
+diff --git a/package/mac80211/patches/902-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch b/package/mac80211/patches/902-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch
+new file mode 100644
+index 0000000..3d501b2
+--- /dev/null
++++ b/package/mac80211/patches/902-wlcore-don-t-switch-channels-on-disconnected-STA-vif.patch
+@@ -0,0 +1,36 @@
++From 4101e8dc540d19f1f6c24930629149191786e4cd Mon Sep 17 00:00:00 2001
++From: Arik Nemtsov <arik@wizery.com>
++Date: Mon, 9 Sep 2013 16:48:59 +0300
++Subject: [PATCH 27/75] wlcore: don't switch channels on disconnected STA vifs
++
++Sending the FW a channel switch command on a disconnected vif may result
++in a beacon loss event. Avoid this edge case.
++
++Signed-off-by: Arik Nemtsov <arik@wizery.com>
++---
++ drivers/net/wireless/ti/wlcore/main.c | 7 +++++++
++ 1 file changed, 7 insertions(+)
++
++--- a/drivers/net/wireless/ti/wlcore/main.c
+++++ b/drivers/net/wireless/ti/wlcore/main.c
++@@ -5181,6 +5181,10 @@ static void wl12xx_op_channel_switch(str
++ 	if (unlikely(wl->state == WLCORE_STATE_OFF)) {
++ 		wl12xx_for_each_wlvif_sta(wl, wlvif) {
++ 			struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
+++
+++			if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+++				continue;
+++
++ 			ieee80211_chswitch_done(vif, false);
++ 		}
++ 		goto out;
++@@ -5196,6 +5200,9 @@ static void wl12xx_op_channel_switch(str
++ 	wl12xx_for_each_wlvif_sta(wl, wlvif) {
++ 		unsigned long delay_usec;
++ 
+++		if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+++			continue;
+++
++ 		ret = wl->ops->channel_switch(wl, wlvif, ch_switch);
++ 		if (ret)
++ 			goto out_sleep;
+diff --git a/package/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch b/package/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch
+deleted file mode 100644
+index 6394377..0000000
+--- a/package/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch
++++ /dev/null
+@@ -1,48 +0,0 @@
+-The pwr_in_suspend flag depends on the MMC settings which can be
+-retrieved from the SDIO subsystem, so it doesn't need to be part of
+-the platform data structure.  Move it to the platform device data that
+-is passed from SDIO to wlcore.
+-
+-Signed-off-by: Luciano Coelho <coelho@ti.com>
+-Reviewed-by: Felipe Balbi <balbi@ti.com>
+-
+---- a/drivers/net/wireless/ti/wlcore/main.c
+-+++ b/drivers/net/wireless/ti/wlcore/main.c
+-@@ -6074,7 +6074,6 @@ static void wlcore_nvs_cb(const struct f
+- 	struct wl1271 *wl = context;
+- 	struct platform_device *pdev = wl->pdev;
+- 	struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+--	struct wl12xx_platform_data *pdata = pdev_data->pdata;
+- 
+- 	int ret;
+- 	irq_handler_t hardirq_fn = NULL;
+-@@ -6127,7 +6126,7 @@ static void wlcore_nvs_cb(const struct f
+- 	if (!ret) {
+- 		wl->irq_wake_enabled = true;
+- 		device_init_wakeup(wl->dev, 1);
+--		if (pdata->pwr_in_suspend)
+-+		if (pdev_data->pwr_in_suspend)
+- 			wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
+- 	}
+- #endif
+---- a/drivers/net/wireless/ti/wlcore/sdio.c
+-+++ b/drivers/net/wireless/ti/wlcore/sdio.c
+-@@ -260,7 +260,7 @@ static int wl1271_probe(struct sdio_func
+- 	dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags);
+- 
+- 	if (mmcflags & MMC_PM_KEEP_POWER)
+--		pdev_data->pdata->pwr_in_suspend = true;
+-+		pdev_data->pwr_in_suspend = true;
+- 
+- 	sdio_set_drvdata(func, glue);
+- 
+---- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+-+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
+-@@ -209,6 +209,7 @@ struct wl1271_if_operations {
+- struct wlcore_platdev_data {
+- 	struct wl12xx_platform_data *pdata;
+- 	struct wl1271_if_operations *if_ops;
+-+	bool pwr_in_suspend;
+- };
+- 
+- #define MAX_NUM_KEYS 14
+diff --git a/package/mac80211/patches/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch b/package/mac80211/patches/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch
+deleted file mode 100644
+index 4b20932..0000000
+--- a/package/mac80211/patches/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch
++++ /dev/null
+@@ -1,131 +0,0 @@
+-Instead of defining an enumeration with the FW specific values for the
+-different clock rates, use the actual frequency instead.  Also add a
+-boolean to specify whether the clock is XTAL or not.
+-
+-Change all board files to reflect this.
+-
+-Additionally, this reverts commit 26f45c (ARM: OMAP2+: Legacy support
+-for wl12xx when booted with devicetree), since this is not be needed
+-anymore, now that DT support for WiLink is implemented.
+-
+-Cc: Tony Lindgren <tony@atomide.com>
+-Cc: Sekhar Nori <nsekhar@ti.com>
+-Signed-off-by: Luciano Coelho <coelho@ti.com>
+-Reviewed-by: Felipe Balbi <balbi@ti.com>
+-
+---- a/drivers/net/wireless/ti/wl12xx/main.c
+-+++ b/drivers/net/wireless/ti/wl12xx/main.c
+-@@ -1711,6 +1711,43 @@ static struct ieee80211_sta_ht_cap wl12x
+- 		},
+- };
+- 
+-+static const struct wl12xx_clock wl12xx_refclock_table[] = {
+-+	{ 19200000,	false,	WL12XX_REFCLOCK_19	},
+-+	{ 26000000,	false,	WL12XX_REFCLOCK_26	},
+-+	{ 26000000,	true,	WL12XX_REFCLOCK_26_XTAL	},
+-+	{ 38400000,	false,	WL12XX_REFCLOCK_38	},
+-+	{ 38400000,	true,	WL12XX_REFCLOCK_38_XTAL	},
+-+	{ 52000000,	false,	WL12XX_REFCLOCK_52	},
+-+	{ 0,		false,	0 }
+-+};
+-+
+-+static const struct wl12xx_clock wl12xx_tcxoclock_table[] = {
+-+	{ 16368000,	true,	WL12XX_TCXOCLOCK_16_368	},
+-+	{ 16800000,	true,	WL12XX_TCXOCLOCK_16_8	},
+-+	{ 19200000,	true,	WL12XX_TCXOCLOCK_19_2	},
+-+	{ 26000000,	true,	WL12XX_TCXOCLOCK_26	},
+-+	{ 32736000,	true,	WL12XX_TCXOCLOCK_32_736	},
+-+	{ 33600000,	true,	WL12XX_TCXOCLOCK_33_6	},
+-+	{ 38400000,	true,	WL12XX_TCXOCLOCK_38_4	},
+-+	{ 52000000,	true,	WL12XX_TCXOCLOCK_52	},
+-+	{ 0,		false,	0 }
+-+};
+-+
+-+static int wl12xx_get_clock_idx(const struct wl12xx_clock *table,
+-+				u32 freq, bool xtal)
+-+{
+-+	int i = 0;
+-+
+-+	while(table[i].freq != 0) {
+-+		if ((table[i].freq == freq) &&
+-+		    (table[i].xtal == xtal))
+-+			return table[i].hw_idx;
+-+		i++;
+-+	};
+-+
+-+	return -EINVAL;
+-+}
+-+
+- static int wl12xx_setup(struct wl1271 *wl)
+- {
+- 	struct wl12xx_priv *priv = wl->priv;
+-@@ -1732,7 +1769,16 @@ static int wl12xx_setup(struct wl1271 *w
+- 	wl12xx_conf_init(wl);
+- 
+- 	if (!fref_param) {
+--		priv->ref_clock = pdata->board_ref_clock;
+-+		priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table,
+-+						       pdata->ref_clock_freq,
+-+						       pdata->ref_clock_xtal);
+-+		if (priv->ref_clock < 0) {
+-+			wl1271_error("Invalid ref_clock frequency (%d Hz, %s)",
+-+				pdata->ref_clock_freq,
+-+				pdata->ref_clock_xtal ? "XTAL" : "not XTAL");
+-+
+-+			return priv->ref_clock;
+-+		}
+- 	} else {
+- 		if (!strcmp(fref_param, "19.2"))
+- 			priv->ref_clock = WL12XX_REFCLOCK_19;
+-@@ -1751,7 +1797,15 @@ static int wl12xx_setup(struct wl1271 *w
+- 	}
+- 
+- 	if (!tcxo_param) {
+--		priv->tcxo_clock = pdata->board_tcxo_clock;
+-+		priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table,
+-+							pdata->tcxo_clock_freq,
+-+							true);
+-+		if (priv->tcxo_clock < 0) {
+-+			wl1271_error("Invalid tcxo_clock frequency (%d Hz)",
+-+				pdata->tcxo_clock_freq);
+-+
+-+			return priv->tcxo_clock;
+-+		}
+- 	} else {
+- 		if (!strcmp(tcxo_param, "19.2"))
+- 			priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
+---- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
+-+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
+-@@ -79,4 +79,32 @@ struct wl12xx_priv {
+- 	struct wl127x_rx_mem_pool_addr *rx_mem_addr;
+- };
+- 
+-+/* Reference clock values */
+-+enum {
+-+	WL12XX_REFCLOCK_19	= 0, /* 19.2 MHz */
+-+	WL12XX_REFCLOCK_26	= 1, /* 26 MHz */
+-+	WL12XX_REFCLOCK_38	= 2, /* 38.4 MHz */
+-+	WL12XX_REFCLOCK_52	= 3, /* 52 MHz */
+-+	WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */
+-+	WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */
+-+};
+-+
+-+/* TCXO clock values */
+-+enum {
+-+	WL12XX_TCXOCLOCK_19_2	= 0, /* 19.2MHz */
+-+	WL12XX_TCXOCLOCK_26	= 1, /* 26 MHz */
+-+	WL12XX_TCXOCLOCK_38_4	= 2, /* 38.4MHz */
+-+	WL12XX_TCXOCLOCK_52	= 3, /* 52 MHz */
+-+	WL12XX_TCXOCLOCK_16_368	= 4, /* 16.368 MHz */
+-+	WL12XX_TCXOCLOCK_32_736	= 5, /* 32.736 MHz */
+-+	WL12XX_TCXOCLOCK_16_8	= 6, /* 16.8 MHz */
+-+	WL12XX_TCXOCLOCK_33_6	= 7, /* 33.6 MHz */
+-+};
+-+
+-+struct wl12xx_clock {
+-+	u32	freq;
+-+	bool	xtal;
+-+	u8	hw_idx;
+-+};
+-+
+- #endif /* __WL12XX_PRIV_H__ */
+diff --git a/package/mac80211/patches/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch b/package/mac80211/patches/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch
+deleted file mode 100644
+index 9e1d190..0000000
+--- a/package/mac80211/patches/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch
++++ /dev/null
+@@ -1,118 +0,0 @@
+-If platform data is not available, try to get the required information
+-from the device tree.  Register an OF match table and parse the
+-appropriate device tree nodes.
+-
+-Parse interrupt property only, for now.
+-
+-Signed-off-by: Luciano Coelho <coelho@ti.com>
+-Reviewed-by: Felipe Balbi <balbi@ti.com>
+-
+---- a/drivers/net/wireless/ti/wlcore/sdio.c
+-+++ b/drivers/net/wireless/ti/wlcore/sdio.c
+-@@ -30,7 +30,7 @@
+- #include <linux/mmc/sdio_ids.h>
+- #include <linux/mmc/card.h>
+- #include <linux/mmc/host.h>
+--#include <linux/gpio.h>
+-+#include <linux/of_irq.h>
+- #include <linux/wl12xx.h>
+- #include <linux/pm_runtime.h>
+- #include <linux/printk.h>
+-@@ -214,6 +214,43 @@ static struct wl1271_if_operations sdio_
+- 	.set_block_size = wl1271_sdio_set_block_size,
+- };
+- 
+-+static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
+-+{
+-+	struct wl12xx_platform_data *pdata;
+-+	struct device_node *np = dev->of_node;
+-+
+-+	if (!np) {
+-+		np = of_find_matching_node(NULL, dev->driver->of_match_table);
+-+		if (!np) {
+-+			dev_notice(dev, "device tree node not available\n");
+-+			pdata = ERR_PTR(-ENODEV);
+-+			goto out;
+-+		}
+-+	}
+-+
+-+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+-+	if (!pdata) {
+-+		dev_err(dev, "can't allocate platform data\n");
+-+		pdata = ERR_PTR(-ENODEV);
+-+		goto out;
+-+	}
+-+
+-+	pdata->irq = irq_of_parse_and_map(np, 0);
+-+	if (pdata->irq < 0) {
+-+		dev_err(dev, "can't get interrupt gpio from the device tree\n");
+-+		goto out_free;
+-+	}
+-+
+-+	goto out;
+-+
+-+out_free:
+-+	kfree(pdata);
+-+	pdata = ERR_PTR(-ENODEV);
+-+
+-+out:
+-+	return pdata;
+-+}
+-+
+- static int wl1271_probe(struct sdio_func *func,
+- 				  const struct sdio_device_id *id)
+- {
+-@@ -248,11 +285,22 @@ static int wl1271_probe(struct sdio_func
+- 	/* Use block mode for transferring over one block size of data */
+- 	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+- 
+-+	/* The pdata allocated here is freed when the device is freed,
+-+	 * so we don't need an additional out label to free it in case
+-+	 * of error further on.
+-+	 */
+-+
+-+	/* Try to get legacy platform data from the board file */
+- 	pdev_data->pdata = wl12xx_get_platform_data();
+- 	if (IS_ERR(pdev_data->pdata)) {
+--		ret = PTR_ERR(pdev_data->pdata);
+--		dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
+--		goto out_free_glue;
+-+		dev_info(&func->dev,
+-+			 "legacy platform data not found, trying device tree\n");
+-+
+-+		pdev_data->pdata = wlcore_get_pdata_from_of(&func->dev);
+-+		if (IS_ERR(pdev_data->pdata)) {
+-+			dev_err(&func->dev, "can't get platform data\n");
+-+			goto out_free_glue;
+-+		}
+- 	}
+- 
+- 	/* if sdio can keep power while host is suspended, enable wow */
+-@@ -386,16 +434,25 @@ static const struct dev_pm_ops wl1271_sd
+- };
+- #endif
+- 
+-+static const struct of_device_id wlcore_sdio_of_match_table[] = {
+-+	{ .compatible = "ti,wilink6" },
+-+	{ .compatible = "ti,wilink7" },
+-+	{ .compatible = "ti,wilink8" },
+-+	{ }
+-+};
+-+MODULE_DEVICE_TABLE(of, wlcore_sdio_of_match_table);
+-+
+- static struct sdio_driver wl1271_sdio_driver = {
+- 	.name		= "wl1271_sdio",
+- 	.id_table	= wl1271_devices,
+- 	.probe		= wl1271_probe,
+- 	.remove		= wl1271_remove,
+--#ifdef CONFIG_PM
+- 	.drv = {
+-+#ifdef CONFIG_PM
+- 		.pm = &wl1271_sdio_pm_ops,
+--	},
+- #endif
+-+		.of_match_table = of_match_ptr(wlcore_sdio_of_match_table),
+-+	},
+- };
+- 
+- static int __init wl1271_init(void)
+diff --git a/package/mac80211/patches/905-wlcore-sdio-add-wilink-clock-providers.patch b/package/mac80211/patches/905-wlcore-sdio-add-wilink-clock-providers.patch
+deleted file mode 100644
+index be1f9ad..0000000
+--- a/package/mac80211/patches/905-wlcore-sdio-add-wilink-clock-providers.patch
++++ /dev/null
+@@ -1,50 +0,0 @@
+-Add refclock and tcxoclock as clock providers in WiLink.  These clocks
+-are not accesible outside the WiLink module, but they are registered
+-in the clock framework anyway.  Only the WiLink chip consumes these
+-clocks.
+-
+-In theory, the WiLink chip could be connected to external clocks
+-instead of using these internal clocks, so make the clock consumer
+-code generic enough.  If external clocks are used, then the internal
+-clock device tree nodes are not necessary, but the external ones must
+-be specified.
+-
+-Signed-off-by: Luciano Coelho <coelho@ti.com>
+-Reviewed-by: Felipe Balbi <balbi@ti.com>
+-
+---- a/drivers/net/wireless/ti/wlcore/sdio.c
+-+++ b/drivers/net/wireless/ti/wlcore/sdio.c
+-@@ -34,6 +34,7 @@
+- #include <linux/wl12xx.h>
+- #include <linux/pm_runtime.h>
+- #include <linux/printk.h>
+-+#include <linux/clk-provider.h>
+- 
+- #include "wlcore.h"
+- #include "wl12xx_80211.h"
+-@@ -214,10 +215,15 @@ static struct wl1271_if_operations sdio_
+- 	.set_block_size = wl1271_sdio_set_block_size,
+- };
+- 
+-+static const struct of_device_id wlcore_sdio_of_clk_match_table[] = {
+-+	{ .compatible = "ti,wilink-clock" },
+-+};
+-+
+- static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
+- {
+- 	struct wl12xx_platform_data *pdata;
+- 	struct device_node *np = dev->of_node;
+-+	struct device_node *clock_node;
+- 
+- 	if (!np) {
+- 		np = of_find_matching_node(NULL, dev->driver->of_match_table);
+-@@ -241,6 +247,9 @@ static struct wl12xx_platform_data *wlco
+- 		goto out_free;
+- 	}
+- 
+-+	for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
+-+		of_fixed_clk_setup(clock_node);
+-+
+- 	goto out;
+- 
+- out_free:
+diff --git a/package/mac80211/patches/906-wlcore-sdio-get-clocks-from-device-tree.patch b/package/mac80211/patches/906-wlcore-sdio-get-clocks-from-device-tree.patch
+deleted file mode 100644
+index 09ff4af..0000000
+--- a/package/mac80211/patches/906-wlcore-sdio-get-clocks-from-device-tree.patch
++++ /dev/null
+@@ -1,90 +0,0 @@
+-Read the clock nodes from the device tree and use them to set the
+-frequency for the refclock and the tcxo clock.
+-
+-Also, call sdio_set_drvdata() earlier, so the glue is already set in
+-the driver data when we call wlcore_get_pdata_from_of() and we don't
+-need to pass it as a parameter.
+-
+-Signed-off-by: Luciano Coelho <coelho@ti.com>
+-Reviewed-by: Felipe Balbi <balbi@ti.com>
+-
+---- a/drivers/net/wireless/ti/wlcore/sdio.c
+-+++ b/drivers/net/wireless/ti/wlcore/sdio.c
+-@@ -53,6 +53,7 @@ static bool dump = false;
+- struct wl12xx_sdio_glue {
+- 	struct device *dev;
+- 	struct platform_device *core;
+-+	struct clk *refclock, *tcxoclock;
+- };
+- 
+- static const struct sdio_device_id wl1271_devices[] = {
+-@@ -224,6 +225,7 @@ static struct wl12xx_platform_data *wlco
+- 	struct wl12xx_platform_data *pdata;
+- 	struct device_node *np = dev->of_node;
+- 	struct device_node *clock_node;
+-+	struct wl12xx_sdio_glue *glue = sdio_get_drvdata(dev_to_sdio_func(dev));
+- 
+- 	if (!np) {
+- 		np = of_find_matching_node(NULL, dev->driver->of_match_table);
+-@@ -250,6 +252,26 @@ static struct wl12xx_platform_data *wlco
+- 	for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
+- 		of_fixed_clk_setup(clock_node);
+- 
+-+	/* TODO: make sure we have this when needed (ie. for WL6 and WL7) */
+-+	glue->refclock = of_clk_get_by_name(np, "refclock");
+-+	if (IS_ERR(glue->refclock)) {
+-+		dev_err(dev, "couldn't find refclock on the device tree\n");
+-+		glue->refclock = NULL;
+-+	} else {
+-+		clk_prepare_enable(glue->refclock);
+-+		pdata->ref_clock_freq = clk_get_rate(glue->refclock);
+-+	}
+-+
+-+	/* TODO: make sure we have this when needed (ie. for WL7) */
+-+	glue->tcxoclock = of_clk_get_by_name(np, "tcxoclock");
+-+	if (IS_ERR(glue->tcxoclock)) {
+-+		dev_err(dev, "couldn't find tcxoclock on the device tree\n");
+-+		glue->tcxoclock = NULL;
+-+	} else {
+-+		clk_prepare_enable(glue->tcxoclock);
+-+		pdata->ref_clock_freq = clk_get_rate(glue->tcxoclock);
+-+	}
+-+
+- 	goto out;
+- 
+- out_free:
+-@@ -294,6 +316,8 @@ static int wl1271_probe(struct sdio_func
+- 	/* Use block mode for transferring over one block size of data */
+- 	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+- 
+-+	sdio_set_drvdata(func, glue);
+-+
+- 	/* The pdata allocated here is freed when the device is freed,
+- 	 * so we don't need an additional out label to free it in case
+- 	 * of error further on.
+-@@ -319,8 +343,6 @@ static int wl1271_probe(struct sdio_func
+- 	if (mmcflags & MMC_PM_KEEP_POWER)
+- 		pdev_data->pwr_in_suspend = true;
+- 
+--	sdio_set_drvdata(func, glue);
+--
+- 	/* Tell PM core that we don't need the card to be powered now */
+- 	pm_runtime_put_noidle(&func->dev);
+- 
+-@@ -387,6 +409,16 @@ static void wl1271_remove(struct sdio_fu
+- {
+- 	struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
+- 
+-+	if (glue->refclock) {
+-+		clk_disable_unprepare(glue->refclock);
+-+		clk_put(glue->refclock);
+-+	}
+-+
+-+	if (glue->tcxoclock) {
+-+		clk_disable_unprepare(glue->tcxoclock);
+-+		clk_put(glue->tcxoclock);
+-+	}
+-+
+- 	/* Undo decrement done above in wl1271_probe */
+- 	pm_runtime_get_noresume(&func->dev);
+- 
+diff --git a/package/mac80211/patches/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch b/package/mac80211/patches/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch
+deleted file mode 100644
+index 6b09177..0000000
+--- a/package/mac80211/patches/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch
++++ /dev/null
+@@ -1,96 +0,0 @@
+-The fref and the tcxo clocks settings are optional in some platforms.
+-WiLink8 doesn't need either, so we don't check the values.  WiLink 6
+-only needs the fref clock, so we check that it is valid or return with
+-an error.  WiLink7 needs both clocks, if either is not available we
+-return with an error.
+-
+-Signed-off-by: Luciano Coelho <coelho@ti.com>
+-Reviewed-by: Felipe Balbi <balbi@ti.com>
+-
+---- a/drivers/net/wireless/ti/wl12xx/main.c
+-+++ b/drivers/net/wireless/ti/wl12xx/main.c
+-@@ -930,6 +930,11 @@ static int wl128x_boot_clk(struct wl1271
+- 	u16 sys_clk_cfg;
+- 	int ret;
+- 
+-+	if ((priv->ref_clock < 0) || (priv->tcxo_clock < 0)) {
+-+		wl1271_error("Missing fref and/or tcxo clock settings\n");
+-+		return -EINVAL;
+-+	}
+-+
+- 	/* For XTAL-only modes, FREF will be used after switching from TCXO */
+- 	if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
+- 	    priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
+-@@ -979,6 +984,11 @@ static int wl127x_boot_clk(struct wl1271
+- 	u32 clk;
+- 	int ret;
+- 
+-+	if (priv->ref_clock < 0) {
+-+		wl1271_error("Missing fref clock settings\n");
+-+		return -EINVAL;
+-+	}
+-+
+- 	if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
+- 		wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
+- 
+-@@ -1768,7 +1778,7 @@ static int wl12xx_setup(struct wl1271 *w
+- 	wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap);
+- 	wl12xx_conf_init(wl);
+- 
+--	if (!fref_param) {
+-+	if (!fref_param && (pdata->ref_clock_freq > 0)) {
+- 		priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table,
+- 						       pdata->ref_clock_freq,
+- 						       pdata->ref_clock_xtal);
+-@@ -1779,6 +1789,8 @@ static int wl12xx_setup(struct wl1271 *w
+- 
+- 			return priv->ref_clock;
+- 		}
+-+	} else if (!fref_param) {
+-+		priv->ref_clock = -EINVAL;
+- 	} else {
+- 		if (!strcmp(fref_param, "19.2"))
+- 			priv->ref_clock = WL12XX_REFCLOCK_19;
+-@@ -1796,7 +1808,7 @@ static int wl12xx_setup(struct wl1271 *w
+- 			wl1271_error("Invalid fref parameter %s", fref_param);
+- 	}
+- 
+--	if (!tcxo_param) {
+-+	if (!fref_param && (pdata->tcxo_clock_freq > 0)) {
+- 		priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table,
+- 							pdata->tcxo_clock_freq,
+- 							true);
+-@@ -1806,7 +1818,9 @@ static int wl12xx_setup(struct wl1271 *w
+- 
+- 			return priv->tcxo_clock;
+- 		}
+--	} else {
+-+	} else if (!fref_param) {
+-+		priv->tcxo_clock = -EINVAL;
+-+	}else {
+- 		if (!strcmp(tcxo_param, "19.2"))
+- 			priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
+- 		else if (!strcmp(tcxo_param, "26"))
+---- a/drivers/net/wireless/ti/wlcore/sdio.c
+-+++ b/drivers/net/wireless/ti/wlcore/sdio.c
+-@@ -252,20 +252,16 @@ static struct wl12xx_platform_data *wlco
+- 	for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
+- 		of_fixed_clk_setup(clock_node);
+- 
+--	/* TODO: make sure we have this when needed (ie. for WL6 and WL7) */
+- 	glue->refclock = of_clk_get_by_name(np, "refclock");
+- 	if (IS_ERR(glue->refclock)) {
+--		dev_err(dev, "couldn't find refclock on the device tree\n");
+- 		glue->refclock = NULL;
+- 	} else {
+- 		clk_prepare_enable(glue->refclock);
+- 		pdata->ref_clock_freq = clk_get_rate(glue->refclock);
+- 	}
+- 
+--	/* TODO: make sure we have this when needed (ie. for WL7) */
+- 	glue->tcxoclock = of_clk_get_by_name(np, "tcxoclock");
+- 	if (IS_ERR(glue->tcxoclock)) {
+--		dev_err(dev, "couldn't find tcxoclock on the device tree\n");
+- 		glue->tcxoclock = NULL;
+- 	} else {
+- 		clk_prepare_enable(glue->tcxoclock);