mac80211: update to 2011-08-10
authorFelix Fietkau <nbd@openwrt.org>
Thu, 11 Aug 2011 13:52:27 +0000 (13:52 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Thu, 11 Aug 2011 13:52:27 +0000 (13:52 +0000)
SVN-Revision: 27958

67 files changed:
package/mac80211/Makefile
package/mac80211/patches/001-disable_b44.patch
package/mac80211/patches/002-disable_rfkill.patch
package/mac80211/patches/005-disable_ssb_build.patch
package/mac80211/patches/006-disable_bcma_build.patch
package/mac80211/patches/007-remove_misc_drivers.patch
package/mac80211/patches/011-no_sdio.patch
package/mac80211/patches/013-disable_b43_nphy.patch
package/mac80211/patches/015-remove-rt2x00-options.patch
package/mac80211/patches/018-revert_printk_va_format.patch
package/mac80211/patches/020-netlink_seq.patch [deleted file]
package/mac80211/patches/022-atomic64_backport.patch
package/mac80211/patches/040-fix_compile_on_2.6.30.patch [deleted file]
package/mac80211/patches/110-disable_usb_compat.patch
package/mac80211/patches/120-pr_fmt_warnings.patch
package/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch
package/mac80211/patches/300-pending_work.patch
package/mac80211/patches/310-ibss_ht.patch
package/mac80211/patches/402-ath9k_blink_default.patch
package/mac80211/patches/403-ath9k-fix-invalid-mac-address-handling.patch
package/mac80211/patches/406-regd_no_assoc_hints.patch
package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch
package/mac80211/patches/430-ath5k_disable_fast_cc.patch
package/mac80211/patches/440-ath5k_calibrate_srev_checks.patch [deleted file]
package/mac80211/patches/441-ath5k_synth_voltage_srev_check.patch [deleted file]
package/mac80211/patches/442-ath5k_spur_channel_srev_check.patch [deleted file]
package/mac80211/patches/443-ath5k_initialize_clockrate.patch [deleted file]
package/mac80211/patches/444-ath5k_delay_calibration.patch [deleted file]
package/mac80211/patches/445-ath5k_fix_mac_clock_restore.patch [deleted file]
package/mac80211/patches/446-ath5k_disable_32khz_clock.patch [deleted file]
package/mac80211/patches/447-ath5k_fix_queue_stop_warning.patch [deleted file]
package/mac80211/patches/500-ath9k_eeprom_debugfs.patch
package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch
package/mac80211/patches/511-ath9k_increase_bcbuf.patch
package/mac80211/patches/512-ath9k_reduce_rxbuf.patch
package/mac80211/patches/513-ath9k_channelbw_debugfs.patch
package/mac80211/patches/530-ath9k_noise_dbm_fixup.patch [deleted file]
package/mac80211/patches/530-mac80211_cur_txpower.patch [new file with mode: 0644]
package/mac80211/patches/531-ath9k_cur_txpower.patch [new file with mode: 0644]
package/mac80211/patches/540-ath9k_rx_stop.patch [deleted file]
package/mac80211/patches/540-ath9k_sw_retry_reduce.patch [new file with mode: 0644]
package/mac80211/patches/541-ath9k_aggr_queue_cleanup.patch [new file with mode: 0644]
package/mac80211/patches/542-ath9k_limit_qlen.patch [new file with mode: 0644]
package/mac80211/patches/550-mac80211_cur_txpower.patch [deleted file]
package/mac80211/patches/551-ath9k_initialize_chainmask.patch [deleted file]
package/mac80211/patches/552-ath9k_remove_tx_indexoffset.patch [deleted file]
package/mac80211/patches/553-ath9k_fix_rate_power.patch [deleted file]
package/mac80211/patches/554-ath9k_test_txpower.patch [deleted file]
package/mac80211/patches/555-ath9k_cur_txpower.patch [deleted file]
package/mac80211/patches/560-ath9k_ps_tx_aggr_fix.patch [deleted file]
package/mac80211/patches/570-mac80211_send_bar.patch [deleted file]
package/mac80211/patches/571-ath9k_send_bar_fix.patch [deleted file]
package/mac80211/patches/572-ath9k_sw_retry_reduce.patch [deleted file]
package/mac80211/patches/573-ath9k_aggr_queue_cleanup.patch [deleted file]
package/mac80211/patches/574-ath9k_limit_qlen.patch [deleted file]
package/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch
package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch
package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch
package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch
package/mac80211/patches/800-b43-gpio-mask-module-option.patch
package/mac80211/patches/810-b43_no_pio.patch
package/mac80211/patches/820-b43-backport.patch [deleted file]
package/mac80211/patches/830-b43-read-correct-register-on-bcma-bus.patch [deleted file]
package/mac80211/patches/840-b43-bus_fix_memory_corruption_when_setting_drivers.patch [deleted file]
package/mac80211/patches/850-b43-add-core-rev-17-used-on-bcma-SoC.patch [deleted file]
package/mac80211/patches/860-b43_restart_config.patch [deleted file]

index 3774979..cb1080f 100644 (file)
@@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=2011-06-22
-PKG_RELEASE:=2
+PKG_VERSION:=2011-08-10
+PKG_RELEASE:=1
 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
-PKG_MD5SUM:=3ffdd5cecedcf4236f599bdbc55ba10d
+PKG_MD5SUM:=fb2ee04eaafbdf4117c475ba78f8f5b9
 
 PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
index 7e6018f..547a453 100644 (file)
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
-@@ -337,8 +337,8 @@ CONFIG_BCMA_HOST_PCI=y
+@@ -339,8 +339,8 @@ CONFIG_B43_BCMA_PIO=y
  
  CONFIG_P54_PCI=m
  
index 1cb319e..887b995 100644 (file)
@@ -9,7 +9,7 @@
  
  ifeq ($(CONFIG_MAC80211),y)
  $(error "ERROR: you have MAC80211 compiled into the kernel, CONFIG_MAC80211=y, as such you cannot replace its mac80211 driver. You need this set to CONFIG_MAC80211=m. If you are using Fedora upgrade your kernel as later version should this set as modular. For further information on Fedora see https://bugzilla.redhat.com/show_bug.cgi?id=470143. If you are using your own kernel recompile it and make mac80211 modular")
-@@ -646,10 +646,10 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27
+@@ -649,10 +649,10 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27
  # We need the backported rfkill module on kernel < 2.6.31.
  # In more recent kernel versions use the in kernel rfkill module.
  ifdef CONFIG_COMPAT_KERNEL_2_6_31
index b067956..04bf827 100644 (file)
@@ -19,7 +19,7 @@
  else
  include $(KLIB_BUILD)/.config
  endif
-@@ -314,7 +313,8 @@ CONFIG_IPW2200_QOS=y
+@@ -315,7 +314,8 @@ CONFIG_IPW2200_QOS=y
  # % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
  endif #CONFIG_WIRELESS_EXT
  
@@ -29,7 +29,7 @@
  # Sonics Silicon Backplane
  CONFIG_SSB_SPROM=y
  
-@@ -327,7 +327,7 @@ endif #CONFIG_PCMCIA
+@@ -328,7 +328,7 @@ endif #CONFIG_PCMCIA
  # CONFIG_SSB_DEBUG=y
  CONFIG_SSB_DRIVER_PCICORE=y
  CONFIG_B43_SSB=y
@@ -38,7 +38,7 @@
  
  CONFIG_BCMA=m
  CONFIG_BCMA_BLOCKIO=y
-@@ -534,7 +534,6 @@ endif #CONFIG_SPI_MASTER end of SPI driv
+@@ -537,7 +537,6 @@ endif #CONFIG_SPI_MASTER end of SPI driv
  
  ifdef CONFIG_MMC
  
index 6912f67..93d00cd 100644 (file)
@@ -11,7 +11,7 @@
  obj-$(CONFIG_COMPAT_STAGING) += drivers/staging/ath6kl/
 --- a/config.mk
 +++ b/config.mk
-@@ -329,9 +329,9 @@ CONFIG_SSB_DRIVER_PCICORE=y
+@@ -330,9 +330,9 @@ CONFIG_SSB_DRIVER_PCICORE=y
  CONFIG_B43_SSB=y
  endif #__CONFIG_SSB
  
@@ -22,5 +22,5 @@
 +# CONFIG_BCMA_BLOCKIO=y
 +# CONFIG_BCMA_HOST_PCI=y
  # CONFIG_BCMA_DEBUG=y
CONFIG_B43_BCMA=y
+ CONFIG_B43_BCMA=y
+ CONFIG_B43_BCMA_PIO=y
index 37c03f2..cdf9e03 100644 (file)
@@ -9,7 +9,7 @@
  endif #CONFIG_STAGING
  
  # mac80211 test driver
-@@ -365,13 +365,13 @@ endif #CONFIG_CRC_ITU_T
+@@ -367,13 +367,13 @@ endif #CONFIG_CRC_ITU_T
  CONFIG_MWL8K=m
  
  # Ethernet drivers go here
@@ -28,7 +28,7 @@
  endif #CONFIG_COMPAT_KERNEL_2_6_27
  
  ifdef CONFIG_WIRELESS_EXT
-@@ -431,21 +431,21 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
+@@ -434,21 +434,21 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
  # Note: this depends on CONFIG_USB_NET_RNDIS_HOST and CONFIG_USB_NET_CDCETHER
  # it also requires new RNDIS_HOST and CDC_ETHER modules which we add
  ifdef CONFIG_COMPAT_KERNEL_2_6_29
index 857020e..bb6be23 100644 (file)
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
-@@ -517,7 +517,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv
+@@ -520,7 +520,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv
  
  ifdef CONFIG_MMC
  
index 63ae11d..ebbf912 100644 (file)
@@ -7,5 +7,5 @@
 -CONFIG_B43_PHY_N=y
 +# CONFIG_B43_PHY_N=y
  # CONFIG_B43_PHY_HT=y
+ # CONFIG_B43_PHY_LCN=y
  # CONFIG_B43_FORCE_PIO=y
- # CONFIG_B43_DEBUG=y
index 86556d7..3bed5b2 100644 (file)
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
-@@ -327,7 +327,7 @@ CONFIG_RTL8180=m
+@@ -329,7 +329,7 @@ CONFIG_RTL8180=m
  
  CONFIG_ADM8211=m
  
@@ -9,7 +9,7 @@
  CONFIG_RT2400PCI=m
  CONFIG_RT2500PCI=m
  ifdef CONFIG_CRC_CCITT
-@@ -466,7 +466,7 @@ CONFIG_RT2800USB_RT35XX=y
+@@ -469,7 +469,7 @@ CONFIG_RT2800USB_RT35XX=y
  # CONFIG_RT2800USB_RT53XX=y
  CONFIG_RT2800USB_UNKNOWN=y
  endif #CONFIG_CRC_CCITT
index 960a65b..8b7e644 100644 (file)
@@ -98,7 +98,7 @@
  
 --- a/drivers/net/wireless/b43legacy/main.c
 +++ b/drivers/net/wireless/b43legacy/main.c
-@@ -181,75 +181,52 @@ static int b43legacy_ratelimit(struct b4
+@@ -180,75 +180,52 @@ static int b43legacy_ratelimit(struct b4
  
  void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...)
  {
diff --git a/package/mac80211/patches/020-netlink_seq.patch b/package/mac80211/patches/020-netlink_seq.patch
deleted file mode 100644 (file)
index 2897b40..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -3728,7 +3728,9 @@ static int nl80211_dump_scan(struct sk_b
-       spin_lock_bh(&rdev->bss_lock);
-       cfg80211_bss_expire(rdev);
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0))
-       cb->seq = rdev->bss_generation;
-+#endif
-       list_for_each_entry(scan, &rdev->bss_list, list) {
-               if (++idx <= start)
index 7589d73..17df9c9 100644 (file)
@@ -11,9 +11,9 @@
 +endif
 --- a/include/linux/compat-2.6.31.h
 +++ b/include/linux/compat-2.6.31.h
-@@ -199,6 +199,20 @@ void compat_synchronize_threaded_irq(str
- #define list_entry_rcu(ptr, type, member) \
-       container_of(rcu_dereference(ptr), type, member)
+@@ -202,6 +202,20 @@ void compat_synchronize_threaded_irq(str
+ #define skb_walk_frags(skb, iter)     \
+       for (iter = skb_shinfo(skb)->frag_list; iter; iter = iter->next)
  
 +#ifndef CONFIG_64BIT
 +
@@ -70,9 +70,9 @@
 +
 --- a/include/linux/compat-3.1.h
 +++ b/include/linux/compat-3.1.h
-@@ -24,6 +24,18 @@
- #define genl_dump_check_consistent(...) do {} while(0)
+@@ -36,6 +36,18 @@
+       .prod_id = { NULL, NULL, (v3), NULL }, \
+       .prod_id_hash = { 0, 0, (vh3), 0 }, }
  
 +/*
 + * In many versions, several architectures do not seem to include an
diff --git a/package/mac80211/patches/040-fix_compile_on_2.6.30.patch b/package/mac80211/patches/040-fix_compile_on_2.6.30.patch
deleted file mode 100644 (file)
index 2773585..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/drivers/net/wireless/b43/main.c~ 2011-07-23 00:33:46.573306410 +0200
-+++ b/drivers/net/wireless/b43/main.c  2011-07-23 00:36:14.657726075 +0200
-@@ -4955,7 +4955,7 @@
- static void b43_wireless_core_detach(struct b43_wldev *dev)
- {
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
--      if (dev->sdev->bus->bustype != SSB_BUSTYPE_SDIO)
-+      if (dev->dev->sdev->bus->bustype != SSB_BUSTYPE_SDIO)
-               compat_destroy_threaded_irq(&dev->irq_compat);
- #endif
-       /* We release firmware that late to not be required to re-request
index 5738dd0..dda9699 100644 (file)
@@ -33,7 +33,7 @@
  #endif
 --- a/config.mk
 +++ b/config.mk
-@@ -452,7 +452,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
+@@ -455,7 +455,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
  # This activates a threading fix for usb urb.
  # this is mainline commit: b3e670443b7fb8a2d29831b62b44a039c283e351
  # This fix will be included in some stable releases.
index 6de5fd6..9b69328 100644 (file)
@@ -1,13 +1,3 @@
---- a/drivers/net/wireless/iwlwifi/iwl-agn.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
-@@ -27,6 +27,7 @@
-  *
-  *****************************************************************************/
-+#undef pr_fmt
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
- #include <linux/kernel.h>
 --- a/drivers/net/wireless/iwlegacy/iwl3945-base.c
 +++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c
 @@ -27,6 +27,7 @@
@@ -27,7 +17,7 @@
 +#undef pr_fmt
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  
- #include <linux/slab.h>
+ #include <linux/hardirq.h>
 --- a/drivers/net/wireless/libertas_tf/if_usb.c
 +++ b/drivers/net/wireless/libertas_tf/if_usb.c
 @@ -9,6 +9,7 @@
@@ -47,7 +37,7 @@
 +#undef pr_fmt
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  
- #include <linux/slab.h>
+ #include <linux/hardirq.h>
 --- a/net/wireless/core.c
 +++ b/net/wireless/core.c
 @@ -4,6 +4,7 @@
 +#undef pr_fmt
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  
- #include <linux/sched.h>
+ #include <linux/hardirq.h>
 --- a/drivers/net/wireless/libertas/if_cs.c
 +++ b/drivers/net/wireless/libertas/if_cs.c
 @@ -21,6 +21,7 @@
 +#undef pr_fmt
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  
- #include <linux/moduleparam.h>
+ #include <linux/hardirq.h>
 --- a/drivers/net/wireless/libertas/if_usb.c
 +++ b/drivers/net/wireless/libertas/if_usb.c
 @@ -2,6 +2,7 @@
index d181971..c1f18af 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath5k/initvals.c
 +++ b/drivers/net/wireless/ath/ath5k/initvals.c
-@@ -58,8 +58,14 @@ static const struct ath5k_ini ar5210_ini
+@@ -57,8 +57,14 @@ static const struct ath5k_ini ar5210_ini
        { AR5K_IMR,             0 },
        { AR5K_IER,             AR5K_IER_DISABLE },
        { AR5K_BSR,             0, AR5K_INI_READ },
@@ -17,7 +17,7 @@
        { AR5K_RXNOFRM,         8 },
 --- a/drivers/net/wireless/ath/ath5k/dma.c
 +++ b/drivers/net/wireless/ath/ath5k/dma.c
-@@ -787,10 +787,18 @@ void ath5k_hw_dma_init(struct ath5k_hw *
+@@ -786,10 +786,18 @@ void ath5k_hw_dma_init(struct ath5k_hw *
         * guess we can tweak it and see how it goes ;-)
         */
        if (ah->ah_version != AR5K_AR5210) {
index a36f99c..7e337c6 100644 (file)
@@ -1,6 +1,107 @@
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -320,6 +320,10 @@ static void b43_wireless_core_exit(struc
+ static int b43_wireless_core_init(struct b43_wldev *dev);
+ static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
+ static int b43_wireless_core_start(struct b43_wldev *dev);
++static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
++                                  struct ieee80211_vif *vif,
++                                  struct ieee80211_bss_conf *conf,
++                                  u32 changed);
+ static int b43_ratelimit(struct b43_wl *wl)
+ {
+@@ -3754,14 +3758,24 @@ static int b43_op_config(struct ieee8021
+       struct ieee80211_conf *conf = &hw->conf;
+       int antenna;
+       int err = 0;
++      bool reload_bss = false;
+       mutex_lock(&wl->mutex);
++      dev = wl->current_dev;
++
+       /* Switch the band (if necessary). This might change the active core. */
+       err = b43_switch_band(wl, conf->channel);
+       if (err)
+               goto out_unlock_mutex;
+-      dev = wl->current_dev;
++
++      /* Need to reload all settings if the core changed */
++      if (dev != wl->current_dev) {
++              dev = wl->current_dev;
++              changed = ~0;
++              reload_bss = true;
++      }
++
+       phy = &dev->phy;
+       if (conf_is_ht(conf))
+@@ -3822,6 +3836,9 @@ out_mac_enable:
+ out_unlock_mutex:
+       mutex_unlock(&wl->mutex);
++      if (wl->vif && reload_bss)
++              b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
++
+       return err;
+ }
+@@ -3910,7 +3927,8 @@ static void b43_op_bss_info_changed(stru
+       if (changed & BSS_CHANGED_BEACON_INT &&
+           (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
+            b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
+-           b43_is_mode(wl, NL80211_IFTYPE_ADHOC)))
++           b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) &&
++          conf->beacon_int)
+               b43_set_beacon_int(dev, conf->beacon_int);
+       if (changed & BSS_CHANGED_BASIC_RATES)
+@@ -4691,6 +4709,9 @@ static int b43_op_add_interface(struct i
+  out_mutex_unlock:
+       mutex_unlock(&wl->mutex);
++      if (err == 0)
++              b43_op_bss_info_changed(hw, vif, &vif->bss_conf, ~0);
++
+       return err;
+ }
+@@ -4761,6 +4782,9 @@ static int b43_op_start(struct ieee80211
+  out_mutex_unlock:
+       mutex_unlock(&wl->mutex);
++      /* reload configuration */
++      b43_op_config(hw, ~0);
++
+       return err;
+ }
+@@ -4917,10 +4941,18 @@ out:
+       if (err)
+               wl->current_dev = NULL; /* Failed to init the dev. */
+       mutex_unlock(&wl->mutex);
+-      if (err)
++
++      if (err) {
+               b43err(wl, "Controller restart FAILED\n");
+-      else
+-              b43info(wl, "Controller restarted\n");
++              return;
++      }
++
++      /* reload configuration */
++      b43_op_config(wl->hw, ~0);
++      if (wl->vif)
++              b43_op_bss_info_changed(wl->hw, wl->vif, &wl->vif->bss_conf, ~0);
++
++      b43info(wl, "Controller restarted\n");
+ }
+ static int b43_setup_bands(struct b43_wldev *dev,
 --- a/net/mac80211/agg-rx.c
 +++ b/net/mac80211/agg-rx.c
-@@ -176,6 +176,8 @@ static void ieee80211_send_addba_resp(st
+@@ -184,6 +184,8 @@ static void ieee80211_send_addba_resp(st
                memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
        else if (sdata->vif.type == NL80211_IFTYPE_STATION)
                memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
  
        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                                          IEEE80211_STYPE_ACTION);
-@@ -262,7 +264,11 @@ void ieee80211_process_addba_request(str
-                               "%pM on tid %u\n",
-                               mgmt->sa, tid);
- #endif /* CONFIG_MAC80211_HT_DEBUG */
--              goto end;
-+
-+              /* delete existing Rx BA session on the same tid */
-+              ___ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
-+                                              WLAN_STATUS_UNSPECIFIED_QOS,
-+                                              false);
-       }
-       /* prepare A-MPDU MLME for Rx aggregation */
 --- a/net/mac80211/agg-tx.c
 +++ b/net/mac80211/agg-tx.c
 @@ -79,7 +79,8 @@ static void ieee80211_send_addba_request
                return -EINVAL;
  
        if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
-@@ -809,7 +811,7 @@ void ieee80211_process_addba_resp(struct
-                * of at least 1.
-                */
-               if (!buf_size)
--                      goto out;
-+                      buf_size = 1;
-               if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED,
-                                    &tid_tx->state)) {
 --- a/net/mac80211/debugfs_sta.c
 +++ b/net/mac80211/debugfs_sta.c
 @@ -59,7 +59,7 @@ static ssize_t sta_flags_read(struct fil
                        break;
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -2137,7 +2137,8 @@ ieee80211_rx_h_action(struct ieee80211_r
+@@ -2147,7 +2147,8 @@ ieee80211_rx_h_action(struct ieee80211_r
                 */
                if (sdata->vif.type != NL80211_IFTYPE_STATION &&
                    sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
                        break;
  
                /* verify action_code is present */
-@@ -2335,13 +2336,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
+@@ -2345,13 +2346,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
  
        if (!ieee80211_vif_is_mesh(&sdata->vif) &&
            sdata->vif.type != NL80211_IFTYPE_ADHOC &&
                break;
        case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
        case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
-@@ -2680,10 +2682,16 @@ static int prepare_for_handlers(struct i
+@@ -2692,10 +2694,16 @@ static int prepare_for_handlers(struct i
                }
                break;
        case NL80211_IFTYPE_WDS:
        WLAN_STA_CLEAR_PS_FILT  = 1<<9,
        WLAN_STA_MFP            = 1<<10,
        WLAN_STA_BLOCK_BA       = 1<<11,
---- a/drivers/net/wireless/ath/ath9k/beacon.c
-+++ b/drivers/net/wireless/ath/ath9k/beacon.c
-@@ -360,6 +360,7 @@ void ath_beacon_tasklet(unsigned long da
-       struct ath_common *common = ath9k_hw_common(ah);
-       struct ath_buf *bf = NULL;
-       struct ieee80211_vif *vif;
-+      struct ath_tx_status ts;
-       int slot;
-       u32 bfaddr, bc = 0;
-@@ -384,7 +385,9 @@ void ath_beacon_tasklet(unsigned long da
-                       ath_dbg(common, ATH_DBG_BSTUCK,
-                               "beacon is officially stuck\n");
-                       sc->sc_flags |= SC_OP_TSF_RESET;
-+                      spin_lock(&sc->sc_pcu_lock);
-                       ath_reset(sc, true);
-+                      spin_unlock(&sc->sc_pcu_lock);
-               }
-               return;
-@@ -464,6 +467,11 @@ void ath_beacon_tasklet(unsigned long da
-               ath9k_hw_txstart(ah, sc->beacon.beaconq);
-               sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
-+              if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
-+                      spin_lock_bh(&sc->sc_pcu_lock);
-+                      ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts);
-+                      spin_unlock_bh(&sc->sc_pcu_lock);
-+              }
-       }
- }
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -617,8 +617,11 @@ void ath_hw_check(struct work_struct *wo
-       ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
-               "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
-       if (busy >= 99) {
--              if (++sc->hw_busy_count >= 3)
-+              if (++sc->hw_busy_count >= 3) {
-+                      spin_lock_bh(&sc->sc_pcu_lock);
-                       ath_reset(sc, true);
-+                      spin_unlock_bh(&sc->sc_pcu_lock);
-+              }
-       } else if (busy >= 0)
-               sc->hw_busy_count = 0;
-@@ -637,7 +640,9 @@ static void ath_hw_pll_rx_hang_check(str
-                       /* Rx is hung for more than 500ms. Reset it */
-                       ath_dbg(common, ATH_DBG_RESET,
-                               "Possible RX hang, resetting");
-+                      spin_lock_bh(&sc->sc_pcu_lock);
-                       ath_reset(sc, true);
-+                      spin_unlock_bh(&sc->sc_pcu_lock);
-                       count = 0;
-               }
-       } else
-@@ -674,7 +679,9 @@ void ath9k_tasklet(unsigned long data)
-       if ((status & ATH9K_INT_FATAL) ||
-           (status & ATH9K_INT_BB_WATCHDOG)) {
-+              spin_lock(&sc->sc_pcu_lock);
-               ath_reset(sc, true);
-+              spin_unlock(&sc->sc_pcu_lock);
-               return;
-       }
-@@ -980,7 +987,6 @@ int ath_reset(struct ath_softc *sc, bool
-       del_timer_sync(&common->ani.timer);
-       ath9k_ps_wakeup(sc);
--      spin_lock_bh(&sc->sc_pcu_lock);
-       ieee80211_stop_queues(hw);
-@@ -1023,7 +1029,6 @@ int ath_reset(struct ath_softc *sc, bool
-       }
-       ieee80211_wake_queues(hw);
--      spin_unlock_bh(&sc->sc_pcu_lock);
-       /* Start ANI */
-       if (!common->disable_ani)
-@@ -2326,9 +2331,9 @@ static void ath9k_flush(struct ieee80211
-       ath9k_ps_wakeup(sc);
-       spin_lock_bh(&sc->sc_pcu_lock);
-       drain_txq = ath_drain_all_txq(sc, false);
--      spin_unlock_bh(&sc->sc_pcu_lock);
-       if (!drain_txq)
-               ath_reset(sc, false);
-+      spin_unlock_bh(&sc->sc_pcu_lock);
-       ath9k_ps_restore(sc);
-       ieee80211_wake_queues(hw);
 --- a/drivers/net/wireless/ath/ath9k/xmit.c
 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -565,11 +565,8 @@ static void ath_tx_complete_aggr(struct 
-       rcu_read_unlock();
--      if (needreset) {
--              spin_unlock_bh(&sc->sc_pcu_lock);
-+      if (needreset)
-               ath_reset(sc, false);
--              spin_lock_bh(&sc->sc_pcu_lock);
--      }
- }
- static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
-@@ -664,7 +661,8 @@ static int ath_compute_num_delims(struct
-        * TODO - this could be improved to be dependent on the rate.
-        *      The hardware can keep up at lower rates, but not higher rates
-        */
--      if (fi->keyix != ATH9K_TXKEYIX_INVALID)
-+      if ((fi->keyix != ATH9K_TXKEYIX_INVALID) &&
-+          !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))
-               ndelim += ATH_AGGR_ENCRYPTDELIM;
-       /*
-@@ -2169,7 +2167,9 @@ static void ath_tx_complete_poll_work(st
-       if (needreset) {
-               ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
-                       "tx hung, resetting the chip\n");
-+              spin_lock_bh(&sc->sc_pcu_lock);
-               ath_reset(sc, true);
-+              spin_unlock_bh(&sc->sc_pcu_lock);
+@@ -551,7 +551,8 @@ static void ath_tx_complete_aggr(struct 
+               if (clear_filter)
+                       tid->ac->clear_ps_filter = true;
+               list_splice(&bf_pending, &tid->buf_q);
+-              ath_tx_queue_tid(txq, tid);
++              if (!an->sleeping)
++                      ath_tx_queue_tid(txq, tid);
+               spin_unlock_bh(&txq->axq_lock);
        }
  
-       ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
---- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
-@@ -236,7 +236,7 @@ static void ar9003_paprd_get_gain_table(
-       memset(entry, 0, sizeof(ah->paprd_gain_table_entries));
-       memset(index, 0, sizeof(ah->paprd_gain_table_index));
--      for (i = 0; i < 32; i++) {
-+      for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) {
-               entry[i] = REG_READ(ah, reg);
-               index[i] = (entry[i] >> 24) & 0xff;
-               reg += 4;
-@@ -246,13 +246,13 @@ static void ar9003_paprd_get_gain_table(
- static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain,
-                                           int target_power)
- {
--      int olpc_gain_delta = 0;
-+      int olpc_gain_delta = 0, cl_gain_mod;
-       int alpha_therm, alpha_volt;
-       int therm_cal_value, volt_cal_value;
-       int therm_value, volt_value;
-       int thermal_gain_corr, voltage_gain_corr;
-       int desired_scale, desired_gain = 0;
--      u32 reg;
-+      u32 reg_olpc  = 0, reg_cl_gain  = 0;
-       REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
-                   AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
-@@ -271,15 +271,29 @@ static unsigned int ar9003_get_desired_g
-       volt_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4,
-                                   AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE);
--      if (chain == 0)
--              reg = AR_PHY_TPC_11_B0;
--      else if (chain == 1)
--              reg = AR_PHY_TPC_11_B1;
--      else
--              reg = AR_PHY_TPC_11_B2;
-+      switch (chain) {
-+      case 0:
-+              reg_olpc = AR_PHY_TPC_11_B0;
-+              reg_cl_gain = AR_PHY_CL_TAB_0;
-+              break;
-+      case 1:
-+              reg_olpc = AR_PHY_TPC_11_B1;
-+              reg_cl_gain = AR_PHY_CL_TAB_1;
-+              break;
-+      case 2:
-+              reg_olpc = AR_PHY_TPC_11_B2;
-+              reg_cl_gain = AR_PHY_CL_TAB_2;
-+              break;
-+      default:
-+              ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
-+              "Invalid chainmask: %d\n", chain);
-+              break;
-+      }
--      olpc_gain_delta = REG_READ_FIELD(ah, reg,
-+      olpc_gain_delta = REG_READ_FIELD(ah, reg_olpc,
-                                        AR_PHY_TPC_11_OLPC_GAIN_DELTA);
-+      cl_gain_mod = REG_READ_FIELD(ah, reg_cl_gain,
-+                                       AR_PHY_CL_TAB_CL_GAIN_MOD);
-       if (olpc_gain_delta >= 128)
-               olpc_gain_delta = olpc_gain_delta - 256;
-@@ -289,7 +303,7 @@ static unsigned int ar9003_get_desired_g
-       voltage_gain_corr = (alpha_volt * (volt_value - volt_cal_value) +
-                            (128 / 2)) / 128;
-       desired_gain = target_power - olpc_gain_delta - thermal_gain_corr -
--          voltage_gain_corr + desired_scale;
-+          voltage_gain_corr + desired_scale + cl_gain_mod;
-       return desired_gain;
- }
-@@ -727,7 +741,7 @@ int ar9003_paprd_setup_gain_table(struct
-       desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
-       gain_index = 0;
--      for (i = 0; i < 32; i++) {
-+      for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) {
-               if (ah->paprd_gain_table_index[i] >= desired_gain)
-                       break;
-               gain_index++;
---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
-@@ -1121,6 +1121,9 @@
- #define AR_PHY_POWERTX_RATE8_POWERTXHT40_5    0x3F00
- #define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S  8
-+#define AR_PHY_CL_TAB_CL_GAIN_MOD             0x1f
-+#define AR_PHY_CL_TAB_CL_GAIN_MOD_S           0
-+
- void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
- #endif  /* AR9003_PHY_H */
---- a/drivers/net/wireless/ath/ath5k/eeprom.c
-+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
-@@ -691,14 +691,12 @@ ath5k_eeprom_free_pcal_info(struct ath5k
-               if (!chinfo[pier].pd_curves)
-                       continue;
--              for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
-+              for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) {
-                       struct ath5k_pdgain_info *pd =
-                                       &chinfo[pier].pd_curves[pdg];
--                      if (pd != NULL) {
--                              kfree(pd->pd_step);
--                              kfree(pd->pd_pwr);
--                      }
-+                      kfree(pd->pd_step);
-+                      kfree(pd->pd_pwr);
-               }
-               kfree(chinfo[pier].pd_curves);
---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-@@ -229,6 +229,7 @@ static void ar9003_hw_fill_txdesc(struct
- static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
-                                struct ath_tx_status *ts)
- {
-+      struct ar9003_txc *txc = (struct ar9003_txc *) ds;
-       struct ar9003_txs *ads;
-       u32 status;
-@@ -238,7 +239,11 @@ static int ar9003_hw_proc_txdesc(struct 
-       if ((status & AR_TxDone) == 0)
-               return -EINPROGRESS;
--      ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
-+      ts->qid = MS(ads->ds_info, AR_TxQcuNum);
-+      if (!txc || (MS(txc->info, AR_TxQcuNum) == ts->qid))
-+              ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
-+      else
-+              return -ENOENT;
-       if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
-           (MS(ads->ds_info, AR_TxRxDesc) != 1)) {
-@@ -254,7 +259,6 @@ static int ar9003_hw_proc_txdesc(struct 
-       ts->ts_seqnum = MS(status, AR_SeqNum);
-       ts->tid = MS(status, AR_TxTid);
--      ts->qid = MS(ads->ds_info, AR_TxQcuNum);
-       ts->desc_id = MS(ads->status1, AR_TxDescId);
-       ts->ts_tstamp = ads->status4;
-       ts->ts_status = 0;
---- a/net/mac80211/wpa.c
-+++ b/net/mac80211/wpa.c
-@@ -15,6 +15,7 @@
- #include <linux/gfp.h>
- #include <asm/unaligned.h>
- #include <net/mac80211.h>
-+#include <crypto/aes.h>
- #include "ieee80211_i.h"
- #include "michael.h"
-@@ -86,6 +87,11 @@ ieee80211_rx_h_michael_mic_verify(struct
-       struct sk_buff *skb = rx->skb;
-       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+      int queue = rx->queue;
-+
-+      /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */
-+      if (rx->queue == NUM_RX_DATA_QUEUES - 1)
-+              queue = 0;
-       /*
-        * it makes no sense to check for MIC errors on anything other
-@@ -148,8 +154,8 @@ ieee80211_rx_h_michael_mic_verify(struct
- update_iv:
-       /* update IV in key information to be able to detect replays */
--      rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32;
--      rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16;
-+      rx->key->u.tkip.rx[queue].iv32 = rx->tkip_iv32;
-+      rx->key->u.tkip.rx[queue].iv16 = rx->tkip_iv16;
-       return RX_CONTINUE;
-@@ -165,6 +171,7 @@ static int tkip_encrypt_skb(struct ieee8
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_key *key = tx->key;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-+      unsigned long flags;
-       unsigned int hdrlen;
-       int len, tail;
-       u8 *pos;
-@@ -192,11 +199,12 @@ static int tkip_encrypt_skb(struct ieee8
-       pos += hdrlen;
-       /* Increase IV for the frame */
-+      spin_lock_irqsave(&key->u.tkip.txlock, flags);
-       key->u.tkip.tx.iv16++;
-       if (key->u.tkip.tx.iv16 == 0)
-               key->u.tkip.tx.iv32++;
--
--      pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
-+      pos = ieee80211_tkip_add_iv(pos, key);
-+      spin_unlock_irqrestore(&key->u.tkip.txlock, flags);
-       /* hwaccel - with software IV */
-       if (info->control.hw_key)
-@@ -205,9 +213,8 @@ static int tkip_encrypt_skb(struct ieee8
-       /* Add room for ICV */
-       skb_put(skb, TKIP_ICV_LEN);
--      hdr = (struct ieee80211_hdr *) skb->data;
-       return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
--                                         key, pos, len, hdr->addr2);
-+                                         key, skb, pos, len);
- }
-@@ -235,6 +242,11 @@ ieee80211_crypto_tkip_decrypt(struct iee
-       struct ieee80211_key *key = rx->key;
-       struct sk_buff *skb = rx->skb;
-       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
-+      int queue = rx->queue;
-+
-+      /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */
-+      if (rx->queue == NUM_RX_DATA_QUEUES - 1)
-+              queue = 0;
-       hdrlen = ieee80211_hdrlen(hdr->frame_control);
-@@ -255,7 +267,7 @@ ieee80211_crypto_tkip_decrypt(struct iee
-       res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
-                                         key, skb->data + hdrlen,
-                                         skb->len - hdrlen, rx->sta->sta.addr,
--                                        hdr->addr1, hwaccel, rx->queue,
-+                                        hdr->addr1, hwaccel, queue,
-                                         &rx->tkip_iv32,
-                                         &rx->tkip_iv16);
-       if (res != TKIP_DECRYPT_OK)
-@@ -283,6 +295,8 @@ static void ccmp_special_blocks(struct s
-       unsigned int hdrlen;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+      memset(scratch, 0, 6 * AES_BLOCK_LEN);
-+
-       b_0 = scratch + 3 * AES_BLOCK_LEN;
-       aad = scratch + 4 * AES_BLOCK_LEN;
-@@ -373,8 +387,10 @@ static int ccmp_encrypt_skb(struct ieee8
-       struct ieee80211_key *key = tx->key;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       int hdrlen, len, tail;
--      u8 *pos, *pn;
--      int i;
-+      u8 *pos;
-+      u8 pn[6];
-+      u64 pn64;
-+      u8 scratch[6 * AES_BLOCK_LEN];
-       if (info->control.hw_key &&
-           !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
-@@ -402,14 +418,14 @@ static int ccmp_encrypt_skb(struct ieee8
-       hdr = (struct ieee80211_hdr *) pos;
-       pos += hdrlen;
--      /* PN = PN + 1 */
--      pn = key->u.ccmp.tx_pn;
-+      pn64 = atomic64_inc_return(&key->u.ccmp.tx_pn);
--      for (i = CCMP_PN_LEN - 1; i >= 0; i--) {
--              pn[i]++;
--              if (pn[i])
--                      break;
--      }
-+      pn[5] = pn64;
-+      pn[4] = pn64 >> 8;
-+      pn[3] = pn64 >> 16;
-+      pn[2] = pn64 >> 24;
-+      pn[1] = pn64 >> 32;
-+      pn[0] = pn64 >> 40;
-       ccmp_pn2hdr(pos, pn, key->conf.keyidx);
-@@ -418,8 +434,8 @@ static int ccmp_encrypt_skb(struct ieee8
-               return 0;
-       pos += CCMP_HDR_LEN;
--      ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0);
--      ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, key->u.ccmp.tx_crypto_buf, pos, len,
-+      ccmp_special_blocks(skb, pn, scratch, 0);
-+      ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
-                                 pos, skb_put(skb, CCMP_MIC_LEN));
-       return 0;
-@@ -475,11 +491,12 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+@@ -1413,7 +1414,8 @@ static void ath_tx_send_ampdu(struct ath
+                */
+               TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
+               list_add_tail(&bf->list, &tid->buf_q);
+-              ath_tx_queue_tid(txctl->txq, tid);
++              if (!txctl->an || !txctl->an->sleeping)
++                      ath_tx_queue_tid(txctl->txq, tid);
+               return;
        }
  
-       if (!(status->flag & RX_FLAG_DECRYPTED)) {
-+              u8 scratch[6 * AES_BLOCK_LEN];
-               /* hardware didn't decrypt/verify MIC */
--              ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1);
-+              ccmp_special_blocks(skb, pn, scratch, 1);
-               if (ieee80211_aes_ccm_decrypt(
--                          key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf,
-+                          key->u.ccmp.tfm, scratch,
-                           skb->data + hdrlen + CCMP_HDR_LEN, data_len,
-                           skb->data + skb->len - CCMP_MIC_LEN,
-                           skb->data + hdrlen + CCMP_HDR_LEN))
---- a/drivers/net/wireless/b43/xmit.c
-+++ b/drivers/net/wireless/b43/xmit.c
-@@ -323,8 +323,7 @@ int b43_generate_txhdr(struct b43_wldev 
-                       /* we give the phase1key and iv16 here, the key is stored in
-                        * shm. With that the hardware can do phase 2 and encryption.
-                        */
--                      ieee80211_get_tkip_key(info->control.hw_key, skb_frag,
--                                      IEEE80211_TKIP_P1_KEY, (u8*)phase1key);
-+                      ieee80211_get_tkip_p1k(info->control.hw_key, skb_frag, phase1key);
-                       /* phase1key is in host endian. Copy to little-endian txhdr->iv. */
-                       for (i = 0; i < 5; i++) {
-                               txhdr->iv[i * 2 + 0] = phase1key[i];
---- a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
-+++ b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
-@@ -240,8 +240,7 @@ static void iwl4965_tx_cmd_build_hwcrypt
-       case WLAN_CIPHER_SUITE_TKIP:
-               tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
--              ieee80211_get_tkip_key(keyconf, skb_frag,
--                      IEEE80211_TKIP_P2_KEY, tx_cmd->key);
-+              ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
-               IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
-               break;
---- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
-@@ -497,8 +497,7 @@ static void iwlagn_tx_cmd_build_hwcrypto
-       case WLAN_CIPHER_SUITE_TKIP:
-               tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
--              ieee80211_get_tkip_key(keyconf, skb_frag,
--                      IEEE80211_TKIP_P2_KEY, tx_cmd->key);
-+              ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
-               IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
-               break;
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -960,21 +960,6 @@ enum sta_notify_cmd {
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -421,6 +421,7 @@ struct station_parameters {
+  * @STATION_INFO_RX_BITRATE: @rxrate fields are filled
+  * @STATION_INFO_BSS_PARAM: @bss_param filled
+  * @STATION_INFO_CONNECTED_TIME: @connected_time filled
++ * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
+  */
+ enum station_info_flags {
+       STATION_INFO_INACTIVE_TIME      = 1<<0,
+@@ -439,7 +440,8 @@ enum station_info_flags {
+       STATION_INFO_SIGNAL_AVG         = 1<<13,
+       STATION_INFO_RX_BITRATE         = 1<<14,
+       STATION_INFO_BSS_PARAM          = 1<<15,
+-      STATION_INFO_CONNECTED_TIME     = 1<<16
++      STATION_INFO_CONNECTED_TIME     = 1<<16,
++      STATION_INFO_ASSOC_REQ_IES      = 1<<17
  };
  
  /**
-- * enum ieee80211_tkip_key_type - get tkip key
-- *
-- * Used by drivers which need to get a tkip key for skb. Some drivers need a
-- * phase 1 key, others need a phase 2 key. A single function allows the driver
-- * to get the key, this enum indicates what type of key is required.
-- *
-- * @IEEE80211_TKIP_P1_KEY: the driver needs a phase 1 key
-- * @IEEE80211_TKIP_P2_KEY: the driver needs a phase 2 key
-- */
--enum ieee80211_tkip_key_type {
--      IEEE80211_TKIP_P1_KEY,
--      IEEE80211_TKIP_P2_KEY,
--};
--
--/**
-  * enum ieee80211_hw_flags - hardware flags
-  *
-  * These flags are used to indicate hardware capabilities to
-@@ -2568,21 +2553,33 @@ struct sk_buff *
- ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
- /**
-- * ieee80211_get_tkip_key - get a TKIP rc4 for skb
-+ * ieee80211_get_tkip_p1k - get a TKIP phase 1 key
-+ *
-+ * This function returns the TKIP phase 1 key for the IV32 taken
-+ * from the given packet.
-+ *
-+ * @keyconf: the parameter passed with the set key
-+ * @skb: the packet to take the IV32 value from that will be encrypted
-+ *    with this P1K
-+ * @p1k: a buffer to which the key will be written, as 5 u16 values
-+ */
-+void ieee80211_get_tkip_p1k(struct ieee80211_key_conf *keyconf,
-+                          struct sk_buff *skb, u16 *p1k);
-+
-+/**
-+ * ieee80211_get_tkip_p2k - get a TKIP phase 2 key
-  *
-- * This function computes a TKIP rc4 key for an skb. It computes
-- * a phase 1 key if needed (iv16 wraps around). This function is to
-- * be used by drivers which can do HW encryption but need to compute
-- * to phase 1/2 key in SW.
-+ * This function computes the TKIP RC4 key for the IV values
-+ * in the packet.
-  *
-  * @keyconf: the parameter passed with the set key
-- * @skb: the skb for which the key is needed
-- * @type: TBD
-- * @key: a buffer to which the key will be written
-- */
--void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
--                              struct sk_buff *skb,
--                              enum ieee80211_tkip_key_type type, u8 *key);
-+ * @skb: the packet to take the IV32/IV16 values from that will be
-+ *    encrypted with this key
-+ * @p2k: a buffer to which the key will be written, 16 bytes
-+ */
-+void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
-+                          struct sk_buff *skb, u8 *p2k);
-+
- /**
-  * ieee80211_wake_queue - wake specific queue
-  * @hw: pointer as obtained from ieee80211_alloc_hw().
---- a/net/mac80211/key.c
-+++ b/net/mac80211/key.c
-@@ -333,6 +333,7 @@ struct ieee80211_key *ieee80211_key_allo
-                                       get_unaligned_le16(seq);
-                       }
-               }
-+              spin_lock_init(&key->u.tkip.txlock);
-               break;
-       case WLAN_CIPHER_SUITE_CCMP:
-               key->conf.iv_len = CCMP_HDR_LEN;
---- a/net/mac80211/key.h
-+++ b/net/mac80211/key.h
-@@ -52,9 +52,10 @@ enum ieee80211_internal_tkip_state {
- };
- struct tkip_ctx {
--      u32 iv32;
--      u16 iv16;
--      u16 p1k[5];
-+      u32 iv32;       /* current iv32 */
-+      u16 iv16;       /* current iv16 */
-+      u16 p1k[5];     /* p1k cache */
-+      u32 p1k_iv32;   /* iv32 for which p1k computed */
-       enum ieee80211_internal_tkip_state state;
- };
-@@ -71,6 +72,9 @@ struct ieee80211_key {
-       union {
-               struct {
-+                      /* protects tx context */
-+                      spinlock_t txlock;
-+
-                       /* last used TSC */
-                       struct tkip_ctx tx;
-@@ -78,7 +82,7 @@ struct ieee80211_key {
-                       struct tkip_ctx rx[NUM_RX_DATA_QUEUES];
-               } tkip;
-               struct {
--                      u8 tx_pn[6];
-+                      atomic64_t tx_pn;
-                       /*
-                        * Last received packet number. The first
-                        * NUM_RX_DATA_QUEUES counters are used with Data
-@@ -88,12 +92,9 @@ struct ieee80211_key {
-                       u8 rx_pn[NUM_RX_DATA_QUEUES + 1][6];
-                       struct crypto_cipher *tfm;
-                       u32 replays; /* dot11RSNAStatsCCMPReplays */
--                      /* scratch buffers for virt_to_page() (crypto API) */
- #ifndef AES_BLOCK_LEN
- #define AES_BLOCK_LEN 16
- #endif
--                      u8 tx_crypto_buf[6 * AES_BLOCK_LEN];
--                      u8 rx_crypto_buf[6 * AES_BLOCK_LEN];
-               } ccmp;
-               struct {
-                       u8 tx_pn[6];
---- a/net/mac80211/tkip.c
-+++ b/net/mac80211/tkip.c
-@@ -101,6 +101,7 @@ static void tkip_mixing_phase1(const u8 
-               p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i;
-       }
-       ctx->state = TKIP_STATE_PHASE1_DONE;
-+      ctx->p1k_iv32 = tsc_IV32;
- }
- static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx,
-@@ -140,60 +141,72 @@ static void tkip_mixing_phase2(const u8 
- /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets
-  * of the IV. Returns pointer to the octet following IVs (i.e., beginning of
-  * the packet payload). */
--u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16)
-+u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key)
- {
--      pos = write_tkip_iv(pos, iv16);
-+      lockdep_assert_held(&key->u.tkip.txlock);
-+
-+      pos = write_tkip_iv(pos, key->u.tkip.tx.iv16);
-       *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */;
-       put_unaligned_le32(key->u.tkip.tx.iv32, pos);
-       return pos + 4;
- }
--void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
--                      struct sk_buff *skb, enum ieee80211_tkip_key_type type,
--                      u8 *outkey)
-+static void ieee80211_compute_tkip_p1k(struct ieee80211_key *key, u32 iv32)
- {
--      struct ieee80211_key *key = (struct ieee80211_key *)
--                      container_of(keyconf, struct ieee80211_key, conf);
--      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
--      u8 *data;
--      const u8 *tk;
--      struct tkip_ctx *ctx;
--      u16 iv16;
--      u32 iv32;
--
--      data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
--      iv16 = data[2] | (data[0] << 8);
--      iv32 = get_unaligned_le32(&data[4]);
--
--      tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
--      ctx = &key->u.tkip.tx;
--
--#ifdef CONFIG_MAC80211_TKIP_DEBUG
--      printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n",
--                      iv16, iv32);
-+      struct ieee80211_sub_if_data *sdata = key->sdata;
-+      struct tkip_ctx *ctx = &key->u.tkip.tx;
-+      const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
--      if (iv32 != ctx->iv32) {
--              printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n",
--                      iv32, ctx->iv32);
--              printk(KERN_DEBUG "Wrap around of iv16 in the middle of a "
--                      "fragmented packet\n");
--      }
--#endif
-+      lockdep_assert_held(&key->u.tkip.txlock);
--      /* Update the p1k only when the iv16 in the packet wraps around, this
--       * might occur after the wrap around of iv16 in the key in case of
--       * fragmented packets. */
--      if (iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT)
--              tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32);
-+      /*
-+       * Update the P1K when the IV32 is different from the value it
-+       * had when we last computed it (or when not initialised yet).
-+       * This might flip-flop back and forth if packets are processed
-+       * out-of-order due to the different ACs, but then we have to
-+       * just compute the P1K more often.
-+       */
-+      if (ctx->p1k_iv32 != iv32 || ctx->state == TKIP_STATE_NOT_INIT)
-+              tkip_mixing_phase1(tk, ctx, sdata->vif.addr, iv32);
-+}
--      if (type == IEEE80211_TKIP_P1_KEY) {
--              memcpy(outkey, ctx->p1k, sizeof(u16) * 5);
--              return;
--      }
-+void ieee80211_get_tkip_p1k(struct ieee80211_key_conf *keyconf,
-+                          struct sk_buff *skb, u16 *p1k)
-+{
-+      struct ieee80211_key *key = (struct ieee80211_key *)
-+                      container_of(keyconf, struct ieee80211_key, conf);
-+      struct tkip_ctx *ctx = &key->u.tkip.tx;
-+      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+      const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
-+      u32 iv32 = get_unaligned_le32(&data[4]);
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&key->u.tkip.txlock, flags);
-+      ieee80211_compute_tkip_p1k(key, iv32);
-+      memcpy(p1k, ctx->p1k, sizeof(ctx->p1k));
-+      spin_unlock_irqrestore(&key->u.tkip.txlock, flags);
-+}
-+EXPORT_SYMBOL(ieee80211_get_tkip_p1k);
--      tkip_mixing_phase2(tk, ctx, iv16, outkey);
-+void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
-+                          struct sk_buff *skb, u8 *p2k)
-+{
-+      struct ieee80211_key *key = (struct ieee80211_key *)
-+                      container_of(keyconf, struct ieee80211_key, conf);
-+      const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
-+      struct tkip_ctx *ctx = &key->u.tkip.tx;
-+      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+      const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
-+      u32 iv32 = get_unaligned_le32(&data[4]);
-+      u16 iv16 = data[2] | (data[0] << 8);
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&key->u.tkip.txlock, flags);
-+      ieee80211_compute_tkip_p1k(key, iv32);
-+      tkip_mixing_phase2(tk, ctx, iv16, p2k);
-+      spin_unlock_irqrestore(&key->u.tkip.txlock, flags);
- }
--EXPORT_SYMBOL(ieee80211_get_tkip_key);
-+EXPORT_SYMBOL(ieee80211_get_tkip_p2k);
- /*
-  * Encrypt packet payload with TKIP using @key. @pos is a pointer to the
-@@ -204,19 +217,15 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key);
-  */
- int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
-                               struct ieee80211_key *key,
--                              u8 *pos, size_t payload_len, u8 *ta)
-+                              struct sk_buff *skb,
-+                              u8 *payload, size_t payload_len)
- {
-       u8 rc4key[16];
--      struct tkip_ctx *ctx = &key->u.tkip.tx;
--      const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
--
--      /* Calculate per-packet key */
--      if (ctx->iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT)
--              tkip_mixing_phase1(tk, ctx, ta, ctx->iv32);
--      tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key);
-+      ieee80211_get_tkip_p2k(&key->conf, skb, rc4key);
--      return ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len);
-+      return ieee80211_wep_encrypt_data(tfm, rc4key, 16,
-+                                        payload, payload_len);
- }
- /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the
---- a/net/mac80211/tkip.h
-+++ b/net/mac80211/tkip.h
-@@ -13,11 +13,13 @@
- #include <linux/crypto.h>
- #include "key.h"
--u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16);
-+u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key);
- int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
--                               struct ieee80211_key *key,
--                               u8 *pos, size_t payload_len, u8 *ta);
-+                              struct ieee80211_key *key,
-+                              struct sk_buff *skb,
-+                              u8 *payload, size_t payload_len);
-+
- enum {
-       TKIP_DECRYPT_OK = 0,
-       TKIP_DECRYPT_NO_EXT_IV = -1,
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -209,6 +209,7 @@ static int ieee80211_get_key(struct wiph
-       u8 seq[6] = {0};
-       struct key_params params;
-       struct ieee80211_key *key = NULL;
-+      u64 pn64;
-       u32 iv32;
-       u16 iv16;
-       int err = -ENOENT;
-@@ -256,12 +257,13 @@ static int ieee80211_get_key(struct wiph
-               params.seq_len = 6;
-               break;
-       case WLAN_CIPHER_SUITE_CCMP:
--              seq[0] = key->u.ccmp.tx_pn[5];
--              seq[1] = key->u.ccmp.tx_pn[4];
--              seq[2] = key->u.ccmp.tx_pn[3];
--              seq[3] = key->u.ccmp.tx_pn[2];
--              seq[4] = key->u.ccmp.tx_pn[1];
--              seq[5] = key->u.ccmp.tx_pn[0];
-+              pn64 = atomic64_read(&key->u.ccmp.tx_pn);
-+              seq[0] = pn64;
-+              seq[1] = pn64 >> 8;
-+              seq[2] = pn64 >> 16;
-+              seq[3] = pn64 >> 24;
-+              seq[4] = pn64 >> 32;
-+              seq[5] = pn64 >> 40;
-               params.seq = seq;
-               params.seq_len = 6;
-               break;
---- a/net/mac80211/debugfs_key.c
-+++ b/net/mac80211/debugfs_key.c
-@@ -79,6 +79,7 @@ static ssize_t key_tx_spec_read(struct f
-                               size_t count, loff_t *ppos)
- {
-       const u8 *tpn;
-+      u64 pn;
-       char buf[20];
-       int len;
-       struct ieee80211_key *key = file->private_data;
-@@ -94,9 +95,10 @@ static ssize_t key_tx_spec_read(struct f
-                               key->u.tkip.tx.iv16);
-               break;
-       case WLAN_CIPHER_SUITE_CCMP:
--              tpn = key->u.ccmp.tx_pn;
-+              pn = atomic64_read(&key->u.ccmp.tx_pn);
-               len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
--                              tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]);
-+                              (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
-+                              (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
-               break;
-       case WLAN_CIPHER_SUITE_AES_CMAC:
-               tpn = key->u.aes_cmac.tx_pn;
---- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
-@@ -653,8 +653,8 @@ static const u32 ar9300_2p2_baseband_pos
-       {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
-       {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
-       {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
--      {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
--      {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a},
-+      {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
-+      {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
-       {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-       {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
-       {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000},
-@@ -761,7 +761,7 @@ static const u32 ar9300_2p2_baseband_cor
-       {0x0000a3ec, 0x20202020},
-       {0x0000a3f0, 0x00000000},
-       {0x0000a3f4, 0x00000246},
--      {0x0000a3f8, 0x0cdbd380},
-+      {0x0000a3f8, 0x0c9bd380},
-       {0x0000a3fc, 0x000f0f01},
-       {0x0000a400, 0x8fa91f01},
-       {0x0000a404, 0x00000000},
-@@ -780,7 +780,7 @@ static const u32 ar9300_2p2_baseband_cor
-       {0x0000a43c, 0x00100000},
-       {0x0000a440, 0x00000000},
-       {0x0000a444, 0x00000000},
--      {0x0000a448, 0x06000080},
-+      {0x0000a448, 0x05000080},
-       {0x0000a44c, 0x00000001},
-       {0x0000a450, 0x00010000},
-       {0x0000a458, 0x00000000},
-@@ -1500,8 +1500,6 @@ static const u32 ar9300_2p2_mac_core[][2
-       {0x0000816c, 0x00000000},
-       {0x000081c0, 0x00000000},
-       {0x000081c4, 0x33332210},
--      {0x000081c8, 0x00000000},
--      {0x000081cc, 0x00000000},
-       {0x000081ec, 0x00000000},
-       {0x000081f0, 0x00000000},
-       {0x000081f4, 0x00000000},
---- a/net/mac80211/work.c
-+++ b/net/mac80211/work.c
-@@ -1075,14 +1075,13 @@ static void ieee80211_work_work(struct w
-                       continue;
-               if (wk->chan != local->tmp_channel)
-                       continue;
--              if (ieee80211_work_ct_coexists(wk->chan_type,
--                                             local->tmp_channel_type))
-+              if (!ieee80211_work_ct_coexists(wk->chan_type,
-+                                              local->tmp_channel_type))
-                       continue;
-               remain_off_channel = true;
-       }
-       if (!remain_off_channel && local->tmp_channel) {
--              bool on_oper_chan = ieee80211_cfg_on_oper_channel(local);
-               local->tmp_channel = NULL;
-               /* If tmp_channel wasn't operating channel, then
-                * we need to go back on-channel.
-@@ -1092,7 +1091,7 @@ static void ieee80211_work_work(struct w
-                * we still need to do a hardware config.  Currently,
-                * we cannot be here while scanning, however.
-                */
--              if (ieee80211_cfg_on_oper_channel(local) && !on_oper_chan)
-+              if (!ieee80211_cfg_on_oper_channel(local))
-                       ieee80211_hw_config(local, 0);
-               /* At the least, we need to disable offchannel_ps,
---- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-@@ -627,6 +627,11 @@ static void ar5008_hw_init_bb(struct ath
-       else
-               synthDelay /= 10;
-+      if (IS_CHAN_HALF_RATE(chan))
-+              synthDelay *= 2;
-+      else if (IS_CHAN_QUARTER_RATE(chan))
-+              synthDelay *= 4;
-+
-       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
-       udelay(synthDelay + BASE_ACTIVATE_DELAY);
---- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
-@@ -499,45 +499,6 @@ void ar9002_hw_enable_async_fifo(struct 
-       }
- }
--/*
-- * If Async FIFO is enabled, the following counters change as MAC now runs
-- * at 117 Mhz instead of 88/44MHz when async FIFO is disabled.
-- *
-- * The values below tested for ht40 2 chain.
-- * Overwrite the delay/timeouts initialized in process ini.
-- */
--void ar9002_hw_update_async_fifo(struct ath_hw *ah)
--{
--      if (AR_SREV_9287_13_OR_LATER(ah)) {
--              REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
--                        AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
--              REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
--                        AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
--              REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
--                        AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
--
--              REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
--              REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
--
--              REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
--                          AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
--              REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
--                            AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
--      }
--}
--
--/*
-- * We don't enable WEP aggregation on mac80211 but we keep this
-- * around for HAL unification purposes.
-- */
--void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah)
--{
--      if (AR_SREV_9287_13_OR_LATER(ah)) {
--              REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
--                          AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
--      }
--}
--
- /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
- void ar9002_hw_attach_ops(struct ath_hw *ah)
- {
---- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
-@@ -111,7 +111,9 @@ static int ar9002_hw_set_channel(struct 
-               switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
-               case 0:
--                      if ((freq % 20) == 0)
-+                      if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
-+                              aModeRefSel = 0;
-+                      else if ((freq % 20) == 0)
-                               aModeRefSel = 3;
-                       else if ((freq % 10) == 0)
-                               aModeRefSel = 2;
-@@ -129,8 +131,9 @@ static int ar9002_hw_set_channel(struct 
-                       channelSel = CHANSEL_5G(freq);
-                       /* RefDivA setting */
--                      REG_RMW_FIELD(ah, AR_AN_SYNTH9,
--                                    AR_AN_SYNTH9_REFDIVA, refDivA);
-+                      ath9k_hw_analog_shift_rmw(ah, AR_AN_SYNTH9,
-+                                    AR_AN_SYNTH9_REFDIVA,
-+                                    AR_AN_SYNTH9_REFDIVA_S, refDivA);
-               }
-@@ -447,26 +450,27 @@ static void ar9002_olc_init(struct ath_h
- static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah,
-                                        struct ath9k_channel *chan)
- {
-+      int ref_div = 5;
-+      int pll_div = 0x2c;
-       u32 pll;
--      pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
-+      if (chan && IS_CHAN_5GHZ(chan) && !IS_CHAN_A_FAST_CLOCK(ah, chan)) {
-+              if (AR_SREV_9280_20(ah)) {
-+                      ref_div = 10;
-+                      pll_div = 0x50;
-+              } else {
-+                      pll_div = 0x28;
-+              }
-+      }
-+
-+      pll = SM(ref_div, AR_RTC_9160_PLL_REFDIV);
-+      pll |= SM(pll_div, AR_RTC_9160_PLL_DIV);
-       if (chan && IS_CHAN_HALF_RATE(chan))
-               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
-       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
--      if (chan && IS_CHAN_5GHZ(chan)) {
--              if (IS_CHAN_A_FAST_CLOCK(ah, chan))
--                      pll = 0x142c;
--              else if (AR_SREV_9280_20(ah))
--                      pll = 0x2850;
--              else
--                      pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
--      } else {
--              pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
--      }
--
-       return pll;
- }
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -87,7 +87,10 @@ static void ath9k_hw_set_clockrate(struc
-       struct ath_common *common = ath9k_hw_common(ah);
-       unsigned int clockrate;
--      if (!ah->curchan) /* should really check for CCK instead */
-+      /* AR9287 v1.3+ uses async FIFO and runs the MAC at 117 MHz */
-+      if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah))
-+              clockrate = 117;
-+      else if (!ah->curchan) /* should really check for CCK instead */
-               clockrate = ATH9K_CLOCK_RATE_CCK;
-       else if (conf->channel->band == IEEE80211_BAND_2GHZ)
-               clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
-@@ -99,6 +102,13 @@ static void ath9k_hw_set_clockrate(struc
-       if (conf_is_ht40(conf))
-               clockrate *= 2;
-+      if (ah->curchan) {
-+              if (IS_CHAN_HALF_RATE(ah->curchan))
-+                      clockrate /= 2;
-+              if (IS_CHAN_QUARTER_RATE(ah->curchan))
-+                      clockrate /= 4;
-+      }
-+
-       common->clockrate = clockrate;
- }
-@@ -895,6 +905,13 @@ static void ath9k_hw_init_interrupt_mask
-       }
- }
-+static void ath9k_hw_set_sifs_time(struct ath_hw *ah, u32 us)
-+{
-+      u32 val = ath9k_hw_mac_to_clks(ah, us - 2);
-+      val = min(val, (u32) 0xFFFF);
-+      REG_WRITE(ah, AR_D_GBL_IFS_SIFS, val);
-+}
-+
- static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
- {
-       u32 val = ath9k_hw_mac_to_clks(ah, us);
-@@ -932,25 +949,60 @@ static bool ath9k_hw_set_global_txtimeou
- void ath9k_hw_init_global_settings(struct ath_hw *ah)
- {
--      struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-+      struct ath_common *common = ath9k_hw_common(ah);
-+      struct ieee80211_conf *conf = &common->hw->conf;
-+      const struct ath9k_channel *chan = ah->curchan;
-       int acktimeout;
-       int slottime;
-       int sifstime;
-+      int rx_lat = 0, tx_lat = 0, eifs = 0;
-+      u32 reg;
-       ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
-               ah->misc_mode);
-+      if (!chan)
-+              return;
-+
-       if (ah->misc_mode != 0)
-               REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode);
--      if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
--              sifstime = 16;
--      else
--              sifstime = 10;
-+      rx_lat = 37;
-+      tx_lat = 54;
-+
-+      if (IS_CHAN_HALF_RATE(chan)) {
-+              eifs = 175;
-+              rx_lat *= 2;
-+              tx_lat *= 2;
-+              if (IS_CHAN_A_FAST_CLOCK(ah, chan))
-+                  tx_lat += 11;
-+
-+              slottime = 13;
-+              sifstime = 32;
-+      } else if (IS_CHAN_QUARTER_RATE(chan)) {
-+              eifs = 340;
-+              rx_lat *= 4;
-+              tx_lat *= 4;
-+              if (IS_CHAN_A_FAST_CLOCK(ah, chan))
-+                  tx_lat += 22;
-+
-+              slottime = 21;
-+              sifstime = 64;
-+      } else {
-+              eifs = REG_READ(ah, AR_D_GBL_IFS_EIFS);
-+              reg = REG_READ(ah, AR_USEC);
-+              rx_lat = MS(reg, AR_USEC_RX_LAT);
-+              tx_lat = MS(reg, AR_USEC_TX_LAT);
-+
-+              slottime = ah->slottime;
-+              if (IS_CHAN_5GHZ(chan))
-+                      sifstime = 16;
-+              else
-+                      sifstime = 10;
-+      }
-       /* As defined by IEEE 802.11-2007 17.3.8.6 */
--      slottime = ah->slottime + 3 * ah->coverage_class;
--      acktimeout = slottime + sifstime;
-+      acktimeout = slottime + sifstime + 3 * ah->coverage_class;
-       /*
-        * Workaround for early ACK timeouts, add an offset to match the
-@@ -962,11 +1014,20 @@ void ath9k_hw_init_global_settings(struc
-       if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
-               acktimeout += 64 - sifstime - ah->slottime;
--      ath9k_hw_setslottime(ah, ah->slottime);
-+      ath9k_hw_set_sifs_time(ah, sifstime);
-+      ath9k_hw_setslottime(ah, slottime);
-       ath9k_hw_set_ack_timeout(ah, acktimeout);
-       ath9k_hw_set_cts_timeout(ah, acktimeout);
-       if (ah->globaltxtimeout != (u32) -1)
-               ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
-+
-+      REG_WRITE(ah, AR_D_GBL_IFS_EIFS, ath9k_hw_mac_to_clks(ah, eifs));
-+      REG_RMW(ah, AR_USEC,
-+              (common->clockrate - 1) |
-+              SM(rx_lat, AR_USEC_RX_LAT) |
-+              SM(tx_lat, AR_USEC_TX_LAT),
-+              AR_USEC_TX_LAT | AR_USEC_RX_LAT | AR_USEC_USEC);
-+
- }
- EXPORT_SYMBOL(ath9k_hw_init_global_settings);
-@@ -1570,9 +1631,13 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-       ath9k_hw_init_global_settings(ah);
--      if (!AR_SREV_9300_20_OR_LATER(ah)) {
--              ar9002_hw_update_async_fifo(ah);
--              ar9002_hw_enable_wep_aggregation(ah);
-+      if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) {
-+              REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
-+                          AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
-+              REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
-+                            AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
-+              REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
-+                          AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
-       }
-       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
-@@ -1932,12 +1997,22 @@ EXPORT_SYMBOL(ath9k_hw_set_sta_beacon_ti
- /* HW Capabilities */
- /*******************/
-+static u8 fixup_chainmask(u8 chip_chainmask, u8 eeprom_chainmask)
-+{
-+      eeprom_chainmask &= chip_chainmask;
-+      if (eeprom_chainmask)
-+              return eeprom_chainmask;
-+      else
-+              return chip_chainmask;
-+}
-+
- int ath9k_hw_fill_cap_info(struct ath_hw *ah)
- {
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
-       struct ath_common *common = ath9k_hw_common(ah);
-       struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
-+      unsigned int chip_chainmask;
-       u16 eeval;
-       u8 ant_div_ctl1, tx_chainmask, rx_chainmask;
-@@ -1974,6 +2049,15 @@ int ath9k_hw_fill_cap_info(struct ath_hw
-       if (eeval & AR5416_OPFLAGS_11G)
-               pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
-+      if (AR_SREV_9485(ah) || AR_SREV_9285(ah) || AR_SREV_9330(ah))
-+              chip_chainmask = 1;
-+      else if (!AR_SREV_9280_20_OR_LATER(ah))
-+              chip_chainmask = 7;
-+      else if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9340(ah))
-+              chip_chainmask = 3;
-+      else
-+              chip_chainmask = 7;
-+
-       pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
-       /*
-        * For AR9271 we will temporarilly uses the rx chainmax as read from
-@@ -1990,6 +2074,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw
-               /* Use rx_chainmask from EEPROM. */
-               pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
-+      pCap->tx_chainmask = fixup_chainmask(chip_chainmask, pCap->tx_chainmask);
-+      pCap->rx_chainmask = fixup_chainmask(chip_chainmask, pCap->rx_chainmask);
-+
-       ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
-       /* enable key search for every frame in an aggregate */
-@@ -2079,10 +2166,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw
-                       pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
-       } else {
-               pCap->tx_desc_len = sizeof(struct ath_desc);
--              if (AR_SREV_9280_20(ah) &&
--                  ((ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) <=
--                    AR5416_EEP_MINOR_VER_16) ||
--                   ah->eep_ops->get_eeprom(ah, EEP_FSTCLK_5G)))
-+              if (AR_SREV_9280_20(ah))
-                       pCap->hw_caps |= ATH9K_HW_CAP_FASTCLOCK;
-       }
---- a/drivers/net/wireless/ath/ath9k/hw.h
-+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -983,8 +983,6 @@ void ath9k_hw_get_delta_slope_vals(struc
- void ar9002_hw_cck_chan14_spread(struct ath_hw *ah);
- int ar9002_hw_rf_claim(struct ath_hw *ah);
- void ar9002_hw_enable_async_fifo(struct ath_hw *ah);
--void ar9002_hw_update_async_fifo(struct ath_hw *ah);
--void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah);
- /*
-  * Code specific to AR9003, we stuff these here to avoid callbacks
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -814,16 +814,19 @@ static bool ath9k_rx_accept(struct ath_c
-                           struct ath_rx_status *rx_stats,
-                           bool *decrypt_error)
- {
--#define is_mc_or_valid_tkip_keyix ((is_mc ||                  \
--              (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \
--              test_bit(rx_stats->rs_keyix, common->tkip_keymap))))
--
-+      bool is_mc, is_valid_tkip, strip_mic, mic_error = false;
-       struct ath_hw *ah = common->ah;
-       __le16 fc;
-       u8 rx_status_len = ah->caps.rx_status_len;
-       fc = hdr->frame_control;
-+      is_mc = !!is_multicast_ether_addr(hdr->addr1);
-+      is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID &&
-+              test_bit(rx_stats->rs_keyix, common->tkip_keymap);
-+      strip_mic = is_valid_tkip && !(rx_stats->rs_status &
-+              (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC));
-+
-       if (!rx_stats->rs_datalen)
-               return false;
-         /*
-@@ -838,6 +841,11 @@ static bool ath9k_rx_accept(struct ath_c
-       if (rx_stats->rs_more)
-               return true;
-+      mic_error = is_valid_tkip && !ieee80211_is_ctl(fc) &&
-+              !ieee80211_has_morefrags(fc) &&
-+              !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
-+              (rx_stats->rs_status & ATH9K_RXERR_MIC);
-+
-       /*
-        * The rx_stats->rs_status will not be set until the end of the
-        * chained descriptors so it can be ignored if rs_more is set. The
-@@ -845,30 +853,18 @@ static bool ath9k_rx_accept(struct ath_c
-        * descriptors.
-        */
-       if (rx_stats->rs_status != 0) {
--              if (rx_stats->rs_status & ATH9K_RXERR_CRC)
-+              if (rx_stats->rs_status & ATH9K_RXERR_CRC) {
-                       rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
-+                      mic_error = false;
-+              }
-               if (rx_stats->rs_status & ATH9K_RXERR_PHY)
-                       return false;
-               if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
-                       *decrypt_error = true;
--              } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
--                      bool is_mc;
--                      /*
--                       * The MIC error bit is only valid if the frame
--                       * is not a control frame or fragment, and it was
--                       * decrypted using a valid TKIP key.
--                       */
--                      is_mc = !!is_multicast_ether_addr(hdr->addr1);
--
--                      if (!ieee80211_is_ctl(fc) &&
--                          !ieee80211_has_morefrags(fc) &&
--                          !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
--                          is_mc_or_valid_tkip_keyix)
--                              rxs->flag |= RX_FLAG_MMIC_ERROR;
--                      else
--                              rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
-+                      mic_error = false;
-               }
-+
-               /*
-                * Reject error frames with the exception of
-                * decryption and MIC failures. For monitor mode,
-@@ -886,6 +882,18 @@ static bool ath9k_rx_accept(struct ath_c
-                       }
-               }
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -2236,7 +2236,7 @@ static int nl80211_send_station(struct s
        }
-+
-+      /*
-+       * For unicast frames the MIC error bit can have false positives,
-+       * so all MIC error reports need to be validated in software.
-+       * False negatives are not common, so skip software verification
-+       * if the hardware considers the MIC valid.
-+       */
-+      if (strip_mic)
-+              rxs->flag |= RX_FLAG_MMIC_STRIPPED;
-+      else if (is_mc && mic_error)
-+              rxs->flag |= RX_FLAG_MMIC_ERROR;
-+
-       return true;
- }
-@@ -1938,6 +1946,9 @@ int ath_rx_tasklet(struct ath_softc *sc,
-                       sc->rx.rxotherant = 0;
-               }
-+              if (rxs->flag & RX_FLAG_MMIC_STRIPPED)
-+                      skb_trim(skb, skb->len - 8);
-+
-               spin_lock_irqsave(&sc->sc_pm_lock, flags);
-               if ((sc->ps_flags & (PS_WAIT_FOR_BEACON |
---- a/drivers/net/wireless/ath/ath9k/reg.h
-+++ b/drivers/net/wireless/ath/ath9k/reg.h
-@@ -600,7 +600,6 @@
- #define AR_D_GBL_IFS_SIFS         0x1030
- #define AR_D_GBL_IFS_SIFS_M       0x0000FFFF
--#define AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR 0x000003AB
- #define AR_D_GBL_IFS_SIFS_RESV0   0xFFFFFFFF
- #define AR_D_TXBLK_BASE            0x1038
-@@ -616,12 +615,10 @@
- #define AR_D_GBL_IFS_SLOT         0x1070
- #define AR_D_GBL_IFS_SLOT_M       0x0000FFFF
- #define AR_D_GBL_IFS_SLOT_RESV0   0xFFFF0000
--#define AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR   0x00000420
- #define AR_D_GBL_IFS_EIFS         0x10b0
- #define AR_D_GBL_IFS_EIFS_M       0x0000FFFF
- #define AR_D_GBL_IFS_EIFS_RESV0   0xFFFF0000
--#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR   0x0000A5EB
- #define AR_D_GBL_IFS_MISC        0x10f0
- #define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL        0x00000007
-@@ -1477,7 +1474,6 @@ enum {
- #define AR_TIME_OUT_ACK_S    0
- #define AR_TIME_OUT_CTS      0x3FFF0000
- #define AR_TIME_OUT_CTS_S    16
--#define AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR    0x16001D56
+       nla_nest_end(msg, sinfoattr);
  
- #define AR_RSSI_THR          0x8018
- #define AR_RSSI_THR_MASK     0x000000FF
-@@ -1493,7 +1489,6 @@ enum {
- #define AR_USEC_TX_LAT_S     14
- #define AR_USEC_RX_LAT       0x1F800000
- #define AR_USEC_RX_LAT_S     23
--#define AR_USEC_ASYNC_FIFO_DUR    0x12e00074
+-      if (sinfo->assoc_req_ies)
++      if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
+               NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
+                       sinfo->assoc_req_ies);
  
- #define AR_RESET_TSF        0x8020
- #define AR_RESET_TSF_ONCE   0x01000000
index 1518afd..0a770d2 100644 (file)
@@ -1,6 +1,6 @@
 --- a/include/net/cfg80211.h
 +++ b/include/net/cfg80211.h
-@@ -1038,6 +1038,7 @@ struct cfg80211_ibss_params {
+@@ -1045,6 +1045,7 @@ struct cfg80211_ibss_params {
        u8 *ssid;
        u8 *bssid;
        struct ieee80211_channel *channel;
@@ -8,7 +8,7 @@
        u8 *ie;
        u8 ssid_len, ie_len;
        u16 beacon_interval;
-@@ -2539,6 +2540,12 @@ struct cfg80211_bss *cfg80211_get_bss(st
+@@ -2478,6 +2479,12 @@ struct cfg80211_bss *cfg80211_get_bss(st
                                      const u8 *bssid,
                                      const u8 *ssid, size_t ssid_len,
                                      u16 capa_mask, u16 capa_val);
  static inline struct cfg80211_bss *
  cfg80211_get_ibss(struct wiphy *wiphy,
                  struct ieee80211_channel *channel,
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -4351,13 +4351,41 @@ static int nl80211_join_ibss(struct sk_b
+               ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+       }
+-      ibss.channel = ieee80211_get_channel(wiphy,
+-              nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
++      if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
++              enum nl80211_channel_type channel_type;
++
++              channel_type = nla_get_u32(
++                      info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
++              if (channel_type != NL80211_CHAN_NO_HT &&
++                  channel_type != NL80211_CHAN_HT20 &&
++                  channel_type != NL80211_CHAN_HT40PLUS &&
++                  channel_type != NL80211_CHAN_HT40MINUS)
++                      return -EINVAL;
++              ibss.channel_type = channel_type;
++      } else {
++              ibss.channel_type = NL80211_CHAN_NO_HT;
++      }
++
++      ibss.channel = rdev_freq_to_chan(rdev,
++              nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
++              ibss.channel_type);
+       if (!ibss.channel ||
++          ibss.channel->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
+           ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
+-          ibss.channel->flags & IEEE80211_CHAN_DISABLED)
++          ibss.channel->flags & IEEE80211_CHAN_RADAR)
+               return -EINVAL;
++      /* Both channels should be able to initiate communication */
++      if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
++           ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
++          !can_beacon_sec_chan(&rdev->wiphy, ibss.channel,
++                               ibss.channel_type)) {
++              printk(KERN_DEBUG
++                     "cfg80211: Secondary channel not "
++                     "allowed to initiate communication\n");
++              return -EINVAL;
++      }
++
+       ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
+       ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -44,7 +44,7 @@ rdev_freq_to_chan(struct cfg80211_regist
+       return chan;
+ }
+-static bool can_beacon_sec_chan(struct wiphy *wiphy,
++bool can_beacon_sec_chan(struct wiphy *wiphy,
+                               struct ieee80211_channel *chan,
+                               enum nl80211_channel_type channel_type)
+ {
+@@ -75,6 +75,7 @@ static bool can_beacon_sec_chan(struct w
+       return true;
+ }
++EXPORT_SYMBOL(can_beacon_sec_chan);
+ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
+                     struct wireless_dev *wdev, int freq,
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -441,6 +441,9 @@ cfg80211_can_add_interface(struct cfg802
+ struct ieee80211_channel *
+ rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
+                 int freq, enum nl80211_channel_type channel_type);
++bool can_beacon_sec_chan(struct wiphy *wiphy,
++                              struct ieee80211_channel *chan,
++                              enum nl80211_channel_type channel_type);
+ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
+                     struct wireless_dev *wdev, int freq,
+                     enum nl80211_channel_type channel_type);
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -365,6 +365,19 @@ struct cfg80211_bss *cfg80211_get_bss(st
+                                     const u8 *ssid, size_t ssid_len,
+                                     u16 capa_mask, u16 capa_val)
+ {
++      /* call HT version with no HT requirements */
++      return cfg80211_get_bss_ht(wiphy, channel, bssid, ssid, ssid_len,
++                                 capa_mask, capa_val, NL80211_CHAN_NO_HT);
++}
++EXPORT_SYMBOL(cfg80211_get_bss);
++
++struct cfg80211_bss *cfg80211_get_bss_ht(struct wiphy *wiphy,
++                                    struct ieee80211_channel *channel,
++                                    const u8 *bssid,
++                                    const u8 *ssid, size_t ssid_len,
++                                    u16 capa_mask, u16 capa_val,
++                                    enum nl80211_channel_type require_ht)
++{
+       struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
+       struct cfg80211_internal_bss *bss, *res = NULL;
+       unsigned long now = jiffies;
+@@ -374,8 +387,26 @@ struct cfg80211_bss *cfg80211_get_bss(st
+       list_for_each_entry(bss, &dev->bss_list, list) {
+               if ((bss->pub.capability & capa_mask) != capa_val)
+                       continue;
+-              if (channel && bss->pub.channel != channel)
+-                      continue;
++              if (channel) {
++                      if (bss->pub.channel != channel)
++                              continue;
++                      if (require_ht != NL80211_CHAN_NO_HT) {
++                              struct ieee80211_ht_info *ht_info;
++                              ht_info = (struct ieee80211_ht_info *)
++                                      ieee80211_bss_get_ie(&bss->pub,
++                                                     WLAN_EID_HT_INFORMATION);
++                              if (!ht_info)
++                                      continue;
++                              if (require_ht == NL80211_CHAN_HT40MINUS &&
++                                            !(ht_info->ht_param &
++                                            IEEE80211_HT_PARAM_CHA_SEC_BELOW))
++                                      continue;
++                              if (require_ht == NL80211_CHAN_HT40PLUS &&
++                                            !(ht_info->ht_param &
++                                            IEEE80211_HT_PARAM_CHA_SEC_ABOVE))
++                                      continue;
++                      }
++              }
+               /* Don't get expired BSS structs */
+               if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
+                   !atomic_read(&bss->hold))
+@@ -392,7 +423,7 @@ struct cfg80211_bss *cfg80211_get_bss(st
+               return NULL;
+       return &res->pub;
+ }
+-EXPORT_SYMBOL(cfg80211_get_bss);
++EXPORT_SYMBOL(cfg80211_get_bss_ht);
+ struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
+                                      struct ieee80211_channel *channel,
 --- a/net/mac80211/ieee80211_i.h
 +++ b/net/mac80211/ieee80211_i.h
-@@ -439,6 +439,7 @@ struct ieee80211_if_ibss {
+@@ -464,6 +464,7 @@ struct ieee80211_if_ibss {
        u8 ssid_len, ie_len;
        u8 *ie;
        struct ieee80211_channel *channel;
  
        unsigned long ibss_join_req;
        /* probe response/beacon for IBSS */
-@@ -1121,6 +1122,7 @@ void ieee80211_ibss_notify_scan_complete
+@@ -1151,6 +1152,7 @@ void ieee80211_ibss_notify_scan_complete
  void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
  struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
                                        u8 *bssid, u8 *addr, u32 supp_rates,
                                        gfp_t gfp);
  int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
                        struct cfg80211_ibss_params *params);
-@@ -1373,6 +1375,12 @@ void ieee80211_recalc_smps(struct ieee80
+@@ -1405,6 +1407,12 @@ void ieee80211_recalc_smps(struct ieee80
  size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
                          const u8 *ids, int n_ids, size_t offset);
  size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
  
  /* internal work items */
  void ieee80211_work_init(struct ieee80211_local *local);
-@@ -1401,6 +1409,8 @@ ieee80211_get_channel_mode(struct ieee80
+@@ -1433,6 +1441,8 @@ ieee80211_get_channel_mode(struct ieee80
  bool ieee80211_set_channel_type(struct ieee80211_local *local,
                                struct ieee80211_sub_if_data *sdata,
                                enum nl80211_channel_type chantype);
  #define debug_noinline noinline
 --- a/net/mac80211/util.c
 +++ b/net/mac80211/util.c
-@@ -1007,23 +1007,8 @@ int ieee80211_build_preq_ies(struct ieee
+@@ -1008,23 +1008,8 @@ int ieee80211_build_preq_ies(struct ieee
                offset = noffset;
        }
  
  
        /*
         * If adding more here, adjust code in main.c
-@@ -1464,3 +1449,100 @@ size_t ieee80211_ie_split_vendor(const u
-       return pos;
+@@ -1548,3 +1533,100 @@ void ieee80211_disable_rssi_reports(stru
+       _ieee80211_enable_rssi_reports(sdata, 0, 0);
  }
+ EXPORT_SYMBOL(ieee80211_disable_rssi_reports);
 +
 +u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband,
 +                             u16 cap)
 +}
 --- a/net/mac80211/work.c
 +++ b/net/mac80211/work.c
-@@ -117,7 +117,6 @@ static void ieee80211_add_ht_ie(struct s
+@@ -118,7 +118,6 @@ static void ieee80211_add_ht_ie(struct s
        u8 *pos;
        u32 flags = channel->flags;
        u16 cap = sband->ht_cap.cap;
  
        if (!sband->ht_cap.ht_supported)
                return;
-@@ -168,34 +167,8 @@ static void ieee80211_add_ht_ie(struct s
+@@ -169,34 +168,8 @@ static void ieee80211_add_ht_ie(struct s
        }
  
        /* reserve and fill IE */
  }
  
  static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
---- a/net/wireless/scan.c
-+++ b/net/wireless/scan.c
-@@ -365,6 +365,18 @@ struct cfg80211_bss *cfg80211_get_bss(st
-                                     const u8 *ssid, size_t ssid_len,
-                                     u16 capa_mask, u16 capa_val)
- {
-+      return cfg80211_get_bss_ht(wiphy, channel, bssid, ssid, ssid_len,
-+                                 capa_mask, capa_val, NL80211_CHAN_NO_HT);
-+}
-+EXPORT_SYMBOL(cfg80211_get_bss);
-+
-+struct cfg80211_bss *cfg80211_get_bss_ht(struct wiphy *wiphy,
-+                                    struct ieee80211_channel *channel,
-+                                    const u8 *bssid,
-+                                    const u8 *ssid, size_t ssid_len,
-+                                    u16 capa_mask, u16 capa_val,
-+                                    enum nl80211_channel_type channel_type)
-+{
-       struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
-       struct cfg80211_internal_bss *bss, *res = NULL;
-       unsigned long now = jiffies;
-@@ -374,8 +386,27 @@ struct cfg80211_bss *cfg80211_get_bss(st
-       list_for_each_entry(bss, &dev->bss_list, list) {
-               if ((bss->pub.capability & capa_mask) != capa_val)
-                       continue;
--              if (channel && bss->pub.channel != channel)
--                      continue;
-+              if (channel) {
-+                      if (bss->pub.channel != channel)
-+                              continue;
-+                      if (channel_type == NL80211_CHAN_HT40MINUS ||
-+                          channel_type == NL80211_CHAN_HT40PLUS) {
-+                              struct ieee80211_ht_info *ht_info;
-+                              ht_info = (struct ieee80211_ht_info *)
-+                                      ieee80211_bss_get_ie(&bss->pub,
-+                                                     WLAN_EID_HT_INFORMATION);
-+                              if (!ht_info)
-+                                      continue;
-+                              if (channel_type == NL80211_CHAN_HT40MINUS &&
-+                                            !(ht_info->ht_param &
-+                                            IEEE80211_HT_PARAM_CHA_SEC_BELOW))
-+                                      continue;
-+                              if (channel_type == NL80211_CHAN_HT40PLUS &&
-+                                            !(ht_info->ht_param &
-+                                            IEEE80211_HT_PARAM_CHA_SEC_ABOVE))
-+                                      continue;
-+                      }
-+              }
-               /* Don't get expired BSS structs */
-               if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
-                   !atomic_read(&bss->hold))
-@@ -392,7 +423,7 @@ struct cfg80211_bss *cfg80211_get_bss(st
-               return NULL;
-       return &res->pub;
- }
--EXPORT_SYMBOL(cfg80211_get_bss);
-+EXPORT_SYMBOL(cfg80211_get_bss_ht);
- struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
-                                      struct ieee80211_channel *channel,
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -4282,13 +4282,42 @@ static int nl80211_join_ibss(struct sk_b
-               ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
-       }
--      ibss.channel = ieee80211_get_channel(wiphy,
--              nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
-+      if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
-+              enum nl80211_channel_type channel_type;
-+
-+              channel_type = nla_get_u32(
-+                      info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
-+              if (channel_type != NL80211_CHAN_NO_HT &&
-+                  channel_type != NL80211_CHAN_HT20 &&
-+                  channel_type != NL80211_CHAN_HT40PLUS &&
-+                  channel_type != NL80211_CHAN_HT40MINUS)
-+                      return -EINVAL;
-+              ibss.channel_type = channel_type;
-+      } else {
-+              ibss.channel_type = NL80211_CHAN_NO_HT;
-+      }
-+
-+      ibss.channel = rdev_freq_to_chan(rdev,
-+              nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
-+              ibss.channel_type);
-+
-       if (!ibss.channel ||
-+          ibss.channel->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
-           ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
-           ibss.channel->flags & IEEE80211_CHAN_DISABLED)
-               return -EINVAL;
-+#if 0
-+      if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
-+           ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
-+          !can_beacon_sec_chan(&rdev->wiphy, ibss.chan, ibss.channel_type)) {
-+              printk(KERN_DEBUG
-+                     "cfg80211: Secondary channel not "
-+                     "allowed to initiate communication\n");
-+              return -EINVAL;
-+      }
-+#endif
-+
-       ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
-       ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
---- a/net/mac80211/agg-rx.c
-+++ b/net/mac80211/agg-rx.c
-@@ -178,6 +178,8 @@ static void ieee80211_send_addba_resp(st
-               memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
-       else if (sdata->vif.type == NL80211_IFTYPE_WDS)
-               memcpy(mgmt->bssid, da, ETH_ALEN);
-+      else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-+              memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
-       mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-                                         IEEE80211_STYPE_ACTION);
 --- a/net/mac80211/agg-tx.c
 +++ b/net/mac80211/agg-tx.c
 @@ -84,6 +84,8 @@ static void ieee80211_send_addba_request
                                          IEEE80211_STYPE_ACTION);
 --- a/net/mac80211/ibss.c
 +++ b/net/mac80211/ibss.c
-@@ -64,6 +64,7 @@ static void ieee80211_rx_mgmt_auth_ibss(
+@@ -35,6 +35,76 @@
+ #define IEEE80211_IBSS_MAX_STA_ENTRIES 128
++static bool ieee80211_can_use_ext_chan(struct ieee80211_sub_if_data *sdata,
++                                     struct ieee80211_channel *channel,
++                                     enum nl80211_channel_type channel_type)
++{
++      /* check if we are legally allowed to use HT extension channel */
++      if ((channel_type == NL80211_CHAN_HT40PLUS) ||
++                      (channel_type == NL80211_CHAN_HT40MINUS)) {
++              int sec_freq = channel->center_freq +
++                           (channel_type == NL80211_CHAN_HT40PLUS ? 20 : -20);
++              struct ieee80211_channel *sec_chan =
++                           ieee80211_get_channel(sdata->wdev.wiphy, sec_freq);
++              if (!sec_chan || sec_chan->flags & (IEEE80211_CHAN_DISABLED |
++                                         IEEE80211_CHAN_PASSIVE_SCAN |
++                                         IEEE80211_CHAN_NO_IBSS |
++                                         IEEE80211_CHAN_RADAR)) {
++                      return false;
++              }
++      }
++      return true;
++}
++
++static void ieee80211_update_ht_elems(struct ieee80211_sub_if_data *sdata,
++                                    struct ieee80211_mgmt *mgmt,
++                                    struct ieee80211_ht_info *ht_info)
++{
++      struct ieee80211_local *local = sdata->local;
++      struct ieee80211_supported_band *sband =
++                      local->hw.wiphy->bands[local->oper_channel->band];
++      enum nl80211_channel_type channel_type =
++                      ieee80211_ht_info_to_channel_type(ht_info);
++
++      if (!ieee80211_can_use_ext_chan(sdata, local->oper_channel, channel_type))
++              channel_type = NL80211_CHAN_HT20;
++
++      if (channel_type != local->_oper_channel_type) {
++              struct sk_buff *skb = rcu_dereference_protected(
++                              sdata->u.ibss.presp,
++                              lockdep_is_held(&ifibss->mtx));
++              struct sk_buff *nskb;
++              u8 *ht_ie;
++
++              /* update HT IE. If not yet existing, create one */
++              nskb = skb_copy(skb, GFP_ATOMIC);
++              ht_ie = (u8 *)cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
++                                             (const u8 *)(nskb->data + 24 +
++                                                      sizeof(mgmt->u.beacon)),
++                                             nskb->len - 24 -
++                                                      sizeof(mgmt->u.beacon));
++              if (!ht_ie)
++                      ht_ie = skb_put(nskb, 4 +
++                                            sizeof(struct ieee80211_ht_cap) +
++                                            sizeof(struct ieee80211_ht_info));
++
++              ht_ie = ieee80211_ie_build_ht_cap(ht_ie, sband,
++                                                sband->ht_cap.cap);
++              ht_ie = ieee80211_ie_build_ht_info(ht_ie, &sband->ht_cap,
++                                           local->oper_channel, channel_type);
++              rcu_assign_pointer(sdata->u.ibss.presp, nskb);
++              kfree_skb(skb);
++
++              if(!ieee80211_set_channel_type(local, sdata, channel_type)) {
++                      channel_type = NL80211_CHAN_HT20;
++                      WARN_ON(!ieee80211_set_channel_type(local, sdata,
++                                                          channel_type));
++              }
++
++              ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
++      }
++
++}
+ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
+                                       struct ieee80211_mgmt *mgmt,
+@@ -64,6 +134,7 @@ static void ieee80211_rx_mgmt_auth_ibss(
  static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                                      const u8 *bssid, const int beacon_int,
                                      struct ieee80211_channel *chan,
                                      const u32 basic_rates,
                                      const u16 capability, u64 tsf)
  {
-@@ -104,8 +105,12 @@ static void __ieee80211_sta_join_ibss(st
+@@ -104,8 +175,17 @@ static void __ieee80211_sta_join_ibss(st
  
        sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
  
 +      /* entering a legacy IBSS. Use given HT configuration. */
 +      if (channel_type == NL80211_CHAN_NO_HT)
 +              channel_type = ifibss->channel_type;
-+
        local->oper_channel = chan;
 -      WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
-+      WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
++
++      /* if phy is on a different extension channel, setting ht40 will fail */
++      if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
++              channel_type = NL80211_CHAN_HT20;
++              WARN_ON(!ieee80211_set_channel_type(local, sdata,
++                                                               channel_type));
++      }
        ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
  
        sband = local->hw.wiphy->bands[chan->band];
-@@ -171,6 +176,17 @@ static void __ieee80211_sta_join_ibss(st
+@@ -171,6 +251,18 @@ static void __ieee80211_sta_join_ibss(st
                memcpy(skb_put(skb, ifibss->ie_len),
                       ifibss->ie, ifibss->ie_len);
  
++      /* add HT capability and information IEs */
 +      if (channel_type != NL80211_CHAN_NO_HT && sband->ht_cap.ht_supported) {
 +              pos = skb_put(skb, 4 +
 +                                 sizeof(struct ieee80211_ht_cap) +
        if (local->hw.queues >= 4) {
                pos = skb_put(skb, 9);
                *pos++ = WLAN_EID_VENDOR_SPECIFIC;
-@@ -219,6 +235,8 @@ static void ieee80211_sta_join_ibss(stru
+@@ -219,6 +311,8 @@ static void ieee80211_sta_join_ibss(stru
        u32 basic_rates;
        int i, j;
        u16 beacon_int = cbss->beacon_interval;
  
        lockdep_assert_held(&sdata->u.ibss.mtx);
  
-@@ -242,9 +260,15 @@ static void ieee80211_sta_join_ibss(stru
+@@ -242,9 +336,23 @@ static void ieee80211_sta_join_ibss(stru
                }
        }
  
 +      if (ht_info_ie)
 +              channel_type = ieee80211_ht_info_to_channel_type(
 +                      (struct ieee80211_ht_info *) (ht_info_ie + 2));
++
++      if (!ieee80211_can_use_ext_chan(sdata, cbss->channel, channel_type)) {
++              channel_type = NL80211_CHAN_HT20;
++#ifdef CONFIG_MAC80211_IBSS_DEBUG
++              printk(KERN_DEBUG "%s: IBSS not allowed on secondary channel\n",
++                     sdata->name);
++#endif
++      }
 +
        __ieee80211_sta_join_ibss(sdata, cbss->bssid,
                                  beacon_int,
                                  basic_rates,
                                  cbss->capability,
                                  cbss->tsf);
-@@ -310,11 +334,65 @@ static void ieee80211_rx_bss_info(struct
+@@ -310,11 +418,24 @@ static void ieee80211_rx_bss_info(struct
                        } else
                                sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
                                                mgmt->sa, supp_rates,
 +                      if (elems->wmm_info)
 +                              set_sta_flags(sta, WLAN_STA_WME);
 +
++                      /* remote station uses ht */
 +                      if (elems->ht_info_elem) {
-+                              struct ieee80211_supported_band *sband =
-+                                      local->hw.wiphy->bands[channel->band];
-+                              enum nl80211_channel_type channel_type;
-+
-+                              channel_type =
-+                                      ieee80211_ht_info_to_channel_type(
-+                                              elems->ht_info_elem);
-+                              if (channel_type != local->_oper_channel_type) {
-+                                      struct sk_buff *skb =
-+                                                      sdata->u.ibss.presp;
-+                                      struct sk_buff *nskb;
-+                                      u8 *ht_ie;
-+
-+                                      nskb = skb_copy(skb, GFP_ATOMIC);
-+                                      ht_ie = (u8 *) cfg80211_find_ie(
-+                                              WLAN_EID_HT_CAPABILITY,
-+                                              nskb->data + 24 +
-+                                                      sizeof(mgmt->u.beacon),
-+                                              nskb->len - 24 -
-+                                                      sizeof(mgmt->u.beacon));
-+
-+                                      if (!ht_ie)
-+                                              ht_ie = skb_put(nskb, 4 +
-+                                            sizeof(struct ieee80211_ht_cap) +
-+                                            sizeof(struct ieee80211_ht_info));
-+                                      ht_ie = ieee80211_ie_build_ht_cap(ht_ie,
-+                                                           sband,
-+                                                           sband->ht_cap.cap);
-+                                      ht_ie = ieee80211_ie_build_ht_info(
-+                                                               ht_ie,
-+                                                               &sband->ht_cap,
-+                                                               channel,
-+                                                               channel_type);
-+                                      sdata->u.ibss.presp = nskb;
-+                                      kfree_skb(skb);
-+
-+                                      local->_oper_channel_type =
-+                                                              channel_type;
-+                                      WARN_ON(!ieee80211_set_channel_type(
-+                                                              local,
-+                                                              sdata,
-+                                                              channel_type));
-+                                      ieee80211_hw_config(local,
-+                                              IEEE80211_CONF_CHANGE_CHANNEL);
-+                              }
-+                              ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
-+                                                      elems->ht_cap_elem,
-+                                                      &sta->sta.ht_cap);
-+
++                              ieee80211_update_ht_elems(sdata, mgmt,
++                                                        elems->ht_info_elem);
++                              ieee80211_ht_cap_ie_to_sta_ht_cap(
++                                              local->hw.wiphy->bands[
++                                                   local->oper_channel->band],
++                                              elems->ht_cap_elem,
++                                              &sta->sta.ht_cap);
 +                      }
 +              }
  
                rcu_read_unlock();
        }
-@@ -404,7 +482,7 @@ static void ieee80211_rx_bss_info(struct
+@@ -404,7 +525,7 @@ static void ieee80211_rx_bss_info(struct
                ieee80211_sta_join_ibss(sdata, bss);
                supp_rates = ieee80211_sta_get_rates(local, elems, band);
                ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
        }
  
   put_bss:
-@@ -417,7 +495,8 @@ static void ieee80211_rx_bss_info(struct
+@@ -417,7 +538,8 @@ static void ieee80211_rx_bss_info(struct
   * must be callable in atomic context.
   */
  struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
                                        gfp_t gfp)
  {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
-@@ -458,6 +537,11 @@ struct sta_info *ieee80211_ibss_add_sta(
+@@ -458,6 +580,11 @@ struct sta_info *ieee80211_ibss_add_sta(
        sta->sta.supp_rates[band] = supp_rates |
                        ieee80211_mandatory_rates(local, band);
  
        rate_control_rate_init(sta);
  
        /* If it fails, maybe we raced another insertion? */
-@@ -556,8 +640,8 @@ static void ieee80211_sta_create_ibss(st
+@@ -556,8 +683,8 @@ static void ieee80211_sta_create_ibss(st
                sdata->drop_unencrypted = 0;
  
        __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
  }
  
  /*
-@@ -594,10 +678,10 @@ static void ieee80211_sta_find_ibss(stru
+@@ -594,10 +721,10 @@ static void ieee80211_sta_find_ibss(stru
                chan = ifibss->channel;
        if (!is_zero_ether_addr(ifibss->bssid))
                bssid = ifibss->bssid;
  
        if (cbss) {
                struct ieee80211_bss *bss;
-@@ -896,10 +980,15 @@ int ieee80211_ibss_join(struct ieee80211
+@@ -896,10 +1023,15 @@ int ieee80211_ibss_join(struct ieee80211
        struct sk_buff *skb;
  
        skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
                            params->ie_len);
        if (!skb)
                return -ENOMEM;
-@@ -920,13 +1009,14 @@ int ieee80211_ibss_join(struct ieee80211
+@@ -920,13 +1052,15 @@ int ieee80211_ibss_join(struct ieee80211
        sdata->vif.bss_conf.beacon_int = params->beacon_interval;
  
        sdata->u.ibss.channel = params->channel;
        /* fix ourselves to that channel now already */
        if (params->channel_fixed) {
                sdata->local->oper_channel = params->channel;
-               WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata,
+-              WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata,
 -                                                  NL80211_CHAN_NO_HT));
-+                                                  params->channel_type));
++              if(!ieee80211_set_channel_type(sdata->local, sdata,
++                                             params->channel_type))
++                      return -EINVAL;
        }
  
        if (params->ie) {
 --- a/net/mac80211/rx.c
 +++ b/net/mac80211/rx.c
-@@ -2138,7 +2138,8 @@ ieee80211_rx_h_action(struct ieee80211_r
+@@ -2148,7 +2148,8 @@ ieee80211_rx_h_action(struct ieee80211_r
                if (sdata->vif.type != NL80211_IFTYPE_STATION &&
                    sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
                    sdata->vif.type != NL80211_IFTYPE_AP &&
                        break;
  
                /* verify action_code is present */
-@@ -2654,7 +2655,8 @@ static int prepare_for_handlers(struct i
+@@ -2666,7 +2667,8 @@ static int prepare_for_handlers(struct i
                        else
                                rate_idx = status->rate_idx;
                        rx->sta = ieee80211_ibss_add_sta(sdata, bssid,
                }
                break;
        case NL80211_IFTYPE_MESH_POINT:
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -186,6 +186,8 @@ static void ieee80211_send_addba_resp(st
+               memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+       else if (sdata->vif.type == NL80211_IFTYPE_WDS)
+               memcpy(mgmt->bssid, da, ETH_ALEN);
++      else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
++              memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
+       mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+                                         IEEE80211_STYPE_ACTION);
index 75e6454..0721227 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -34,7 +34,7 @@ int ath9k_modparam_nohwcrypt;
+@@ -35,7 +35,7 @@ int ath9k_modparam_nohwcrypt;
  module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
  MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
  
index 8803888..cc59b75 100644 (file)
@@ -8,7 +8,7 @@
  #include <asm/unaligned.h>
  
  #include "hw.h"
-@@ -453,8 +454,16 @@ static int ath9k_hw_init_macaddr(struct 
+@@ -460,8 +461,16 @@ static int ath9k_hw_init_macaddr(struct 
                common->macaddr[2 * i] = eeval >> 8;
                common->macaddr[2 * i + 1] = eeval & 0xff;
        }
index 597d151..582d569 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/wireless/reg.c
 +++ b/net/wireless/reg.c
-@@ -1643,6 +1643,8 @@ void regulatory_hint_11d(struct wiphy *w
+@@ -1642,6 +1642,8 @@ void regulatory_hint_11d(struct wiphy *w
        enum environment_cap env = ENVIRON_ANY;
        struct regulatory_request *request;
  
@@ -9,7 +9,7 @@
        mutex_lock(&reg_mutex);
  
        if (unlikely(!last_request))
-@@ -1849,6 +1851,8 @@ static void restore_regulatory_settings(
+@@ -1848,6 +1850,8 @@ static void restore_regulatory_settings(
  
  void regulatory_hint_disconnect(void)
  {
index fdff5dc..f1ae1ad 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1495,15 +1495,6 @@ static int ath9k_add_interface(struct ie
+@@ -1499,15 +1499,6 @@ static int ath9k_add_interface(struct ie
                }
        }
  
@@ -16,7 +16,7 @@
        ath_dbg(common, ATH_DBG_CONFIG,
                "Attach a VIF of type: %d\n", vif->type);
  
-@@ -1529,15 +1520,6 @@ static int ath9k_change_interface(struct
+@@ -1533,15 +1524,6 @@ static int ath9k_change_interface(struct
        mutex_lock(&sc->mutex);
        ath9k_ps_wakeup(sc);
  
index a754774..65491e0 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
 +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
-@@ -95,13 +95,8 @@ ath5k_add_interface(struct ieee80211_hw 
+@@ -83,13 +83,8 @@ ath5k_add_interface(struct ieee80211_hw 
                goto end;
        }
  
@@ -9,30 +9,30 @@
 -       * We would need to operate the HW in ad-hoc mode to allow TSF updates
 -       * for the IBSS, but this breaks with additional AP or STA interfaces
 -       * at the moment. */
--      if (sc->num_adhoc_vifs ||
--          (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
+-      if (ah->num_adhoc_vifs ||
+-          (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
 +      /* Don't allow more than one ad-hoc interface */
-+      if (sc->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) {
-               ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n");
++      if (ah->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) {
+               ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n");
                ret = -ELNRNG;
                goto end;
 --- a/drivers/net/wireless/ath/ath5k/base.c
 +++ b/drivers/net/wireless/ath/ath5k/base.c
-@@ -1883,7 +1883,7 @@ ath5k_beacon_send(struct ath5k_softc *sc
-               sc->bmisscount = 0;
+@@ -1866,7 +1866,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
+               ah->bmisscount = 0;
        }
  
--      if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) ||
-+      if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs + sc->num_adhoc_vifs > 1) ||
-                       sc->opmode == NL80211_IFTYPE_MESH_POINT) {
+-      if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) ||
++      if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + ah->num_adhoc_vifs > 1) ||
+                       ah->opmode == NL80211_IFTYPE_MESH_POINT) {
                u64 tsf = ath5k_hw_get_tsf64(ah);
                u32 tsftu = TSF_TO_TU(tsf);
-@@ -1961,7 +1961,7 @@ ath5k_beacon_update_timers(struct ath5k_
+@@ -1951,7 +1951,7 @@ ath5k_beacon_update_timers(struct ath5k_
        u64 hw_tsf;
  
-       intval = sc->bintval & AR5K_BEACON_PERIOD;
--      if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
-+      if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs + sc->num_adhoc_vifs > 1) {
+       intval = ah->bintval & AR5K_BEACON_PERIOD;
+-      if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) {
++      if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + ah->num_adhoc_vifs > 1) {
                intval /= ATH_BCBUF;    /* staggered multi-bss beacons */
                if (intval < 15)
-                       ATH5K_WARN(sc, "intval %u is too low, min 15\n",
+                       ATH5K_WARN(ah, "intval %u is too low, min 15\n",
index e049645..8ca821c 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath5k/reset.c
 +++ b/drivers/net/wireless/ath/ath5k/reset.c
-@@ -1035,6 +1035,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, 
+@@ -1040,6 +1040,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, 
        tsf_lo = 0;
        mode = 0;
  
@@ -8,7 +8,7 @@
        /*
         * Sanity check for fast flag
         * Fast channel change only available
-@@ -1042,6 +1043,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, 
+@@ -1047,6 +1048,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, 
         */
        if (fast && (ah->ah_radio != AR5K_RF2413) &&
        (ah->ah_radio != AR5K_RF5413))
diff --git a/package/mac80211/patches/440-ath5k_calibrate_srev_checks.patch b/package/mac80211/patches/440-ath5k_calibrate_srev_checks.patch
deleted file mode 100644 (file)
index cbfdad4..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/drivers/net/wireless/ath/ath5k/phy.c
-+++ b/drivers/net/wireless/ath/ath5k/phy.c
-@@ -1604,11 +1604,13 @@ int ath5k_hw_phy_calibrate(struct ath5k_
-       int ret;
-       if (ah->ah_radio == AR5K_RF5110)
--              ret = ath5k_hw_rf5110_calibrate(ah, channel);
--      else {
--              ret = ath5k_hw_rf511x_iq_calibrate(ah);
-+              return ath5k_hw_rf5110_calibrate(ah, channel);
-+
-+      ret = ath5k_hw_rf511x_iq_calibrate(ah);
-+
-+      if (ah->ah_radio == AR5K_RF5112 &&
-+          (channel->hw_value & (CHANNEL_5GHZ | CHANNEL_OFDM)))
-               ath5k_hw_request_rfgain_probe(ah);
--      }
-       return ret;
- }
diff --git a/package/mac80211/patches/441-ath5k_synth_voltage_srev_check.patch b/package/mac80211/patches/441-ath5k_synth_voltage_srev_check.patch
deleted file mode 100644 (file)
index d08b823..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
---- a/drivers/net/wireless/ath/ath5k/phy.c
-+++ b/drivers/net/wireless/ath/ath5k/phy.c
-@@ -970,17 +970,20 @@ static int ath5k_hw_rfregs_init(struct a
-                       }
-                       /* Lower synth voltage on Rev 2 */
--                      ath5k_hw_rfb_op(ah, rf_regs, 2,
--                                      AR5K_RF_HIGH_VC_CP, true);
-+                      if (ah->ah_radio == AR5K_RF5112 &&
-+                          (ah->ah_radio_5ghz_revision & AR5K_SREV_REV) > 0) {
-+                              ath5k_hw_rfb_op(ah, rf_regs, 2,
-+                                              AR5K_RF_HIGH_VC_CP, true);
--                      ath5k_hw_rfb_op(ah, rf_regs, 2,
--                                      AR5K_RF_MID_VC_CP, true);
-+                              ath5k_hw_rfb_op(ah, rf_regs, 2,
-+                                              AR5K_RF_MID_VC_CP, true);
--                      ath5k_hw_rfb_op(ah, rf_regs, 2,
--                                      AR5K_RF_LOW_VC_CP, true);
-+                              ath5k_hw_rfb_op(ah, rf_regs, 2,
-+                                              AR5K_RF_LOW_VC_CP, true);
--                      ath5k_hw_rfb_op(ah, rf_regs, 2,
--                                      AR5K_RF_PUSH_UP, true);
-+                              ath5k_hw_rfb_op(ah, rf_regs, 2,
-+                                              AR5K_RF_PUSH_UP, true);
-+                      }
-                       /* Decrease power consumption on 5213+ BaseBand */
-                       if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
diff --git a/package/mac80211/patches/442-ath5k_spur_channel_srev_check.patch b/package/mac80211/patches/442-ath5k_spur_channel_srev_check.patch
deleted file mode 100644 (file)
index 1931be8..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/drivers/net/wireless/ath/ath5k/phy.c
-+++ b/drivers/net/wireless/ath/ath5k/phy.c
-@@ -105,6 +105,7 @@ bool ath5k_hw_chan_has_spur_noise(struct
-       if ((ah->ah_radio == AR5K_RF5112) ||
-       (ah->ah_radio == AR5K_RF5413) ||
-+      (ah->ah_radio == AR5K_RF2413) ||
-       (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
-               refclk_freq = 40;
-       else
diff --git a/package/mac80211/patches/443-ath5k_initialize_clockrate.patch b/package/mac80211/patches/443-ath5k_initialize_clockrate.patch
deleted file mode 100644 (file)
index fedc2f4..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/drivers/net/wireless/ath/ath5k/base.c
-+++ b/drivers/net/wireless/ath/ath5k/base.c
-@@ -2422,6 +2422,7 @@ ath5k_init_softc(struct ath5k_softc *sc,
-       common->ah = sc->ah;
-       common->hw = hw;
-       common->priv = sc;
-+      common->clockrate = 40;
-       /*
-        * Cache line size is used to size and align various
diff --git a/package/mac80211/patches/444-ath5k_delay_calibration.patch b/package/mac80211/patches/444-ath5k_delay_calibration.patch
deleted file mode 100644 (file)
index f5dd3f2..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/drivers/net/wireless/ath/ath5k/base.c
-+++ b/drivers/net/wireless/ath/ath5k/base.c
-@@ -2728,7 +2728,7 @@ ath5k_reset(struct ath5k_softc *sc, stru
-       ath5k_ani_init(ah, ani_mode);
--      ah->ah_cal_next_full = jiffies;
-+      ah->ah_cal_next_full = jiffies + msecs_to_jiffies(100);
-       ah->ah_cal_next_ani = jiffies;
-       ah->ah_cal_next_nf = jiffies;
-       ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);
diff --git a/package/mac80211/patches/445-ath5k_fix_mac_clock_restore.patch b/package/mac80211/patches/445-ath5k_fix_mac_clock_restore.patch
deleted file mode 100644 (file)
index e171cd1..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
---- a/drivers/net/wireless/ath/ath5k/reset.c
-+++ b/drivers/net/wireless/ath/ath5k/reset.c
-@@ -233,7 +233,7 @@ static void ath5k_hw_init_core_clock(str
- static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
- {
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
--      u32 scal, spending;
-+      u32 scal, spending, sclock;
-       /* Only set 32KHz settings if we have an external
-        * 32KHz crystal present */
-@@ -317,6 +317,15 @@ static void ath5k_hw_set_sleep_clock(str
-               /* Set up tsf increment on each cycle */
-               AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
-+
-+              if ((ah->ah_radio == AR5K_RF5112) ||
-+                      (ah->ah_radio == AR5K_RF5413) ||
-+                      (ah->ah_radio == AR5K_RF2316) ||
-+                      (ah->ah_radio == AR5K_RF2317))
-+                      sclock = 40 - 1;
-+              else
-+                      sclock = 32 - 1;
-+              AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, sclock);
-       }
- }
diff --git a/package/mac80211/patches/446-ath5k_disable_32khz_clock.patch b/package/mac80211/patches/446-ath5k_disable_32khz_clock.patch
deleted file mode 100644 (file)
index 21bf037..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/drivers/net/wireless/ath/ath5k/reset.c
-+++ b/drivers/net/wireless/ath/ath5k/reset.c
-@@ -1287,15 +1287,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, 
-        */
-       ath5k_hw_dma_init(ah);
--
--      /* Enable 32KHz clock function for AR5212+ chips
--       * Set clocks to 32KHz operation and use an
--       * external 32KHz crystal when sleeping if one
--       * exists */
--      if (ah->ah_version == AR5K_AR5212 &&
--          op_mode != NL80211_IFTYPE_AP)
--              ath5k_hw_set_sleep_clock(ah, true);
--
-       /*
-        * Disable beacons and reset the TSF
-        */
diff --git a/package/mac80211/patches/447-ath5k_fix_queue_stop_warning.patch b/package/mac80211/patches/447-ath5k_fix_queue_stop_warning.patch
deleted file mode 100644 (file)
index ade0eef..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/drivers/net/wireless/ath/ath5k/base.c
-+++ b/drivers/net/wireless/ath/ath5k/base.c
-@@ -1555,7 +1555,8 @@ ath5k_tx_queue(struct ieee80211_hw *hw, 
-               goto drop_packet;
-       }
--      if (txq->txq_len >= txq->txq_max)
-+      if (txq->txq_len >= txq->txq_max &&
-+          txq->qnum <= AR5K_TX_QUEUE_ID_DATA_MAX)
-               ieee80211_stop_queue(hw, txq->qnum);
-       spin_lock_irqsave(&sc->txbuflock, flags);
-@@ -1931,6 +1932,10 @@ ath5k_beacon_send(struct ath5k_softc *sc
-       skb = ieee80211_get_buffered_bc(sc->hw, vif);
-       while (skb) {
-               ath5k_tx_queue(sc->hw, skb, sc->cabq);
-+
-+              if (sc->cabq->txq_len >= sc->cabq->txq_max)
-+                      break;
-+
-               skb = ieee80211_get_buffered_bc(sc->hw, vif);
-       }
index df11fe4..dde30f9 100644 (file)
@@ -1,7 +1,7 @@
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1181,6 +1181,53 @@ static const struct file_operations fops
-       .llseek = default_llseek,/* read accesses f_pos */
+@@ -1219,6 +1219,53 @@ static const struct file_operations fops
+       .llseek = default_llseek,
  };
  
 +static ssize_t read_file_eeprom(struct file *file, char __user *user_buf,
@@ -54,7 +54,7 @@
  int ath9k_init_debug(struct ath_hw *ah)
  {
        struct ath_common *common = ath9k_hw_common(ah);
-@@ -1231,6 +1278,9 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1273,6 +1320,9 @@ int ath9k_init_debug(struct ath_hw *ah)
        debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
                           sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
  
index d93686c..834e1a2 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/hw.c
 +++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1656,8 +1656,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+@@ -1664,8 +1664,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
        REG_WRITE(ah, AR_OBS, 8);
  
        if (ah->config.rx_intr_mitigation) {
index 0b829ec..2931a5e 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -363,7 +363,7 @@ struct ath_vif {
+@@ -366,7 +366,7 @@ struct ath_vif {
   * number of beacon intervals, the game's up.
   */
  #define BSTUCK_THRESH                 9
@@ -11,7 +11,7 @@
  #define IEEE80211_MS_TO_TU(x)           (((x) * 1000) / 1024)
 --- a/drivers/net/wireless/ath/ath9k/hw.c
 +++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -374,8 +374,8 @@ static void ath9k_hw_init_config(struct 
+@@ -382,8 +382,8 @@ static void ath9k_hw_init_config(struct 
  {
        int i;
  
index 2384931..7451e61 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -117,7 +117,7 @@ void ath_descdma_cleanup(struct ath_soft
+@@ -123,7 +123,7 @@ void ath_descdma_cleanup(struct ath_soft
  /* RX / TX */
  /***********/
  
index 28251ee..4aeddda 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -586,6 +586,7 @@ struct ath_softc {
+@@ -588,6 +588,7 @@ struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
  
@@ -10,7 +10,7 @@
        struct survey_info *cur_survey;
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1281,6 +1281,9 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1323,6 +1323,9 @@ int ath9k_init_debug(struct ath_hw *ah)
        debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_eeprom);
  
diff --git a/package/mac80211/patches/530-ath9k_noise_dbm_fixup.patch b/package/mac80211/patches/530-ath9k_noise_dbm_fixup.patch
deleted file mode 100644 (file)
index 4e9f387..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/calib.c
-+++ b/drivers/net/wireless/ath/ath9k/calib.c
-@@ -63,6 +63,19 @@ static s16 ath9k_hw_get_default_nf(struc
-       return ath9k_hw_get_nf_limits(ah, chan)->nominal;
- }
-+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
-+{
-+      s8 noise = ATH_DEFAULT_NOISE_FLOOR;
-+
-+      if (chan && chan->noisefloor) {
-+              s8 delta = chan->noisefloor -
-+                         ath9k_hw_get_default_nf(ah, chan);
-+              if (delta > 0)
-+                      noise += delta;
-+      }
-+      return noise;
-+}
-+EXPORT_SYMBOL(ath9k_hw_getchan_noise);
- static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
-                                             struct ath9k_hw_cal_data *cal,
-@@ -378,6 +391,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, s
-       if (!caldata) {
-               chan->noisefloor = nf;
-+              ah->noise = ath9k_hw_getchan_noise(ah, chan);
-               return false;
-       }
-@@ -385,6 +399,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, s
-       caldata->nfcal_pending = false;
-       ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
-       chan->noisefloor = h[0].privNF;
-+      ah->noise = ath9k_hw_getchan_noise(ah, chan);
-       return true;
- }
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1488,6 +1488,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-               memset(caldata, 0, sizeof(*caldata));
-               ath9k_init_nfcal_hist_buffer(ah, chan);
-       }
-+      ah->noise = ath9k_hw_getchan_noise(ah, chan);
-       if (bChannelChange &&
-           (ah->chip_fullsleep != true) &&
---- a/drivers/net/wireless/ath/ath9k/hw.h
-+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -688,6 +688,7 @@ struct ath_hw {
-       enum nl80211_iftype opmode;
-       enum ath9k_power_mode power_mode;
-+      s8 noise;
-       struct ath9k_hw_cal_data *caldata;
-       struct ath9k_pacal_info pacal_info;
-       struct ar5416Stats stats;
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -163,7 +163,7 @@ static void ath_update_survey_nf(struct 
-       if (chan->noisefloor) {
-               survey->filled |= SURVEY_INFO_NOISE_DBM;
--              survey->noise = chan->noisefloor;
-+              survey->noise = ath9k_hw_getchan_noise(ah, chan);
-       }
- }
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -994,6 +994,8 @@ static int ath9k_rx_skb_preprocess(struc
-                                  struct ieee80211_rx_status *rx_status,
-                                  bool *decrypt_error)
- {
-+      struct ath_hw *ah = common->ah;
-+
-       memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
-       /*
-@@ -1014,7 +1016,7 @@ static int ath9k_rx_skb_preprocess(struc
-       rx_status->band = hw->conf.channel->band;
-       rx_status->freq = hw->conf.channel->center_freq;
--      rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
-+      rx_status->signal = ah->noise + rx_stats->rs_rssi;
-       rx_status->antenna = rx_stats->rs_antenna;
-       rx_status->flag |= RX_FLAG_MACTIME_MPDU;
---- a/drivers/net/wireless/ath/ath9k/calib.h
-+++ b/drivers/net/wireless/ath/ath9k/calib.h
-@@ -108,6 +108,7 @@ void ath9k_init_nfcal_hist_buffer(struct
- void ath9k_hw_bstuck_nfcal(struct ath_hw *ah);
- void ath9k_hw_reset_calibration(struct ath_hw *ah,
-                               struct ath9k_cal_list *currCal);
-+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
- #endif /* CALIB_H */
diff --git a/package/mac80211/patches/530-mac80211_cur_txpower.patch b/package/mac80211/patches/530-mac80211_cur_txpower.patch
new file mode 100644 (file)
index 0000000..5e99c03
--- /dev/null
@@ -0,0 +1,32 @@
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -790,7 +790,7 @@ enum ieee80211_smps_mode {
+  */
+ struct ieee80211_conf {
+       u32 flags;
+-      int power_level, dynamic_ps_timeout;
++      int cur_power_level, power_level, dynamic_ps_timeout;
+       int max_sleep_period;
+       u16 listen_interval;
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1532,7 +1532,7 @@ static int ieee80211_get_tx_power(struct
+ {
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+-      *dbm = local->hw.conf.power_level;
++      *dbm = local->hw.conf.cur_power_level;
+       return 0;
+ }
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -210,6 +210,7 @@ int ieee80211_hw_config(struct ieee80211
+       if (local->hw.conf.power_level != power) {
+               changed |= IEEE80211_CONF_CHANGE_POWER;
++              local->hw.conf.cur_power_level = power;
+               local->hw.conf.power_level = power;
+       }
diff --git a/package/mac80211/patches/531-ath9k_cur_txpower.patch b/package/mac80211/patches/531-ath9k_cur_txpower.patch
new file mode 100644 (file)
index 0000000..3c0a466
--- /dev/null
@@ -0,0 +1,35 @@
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -1731,6 +1731,8 @@ static int ath9k_config(struct ieee80211
+                       return -EINVAL;
+               }
++              conf->cur_power_level = sc->curtxpow / 2;
++
+               /*
+                * The most recent snapshot of channel->noisefloor for the old
+                * channel is only available after the hardware reset. Copy it to
+@@ -1748,6 +1750,7 @@ static int ath9k_config(struct ieee80211
+               ath9k_cmn_update_txpow(ah, sc->curtxpow,
+                                      sc->config.txpowlimit, &sc->curtxpow);
+               ath9k_ps_restore(sc);
++              conf->cur_power_level = sc->curtxpow / 2;
+       }
+       if (disable_radio) {
+--- a/drivers/net/wireless/ath/ath9k/common.c
++++ b/drivers/net/wireless/ath/ath9k/common.c
+@@ -161,10 +161,12 @@ EXPORT_SYMBOL(ath9k_cmn_count_streams);
+ void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
+                           u16 new_txpow, u16 *txpower)
+ {
++      struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
++
+       if (cur_txpow != new_txpow) {
+               ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
+               /* read back in case value is clamped */
+-              *txpower = ath9k_hw_regulatory(ah)->power_limit;
++              *txpower = min_t(u16, reg->power_limit, reg->max_power_level);
+       }
+ }
+ EXPORT_SYMBOL(ath9k_cmn_update_txpow);
diff --git a/package/mac80211/patches/540-ath9k_rx_stop.patch b/package/mac80211/patches/540-ath9k_rx_stop.patch
deleted file mode 100644 (file)
index 17c4c28..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/mac.c
-+++ b/drivers/net/wireless/ath/ath9k/mac.c
-@@ -737,7 +737,9 @@ bool ath9k_hw_stopdmarecv(struct ath_hw 
-               if (!AR_SREV_9300_20_OR_LATER(ah)) {
-                       mac_status = REG_READ(ah, AR_DMADBG_7) & 0x7f0;
--                      if (mac_status == 0x1c0 && mac_status == last_mac_status) {
-+                      if (mac_status == last_mac_status &&
-+                          (mac_status == 0x1c0 ||
-+                           (AR_SREV_9100(ah) && mac_status == 0x020))) {
-                               *reset = true;
-                               break;
-                       }
diff --git a/package/mac80211/patches/540-ath9k_sw_retry_reduce.patch b/package/mac80211/patches/540-ath9k_sw_retry_reduce.patch
new file mode 100644 (file)
index 0000000..d34b851
--- /dev/null
@@ -0,0 +1,61 @@
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -248,13 +248,16 @@ static void ath_tid_drain(struct ath_sof
+ }
+ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
+-                           struct sk_buff *skb)
++                           struct sk_buff *skb, int count)
+ {
+       struct ath_frame_info *fi = get_frame_info(skb);
+       struct ieee80211_hdr *hdr;
++      int prev = fi->retries;
+       TX_STAT_INC(txq->axq_qnum, a_retries);
+-      if (fi->retries++ > 0)
++      fi->retries += count;
++
++      if (prev > 0)
+               return;
+       hdr = (struct ieee80211_hdr *)skb->data;
+@@ -359,6 +362,7 @@ static void ath_tx_complete_aggr(struct 
+       int nframes;
+       u8 tidno;
+       bool clear_filter;
++      int i, retries;
+       skb = bf->bf_mpdu;
+       hdr = (struct ieee80211_hdr *)skb->data;
+@@ -367,6 +371,10 @@ static void ath_tx_complete_aggr(struct 
+       memcpy(rates, tx_info->control.rates, sizeof(rates));
++      retries = ts->ts_longretry + 1;
++      for (i = 0; i < ts->ts_rateindex; i++)
++              retries += rates[i].count;
++
+       rcu_read_lock();
+       sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
+@@ -451,7 +459,8 @@ static void ath_tx_complete_aggr(struct 
+                       } else if (fi->retries < ATH_MAX_SW_RETRIES) {
+                               if (!(ts->ts_status & ATH9K_TXERR_FILT) ||
+                                   !an->sleeping)
+-                                      ath_tx_set_retry(sc, txq, bf->bf_mpdu);
++                                      ath_tx_set_retry(sc, txq, bf->bf_mpdu,
++                                                       retries);
+                               clear_filter = true;
+                               txpending = 1;
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -538,7 +538,7 @@ struct ath_ant_comb {
+ #define DEFAULT_CACHELINE       32
+ #define ATH_REGCLASSIDS_MAX     10
+ #define ATH_CABQ_READY_TIME     80      /* % of beacon interval */
+-#define ATH_MAX_SW_RETRIES      10
++#define ATH_MAX_SW_RETRIES      20
+ #define ATH_CHAN_MAX            255
+ #define ATH_TXPOWER_MAX         100     /* .5 dBm units */
diff --git a/package/mac80211/patches/541-ath9k_aggr_queue_cleanup.patch b/package/mac80211/patches/541-ath9k_aggr_queue_cleanup.patch
new file mode 100644 (file)
index 0000000..1ea3c14
--- /dev/null
@@ -0,0 +1,281 @@
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -206,6 +206,7 @@ struct ath_atx_ac {
+ };
+ struct ath_frame_info {
++      struct ath_buf *bf;
+       int framelen;
+       u32 keyix;
+       enum ath9k_key_type keytype;
+@@ -235,7 +236,7 @@ struct ath_buf {
+ struct ath_atx_tid {
+       struct list_head list;
+-      struct list_head buf_q;
++      struct sk_buff_head buf_q;
+       struct ath_node *an;
+       struct ath_atx_ac *ac;
+       unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -711,7 +711,7 @@ static ssize_t read_file_stations(struct
+                                       " tid: %p %s %s %i %p %p\n",
+                                       tid, tid->sched ? "sched" : "idle",
+                                       tid->paused ? "paused" : "running",
+-                                      list_empty(&tid->buf_q),
++                                      skb_queue_empty(&tid->buf_q),
+                                       tid->an, tid->ac);
+                       if (len >= size)
+                               goto done;
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -129,7 +129,7 @@ static void ath_tx_resume_tid(struct ath
+       spin_lock_bh(&txq->axq_lock);
+       tid->paused = false;
+-      if (list_empty(&tid->buf_q))
++      if (skb_queue_empty(&tid->buf_q))
+               goto unlock;
+       ath_tx_queue_tid(txq, tid);
+@@ -149,6 +149,7 @@ static struct ath_frame_info *get_frame_
+ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+ {
+       struct ath_txq *txq = tid->ac->txq;
++      struct sk_buff *skb;
+       struct ath_buf *bf;
+       struct list_head bf_head;
+       struct ath_tx_status ts;
+@@ -159,12 +160,13 @@ static void ath_tx_flush_tid(struct ath_
+       memset(&ts, 0, sizeof(ts));
+       spin_lock_bh(&txq->axq_lock);
+-      while (!list_empty(&tid->buf_q)) {
+-              bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+-              list_move_tail(&bf->list, &bf_head);
++      while ((skb = __skb_dequeue(&tid->buf_q))) {
++              fi = get_frame_info(skb);
++              bf = fi->bf;
++
++              list_add_tail(&bf->list, &bf_head);
+               spin_unlock_bh(&txq->axq_lock);
+-              fi = get_frame_info(bf->bf_mpdu);
+               if (fi->retries) {
+                       ath_tx_update_baw(sc, tid, fi->seqno);
+                       ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1);
+@@ -219,6 +221,7 @@ static void ath_tid_drain(struct ath_sof
+                         struct ath_atx_tid *tid)
+ {
++      struct sk_buff *skb;
+       struct ath_buf *bf;
+       struct list_head bf_head;
+       struct ath_tx_status ts;
+@@ -227,14 +230,12 @@ static void ath_tid_drain(struct ath_sof
+       memset(&ts, 0, sizeof(ts));
+       INIT_LIST_HEAD(&bf_head);
+-      for (;;) {
+-              if (list_empty(&tid->buf_q))
+-                      break;
++      while ((skb = __skb_dequeue(&tid->buf_q))) {
++              fi = get_frame_info(skb);
++              bf = fi->bf;
+-              bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+-              list_move_tail(&bf->list, &bf_head);
++              list_add_tail(&bf->list, &bf_head);
+-              fi = get_frame_info(bf->bf_mpdu);
+               if (fi->retries)
+                       ath_tx_update_baw(sc, tid, fi->seqno);
+@@ -352,7 +353,8 @@ static void ath_tx_complete_aggr(struct 
+       struct ieee80211_tx_info *tx_info;
+       struct ath_atx_tid *tid = NULL;
+       struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
+-      struct list_head bf_head, bf_pending;
++      struct list_head bf_head;
++      struct sk_buff_head bf_pending;
+       u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
+       u32 ba[WME_BA_BMP_SIZE >> 5];
+       int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
+@@ -430,8 +432,7 @@ static void ath_tx_complete_aggr(struct 
+               }
+       }
+-      INIT_LIST_HEAD(&bf_pending);
+-      INIT_LIST_HEAD(&bf_head);
++      __skb_queue_head_init(&bf_pending);
+       ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
+       while (bf) {
+@@ -476,10 +477,10 @@ static void ath_tx_complete_aggr(struct 
+                * Make sure the last desc is reclaimed if it
+                * not a holding desc.
+                */
+-              if (!bf_last->bf_stale || bf_next != NULL)
++              INIT_LIST_HEAD(&bf_head);
++              if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) ||
++                  bf_next != NULL || !bf_last->bf_stale)
+                       list_move_tail(&bf->list, &bf_head);
+-              else
+-                      INIT_LIST_HEAD(&bf_head);
+               if (!txpending || (tid->state & AGGR_CLEANUP)) {
+                       /*
+@@ -530,7 +531,7 @@ static void ath_tx_complete_aggr(struct 
+                                       ath9k_hw_cleartxdesc(sc->sc_ah,
+                                                            tbf->bf_desc);
+-                                      list_add_tail(&tbf->list, &bf_head);
++                                      fi->bf = tbf;
+                               } else {
+                                       /*
+                                        * Clear descriptor status words for
+@@ -545,21 +546,21 @@ static void ath_tx_complete_aggr(struct 
+                        * Put this buffer to the temporary pending
+                        * queue to retain ordering
+                        */
+-                      list_splice_tail_init(&bf_head, &bf_pending);
++                      __skb_queue_tail(&bf_pending, skb);
+               }
+               bf = bf_next;
+       }
+       /* prepend un-acked frames to the beginning of the pending frame queue */
+-      if (!list_empty(&bf_pending)) {
++      if (!skb_queue_empty(&bf_pending)) {
+               if (an->sleeping)
+                       ieee80211_sta_set_tim(sta);
+               spin_lock_bh(&txq->axq_lock);
+               if (clear_filter)
+                       tid->ac->clear_ps_filter = true;
+-              list_splice(&bf_pending, &tid->buf_q);
++              skb_queue_splice(&bf_pending, &tid->buf_q);
+               if (!an->sleeping)
+                       ath_tx_queue_tid(txq, tid);
+               spin_unlock_bh(&txq->axq_lock);
+@@ -721,19 +722,22 @@ static enum ATH_AGGR_STATUS ath_tx_form_
+                                            int *aggr_len)
+ {
+ #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
+-      struct ath_buf *bf, *bf_first, *bf_prev = NULL;
++      struct ath_buf *bf, *bf_first = NULL, *bf_prev = NULL;
+       int rl = 0, nframes = 0, ndelim, prev_al = 0;
+       u16 aggr_limit = 0, al = 0, bpad = 0,
+               al_delta, h_baw = tid->baw_size / 2;
+       enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
+       struct ieee80211_tx_info *tx_info;
+       struct ath_frame_info *fi;
+-
+-      bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
++      struct sk_buff *skb;
+       do {
+-              bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+-              fi = get_frame_info(bf->bf_mpdu);
++              skb = skb_peek(&tid->buf_q);
++              fi = get_frame_info(skb);
++              bf = fi->bf;
++
++              if (!bf_first)
++                      bf_first = bf;
+               /* do not step over block-ack window */
+               if (!BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno)) {
+@@ -784,7 +788,9 @@ static enum ATH_AGGR_STATUS ath_tx_form_
+               if (!fi->retries)
+                       ath_tx_addto_baw(sc, tid, fi->seqno);
+               ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
+-              list_move_tail(&bf->list, bf_q);
++
++              __skb_unlink(skb, &tid->buf_q);
++              list_add_tail(&bf->list, bf_q);
+               if (bf_prev) {
+                       bf_prev->bf_next = bf;
+                       ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc,
+@@ -792,7 +798,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
+               }
+               bf_prev = bf;
+-      } while (!list_empty(&tid->buf_q));
++      } while (!skb_queue_empty(&tid->buf_q));
+       *aggr_len = al;
+@@ -810,7 +816,7 @@ static void ath_tx_sched_aggr(struct ath
+       int aggr_len;
+       do {
+-              if (list_empty(&tid->buf_q))
++              if (skb_queue_empty(&tid->buf_q))
+                       return;
+               INIT_LIST_HEAD(&bf_q);
+@@ -931,7 +937,7 @@ bool ath_tx_aggr_sleep(struct ath_softc 
+               spin_lock_bh(&txq->axq_lock);
+-              if (!list_empty(&tid->buf_q))
++              if (!skb_queue_empty(&tid->buf_q))
+                       buffered = true;
+               tid->sched = false;
+@@ -964,7 +970,7 @@ void ath_tx_aggr_wakeup(struct ath_softc
+               spin_lock_bh(&txq->axq_lock);
+               ac->clear_ps_filter = true;
+-              if (!list_empty(&tid->buf_q) && !tid->paused) {
++              if (!skb_queue_empty(&tid->buf_q) && !tid->paused) {
+                       ath_tx_queue_tid(txq, tid);
+                       ath_txq_schedule(sc, txq);
+               }
+@@ -1308,7 +1314,7 @@ void ath_txq_schedule(struct ath_softc *
+                        * add tid to round-robin queue if more frames
+                        * are pending for the tid
+                        */
+-                      if (!list_empty(&tid->buf_q))
++                      if (!skb_queue_empty(&tid->buf_q))
+                               ath_tx_queue_tid(txq, tid);
+                       if (tid == last_tid ||
+@@ -1414,7 +1420,7 @@ static void ath_tx_send_ampdu(struct ath
+        * - seqno is not within block-ack window
+        * - h/w queue depth exceeds low water mark
+        */
+-      if (!list_empty(&tid->buf_q) || tid->paused ||
++      if (!skb_queue_empty(&tid->buf_q) || tid->paused ||
+           !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) ||
+           txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) {
+               /*
+@@ -1422,7 +1428,7 @@ static void ath_tx_send_ampdu(struct ath
+                * for aggregation.
+                */
+               TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
+-              list_add_tail(&bf->list, &tid->buf_q);
++              __skb_queue_tail(&tid->buf_q, bf->bf_mpdu);
+               if (!txctl->an || !txctl->an->sleeping)
+                       ath_tx_queue_tid(txctl->txq, tid);
+               return;
+@@ -1753,6 +1759,7 @@ static struct ath_buf *ath_tx_setup_buff
+                           bf->bf_buf_addr,
+                           txq->axq_qnum);
++      fi->bf = bf;
+       return bf;
+ }
+@@ -2370,7 +2377,7 @@ void ath_tx_node_init(struct ath_softc *
+               tid->sched     = false;
+               tid->paused    = false;
+               tid->state &= ~AGGR_CLEANUP;
+-              INIT_LIST_HEAD(&tid->buf_q);
++              __skb_queue_head_init(&tid->buf_q);
+               acno = TID_TO_WME_AC(tidno);
+               tid->ac = &an->ac[acno];
+               tid->state &= ~AGGR_ADDBA_COMPLETE;
diff --git a/package/mac80211/patches/542-ath9k_limit_qlen.patch b/package/mac80211/patches/542-ath9k_limit_qlen.patch
new file mode 100644 (file)
index 0000000..e774186
--- /dev/null
@@ -0,0 +1,176 @@
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -240,6 +240,7 @@ struct ath_atx_tid {
+       struct ath_node *an;
+       struct ath_atx_ac *ac;
+       unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
++      int buf_pending;
+       u16 seq_start;
+       u16 seq_next;
+       u16 baw_size;
+@@ -286,6 +287,9 @@ struct ath_tx_control {
+  *  (axq_qnum).
+  */
+ struct ath_tx {
++      u32 qlen_single;
++      u32 qlen_aggr;
++
+       u16 seq_no;
+       u32 txqsetup;
+       spinlock_t txbuflock;
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -1288,6 +1288,10 @@ int ath9k_init_debug(struct ath_hw *ah)
+                           sc, &fops_wiphy);
+       debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
+                           &fops_xmit);
++      debugfs_create_u32("qlen_single", S_IRUSR | S_IWUSR,
++                         sc->debug.debugfs_phy, &sc->tx.qlen_single);
++      debugfs_create_u32("qlen_aggr", S_IRUSR | S_IWUSR,
++                         sc->debug.debugfs_phy, &sc->tx.qlen_aggr);
+       debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
+                           &fops_stations);
+       debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -340,6 +340,14 @@ static void ath_tx_count_frames(struct a
+       }
+ }
++static struct ath_atx_tid *ath_get_tid(struct ath_node *an, struct sk_buff *skb)
++{
++      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
++      u8 tidno;
++
++      tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
++      return ATH_AN_2_TID(an, tidno);
++}
+ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
+                                struct ath_buf *bf, struct list_head *bf_q,
+@@ -435,6 +443,8 @@ static void ath_tx_complete_aggr(struct 
+       __skb_queue_head_init(&bf_pending);
+       ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
++      tid->buf_pending -= nframes;
++
+       while (bf) {
+               txfail = txpending = sendbar = 0;
+               bf_next = bf->bf_next;
+@@ -789,6 +799,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
+                       ath_tx_addto_baw(sc, tid, fi->seqno);
+               ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
++              tid->buf_pending++;
+               __skb_unlink(skb, &tid->buf_q);
+               list_add_tail(&bf->list, bf_q);
+               if (bf_prev) {
+@@ -1441,6 +1452,8 @@ static void ath_tx_send_ampdu(struct ath
+       if (!fi->retries)
+               ath_tx_addto_baw(sc, tid, fi->seqno);
++      tid->buf_pending++;
++
+       /* Queue to h/w without aggregation */
+       TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
+       bf->bf_lastbf = bf;
+@@ -1505,7 +1518,6 @@ static void setup_frame_info(struct ieee
+       struct ath_atx_tid *tid;
+       enum ath9k_key_type keytype;
+       u16 seqno = 0;
+-      u8 tidno;
+       keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
+@@ -1516,13 +1528,11 @@ static void setup_frame_info(struct ieee
+       if (an && ieee80211_is_data_qos(hdr->frame_control) &&
+               conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) {
+-              tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
+-
+               /*
+                * Override seqno set by upper layer with the one
+                * in tx aggregation state.
+                */
+-              tid = ATH_AN_2_TID(an, tidno);
++              tid = ath_get_tid(an, skb);
+               seqno = tid->seq_next;
+               hdr->seq_ctrl = cpu_to_le16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
+               INCR(tid->seq_next, IEEE80211_SEQ_MAX);
+@@ -1766,24 +1776,14 @@ static struct ath_buf *ath_tx_setup_buff
+ /* FIXME: tx power */
+ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
+-                           struct ath_tx_control *txctl)
++                           struct ath_tx_control *txctl,
++                           struct ath_atx_tid *tid)
+ {
+       struct sk_buff *skb = bf->bf_mpdu;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+-      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct list_head bf_head;
+-      struct ath_atx_tid *tid = NULL;
+-      u8 tidno;
+       spin_lock_bh(&txctl->txq->axq_lock);
+-      if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an &&
+-              ieee80211_is_data_qos(hdr->frame_control)) {
+-              tidno = ieee80211_get_qos_ctl(hdr)[0] &
+-                      IEEE80211_QOS_CTL_TID_MASK;
+-              tid = ATH_AN_2_TID(txctl->an, tidno);
+-
+-              WARN_ON(tid->ac->txq != txctl->txq);
+-      }
+       if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
+               /*
+@@ -1823,6 +1823,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+       struct ieee80211_vif *vif = info->control.vif;
+       struct ath_softc *sc = hw->priv;
+       struct ath_txq *txq = txctl->txq;
++      struct ath_atx_tid *tid = NULL;
+       struct ath_buf *bf;
+       int padpos, padsize;
+       int frmlen = skb->len + FCS_LEN;
+@@ -1856,6 +1857,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+               skb_push(skb, padsize);
+               memmove(skb->data, skb->data + padsize, padpos);
++              hdr = (struct ieee80211_hdr *) skb->data;
+       }
+       if ((vif && vif->type != NL80211_IFTYPE_AP &&
+@@ -1865,6 +1867,24 @@ int ath_tx_start(struct ieee80211_hw *hw
+       setup_frame_info(hw, skb, frmlen);
++      if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an &&
++          ieee80211_is_data_qos(hdr->frame_control)) {
++              tid = ath_get_tid(txctl->an, skb);
++
++              WARN_ON(tid->ac->txq != txq);
++      }
++
++      if ((info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
++              if (sc->tx.qlen_aggr > 0 && skb_queue_len(&tid->buf_q) +
++                  tid->buf_pending >= sc->tx.qlen_aggr)
++                      return -ENOMEM;
++      } else {
++              if (sc->tx.qlen_single > 0 &&
++                  txq->axq_depth - txq->axq_ampdu_depth >=
++                    sc->tx.qlen_single)
++                      return -ENOMEM;
++      }
++
+       /*
+        * At this point, the vif, hw_key and sta pointers in the tx control
+        * info are no longer valid (overwritten by the ath_frame_info data.
+@@ -1883,7 +1903,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+       }
+       spin_unlock_bh(&txq->axq_lock);
+-      ath_tx_start_dma(sc, bf, txctl);
++      ath_tx_start_dma(sc, bf, txctl, tid);
+       return 0;
+ }
diff --git a/package/mac80211/patches/550-mac80211_cur_txpower.patch b/package/mac80211/patches/550-mac80211_cur_txpower.patch
deleted file mode 100644 (file)
index 8e729c1..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -779,7 +779,7 @@ enum ieee80211_smps_mode {
-  */
- struct ieee80211_conf {
-       u32 flags;
--      int power_level, dynamic_ps_timeout;
-+      int cur_power_level, power_level, dynamic_ps_timeout;
-       int max_sleep_period;
-       u16 listen_interval;
---- a/net/mac80211/cfg.c
-+++ b/net/mac80211/cfg.c
-@@ -1524,7 +1524,7 @@ static int ieee80211_get_tx_power(struct
- {
-       struct ieee80211_local *local = wiphy_priv(wiphy);
--      *dbm = local->hw.conf.power_level;
-+      *dbm = local->hw.conf.cur_power_level;
-       return 0;
- }
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -210,6 +210,7 @@ int ieee80211_hw_config(struct ieee80211
-       if (local->hw.conf.power_level != power) {
-               changed |= IEEE80211_CONF_CHANGE_POWER;
-+              local->hw.conf.cur_power_level = power;
-               local->hw.conf.power_level = power;
-       }
diff --git a/package/mac80211/patches/551-ath9k_initialize_chainmask.patch b/package/mac80211/patches/551-ath9k_initialize_chainmask.patch
deleted file mode 100644 (file)
index 03f7c36..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -667,8 +667,10 @@ static void ath9k_init_band_txpower(stru
- static void ath9k_init_txpower_limits(struct ath_softc *sc)
- {
-       struct ath_hw *ah = sc->sc_ah;
-+      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       struct ath9k_channel *curchan = ah->curchan;
-+      ah->txchainmask = common->tx_chainmask;
-       if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
-               ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
-       if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
diff --git a/package/mac80211/patches/552-ath9k_remove_tx_indexoffset.patch b/package/mac80211/patches/552-ath9k_remove_tx_indexoffset.patch
deleted file mode 100644 (file)
index c8e2640..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
-+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
-@@ -247,8 +247,7 @@ static u32 ath9k_hw_4k_get_eeprom(struct
- }
- static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
--                                struct ath9k_channel *chan,
--                                int16_t *pTxPowerIndexOffset)
-+                                struct ath9k_channel *chan)
- {
-       struct ath_common *common = ath9k_hw_common(ah);
-       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
-@@ -358,8 +357,6 @@ static void ath9k_hw_set_4k_power_cal_ta
-                       REGWRITE_BUFFER_FLUSH(ah);
-               }
-       }
--
--      *pTxPowerIndexOffset = 0;
- }
- static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
-@@ -582,7 +579,6 @@ static void ath9k_hw_4k_set_txpower(stru
-       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
-       struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
-       int16_t ratesArray[Ar5416RateSize];
--      int16_t txPowerIndexOffset = 0;
-       u8 ht40PowerIncForPdadc = 2;
-       int i;
-@@ -599,11 +595,10 @@ static void ath9k_hw_4k_set_txpower(stru
-                                            twiceMaxRegulatoryPower,
-                                            powerLimit);
--      ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
-+      ath9k_hw_set_4k_power_cal_table(ah, chan);
-       regulatory->max_power_level = 0;
-       for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
--              ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
-               if (ratesArray[i] > MAX_RATE_POWER)
-                       ratesArray[i] = MAX_RATE_POWER;
---- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
-+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
-@@ -306,8 +306,7 @@ static void ar9287_eeprom_olpc_set_pdadc
- }
- static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
--                                              struct ath9k_channel *chan,
--                                              int16_t *pTxPowerIndexOffset)
-+                                              struct ath9k_channel *chan)
- {
-       struct cal_data_per_freq_ar9287 *pRawDataset;
-       struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
-@@ -446,8 +445,6 @@ static void ath9k_hw_set_ar9287_power_ca
-                       REGWRITE_BUFFER_FLUSH(ah);
-               }
-       }
--
--      *pTxPowerIndexOffset = 0;
- }
- static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
-@@ -722,7 +719,6 @@ static void ath9k_hw_ar9287_set_txpower(
-       struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
-       struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
-       int16_t ratesArray[Ar5416RateSize];
--      int16_t txPowerIndexOffset = 0;
-       u8 ht40PowerIncForPdadc = 2;
-       int i;
-@@ -738,11 +734,10 @@ static void ath9k_hw_ar9287_set_txpower(
-                                                twiceMaxRegulatoryPower,
-                                                powerLimit);
--      ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset);
-+      ath9k_hw_set_ar9287_power_cal_table(ah, chan);
-       regulatory->max_power_level = 0;
-       for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
--              ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
-               if (ratesArray[i] > MAX_RATE_POWER)
-                       ratesArray[i] = MAX_RATE_POWER;
---- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
-+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
-@@ -692,8 +692,7 @@ static void ath9k_adjust_pdadc_values(st
- }
- static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
--                                struct ath9k_channel *chan,
--                                int16_t *pTxPowerIndexOffset)
-+                                struct ath9k_channel *chan)
- {
- #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
- #define SM_PDGAIN_B(x, y) \
-@@ -857,7 +856,6 @@ static void ath9k_hw_set_def_power_cal_t
-               }
-       }
--      *pTxPowerIndexOffset = 0;
- #undef SM_PD_GAIN
- #undef SM_PDGAIN_B
- }
-@@ -1145,7 +1143,6 @@ static void ath9k_hw_def_set_txpower(str
-       struct modal_eep_header *pModal =
-               &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
-       int16_t ratesArray[Ar5416RateSize];
--      int16_t txPowerIndexOffset = 0;
-       u8 ht40PowerIncForPdadc = 2;
-       int i, cck_ofdm_delta = 0;
-@@ -1162,11 +1159,10 @@ static void ath9k_hw_def_set_txpower(str
-                                              twiceMaxRegulatoryPower,
-                                              powerLimit);
--      ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
-+      ath9k_hw_set_def_power_cal_table(ah, chan);
-       regulatory->max_power_level = 0;
-       for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
--              ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
-               if (ratesArray[i] > MAX_RATE_POWER)
-                       ratesArray[i] = MAX_RATE_POWER;
-               if (ratesArray[i] > regulatory->max_power_level)
diff --git a/package/mac80211/patches/553-ath9k_fix_rate_power.patch b/package/mac80211/patches/553-ath9k_fix_rate_power.patch
deleted file mode 100644 (file)
index fc79d5f..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
-@@ -4922,25 +4922,7 @@ static void ath9k_hw_ar9300_set_txpower(
-                       "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
-       }
--      /*
--       * This is the TX power we send back to driver core,
--       * and it can use to pass to userspace to display our
--       * currently configured TX power setting.
--       *
--       * Since power is rate dependent, use one of the indices
--       * from the AR9300_Rates enum to select an entry from
--       * targetPowerValT2[] to report. Currently returns the
--       * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
--       * as CCK power is less interesting (?).
--       */
--      i = ALL_TARGET_LEGACY_6_24; /* legacy */
--      if (IS_CHAN_HT40(chan))
--              i = ALL_TARGET_HT40_0_8_16; /* ht40 */
--      else if (IS_CHAN_HT20(chan))
--              i = ALL_TARGET_HT20_0_8_16; /* ht20 */
--
--      ah->txpower_limit = targetPowerValT2[i];
--      regulatory->max_power_level = targetPowerValT2[i];
-+      ah->txpower_limit = regulatory->max_power_level;
-       /* Write target power array to registers */
-       ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
---- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
-+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
-@@ -609,15 +609,6 @@ static void ath9k_hw_4k_set_txpower(stru
-       if (test)
-           return;
--      /* Update regulatory */
--      i = rate6mb;
--      if (IS_CHAN_HT40(chan))
--              i = rateHt40_0;
--      else if (IS_CHAN_HT20(chan))
--              i = rateHt20_0;
--
--      regulatory->max_power_level = ratesArray[i];
--
-       if (AR_SREV_9280_20_OR_LATER(ah)) {
-               for (i = 0; i < Ar5416RateSize; i++)
-                       ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
---- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
-+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
-@@ -748,13 +748,6 @@ static void ath9k_hw_ar9287_set_txpower(
-       if (test)
-               return;
--      if (IS_CHAN_2GHZ(chan))
--              i = rate1l;
--      else
--              i = rate6mb;
--
--      regulatory->max_power_level = ratesArray[i];
--
-       if (AR_SREV_9280_20_OR_LATER(ah)) {
-               for (i = 0; i < Ar5416RateSize; i++)
-                       ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
---- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
-+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
-@@ -1169,17 +1169,6 @@ static void ath9k_hw_def_set_txpower(str
-                       regulatory->max_power_level = ratesArray[i];
-       }
--      if (!test) {
--              i = rate6mb;
--
--              if (IS_CHAN_HT40(chan))
--                      i = rateHt40_0;
--              else if (IS_CHAN_HT20(chan))
--                      i = rateHt20_0;
--
--              regulatory->max_power_level = ratesArray[i];
--      }
--
-       switch(ar5416_get_ntxchains(ah->txchainmask)) {
-       case 1:
-               break;
diff --git a/package/mac80211/patches/554-ath9k_test_txpower.patch b/package/mac80211/patches/554-ath9k_test_txpower.patch
deleted file mode 100644 (file)
index 96131dc..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -2442,15 +2442,18 @@ void ath9k_hw_set_txpowerlimit(struct at
-       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
-       struct ath9k_channel *chan = ah->curchan;
-       struct ieee80211_channel *channel = chan->chan;
-+      int reg_pwr = min_t(int, MAX_RATE_POWER, regulatory->power_limit);
-+      int chan_pwr = channel->max_power * 2;
-+
-+      if (test)
-+              reg_pwr = chan_pwr = MAX_RATE_POWER;
-       regulatory->power_limit = min(limit, (u32) MAX_RATE_POWER);
-       ah->eep_ops->set_txpower(ah, chan,
-                                ath9k_regd_get_ctl(regulatory, chan),
-                                channel->max_antenna_gain * 2,
--                               channel->max_power * 2,
--                               min((u32) MAX_RATE_POWER,
--                               (u32) regulatory->power_limit), test);
-+                               chan_pwr, reg_pwr, test);
- }
- EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
diff --git a/package/mac80211/patches/555-ath9k_cur_txpower.patch b/package/mac80211/patches/555-ath9k_cur_txpower.patch
deleted file mode 100644 (file)
index 7bc92f1..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1727,6 +1727,8 @@ static int ath9k_config(struct ieee80211
-                       return -EINVAL;
-               }
-+              conf->cur_power_level = sc->curtxpow / 2;
-+
-               /*
-                * The most recent snapshot of channel->noisefloor for the old
-                * channel is only available after the hardware reset. Copy it to
-@@ -1744,6 +1746,7 @@ static int ath9k_config(struct ieee80211
-               ath9k_cmn_update_txpow(ah, sc->curtxpow,
-                                      sc->config.txpowlimit, &sc->curtxpow);
-               ath9k_ps_restore(sc);
-+              conf->cur_power_level = sc->curtxpow / 2;
-       }
-       if (disable_radio) {
---- a/drivers/net/wireless/ath/ath9k/common.c
-+++ b/drivers/net/wireless/ath/ath9k/common.c
-@@ -161,10 +161,12 @@ EXPORT_SYMBOL(ath9k_cmn_count_streams);
- void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
-                           u16 new_txpow, u16 *txpower)
- {
-+      struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
-+
-       if (cur_txpow != new_txpow) {
-               ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
-               /* read back in case value is clamped */
--              *txpower = ath9k_hw_regulatory(ah)->power_limit;
-+              *txpower = min_t(u16, reg->power_limit, reg->max_power_level);
-       }
- }
- EXPORT_SYMBOL(ath9k_cmn_update_txpow);
diff --git a/package/mac80211/patches/560-ath9k_ps_tx_aggr_fix.patch b/package/mac80211/patches/560-ath9k_ps_tx_aggr_fix.patch
deleted file mode 100644 (file)
index 666b002..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -550,7 +550,8 @@ static void ath_tx_complete_aggr(struct 
-               if (clear_filter)
-                       tid->ac->clear_ps_filter = true;
-               list_splice(&bf_pending, &tid->buf_q);
--              ath_tx_queue_tid(txq, tid);
-+              if (!an->sleeping)
-+                      ath_tx_queue_tid(txq, tid);
-               spin_unlock_bh(&txq->axq_lock);
-       }
-@@ -1410,7 +1411,8 @@ static void ath_tx_send_ampdu(struct ath
-                */
-               TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
-               list_add_tail(&bf->list, &tid->buf_q);
--              ath_tx_queue_tid(txctl->txq, tid);
-+              if (!txctl->an || !txctl->an->sleeping)
-+                      ath_tx_queue_tid(txctl->txq, tid);
-               return;
-       }
diff --git a/package/mac80211/patches/570-mac80211_send_bar.patch b/package/mac80211/patches/570-mac80211_send_bar.patch
deleted file mode 100644 (file)
index 5952da6..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
---- a/net/mac80211/agg-tx.c
-+++ b/net/mac80211/agg-tx.c
-@@ -109,8 +109,9 @@ static void ieee80211_send_addba_request
-       ieee80211_tx_skb(sdata, skb);
- }
--void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
-+void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
- {
-+      struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
-       struct ieee80211_local *local = sdata->local;
-       struct sk_buff *skb;
-       struct ieee80211_bar *bar;
-@@ -138,6 +139,7 @@ void ieee80211_send_bar(struct ieee80211
-       IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
-       ieee80211_tx_skb(sdata, skb);
- }
-+EXPORT_SYMBOL(ieee80211_send_bar);
- void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
-                            struct tid_ampdu_tx *tid_tx)
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -3007,6 +3007,19 @@ void ieee80211_remain_on_channel_expired
- void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
-                                 const u8 *addr);
-+/**
-+ * ieee80211_send_bar - send a BlockAckReq frame
-+ *
-+ * can be used to flush pending frames from the peer's aggregation reorder
-+ * buffer.
-+ *
-+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
-+ * @ra: the peer's destination address
-+ * @tid: the TID of the aggregation session
-+ * @ssn: the new starting sequence number for the receiver
-+ */
-+void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn);
-+
- /* Rate control API */
- /**
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -1225,7 +1225,6 @@ struct ieee80211_tx_status_rtap_hdr {
- void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
-                                      struct ieee80211_ht_cap *ht_cap_ie,
-                                      struct ieee80211_sta_ht_cap *ht_cap);
--void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
- void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
-                         const u8 *da, u16 tid,
-                         u16 initiator, u16 reason_code);
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -239,7 +239,7 @@ void ieee80211_tx_status(struct ieee8021
-                       tid = qc[0] & 0xf;
-                       ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10)
-                                               & IEEE80211_SCTL_SEQ);
--                      ieee80211_send_bar(sta->sdata, hdr->addr1,
-+                      ieee80211_send_bar(&sta->sdata->vif, hdr->addr1,
-                                          tid, ssn);
-               }
diff --git a/package/mac80211/patches/571-ath9k_send_bar_fix.patch b/package/mac80211/patches/571-ath9k_send_bar_fix.patch
deleted file mode 100644 (file)
index aa162b6..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -246,6 +246,7 @@ struct ath_atx_tid {
- };
- struct ath_node {
-+      struct ieee80211_vif *vif;
- #ifdef CONFIG_ATH9K_DEBUGFS
-       struct list_head list; /* for sc->nodes */
-       struct ieee80211_sta *sta; /* station struct we're part of */
-@@ -274,7 +275,6 @@ struct ath_tx_control {
- #define ATH_TX_ERROR        0x01
- #define ATH_TX_XRETRY       0x02
--#define ATH_TX_BAR          0x04
- /**
-  * @txq_map:  Index is mac80211 queue number.  This is
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1801,6 +1801,7 @@ static int ath9k_sta_add(struct ieee8021
-       struct ieee80211_key_conf ps_key = { };
-       ath_node_attach(sc, sta);
-+      an->vif = vif;
-       if (vif->type != NL80211_IFTYPE_AP &&
-           vif->type != NL80211_IFTYPE_AP_VLAN)
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -51,7 +51,7 @@ static void ath_tx_send_normal(struct at
-                              struct list_head *bf_head);
- static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
-                               struct ath_txq *txq, struct list_head *bf_q,
--                              struct ath_tx_status *ts, int txok, int sendbar);
-+                              struct ath_tx_status *ts, int txok);
- static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
-                            struct list_head *head, bool internal);
- static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len);
-@@ -166,7 +166,7 @@ static void ath_tx_flush_tid(struct ath_
-               fi = get_frame_info(bf->bf_mpdu);
-               if (fi->retries) {
-                       ath_tx_update_baw(sc, tid, fi->seqno);
--                      ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1);
-+                      ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
-               } else {
-                       ath_tx_send_normal(sc, txq, NULL, &bf_head);
-               }
-@@ -238,7 +238,7 @@ static void ath_tid_drain(struct ath_sof
-                       ath_tx_update_baw(sc, tid, fi->seqno);
-               spin_unlock(&txq->axq_lock);
--              ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
-+              ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
-               spin_lock(&txq->axq_lock);
-       }
-@@ -381,8 +381,7 @@ static void ath_tx_complete_aggr(struct 
-                               list_move_tail(&bf->list, &bf_head);
-                       ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false);
--                      ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
--                              0, 0);
-+                      ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0);
-                       bf = bf_next;
-               }
-@@ -426,7 +425,7 @@ static void ath_tx_complete_aggr(struct 
-       ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
-       while (bf) {
--              txfail = txpending = sendbar = 0;
-+              txfail = txpending = 0;
-               bf_next = bf->bf_next;
-               skb = bf->bf_mpdu;
-@@ -489,7 +488,7 @@ static void ath_tx_complete_aggr(struct 
-                       }
-                       ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
--                              !txfail, sendbar);
-+                              !txfail);
-               } else {
-                       /* retry the un-acked ones */
-                       ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false);
-@@ -514,7 +513,7 @@ static void ath_tx_complete_aggr(struct 
-                                                               nbad, 0, false);
-                                               ath_tx_complete_buf(sc, bf, txq,
-                                                                   &bf_head,
--                                                                  ts, 0, 0);
-+                                                                  ts, 0);
-                                               break;
-                                       }
-@@ -564,6 +563,9 @@ static void ath_tx_complete_aggr(struct 
-               }
-       }
-+      if (sendbar || (tid->state & AGGR_CLEANUP))
-+              ieee80211_send_bar(an->vif, sta->addr, tidno, tid->seq_start << 4);
-+
-       rcu_read_unlock();
-       if (needreset)
-@@ -900,6 +902,7 @@ void ath_tx_aggr_stop(struct ath_softc *
-       spin_unlock_bh(&txq->axq_lock);
-       ath_tx_flush_tid(sc, txtid);
-+      ieee80211_send_bar(an->vif, sta->addr, tid, txtid->seq_start << 4);
- }
- bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an)
-@@ -1178,7 +1181,7 @@ static void ath_drain_txq_list(struct at
-                       ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0,
-                                            retry_tx);
-               else
--                      ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
-+                      ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
-               spin_lock_bh(&txq->axq_lock);
-       }
- }
-@@ -1885,9 +1888,6 @@ static void ath_tx_complete(struct ath_s
-       ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
--      if (tx_flags & ATH_TX_BAR)
--              tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
--
-       if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
-               /* Frame was ACKed */
-               tx_info->flags |= IEEE80211_TX_STAT_ACK;
-@@ -1932,15 +1932,12 @@ static void ath_tx_complete(struct ath_s
- static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
-                               struct ath_txq *txq, struct list_head *bf_q,
--                              struct ath_tx_status *ts, int txok, int sendbar)
-+                              struct ath_tx_status *ts, int txok)
- {
-       struct sk_buff *skb = bf->bf_mpdu;
-       unsigned long flags;
-       int tx_flags = 0;
--      if (sendbar)
--              tx_flags = ATH_TX_BAR;
--
-       if (!txok) {
-               tx_flags |= ATH_TX_ERROR;
-@@ -2056,7 +2053,7 @@ static void ath_tx_process_buffer(struct
-               if (ts->ts_status & ATH9K_TXERR_XRETRY)
-                       bf->bf_state.bf_type |= BUF_XRETRY;
-               ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok, true);
--              ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0);
-+              ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok);
-       } else
-               ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true);
diff --git a/package/mac80211/patches/572-ath9k_sw_retry_reduce.patch b/package/mac80211/patches/572-ath9k_sw_retry_reduce.patch
deleted file mode 100644 (file)
index a4c6fbe..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -247,13 +247,16 @@ static void ath_tid_drain(struct ath_sof
- }
- static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
--                           struct sk_buff *skb)
-+                           struct sk_buff *skb, int count)
- {
-       struct ath_frame_info *fi = get_frame_info(skb);
-       struct ieee80211_hdr *hdr;
-+      int prev = fi->retries;
-       TX_STAT_INC(txq->axq_qnum, a_retries);
--      if (fi->retries++ > 0)
-+      fi->retries += count;
-+
-+      if (prev > 0)
-               return;
-       hdr = (struct ieee80211_hdr *)skb->data;
-@@ -358,6 +361,7 @@ static void ath_tx_complete_aggr(struct 
-       int nframes;
-       u8 tidno;
-       bool clear_filter;
-+      int i, retries;
-       skb = bf->bf_mpdu;
-       hdr = (struct ieee80211_hdr *)skb->data;
-@@ -366,6 +370,10 @@ static void ath_tx_complete_aggr(struct 
-       memcpy(rates, tx_info->control.rates, sizeof(rates));
-+      retries = ts->ts_longretry + 1;
-+      for (i = 0; i < ts->ts_rateindex; i++)
-+              retries += rates[i].count;
-+
-       rcu_read_lock();
-       sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
-@@ -449,7 +457,8 @@ static void ath_tx_complete_aggr(struct 
-                       } else if (fi->retries < ATH_MAX_SW_RETRIES) {
-                               if (!(ts->ts_status & ATH9K_TXERR_FILT) ||
-                                   !an->sleeping)
--                                      ath_tx_set_retry(sc, txq, bf->bf_mpdu);
-+                                      ath_tx_set_retry(sc, txq, bf->bf_mpdu,
-+                                                       retries);
-                               clear_filter = true;
-                               txpending = 1;
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -535,7 +535,7 @@ struct ath_ant_comb {
- #define DEFAULT_CACHELINE       32
- #define ATH_REGCLASSIDS_MAX     10
- #define ATH_CABQ_READY_TIME     80      /* % of beacon interval */
--#define ATH_MAX_SW_RETRIES      10
-+#define ATH_MAX_SW_RETRIES      20
- #define ATH_CHAN_MAX            255
- #define ATH_TXPOWER_MAX         100     /* .5 dBm units */
diff --git a/package/mac80211/patches/573-ath9k_aggr_queue_cleanup.patch b/package/mac80211/patches/573-ath9k_aggr_queue_cleanup.patch
deleted file mode 100644 (file)
index 2bec9dc..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -200,6 +200,7 @@ struct ath_atx_ac {
- };
- struct ath_frame_info {
-+      struct ath_buf *bf;
-       int framelen;
-       u32 keyix;
-       enum ath9k_key_type keytype;
-@@ -230,7 +231,7 @@ struct ath_buf {
- struct ath_atx_tid {
-       struct list_head list;
--      struct list_head buf_q;
-+      struct sk_buff_head buf_q;
-       struct ath_node *an;
-       struct ath_atx_ac *ac;
-       unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -711,7 +711,7 @@ static ssize_t read_file_stations(struct
-                                       " tid: %p %s %s %i %p %p\n",
-                                       tid, tid->sched ? "sched" : "idle",
-                                       tid->paused ? "paused" : "running",
--                                      list_empty(&tid->buf_q),
-+                                      skb_queue_empty(&tid->buf_q),
-                                       tid->an, tid->ac);
-                       if (len >= size)
-                               goto done;
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -128,7 +128,7 @@ static void ath_tx_resume_tid(struct ath
-       spin_lock_bh(&txq->axq_lock);
-       tid->paused = false;
--      if (list_empty(&tid->buf_q))
-+      if (skb_queue_empty(&tid->buf_q))
-               goto unlock;
-       ath_tx_queue_tid(txq, tid);
-@@ -148,6 +148,7 @@ static struct ath_frame_info *get_frame_
- static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
- {
-       struct ath_txq *txq = tid->ac->txq;
-+      struct sk_buff *skb;
-       struct ath_buf *bf;
-       struct list_head bf_head;
-       struct ath_tx_status ts;
-@@ -158,12 +159,13 @@ static void ath_tx_flush_tid(struct ath_
-       memset(&ts, 0, sizeof(ts));
-       spin_lock_bh(&txq->axq_lock);
--      while (!list_empty(&tid->buf_q)) {
--              bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
--              list_move_tail(&bf->list, &bf_head);
-+      while ((skb = __skb_dequeue(&tid->buf_q))) {
-+              fi = get_frame_info(skb);
-+              bf = fi->bf;
-+
-+              list_add_tail(&bf->list, &bf_head);
-               spin_unlock_bh(&txq->axq_lock);
--              fi = get_frame_info(bf->bf_mpdu);
-               if (fi->retries) {
-                       ath_tx_update_baw(sc, tid, fi->seqno);
-                       ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
-@@ -218,6 +220,7 @@ static void ath_tid_drain(struct ath_sof
-                         struct ath_atx_tid *tid)
- {
-+      struct sk_buff *skb;
-       struct ath_buf *bf;
-       struct list_head bf_head;
-       struct ath_tx_status ts;
-@@ -226,14 +229,12 @@ static void ath_tid_drain(struct ath_sof
-       memset(&ts, 0, sizeof(ts));
-       INIT_LIST_HEAD(&bf_head);
--      for (;;) {
--              if (list_empty(&tid->buf_q))
--                      break;
-+      while ((skb = __skb_dequeue(&tid->buf_q))) {
-+              fi = get_frame_info(skb);
-+              bf = fi->bf;
--              bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
--              list_move_tail(&bf->list, &bf_head);
-+              list_add_tail(&bf->list, &bf_head);
--              fi = get_frame_info(bf->bf_mpdu);
-               if (fi->retries)
-                       ath_tx_update_baw(sc, tid, fi->seqno);
-@@ -351,7 +352,8 @@ static void ath_tx_complete_aggr(struct 
-       struct ieee80211_tx_info *tx_info;
-       struct ath_atx_tid *tid = NULL;
-       struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
--      struct list_head bf_head, bf_pending;
-+      struct list_head bf_head;
-+      struct sk_buff_head bf_pending;
-       u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
-       u32 ba[WME_BA_BMP_SIZE >> 5];
-       int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
-@@ -428,8 +430,7 @@ static void ath_tx_complete_aggr(struct 
-               }
-       }
--      INIT_LIST_HEAD(&bf_pending);
--      INIT_LIST_HEAD(&bf_head);
-+      __skb_queue_head_init(&bf_pending);
-       ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
-       while (bf) {
-@@ -474,10 +475,10 @@ static void ath_tx_complete_aggr(struct 
-                * Make sure the last desc is reclaimed if it
-                * not a holding desc.
-                */
--              if (!bf_last->bf_stale || bf_next != NULL)
-+              INIT_LIST_HEAD(&bf_head);
-+              if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) ||
-+                  bf_next != NULL || !bf_last->bf_stale)
-                       list_move_tail(&bf->list, &bf_head);
--              else
--                      INIT_LIST_HEAD(&bf_head);
-               if (!txpending || (tid->state & AGGR_CLEANUP)) {
-                       /*
-@@ -528,7 +529,7 @@ static void ath_tx_complete_aggr(struct 
-                                       ath9k_hw_cleartxdesc(sc->sc_ah,
-                                                            tbf->bf_desc);
--                                      list_add_tail(&tbf->list, &bf_head);
-+                                      fi->bf = tbf;
-                               } else {
-                                       /*
-                                        * Clear descriptor status words for
-@@ -543,21 +544,21 @@ static void ath_tx_complete_aggr(struct 
-                        * Put this buffer to the temporary pending
-                        * queue to retain ordering
-                        */
--                      list_splice_tail_init(&bf_head, &bf_pending);
-+                      __skb_queue_tail(&bf_pending, skb);
-               }
-               bf = bf_next;
-       }
-       /* prepend un-acked frames to the beginning of the pending frame queue */
--      if (!list_empty(&bf_pending)) {
-+      if (!skb_queue_empty(&bf_pending)) {
-               if (an->sleeping)
-                       ieee80211_sta_set_tim(sta);
-               spin_lock_bh(&txq->axq_lock);
-               if (clear_filter)
-                       tid->ac->clear_ps_filter = true;
--              list_splice(&bf_pending, &tid->buf_q);
-+              skb_queue_splice(&bf_pending, &tid->buf_q);
-               if (!an->sleeping)
-                       ath_tx_queue_tid(txq, tid);
-               spin_unlock_bh(&txq->axq_lock);
-@@ -722,19 +723,22 @@ static enum ATH_AGGR_STATUS ath_tx_form_
-                                            int *aggr_len)
- {
- #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
--      struct ath_buf *bf, *bf_first, *bf_prev = NULL;
-+      struct ath_buf *bf, *bf_first = NULL, *bf_prev = NULL;
-       int rl = 0, nframes = 0, ndelim, prev_al = 0;
-       u16 aggr_limit = 0, al = 0, bpad = 0,
-               al_delta, h_baw = tid->baw_size / 2;
-       enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
-       struct ieee80211_tx_info *tx_info;
-       struct ath_frame_info *fi;
--
--      bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
-+      struct sk_buff *skb;
-       do {
--              bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
--              fi = get_frame_info(bf->bf_mpdu);
-+              skb = skb_peek(&tid->buf_q);
-+              fi = get_frame_info(skb);
-+              bf = fi->bf;
-+
-+              if (!bf_first)
-+                      bf_first = bf;
-               /* do not step over block-ack window */
-               if (!BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno)) {
-@@ -785,7 +789,9 @@ static enum ATH_AGGR_STATUS ath_tx_form_
-               if (!fi->retries)
-                       ath_tx_addto_baw(sc, tid, fi->seqno);
-               ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
--              list_move_tail(&bf->list, bf_q);
-+
-+              __skb_unlink(skb, &tid->buf_q);
-+              list_add_tail(&bf->list, bf_q);
-               if (bf_prev) {
-                       bf_prev->bf_next = bf;
-                       ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc,
-@@ -793,7 +799,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
-               }
-               bf_prev = bf;
--      } while (!list_empty(&tid->buf_q));
-+      } while (!skb_queue_empty(&tid->buf_q));
-       *aggr_len = al;
-@@ -811,7 +817,7 @@ static void ath_tx_sched_aggr(struct ath
-       int aggr_len;
-       do {
--              if (list_empty(&tid->buf_q))
-+              if (skb_queue_empty(&tid->buf_q))
-                       return;
-               INIT_LIST_HEAD(&bf_q);
-@@ -933,7 +939,7 @@ bool ath_tx_aggr_sleep(struct ath_softc 
-               spin_lock_bh(&txq->axq_lock);
--              if (!list_empty(&tid->buf_q))
-+              if (!skb_queue_empty(&tid->buf_q))
-                       buffered = true;
-               tid->sched = false;
-@@ -966,7 +972,7 @@ void ath_tx_aggr_wakeup(struct ath_softc
-               spin_lock_bh(&txq->axq_lock);
-               ac->clear_ps_filter = true;
--              if (!list_empty(&tid->buf_q) && !tid->paused) {
-+              if (!skb_queue_empty(&tid->buf_q) && !tid->paused) {
-                       ath_tx_queue_tid(txq, tid);
-                       ath_txq_schedule(sc, txq);
-               }
-@@ -1308,7 +1314,7 @@ void ath_txq_schedule(struct ath_softc *
-                        * add tid to round-robin queue if more frames
-                        * are pending for the tid
-                        */
--                      if (!list_empty(&tid->buf_q))
-+                      if (!skb_queue_empty(&tid->buf_q))
-                               ath_tx_queue_tid(txq, tid);
-                       if (tid == last_tid ||
-@@ -1414,7 +1420,7 @@ static void ath_tx_send_ampdu(struct ath
-        * - seqno is not within block-ack window
-        * - h/w queue depth exceeds low water mark
-        */
--      if (!list_empty(&tid->buf_q) || tid->paused ||
-+      if (!skb_queue_empty(&tid->buf_q) || tid->paused ||
-           !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) ||
-           txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) {
-               /*
-@@ -1422,7 +1428,7 @@ static void ath_tx_send_ampdu(struct ath
-                * for aggregation.
-                */
-               TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
--              list_add_tail(&bf->list, &tid->buf_q);
-+              __skb_queue_tail(&tid->buf_q, bf->bf_mpdu);
-               if (!txctl->an || !txctl->an->sleeping)
-                       ath_tx_queue_tid(txctl->txq, tid);
-               return;
-@@ -1753,6 +1759,7 @@ static struct ath_buf *ath_tx_setup_buff
-                           bf->bf_buf_addr,
-                           txq->axq_qnum);
-+      fi->bf = bf;
-       return bf;
- }
-@@ -2364,7 +2371,7 @@ void ath_tx_node_init(struct ath_softc *
-               tid->sched     = false;
-               tid->paused    = false;
-               tid->state &= ~AGGR_CLEANUP;
--              INIT_LIST_HEAD(&tid->buf_q);
-+              __skb_queue_head_init(&tid->buf_q);
-               acno = TID_TO_WME_AC(tidno);
-               tid->ac = &an->ac[acno];
-               tid->state &= ~AGGR_ADDBA_COMPLETE;
diff --git a/package/mac80211/patches/574-ath9k_limit_qlen.patch b/package/mac80211/patches/574-ath9k_limit_qlen.patch
deleted file mode 100644 (file)
index 77f1f5c..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -235,6 +235,7 @@ struct ath_atx_tid {
-       struct ath_node *an;
-       struct ath_atx_ac *ac;
-       unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
-+      int buf_pending;
-       u16 seq_start;
-       u16 seq_next;
-       u16 baw_size;
-@@ -283,6 +284,9 @@ struct ath_tx_control {
-  *  (axq_qnum).
-  */
- struct ath_tx {
-+      u32 qlen_single;
-+      u32 qlen_aggr;
-+
-       u16 seq_no;
-       u32 txqsetup;
-       spinlock_t txbuflock;
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1250,6 +1250,10 @@ int ath9k_init_debug(struct ath_hw *ah)
-                           sc, &fops_wiphy);
-       debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
-                           &fops_xmit);
-+      debugfs_create_u32("qlen_single", S_IRUSR | S_IWUSR,
-+                         sc->debug.debugfs_phy, &sc->tx.qlen_single);
-+      debugfs_create_u32("qlen_aggr", S_IRUSR | S_IWUSR,
-+                         sc->debug.debugfs_phy, &sc->tx.qlen_aggr);
-       debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
-                           &fops_stations);
-       debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -339,6 +339,14 @@ static void ath_tx_count_frames(struct a
-       }
- }
-+static struct ath_atx_tid *ath_get_tid(struct ath_node *an, struct sk_buff *skb)
-+{
-+      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-+      u8 tidno;
-+
-+      tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
-+      return ATH_AN_2_TID(an, tidno);
-+}
- static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
-                                struct ath_buf *bf, struct list_head *bf_q,
-@@ -433,6 +441,8 @@ static void ath_tx_complete_aggr(struct 
-       __skb_queue_head_init(&bf_pending);
-       ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
-+      tid->buf_pending -= nframes;
-+
-       while (bf) {
-               txfail = txpending = 0;
-               bf_next = bf->bf_next;
-@@ -790,6 +800,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
-                       ath_tx_addto_baw(sc, tid, fi->seqno);
-               ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
-+              tid->buf_pending++;
-               __skb_unlink(skb, &tid->buf_q);
-               list_add_tail(&bf->list, bf_q);
-               if (bf_prev) {
-@@ -1441,6 +1452,8 @@ static void ath_tx_send_ampdu(struct ath
-       if (!fi->retries)
-               ath_tx_addto_baw(sc, tid, fi->seqno);
-+      tid->buf_pending++;
-+
-       /* Queue to h/w without aggregation */
-       TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
-       bf->bf_lastbf = bf;
-@@ -1505,7 +1518,6 @@ static void setup_frame_info(struct ieee
-       struct ath_atx_tid *tid;
-       enum ath9k_key_type keytype;
-       u16 seqno = 0;
--      u8 tidno;
-       keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
-@@ -1516,13 +1528,11 @@ static void setup_frame_info(struct ieee
-       if (an && ieee80211_is_data_qos(hdr->frame_control) &&
-               conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) {
--              tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
--
-               /*
-                * Override seqno set by upper layer with the one
-                * in tx aggregation state.
-                */
--              tid = ATH_AN_2_TID(an, tidno);
-+              tid = ath_get_tid(an, skb);
-               seqno = tid->seq_next;
-               hdr->seq_ctrl = cpu_to_le16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
-               INCR(tid->seq_next, IEEE80211_SEQ_MAX);
-@@ -1766,24 +1776,14 @@ static struct ath_buf *ath_tx_setup_buff
- /* FIXME: tx power */
- static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
--                           struct ath_tx_control *txctl)
-+                           struct ath_tx_control *txctl,
-+                           struct ath_atx_tid *tid)
- {
-       struct sk_buff *skb = bf->bf_mpdu;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
--      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct list_head bf_head;
--      struct ath_atx_tid *tid = NULL;
--      u8 tidno;
-       spin_lock_bh(&txctl->txq->axq_lock);
--      if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an &&
--              ieee80211_is_data_qos(hdr->frame_control)) {
--              tidno = ieee80211_get_qos_ctl(hdr)[0] &
--                      IEEE80211_QOS_CTL_TID_MASK;
--              tid = ATH_AN_2_TID(txctl->an, tidno);
--
--              WARN_ON(tid->ac->txq != txctl->txq);
--      }
-       if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
-               /*
-@@ -1824,6 +1824,7 @@ int ath_tx_start(struct ieee80211_hw *hw
-       struct ieee80211_vif *vif = info->control.vif;
-       struct ath_softc *sc = hw->priv;
-       struct ath_txq *txq = txctl->txq;
-+      struct ath_atx_tid *tid = NULL;
-       struct ath_buf *bf;
-       int padpos, padsize;
-       int frmlen = skb->len + FCS_LEN;
-@@ -1857,6 +1858,7 @@ int ath_tx_start(struct ieee80211_hw *hw
-               skb_push(skb, padsize);
-               memmove(skb->data, skb->data + padsize, padpos);
-+              hdr = (struct ieee80211_hdr *) skb->data;
-       }
-       if ((vif && vif->type != NL80211_IFTYPE_AP &&
-@@ -1866,6 +1868,24 @@ int ath_tx_start(struct ieee80211_hw *hw
-       setup_frame_info(hw, skb, frmlen);
-+      if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an &&
-+          ieee80211_is_data_qos(hdr->frame_control)) {
-+              tid = ath_get_tid(txctl->an, skb);
-+
-+              WARN_ON(tid->ac->txq != txq);
-+      }
-+
-+      if ((info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
-+              if (sc->tx.qlen_aggr > 0 && skb_queue_len(&tid->buf_q) +
-+                  tid->buf_pending >= sc->tx.qlen_aggr)
-+                      return -ENOMEM;
-+      } else {
-+              if (sc->tx.qlen_single > 0 &&
-+                  txq->axq_depth - txq->axq_ampdu_depth >=
-+                    sc->tx.qlen_single)
-+                      return -ENOMEM;
-+      }
-+
-       /*
-        * At this point, the vif, hw_key and sta pointers in the tx control
-        * info are no longer valid (overwritten by the ath_frame_info data.
-@@ -1884,7 +1904,7 @@ int ath_tx_start(struct ieee80211_hw *hw
-       }
-       spin_unlock_bh(&txq->axq_lock);
--      ath_tx_start_dma(sc, bf, txctl);
-+      ath_tx_start_dma(sc, bf, txctl, tid);
-       return 0;
- }
index 2194cca..7f8c9a5 100644 (file)
@@ -22,7 +22,7 @@
 +#endif /* _RT2X00_PLATFORM_H */
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -38,6 +38,7 @@
+@@ -39,6 +39,7 @@
  #include <linux/input-polldev.h>
  #include <linux/kfifo.h>
  #include <linux/timer.h>
index fc58744..7a84e81 100644 (file)
 +}
 --- a/drivers/net/wireless/rt2x00/rt2x00.h
 +++ b/drivers/net/wireless/rt2x00/rt2x00.h
-@@ -538,6 +538,7 @@ struct rt2x00lib_ops {
+@@ -539,6 +539,7 @@ struct rt2x00lib_ops {
                               const u8 *data, const size_t len);
        int (*load_firmware) (struct rt2x00_dev *rt2x00dev,
                              const u8 *data, const size_t len);
  
        /*
         * Device initialization/deinitialization handlers.
-@@ -684,6 +685,7 @@ enum rt2x00_capability_flags {
+@@ -685,6 +686,7 @@ enum rt2x00_capability_flags {
        REQUIRE_SW_SEQNO,
        REQUIRE_HT_TX_DESC,
        REQUIRE_PS_AUTOWAKE,
  
        /*
         * Capabilities
-@@ -939,6 +941,11 @@ struct rt2x00_dev {
+@@ -940,6 +942,11 @@ struct rt2x00_dev {
        const struct firmware *fw;
  
        /*
  
  #ifdef CONFIG_PCI
  static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
-@@ -315,6 +305,20 @@ static int rt2800pci_write_firmware(stru
+@@ -311,6 +301,20 @@ static int rt2800pci_write_firmware(stru
  }
  
  /*
   * Initialization functions.
   */
  static bool rt2800pci_get_entry_state(struct queue_entry *entry)
-@@ -1057,6 +1061,7 @@ static const struct rt2x00lib_ops rt2800
+@@ -1050,6 +1054,7 @@ static const struct rt2x00lib_ops rt2800
        .get_firmware_name      = rt2800pci_get_firmware_name,
        .check_firmware         = rt2800_check_firmware,
        .load_firmware          = rt2800_load_firmware,
        .get_entry_state        = rt2800pci_get_entry_state,
 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
 +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
-@@ -1122,6 +1122,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
+@@ -1121,6 +1121,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
        INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
        INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
  
        /*
         * Let the driver probe the device to detect the capabilities.
         */
-@@ -1223,6 +1227,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
+@@ -1222,6 +1226,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
         * Free queue structures.
         */
        rt2x00queue_free(rt2x00dev);
index 283a1b3..9e30620 100644 (file)
@@ -1,6 +1,6 @@
 --- a/config.mk
 +++ b/config.mk
-@@ -578,6 +578,7 @@ CONFIG_RT2X00=y
+@@ -581,6 +581,7 @@ CONFIG_RT2X00=y
  CONFIG_RT2X00_LIB=m
  CONFIG_RT2800_LIB=m
  CONFIG_RT2X00_LIB_FIRMWARE=y
index c59441d..c95e2a5 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/mwl8k.c
 +++ b/drivers/net/wireless/mwl8k.c
-@@ -5194,6 +5194,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
+@@ -5195,6 +5195,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) = {
index 1dee123..d61e11a 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/b43/b43.h
 +++ b/drivers/net/wireless/b43/b43.h
-@@ -740,6 +740,7 @@ struct b43_wldev {
+@@ -746,6 +746,7 @@ struct b43_wldev {
        bool qos_enabled;               /* TRUE, if QoS is used. */
        bool hwcrypto_enabled;          /* TRUE, if HW crypto acceleration is enabled. */
        bool use_pio;                   /* TRUE if next init should use PIO */
@@ -10,7 +10,7 @@
        struct b43_phy phy;
 --- a/drivers/net/wireless/b43/main.c
 +++ b/drivers/net/wireless/b43/main.c
-@@ -76,6 +76,11 @@ MODULE_FIRMWARE("b43/ucode16_mimo.fw");
+@@ -75,6 +75,11 @@ MODULE_FIRMWARE("b43/ucode16_mimo.fw");
  MODULE_FIRMWARE("b43/ucode5.fw");
  MODULE_FIRMWARE("b43/ucode9.fw");
  
@@ -22,7 +22,7 @@
  static int modparam_bad_frames_preempt;
  module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
  MODULE_PARM_DESC(bad_frames_preempt,
-@@ -2575,10 +2580,10 @@ static int b43_gpio_init(struct b43_wlde
+@@ -2671,10 +2676,10 @@ static int b43_gpio_init(struct b43_wlde
                    & ~B43_MACCTL_GPOUTSMSK);
  
        b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK)
@@ -35,7 +35,7 @@
        if (dev->dev->chip_id == 0x4301) {
                mask |= 0x0060;
                set |= 0x0060;
-@@ -5137,10 +5142,10 @@ static void b43_print_driverinfo(void)
+@@ -5441,10 +5446,10 @@ static void b43_print_driverinfo(void)
        feat_sdio = "S";
  #endif
        printk(KERN_INFO "Broadcom 43xx driver loaded "
index a913b6d..1d0382c 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/b43/Makefile
 +++ b/drivers/net/wireless/b43/Makefile
-@@ -17,7 +17,7 @@ b43-y                                += xmit.o
+@@ -19,7 +19,7 @@ b43-y                                += xmit.o
  b43-y                         += lo.o
  b43-y                         += wa.o
  b43-y                         += dma.o
@@ -11,7 +11,7 @@
  b43-$(CONFIG_B43_PCMCIA)      += pcmcia.o
 --- a/drivers/net/wireless/b43/main.c
 +++ b/drivers/net/wireless/b43/main.c
-@@ -1834,9 +1834,11 @@ static void b43_do_interrupt_thread(stru
+@@ -1884,9 +1884,11 @@ static void b43_do_interrupt_thread(stru
                               dma_reason[4], dma_reason[5]);
                        b43err(dev->wl, "This device does not support DMA "
                               "on your system. It will now be switched to PIO.\n");
diff --git a/package/mac80211/patches/820-b43-backport.patch b/package/mac80211/patches/820-b43-backport.patch
deleted file mode 100644 (file)
index 3dbf936..0000000
+++ /dev/null
@@ -1,2568 +0,0 @@
---- a/drivers/net/wireless/b43/Kconfig
-+++ b/drivers/net/wireless/b43/Kconfig
-@@ -90,6 +90,12 @@ config B43_SDIO
- #Data transfers to the device via PIO. We want it as a fallback even
- # if we can do DMA.
-+config B43_BCMA_PIO
-+      bool
-+      depends on B43_BCMA
-+      select BCMA_BLOCKIO
-+      default y
-+
- config B43_PIO
-       bool
-       depends on B43
-@@ -125,6 +131,14 @@ config B43_PHY_HT
-         Say N, this is BROKEN and crashes driver.
-+config B43_PHY_LCN
-+      bool "Support for LCN-PHY devices (BROKEN)"
-+      depends on B43 && BROKEN
-+      ---help---
-+        Support for the LCN-PHY.
-+
-+        Say N, this is BROKEN and crashes driver.
-+
- # This config option automatically enables b43 LEDS support,
- # if it's possible.
- config B43_LEDS
---- a/drivers/net/wireless/b43/Makefile
-+++ b/drivers/net/wireless/b43/Makefile
-@@ -11,7 +11,9 @@ b43-$(CONFIG_B43_PHY_N)              += phy_n.o
- b43-$(CONFIG_B43_PHY_LP)      += phy_lp.o
- b43-$(CONFIG_B43_PHY_LP)      += tables_lpphy.o
- b43-$(CONFIG_B43_PHY_HT)      += phy_ht.o
-+b43-$(CONFIG_B43_PHY_HT)      += tables_phy_ht.o
- b43-$(CONFIG_B43_PHY_HT)      += radio_2059.o
-+b43-$(CONFIG_B43_PHY_LCN)     += phy_lcn.o tables_phy_lcn.o
- b43-y                         += sysfs.o
- b43-y                         += xmit.o
- b43-y                         += lo.o
---- a/drivers/net/wireless/b43/b43.h
-+++ b/drivers/net/wireless/b43/b43.h
-@@ -433,6 +433,12 @@ enum {
- #define  B43_BCMA_IOCTL_PHY_BW_40MHZ  0x00000080      /* 40 MHz bandwidth, 160 MHz PHY */
- #define B43_BCMA_IOCTL_GMODE          0x00002000      /* G Mode Enable */
-+/* BCMA 802.11 core specific IO status (BCMA_IOST) flags */
-+#define B43_BCMA_IOST_2G_PHY          0x00000001      /* 2.4G capable phy */
-+#define B43_BCMA_IOST_5G_PHY          0x00000002      /* 5G capable phy */
-+#define B43_BCMA_IOST_FASTCLKA                0x00000004      /* Fast Clock Available */
-+#define B43_BCMA_IOST_DUALB_PHY               0x00000008      /* Dualband phy */
-+
- /* 802.11 core specific TM State Low (SSB_TMSLOW) flags */
- #define B43_TMSLOW_GMODE              0x20000000      /* G Mode Enable */
- #define B43_TMSLOW_PHY_BANDWIDTH      0x00C00000      /* PHY band width and clock speed mask (N-PHY only) */
-@@ -588,6 +594,7 @@ struct b43_dma {
-       struct b43_dmaring *rx_ring;
-       u32 translation; /* Routing bits */
-+      bool parity; /* Check for parity */
- };
- struct b43_pio_txqueue;
-@@ -726,7 +733,6 @@ enum {
- /* Data structure for one wireless device (802.11 core) */
- struct b43_wldev {
--      struct ssb_device *sdev; /* TODO: remove when b43_bus_dev is ready */
-       struct b43_bus_dev *dev;
-       struct b43_wl *wl;
---- a/drivers/net/wireless/b43/bus.c
-+++ b/drivers/net/wireless/b43/bus.c
-@@ -23,58 +23,155 @@
- #include "b43.h"
- #include "bus.h"
-+/* BCMA */
-+#ifdef CONFIG_B43_BCMA
-+static int b43_bus_bcma_bus_may_powerdown(struct b43_bus_dev *dev)
-+{
-+      return 0; /* bcma_bus_may_powerdown(dev->bdev->bus); */
-+}
-+static int b43_bus_bcma_bus_powerup(struct b43_bus_dev *dev,
-+                                        bool dynamic_pctl)
-+{
-+      return 0; /* bcma_bus_powerup(dev->sdev->bus, dynamic_pctl); */
-+}
-+static int b43_bus_bcma_device_is_enabled(struct b43_bus_dev *dev)
-+{
-+      return bcma_core_is_enabled(dev->bdev);
-+}
-+static void b43_bus_bcma_device_enable(struct b43_bus_dev *dev,
-+                                           u32 core_specific_flags)
-+{
-+      bcma_core_enable(dev->bdev, core_specific_flags);
-+}
-+static void b43_bus_bcma_device_disable(struct b43_bus_dev *dev,
-+                                            u32 core_specific_flags)
-+{
-+      bcma_core_disable(dev->bdev, core_specific_flags);
-+}
-+static u16 b43_bus_bcma_read16(struct b43_bus_dev *dev, u16 offset)
-+{
-+      return bcma_read16(dev->bdev, offset);
-+}
-+static u32 b43_bus_bcma_read32(struct b43_bus_dev *dev, u16 offset)
-+{
-+      return bcma_read32(dev->bdev, offset);
-+}
-+static
-+void b43_bus_bcma_write16(struct b43_bus_dev *dev, u16 offset, u16 value)
-+{
-+      bcma_write16(dev->bdev, offset, value);
-+}
-+static
-+void b43_bus_bcma_write32(struct b43_bus_dev *dev, u16 offset, u32 value)
-+{
-+      bcma_write32(dev->bdev, offset, value);
-+}
-+static
-+void b43_bus_bcma_block_read(struct b43_bus_dev *dev, void *buffer,
-+                           size_t count, u16 offset, u8 reg_width)
-+{
-+      bcma_block_read(dev->bdev, buffer, count, offset, reg_width);
-+}
-+static
-+void b43_bus_bcma_block_write(struct b43_bus_dev *dev, const void *buffer,
-+                            size_t count, u16 offset, u8 reg_width)
-+{
-+      bcma_block_write(dev->bdev, buffer, count, offset, reg_width);
-+}
-+
-+struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core)
-+{
-+      struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-+      if (!dev)
-+              return NULL;
-+
-+      dev->bus_type = B43_BUS_BCMA;
-+      dev->bdev = core;
-+
-+      dev->bus_may_powerdown = b43_bus_bcma_bus_may_powerdown;
-+      dev->bus_powerup = b43_bus_bcma_bus_powerup;
-+      dev->device_is_enabled = b43_bus_bcma_device_is_enabled;
-+      dev->device_enable = b43_bus_bcma_device_enable;
-+      dev->device_disable = b43_bus_bcma_device_disable;
-+
-+      dev->read16 = b43_bus_bcma_read16;
-+      dev->read32 = b43_bus_bcma_read32;
-+      dev->write16 = b43_bus_bcma_write16;
-+      dev->write32 = b43_bus_bcma_write32;
-+      dev->block_read = b43_bus_bcma_block_read;
-+      dev->block_write = b43_bus_bcma_block_write;
-+
-+      dev->dev = &core->dev;
-+      dev->dma_dev = core->dma_dev;
-+      dev->irq = core->irq;
-+
-+      /*
-+      dev->board_vendor = core->bus->boardinfo.vendor;
-+      dev->board_type = core->bus->boardinfo.type;
-+      dev->board_rev = core->bus->boardinfo.rev;
-+      */
-+
-+      dev->chip_id = core->bus->chipinfo.id;
-+      dev->chip_rev = core->bus->chipinfo.rev;
-+      dev->chip_pkg = core->bus->chipinfo.pkg;
-+
-+      dev->bus_sprom = &core->bus->sprom;
-+
-+      dev->core_id = core->id.id;
-+      dev->core_rev = core->id.rev;
-+
-+      return dev;
-+}
-+#endif /* CONFIG_B43_BCMA */
- /* SSB */
- #ifdef CONFIG_B43_SSB
--static inline int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev)
-+static int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev)
- {
-       return ssb_bus_may_powerdown(dev->sdev->bus);
- }
--static inline int b43_bus_ssb_bus_powerup(struct b43_bus_dev *dev,
-+static int b43_bus_ssb_bus_powerup(struct b43_bus_dev *dev,
-                                         bool dynamic_pctl)
- {
-       return ssb_bus_powerup(dev->sdev->bus, dynamic_pctl);
- }
--static inline int b43_bus_ssb_device_is_enabled(struct b43_bus_dev *dev)
-+static int b43_bus_ssb_device_is_enabled(struct b43_bus_dev *dev)
- {
-       return ssb_device_is_enabled(dev->sdev);
- }
--static inline void b43_bus_ssb_device_enable(struct b43_bus_dev *dev,
-+static void b43_bus_ssb_device_enable(struct b43_bus_dev *dev,
-                                            u32 core_specific_flags)
- {
-       ssb_device_enable(dev->sdev, core_specific_flags);
- }
--static inline void b43_bus_ssb_device_disable(struct b43_bus_dev *dev,
-+static void b43_bus_ssb_device_disable(struct b43_bus_dev *dev,
-                                             u32 core_specific_flags)
- {
-       ssb_device_disable(dev->sdev, core_specific_flags);
- }
--static inline u16 b43_bus_ssb_read16(struct b43_bus_dev *dev, u16 offset)
-+static u16 b43_bus_ssb_read16(struct b43_bus_dev *dev, u16 offset)
- {
-       return ssb_read16(dev->sdev, offset);
- }
--static inline u32 b43_bus_ssb_read32(struct b43_bus_dev *dev, u16 offset)
-+static u32 b43_bus_ssb_read32(struct b43_bus_dev *dev, u16 offset)
- {
-       return ssb_read32(dev->sdev, offset);
- }
--static inline
--void b43_bus_ssb_write16(struct b43_bus_dev *dev, u16 offset, u16 value)
-+static void b43_bus_ssb_write16(struct b43_bus_dev *dev, u16 offset, u16 value)
- {
-       ssb_write16(dev->sdev, offset, value);
- }
--static inline
--void b43_bus_ssb_write32(struct b43_bus_dev *dev, u16 offset, u32 value)
-+static void b43_bus_ssb_write32(struct b43_bus_dev *dev, u16 offset, u32 value)
- {
-       ssb_write32(dev->sdev, offset, value);
- }
--static inline
--void b43_bus_ssb_block_read(struct b43_bus_dev *dev, void *buffer,
--                          size_t count, u16 offset, u8 reg_width)
-+static void b43_bus_ssb_block_read(struct b43_bus_dev *dev, void *buffer,
-+                                 size_t count, u16 offset, u8 reg_width)
- {
-       ssb_block_read(dev->sdev, buffer, count, offset, reg_width);
- }
--static inline
-+static
- void b43_bus_ssb_block_write(struct b43_bus_dev *dev, const void *buffer,
-                            size_t count, u16 offset, u8 reg_width)
- {
-@@ -125,3 +222,32 @@ struct b43_bus_dev *b43_bus_dev_ssb_init
-       return dev;
- }
- #endif /* CONFIG_B43_SSB */
-+
-+void *b43_bus_get_wldev(struct b43_bus_dev *dev)
-+{
-+      switch (dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+      case B43_BUS_BCMA:
-+              return bcma_get_drvdata(dev->bdev);
-+#endif
-+#ifdef CONFIG_B43_SSB
-+      case B43_BUS_SSB:
-+              return ssb_get_drvdata(dev->sdev);
-+#endif
-+      }
-+      return NULL;
-+}
-+
-+void b43_bus_set_wldev(struct b43_bus_dev *dev, void *wldev)
-+{
-+      switch (dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+      case B43_BUS_BCMA:
-+              bcma_set_drvdata(dev->bdev, wldev);
-+#endif
-+#ifdef CONFIG_B43_SSB
-+      case B43_BUS_SSB:
-+              ssb_set_drvdata(dev->sdev, wldev);
-+#endif
-+      }
-+}
---- a/drivers/net/wireless/b43/bus.h
-+++ b/drivers/net/wireless/b43/bus.h
-@@ -2,12 +2,16 @@
- #define B43_BUS_H_
- enum b43_bus_type {
-+#ifdef CONFIG_B43_BCMA
-+      B43_BUS_BCMA,
-+#endif
-       B43_BUS_SSB,
- };
- struct b43_bus_dev {
-       enum b43_bus_type bus_type;
-       union {
-+              struct bcma_device *bdev;
-               struct ssb_device *sdev;
-       };
-@@ -57,6 +61,10 @@ static inline bool b43_bus_host_is_sdio(
-               dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO);
- }
-+struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core);
- struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev);
-+void *b43_bus_get_wldev(struct b43_bus_dev *dev);
-+void b43_bus_set_wldev(struct b43_bus_dev *dev, void *data);
-+
- #endif /* B43_BUS_H_ */
---- a/drivers/net/wireless/b43/dma.c
-+++ b/drivers/net/wireless/b43/dma.c
-@@ -174,7 +174,7 @@ static void op64_fill_descriptor(struct 
-       addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
-       addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
-           >> SSB_DMA_TRANSLATION_SHIFT;
--      addrhi |= (ring->dev->dma.translation << 1);
-+      addrhi |= ring->dev->dma.translation;
-       if (slot == ring->nr_slots - 1)
-               ctl0 |= B43_DMA64_DCTL0_DTABLEEND;
-       if (start)
-@@ -659,6 +659,7 @@ static int dmacontroller_setup(struct b4
-       u32 value;
-       u32 addrext;
-       u32 trans = ring->dev->dma.translation;
-+      bool parity = ring->dev->dma.parity;
-       if (ring->tx) {
-               if (ring->type == B43_DMA_64BIT) {
-@@ -669,13 +670,15 @@ static int dmacontroller_setup(struct b4
-                       value = B43_DMA64_TXENABLE;
-                       value |= (addrext << B43_DMA64_TXADDREXT_SHIFT)
-                           & B43_DMA64_TXADDREXT_MASK;
-+                      if (!parity)
-+                              value |= B43_DMA64_TXPARITYDISABLE;
-                       b43_dma_write(ring, B43_DMA64_TXCTL, value);
-                       b43_dma_write(ring, B43_DMA64_TXRINGLO,
-                                     (ringbase & 0xFFFFFFFF));
-                       b43_dma_write(ring, B43_DMA64_TXRINGHI,
-                                     ((ringbase >> 32) &
-                                      ~SSB_DMA_TRANSLATION_MASK)
--                                    | (trans << 1));
-+                                    | trans);
-               } else {
-                       u32 ringbase = (u32) (ring->dmabase);
-@@ -684,6 +687,8 @@ static int dmacontroller_setup(struct b4
-                       value = B43_DMA32_TXENABLE;
-                       value |= (addrext << B43_DMA32_TXADDREXT_SHIFT)
-                           & B43_DMA32_TXADDREXT_MASK;
-+                      if (!parity)
-+                              value |= B43_DMA32_TXPARITYDISABLE;
-                       b43_dma_write(ring, B43_DMA32_TXCTL, value);
-                       b43_dma_write(ring, B43_DMA32_TXRING,
-                                     (ringbase & ~SSB_DMA_TRANSLATION_MASK)
-@@ -702,13 +707,15 @@ static int dmacontroller_setup(struct b4
-                       value |= B43_DMA64_RXENABLE;
-                       value |= (addrext << B43_DMA64_RXADDREXT_SHIFT)
-                           & B43_DMA64_RXADDREXT_MASK;
-+                      if (!parity)
-+                              value |= B43_DMA64_RXPARITYDISABLE;
-                       b43_dma_write(ring, B43_DMA64_RXCTL, value);
-                       b43_dma_write(ring, B43_DMA64_RXRINGLO,
-                                     (ringbase & 0xFFFFFFFF));
-                       b43_dma_write(ring, B43_DMA64_RXRINGHI,
-                                     ((ringbase >> 32) &
-                                      ~SSB_DMA_TRANSLATION_MASK)
--                                    | (trans << 1));
-+                                    | trans);
-                       b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots *
-                                     sizeof(struct b43_dmadesc64));
-               } else {
-@@ -720,6 +727,8 @@ static int dmacontroller_setup(struct b4
-                       value |= B43_DMA32_RXENABLE;
-                       value |= (addrext << B43_DMA32_RXADDREXT_SHIFT)
-                           & B43_DMA32_RXADDREXT_MASK;
-+                      if (!parity)
-+                              value |= B43_DMA32_RXPARITYDISABLE;
-                       b43_dma_write(ring, B43_DMA32_RXCTL, value);
-                       b43_dma_write(ring, B43_DMA32_RXRING,
-                                     (ringbase & ~SSB_DMA_TRANSLATION_MASK)
-@@ -1055,7 +1064,26 @@ int b43_dma_init(struct b43_wldev *dev)
-       err = b43_dma_set_mask(dev, dmamask);
-       if (err)
-               return err;
--      dma->translation = ssb_dma_translation(dev->sdev);
-+
-+      switch (dev->dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+      case B43_BUS_BCMA:
-+              dma->translation = bcma_core_dma_translation(dev->dev->bdev);
-+              break;
-+#endif
-+#ifdef CONFIG_B43_SSB
-+      case B43_BUS_SSB:
-+              dma->translation = ssb_dma_translation(dev->dev->sdev);
-+              break;
-+#endif
-+      }
-+
-+      dma->parity = true;
-+#ifdef CONFIG_B43_BCMA
-+      /* TODO: find out which SSB devices need disabling parity */
-+      if (dev->dev->bus_type == B43_BUS_BCMA)
-+              dma->parity = false;
-+#endif
-       err = -ENOMEM;
-       /* setup TX DMA channels. */
-@@ -1600,6 +1628,7 @@ void b43_dma_rx(struct b43_dmaring *ring
-               dma_rx(ring, &slot);
-               update_max_used_slots(ring, ++used_slots);
-       }
-+      wmb();
-       ops->set_current_rxslot(ring, slot);
-       ring->current_slot = slot;
- }
---- a/drivers/net/wireless/b43/dma.h
-+++ b/drivers/net/wireless/b43/dma.h
-@@ -20,6 +20,7 @@
- #define               B43_DMA32_TXSUSPEND                     0x00000002
- #define               B43_DMA32_TXLOOPBACK            0x00000004
- #define               B43_DMA32_TXFLUSH                       0x00000010
-+#define               B43_DMA32_TXPARITYDISABLE               0x00000800
- #define               B43_DMA32_TXADDREXT_MASK                0x00030000
- #define               B43_DMA32_TXADDREXT_SHIFT               16
- #define B43_DMA32_TXRING                              0x04
-@@ -44,6 +45,7 @@
- #define               B43_DMA32_RXFROFF_MASK          0x000000FE
- #define               B43_DMA32_RXFROFF_SHIFT         1
- #define               B43_DMA32_RXDIRECTFIFO          0x00000100
-+#define               B43_DMA32_RXPARITYDISABLE               0x00000800
- #define               B43_DMA32_RXADDREXT_MASK                0x00030000
- #define               B43_DMA32_RXADDREXT_SHIFT               16
- #define B43_DMA32_RXRING                              0x14
-@@ -84,6 +86,7 @@ struct b43_dmadesc32 {
- #define               B43_DMA64_TXSUSPEND                     0x00000002
- #define               B43_DMA64_TXLOOPBACK            0x00000004
- #define               B43_DMA64_TXFLUSH                       0x00000010
-+#define               B43_DMA64_TXPARITYDISABLE               0x00000800
- #define               B43_DMA64_TXADDREXT_MASK                0x00030000
- #define               B43_DMA64_TXADDREXT_SHIFT               16
- #define B43_DMA64_TXINDEX                             0x04
-@@ -111,6 +114,7 @@ struct b43_dmadesc32 {
- #define               B43_DMA64_RXFROFF_MASK          0x000000FE
- #define               B43_DMA64_RXFROFF_SHIFT         1
- #define               B43_DMA64_RXDIRECTFIFO          0x00000100
-+#define               B43_DMA64_RXPARITYDISABLE               0x00000800
- #define               B43_DMA64_RXADDREXT_MASK                0x00030000
- #define               B43_DMA64_RXADDREXT_SHIFT               16
- #define B43_DMA64_RXINDEX                             0x24
---- a/drivers/net/wireless/b43/main.c
-+++ b/drivers/net/wireless/b43/main.c
-@@ -1136,6 +1136,41 @@ void b43_power_saving_ctl_bits(struct b4
-       }
- }
-+#ifdef CONFIG_B43_BCMA
-+static void b43_bcma_phy_reset(struct b43_wldev *dev)
-+{
-+      u32 flags;
-+
-+      /* Put PHY into reset */
-+      flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
-+      flags |= B43_BCMA_IOCTL_PHY_RESET;
-+      flags |= B43_BCMA_IOCTL_PHY_BW_20MHZ; /* Make 20 MHz def */
-+      bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
-+      udelay(2);
-+
-+      /* Take PHY out of reset */
-+      flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
-+      flags &= ~B43_BCMA_IOCTL_PHY_RESET;
-+      flags |= BCMA_IOCTL_FGC;
-+      bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
-+      udelay(1);
-+
-+      /* Do not force clock anymore */
-+      flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
-+      flags &= ~BCMA_IOCTL_FGC;
-+      bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
-+      udelay(1);
-+}
-+
-+static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode)
-+{
-+      b43_device_enable(dev, B43_BCMA_IOCTL_PHY_CLKEN);
-+      bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST);
-+      b43_bcma_phy_reset(dev);
-+      bcma_core_pll_ctl(dev->dev->bdev, 0x300, 0x3000000, true);
-+}
-+#endif
-+
- static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode)
- {
-       struct ssb_device *sdev = dev->dev->sdev;
-@@ -1168,7 +1203,18 @@ void b43_wireless_core_reset(struct b43_
- {
-       u32 macctl;
--      b43_ssb_wireless_core_reset(dev, gmode);
-+      switch (dev->dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+      case B43_BUS_BCMA:
-+              b43_bcma_wireless_core_reset(dev, gmode);
-+              break;
-+#endif
-+#ifdef CONFIG_B43_SSB
-+      case B43_BUS_SSB:
-+              b43_ssb_wireless_core_reset(dev, gmode);
-+              break;
-+#endif
-+      }
-       /* Turn Analog ON, but only if we already know the PHY-type.
-        * This protects against very early setup where we don't know the
-@@ -1921,7 +1967,7 @@ static irqreturn_t b43_do_interrupt(stru
-               return IRQ_NONE;
-       reason &= dev->irq_mask;
-       if (!reason)
--              return IRQ_HANDLED;
-+              return IRQ_NONE;
-       dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON)
-           & 0x0001DC00;
-@@ -2116,21 +2162,43 @@ static int b43_try_request_fw(struct b43
-       u32 tmshigh;
-       int err;
-+      /* Files for HT and LCN were found by trying one by one */
-+
-       /* Get microcode */
--      if ((rev >= 5) && (rev <= 10))
-+      if ((rev >= 5) && (rev <= 10)) {
-               filename = "ucode5";
--      else if ((rev >= 11) && (rev <= 12))
-+      } else if ((rev >= 11) && (rev <= 12)) {
-               filename = "ucode11";
--      else if (rev == 13)
-+      } else if (rev == 13) {
-               filename = "ucode13";
--      else if (rev == 14)
-+      } else if (rev == 14) {
-               filename = "ucode14";
--      else if (rev == 15)
-+      } else if (rev == 15) {
-               filename = "ucode15";
--      else if ((rev >= 16) && (rev <= 20))
--              filename = "ucode16_mimo";
--      else
--              goto err_no_ucode;
-+      } else {
-+              switch (dev->phy.type) {
-+              case B43_PHYTYPE_N:
-+                      if (rev >= 16)
-+                              filename = "ucode16_mimo";
-+                      else
-+                              goto err_no_ucode;
-+                      break;
-+              case B43_PHYTYPE_HT:
-+                      if (rev == 29)
-+                              filename = "ucode29_mimo";
-+                      else
-+                              goto err_no_ucode;
-+                      break;
-+              case B43_PHYTYPE_LCN:
-+                      if (rev == 24)
-+                              filename = "ucode24_mimo";
-+                      else
-+                              goto err_no_ucode;
-+                      break;
-+              default:
-+                      goto err_no_ucode;
-+              }
-+      }
-       err = b43_do_request_fw(ctx, filename, &fw->ucode);
-       if (err)
-               goto err_load;
-@@ -2189,6 +2257,18 @@ static int b43_try_request_fw(struct b43
-               else
-                       goto err_no_initvals;
-               break;
-+      case B43_PHYTYPE_HT:
-+              if (rev == 29)
-+                      filename = "ht0initvals29";
-+              else
-+                      goto err_no_initvals;
-+              break;
-+      case B43_PHYTYPE_LCN:
-+              if (rev == 24)
-+                      filename = "lcn0initvals24";
-+              else
-+                      goto err_no_initvals;
-+              break;
-       default:
-               goto err_no_initvals;
-       }
-@@ -2236,6 +2316,18 @@ static int b43_try_request_fw(struct b43
-               else
-                       goto err_no_initvals;
-               break;
-+      case B43_PHYTYPE_HT:
-+              if (rev == 29)
-+                      filename = "ht0bsinitvals29";
-+              else
-+                      goto err_no_initvals;
-+              break;
-+      case B43_PHYTYPE_LCN:
-+              if (rev == 24)
-+                      filename = "lcn0bsinitvals24";
-+              else
-+                      goto err_no_initvals;
-+              break;
-       default:
-               goto err_no_initvals;
-       }
-@@ -2607,11 +2699,24 @@ static int b43_gpio_init(struct b43_wlde
-       if (dev->dev->core_rev >= 2)
-               mask |= 0x0010; /* FIXME: This is redundant. */
--      gpiodev = b43_ssb_gpio_dev(dev);
--      if (gpiodev)
--              ssb_write32(gpiodev, B43_GPIO_CONTROL,
--                          (ssb_read32(gpiodev, B43_GPIO_CONTROL)
--                           & mask) | set);
-+      switch (dev->dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+      case B43_BUS_BCMA:
-+              bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL,
-+                              (bcma_cc_read32(&dev->dev->bdev->bus->drv_cc,
-+                                      BCMA_CC_GPIOCTL) & mask) | set);
-+              break;
-+#endif
-+#ifdef CONFIG_B43_SSB
-+      case B43_BUS_SSB:
-+              gpiodev = b43_ssb_gpio_dev(dev);
-+              if (gpiodev)
-+                      ssb_write32(gpiodev, B43_GPIO_CONTROL,
-+                                  (ssb_read32(gpiodev, B43_GPIO_CONTROL)
-+                                  & mask) | set);
-+              break;
-+#endif
-+      }
-       return 0;
- }
-@@ -2621,9 +2726,21 @@ static void b43_gpio_cleanup(struct b43_
- {
-       struct ssb_device *gpiodev;
--      gpiodev = b43_ssb_gpio_dev(dev);
--      if (gpiodev)
--              ssb_write32(gpiodev, B43_GPIO_CONTROL, 0);
-+      switch (dev->dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+      case B43_BUS_BCMA:
-+              bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL,
-+                              0);
-+              break;
-+#endif
-+#ifdef CONFIG_B43_SSB
-+      case B43_BUS_SSB:
-+              gpiodev = b43_ssb_gpio_dev(dev);
-+              if (gpiodev)
-+                      ssb_write32(gpiodev, B43_GPIO_CONTROL, 0);
-+              break;
-+#endif
-+      }
- }
- /* http://bcm-specs.sipsolutions.net/EnableMac */
-@@ -2695,12 +2812,30 @@ out:
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
- void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
- {
--      u32 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
--      if (on)
--              tmslow |= B43_TMSLOW_MACPHYCLKEN;
--      else
--              tmslow &= ~B43_TMSLOW_MACPHYCLKEN;
--      ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
-+      u32 tmp;
-+
-+      switch (dev->dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+      case B43_BUS_BCMA:
-+              tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
-+              if (on)
-+                      tmp |= B43_BCMA_IOCTL_MACPHYCLKEN;
-+              else
-+                      tmp &= ~B43_BCMA_IOCTL_MACPHYCLKEN;
-+              bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
-+              break;
-+#endif
-+#ifdef CONFIG_B43_SSB
-+      case B43_BUS_SSB:
-+              tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
-+              if (on)
-+                      tmp |= B43_TMSLOW_MACPHYCLKEN;
-+              else
-+                      tmp &= ~B43_TMSLOW_MACPHYCLKEN;
-+              ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
-+              break;
-+#endif
-+      }
- }
- static void b43_adjust_opmode(struct b43_wldev *dev)
-@@ -2939,8 +3074,20 @@ static int b43_chip_init(struct b43_wlde
-       b43_mac_phy_clock_set(dev, true);
--      b43_write16(dev, B43_MMIO_POWERUP_DELAY,
--                  dev->sdev->bus->chipco.fast_pwrup_delay);
-+      switch (dev->dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+      case B43_BUS_BCMA:
-+              /* FIXME: 0xE74 is quite common, but should be read from CC */
-+              b43_write16(dev, B43_MMIO_POWERUP_DELAY, 0xE74);
-+              break;
-+#endif
-+#ifdef CONFIG_B43_SSB
-+      case B43_BUS_SSB:
-+              b43_write16(dev, B43_MMIO_POWERUP_DELAY,
-+                          dev->dev->sdev->bus->chipco.fast_pwrup_delay);
-+              break;
-+#endif
-+      }
-       err = 0;
-       b43dbg(dev->wl, "Chip initialized\n");
-@@ -3456,21 +3603,33 @@ static void b43_op_set_tsf(struct ieee80
- static void b43_put_phy_into_reset(struct b43_wldev *dev)
- {
--      struct ssb_device *sdev = dev->sdev;
--      u32 tmslow;
-+      u32 tmp;
--      tmslow = ssb_read32(sdev, SSB_TMSLOW);
--      tmslow &= ~B43_TMSLOW_GMODE;
--      tmslow |= B43_TMSLOW_PHYRESET;
--      tmslow |= SSB_TMSLOW_FGC;
--      ssb_write32(sdev, SSB_TMSLOW, tmslow);
--      msleep(1);
-+      switch (dev->dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+      case B43_BUS_BCMA:
-+              b43err(dev->wl,
-+                     "Putting PHY into reset not supported on BCMA\n");
-+              break;
-+#endif
-+#ifdef CONFIG_B43_SSB
-+      case B43_BUS_SSB:
-+              tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
-+              tmp &= ~B43_TMSLOW_GMODE;
-+              tmp |= B43_TMSLOW_PHYRESET;
-+              tmp |= SSB_TMSLOW_FGC;
-+              ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
-+              msleep(1);
-+
-+              tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
-+              tmp &= ~SSB_TMSLOW_FGC;
-+              tmp |= B43_TMSLOW_PHYRESET;
-+              ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
-+              msleep(1);
--      tmslow = ssb_read32(sdev, SSB_TMSLOW);
--      tmslow &= ~SSB_TMSLOW_FGC;
--      tmslow |= B43_TMSLOW_PHYRESET;
--      ssb_write32(sdev, SSB_TMSLOW, tmslow);
--      msleep(1);
-+              break;
-+#endif
-+      }
- }
- static const char *band_to_string(enum ieee80211_band band)
-@@ -4100,6 +4259,12 @@ static int b43_phy_versioning(struct b43
-                       unsupported = 1;
-               break;
- #endif
-+#ifdef CONFIG_B43_PHY_LCN
-+      case B43_PHYTYPE_LCN:
-+              if (phy_rev > 1)
-+                      unsupported = 1;
-+              break;
-+#endif
-       default:
-               unsupported = 1;
-       };
-@@ -4113,22 +4278,42 @@ static int b43_phy_versioning(struct b43
-              analog_type, phy_type, phy_rev);
-       /* Get RADIO versioning */
--      if (dev->dev->chip_id == 0x4317) {
--              if (dev->dev->chip_rev == 0)
--                      tmp = 0x3205017F;
--              else if (dev->dev->chip_rev == 1)
--                      tmp = 0x4205017F;
--              else
--                      tmp = 0x5205017F;
-+      if (dev->dev->core_rev >= 24) {
-+              u16 radio24[3];
-+
-+              for (tmp = 0; tmp < 3; tmp++) {
-+                      b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
-+                      radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
-+              }
-+
-+              /* Broadcom uses "id" for our "ver" and has separated "ver" */
-+              /* radio_ver = (radio24[0] & 0xF0) >> 4; */
-+
-+              radio_manuf = 0x17F;
-+              radio_ver = (radio24[2] << 8) | radio24[1];
-+              radio_rev = (radio24[0] & 0xF);
-       } else {
--              b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID);
--              tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
--              b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID);
--              tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16;
--      }
--      radio_manuf = (tmp & 0x00000FFF);
--      radio_ver = (tmp & 0x0FFFF000) >> 12;
--      radio_rev = (tmp & 0xF0000000) >> 28;
-+              if (dev->dev->chip_id == 0x4317) {
-+                      if (dev->dev->chip_rev == 0)
-+                              tmp = 0x3205017F;
-+                      else if (dev->dev->chip_rev == 1)
-+                              tmp = 0x4205017F;
-+                      else
-+                              tmp = 0x5205017F;
-+              } else {
-+                      b43_write16(dev, B43_MMIO_RADIO_CONTROL,
-+                                  B43_RADIOCTL_ID);
-+                      tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
-+                      b43_write16(dev, B43_MMIO_RADIO_CONTROL,
-+                                  B43_RADIOCTL_ID);
-+                      tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH)
-+                              << 16;
-+              }
-+              radio_manuf = (tmp & 0x00000FFF);
-+              radio_ver = (tmp & 0x0FFFF000) >> 12;
-+              radio_rev = (tmp & 0xF0000000) >> 28;
-+      }
-+
-       if (radio_manuf != 0x17F /* Broadcom */)
-               unsupported = 1;
-       switch (phy_type) {
-@@ -4160,6 +4345,10 @@ static int b43_phy_versioning(struct b43
-               if (radio_ver != 0x2059)
-                       unsupported = 1;
-               break;
-+      case B43_PHYTYPE_LCN:
-+              if (radio_ver != 0x2064)
-+                      unsupported = 1;
-+              break;
-       default:
-               B43_WARN_ON(1);
-       }
-@@ -4343,7 +4532,6 @@ static void b43_wireless_core_exit(struc
- /* Initialize a wireless core */
- static int b43_wireless_core_init(struct b43_wldev *dev)
- {
--      struct ssb_bus *bus = dev->sdev->bus;
-       struct ssb_sprom *sprom = dev->dev->bus_sprom;
-       struct b43_phy *phy = &dev->phy;
-       int err;
-@@ -4362,7 +4550,20 @@ static int b43_wireless_core_init(struct
-       phy->ops->prepare_structs(dev);
-       /* Enable IRQ routing to this device. */
--      ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->sdev);
-+      switch (dev->dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+      case B43_BUS_BCMA:
-+              bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci,
-+                                    dev->dev->bdev, true);
-+              break;
-+#endif
-+#ifdef CONFIG_B43_SSB
-+      case B43_BUS_SSB:
-+              ssb_pcicore_dev_irqvecs_enable(&dev->dev->sdev->bus->pcicore,
-+                                             dev->dev->sdev);
-+              break;
-+#endif
-+      }
-       b43_imcfglo_timeouts_workaround(dev);
-       b43_bluetooth_coext_disable(dev);
-@@ -4393,8 +4594,9 @@ static int b43_wireless_core_init(struct
-       if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
-               hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
- #ifdef CONFIG_SSB_DRIVER_PCICORE
--      if ((bus->bustype == SSB_BUSTYPE_PCI) &&
--          (bus->pcicore.dev->id.revision <= 10))
-+      if (dev->dev->bus_type == B43_BUS_SSB &&
-+          dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
-+          dev->dev->sdev->bus->pcicore.dev->id.revision <= 10)
-               hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */
- #endif
-       hf &= ~B43_HF_SKCFPUP;
-@@ -4764,9 +4966,9 @@ static void b43_wireless_core_detach(str
- static int b43_wireless_core_attach(struct b43_wldev *dev)
- {
-       struct b43_wl *wl = dev->wl;
--      struct ssb_bus *bus = dev->sdev->bus;
--      struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL;
-+      struct pci_dev *pdev = NULL;
-       int err;
-+      u32 tmp;
-       bool have_2ghz_phy = 0, have_5ghz_phy = 0;
-       /* Do NOT do any device initialization here.
-@@ -4776,20 +4978,38 @@ static int b43_wireless_core_attach(stru
-        * that in core_init(), too.
-        */
-+#ifdef CONFIG_B43_SSB
-+      if (dev->dev->bus_type == B43_BUS_SSB &&
-+          dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI)
-+              pdev = dev->dev->sdev->bus->host_pci;
-+#endif
-+
-       err = b43_bus_powerup(dev, 0);
-       if (err) {
-               b43err(wl, "Bus powerup failed\n");
-               goto out;
-       }
--      /* Get the PHY type. */
--      if (dev->dev->core_rev >= 5) {
--              u32 tmshigh;
--              tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
--              have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY);
--              have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY);
--      } else
--              B43_WARN_ON(1);
-+      /* Get the PHY type. */
-+      switch (dev->dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+      case B43_BUS_BCMA:
-+              tmp = bcma_aread32(dev->dev->bdev, BCMA_IOST);
-+              have_2ghz_phy = !!(tmp & B43_BCMA_IOST_2G_PHY);
-+              have_5ghz_phy = !!(tmp & B43_BCMA_IOST_5G_PHY);
-+              break;
-+#endif
-+#ifdef CONFIG_B43_SSB
-+      case B43_BUS_SSB:
-+              if (dev->dev->core_rev >= 5) {
-+                      tmp = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
-+                      have_2ghz_phy = !!(tmp & B43_TMSHIGH_HAVE_2GHZ_PHY);
-+                      have_5ghz_phy = !!(tmp & B43_TMSHIGH_HAVE_5GHZ_PHY);
-+              } else
-+                      B43_WARN_ON(1);
-+              break;
-+#endif
-+      }
-       dev->phy.gmode = have_2ghz_phy;
-       dev->phy.radio_on = 1;
-@@ -4815,6 +5035,8 @@ static int b43_wireless_core_attach(stru
- #endif
-               case B43_PHYTYPE_G:
-               case B43_PHYTYPE_N:
-+              case B43_PHYTYPE_HT:
-+              case B43_PHYTYPE_LCN:
-                       have_2ghz_phy = 1;
-                       break;
-               default:
-@@ -4877,13 +5099,13 @@ static void b43_one_core_detach(struct b
-       /* Do not cancel ieee80211-workqueue based work here.
-        * See comment in b43_remove(). */
--      wldev = ssb_get_drvdata(dev->sdev);
-+      wldev = b43_bus_get_wldev(dev);
-       wl = wldev->wl;
-       b43_debugfs_remove_device(wldev);
-       b43_wireless_core_detach(wldev);
-       list_del(&wldev->list);
-       wl->nr_devs--;
--      ssb_set_drvdata(dev->sdev, NULL);
-+      b43_bus_set_wldev(dev, NULL);
-       kfree(wldev);
- }
-@@ -4898,7 +5120,6 @@ static int b43_one_core_attach(struct b4
-       wldev->use_pio = b43_modparam_pio;
-       wldev->dev = dev;
--      wldev->sdev = dev->sdev; /* TODO: Remove when not needed */
-       wldev->wl = wl;
-       b43_set_status(wldev, B43_STAT_UNINIT);
-       wldev->bad_frames_preempt = modparam_bad_frames_preempt;
-@@ -4910,7 +5131,7 @@ static int b43_one_core_attach(struct b4
-       list_add(&wldev->list, &wl->devlist);
-       wl->nr_devs++;
--      ssb_set_drvdata(dev->sdev, wldev);
-+      b43_bus_set_wldev(dev, wldev);
-       b43_debugfs_add_device(wldev);
-       out:
-@@ -4959,11 +5180,12 @@ static void b43_wireless_exit(struct b43
-       ieee80211_free_hw(hw);
- }
--static struct b43_wl *b43_wireless_init(struct ssb_device *dev)
-+static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)
- {
--      struct ssb_sprom *sprom = &dev->bus->sprom;
-+      struct ssb_sprom *sprom = dev->bus_sprom;
-       struct ieee80211_hw *hw;
-       struct b43_wl *wl;
-+      char chip_name[6];
-       hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops);
-       if (!hw) {
-@@ -5002,21 +5224,70 @@ static struct b43_wl *b43_wireless_init(
-       INIT_WORK(&wl->tx_work, b43_tx_work);
-       skb_queue_head_init(&wl->tx_queue);
--      b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
--              dev->bus->chip_id, dev->id.revision);
-+      snprintf(chip_name, ARRAY_SIZE(chip_name),
-+               (dev->chip_id > 0x9999) ? "%d" : "%04X", dev->chip_id);
-+      b43info(wl, "Broadcom %s WLAN found (core revision %u)\n", chip_name,
-+              dev->core_rev);
-       return wl;
- }
- #ifdef CONFIG_B43_BCMA
- static int b43_bcma_probe(struct bcma_device *core)
- {
--      b43err(NULL, "BCMA is not supported yet!");
--      return -EOPNOTSUPP;
-+      struct b43_bus_dev *dev;
-+      struct b43_wl *wl;
-+      int err;
-+
-+      dev = b43_bus_dev_bcma_init(core);
-+      if (!dev)
-+              return -ENODEV;
-+
-+      wl = b43_wireless_init(dev);
-+      if (IS_ERR(wl)) {
-+              err = PTR_ERR(wl);
-+              goto bcma_out;
-+      }
-+
-+      err = b43_one_core_attach(dev, wl);
-+      if (err)
-+              goto bcma_err_wireless_exit;
-+
-+      err = ieee80211_register_hw(wl->hw);
-+      if (err)
-+              goto bcma_err_one_core_detach;
-+      b43_leds_register(wl->current_dev);
-+
-+bcma_out:
-+      return err;
-+
-+bcma_err_one_core_detach:
-+      b43_one_core_detach(dev);
-+bcma_err_wireless_exit:
-+      ieee80211_free_hw(wl->hw);
-+      return err;
- }
- static void b43_bcma_remove(struct bcma_device *core)
- {
--      /* TODO */
-+      struct b43_wldev *wldev = bcma_get_drvdata(core);
-+      struct b43_wl *wl = wldev->wl;
-+
-+      /* We must cancel any work here before unregistering from ieee80211,
-+       * as the ieee80211 unreg will destroy the workqueue. */
-+      cancel_work_sync(&wldev->restart_work);
-+
-+      /* Restore the queues count before unregistering, because firmware detect
-+       * might have modified it. Restoring is important, so the networking
-+       * stack can properly free resources. */
-+      wl->hw->queues = wl->mac80211_initially_registered_queues;
-+      b43_leds_stop(wldev);
-+      ieee80211_unregister_hw(wl->hw);
-+
-+      b43_one_core_detach(wldev->dev);
-+
-+      b43_leds_unregister(wl);
-+
-+      ieee80211_free_hw(wl->hw);
- }
- static struct bcma_driver b43_bcma_driver = {
-@@ -5045,7 +5316,7 @@ int b43_ssb_probe(struct ssb_device *sde
-               /* Probing the first core. Must setup common struct b43_wl */
-               first = 1;
-               b43_sprom_fixup(sdev->bus);
--              wl = b43_wireless_init(sdev);
-+              wl = b43_wireless_init(dev);
-               if (IS_ERR(wl)) {
-                       err = PTR_ERR(wl);
-                       goto out;
---- a/drivers/net/wireless/b43/phy_common.c
-+++ b/drivers/net/wireless/b43/phy_common.c
-@@ -32,6 +32,7 @@
- #include "phy_n.h"
- #include "phy_lp.h"
- #include "phy_ht.h"
-+#include "phy_lcn.h"
- #include "b43.h"
- #include "main.h"
-@@ -65,6 +66,11 @@ int b43_phy_allocate(struct b43_wldev *d
-               phy->ops = &b43_phyops_ht;
- #endif
-               break;
-+      case B43_PHYTYPE_LCN:
-+#ifdef CONFIG_B43_PHY_LCN
-+              phy->ops = &b43_phyops_lcn;
-+#endif
-+              break;
-       }
-       if (B43_WARN_ON(!phy->ops))
-               return -ENODEV;
---- a/drivers/net/wireless/b43/phy_common.h
-+++ b/drivers/net/wireless/b43/phy_common.h
-@@ -198,6 +198,7 @@ struct b43_phy_g;
- struct b43_phy_n;
- struct b43_phy_lp;
- struct b43_phy_ht;
-+struct b43_phy_lcn;
- struct b43_phy {
-       /* Hardware operation callbacks. */
-@@ -222,6 +223,8 @@ struct b43_phy {
-               struct b43_phy_lp *lp;
-               /* HT-PHY specific information */
-               struct b43_phy_ht *ht;
-+              /* LCN-PHY specific information */
-+              struct b43_phy_lcn *lcn;
-       };
-       /* Band support flags. */
---- a/drivers/net/wireless/b43/phy_ht.c
-+++ b/drivers/net/wireless/b43/phy_ht.c
-@@ -24,9 +24,14 @@
- #include "b43.h"
- #include "phy_ht.h"
-+#include "tables_phy_ht.h"
- #include "radio_2059.h"
- #include "main.h"
-+/**************************************************
-+ * Radio 2059.
-+ **************************************************/
-+
- static void b43_radio_2059_channel_setup(struct b43_wldev *dev,
-                       const struct b43_phy_ht_channeltab_e_radio2059 *e)
- {
-@@ -56,7 +61,7 @@ static void b43_radio_2059_channel_setup
-       b43_radio_write(dev, 0x98, e->radio_syn98);
-       for (i = 0; i < 2; i++) {
--              routing = i ? 0x800 : 0x400;
-+              routing = i ? R2059_RXRX1 : R2059_TXRX0;
-               b43_radio_write(dev, routing | 0x4a, e->radio_rxtx4a);
-               b43_radio_write(dev, routing | 0x58, e->radio_rxtx58);
-               b43_radio_write(dev, routing | 0x5a, e->radio_rxtx5a);
-@@ -78,11 +83,120 @@ static void b43_radio_2059_channel_setup
-       udelay(300);
- }
-+static void b43_radio_2059_init(struct b43_wldev *dev)
-+{
-+      const u16 routing[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1 };
-+      const u16 radio_values[3][2] = {
-+              { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 },
-+      };
-+      u16 i, j;
-+
-+      b43_radio_write(dev, R2059_ALL | 0x51, 0x0070);
-+      b43_radio_write(dev, R2059_ALL | 0x5a, 0x0003);
-+
-+      for (i = 0; i < ARRAY_SIZE(routing); i++)
-+              b43_radio_set(dev, routing[i] | 0x146, 0x3);
-+
-+      b43_radio_set(dev, 0x2e, 0x0078);
-+      b43_radio_set(dev, 0xc0, 0x0080);
-+      msleep(2);
-+      b43_radio_mask(dev, 0x2e, ~0x0078);
-+      b43_radio_mask(dev, 0xc0, ~0x0080);
-+
-+      if (1) { /* FIXME */
-+              b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x1);
-+              udelay(10);
-+              b43_radio_set(dev, R2059_RXRX1 | 0x0BF, 0x1);
-+              b43_radio_maskset(dev, R2059_RXRX1 | 0x19B, 0x3, 0x2);
-+
-+              b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x2);
-+              udelay(100);
-+              b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x2);
-+
-+              for (i = 0; i < 10000; i++) {
-+                      if (b43_radio_read(dev, R2059_RXRX1 | 0x145) & 1) {
-+                              i = 0;
-+                              break;
-+                      }
-+                      udelay(100);
-+              }
-+              if (i)
-+                      b43err(dev->wl, "radio 0x945 timeout\n");
-+
-+              b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x1);
-+              b43_radio_set(dev, 0xa, 0x60);
-+
-+              for (i = 0; i < 3; i++) {
-+                      b43_radio_write(dev, 0x17F, radio_values[i][0]);
-+                      b43_radio_write(dev, 0x13D, 0x6E);
-+                      b43_radio_write(dev, 0x13E, radio_values[i][1]);
-+                      b43_radio_write(dev, 0x13C, 0x55);
-+
-+                      for (j = 0; j < 10000; j++) {
-+                              if (b43_radio_read(dev, 0x140) & 2) {
-+                                      j = 0;
-+                                      break;
-+                              }
-+                              udelay(500);
-+                      }
-+                      if (j)
-+                              b43err(dev->wl, "radio 0x140 timeout\n");
-+
-+                      b43_radio_write(dev, 0x13C, 0x15);
-+              }
-+
-+              b43_radio_mask(dev, 0x17F, ~0x1);
-+      }
-+
-+      b43_radio_mask(dev, 0x11, ~0x0008);
-+}
-+
-+/**************************************************
-+ * Channel switching ops.
-+ **************************************************/
-+
- static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
-                               const struct b43_phy_ht_channeltab_e_phy *e,
-                               struct ieee80211_channel *new_channel)
- {
--      /* TODO */
-+      bool old_band_5ghz;
-+      u8 i;
-+
-+      old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */
-+      if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
-+              /* TODO */
-+      } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
-+              /* TODO */
-+      }
-+
-+      b43_phy_write(dev, B43_PHY_HT_BW1, e->bw1);
-+      b43_phy_write(dev, B43_PHY_HT_BW2, e->bw2);
-+      b43_phy_write(dev, B43_PHY_HT_BW3, e->bw3);
-+      b43_phy_write(dev, B43_PHY_HT_BW4, e->bw4);
-+      b43_phy_write(dev, B43_PHY_HT_BW5, e->bw5);
-+      b43_phy_write(dev, B43_PHY_HT_BW6, e->bw6);
-+
-+      /* TODO: some ops on PHY regs 0x0B0 and 0xC0A */
-+
-+      /* TODO: separated function? */
-+      for (i = 0; i < 3; i++) {
-+              u16 mask;
-+              u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8));
-+
-+              if (0) /* FIXME */
-+                      mask = 0x2 << (i * 4);
-+              else
-+                      mask = 0;
-+              b43_phy_mask(dev, B43_PHY_EXTG(0x108), mask);
-+
-+              b43_httab_write(dev, B43_HTTAB16(7, 0x110 + i), tmp >> 16);
-+              b43_httab_write(dev, B43_HTTAB8(13, 0x63 + (i * 4)),
-+                              tmp & 0xFF);
-+              b43_httab_write(dev, B43_HTTAB8(13, 0x73 + (i * 4)),
-+                              tmp & 0xFF);
-+      }
-+
-+      b43_phy_write(dev, 0x017e, 0x3830);
- }
- static int b43_phy_ht_set_channel(struct b43_wldev *dev,
-@@ -139,6 +253,13 @@ static void b43_phy_ht_op_prepare_struct
-       memset(phy_ht, 0, sizeof(*phy_ht));
- }
-+static int b43_phy_ht_op_init(struct b43_wldev *dev)
-+{
-+      b43_phy_ht_tables_init(dev);
-+
-+      return 0;
-+}
-+
- static void b43_phy_ht_op_free(struct b43_wldev *dev)
- {
-       struct b43_phy *phy = &dev->phy;
-@@ -155,13 +276,25 @@ static void b43_phy_ht_op_software_rfkil
-       if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
-               b43err(dev->wl, "MAC not suspended\n");
-+      /* In the following PHY ops we copy wl's dummy behaviour.
-+       * TODO: Find out if reads (currently hidden in masks/masksets) are
-+       * needed and replace following ops with just writes or w&r.
-+       * Note: B43_PHY_HT_RF_CTL1 register is tricky, wrong operation can
-+       * cause delayed (!) machine lock up. */
-       if (blocked) {
--              b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0);
-+              b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0);
-       } else {
--              b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0);
--              b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x1);
--              b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0);
--              b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x2);
-+              b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0);
-+              b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, 0, 0x1);
-+              b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0);
-+              b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, 0, 0x2);
-+
-+              if (dev->phy.radio_ver == 0x2059)
-+                      b43_radio_2059_init(dev);
-+              else
-+                      B43_WARN_ON(1);
-+
-+              b43_switch_channel(dev, dev->phy.channel);
-       }
- }
-@@ -203,7 +336,7 @@ static int b43_phy_ht_op_switch_channel(
- static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev)
- {
-       if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
--              return 1;
-+              return 11;
-       return 36;
- }
-@@ -247,6 +380,16 @@ static void b43_phy_ht_op_radio_write(st
-       b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
- }
-+static enum b43_txpwr_result
-+b43_phy_ht_op_recalc_txpower(struct b43_wldev *dev, bool ignore_tssi)
-+{
-+      return B43_TXPWR_RES_DONE;
-+}
-+
-+static void b43_phy_ht_op_adjust_txpower(struct b43_wldev *dev)
-+{
-+}
-+
- /**************************************************
-  * PHY ops struct.
-  **************************************************/
-@@ -255,9 +398,7 @@ const struct b43_phy_operations b43_phyo
-       .allocate               = b43_phy_ht_op_allocate,
-       .free                   = b43_phy_ht_op_free,
-       .prepare_structs        = b43_phy_ht_op_prepare_structs,
--      /*
-       .init                   = b43_phy_ht_op_init,
--      */
-       .phy_read               = b43_phy_ht_op_read,
-       .phy_write              = b43_phy_ht_op_write,
-       .phy_maskset            = b43_phy_ht_op_maskset,
-@@ -267,8 +408,6 @@ const struct b43_phy_operations b43_phyo
-       .switch_analog          = b43_phy_ht_op_switch_analog,
-       .switch_channel         = b43_phy_ht_op_switch_channel,
-       .get_default_chan       = b43_phy_ht_op_get_default_chan,
--      /*
-       .recalc_txpower         = b43_phy_ht_op_recalc_txpower,
-       .adjust_txpower         = b43_phy_ht_op_adjust_txpower,
--      */
- };
---- a/drivers/net/wireless/b43/phy_ht.h
-+++ b/drivers/net/wireless/b43/phy_ht.h
-@@ -4,9 +4,16 @@
- #include "phy_common.h"
-+#define B43_PHY_HT_BANDCTL                    0x009 /* Band control */
- #define B43_PHY_HT_TABLE_ADDR                 0x072 /* Table address */
- #define B43_PHY_HT_TABLE_DATALO                       0x073 /* Table data low */
- #define B43_PHY_HT_TABLE_DATAHI                       0x074 /* Table data high */
-+#define B43_PHY_HT_BW1                                0x1CE
-+#define B43_PHY_HT_BW2                                0x1CF
-+#define B43_PHY_HT_BW3                                0x1D0
-+#define B43_PHY_HT_BW4                                0x1D1
-+#define B43_PHY_HT_BW5                                0x1D2
-+#define B43_PHY_HT_BW6                                0x1D3
- #define B43_PHY_HT_RF_CTL1                    B43_PHY_EXTG(0x010)
-@@ -20,7 +27,12 @@
- /* Values for PHY registers used on channel switching */
- struct b43_phy_ht_channeltab_e_phy {
--      /* TODO */
-+      u16 bw1;
-+      u16 bw2;
-+      u16 bw3;
-+      u16 bw4;
-+      u16 bw5;
-+      u16 bw6;
- };
---- /dev/null
-+++ b/drivers/net/wireless/b43/phy_lcn.c
-@@ -0,0 +1,52 @@
-+/*
-+
-+  Broadcom B43 wireless driver
-+  IEEE 802.11n LCN-PHY support
-+
-+  This program is free software; you can redistribute it and/or modify
-+  it under the terms of the GNU General Public License as published by
-+  the Free Software Foundation; either version 2 of the License, or
-+  (at your option) any later version.
-+
-+  This program is distributed in the hope that it will be useful,
-+  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+  GNU General Public License for more details.
-+
-+  You should have received a copy of the GNU General Public License
-+  along with this program; see the file COPYING.  If not, write to
-+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
-+  Boston, MA 02110-1301, USA.
-+
-+*/
-+
-+#include <linux/slab.h>
-+
-+#include "b43.h"
-+#include "phy_lcn.h"
-+#include "tables_phy_lcn.h"
-+#include "main.h"
-+
-+/**************************************************
-+ * PHY ops struct.
-+ **************************************************/
-+
-+const struct b43_phy_operations b43_phyops_lcn = {
-+      /*
-+      .allocate               = b43_phy_lcn_op_allocate,
-+      .free                   = b43_phy_lcn_op_free,
-+      .prepare_structs        = b43_phy_lcn_op_prepare_structs,
-+      .init                   = b43_phy_lcn_op_init,
-+      .phy_read               = b43_phy_lcn_op_read,
-+      .phy_write              = b43_phy_lcn_op_write,
-+      .phy_maskset            = b43_phy_lcn_op_maskset,
-+      .radio_read             = b43_phy_lcn_op_radio_read,
-+      .radio_write            = b43_phy_lcn_op_radio_write,
-+      .software_rfkill        = b43_phy_lcn_op_software_rfkill,
-+      .switch_analog          = b43_phy_lcn_op_switch_analog,
-+      .switch_channel         = b43_phy_lcn_op_switch_channel,
-+      .get_default_chan       = b43_phy_lcn_op_get_default_chan,
-+      .recalc_txpower         = b43_phy_lcn_op_recalc_txpower,
-+      .adjust_txpower         = b43_phy_lcn_op_adjust_txpower,
-+      */
-+};
---- /dev/null
-+++ b/drivers/net/wireless/b43/phy_lcn.h
-@@ -0,0 +1,14 @@
-+#ifndef B43_PHY_LCN_H_
-+#define B43_PHY_LCN_H_
-+
-+#include "phy_common.h"
-+
-+
-+struct b43_phy_lcn {
-+};
-+
-+
-+struct b43_phy_operations;
-+extern const struct b43_phy_operations b43_phyops_lcn;
-+
-+#endif /* B43_PHY_LCN_H_ */
-\ No newline at end of file
---- a/drivers/net/wireless/b43/phy_n.c
-+++ b/drivers/net/wireless/b43/phy_n.c
-@@ -603,17 +603,33 @@ static void b43_nphy_tx_lp_fbw(struct b4
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
- static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force)
- {
--      u32 tmslow;
-+      u32 tmp;
-       if (dev->phy.type != B43_PHYTYPE_N)
-               return;
--      tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
--      if (force)
--              tmslow |= SSB_TMSLOW_FGC;
--      else
--              tmslow &= ~SSB_TMSLOW_FGC;
--      ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
-+      switch (dev->dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+      case B43_BUS_BCMA:
-+              tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
-+              if (force)
-+                      tmp |= BCMA_IOCTL_FGC;
-+              else
-+                      tmp &= ~BCMA_IOCTL_FGC;
-+              bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
-+              break;
-+#endif
-+#ifdef CONFIG_B43_SSB
-+      case B43_BUS_SSB:
-+              tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
-+              if (force)
-+                      tmp |= SSB_TMSLOW_FGC;
-+              else
-+                      tmp &= ~SSB_TMSLOW_FGC;
-+              ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
-+              break;
-+#endif
-+      }
- }
- /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
-@@ -958,8 +974,21 @@ static void b43_nphy_superswitch_init(st
-               b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0);
-               b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0);
--              ssb_chipco_gpio_control(&dev->sdev->bus->chipco, 0xFC00,
--                                      0xFC00);
-+              switch (dev->dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+              case B43_BUS_BCMA:
-+                      bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc,
-+                                               0xFC00, 0xFC00);
-+                      break;
-+#endif
-+#ifdef CONFIG_B43_SSB
-+              case B43_BUS_SSB:
-+                      ssb_chipco_gpio_control(&dev->dev->sdev->bus->chipco,
-+                                              0xFC00, 0xFC00);
-+                      break;
-+#endif
-+              }
-+
-               b43_write32(dev, B43_MMIO_MACCTL,
-                       b43_read32(dev, B43_MMIO_MACCTL) &
-                       ~B43_MACCTL_GPOUTSMSK);
-@@ -3600,7 +3629,20 @@ int b43_phy_initn(struct b43_wldev *dev)
-       if ((dev->phy.rev >= 3) &&
-          (sprom->boardflags_lo & B43_BFL_EXTLNA) &&
-          (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) {
--              chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40);
-+              switch (dev->dev->bus_type) {
-+#ifdef CONFIG_B43_BCMA
-+              case B43_BUS_BCMA:
-+                      bcma_cc_set32(&dev->dev->bdev->bus->drv_cc,
-+                                    BCMA_CC_CHIPCTL, 0x40);
-+                      break;
-+#endif
-+#ifdef CONFIG_B43_SSB
-+              case B43_BUS_SSB:
-+                      chipco_set32(&dev->dev->sdev->bus->chipco,
-+                                   SSB_CHIPCO_CHIPCTL, 0x40);
-+                      break;
-+#endif
-+              }
-       }
-       nphy->deaf_count = 0;
-       b43_nphy_tables_init(dev);
---- a/drivers/net/wireless/b43/radio_2059.c
-+++ b/drivers/net/wireless/b43/radio_2059.c
-@@ -23,8 +23,152 @@
- #include "b43.h"
- #include "radio_2059.h"
-+#define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
-+                r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
-+                r20, r21, r22, r23, r24, r25, r26, r27, r28) \
-+      .radio_syn16                    = r00,  \
-+      .radio_syn17                    = r01,  \
-+      .radio_syn22                    = r02,  \
-+      .radio_syn25                    = r03,  \
-+      .radio_syn27                    = r04,  \
-+      .radio_syn28                    = r05,  \
-+      .radio_syn29                    = r06,  \
-+      .radio_syn2c                    = r07,  \
-+      .radio_syn2d                    = r08,  \
-+      .radio_syn37                    = r09,  \
-+      .radio_syn41                    = r10,  \
-+      .radio_syn43                    = r11,  \
-+      .radio_syn47                    = r12,  \
-+      .radio_syn4a                    = r13,  \
-+      .radio_syn58                    = r14,  \
-+      .radio_syn5a                    = r15,  \
-+      .radio_syn6a                    = r16,  \
-+      .radio_syn6d                    = r17,  \
-+      .radio_syn6e                    = r18,  \
-+      .radio_syn92                    = r19,  \
-+      .radio_syn98                    = r20,  \
-+      .radio_rxtx4a                   = r21,  \
-+      .radio_rxtx58                   = r22,  \
-+      .radio_rxtx5a                   = r23,  \
-+      .radio_rxtx6a                   = r24,  \
-+      .radio_rxtx6d                   = r25,  \
-+      .radio_rxtx6e                   = r26,  \
-+      .radio_rxtx92                   = r27,  \
-+      .radio_rxtx98                   = r28
-+
-+#define PHYREGS(r0, r1, r2, r3, r4, r5)       \
-+      .phy_regs.bw1   = r0,   \
-+      .phy_regs.bw2   = r1,   \
-+      .phy_regs.bw3   = r2,   \
-+      .phy_regs.bw4   = r3,   \
-+      .phy_regs.bw5   = r4,   \
-+      .phy_regs.bw6   = r5
-+
-+static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radio2059[] = {
-+  {   .freq                   = 2412,
-+      RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
-+                0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
-+  },
-+  {   .freq                   = 2417,
-+      RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
-+                0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
-+  },
-+  {   .freq                   = 2422,
-+      RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
-+                0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
-+  },
-+  {   .freq                   = 2427,
-+      RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
-+                0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
-+  },
-+  {   .freq                   = 2432,
-+      RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
-+                0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
-+  },
-+  {   .freq                   = 2437,
-+      RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
-+                0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
-+  },
-+  {   .freq                   = 2442,
-+      RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
-+                0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
-+  },
-+  {   .freq                   = 2447,
-+      RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
-+                0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
-+  },
-+  {   .freq                   = 2452,
-+      RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
-+                0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
-+  },
-+  {   .freq                   = 2457,
-+      RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
-+                0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
-+  },
-+  {   .freq                   = 2462,
-+      RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
-+                0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
-+  },
-+  {   .freq                   = 2467,
-+      RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
-+                0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
-+  },
-+  {   .freq                   = 2472,
-+      RADIOREGS(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
-+                0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
-+                0x00, 0x00, 0x00, 0xf0, 0x00),
-+      PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
-+  },
-+};
-+
- const struct b43_phy_ht_channeltab_e_radio2059
- *b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq)
- {
-+      const struct b43_phy_ht_channeltab_e_radio2059 *e;
-+      unsigned int i;
-+
-+      e = b43_phy_ht_channeltab_radio2059;
-+      for (i = 0; i < ARRAY_SIZE(b43_phy_ht_channeltab_radio2059); i++, e++) {
-+              if (e->freq == freq)
-+                      return e;
-+      }
-+
-       return NULL;
- }
---- a/drivers/net/wireless/b43/radio_2059.h
-+++ b/drivers/net/wireless/b43/radio_2059.h
-@@ -5,6 +5,11 @@
- #include "phy_ht.h"
-+#define R2059_SYN                     0x000
-+#define R2059_TXRX0                   0x400
-+#define R2059_RXRX1                   0x800
-+#define R2059_ALL                     0xC00
-+
- /* Values for various registers uploaded on channel switching */
- struct b43_phy_ht_channeltab_e_radio2059 {
-       /* The channel frequency in MHz */
---- /dev/null
-+++ b/drivers/net/wireless/b43/tables_phy_ht.c
-@@ -0,0 +1,750 @@
-+/*
-+
-+  Broadcom B43 wireless driver
-+  IEEE 802.11n HT-PHY data tables
-+
-+  This program is free software; you can redistribute it and/or modify
-+  it under the terms of the GNU General Public License as published by
-+  the Free Software Foundation; either version 2 of the License, or
-+  (at your option) any later version.
-+
-+  This program is distributed in the hope that it will be useful,
-+  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+  GNU General Public License for more details.
-+
-+  You should have received a copy of the GNU General Public License
-+  along with this program; see the file COPYING.  If not, write to
-+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
-+  Boston, MA 02110-1301, USA.
-+
-+*/
-+
-+#include "b43.h"
-+#include "tables_phy_ht.h"
-+#include "phy_common.h"
-+#include "phy_ht.h"
-+
-+static const u16 b43_httab_0x12[] = {
-+      0x0000, 0x0008, 0x000a, 0x0010, 0x0012, 0x0019,
-+      0x001a, 0x001c, 0x0080, 0x0088, 0x008a, 0x0090,
-+      0x0092, 0x0099, 0x009a, 0x009c, 0x0100, 0x0108,
-+      0x010a, 0x0110, 0x0112, 0x0119, 0x011a, 0x011c,
-+      0x0180, 0x0188, 0x018a, 0x0190, 0x0192, 0x0199,
-+      0x019a, 0x019c, 0x0000, 0x0098, 0x00a0, 0x00a8,
-+      0x009a, 0x00a2, 0x00aa, 0x0120, 0x0128, 0x0128,
-+      0x0130, 0x0138, 0x0138, 0x0140, 0x0122, 0x012a,
-+      0x012a, 0x0132, 0x013a, 0x013a, 0x0142, 0x01a8,
-+      0x01b0, 0x01b8, 0x01b0, 0x01b8, 0x01c0, 0x01c8,
-+      0x01c0, 0x01c8, 0x01d0, 0x01d0, 0x01d8, 0x01aa,
-+      0x01b2, 0x01ba, 0x01b2, 0x01ba, 0x01c2, 0x01ca,
-+      0x01c2, 0x01ca, 0x01d2, 0x01d2, 0x01da, 0x0001,
-+      0x0002, 0x0004, 0x0009, 0x000c, 0x0011, 0x0014,
-+      0x0018, 0x0020, 0x0021, 0x0022, 0x0024, 0x0081,
-+      0x0082, 0x0084, 0x0089, 0x008c, 0x0091, 0x0094,
-+      0x0098, 0x00a0, 0x00a1, 0x00a2, 0x00a4, 0x0007,
-+      0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007,
-+      0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007,
-+      0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007,
-+      0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007,
-+      0x0007, 0x0007,
-+};
-+
-+static const u16 b43_httab_0x27[] = {
-+      0x0009, 0x000e, 0x0011, 0x0014, 0x0017, 0x001a,
-+      0x001d, 0x0020, 0x0009, 0x000e, 0x0011, 0x0014,
-+      0x0017, 0x001a, 0x001d, 0x0020, 0x0009, 0x000e,
-+      0x0011, 0x0014, 0x0017, 0x001a, 0x001d, 0x0020,
-+      0x0009, 0x000e, 0x0011, 0x0014, 0x0017, 0x001a,
-+      0x001d, 0x0020,
-+};
-+
-+static const u16 b43_httab_0x26[] = {
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-+      0x0000, 0x0000,
-+};
-+
-+static const u32 b43_httab_0x25[] = {
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+      0x00000000, 0x00000000, 0x00000000, 0x00000000,
-+};
-+
-+static const u32 b43_httab_0x2f[] = {
-+      0x00035700, 0x0002cc9a, 0x00026666, 0x0001581f,
-+      0x0001581f, 0x0001581f, 0x0001581f, 0x0001581f,
-+      0x0001581f, 0x0001581f, 0x0001581f, 0x00035700,
-+      0x0002cc9a, 0x00026666, 0x0001581f, 0x0001581f,
-+      0x0001581f, 0x0001581f, 0x0001581f, 0x0001581f,
-+      0x0001581f, 0x0001581f,
-+};
-+
-+static const u16 b43_httab_0x1a[] = {
-+      0x0055, 0x0054, 0x0054, 0x0053, 0x0052, 0x0052,
-+      0x0051, 0x0051, 0x0050, 0x004f, 0x004f, 0x004e,
-+      0x004e, 0x004d, 0x004c, 0x004c, 0x004b, 0x004a,
-+      0x0049, 0x0049, 0x0048, 0x0047, 0x0046, 0x0046,
-+      0x0045, 0x0044, 0x0043, 0x0042, 0x0041, 0x0040,
-+      0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003a,
-+      0x0039, 0x0038, 0x0037, 0x0036, 0x0035, 0x0033,
-+      0x0032, 0x0031, 0x002f, 0x002e, 0x002c, 0x002b,
-+      0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f,
-+      0x001d, 0x001a, 0x0018, 0x0015, 0x0012, 0x000e,
-+      0x000b, 0x0007, 0x0002, 0x00fd,
-+};
-+
-+static const u16 b43_httab_0x1b[] = {
-+      0x0055, 0x0054, 0x0054, 0x0053, 0x0052, 0x0052,
-+      0x0051, 0x0051, 0x0050, 0x004f, 0x004f, 0x004e,
-+      0x004e, 0x004d, 0x004c, 0x004c, 0x004b, 0x004a,
-+      0x0049, 0x0049, 0x0048, 0x0047, 0x0046, 0x0046,
-+      0x0045, 0x0044, 0x0043, 0x0042, 0x0041, 0x0040,
-+      0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003a,
-+      0x0039, 0x0038, 0x0037, 0x0036, 0x0035, 0x0033,
-+      0x0032, 0x0031, 0x002f, 0x002e, 0x002c, 0x002b,
-+      0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f,
-+      0x001d, 0x001a, 0x0018, 0x0015, 0x0012, 0x000e,
-+      0x000b, 0x0007, 0x0002, 0x00fd,
-+};
-+
-+static const u16 b43_httab_0x1c[] = {
-+      0x0055, 0x0054, 0x0054, 0x0053, 0x0052, 0x0052,
-+      0x0051, 0x0051, 0x0050, 0x004f, 0x004f, 0x004e,
-+      0x004e, 0x004d, 0x004c, 0x004c, 0x004b, 0x004a,
-+      0x0049, 0x0049, 0x0048, 0x0047, 0x0046, 0x0046,
-+      0x0045, 0x0044, 0x0043, 0x0042, 0x0041, 0x0040,
-+      0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003a,
-+      0x0039, 0x0038, 0x0037, 0x0036, 0x0035, 0x0033,
-+      0x0032, 0x0031, 0x002f, 0x002e, 0x002c, 0x002b,
-+      0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f,
-+      0x001d, 0x001a, 0x0018, 0x0015, 0x0012, 0x000e,
-+      0x000b, 0x0007, 0x0002, 0x00fd,
-+};
-+
-+static const u32 b43_httab_0x1a_0xc0[] = {
-+      0x5bf70044, 0x5bf70042, 0x5bf70040, 0x5bf7003e,
-+      0x5bf7003c, 0x5bf7003b, 0x5bf70039, 0x5bf70037,
-+      0x5bf70036, 0x5bf70034, 0x5bf70033, 0x5bf70031,
-+      0x5bf70030, 0x5ba70044, 0x5ba70042, 0x5ba70040,
-+      0x5ba7003e, 0x5ba7003c, 0x5ba7003b, 0x5ba70039,
-+      0x5ba70037, 0x5ba70036, 0x5ba70034, 0x5ba70033,
-+      0x5b770044, 0x5b770042, 0x5b770040, 0x5b77003e,
-+      0x5b77003c, 0x5b77003b, 0x5b770039, 0x5b770037,
-+      0x5b770036, 0x5b770034, 0x5b770033, 0x5b770031,
-+      0x5b770030, 0x5b77002f, 0x5b77002d, 0x5b77002c,
-+      0x5b470044, 0x5b470042, 0x5b470040, 0x5b47003e,
-+      0x5b47003c, 0x5b47003b, 0x5b470039, 0x5b470037,
-+      0x5b470036, 0x5b470034, 0x5b470033, 0x5b470031,
-+      0x5b470030, 0x5b47002f, 0x5b47002d, 0x5b47002c,
-+      0x5b47002b, 0x5b47002a, 0x5b270044, 0x5b270042,
-+      0x5b270040, 0x5b27003e, 0x5b27003c, 0x5b27003b,
-+      0x5b270039, 0x5b270037, 0x5b270036, 0x5b270034,
-+      0x5b270033, 0x5b270031, 0x5b270030, 0x5b27002f,
-+      0x5b170044, 0x5b170042, 0x5b170040, 0x5b17003e,
-+      0x5b17003c, 0x5b17003b, 0x5b170039, 0x5b170037,
-+      0x5b170036, 0x5b170034, 0x5b170033, 0x5b170031,
-+      0x5b170030, 0x5b17002f, 0x5b17002d, 0x5b17002c,
-+      0x5b17002b, 0x5b17002a, 0x5b170028, 0x5b170027,
-+      0x5b170026, 0x5b170025, 0x5b170024, 0x5b170023,
-+      0x5b070044, 0x5b070042, 0x5b070040, 0x5b07003e,
-+  &n