diff options
author | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-10-05 10:12:53 +0000 |
---|---|---|
committer | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-10-05 10:12:53 +0000 |
commit | 5c105d9f3fd086aff195d3849dcf847d6b0bd927 (patch) | |
tree | 1229a11f725bfa58aa7c57a76898553bb5f6654a /package/mac80211/patches | |
download | openwrt-5c105d9f3fd086aff195d3849dcf847d6b0bd927.tar.gz openwrt-5c105d9f3fd086aff195d3849dcf847d6b0bd927.zip |
branch Attitude Adjustment
git-svn-id: svn://svn.openwrt.org/openwrt/branches/attitude_adjustment@33625 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/mac80211/patches')
91 files changed, 5916 insertions, 0 deletions
diff --git a/package/mac80211/patches/000-disable_ethernet.patch b/package/mac80211/patches/000-disable_ethernet.patch new file mode 100644 index 000000000..08f908b10 --- /dev/null +++ b/package/mac80211/patches/000-disable_ethernet.patch @@ -0,0 +1,12 @@ +--- a/Makefile ++++ b/Makefile +@@ -45,9 +45,6 @@ obj-$(CONFIG_COMPAT_WIRELESS_MODULES) += + + obj-$(CONFIG_COMPAT_NET_USB_MODULES) += drivers/net/usb/ + +-obj-$(CONFIG_COMPAT_NETWORK_MODULES) += drivers/net/ethernet/atheros/ +-obj-$(CONFIG_COMPAT_NETWORK_MODULES) += drivers/net/ethernet/broadcom/ +- + obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/ssb/ + obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/bcma/ + obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/misc/eeprom/ diff --git a/package/mac80211/patches/001-disable_b44.patch b/package/mac80211/patches/001-disable_b44.patch new file mode 100644 index 000000000..389dac1ae --- /dev/null +++ b/package/mac80211/patches/001-disable_b44.patch @@ -0,0 +1,13 @@ +--- a/config.mk ++++ b/config.mk +@@ -377,8 +377,8 @@ export CONFIG_B43_BCMA_EXTRA=y + + export CONFIG_P54_PCI=m + +-export CONFIG_B44=m +-export CONFIG_B44_PCI=y ++# export CONFIG_B44=m ++# export CONFIG_B44_PCI=y + + export CONFIG_RTL8180=m + diff --git a/package/mac80211/patches/002-disable_rfkill.patch b/package/mac80211/patches/002-disable_rfkill.patch new file mode 100644 index 000000000..685006bd5 --- /dev/null +++ b/package/mac80211/patches/002-disable_rfkill.patch @@ -0,0 +1,38 @@ +--- a/config.mk ++++ b/config.mk +@@ -78,7 +78,7 @@ endif # build check + endif # kernel Makefile check + + # These both are needed by 802.11 and bluetooth so enable +- export CONFIG_COMPAT_RFKILL=y ++# export CONFIG_COMPAT_RFKILL=y + + 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") +@@ -690,10 +690,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 +-export CONFIG_RFKILL_BACKPORT=m ++#export CONFIG_RFKILL_BACKPORT=m + ifdef CONFIG_LEDS_TRIGGERS +-export CONFIG_RFKILL_BACKPORT_LEDS=y ++#export CONFIG_RFKILL_BACKPORT_LEDS=y + endif #CONFIG_LEDS_TRIGGERS +-export CONFIG_RFKILL_BACKPORT_INPUT=y ++#export CONFIG_RFKILL_BACKPORT_INPUT=y + endif #CONFIG_COMPAT_KERNEL_2_6_31 + +--- a/include/linux/rfkill.h ++++ b/include/linux/rfkill.h +@@ -3,6 +3,10 @@ + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) + ++#undef CONFIG_RFKILL ++#undef CONFIG_RFKILL_LEDS ++#undef CONFIG_RFKILL_MODULE ++ + #include_next <linux/rfkill.h> + + #else diff --git a/package/mac80211/patches/003-disable_bt.patch b/package/mac80211/patches/003-disable_bt.patch new file mode 100644 index 000000000..b56ccbdc6 --- /dev/null +++ b/package/mac80211/patches/003-disable_bt.patch @@ -0,0 +1,15 @@ +--- a/config.mk ++++ b/config.mk +@@ -100,9 +100,9 @@ ifndef CONFIG_COMPAT_KERNEL_2_6_27 + ifeq ($(CONFIG_BT),y) + # we'll ignore compiling bluetooth + else +- export CONFIG_COMPAT_BLUETOOTH=y +- export CONFIG_COMPAT_BLUETOOTH_MODULES=m +- export CONFIG_HID_GENERIC=m ++# export CONFIG_COMPAT_BLUETOOTH=y ++# export CONFIG_COMPAT_BLUETOOTH_MODULES=m ++# export CONFIG_HID_GENERIC=m + endif + endif #CONFIG_COMPAT_KERNEL_2_6_27 + diff --git a/package/mac80211/patches/005-disable_ssb_build.patch b/package/mac80211/patches/005-disable_ssb_build.patch new file mode 100644 index 000000000..d42a6121d --- /dev/null +++ b/package/mac80211/patches/005-disable_ssb_build.patch @@ -0,0 +1,49 @@ +--- a/Makefile ++++ b/Makefile +@@ -45,7 +45,6 @@ obj-$(CONFIG_COMPAT_WIRELESS_MODULES) += + + obj-$(CONFIG_COMPAT_NET_USB_MODULES) += drivers/net/usb/ + +-obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/ssb/ + obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/bcma/ + obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/misc/eeprom/ + +--- a/config.mk ++++ b/config.mk +@@ -3,7 +3,7 @@ ifeq ($(wildcard $(KLIB_BUILD)/.config), + export CONFIG_PCI=y + export CONFIG_USB=y + export CONFIG_PCMCIA=y +- export CONFIG_SSB=m ++# export CONFIG_SSB=m + else + include $(KLIB_BUILD)/.config + endif +@@ -353,7 +353,8 @@ export CONFIG_IPW2200_QOS=y + # % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface + endif #CONFIG_WIRELESS_EXT + +-ifdef CONFIG_SSB ++# disabled ++ifdef __CONFIG_SSB + # Sonics Silicon Backplane + export CONFIG_SSB_SPROM=y + +@@ -366,7 +367,7 @@ endif #CONFIG_PCMCIA + # export CONFIG_SSB_DEBUG=y + export CONFIG_SSB_DRIVER_PCICORE=y + export CONFIG_B43_SSB=y +-endif #CONFIG_SSB ++endif #__CONFIG_SSB + + export CONFIG_BCMA=m + export CONFIG_BCMA_BLOCKIO=y +@@ -580,7 +581,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv + + ifdef CONFIG_MMC + +-export CONFIG_SSB_SDIOHOST=y ++# export CONFIG_SSB_SDIOHOST=y + export CONFIG_B43_SDIO=y + + ifdef CONFIG_CRC7 diff --git a/package/mac80211/patches/006-disable_bcma_build.patch b/package/mac80211/patches/006-disable_bcma_build.patch new file mode 100644 index 000000000..da11ad455 --- /dev/null +++ b/package/mac80211/patches/006-disable_bcma_build.patch @@ -0,0 +1,30 @@ +--- a/Makefile ++++ b/Makefile +@@ -45,7 +45,6 @@ obj-$(CONFIG_COMPAT_WIRELESS_MODULES) += + + obj-$(CONFIG_COMPAT_NET_USB_MODULES) += drivers/net/usb/ + +-obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/bcma/ + obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/misc/eeprom/ + + ifeq ($(CONFIG_STAGING_EXCLUDE_BUILD),) +--- a/config.mk ++++ b/config.mk +@@ -369,12 +369,12 @@ export CONFIG_SSB_DRIVER_PCICORE=y + export CONFIG_B43_SSB=y + endif #__CONFIG_SSB + +-export CONFIG_BCMA=m +-export CONFIG_BCMA_BLOCKIO=y +-export CONFIG_BCMA_HOST_PCI=y ++# export CONFIG_BCMA=m ++# export CONFIG_BCMA_BLOCKIO=y ++# export CONFIG_BCMA_HOST_PCI=y + # export CONFIG_BCMA_DEBUG=y +-export CONFIG_B43_BCMA=y +-export CONFIG_B43_BCMA_EXTRA=y ++# export CONFIG_B43_BCMA=y ++# export CONFIG_B43_BCMA_EXTRA=y + + export CONFIG_P54_PCI=m + diff --git a/package/mac80211/patches/007-remove_misc_drivers.patch b/package/mac80211/patches/007-remove_misc_drivers.patch new file mode 100644 index 000000000..9e7f65166 --- /dev/null +++ b/package/mac80211/patches/007-remove_misc_drivers.patch @@ -0,0 +1,61 @@ +--- a/config.mk ++++ b/config.mk +@@ -241,7 +241,7 @@ $(warning "WARNING: CONFIG_CFG80211_WEXT + endif #CONFIG_WIRELESS_EXT + + ifdef CONFIG_STAGING +-export CONFIG_COMPAT_STAGING=m ++# export CONFIG_COMPAT_STAGING=m + endif #CONFIG_STAGING + + # mac80211 test driver +@@ -406,12 +406,12 @@ endif #CONFIG_CRC_ITU_T + export CONFIG_MWL8K=m + + # Ethernet drivers go here +-export CONFIG_ATL1=m +-export CONFIG_ATL2=m +-export CONFIG_ATL1E=m ++# export CONFIG_ATL1=m ++# export CONFIG_ATL2=m ++# export CONFIG_ATL1E=m + ifndef CONFIG_COMPAT_KERNEL_2_6_28 +-export CONFIG_ATL1C=m +-export CONFIG_ALX=m ++# export CONFIG_ATL1C=m ++# export CONFIG_ALX=m + endif #CONFIG_COMPAT_KERNEL_2_6_28 + + ifdef CONFIG_WIRELESS_EXT +@@ -472,21 +472,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 +-export CONFIG_USB_COMPAT_USBNET=n +-export CONFIG_USB_NET_COMPAT_RNDIS_HOST=n +-export CONFIG_USB_NET_COMPAT_RNDIS_WLAN=n +-export CONFIG_USB_NET_COMPAT_CDCETHER=n ++# export CONFIG_USB_COMPAT_USBNET=n ++# export CONFIG_USB_NET_COMPAT_RNDIS_HOST=n ++# export CONFIG_USB_NET_COMPAT_RNDIS_WLAN=n ++# export CONFIG_USB_NET_COMPAT_CDCETHER=n + else #CONFIG_COMPAT_KERNEL_2_6_29 +-export CONFIG_USB_COMPAT_USBNET=m ++# export CONFIG_USB_COMPAT_USBNET=m + ifdef CONFIG_USB_NET_CDCETHER +-export CONFIG_USB_NET_COMPAT_RNDIS_HOST=m +-export CONFIG_USB_NET_COMPAT_RNDIS_WLAN=m ++# export CONFIG_USB_NET_COMPAT_RNDIS_HOST=m ++# export CONFIG_USB_NET_COMPAT_RNDIS_WLAN=m + endif #CONFIG_USB_NET_CDCETHER + ifdef CONFIG_USB_NET_CDCETHER_MODULE +-export CONFIG_USB_NET_COMPAT_RNDIS_HOST=m +-export CONFIG_USB_NET_COMPAT_RNDIS_WLAN=m ++# export CONFIG_USB_NET_COMPAT_RNDIS_HOST=m ++# export CONFIG_USB_NET_COMPAT_RNDIS_WLAN=m + endif #CONFIG_USB_NET_CDCETHER +-export CONFIG_USB_NET_COMPAT_CDCETHER=m ++# export CONFIG_USB_NET_COMPAT_CDCETHER=m + endif #CONFIG_COMPAT_KERNEL_2_6_29 + + diff --git a/package/mac80211/patches/008-disable_mesh.patch b/package/mac80211/patches/008-disable_mesh.patch new file mode 100644 index 000000000..d5a0ac8e6 --- /dev/null +++ b/package/mac80211/patches/008-disable_mesh.patch @@ -0,0 +1,11 @@ +--- a/config.mk ++++ b/config.mk +@@ -177,7 +177,7 @@ export CONFIG_MAC80211_LEDS=y + endif #CONFIG_LEDS_TRIGGERS + + # enable mesh networking too +-export CONFIG_MAC80211_MESH=y ++# export CONFIG_MAC80211_MESH=y + + export CONFIG_CFG80211=m + export CONFIG_CFG80211_DEFAULT_PS=y diff --git a/package/mac80211/patches/009-remove_mac80211_module_dependence.patch b/package/mac80211/patches/009-remove_mac80211_module_dependence.patch new file mode 100644 index 000000000..2bc46c4ed --- /dev/null +++ b/package/mac80211/patches/009-remove_mac80211_module_dependence.patch @@ -0,0 +1,11 @@ +--- a/config.mk ++++ b/config.mk +@@ -54,7 +54,7 @@ endif + ifeq ($(KERNEL_VERSION),2) + ifeq ($(shell test $(KERNEL_VERSION) -eq 2 -a $(KERNEL_26SUBLEVEL) -ge 27 -a $(KERNEL_26SUBLEVEL) -le 31 && echo yes),yes) + ifeq ($(CONFIG_MAC80211),) +-$(error "ERROR: Your >=2.6.27 and <= 2.6.31 kernel has CONFIG_MAC80211 disabled, you should have it CONFIG_MAC80211=m if you want to use this thing.") ++# $(error "ERROR: Your >=2.6.27 and <= 2.6.31 kernel has CONFIG_MAC80211 disabled, you should have it CONFIG_MAC80211=m if you want to use this thing.") + endif + endif + endif diff --git a/package/mac80211/patches/010-no_pcmcia.patch b/package/mac80211/patches/010-no_pcmcia.patch new file mode 100644 index 000000000..af6a7545b --- /dev/null +++ b/package/mac80211/patches/010-no_pcmcia.patch @@ -0,0 +1,20 @@ +--- a/config.mk ++++ b/config.mk +@@ -2,7 +2,7 @@ ifeq ($(wildcard $(KLIB_BUILD)/.config), + # These will be ignored by compat autoconf + export CONFIG_PCI=y + export CONFIG_USB=y +- export CONFIG_PCMCIA=y ++# export CONFIG_PCMCIA=y + # export CONFIG_SSB=m + else + include $(KLIB_BUILD)/.config +@@ -304,7 +304,7 @@ export CONFIG_B43=m + export CONFIG_B43_HWRNG=y + export CONFIG_B43_PCI_AUTOSELECT=y + ifdef CONFIG_PCMCIA +-export CONFIG_B43_PCMCIA=y ++# export CONFIG_B43_PCMCIA=y + endif #CONFIG_PCMCIA + ifdef CONFIG_MAC80211_LEDS + export CONFIG_B43_LEDS=y diff --git a/package/mac80211/patches/011-no_sdio.patch b/package/mac80211/patches/011-no_sdio.patch new file mode 100644 index 000000000..4d364e045 --- /dev/null +++ b/package/mac80211/patches/011-no_sdio.patch @@ -0,0 +1,11 @@ +--- a/config.mk ++++ b/config.mk +@@ -582,7 +582,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv + ifdef CONFIG_MMC + + # export CONFIG_SSB_SDIOHOST=y +-export CONFIG_B43_SDIO=y ++# export CONFIG_B43_SDIO=y + + ifdef CONFIG_CRC7 + ifdef CONFIG_WL12XX_PLATFORM_DATA diff --git a/package/mac80211/patches/013-disable_b43_nphy.patch b/package/mac80211/patches/013-disable_b43_nphy.patch new file mode 100644 index 000000000..ba37bad95 --- /dev/null +++ b/package/mac80211/patches/013-disable_b43_nphy.patch @@ -0,0 +1,13 @@ +--- a/config.mk ++++ b/config.mk +@@ -310,8 +310,8 @@ ifdef CONFIG_MAC80211_LEDS + export CONFIG_B43_LEDS=y + endif #CONFIG_MAC80211_LEDS + export CONFIG_B43_PHY_LP=y +-export CONFIG_B43_PHY_N=y +-export CONFIG_B43_PHY_HT=y ++# export CONFIG_B43_PHY_N=y ++# export CONFIG_B43_PHY_HT=y + # export CONFIG_B43_PHY_LCN=y + # export CONFIG_B43_DEBUG=y + diff --git a/package/mac80211/patches/015-remove-rt2x00-options.patch b/package/mac80211/patches/015-remove-rt2x00-options.patch new file mode 100644 index 000000000..66c0d67a5 --- /dev/null +++ b/package/mac80211/patches/015-remove-rt2x00-options.patch @@ -0,0 +1,20 @@ +--- a/config.mk ++++ b/config.mk +@@ -385,7 +385,7 @@ export CONFIG_RTL8180=m + + export CONFIG_ADM8211=m + +-export CONFIG_RT2X00_LIB_PCI=m ++# export CONFIG_RT2X00_LIB_PCI=m + export CONFIG_RT2400PCI=m + export CONFIG_RT2500PCI=m + ifdef CONFIG_CRC_CCITT +@@ -528,7 +528,7 @@ export CONFIG_RT2800USB_RT35XX=y + export CONFIG_RT2800USB_RT53XX=y + export CONFIG_RT2800USB_UNKNOWN=y + endif #CONFIG_CRC_CCITT +-export CONFIG_RT2X00_LIB_USB=m ++# export CONFIG_RT2X00_LIB_USB=m + NEED_RT2X00=y + # RT73USB requires firmware + ifdef CONFIG_CRC_ITU_T diff --git a/package/mac80211/patches/016-remove_pid_algo.patch b/package/mac80211/patches/016-remove_pid_algo.patch new file mode 100644 index 000000000..7180a63ce --- /dev/null +++ b/package/mac80211/patches/016-remove_pid_algo.patch @@ -0,0 +1,11 @@ +--- a/config.mk ++++ b/config.mk +@@ -169,7 +169,7 @@ export CONFIG_MAC80211_RC_DEFAULT_MINSTR + # This is the one used by our compat-drivers net/mac80211/rate.c + # in case you have and old kernel which is overriding this to pid. + export CONFIG_COMPAT_MAC80211_RC_DEFAULT=minstrel_ht +-export CONFIG_MAC80211_RC_PID=y ++# export CONFIG_MAC80211_RC_PID=y + export CONFIG_MAC80211_RC_MINSTREL=y + export CONFIG_MAC80211_RC_MINSTREL_HT=y + ifdef CONFIG_LEDS_TRIGGERS diff --git a/package/mac80211/patches/017-remove_ath9k_rc.patch b/package/mac80211/patches/017-remove_ath9k_rc.patch new file mode 100644 index 000000000..99b520911 --- /dev/null +++ b/package/mac80211/patches/017-remove_ath9k_rc.patch @@ -0,0 +1,11 @@ +--- a/config.mk ++++ b/config.mk +@@ -265,7 +265,7 @@ export CONFIG_ATH9K_COMMON=m + # as default once we get minstrel properly tested and blessed by + # our systems engineering team. CCK rates also need to be used + # for long range considerations. +-export CONFIG_COMPAT_ATH9K_RATE_CONTROL=y ++# export CONFIG_COMPAT_ATH9K_RATE_CONTROL=y + + export CONFIG_ATH9K_BTCOEX_SUPPORT=y + diff --git a/package/mac80211/patches/018-revert_printk_va_format.patch b/package/mac80211/patches/018-revert_printk_va_format.patch new file mode 100644 index 000000000..fa2237c95 --- /dev/null +++ b/package/mac80211/patches/018-revert_printk_va_format.patch @@ -0,0 +1,188 @@ +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -341,83 +341,59 @@ static int b43_ratelimit(struct b43_wl * + + void b43info(struct b43_wl *wl, const char *fmt, ...) + { +- struct va_format vaf; + va_list args; + + if (b43_modparam_verbose < B43_VERBOSITY_INFO) + return; + if (!b43_ratelimit(wl)) + return; +- + va_start(args, fmt); +- +- vaf.fmt = fmt; +- vaf.va = &args; +- +- printk(KERN_INFO "b43-%s: %pV", +- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); +- ++ printk(KERN_INFO "b43-%s: ", ++ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); ++ vprintk(fmt, args); + va_end(args); + } + + void b43err(struct b43_wl *wl, const char *fmt, ...) + { +- struct va_format vaf; + va_list args; + + if (b43_modparam_verbose < B43_VERBOSITY_ERROR) + return; + if (!b43_ratelimit(wl)) + return; +- + va_start(args, fmt); +- +- vaf.fmt = fmt; +- vaf.va = &args; +- +- printk(KERN_ERR "b43-%s ERROR: %pV", +- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); +- ++ printk(KERN_ERR "b43-%s ERROR: ", ++ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); ++ vprintk(fmt, args); + va_end(args); + } + + void b43warn(struct b43_wl *wl, const char *fmt, ...) + { +- struct va_format vaf; + va_list args; + + if (b43_modparam_verbose < B43_VERBOSITY_WARN) + return; + if (!b43_ratelimit(wl)) + return; +- + va_start(args, fmt); +- +- vaf.fmt = fmt; +- vaf.va = &args; +- +- printk(KERN_WARNING "b43-%s warning: %pV", +- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); +- ++ printk(KERN_WARNING "b43-%s warning: ", ++ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); ++ vprintk(fmt, args); + va_end(args); + } + + void b43dbg(struct b43_wl *wl, const char *fmt, ...) + { +- struct va_format vaf; + va_list args; + + if (b43_modparam_verbose < B43_VERBOSITY_DEBUG) + return; +- + va_start(args, fmt); +- +- vaf.fmt = fmt; +- vaf.va = &args; +- +- printk(KERN_DEBUG "b43-%s debug: %pV", +- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); +- ++ printk(KERN_DEBUG "b43-%s debug: ", ++ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); ++ vprintk(fmt, args); + va_end(args); + } + +--- a/drivers/net/wireless/b43legacy/main.c ++++ b/drivers/net/wireless/b43legacy/main.c +@@ -179,75 +179,52 @@ static int b43legacy_ratelimit(struct b4 + + void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...) + { +- struct va_format vaf; + va_list args; + + if (!b43legacy_ratelimit(wl)) + return; +- + va_start(args, fmt); +- +- vaf.fmt = fmt; +- vaf.va = &args; +- +- printk(KERN_INFO "b43legacy-%s: %pV", +- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); +- ++ printk(KERN_INFO "b43legacy-%s: ", ++ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); ++ vprintk(fmt, args); + va_end(args); + } + + void b43legacyerr(struct b43legacy_wl *wl, const char *fmt, ...) + { +- struct va_format vaf; + va_list args; + + if (!b43legacy_ratelimit(wl)) + return; +- + va_start(args, fmt); +- +- vaf.fmt = fmt; +- vaf.va = &args; +- +- printk(KERN_ERR "b43legacy-%s ERROR: %pV", +- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); +- ++ printk(KERN_ERR "b43legacy-%s ERROR: ", ++ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); ++ vprintk(fmt, args); + va_end(args); + } + + void b43legacywarn(struct b43legacy_wl *wl, const char *fmt, ...) + { +- struct va_format vaf; + va_list args; + + if (!b43legacy_ratelimit(wl)) + return; +- + va_start(args, fmt); +- +- vaf.fmt = fmt; +- vaf.va = &args; +- +- printk(KERN_WARNING "b43legacy-%s warning: %pV", +- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); +- ++ printk(KERN_WARNING "b43legacy-%s warning: ", ++ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); ++ vprintk(fmt, args); + va_end(args); + } + + #if B43legacy_DEBUG + void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...) + { +- struct va_format vaf; + va_list args; + + va_start(args, fmt); +- +- vaf.fmt = fmt; +- vaf.va = &args; +- +- printk(KERN_DEBUG "b43legacy-%s debug: %pV", +- (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf); +- ++ printk(KERN_DEBUG "b43legacy-%s debug: ", ++ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); ++ vprintk(fmt, args); + va_end(args); + } + #endif /* DEBUG */ diff --git a/package/mac80211/patches/019-remove_ath5k_pci_option.patch b/package/mac80211/patches/019-remove_ath5k_pci_option.patch new file mode 100644 index 000000000..d0149d39c --- /dev/null +++ b/package/mac80211/patches/019-remove_ath5k_pci_option.patch @@ -0,0 +1,11 @@ +--- a/config.mk ++++ b/config.mk +@@ -282,7 +282,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27 + # PCI Drivers + ifdef CONFIG_PCI + +-export CONFIG_ATH5K_PCI=y ++# export CONFIG_ATH5K_PCI=y + export CONFIG_ATH9K_PCI=y + + export CONFIG_IWLWIFI=m diff --git a/package/mac80211/patches/021-add_include_for_bcma.patch b/package/mac80211/patches/021-add_include_for_bcma.patch new file mode 100644 index 000000000..e2e856eb0 --- /dev/null +++ b/package/mac80211/patches/021-add_include_for_bcma.patch @@ -0,0 +1,11 @@ +--- a/include/linux/compat-3.0.h ++++ b/include/linux/compat-3.0.h +@@ -36,6 +36,8 @@ static inline struct page *shmem_read_ma + #endif + + ++#include <linux/mod_devicetable.h> ++ + /* + * since commit 1c5cae815d19ffe02bdfda1260949ef2b1806171 + * "net: call dev_alloc_name from register_netdevice" dev_alloc_name is diff --git a/package/mac80211/patches/022-remove_crc8_and_cordic.patch b/package/mac80211/patches/022-remove_crc8_and_cordic.patch new file mode 100644 index 000000000..13ad2c895 --- /dev/null +++ b/package/mac80211/patches/022-remove_crc8_and_cordic.patch @@ -0,0 +1,166 @@ +--- a/compat/Makefile ++++ b/compat/Makefile +@@ -47,8 +47,6 @@ compat-$(CONFIG_COMPAT_KERNEL_3_3) += \ + compat-$(CONFIG_COMPAT_KERNEL_3_4) += compat-3.4.o + compat-$(CONFIG_COMPAT_KERNEL_3_7) += compat-3.7.o + +-compat-$(CONFIG_COMPAT_CORDIC) += cordic.o +-compat-$(CONFIG_COMPAT_CRC8) += crc8.o + + ifndef CONFIG_64BIT + ifndef CONFIG_GENERIC_ATOMIC64 +--- a/include/linux/cordic.h ++++ /dev/null +@@ -1,48 +0,0 @@ +-/* +- * Copyright (c) 2011 Broadcom Corporation +- * +- * Permission to use, copy, modify, and/or distribute this software for any +- * purpose with or without fee is hereby granted, provided that the above +- * copyright notice and this permission notice appear in all copies. +- * +- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +- */ +-#ifndef __CORDIC_H_ +-#define __CORDIC_H_ +- +-#include <linux/types.h> +- +-/** +- * struct cordic_iq - i/q coordinate. +- * +- * @i: real part of coordinate (in phase). +- * @q: imaginary part of coordinate (quadrature). +- */ +-struct cordic_iq { +- s32 i; +- s32 q; +-}; +- +-/** +- * cordic_calc_iq() - calculates the i/q coordinate for given angle. +- * +- * @theta: angle in degrees for which i/q coordinate is to be calculated. +- * @coord: function output parameter holding the i/q coordinate. +- * +- * The function calculates the i/q coordinate for a given angle using +- * cordic algorithm. The coordinate consists of a real (i) and an +- * imaginary (q) part. The real part is essentially the cosine of the +- * angle and the imaginary part is the sine of the angle. The returned +- * values are scaled by 2^16 for precision. The range for theta is +- * for -180 degrees to +180 degrees. Passed values outside this range are +- * converted before doing the actual calculation. +- */ +-struct cordic_iq cordic_calc_iq(s32 theta); +- +-#endif /* __CORDIC_H_ */ +--- a/include/linux/crc8.h ++++ /dev/null +@@ -1,101 +0,0 @@ +-/* +- * Copyright (c) 2011 Broadcom Corporation +- * +- * Permission to use, copy, modify, and/or distribute this software for any +- * purpose with or without fee is hereby granted, provided that the above +- * copyright notice and this permission notice appear in all copies. +- * +- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +- */ +-#ifndef __CRC8_H_ +-#define __CRC8_H_ +- +-#include <linux/types.h> +- +-/* see usage of this value in crc8() description */ +-#define CRC8_INIT_VALUE 0xFF +- +-/* +- * Return value of crc8() indicating valid message+crc. This is true +- * if a CRC is inverted before transmission. The CRC computed over the +- * whole received bitstream is _table[x], where x is the bit pattern +- * of the modification (almost always 0xff). +- */ +-#define CRC8_GOOD_VALUE(_table) (_table[0xFF]) +- +-/* required table size for crc8 algorithm */ +-#define CRC8_TABLE_SIZE 256 +- +-/* helper macro assuring right table size is used */ +-#define DECLARE_CRC8_TABLE(_table) \ +- static u8 _table[CRC8_TABLE_SIZE] +- +-/** +- * crc8_populate_lsb - fill crc table for given polynomial in regular bit order. +- * +- * @table: table to be filled. +- * @polynomial: polynomial for which table is to be filled. +- * +- * This function fills the provided table according the polynomial provided for +- * regular bit order (lsb first). Polynomials in CRC algorithms are typically +- * represented as shown below. +- * +- * poly = x^8 + x^7 + x^6 + x^4 + x^2 + 1 +- * +- * For lsb first direction x^7 maps to the lsb. So the polynomial is as below. +- * +- * - lsb first: poly = 10101011(1) = 0xAB +- */ +-void crc8_populate_lsb(u8 table[CRC8_TABLE_SIZE], u8 polynomial); +- +-/** +- * crc8_populate_msb - fill crc table for given polynomial in reverse bit order. +- * +- * @table: table to be filled. +- * @polynomial: polynomial for which table is to be filled. +- * +- * This function fills the provided table according the polynomial provided for +- * reverse bit order (msb first). Polynomials in CRC algorithms are typically +- * represented as shown below. +- * +- * poly = x^8 + x^7 + x^6 + x^4 + x^2 + 1 +- * +- * For msb first direction x^7 maps to the msb. So the polynomial is as below. +- * +- * - msb first: poly = (1)11010101 = 0xD5 +- */ +-void crc8_populate_msb(u8 table[CRC8_TABLE_SIZE], u8 polynomial); +- +-/** +- * crc8() - calculate a crc8 over the given input data. +- * +- * @table: crc table used for calculation. +- * @pdata: pointer to data buffer. +- * @nbytes: number of bytes in data buffer. +- * @crc: previous returned crc8 value. +- * +- * The CRC8 is calculated using the polynomial given in crc8_populate_msb() +- * or crc8_populate_lsb(). +- * +- * The caller provides the initial value (either %CRC8_INIT_VALUE +- * or the previous returned value) to allow for processing of +- * discontiguous blocks of data. When generating the CRC the +- * caller is responsible for complementing the final return value +- * and inserting it into the byte stream. When validating a byte +- * stream (including CRC8), a final return value of %CRC8_GOOD_VALUE +- * indicates the byte stream data can be considered valid. +- * +- * Reference: +- * "A Painless Guide to CRC Error Detection Algorithms", ver 3, Aug 1993 +- * Williams, Ross N., ross<at>ross.net +- * (see URL http://www.ross.net/crc/download/crc_v3.txt). +- */ +-u8 crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc); +- +-#endif /* __CRC8_H_ */ diff --git a/package/mac80211/patches/023-ath9k_disable_btcoex.patch b/package/mac80211/patches/023-ath9k_disable_btcoex.patch new file mode 100644 index 000000000..37ae2d5d7 --- /dev/null +++ b/package/mac80211/patches/023-ath9k_disable_btcoex.patch @@ -0,0 +1,11 @@ +--- a/config.mk ++++ b/config.mk +@@ -267,7 +267,7 @@ export CONFIG_ATH9K_COMMON=m + # for long range considerations. + # export CONFIG_COMPAT_ATH9K_RATE_CONTROL=y + +-export CONFIG_ATH9K_BTCOEX_SUPPORT=y ++# export CONFIG_ATH9K_BTCOEX_SUPPORT=y + + # WIL6210 requires MSI only available >= 2.6.30 + ifndef CONFIG_COMPAT_KERNEL_2_6_30 diff --git a/package/mac80211/patches/030-disable_tty_set_termios.patch b/package/mac80211/patches/030-disable_tty_set_termios.patch new file mode 100644 index 000000000..fc5d4d63f --- /dev/null +++ b/package/mac80211/patches/030-disable_tty_set_termios.patch @@ -0,0 +1,16 @@ +--- a/compat/compat-2.6.39.c ++++ b/compat/compat-2.6.39.c +@@ -12,6 +12,7 @@ + #include <linux/tty.h> + #include <linux/sched.h> + ++#ifdef CONFIG_COMPAT_BLUETOOTH + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) + /* + * Termios Helper Methods +@@ -111,4 +112,4 @@ int tty_set_termios(struct tty_struct *t + } + EXPORT_SYMBOL_GPL(tty_set_termios); + #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */ +- ++#endif diff --git a/package/mac80211/patches/050-compat_firmware.patch b/package/mac80211/patches/050-compat_firmware.patch new file mode 100644 index 000000000..e4b91a316 --- /dev/null +++ b/package/mac80211/patches/050-compat_firmware.patch @@ -0,0 +1,78 @@ +--- a/compat/Makefile ++++ b/compat/Makefile +@@ -1,7 +1,10 @@ + obj-m += compat.o + #compat-objs := + +-obj-$(CONFIG_COMPAT_FIRMWARE_CLASS) += compat_firmware_class.o ++ifdef CONFIG_COMPAT_FIRMWARE_CLASS ++ compat-y += compat_firmware_class.o ++endif ++ + obj-$(CONFIG_COMPAT_NET_SCH_CODEL) += sch_codel.o + + sch_fq_codel-y = sch_fq_codel_core.o flow_dissector.o +--- a/compat/compat_firmware_class.c ++++ b/compat/compat_firmware_class.c +@@ -741,19 +741,16 @@ compat_request_firmware_nowait( + return 0; + } + +-static int __init firmware_class_init(void) ++int __init firmware_class_init(void) + { + return class_register(&firmware_class); + } + +-static void __exit firmware_class_exit(void) ++void __exit firmware_class_exit(void) + { + class_unregister(&firmware_class); + } + +-fs_initcall(firmware_class_init); +-module_exit(firmware_class_exit); +- + EXPORT_SYMBOL_GPL(release_firmware); + EXPORT_SYMBOL_GPL(request_firmware); + EXPORT_SYMBOL_GPL(request_firmware_nowait); +--- a/compat/main.c ++++ b/compat/main.c +@@ -47,6 +47,17 @@ void compat_dependency_symbol(void) + EXPORT_SYMBOL_GPL(compat_dependency_symbol); + + ++#if defined(CONFIG_FW_LOADER) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) ++int __init firmware_class_init(void); ++void __exit firmware_class_exit(void); ++#else ++static inline int firmware_class_init(void) ++{ ++ return 0; ++} ++static inline void firmware_class_exit(void) {} ++#endif ++ + static int __init compat_init(void) + { + compat_pm_qos_power_init(); +@@ -63,7 +74,8 @@ static int __init compat_init(void) + printk(KERN_INFO "compat.git: " + COMPAT_BASE_TREE "\n"); + +- return 0; ++ firmware_class_init(); ++ return 0; + } + module_init(compat_init); + +@@ -72,7 +84,8 @@ static void __exit compat_exit(void) + compat_pm_qos_power_deinit(); + compat_system_workqueue_destroy(); + +- return; ++ firmware_class_exit(); ++ return; + } + module_exit(compat_exit); + diff --git a/package/mac80211/patches/060-compat_add_module_pci_driver.patch b/package/mac80211/patches/060-compat_add_module_pci_driver.patch new file mode 100644 index 000000000..277ca3d37 --- /dev/null +++ b/package/mac80211/patches/060-compat_add_module_pci_driver.patch @@ -0,0 +1,22 @@ +--- a/include/linux/compat-3.4.h ++++ b/include/linux/compat-3.4.h +@@ -112,6 +112,19 @@ static inline void eth_hw_addr_random(st + module_driver(__pci_driver, pci_register_driver, \ + pci_unregister_driver) + ++/* source include/linux/pci.h */ ++/** ++ * module_pci_driver() - Helper macro for registering a PCI driver ++ * @__pci_driver: pci_driver struct ++ * ++ * Helper macro for PCI drivers which do not do anything special in module ++ * init/exit. This eliminates a lot of boilerplate. Each module may only ++ * use this macro once, and calling it replaces module_init() and module_exit() ++ */ ++#define module_pci_driver(__pci_driver) \ ++ module_driver(__pci_driver, pci_register_driver, \ ++ pci_unregister_driver) ++ + #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) */ + + #endif /* LINUX_5_4_COMPAT_H */ diff --git a/package/mac80211/patches/070-disable_codel.patch b/package/mac80211/patches/070-disable_codel.patch new file mode 100644 index 000000000..0d6d74911 --- /dev/null +++ b/package/mac80211/patches/070-disable_codel.patch @@ -0,0 +1,19 @@ +--- a/compat/scripts/gen-compat-config.sh ++++ b/compat/scripts/gen-compat-config.sh +@@ -66,16 +66,3 @@ if [[ ${CONFIG_COMPAT_KERNEL_2_6_36} = " + echo "export CONFIG_COMPAT_KFIFO=y" + fi + fi +- +-if [[ ${CONFIG_COMPAT_KERNEL_3_5} = "y" ]]; then +- # We don't have 2.6.24 backport support yet for Codel / FQ CoDel +- # For those who want to try this is what is required that I can tell +- # so far: +- # * struct Qdisc_ops +- # - init and change callback ops use a different argument dataype +- # - you need to parse data received from userspace differently +- if [[ ${CONFIG_COMPAT_KERNEL_2_6_25} != "y" ]]; then +- echo "export CONFIG_COMPAT_NET_SCH_CODEL=m" +- echo "export CONFIG_COMPAT_NET_SCH_FQ_CODEL=m" +- fi +-fi diff --git a/package/mac80211/patches/071-add_codel_ifdef.patch b/package/mac80211/patches/071-add_codel_ifdef.patch new file mode 100644 index 000000000..86b415170 --- /dev/null +++ b/package/mac80211/patches/071-add_codel_ifdef.patch @@ -0,0 +1,19 @@ +--- a/include/linux/compat-3.5.h ++++ b/include/linux/compat-3.5.h +@@ -8,6 +8,8 @@ + + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + ++#ifndef TCA_CODEL_MAX ++ + /* + * This backports: + * +@@ -135,6 +137,7 @@ static inline int compat_vga_switcheroo_ + + #define SIZE_MAX (~(size_t)0) + ++#endif /* TCA_CODEL_MAX */ + + #include <linux/pkt_sched.h> + diff --git a/package/mac80211/patches/100-disable_pcmcia_compat.patch b/package/mac80211/patches/100-disable_pcmcia_compat.patch new file mode 100644 index 000000000..60927555b --- /dev/null +++ b/package/mac80211/patches/100-disable_pcmcia_compat.patch @@ -0,0 +1,65 @@ +--- a/compat/compat-2.6.28.c ++++ b/compat/compat-2.6.28.c +@@ -86,7 +86,7 @@ EXPORT_SYMBOL_GPL(usb_poison_urb); + #endif + #endif /* CONFIG_USB */ + +-#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++#if 0 + + #include <pcmcia/ds.h> + struct pcmcia_cfg_mem { +--- a/compat/compat-2.6.33.c ++++ b/compat/compat-2.6.33.c +@@ -10,7 +10,7 @@ + + #include <linux/compat.h> + +-#if defined(CONFIG_PCCARD) || defined(CONFIG_PCCARD_MODULE) ++#if 0 + + /** + * pccard_loop_tuple() - loop over tuples in the CIS +@@ -72,7 +72,7 @@ next_entry: + EXPORT_SYMBOL_GPL(pccard_loop_tuple); + /* Source: drivers/pcmcia/cistpl.c */ + +-#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++#if 0 + + struct pcmcia_loop_mem { + struct pcmcia_device *p_dev; +--- a/include/linux/compat-2.6.28.h ++++ b/include/linux/compat-2.6.28.h +@@ -49,7 +49,7 @@ typedef u32 phys_addr_t; + }) + #endif /* From include/asm-generic/bug.h */ + +-#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++#if 0 + + #include <pcmcia/cs_types.h> + #include <pcmcia/cs.h> +--- a/include/linux/compat-2.6.33.h ++++ b/include/linux/compat-2.6.33.h +@@ -7,7 +7,7 @@ + + #include <linux/skbuff.h> + #include <linux/pci.h> +-#if defined(CONFIG_PCCARD) || defined(CONFIG_PCCARD_MODULE) ++#if 0 + #include <pcmcia/cs_types.h> + #include <pcmcia/cistpl.h> + #include <pcmcia/ds.h> +@@ -82,9 +82,9 @@ static inline struct sk_buff *netdev_all + return skb; + } + +-#if defined(CONFIG_PCCARD) || defined(CONFIG_PCCARD_MODULE) ++#if 0 + +-#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++#if 0 + + #define pcmcia_request_window(a, b, c) pcmcia_request_window(&a, b, c) + diff --git a/package/mac80211/patches/110-disable_usb_compat.patch b/package/mac80211/patches/110-disable_usb_compat.patch new file mode 100644 index 000000000..d6287fd04 --- /dev/null +++ b/package/mac80211/patches/110-disable_usb_compat.patch @@ -0,0 +1,44 @@ +--- a/compat/compat-2.6.28.c ++++ b/compat/compat-2.6.28.c +@@ -165,7 +165,7 @@ EXPORT_SYMBOL_GPL(pcmcia_loop_config); + + #endif /* CONFIG_PCMCIA */ + +-#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE) ++#if 0 + + void usb_unpoison_urb(struct urb *urb) + { +--- a/compat/compat-2.6.29.c ++++ b/compat/compat-2.6.29.c +@@ -49,7 +49,7 @@ void netdev_attach_ops(struct net_device + EXPORT_SYMBOL_GPL(netdev_attach_ops); + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)) +-#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE) ++#if 0 + /** + * usb_unpoison_anchored_urbs - let an anchor be used successfully again + * @anchor: anchor the requests are bound to +--- a/include/linux/compat-2.6.28.h ++++ b/include/linux/compat-2.6.28.h +@@ -74,7 +74,7 @@ int pcmcia_loop_config(struct pcmcia_dev + /* USB anchors were added as of 2.6.23 */ + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)) + +-#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE) ++#if 0 + #if 0 + extern void usb_poison_urb(struct urb *urb); + #endif +--- a/config.mk ++++ b/config.mk +@@ -510,7 +510,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. +-export CONFIG_COMPAT_USB_URB_THREAD_FIX=y ++# export CONFIG_COMPAT_USB_URB_THREAD_FIX=y + + export CONFIG_ATH9K_HTC=m + # export CONFIG_ATH9K_HTC_DEBUGFS=y diff --git a/package/mac80211/patches/130-mesh_pathtbl_backport.patch b/package/mac80211/patches/130-mesh_pathtbl_backport.patch new file mode 100644 index 000000000..15ad03ced --- /dev/null +++ b/package/mac80211/patches/130-mesh_pathtbl_backport.patch @@ -0,0 +1,10 @@ +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -813,7 +813,6 @@ static void table_flush_by_iface(struct + struct hlist_node *p; + int i; + +- WARN_ON(!rcu_read_lock_held()); + for_each_mesh_entry(tbl, p, node, i) { + mpath = node->mpath; + if (mpath->sdata != sdata) diff --git a/package/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch b/package/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch new file mode 100644 index 000000000..9e08a0897 --- /dev/null +++ b/package/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch @@ -0,0 +1,38 @@ +--- a/drivers/net/wireless/ath/ath5k/initvals.c ++++ b/drivers/net/wireless/ath/ath5k/initvals.c +@@ -65,8 +65,14 @@ static const struct ath5k_ini ar5210_ini + { AR5K_IMR, 0 }, + { AR5K_IER, AR5K_IER_DISABLE }, + { AR5K_BSR, 0, AR5K_INI_READ }, ++#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79) + { AR5K_TXCFG, AR5K_DMASIZE_128B }, + { AR5K_RXCFG, AR5K_DMASIZE_128B }, ++#else ++ /* WAR for AR71xx PCI bug */ ++ { AR5K_TXCFG, AR5K_DMASIZE_128B }, ++ { AR5K_RXCFG, AR5K_DMASIZE_4B }, ++#endif + { AR5K_CFG, AR5K_INIT_CFG }, + { AR5K_TOPS, 8 }, + { AR5K_RXNOFRM, 8 }, +--- a/drivers/net/wireless/ath/ath5k/dma.c ++++ b/drivers/net/wireless/ath/ath5k/dma.c +@@ -863,10 +863,18 @@ ath5k_hw_dma_init(struct ath5k_hw *ah) + * guess we can tweak it and see how it goes ;-) + */ + if (ah->ah_version != AR5K_AR5210) { ++#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79) + AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, + AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); + AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, + AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B); ++#else ++ /* WAR for AR71xx PCI bug */ ++ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, ++ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); ++ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, ++ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_4B); ++#endif + } + + /* Pre-enable interrupts on 5211/5212*/ diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch new file mode 100644 index 000000000..f7a0aede5 --- /dev/null +++ b/package/mac80211/patches/300-pending_work.patch @@ -0,0 +1,592 @@ +--- a/drivers/net/wireless/ath/ath5k/base.c ++++ b/drivers/net/wireless/ath/ath5k/base.c +@@ -325,6 +325,8 @@ ath5k_setup_channels(struct ath5k_hw *ah + if (!ath5k_is_standard_channel(ch, band)) + continue; + ++ channels[count].max_power = AR5K_TUNE_MAX_TXPOWER/2; ++ + count++; + } + +--- a/net/mac80211/agg-rx.c ++++ b/net/mac80211/agg-rx.c +@@ -203,6 +203,8 @@ static void ieee80211_send_addba_resp(st + memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); + else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) + memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN); ++ else if (sdata->vif.type == NL80211_IFTYPE_WDS) ++ memcpy(mgmt->bssid, da, 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 +@@ -81,7 +81,8 @@ static void ieee80211_send_addba_request + memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); + if (sdata->vif.type == NL80211_IFTYPE_AP || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN || +- sdata->vif.type == NL80211_IFTYPE_MESH_POINT) ++ sdata->vif.type == NL80211_IFTYPE_MESH_POINT || ++ sdata->vif.type == NL80211_IFTYPE_WDS) + 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); +@@ -460,6 +461,7 @@ int ieee80211_start_tx_ba_session(struct + sdata->vif.type != NL80211_IFTYPE_MESH_POINT && + sdata->vif.type != NL80211_IFTYPE_AP_VLAN && + sdata->vif.type != NL80211_IFTYPE_AP && ++ sdata->vif.type != NL80211_IFTYPE_WDS && + sdata->vif.type != NL80211_IFTYPE_ADHOC) + return -EINVAL; + +@@ -869,7 +871,7 @@ void ieee80211_process_addba_resp(struct + + } else { + ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR, +- true); ++ false); + } + + out: +--- a/net/mac80211/debugfs_sta.c ++++ b/net/mac80211/debugfs_sta.c +@@ -63,11 +63,11 @@ static ssize_t sta_flags_read(struct fil + test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : "" + + int res = scnprintf(buf, sizeof(buf), +- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", ++ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + TEST(AUTH), TEST(ASSOC), TEST(PS_STA), + TEST(PS_DRIVER), TEST(AUTHORIZED), + TEST(SHORT_PREAMBLE), +- TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT), ++ TEST(WME), TEST(CLEAR_PS_FILT), + TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), + TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), + TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT), +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -420,7 +420,6 @@ int ieee80211_do_open(struct wireless_de + struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); + struct net_device *dev = wdev->netdev; + struct ieee80211_local *local = sdata->local; +- struct sta_info *sta; + u32 changed = 0; + int res; + u32 hw_reconf_flags = 0; +@@ -575,30 +574,8 @@ int ieee80211_do_open(struct wireless_de + + set_bit(SDATA_STATE_RUNNING, &sdata->state); + +- if (sdata->vif.type == NL80211_IFTYPE_WDS) { +- /* Create STA entry for the WDS peer */ +- sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, +- GFP_KERNEL); +- if (!sta) { +- res = -ENOMEM; +- goto err_del_interface; +- } +- +- sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); +- sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); +- sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); +- +- res = sta_info_insert(sta); +- if (res) { +- /* STA has been freed */ +- goto err_del_interface; +- } +- +- rate_control_rate_init(sta); +- netif_carrier_on(dev); +- } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) { ++ if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) + rcu_assign_pointer(local->p2p_sdata, sdata); +- } + + /* + * set_multicast_list will be invoked by the networking core +@@ -997,6 +974,72 @@ static void ieee80211_if_setup(struct ne + dev->destructor = free_netdev; + } + ++static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_rx_status *rx_status; ++ struct ieee802_11_elems elems; ++ struct ieee80211_mgmt *mgmt; ++ struct sta_info *sta; ++ size_t baselen; ++ u32 rates = 0; ++ u16 stype; ++ bool new = false; ++ enum ieee80211_band band = local->hw.conf.channel->band; ++ struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; ++ ++ rx_status = IEEE80211_SKB_RXCB(skb); ++ mgmt = (struct ieee80211_mgmt *) skb->data; ++ stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; ++ ++ if (stype != IEEE80211_STYPE_BEACON) ++ return; ++ ++ baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; ++ if (baselen > skb->len) ++ return; ++ ++ ieee802_11_parse_elems(mgmt->u.probe_resp.variable, ++ skb->len - baselen, &elems); ++ ++ rates = ieee80211_sta_get_rates(local, &elems, band, NULL); ++ ++ rcu_read_lock(); ++ ++ sta = sta_info_get(sdata, sdata->u.wds.remote_addr); ++ ++ if (!sta) { ++ rcu_read_unlock(); ++ sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, ++ GFP_KERNEL); ++ if (!sta) ++ return; ++ ++ new = true; ++ } ++ ++ sta->last_rx = jiffies; ++ sta->sta.supp_rates[local->hw.conf.channel->band] = rates; ++ ++ if (elems.ht_cap_elem) ++ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, ++ elems.ht_cap_elem, &sta->sta.ht_cap); ++ ++ if (elems.wmm_param) ++ set_sta_flag(sta, WLAN_STA_WME); ++ ++ if (new) { ++ sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); ++ sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); ++ sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); ++ rate_control_rate_init(sta); ++ sta_info_insert_rcu(sta); ++ } ++ ++ rcu_read_unlock(); ++} ++ + static void ieee80211_iface_work(struct work_struct *work) + { + struct ieee80211_sub_if_data *sdata = +@@ -1101,6 +1144,9 @@ static void ieee80211_iface_work(struct + break; + ieee80211_mesh_rx_queued_mgmt(sdata, skb); + break; ++ case NL80211_IFTYPE_WDS: ++ ieee80211_wds_rx_queued_mgmt(sdata, skb); ++ break; + default: + WARN(1, "frame for unexpected interface type"); + break; +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2279,6 +2279,7 @@ ieee80211_rx_h_action(struct ieee80211_r + sdata->vif.type != NL80211_IFTYPE_MESH_POINT && + sdata->vif.type != NL80211_IFTYPE_AP_VLAN && + sdata->vif.type != NL80211_IFTYPE_AP && ++ sdata->vif.type != NL80211_IFTYPE_WDS && + sdata->vif.type != NL80211_IFTYPE_ADHOC) + break; + +@@ -2496,14 +2497,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_ + + if (!ieee80211_vif_is_mesh(&sdata->vif) && + sdata->vif.type != NL80211_IFTYPE_ADHOC && +- sdata->vif.type != NL80211_IFTYPE_STATION) ++ sdata->vif.type != NL80211_IFTYPE_STATION && ++ sdata->vif.type != NL80211_IFTYPE_WDS) + return RX_DROP_MONITOR; + + switch (stype) { + case cpu_to_le16(IEEE80211_STYPE_AUTH): + case cpu_to_le16(IEEE80211_STYPE_BEACON): + case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): +- /* process for all: mesh, mlme, ibss */ ++ /* process for all: mesh, mlme, ibss, wds */ + break; + case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP): + case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP): +@@ -2827,10 +2829,16 @@ static int prepare_for_handlers(struct i + } + break; + case NL80211_IFTYPE_WDS: +- if (bssid || !ieee80211_is_data(hdr->frame_control)) +- return 0; + if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2)) + return 0; ++ ++ if (ieee80211_is_data(hdr->frame_control) || ++ ieee80211_is_action(hdr->frame_control)) { ++ if (compare_ether_addr(sdata->vif.addr, hdr->addr1)) ++ return 0; ++ } else if (!ieee80211_is_beacon(hdr->frame_control)) ++ return 0; ++ + break; + case NL80211_IFTYPE_P2P_DEVICE: + if (!ieee80211_is_public_action(hdr, skb->len) && +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -32,7 +32,6 @@ + * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble + * frames. + * @WLAN_STA_WME: Station is a QoS-STA. +- * @WLAN_STA_WDS: Station is one of our WDS peers. + * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the + * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next + * frame to this station is transmitted. +@@ -64,7 +63,6 @@ enum ieee80211_sta_info_flags { + WLAN_STA_AUTHORIZED, + WLAN_STA_SHORT_PREAMBLE, + WLAN_STA_WME, +- WLAN_STA_WDS, + WLAN_STA_CLEAR_PS_FILT, + WLAN_STA_MFP, + WLAN_STA_BLOCK_BA, +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -517,29 +517,41 @@ void ieee80211_tx_status(struct ieee8021 + + if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { + u64 cookie = (unsigned long)skb; ++ bool found = false; ++ + acked = info->flags & IEEE80211_TX_STAT_ACK; + +- if (ieee80211_is_nullfunc(hdr->frame_control) || +- ieee80211_is_qos_nullfunc(hdr->frame_control)) { +- cfg80211_probe_status(skb->dev, hdr->addr1, +- cookie, acked, GFP_ATOMIC); +- } else if (skb->dev) { +- cfg80211_mgmt_tx_status( +- skb->dev->ieee80211_ptr, cookie, skb->data, +- skb->len, acked, GFP_ATOMIC); +- } else { +- struct ieee80211_sub_if_data *p2p_sdata; ++ rcu_read_lock(); + +- rcu_read_lock(); ++ list_for_each_entry_rcu(sdata, &local->interfaces, list) { ++ if (!sdata->dev) ++ continue; + +- p2p_sdata = rcu_dereference(local->p2p_sdata); +- if (p2p_sdata) { +- cfg80211_mgmt_tx_status( +- &p2p_sdata->wdev, cookie, skb->data, +- skb->len, acked, GFP_ATOMIC); +- } +- rcu_read_unlock(); ++ if (skb->dev != sdata->dev) ++ continue; ++ ++ found = true; ++ break; + } ++ ++ if (!skb->dev) { ++ sdata = rcu_dereference(local->p2p_sdata); ++ if (sdata) ++ found = true; ++ } ++ ++ if (!found) ++ skb->dev = NULL; ++ else if (ieee80211_is_nullfunc(hdr->frame_control) || ++ ieee80211_is_qos_nullfunc(hdr->frame_control)) { ++ cfg80211_probe_status(sdata->dev, hdr->addr1, ++ cookie, acked, GFP_ATOMIC); ++ } else { ++ cfg80211_mgmt_tx_status(&sdata->wdev, cookie, skb->data, ++ skb->len, acked, GFP_ATOMIC); ++ } ++ ++ rcu_read_unlock(); + } + + if (unlikely(info->ack_frame_id)) { +--- a/drivers/net/wireless/p54/main.c ++++ b/drivers/net/wireless/p54/main.c +@@ -139,6 +139,7 @@ static int p54_beacon_format_ie_tim(stru + static int p54_beacon_update(struct p54_common *priv, + struct ieee80211_vif *vif) + { ++ struct ieee80211_tx_control control = { }; + struct sk_buff *beacon; + int ret; + +@@ -158,7 +159,7 @@ static int p54_beacon_update(struct p54_ + * to cancel the old beacon template by hand, instead the firmware + * will release the previous one through the feedback mechanism. + */ +- p54_tx_80211(priv->hw, NULL, beacon); ++ p54_tx_80211(priv->hw, &control, beacon); + priv->tsf_high32 = 0; + priv->tsf_low32 = 0; + +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -352,6 +352,9 @@ static void reg_regdb_search(struct work + struct reg_regdb_search_request *request; + const struct ieee80211_regdomain *curdom, *regdom; + int i, r; ++ bool set_reg = false; ++ ++ mutex_lock(&cfg80211_mutex); + + mutex_lock(®_regdb_search_mutex); + while (!list_empty(®_regdb_search_list)) { +@@ -367,9 +370,7 @@ static void reg_regdb_search(struct work + r = reg_copy_regd(®dom, curdom); + if (r) + break; +- mutex_lock(&cfg80211_mutex); +- set_regdom(regdom); +- mutex_unlock(&cfg80211_mutex); ++ set_reg = true; + break; + } + } +@@ -377,6 +378,11 @@ static void reg_regdb_search(struct work + kfree(request); + } + mutex_unlock(®_regdb_search_mutex); ++ ++ if (set_reg) ++ set_regdom(regdom); ++ ++ mutex_unlock(&cfg80211_mutex); + } + + static DECLARE_WORK(reg_regdb_work, reg_regdb_search); +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -424,8 +424,8 @@ u32 ath_calcrxfilter(struct ath_softc *s + rfilt |= ATH9K_RX_FILTER_COMP_BAR; + + if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) { +- /* The following may also be needed for other older chips */ +- if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160) ++ /* This is needed for older chips */ ++ if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160) + rfilt |= ATH9K_RX_FILTER_PROM; + rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; + } +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -818,23 +818,71 @@ void ieee80211_sta_process_chanswitch(st + } + + static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, +- u16 capab_info, u8 *pwr_constr_elem, +- u8 pwr_constr_elem_len) ++ struct ieee80211_channel *channel, ++ const u8 *country_ie, u8 country_ie_len, ++ const u8 *pwr_constr_elem) + { +- struct ieee80211_conf *conf = &sdata->local->hw.conf; ++ struct ieee80211_country_ie_triplet *triplet; ++ int chan = ieee80211_frequency_to_channel(channel->center_freq); ++ int i, chan_pwr, chan_increment, new_ap_level; ++ bool have_chan_pwr = false; + +- if (!(capab_info & WLAN_CAPABILITY_SPECTRUM_MGMT)) ++ /* Invalid IE */ ++ if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) + return; + +- /* Power constraint IE length should be 1 octet */ +- if (pwr_constr_elem_len != 1) +- return; ++ triplet = (void *)(country_ie + 3); ++ country_ie_len -= 3; + +- if ((*pwr_constr_elem <= conf->channel->max_reg_power) && +- (*pwr_constr_elem != sdata->local->power_constr_level)) { +- sdata->local->power_constr_level = *pwr_constr_elem; +- ieee80211_hw_config(sdata->local, 0); ++ switch (channel->band) { ++ default: ++ WARN_ON_ONCE(1); ++ /* fall through */ ++ case IEEE80211_BAND_2GHZ: ++ case IEEE80211_BAND_60GHZ: ++ chan_increment = 1; ++ break; ++ case IEEE80211_BAND_5GHZ: ++ chan_increment = 4; ++ break; + } ++ ++ /* find channel */ ++ while (country_ie_len >= 3) { ++ u8 first_channel = triplet->chans.first_channel; ++ ++ if (first_channel >= IEEE80211_COUNTRY_EXTENSION_ID) ++ goto next; ++ ++ for (i = 0; i < triplet->chans.num_channels; i++) { ++ if (first_channel + i * chan_increment == chan) { ++ have_chan_pwr = true; ++ chan_pwr = triplet->chans.max_power; ++ break; ++ } ++ } ++ if (have_chan_pwr) ++ break; ++ ++ next: ++ triplet++; ++ country_ie_len -= 3; ++ } ++ ++ if (!have_chan_pwr) ++ return; ++ ++ new_ap_level = max_t(int, 0, chan_pwr - *pwr_constr_elem); ++ ++ if (sdata->local->ap_power_level == new_ap_level) ++ return; ++ ++ sdata_info(sdata, ++ "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n", ++ new_ap_level, chan_pwr, *pwr_constr_elem, ++ sdata->u.mgd.bssid); ++ sdata->local->ap_power_level = new_ap_level; ++ ieee80211_hw_config(sdata->local, 0); + } + + void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif) +@@ -1390,7 +1438,7 @@ static void ieee80211_set_disassoc(struc + sta = sta_info_get(sdata, ifmgd->bssid); + if (sta) { + set_sta_flag(sta, WLAN_STA_BLOCK_BA); +- ieee80211_sta_tear_down_BA_sessions(sta, tx); ++ ieee80211_sta_tear_down_BA_sessions(sta, false); + } + mutex_unlock(&local->sta_mtx); + +@@ -1438,7 +1486,7 @@ static void ieee80211_set_disassoc(struc + memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); + memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask)); + +- local->power_constr_level = 0; ++ local->ap_power_level = 0; + + del_timer_sync(&local->dynamic_ps_timer); + cancel_work_sync(&local->dynamic_ps_enable_work); +@@ -2530,15 +2578,13 @@ static void ieee80211_rx_mgmt_beacon(str + bssid, true); + } + +- /* Note: country IE parsing is done for us by cfg80211 */ +- if (elems.country_elem) { +- /* TODO: IBSS also needs this */ +- if (elems.pwr_constr_elem) +- ieee80211_handle_pwr_constr(sdata, +- le16_to_cpu(mgmt->u.probe_resp.capab_info), +- elems.pwr_constr_elem, +- elems.pwr_constr_elem_len); +- } ++ if (elems.country_elem && elems.pwr_constr_elem && ++ mgmt->u.probe_resp.capab_info & ++ cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT)) ++ ieee80211_handle_pwr_constr(sdata, local->oper_channel, ++ elems.country_elem, ++ elems.country_elem_len, ++ elems.pwr_constr_elem); + + ieee80211_bss_info_change_notify(sdata, changed); + } +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -674,7 +674,7 @@ int __must_check __sta_info_destroy(stru + * will be sufficient. + */ + set_sta_flag(sta, WLAN_STA_BLOCK_BA); +- ieee80211_sta_tear_down_BA_sessions(sta, true); ++ ieee80211_sta_tear_down_BA_sessions(sta, false); + + ret = sta_info_hash_del(local, sta); + if (ret) +--- a/drivers/net/wireless/ath/ath5k/phy.c ++++ b/drivers/net/wireless/ath/ath5k/phy.c +@@ -1977,11 +1977,13 @@ ath5k_hw_set_spur_mitigation_filter(stru + spur_delta_phase = (spur_offset << 18) / 25; + spur_freq_sigma_delta = (spur_delta_phase >> 10); + symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2; ++ break; + case AR5K_BWMODE_5MHZ: + /* Both sample_freq and chip_freq are 10MHz (?) */ + spur_delta_phase = (spur_offset << 19) / 25; + spur_freq_sigma_delta = (spur_delta_phase >> 10); + symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4; ++ break; + default: + if (channel->band == IEEE80211_BAND_5GHZ) { + /* Both sample_freq and chip_freq are 40MHz */ +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1062,7 +1062,7 @@ struct ieee80211_local { + bool disable_dynamic_ps; + + int user_power_level; /* in dBm */ +- int power_constr_level; /* in dBm */ ++ int ap_power_level; /* in dBm */ + + enum ieee80211_smps_mode smps_mode; + +@@ -1170,7 +1170,6 @@ struct ieee802_11_elems { + u8 prep_len; + u8 perr_len; + u8 country_elem_len; +- u8 pwr_constr_elem_len; + u8 quiet_elem_len; + u8 num_of_quiet_elem; /* can be more the one */ + u8 timeout_int_len; +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -792,8 +792,11 @@ u32 ieee802_11_parse_elems_crc(u8 *start + elems->country_elem_len = elen; + break; + case WLAN_EID_PWR_CONSTRAINT: ++ if (elen != 1) { ++ elem_parse_failed = true; ++ break; ++ } + elems->pwr_constr_elem = pos; +- elems->pwr_constr_elem_len = elen; + break; + case WLAN_EID_TIMEOUT_INTERVAL: + elems->timeout_int = pos; +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -154,13 +154,11 @@ int ieee80211_hw_config(struct ieee80211 + + if (test_bit(SCAN_SW_SCANNING, &local->scanning) || + test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || +- test_bit(SCAN_HW_SCANNING, &local->scanning)) ++ test_bit(SCAN_HW_SCANNING, &local->scanning) || ++ !local->ap_power_level) + power = chan->max_power; + else +- power = local->power_constr_level ? +- min(chan->max_power, +- (chan->max_reg_power - local->power_constr_level)) : +- chan->max_power; ++ power = min(chan->max_power, local->ap_power_level); + + if (local->user_power_level >= 0) + power = min(power, local->user_power_level); diff --git a/package/mac80211/patches/310-ap_scan.patch b/package/mac80211/patches/310-ap_scan.patch new file mode 100644 index 000000000..67a9dcaba --- /dev/null +++ b/package/mac80211/patches/310-ap_scan.patch @@ -0,0 +1,11 @@ +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1796,8 +1796,6 @@ static int ieee80211_scan(struct wiphy * + * beaconing hasn't been configured yet + */ + case NL80211_IFTYPE_AP: +- if (sdata->u.ap.beacon) +- return -EOPNOTSUPP; + break; + default: + return -EOPNOTSUPP; diff --git a/package/mac80211/patches/400-ath_move_debug_code.patch b/package/mac80211/patches/400-ath_move_debug_code.patch new file mode 100644 index 000000000..256da42de --- /dev/null +++ b/package/mac80211/patches/400-ath_move_debug_code.patch @@ -0,0 +1,28 @@ +--- a/drivers/net/wireless/ath/Makefile ++++ b/drivers/net/wireless/ath/Makefile +@@ -8,7 +8,7 @@ obj-$(CONFIG_ATH_COMMON) += ath.o + ath-objs := main.o \ + regd.o \ + hw.o \ +- key.o ++ key.o \ ++ debug.o + +-ath-$(CONFIG_ATH_DEBUG) += debug.o + ccflags-y += -D__CHECK_ENDIAN__ +--- a/drivers/net/wireless/ath/ath.h ++++ b/drivers/net/wireless/ath/ath.h +@@ -280,13 +280,6 @@ void _ath_dbg(struct ath_common *common, + #endif /* CONFIG_ATH_DEBUG */ + + /** Returns string describing opmode, or NULL if unknown mode. */ +-#ifdef CONFIG_ATH_DEBUG + const char *ath_opmode_to_string(enum nl80211_iftype opmode); +-#else +-static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode) +-{ +- return "UNKNOWN"; +-} +-#endif + + #endif /* ATH_H */ diff --git a/package/mac80211/patches/401-ath9k_blink_default.patch b/package/mac80211/patches/401-ath9k_blink_default.patch new file mode 100644 index 000000000..10c763696 --- /dev/null +++ b/package/mac80211/patches/401-ath9k_blink_default.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -40,7 +40,7 @@ int ath9k_modparam_nohwcrypt; + module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444); + MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); + +-int led_blink; ++int led_blink = 1; + module_param_named(blink, led_blink, int, 0444); + MODULE_PARM_DESC(blink, "Enable LED blink on activity"); + diff --git a/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch b/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch new file mode 100644 index 000000000..7c59e1f10 --- /dev/null +++ b/package/mac80211/patches/402-ath9k-fix-invalid-mac-address-handling.patch @@ -0,0 +1,29 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -17,6 +17,7 @@ + #include <linux/io.h> + #include <linux/slab.h> + #include <linux/module.h> ++#include <linux/etherdevice.h> + #include <asm/unaligned.h> + + #include "hw.h" +@@ -523,8 +524,16 @@ static int ath9k_hw_init_macaddr(struct + common->macaddr[2 * i] = eeval >> 8; + common->macaddr[2 * i + 1] = eeval & 0xff; + } +- if (sum == 0 || sum == 0xffff * 3) +- return -EADDRNOTAVAIL; ++ if (!is_valid_ether_addr(common->macaddr)) { ++ ath_err(common, ++ "eeprom contains invalid mac address: %pM\n", ++ common->macaddr); ++ ++ random_ether_addr(common->macaddr); ++ ath_err(common, ++ "random mac address will be used: %pM\n", ++ common->macaddr); ++ } + + return 0; + } diff --git a/package/mac80211/patches/403-ath_regd_optional.patch b/package/mac80211/patches/403-ath_regd_optional.patch new file mode 100644 index 000000000..1854c271e --- /dev/null +++ b/package/mac80211/patches/403-ath_regd_optional.patch @@ -0,0 +1,46 @@ +--- a/drivers/net/wireless/ath/regd.c ++++ b/drivers/net/wireless/ath/regd.c +@@ -200,6 +200,10 @@ ath_reg_apply_beaconing_flags(struct wip + u32 bandwidth = 0; + int r; + ++#ifdef ATH_USER_REGD ++ return; ++#endif ++ + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + + if (!wiphy->bands[band]) +@@ -259,6 +263,10 @@ ath_reg_apply_active_scan_flags(struct w + u32 bandwidth = 0; + int r; + ++#ifdef ATH_USER_REGD ++ return; ++#endif ++ + sband = wiphy->bands[IEEE80211_BAND_2GHZ]; + if (!sband) + return; +@@ -308,6 +316,10 @@ static void ath_reg_apply_radar_flags(st + struct ieee80211_channel *ch; + unsigned int i; + ++#ifdef ATH_USER_REGD ++ return; ++#endif ++ + if (!wiphy->bands[IEEE80211_BAND_5GHZ]) + return; + +@@ -514,6 +526,10 @@ ath_regd_init_wiphy(struct ath_regulator + { + const struct ieee80211_regdomain *regd; + ++#ifdef ATH_USER_REGD ++ return 0; ++#endif ++ + wiphy->reg_notifier = reg_notifier; + wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; + diff --git a/package/mac80211/patches/404-world_regd_fixup.patch b/package/mac80211/patches/404-world_regd_fixup.patch new file mode 100644 index 000000000..d609b55e0 --- /dev/null +++ b/package/mac80211/patches/404-world_regd_fixup.patch @@ -0,0 +1,84 @@ +--- a/drivers/net/wireless/ath/regd.c ++++ b/drivers/net/wireless/ath/regd.c +@@ -44,7 +44,8 @@ static int __ath_regd_init(struct ath_re + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) + + /* We allow IBSS on these on a case by case basis by regulatory domain */ +-#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 40, 0, 30,\ ++#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5250, 40, 0, 30, 0), \ ++ REG_RULE(5250, 5350+10, 40, 0, 30,\ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) + #define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 40, 0, 30,\ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) +@@ -62,57 +63,56 @@ static int __ath_regd_init(struct ath_re + #define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \ + ATH9K_5GHZ_5725_5850 + ++#define REGD_RULES(...) \ ++ .reg_rules = { __VA_ARGS__ }, \ ++ .n_reg_rules = ARRAY_SIZE(((struct ieee80211_reg_rule[]) { __VA_ARGS__ })) ++ + /* Can be used for: + * 0x60, 0x61, 0x62 */ + static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = { +- .n_reg_rules = 5, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_ALL, + ATH9K_5GHZ_ALL, +- } ++ ) + }; + + /* Can be used by 0x63 and 0x65 */ + static const struct ieee80211_regdomain ath_world_regdom_63_65 = { +- .n_reg_rules = 4, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_CH01_11, + ATH9K_2GHZ_CH12_13, + ATH9K_5GHZ_NO_MIDBAND, +- } ++ ) + }; + + /* Can be used by 0x64 only */ + static const struct ieee80211_regdomain ath_world_regdom_64 = { +- .n_reg_rules = 3, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_CH01_11, + ATH9K_5GHZ_NO_MIDBAND, +- } ++ ) + }; + + /* Can be used by 0x66 and 0x69 */ + static const struct ieee80211_regdomain ath_world_regdom_66_69 = { +- .n_reg_rules = 3, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_CH01_11, + ATH9K_5GHZ_ALL, +- } ++ ) + }; + + /* Can be used by 0x67, 0x68, 0x6A and 0x6C */ + static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = { +- .n_reg_rules = 4, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_CH01_11, + ATH9K_2GHZ_CH12_13, + ATH9K_5GHZ_ALL, +- } ++ ) + }; + + static inline bool is_wwr_sku(u16 regd) diff --git a/package/mac80211/patches/405-regd_no_assoc_hints.patch b/package/mac80211/patches/405-regd_no_assoc_hints.patch new file mode 100644 index 000000000..8a5c2a2e3 --- /dev/null +++ b/package/mac80211/patches/405-regd_no_assoc_hints.patch @@ -0,0 +1,20 @@ +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -1796,6 +1796,8 @@ void regulatory_hint_11d(struct wiphy *w + enum environment_cap env = ENVIRON_ANY; + struct regulatory_request *request; + ++ return; ++ + mutex_lock(®_mutex); + + if (unlikely(!last_request)) +@@ -2030,6 +2032,8 @@ static void restore_regulatory_settings( + + void regulatory_hint_disconnect(void) + { ++ return; ++ + REG_DBG_PRINT("All devices are disconnected, going to " + "restore regulatory settings\n"); + restore_regulatory_settings(false); diff --git a/package/mac80211/patches/406-ath_regd_us.patch b/package/mac80211/patches/406-ath_regd_us.patch new file mode 100644 index 000000000..cc5587780 --- /dev/null +++ b/package/mac80211/patches/406-ath_regd_us.patch @@ -0,0 +1,26 @@ +--- a/drivers/net/wireless/ath/regd_common.h ++++ b/drivers/net/wireless/ath/regd_common.h +@@ -32,6 +32,7 @@ enum EnumRd { + FCC2_WORLD = 0x21, + FCC2_ETSIC = 0x22, + FCC6_WORLD = 0x23, ++ FCC3_FCCA_2 = 0x2A, + FRANCE_RES = 0x31, + FCC3_FCCA = 0x3A, + FCC3_WORLD = 0x3B, +@@ -167,6 +168,7 @@ static struct reg_dmn_pair_mapping regDo + {FCC2_WORLD, CTL_FCC, CTL_ETSI}, + {FCC2_ETSIC, CTL_FCC, CTL_ETSI}, + {FCC3_FCCA, CTL_FCC, CTL_FCC}, ++ {FCC3_FCCA_2, CTL_FCC, CTL_FCC}, + {FCC3_WORLD, CTL_FCC, CTL_ETSI}, + {FCC4_FCCA, CTL_FCC, CTL_FCC}, + {FCC5_FCCA, CTL_FCC, CTL_FCC}, +@@ -463,6 +465,7 @@ static struct country_code_to_enum_rd al + {CTRY_UAE, NULL1_WORLD, "AE"}, + {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"}, + {CTRY_UNITED_STATES, FCC3_FCCA, "US"}, ++ {CTRY_UNITED_STATES, FCC3_FCCA_2, "US"}, + /* This "PS" is for US public safety actually... to support this we + * would need to assign new special alpha2 to CRDA db as with the world + * regdomain and use another alpha2 */ diff --git a/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch new file mode 100644 index 000000000..aabf3c3f4 --- /dev/null +++ b/package/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch @@ -0,0 +1,10 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -667,6 +667,7 @@ static const struct ieee80211_iface_limi + #ifdef CONFIG_MAC80211_MESH + BIT(NL80211_IFTYPE_MESH_POINT) | + #endif ++ BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_GO) }, + }; diff --git a/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch b/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch new file mode 100644 index 000000000..8e02950e4 --- /dev/null +++ b/package/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch @@ -0,0 +1,46 @@ +--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c ++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c +@@ -89,13 +89,8 @@ ath5k_add_interface(struct ieee80211_hw + goto end; + } + +- /* Don't allow other interfaces if one ad-hoc is configured. +- * TODO: Fix the problems with ad-hoc and multiple other interfaces. +- * 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 (ah->num_adhoc_vifs || +- (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { ++ /* Don't allow more than one ad-hoc interface */ ++ 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 +@@ -1878,7 +1878,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) + } + + if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + +- ah->num_mesh_vifs > 1) || ++ ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) || + ah->opmode == NL80211_IFTYPE_MESH_POINT) { + u64 tsf = ath5k_hw_get_tsf64(ah); + u32 tsftu = TSF_TO_TU(tsf); +@@ -1964,7 +1964,7 @@ ath5k_beacon_update_timers(struct ath5k_ + + intval = ah->bintval & AR5K_BEACON_PERIOD; + if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +- + ah->num_mesh_vifs > 1) { ++ + ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) { + intval /= ATH_BCBUF; /* staggered multi-bss beacons */ + if (intval < 15) + ATH5K_WARN(ah, "intval %u is too low, min 15\n", +@@ -2427,6 +2427,7 @@ static const struct ieee80211_iface_limi + #ifdef CONFIG_MAC80211_MESH + BIT(NL80211_IFTYPE_MESH_POINT) | + #endif ++ BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP) }, + }; + diff --git a/package/mac80211/patches/412-mac80211_allow_adhoc_and_ap.patch b/package/mac80211/patches/412-mac80211_allow_adhoc_and_ap.patch new file mode 100644 index 000000000..93f35567e --- /dev/null +++ b/package/mac80211/patches/412-mac80211_allow_adhoc_and_ap.patch @@ -0,0 +1,20 @@ +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -792,17 +792,11 @@ int ieee80211_register_hw(struct ieee802 + */ + for (i = 0; i < hw->wiphy->n_iface_combinations; i++) { + const struct ieee80211_iface_combination *c; +- int j; + + c = &hw->wiphy->iface_combinations[i]; + + if (c->num_different_channels > 1) + return -EINVAL; +- +- for (j = 0; j < c->n_limits; j++) +- if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) && +- c->limits[j].max > 1) +- return -EINVAL; + } + + #ifndef CONFIG_MAC80211_MESH diff --git a/package/mac80211/patches/420-ath5k_disable_fast_cc.patch b/package/mac80211/patches/420-ath5k_disable_fast_cc.patch new file mode 100644 index 000000000..bd661c6fb --- /dev/null +++ b/package/mac80211/patches/420-ath5k_disable_fast_cc.patch @@ -0,0 +1,18 @@ +--- a/drivers/net/wireless/ath/ath5k/reset.c ++++ b/drivers/net/wireless/ath/ath5k/reset.c +@@ -1156,6 +1156,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum + tsf_lo = 0; + mode = 0; + ++#if 0 + /* + * Sanity check for fast flag + * Fast channel change only available +@@ -1163,6 +1164,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum + */ + if (fast && (ah->ah_radio != AR5K_RF2413) && + (ah->ah_radio != AR5K_RF5413)) ++#endif + fast = false; + + /* Disable sleep clock operation diff --git a/package/mac80211/patches/430-add_ath5k_platform.patch b/package/mac80211/patches/430-add_ath5k_platform.patch new file mode 100644 index 000000000..b213e2a81 --- /dev/null +++ b/package/mac80211/patches/430-add_ath5k_platform.patch @@ -0,0 +1,33 @@ +--- /dev/null ++++ b/include/linux/ath5k_platform.h +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (c) 2008 Atheros Communications Inc. ++ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org> ++ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org> ++ * Copyright (c) 2010 Daniel Golle <daniel.golle@gmail.com> ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifndef _LINUX_ATH5K_PLATFORM_H ++#define _LINUX_ATH5K_PLATFORM_H ++ ++#define ATH5K_PLAT_EEP_MAX_WORDS 2048 ++ ++struct ath5k_platform_data { ++ u16 *eeprom_data; ++ u8 *macaddr; ++}; ++ ++#endif /* _LINUX_ATH5K_PLATFORM_H */ diff --git a/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch b/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch new file mode 100644 index 000000000..6cafa236a --- /dev/null +++ b/package/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch @@ -0,0 +1,56 @@ +--- a/drivers/net/wireless/ath/ath5k/pci.c ++++ b/drivers/net/wireless/ath/ath5k/pci.c +@@ -23,6 +23,7 @@ + #include <linux/pci-aspm.h> + #include <linux/etherdevice.h> + #include <linux/module.h> ++#include <linux/ath5k_platform.h> + #include "../ath.h" + #include "ath5k.h" + #include "debug.h" +@@ -74,7 +75,7 @@ static void ath5k_pci_read_cachesize(str + } + + /* +- * Read from eeprom ++ * Read from eeprom or platform_data + */ + static bool + ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) +@@ -82,6 +83,19 @@ ath5k_pci_eeprom_read(struct ath_common + struct ath5k_hw *ah = (struct ath5k_hw *) common->ah; + u32 status, timeout; + ++ struct ath5k_platform_data *pdata = NULL; ++ ++ if (ah->pdev) ++ pdata = ah->pdev->dev.platform_data; ++ ++ if (pdata && pdata->eeprom_data && pdata->eeprom_data[61] == AR5K_EEPROM_MAGIC_VALUE) { ++ if (offset >= ATH5K_PLAT_EEP_MAX_WORDS) ++ return false; ++ ++ *data = pdata->eeprom_data[offset]; ++ return true; ++ } ++ + /* + * Initialize EEPROM access + */ +@@ -125,6 +139,16 @@ static int ath5k_pci_eeprom_read_mac(str + u16 data; + int octet; + ++ struct ath5k_platform_data *pdata = NULL; ++ ++ if (ah->pdev) ++ pdata = ah->pdev->dev.platform_data; ++ ++ if (pdata && pdata->macaddr) { ++ memcpy(mac, pdata->macaddr, ETH_ALEN); ++ return 0; ++ } ++ + AR5K_EEPROM_READ(0x20, data); + + for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { diff --git a/package/mac80211/patches/432-ath5k_add_pciids.patch b/package/mac80211/patches/432-ath5k_add_pciids.patch new file mode 100644 index 000000000..8db5e1b3f --- /dev/null +++ b/package/mac80211/patches/432-ath5k_add_pciids.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath5k/pci.c ++++ b/drivers/net/wireless/ath/ath5k/pci.c +@@ -50,6 +50,8 @@ static DEFINE_PCI_DEVICE_TABLE(ath5k_pci + { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ + { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ + { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ ++ { PCI_VDEVICE(ATHEROS, 0xff16) }, /* 2413,2414 sx76x on lantiq_danube */ ++ { PCI_VDEVICE(ATHEROS, 0xff1a) }, /* 2417 arv45xx on lantiq_danube */ + { PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */ + { 0 } + }; diff --git a/package/mac80211/patches/440-ath5k_channel_bw_debugfs.patch b/package/mac80211/patches/440-ath5k_channel_bw_debugfs.patch new file mode 100644 index 000000000..a2141ab24 --- /dev/null +++ b/package/mac80211/patches/440-ath5k_channel_bw_debugfs.patch @@ -0,0 +1,113 @@ +This adds a bwmode debugfs file which can be used to set alternate +channel operating bandwidths. Only tested with AR5413 and only at +5 and 20 mhz channels. + +Signed-off-by: Pat Erley <pat-lkml at erley.org> +--- +Other devices will need to be added to the switch in write_file_bwmode + +drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++ + 1 files changed, 86 insertions(+), 0 deletions(-) + +--- a/drivers/net/wireless/ath/ath5k/debug.c ++++ b/drivers/net/wireless/ath/ath5k/debug.c +@@ -813,6 +813,89 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++/* debugfs: bwmode */ ++ ++static ssize_t read_file_bwmode(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath5k_hw *ah = file->private_data; ++ char buf[15]; ++ unsigned int len = 0; ++ ++ int cur_ah_bwmode = ah->ah_bwmode; ++ ++#define print_selected(MODE, LABEL) \ ++ if (cur_ah_bwmode == MODE) \ ++ len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \ ++ else \ ++ len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \ ++ len += snprintf(buf+len, sizeof(buf)-len, " "); ++ ++ print_selected(AR5K_BWMODE_5MHZ, "5"); ++ print_selected(AR5K_BWMODE_10MHZ, "10"); ++ print_selected(AR5K_BWMODE_DEFAULT, "20"); ++ print_selected(AR5K_BWMODE_40MHZ, "40"); ++#undef print_selected ++ ++ len += snprintf(buf+len, sizeof(buf)-len, "\n"); ++ ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_bwmode(struct file *file, ++ const char __user *userbuf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath5k_hw *ah = file->private_data; ++ char buf[3]; ++ int bw = 20; ++ int tobwmode = AR5K_BWMODE_DEFAULT; ++ ++ if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) ++ return -EFAULT; ++ ++ /* TODO: Add check for active interface */ ++ ++ if(strncmp(buf, "5", 1) == 0 ) { ++ tobwmode = AR5K_BWMODE_5MHZ; ++ bw = 5; ++ } else if ( strncmp(buf, "10", 2) == 0 ) { ++ tobwmode = AR5K_BWMODE_10MHZ; ++ bw = 10; ++ } else if ( strncmp(buf, "20", 2) == 0 ) { ++ tobwmode = AR5K_BWMODE_DEFAULT; ++ bw = 20; ++ } else if ( strncmp(buf, "40", 2) == 0 ) { ++ tobwmode = AR5K_BWMODE_40MHZ; ++ bw = 40; ++ } else ++ return -EINVAL; ++ ++ ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n", ++ bw, tobwmode); ++ ++ switch (ah->ah_radio) { ++ /* TODO: only define radios that actually support 5/10mhz channels */ ++ case AR5K_RF5413: case AR5K_RF5110: case AR5K_RF5111: case AR5K_RF5112: case AR5K_RF2413: case AR5K_RF2316: case AR5K_RF2317: case AR5K_RF2425: ++ if(ah->ah_bwmode != tobwmode) { ++ mutex_lock(&ah->lock); ++ ah->ah_bwmode = tobwmode; ++ mutex_unlock(&ah->lock); ++ } ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ return count; ++} ++ ++static const struct file_operations fops_bwmode = { ++ .read = read_file_bwmode, ++ .write = write_file_bwmode, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; + + /* debugfs: queues etc */ + +@@ -904,6 +987,9 @@ ath5k_debug_init_device(struct ath5k_hw + debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah, + &fops_beacon); + ++ debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah, ++ &fops_bwmode); ++ + debugfs_create_file("reset", S_IWUSR, phydir, ah, &fops_reset); + + debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah, diff --git a/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch new file mode 100644 index 000000000..11272b96e --- /dev/null +++ b/package/mac80211/patches/500-ath9k_eeprom_debugfs.patch @@ -0,0 +1,65 @@ +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1532,6 +1532,53 @@ static const struct file_operations fops + + #endif + ++static ssize_t read_file_eeprom(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_hw *ah = sc->sc_ah; ++ struct ath_common *common = ath9k_hw_common(ah); ++ int bytes = 0; ++ int pos = *ppos; ++ int size = 4096; ++ u16 val; ++ int i; ++ ++ if (AR_SREV_9300_20_OR_LATER(ah)) ++ size = 16384; ++ ++ if (*ppos < 0) ++ return -EINVAL; ++ ++ if (count > size - *ppos) ++ count = size - *ppos; ++ ++ for (i = *ppos / 2; count > 0; count -= bytes, *ppos += bytes, i++) { ++ void *from = &val; ++ ++ if (!common->bus_ops->eeprom_read(common, i, &val)) ++ val = 0xffff; ++ ++ if (*ppos % 2) { ++ from++; ++ bytes = 1; ++ } else if (count == 1) { ++ bytes = 1; ++ } else { ++ bytes = 2; ++ } ++ copy_to_user(user_buf, from, bytes); ++ user_buf += bytes; ++ } ++ return *ppos - pos; ++} ++ ++static const struct file_operations fops_eeprom = { ++ .read = read_file_eeprom, ++ .open = simple_open, ++ .owner = THIS_MODULE ++}; ++ + int ath9k_init_debug(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); +@@ -1603,5 +1650,8 @@ 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); + ++ debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, ++ &fops_eeprom); ++ + return 0; + } diff --git a/package/mac80211/patches/501-ath9k-eeprom_endianess.patch b/package/mac80211/patches/501-ath9k-eeprom_endianess.patch new file mode 100644 index 000000000..52ae70fc6 --- /dev/null +++ b/package/mac80211/patches/501-ath9k-eeprom_endianess.patch @@ -0,0 +1,102 @@ +--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c ++++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c +@@ -266,7 +266,7 @@ static int ath9k_hw_def_check_eeprom(str + { + struct ar5416_eeprom_def *eep = &ah->eeprom.def; + struct ath_common *common = ath9k_hw_common(ah); +- u16 *eepdata, temp, magic, magic2; ++ u16 *eepdata, temp, magic; + u32 sum = 0, el; + bool need_swap = false; + int i, addr, size; +@@ -276,27 +276,16 @@ static int ath9k_hw_def_check_eeprom(str + return false; + } + +- if (!ath9k_hw_use_flash(ah)) { +- ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic); +- +- if (magic != AR5416_EEPROM_MAGIC) { +- magic2 = swab16(magic); +- +- if (magic2 == AR5416_EEPROM_MAGIC) { +- size = sizeof(struct ar5416_eeprom_def); +- need_swap = true; +- eepdata = (u16 *) (&ah->eeprom); +- +- for (addr = 0; addr < size / sizeof(u16); addr++) { +- temp = swab16(*eepdata); +- *eepdata = temp; +- eepdata++; +- } +- } else { +- ath_err(common, +- "Invalid EEPROM Magic. Endianness mismatch.\n"); +- return -EINVAL; +- } ++ if (swab16(magic) == AR5416_EEPROM_MAGIC && ++ !(ah->ah_flags & AH_NO_EEP_SWAP)) { ++ size = sizeof(struct ar5416_eeprom_def); ++ need_swap = true; ++ eepdata = (u16 *) (&ah->eeprom); ++ ++ for (addr = 0; addr < size / sizeof(u16); addr++) { ++ temp = swab16(*eepdata); ++ *eepdata = temp; ++ eepdata++; + } + } + +--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c ++++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c +@@ -195,7 +195,7 @@ static int ath9k_hw_4k_check_eeprom(stru + int i, addr; + + +- if (!ath9k_hw_use_flash(ah)) { ++ if (!(ah->ah_flags & AH_NO_EEP_SWAP)) { + if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, + &magic)) { + ath_err(common, "Reading Magic # failed\n"); +--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c ++++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c +@@ -189,7 +189,7 @@ static int ath9k_hw_ar9287_check_eeprom( + struct ar9287_eeprom *eep = &ah->eeprom.map9287; + struct ath_common *common = ath9k_hw_common(ah); + +- if (!ath9k_hw_use_flash(ah)) { ++ if (!(ah->ah_flags & AH_NO_EEP_SWAP)) { + if (!ath9k_hw_nvram_read(common, AR5416_EEPROM_MAGIC_OFFSET, + &magic)) { + ath_err(common, "Reading Magic # failed\n"); +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -705,6 +705,7 @@ enum ath_cal_list { + #define AH_USE_EEPROM 0x1 + #define AH_UNPLUGGED 0x2 /* The card has been physically removed. */ + #define AH_FASTCC 0x4 ++#define AH_NO_EEP_SWAP 0x8 /* Do not swap EEPROM data */ + + struct ath_hw { + struct ath_ops reg_ops; +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -537,6 +537,8 @@ static int ath9k_init_softc(u16 devid, s + ah->is_clk_25mhz = pdata->is_clk_25mhz; + ah->get_mac_revision = pdata->get_mac_revision; + ah->external_reset = pdata->external_reset; ++ if (!pdata->endian_check) ++ ah->ah_flags |= AH_NO_EEP_SWAP; + } + + common = ath9k_hw_common(ah); +--- a/include/linux/ath9k_platform.h ++++ b/include/linux/ath9k_platform.h +@@ -29,6 +29,7 @@ struct ath9k_platform_data { + u32 gpio_mask; + u32 gpio_val; + ++ bool endian_check; + bool is_clk_25mhz; + int (*get_mac_revision)(void); + int (*external_reset)(void); diff --git a/package/mac80211/patches/502-ath9k_ahb_init.patch b/package/mac80211/patches/502-ath9k_ahb_init.patch new file mode 100644 index 000000000..7d3df6b20 --- /dev/null +++ b/package/mac80211/patches/502-ath9k_ahb_init.patch @@ -0,0 +1,32 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -926,23 +926,23 @@ static int __init ath9k_init(void) + goto err_out; + } + +- error = ath_pci_init(); ++ error = ath_ahb_init(); + if (error < 0) { +- pr_err("No PCI devices found, driver not installed\n"); + error = -ENODEV; + goto err_rate_unregister; + } + +- error = ath_ahb_init(); ++ error = ath_pci_init(); + if (error < 0) { ++ pr_err("No PCI devices found, driver not installed\n"); + error = -ENODEV; +- goto err_pci_exit; ++ goto err_ahb_exit; + } + + return 0; + +- err_pci_exit: +- ath_pci_exit(); ++ err_ahb_exit: ++ ath_ahb_exit(); + + err_rate_unregister: + ath_rate_control_unregister(); diff --git a/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch new file mode 100644 index 000000000..3b78afae3 --- /dev/null +++ b/package/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch @@ -0,0 +1,13 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1949,8 +1949,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st + REG_WRITE(ah, AR_OBS, 8); + + if (ah->config.rx_intr_mitigation) { +- REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); +- REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); ++ REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 250); ++ REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 500); + } + + if (ah->config.tx_intr_mitigation) { diff --git a/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch b/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch new file mode 100644 index 000000000..db13fea1b --- /dev/null +++ b/package/mac80211/patches/511-ath9k_reduce_rxbuf.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -122,7 +122,7 @@ void ath_descdma_cleanup(struct ath_soft + /* RX / TX */ + /***********/ + +-#define ATH_RXBUF 512 ++#define ATH_RXBUF 256 + #define ATH_TXBUF 512 + #define ATH_TXBUF_RESERVE 5 + #define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE) diff --git a/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch new file mode 100644 index 000000000..d4087a0b2 --- /dev/null +++ b/package/mac80211/patches/512-ath9k_channelbw_debugfs.patch @@ -0,0 +1,128 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -659,6 +659,7 @@ struct ath_softc { + struct ieee80211_hw *hw; + struct device *dev; + ++ u32 chan_bw; + struct survey_info *cur_survey; + struct survey_info survey[ATH9K_NUM_CHANNELS]; + +@@ -734,6 +735,7 @@ struct ath_softc { + #endif + }; + ++int ath9k_config(struct ieee80211_hw *hw, u32 changed); + void ath9k_tasklet(unsigned long data); + int ath_cabq_update(struct ath_softc *); + +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1579,6 +1579,50 @@ static const struct file_operations fops + .owner = THIS_MODULE + }; + ++ ++static ssize_t read_file_chan_bw(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ char buf[32]; ++ unsigned int len; ++ ++ len = sprintf(buf, "0x%08x\n", sc->chan_bw); ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_chan_bw(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ unsigned long chan_bw; ++ char buf[32]; ++ ssize_t len; ++ ++ len = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ if (strict_strtoul(buf, 0, &chan_bw)) ++ return -EINVAL; ++ ++ sc->chan_bw = chan_bw; ++ if (!(sc->sc_flags & SC_OP_INVALID)) ++ ath9k_config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL); ++ ++ return count; ++} ++ ++static const struct file_operations fops_chanbw = { ++ .read = read_file_chan_bw, ++ .write = write_file_chan_bw, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++ + int ath9k_init_debug(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); +@@ -1653,5 +1697,8 @@ int ath9k_init_debug(struct ath_hw *ah) + debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_eeprom); + ++ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, ++ sc, &fops_chanbw); ++ + return 0; + } +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1127,7 +1127,7 @@ static void ath9k_disable_ps(struct ath_ + ath_dbg(common, PS, "PowerSave disabled\n"); + } + +-static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ++int ath9k_config(struct ieee80211_hw *hw, u32 changed) + { + struct ath_softc *sc = hw->priv; + struct ath_hw *ah = sc->sc_ah; +@@ -1181,9 +1181,11 @@ static int ath9k_config(struct ieee80211 + + if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { + struct ieee80211_channel *curchan = hw->conf.channel; ++ struct ath9k_channel *hchan; + int pos = curchan->hw_value; + int old_pos = -1; + unsigned long flags; ++ u32 oldflags; + + if (ah->curchan) + old_pos = ah->curchan - &ah->channels[0]; +@@ -1226,7 +1228,23 @@ static int ath9k_config(struct ieee80211 + memset(&sc->survey[pos], 0, sizeof(struct survey_info)); + } + +- if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { ++ hchan = &sc->sc_ah->channels[pos]; ++ oldflags = hchan->channelFlags; ++ switch (sc->chan_bw) { ++ case 5: ++ hchan->channelFlags &= ~CHANNEL_HALF; ++ hchan->channelFlags |= CHANNEL_QUARTER; ++ break; ++ case 10: ++ hchan->channelFlags &= ~CHANNEL_QUARTER; ++ hchan->channelFlags |= CHANNEL_HALF; ++ break; ++ default: ++ hchan->channelFlags &= ~(CHANNEL_HALF | CHANNEL_QUARTER); ++ break; ++ } ++ ++ if (ath_set_channel(sc, hw, hchan) < 0) { + ath_err(common, "Unable to set channel\n"); + mutex_unlock(&sc->mutex); + ath9k_ps_restore(sc); diff --git a/package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch b/package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch new file mode 100644 index 000000000..25f4fdd40 --- /dev/null +++ b/package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch @@ -0,0 +1,10 @@ +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -964,6 +964,7 @@ static const struct net_device_ops ieee8 + static void ieee80211_if_setup(struct net_device *dev) + { + ether_setup(dev); ++ dev->tx_queue_len = 32; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; + netdev_attach_ops(dev, &ieee80211_dataif_ops); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) diff --git a/package/mac80211/patches/520-mac80211_cur_txpower.patch b/package/mac80211/patches/520-mac80211_cur_txpower.patch new file mode 100644 index 000000000..54f2e5040 --- /dev/null +++ b/package/mac80211/patches/520-mac80211_cur_txpower.patch @@ -0,0 +1,31 @@ +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1372,6 +1372,7 @@ struct ieee80211_hw { + u8 max_tx_aggregation_subframes; + u8 offchannel_tx_hw_queue; + u8 radiotap_mcs_details; ++ s8 cur_power_level; + netdev_features_t netdev_features; + }; + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1967,7 +1967,7 @@ static int ieee80211_get_tx_power(struct + { + struct ieee80211_local *local = wiphy_priv(wiphy); + +- *dbm = local->hw.conf.power_level; ++ *dbm = local->hw.cur_power_level; + + return 0; + } +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -165,6 +165,7 @@ int ieee80211_hw_config(struct ieee80211 + + if (local->hw.conf.power_level != power) { + changed |= IEEE80211_CONF_CHANGE_POWER; ++ local->hw.cur_power_level = power; + local->hw.conf.power_level = power; + } + diff --git a/package/mac80211/patches/521-ath9k_cur_txpower.patch b/package/mac80211/patches/521-ath9k_cur_txpower.patch new file mode 100644 index 000000000..1133cfa6b --- /dev/null +++ b/package/mac80211/patches/521-ath9k_cur_txpower.patch @@ -0,0 +1,19 @@ +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1251,6 +1251,8 @@ int ath9k_config(struct ieee80211_hw *hw + return -EINVAL; + } + ++ hw->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 +@@ -1265,6 +1267,7 @@ int ath9k_config(struct ieee80211_hw *hw + sc->config.txpowlimit = 2 * conf->power_level; + ath9k_cmn_update_txpow(ah, sc->curtxpow, + sc->config.txpowlimit, &sc->curtxpow); ++ hw->cur_power_level = sc->curtxpow / 2; + } + + mutex_unlock(&sc->mutex); diff --git a/package/mac80211/patches/522-ath9k_per_chain_signal_strength.patch b/package/mac80211/patches/522-ath9k_per_chain_signal_strength.patch new file mode 100644 index 000000000..8b26a50b3 --- /dev/null +++ b/package/mac80211/patches/522-ath9k_per_chain_signal_strength.patch @@ -0,0 +1,384 @@ +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -729,6 +729,9 @@ enum mac80211_rx_flags { + * @signal: signal strength when receiving this frame, either in dBm, in dB or + * unspecified depending on the hardware capabilities flags + * @IEEE80211_HW_SIGNAL_* ++ * @chains: bitmask of receive chains for which separate signal strength ++ * values were filled. ++ * @chain_signal: per-chain signal strength, same format as @signal + * @antenna: antenna used + * @rate_idx: index of data rate into band's supported rates or MCS index if + * HT rates are use (RX_FLAG_HT) +@@ -749,6 +752,8 @@ struct ieee80211_rx_status { + u8 band; + u8 antenna; + s8 signal; ++ u8 chains; ++ s8 chain_signal[4]; + u8 ampdu_delimiter_crc; + }; + +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -325,6 +325,11 @@ struct sta_info { + unsigned long rx_dropped; + int last_signal; + struct ewma avg_signal; ++ ++ u8 chains; ++ s8 chain_signal_last[4]; ++ struct ewma chain_signal_avg[4]; ++ + /* Plus 1 for non-QoS frames */ + __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES + 1]; + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1271,6 +1271,7 @@ ieee80211_rx_h_sta_process(struct ieee80 + struct sk_buff *skb = rx->skb; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; ++ int i; + + if (!sta) + return RX_CONTINUE; +@@ -1315,6 +1316,19 @@ ieee80211_rx_h_sta_process(struct ieee80 + ewma_add(&sta->avg_signal, -status->signal); + } + ++ if (status->chains) { ++ sta->chains = status->chains; ++ for (i = 0; i < 4; i++) { ++ int signal = status->chain_signal[i]; ++ ++ if (!(status->chains & BIT(i))) ++ continue; ++ ++ sta->chain_signal_last[i] = signal; ++ ewma_add(&sta->chain_signal_avg[i], -signal); ++ } ++ } ++ + /* + * Change STA power saving mode only at the end of a frame + * exchange sequence. +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -254,6 +254,8 @@ struct sta_info *sta_info_alloc(struct i + do_posix_clock_monotonic_gettime(&uptime); + sta->last_connected = uptime.tv_sec; + ewma_init(&sta->avg_signal, 1024, 8); ++ for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++) ++ ewma_init(&sta->chain_signal_avg[i], 1024, 8); + + if (sta_prepare_rate_control(local, sta, gfp)) { + kfree(sta); +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -549,6 +549,8 @@ struct station_parameters { + * @STATION_INFO_STA_FLAGS: @sta_flags filled + * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled + * @STATION_INFO_T_OFFSET: @t_offset filled ++ * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled ++ * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled + */ + enum station_info_flags { + STATION_INFO_INACTIVE_TIME = 1<<0, +@@ -572,6 +574,8 @@ enum station_info_flags { + STATION_INFO_STA_FLAGS = 1<<18, + STATION_INFO_BEACON_LOSS_COUNT = 1<<19, + STATION_INFO_T_OFFSET = 1<<20, ++ STATION_INFO_CHAIN_SIGNAL = 1<<21, ++ STATION_INFO_CHAIN_SIGNAL_AVG = 1<<22, + }; + + /** +@@ -655,6 +659,9 @@ struct sta_bss_parameters { + * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. + * @signal_avg: Average signal strength, type depends on the wiphy's signal_type. + * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. ++ * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg ++ * @chain_signal: per-chain signal strength of last received packet in dBm ++ * @chain_signal_avg: per-chain signal strength average in dBm + * @txrate: current unicast bitrate from this station + * @rxrate: current unicast bitrate to this station + * @rx_packets: packets received from this station +@@ -687,6 +694,11 @@ struct station_info { + u8 plink_state; + s8 signal; + s8 signal_avg; ++ ++ u8 chains; ++ s8 chain_signal[4]; ++ s8 chain_signal_avg[4]; ++ + struct rate_info txrate; + struct rate_info rxrate; + u32 rx_packets; +--- a/drivers/net/wireless/ath/ath9k/mac.h ++++ b/drivers/net/wireless/ath/ath9k/mac.h +@@ -133,12 +133,8 @@ struct ath_rx_status { + u8 rs_rate; + u8 rs_antenna; + u8 rs_more; +- int8_t rs_rssi_ctl0; +- int8_t rs_rssi_ctl1; +- int8_t rs_rssi_ctl2; +- int8_t rs_rssi_ext0; +- int8_t rs_rssi_ext1; +- int8_t rs_rssi_ext2; ++ int8_t rs_rssi_ctl[3]; ++ int8_t rs_rssi_ext[3]; + u8 rs_isaggr; + u8 rs_moreaggr; + u8 rs_num_delims; +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -955,6 +955,7 @@ static int ath9k_rx_skb_preprocess(struc + bool *decrypt_error) + { + struct ath_hw *ah = common->ah; ++ int i, j; + + /* + * everything but the rate is checked here, the rate check is done +@@ -980,6 +981,20 @@ static int ath9k_rx_skb_preprocess(struc + if (rx_stats->rs_moreaggr) + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; + ++ for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) { ++ s8 rssi; ++ ++ if (!(ah->rxchainmask & BIT(i))) ++ continue; ++ ++ rssi = rx_stats->rs_rssi_ctl[i]; ++ if (rssi != ATH9K_RSSI_BAD) { ++ rx_status->chains |= BIT(j); ++ rx_status->chain_signal[j] = ah->noise + rssi; ++ } ++ j++; ++ } ++ + return 0; + } + +--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c +@@ -458,12 +458,12 @@ int ath9k_hw_process_rxdesc_edma(struct + + /* XXX: Keycache */ + rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined); +- rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00); +- rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01); +- rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02); +- rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10); +- rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11); +- rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12); ++ rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00); ++ rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01); ++ rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02); ++ rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10); ++ rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11); ++ rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12); + + if (rxsp->status11 & AR_RxKeyIdxValid) + rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx); +--- a/drivers/net/wireless/ath/ath9k/mac.c ++++ b/drivers/net/wireless/ath/ath9k/mac.c +@@ -553,25 +553,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a + + if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) { + rs->rs_rssi = ATH9K_RSSI_BAD; +- rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ext0 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ext1 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ext2 = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD; + } else { + rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); +- rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0, ++ rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0, + AR_RxRSSIAnt00); +- rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0, ++ rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0, + AR_RxRSSIAnt01); +- rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0, ++ rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0, + AR_RxRSSIAnt02); +- rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4, ++ rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4, + AR_RxRSSIAnt10); +- rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4, ++ rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4, + AR_RxRSSIAnt11); +- rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4, ++ rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4, + AR_RxRSSIAnt12); + } + if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -997,12 +997,12 @@ void ath_debug_stat_rx(struct ath_softc + #ifdef CONFIG_ATH9K_MAC_DEBUG + spin_lock(&sc->debug.samp_lock); + RX_SAMP_DBG(jiffies) = jiffies; +- RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0; +- RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1; +- RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2; +- RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0; +- RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1; +- RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2; ++ RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl[0]; ++ RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl[1]; ++ RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl[2]; ++ RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext[0]; ++ RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext[1]; ++ RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext[2]; + RX_SAMP_DBG(antenna) = rs->rs_antenna; + RX_SAMP_DBG(rssi) = rs->rs_rssi; + RX_SAMP_DBG(rate) = rs->rs_rate; +--- a/include/linux/nl80211.h ++++ b/include/linux/nl80211.h +@@ -1760,6 +1760,8 @@ enum nl80211_sta_bss_param { + * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update. + * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32) + * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64) ++ * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU ++ * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average + * @__NL80211_STA_INFO_AFTER_LAST: internal + * @NL80211_STA_INFO_MAX: highest possible station info attribute + */ +@@ -1784,6 +1786,8 @@ enum nl80211_sta_info { + NL80211_STA_INFO_STA_FLAGS, + NL80211_STA_INFO_BEACON_LOSS, + NL80211_STA_INFO_T_OFFSET, ++ NL80211_STA_INFO_CHAIN_SIGNAL, ++ NL80211_STA_INFO_CHAIN_SIGNAL_AVG, + + /* keep last */ + __NL80211_STA_INFO_AFTER_LAST, +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -2769,6 +2769,32 @@ nla_put_failure: + return false; + } + ++static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal, ++ int id) ++{ ++ void *attr; ++ int i = 0; ++ ++ if (!mask) ++ return true; ++ ++ attr = nla_nest_start(msg, id); ++ if (!attr) ++ return false; ++ ++ for (i = 0; i < 4; i++) { ++ if (!(mask & BIT(i))) ++ continue; ++ ++ if (nla_put_u8(msg, i, signal[i])) ++ return false; ++ } ++ ++ nla_nest_end(msg, attr); ++ ++ return true; ++} ++ + static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, + int flags, + struct cfg80211_registered_device *rdev, +@@ -2830,6 +2856,18 @@ static int nl80211_send_station(struct s + default: + break; + } ++ if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) { ++ if (!nl80211_put_signal(msg, sinfo->chains, ++ sinfo->chain_signal, ++ NL80211_STA_INFO_CHAIN_SIGNAL)) ++ goto nla_put_failure; ++ } ++ if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) { ++ if (!nl80211_put_signal(msg, sinfo->chains, ++ sinfo->chain_signal_avg, ++ NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) ++ goto nla_put_failure; ++ } + if (sinfo->filled & STATION_INFO_TX_BITRATE) { + if (!nl80211_put_sta_rate(msg, &sinfo->txrate, + NL80211_STA_INFO_TX_BITRATE)) +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -367,6 +367,7 @@ static void sta_set_sinfo(struct sta_inf + struct ieee80211_sub_if_data *sdata = sta->sdata; + struct ieee80211_local *local = sdata->local; + struct timespec uptime; ++ int i; + + sinfo->generation = sdata->local->sta_generation; + +@@ -406,6 +407,17 @@ static void sta_set_sinfo(struct sta_inf + sinfo->signal = (s8)sta->last_signal; + sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); + } ++ if (sta->chains) { ++ sinfo->filled |= STATION_INFO_CHAIN_SIGNAL | ++ STATION_INFO_CHAIN_SIGNAL_AVG; ++ ++ sinfo->chains = sta->chains; ++ for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { ++ sinfo->chain_signal[i] = sta->chain_signal_last[i]; ++ sinfo->chain_signal_avg[i] = ++ (s8) -ewma_read(&sta->chain_signal_avg[i]); ++ } ++ } + + sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); + +--- a/drivers/net/wireless/ath/ath9k/dfs.c ++++ b/drivers/net/wireless/ath/ath9k/dfs.c +@@ -164,8 +164,8 @@ void ath9k_dfs_process_phyerr(struct ath + return; + } + +- ard.rssi = rs->rs_rssi_ctl0; +- ard.ext_rssi = rs->rs_rssi_ext0; ++ ard.rssi = rs->rs_rssi_ctl[0]; ++ ard.ext_rssi = rs->rs_rssi_ext[0]; + + /* + * hardware stores this as 8 bit signed value. +--- a/drivers/net/wireless/ath/ath9k/antenna.c ++++ b/drivers/net/wireless/ath/ath9k/antenna.c +@@ -529,14 +529,14 @@ void ath_ant_comb_scan(struct ath_softc + struct ath_ant_comb *antcomb = &sc->ant_comb; + int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; + int curr_main_set; +- int main_rssi = rs->rs_rssi_ctl0; +- int alt_rssi = rs->rs_rssi_ctl1; ++ int main_rssi = rs->rs_rssi_ctl[0]; ++ int alt_rssi = rs->rs_rssi_ctl[1]; + int rx_ant_conf, main_ant_conf; + bool short_scan = false; + +- rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & ++ rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) & + ATH_ANT_RX_MASK; +- main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & ++ main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) & + ATH_ANT_RX_MASK; + + /* Record packet only when both main_rssi and alt_rssi is positive */ diff --git a/package/mac80211/patches/523-cfg80211_fix_antenna_gain.patch b/package/mac80211/patches/523-cfg80211_fix_antenna_gain.patch new file mode 100644 index 000000000..98f3d9675 --- /dev/null +++ b/package/mac80211/patches/523-cfg80211_fix_antenna_gain.patch @@ -0,0 +1,12 @@ +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -908,8 +908,7 @@ static void handle_channel(struct wiphy + + chan->beacon_found = false; + chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags); +- chan->max_antenna_gain = min(chan->orig_mag, +- (int) MBI_TO_DBI(power_rule->max_antenna_gain)); ++ chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); + chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp); + if (chan->orig_mpwr) { + /* diff --git a/package/mac80211/patches/524-mac80211_configure_antenna_gain.patch b/package/mac80211/patches/524-mac80211_configure_antenna_gain.patch new file mode 100644 index 000000000..b2870a8aa --- /dev/null +++ b/package/mac80211/patches/524-mac80211_configure_antenna_gain.patch @@ -0,0 +1,179 @@ +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -851,6 +851,7 @@ enum ieee80211_smps_mode { + * the CONF_PS flag is set. + * + * @power_level: requested transmit power (in dBm) ++ * @max_antenna_gain: maximum antenna gain adjusted by user config (in dBi) + * + * @channel: the channel to tune to + * @channel_type: the channel (HT) type +@@ -870,6 +871,7 @@ struct ieee80211_conf { + u32 flags; + int power_level, dynamic_ps_timeout; + int max_sleep_period; ++ int max_antenna_gain; + + u16 listen_interval; + u8 ps_dtim_period; +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -101,7 +101,7 @@ int ieee80211_hw_config(struct ieee80211 + { + struct ieee80211_channel *chan; + int ret = 0; +- int power; ++ int power, ant_gain, max_power; + enum nl80211_channel_type channel_type; + u32 offchannel_flag; + +@@ -152,19 +152,31 @@ int ieee80211_hw_config(struct ieee80211 + changed |= IEEE80211_CONF_CHANGE_SMPS; + } + +- if (test_bit(SCAN_SW_SCANNING, &local->scanning) || +- test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || +- test_bit(SCAN_HW_SCANNING, &local->scanning) || +- !local->ap_power_level) +- power = chan->max_power; +- else +- power = min(chan->max_power, local->ap_power_level); ++ max_power = chan->max_reg_power; ++ if (!test_bit(SCAN_SW_SCANNING, &local->scanning) && ++ !test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) && ++ !test_bit(SCAN_HW_SCANNING, &local->scanning) && ++ local->ap_power_level) ++ max_power = min(max_power, local->ap_power_level); ++ ++ ant_gain = chan->max_antenna_gain; ++ if (local->user_antenna_gain > 0) { ++ if (local->user_antenna_gain > ant_gain) { ++ max_power -= local->user_antenna_gain - ant_gain; ++ ant_gain = 0; ++ } else ++ ant_gain -= local->user_antenna_gain; ++ } ++ ++ power = min(chan->max_power, max_power); + + if (local->user_power_level >= 0) + power = min(power, local->user_power_level); + +- if (local->hw.conf.power_level != power) { ++ if (local->hw.conf.power_level != power || ++ local->hw.conf.max_antenna_gain != ant_gain) { + changed |= IEEE80211_CONF_CHANGE_POWER; ++ local->hw.conf.max_antenna_gain = ant_gain; + local->hw.cur_power_level = power; + local->hw.conf.power_level = power; + } +@@ -620,6 +632,7 @@ struct ieee80211_hw *ieee80211_alloc_hw( + IEEE80211_RADIOTAP_MCS_HAVE_GI | + IEEE80211_RADIOTAP_MCS_HAVE_BW; + local->user_power_level = -1; ++ local->user_antenna_gain = -1; + wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; + + INIT_LIST_HEAD(&local->interfaces); +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1063,6 +1063,7 @@ struct ieee80211_local { + + int user_power_level; /* in dBm */ + int ap_power_level; /* in dBm */ ++ int user_antenna_gain; /* in dBi */ + + enum ieee80211_smps_mode smps_mode; + +--- a/include/linux/nl80211.h ++++ b/include/linux/nl80211.h +@@ -1517,6 +1517,8 @@ enum nl80211_attrs { + + NL80211_ATTR_USER_REG_HINT_TYPE, + ++ NL80211_ATTR_WIPHY_ANTENNA_GAIN, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -355,6 +355,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, + [NL80211_ATTR_WDEV] = { .type = NLA_U64 }, + [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 }, ++ [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, + }; + + /* policy for the key attributes */ +@@ -1604,6 +1605,22 @@ static int nl80211_set_wiphy(struct sk_b + goto bad_res; + } + ++ if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) { ++ int idx, dbi = 0; ++ ++ if (!rdev->ops->set_antenna_gain) { ++ result = -EOPNOTSUPP; ++ goto bad_res; ++ } ++ ++ idx = NL80211_ATTR_WIPHY_ANTENNA_GAIN; ++ dbi = nla_get_u32(info->attrs[idx]); ++ ++ result = rdev->ops->set_antenna_gain(&rdev->wiphy, dbi); ++ if (result) ++ goto bad_res; ++ } ++ + if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && + info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { + u32 tx_ant, rx_ant; +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1984,6 +1984,19 @@ static int ieee80211_get_tx_power(struct + return 0; + } + ++static int ieee80211_set_antenna_gain(struct wiphy *wiphy, int dbi) ++{ ++ struct ieee80211_local *local = wiphy_priv(wiphy); ++ ++ if (dbi < 0) ++ return -EINVAL; ++ ++ local->user_antenna_gain = dbi; ++ ieee80211_hw_config(local, 0); ++ ++ return 0; ++} ++ + static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, + const u8 *addr) + { +@@ -3082,6 +3095,7 @@ struct cfg80211_ops mac80211_config_ops + .set_wiphy_params = ieee80211_set_wiphy_params, + .set_tx_power = ieee80211_set_tx_power, + .get_tx_power = ieee80211_get_tx_power, ++ .set_antenna_gain = ieee80211_set_antenna_gain, + .set_wds_peer = ieee80211_set_wds_peer, + .rfkill_poll = ieee80211_rfkill_poll, + CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -1551,6 +1551,7 @@ struct cfg80211_gtk_rekey_data { + * the power passed is in mBm, to get dBm use MBM_TO_DBM(). + * @get_tx_power: store the current TX power into the dbm variable; + * return 0 if successful ++ * @set_antenna_gain: set antenna gain to reduce maximum tx power if necessary + * + * @set_wds_peer: set the WDS peer for a WDS interface + * +@@ -1750,6 +1751,7 @@ struct cfg80211_ops { + int (*set_tx_power)(struct wiphy *wiphy, + enum nl80211_tx_power_setting type, int mbm); + int (*get_tx_power)(struct wiphy *wiphy, int *dbm); ++ int (*set_antenna_gain)(struct wiphy *wiphy, int dbi); + + int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, + const u8 *addr); diff --git a/package/mac80211/patches/525-ath9k_use_configured_antenna_gain.patch b/package/mac80211/patches/525-ath9k_use_configured_antenna_gain.patch new file mode 100644 index 000000000..35096b255 --- /dev/null +++ b/package/mac80211/patches/525-ath9k_use_configured_antenna_gain.patch @@ -0,0 +1,34 @@ +--- a/drivers/net/wireless/ath/ath.h ++++ b/drivers/net/wireless/ath/ath.h +@@ -73,6 +73,7 @@ struct ath_regulatory { + u16 max_power_level; + u16 current_rd; + int16_t power_limit; ++ int16_t max_antenna_gain; + struct reg_dmn_pair_mapping *regpair; + }; + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -2828,7 +2828,7 @@ void ath9k_hw_apply_txpower(struct ath_h + channel = chan->chan; + chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER); + new_pwr = min_t(int, chan_pwr, reg->power_limit); +- max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2; ++ max_gain = chan_pwr - new_pwr + reg->max_antenna_gain * 2; + + ant_gain = get_antenna_gain(ah, chan); + if (ant_gain > max_gain) +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1263,7 +1263,10 @@ int ath9k_config(struct ieee80211_hw *hw + } + + if (changed & IEEE80211_CONF_CHANGE_POWER) { ++ struct ath_regulatory *reg = ath9k_hw_regulatory(ah); ++ + ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level); ++ reg->max_antenna_gain = conf->max_antenna_gain; + sc->config.txpowlimit = 2 * conf->power_level; + ath9k_cmn_update_txpow(ah, sc->curtxpow, + sc->config.txpowlimit, &sc->curtxpow); diff --git a/package/mac80211/patches/526-cfg80211_fix_max_reg_power.patch b/package/mac80211/patches/526-cfg80211_fix_max_reg_power.patch new file mode 100644 index 000000000..6f8d53f95 --- /dev/null +++ b/package/mac80211/patches/526-cfg80211_fix_max_reg_power.patch @@ -0,0 +1,21 @@ +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -901,7 +901,7 @@ static void handle_channel(struct wiphy + map_regdom_flags(reg_rule->flags) | bw_flags; + chan->max_antenna_gain = chan->orig_mag = + (int) MBI_TO_DBI(power_rule->max_antenna_gain); +- chan->max_power = chan->orig_mpwr = ++ chan->max_reg_power = chan->max_power = chan->orig_mpwr = + (int) MBM_TO_DBM(power_rule->max_eirp); + return; + } +@@ -1323,7 +1323,8 @@ static void handle_channel_custom(struct + + chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; + chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); +- chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); ++ chan->max_reg_power = chan->max_power = ++ (int) MBM_TO_DBM(power_rule->max_eirp); + } + + static void handle_band_custom(struct wiphy *wiphy, enum ieee80211_band band, diff --git a/package/mac80211/patches/530-ath9k_fix_initvals.patch b/package/mac80211/patches/530-ath9k_fix_initvals.patch new file mode 100644 index 000000000..d86e718f0 --- /dev/null +++ b/package/mac80211/patches/530-ath9k_fix_initvals.patch @@ -0,0 +1,208 @@ +--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +@@ -534,108 +534,108 @@ static const u32 ar9300_2p2_baseband_cor + + static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +- {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, +- {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, +- {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, ++ {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, ++ {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, ++ {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, +- {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, +- {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, +- {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, +- {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, +- {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202}, +- {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400}, +- {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402}, +- {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404}, +- {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603}, +- {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02}, +- {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04}, +- {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20}, +- {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20}, +- {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22}, +- {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24}, +- {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640}, +- {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660}, +- {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861}, +- {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81}, +- {0x0000a54c, 0x5a08442e, 0x5a08442e, 0x47001a83, 0x47001a83}, +- {0x0000a550, 0x5e0a4431, 0x5e0a4431, 0x4a001c84, 0x4a001c84}, +- {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3}, +- {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5}, +- {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9}, +- {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb}, +- {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, +- {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, +- {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, +- {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, +- {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, +- {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202}, +- {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400}, +- {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402}, +- {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404}, +- {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603}, +- {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02}, +- {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04}, +- {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20}, +- {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20}, +- {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22}, +- {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24}, +- {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640}, +- {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660}, +- {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861}, +- {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81}, +- {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83}, +- {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84}, +- {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3}, +- {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5}, +- {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9}, +- {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb}, +- {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, +- {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, ++ {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, ++ {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, ++ {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, ++ {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, ++ {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, ++ {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, ++ {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, ++ {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, ++ {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, ++ {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, ++ {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, ++ {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, ++ {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, ++ {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, ++ {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, ++ {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, ++ {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, ++ {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, ++ {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, ++ {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, ++ {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, ++ {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, ++ {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, ++ {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, ++ {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, ++ {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, ++ {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, ++ {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, ++ {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, ++ {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, ++ {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, ++ {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, ++ {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, ++ {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, ++ {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, ++ {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, ++ {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, ++ {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, ++ {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, ++ {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, ++ {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, ++ {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, ++ {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, ++ {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, ++ {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, ++ {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, ++ {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, ++ {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, ++ {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, ++ {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, ++ {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, ++ {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, ++ {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, ++ {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, ++ {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, ++ {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, ++ {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, ++ {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, ++ {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, ++ {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, ++ {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, ++ {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, ++ {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, ++ {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, ++ {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, +- {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, +- {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, +- {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000}, +- {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501}, +- {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501}, +- {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03}, +- {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, +- {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04}, +- {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, +- {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, +- {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, +- {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, ++ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, ++ {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, ++ {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, ++ {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, ++ {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, ++ {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, ++ {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, ++ {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, ++ {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, ++ {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, ++ {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, +- {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, +- {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, +- {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, ++ {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, ++ {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, ++ {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, +- {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, +- {0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, +- {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, +- {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, +- {0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, +- {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, +- {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, +- {0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001}, +- {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, ++ {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, ++ {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, ++ {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, ++ {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, ++ {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, ++ {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, ++ {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, ++ {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, ++ {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, + }; + + static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = { diff --git a/package/mac80211/patches/540-ath9k_extra_leds.patch b/package/mac80211/patches/540-ath9k_extra_leds.patch new file mode 100644 index 000000000..86dc51856 --- /dev/null +++ b/package/mac80211/patches/540-ath9k_extra_leds.patch @@ -0,0 +1,258 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -538,6 +538,9 @@ struct ath9k_wow_pattern { + #ifdef CONFIG_MAC80211_LEDS + void ath_init_leds(struct ath_softc *sc); + void ath_deinit_leds(struct ath_softc *sc); ++int ath_create_gpio_led(struct ath_softc *sc, int gpio, const char *name, ++ const char *trigger, bool active_low); ++ + #else + static inline void ath_init_leds(struct ath_softc *sc) + { +@@ -655,6 +658,13 @@ struct ath9k_vif_iter_data { + int nadhocs; /* number of adhoc vifs */ + }; + ++struct ath_led { ++ struct list_head list; ++ struct ath_softc *sc; ++ const struct gpio_led *gpio; ++ struct led_classdev cdev; ++}; ++ + struct ath_softc { + struct ieee80211_hw *hw; + struct device *dev; +@@ -696,9 +706,8 @@ struct ath_softc { + struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; + + #ifdef CONFIG_MAC80211_LEDS +- bool led_registered; +- char led_name[32]; +- struct led_classdev led_cdev; ++ const char *led_default_trigger; ++ struct list_head leds; + #endif + + struct ath9k_hw_cal_data caldata; +--- a/drivers/net/wireless/ath/ath9k/gpio.c ++++ b/drivers/net/wireless/ath/ath9k/gpio.c +@@ -24,22 +24,89 @@ + static void ath_led_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) + { +- struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev); +- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF)); ++ struct ath_led *led = container_of(led_cdev, struct ath_led, cdev); ++ struct ath_softc *sc = led->sc; ++ ++ ath9k_ps_wakeup(sc); ++ ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio, ++ (brightness != LED_OFF) ^ led->gpio->active_low); ++ ath9k_ps_restore(sc); ++} ++ ++static int ath_add_led(struct ath_softc *sc, struct ath_led *led) ++{ ++ const struct gpio_led *gpio = led->gpio; ++ int ret; ++ ++ led->cdev.name = gpio->name; ++ led->cdev.default_trigger = gpio->default_trigger; ++ led->cdev.brightness_set = ath_led_brightness; ++ ++ ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->cdev); ++ if (ret < 0) ++ return ret; ++ ++ led->sc = sc; ++ list_add(&led->list, &sc->leds); ++ ++ /* Configure gpio for output */ ++ ath9k_hw_cfg_output(sc->sc_ah, gpio->gpio, ++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ++ ++ /* LED off */ ++ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); ++ ++ return 0; ++} ++ ++int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name, ++ const char *trigger, bool active_low) ++{ ++ struct ath_led *led; ++ struct gpio_led *gpio; ++ char *_name; ++ int ret; ++ ++ led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1, ++ GFP_KERNEL); ++ if (!led) ++ return -ENOMEM; ++ ++ led->gpio = gpio = (struct gpio_led *) (led + 1); ++ _name = (char *) (led->gpio + 1); ++ ++ strcpy(_name, name); ++ gpio->name = _name; ++ gpio->gpio = gpio_num; ++ gpio->active_low = active_low; ++ gpio->default_trigger = trigger; ++ ++ ret = ath_add_led(sc, led); ++ if (unlikely(ret < 0)) ++ kfree(led); ++ ++ return ret; + } + + void ath_deinit_leds(struct ath_softc *sc) + { +- if (!sc->led_registered) +- return; ++ struct ath_led *led; + +- ath_led_brightness(&sc->led_cdev, LED_OFF); +- led_classdev_unregister(&sc->led_cdev); ++ while (!list_empty(&sc->leds)) { ++ led = list_first_entry(&sc->leds, struct ath_led, list); ++ list_del(&led->list); ++ ath_led_brightness(&led->cdev, LED_OFF); ++ led_classdev_unregister(&led->cdev); ++ kfree(led); ++ } + } + + void ath_init_leds(struct ath_softc *sc) + { +- int ret; ++ char led_name[32]; ++ const char *trigger; ++ ++ INIT_LIST_HEAD(&sc->leds); + + if (AR_SREV_9100(sc->sc_ah)) + return; +@@ -57,26 +124,15 @@ void ath_init_leds(struct ath_softc *sc) + sc->sc_ah->led_pin = ATH_LED_PIN_DEF; + } + +- /* Configure gpio 1 for output */ +- ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, +- AR_GPIO_OUTPUT_MUX_AS_OUTPUT); +- /* LED off, active low */ +- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); +- +- if (!led_blink) +- sc->led_cdev.default_trigger = +- ieee80211_get_radio_led_name(sc->hw); +- +- snprintf(sc->led_name, sizeof(sc->led_name), +- "ath9k-%s", wiphy_name(sc->hw->wiphy)); +- sc->led_cdev.name = sc->led_name; +- sc->led_cdev.brightness_set = ath_led_brightness; ++ snprintf(led_name, sizeof(led_name), "ath9k-%s", ++ wiphy_name(sc->hw->wiphy)); + +- ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev); +- if (ret < 0) +- return; ++ if (led_blink) ++ trigger = sc->led_default_trigger; ++ else ++ trigger = ieee80211_get_radio_led_name(sc->hw); + +- sc->led_registered = true; ++ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, 1); + } + #endif + +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -811,7 +811,7 @@ int ath9k_init_device(u16 devid, struct + + #ifdef CONFIG_MAC80211_LEDS + /* must be initialized before ieee80211_register_hw */ +- sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, ++ sc->led_default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, + IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink, + ARRAY_SIZE(ath9k_tpt_blink)); + #endif +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1255,6 +1255,61 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++#ifdef CONFIG_MAC80211_LEDS ++ ++static ssize_t write_file_gpio_led(struct file *file, const char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ char buf[32], *str, *name, *c; ++ ssize_t len; ++ unsigned int gpio; ++ bool active_low = false; ++ ++ len = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, ubuf, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ name = strchr(buf, ','); ++ if (!name) ++ return -EINVAL; ++ ++ *(name++) = 0; ++ if (!*name) ++ return -EINVAL; ++ ++ c = strchr(name, '\n'); ++ if (c) ++ *c = 0; ++ ++ str = buf; ++ if (*str == '!') { ++ str++; ++ active_low = true; ++ } ++ ++ if (kstrtouint(str, 0, &gpio) < 0) ++ return -EINVAL; ++ ++ if (gpio >= sc->sc_ah->caps.num_gpio_pins) ++ return -EINVAL; ++ ++ if (ath_create_gpio_led(sc, gpio, name, NULL, active_low) < 0) ++ return -EINVAL; ++ ++ return count; ++} ++ ++static const struct file_operations fops_gpio_led = { ++ .write = write_file_gpio_led, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++#endif ++ + #ifdef CONFIG_ATH9K_MAC_DEBUG + + void ath9k_debug_samp_bb_mac(struct ath_softc *sc) +@@ -1688,6 +1743,11 @@ int ath9k_init_debug(struct ath_hw *ah) + &fops_samps); + #endif + ++#ifdef CONFIG_MAC80211_LEDS ++ debugfs_create_file("gpio_led", S_IWUSR, ++ sc->debug.debugfs_phy, sc, &fops_gpio_led); ++#endif ++ + debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, + sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); + diff --git a/package/mac80211/patches/541-ath9k_extra_platform_leds.patch b/package/mac80211/patches/541-ath9k_extra_platform_leds.patch new file mode 100644 index 000000000..ac8ee533d --- /dev/null +++ b/package/mac80211/patches/541-ath9k_extra_platform_leds.patch @@ -0,0 +1,71 @@ +--- a/include/linux/ath9k_platform.h ++++ b/include/linux/ath9k_platform.h +@@ -33,6 +33,9 @@ struct ath9k_platform_data { + bool is_clk_25mhz; + int (*get_mac_revision)(void); + int (*external_reset)(void); ++ ++ int num_leds; ++ const struct gpio_led *leds; + }; + + #endif /* _LINUX_ATH9K_PLATFORM_H */ +--- a/drivers/net/wireless/ath/ath9k/gpio.c ++++ b/drivers/net/wireless/ath/ath9k/gpio.c +@@ -14,6 +14,7 @@ + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + ++#include <linux/ath9k_platform.h> + #include "ath9k.h" + + /********************************/ +@@ -88,6 +89,24 @@ int ath_create_gpio_led(struct ath_softc + return ret; + } + ++static int ath_create_platform_led(struct ath_softc *sc, ++ const struct gpio_led *gpio) ++{ ++ struct ath_led *led; ++ int ret; ++ ++ led = kzalloc(sizeof(*led), GFP_KERNEL); ++ if (!led) ++ return -ENOMEM; ++ ++ led->gpio = gpio; ++ ret = ath_add_led(sc, led); ++ if (ret < 0) ++ kfree(led); ++ ++ return ret; ++} ++ + void ath_deinit_leds(struct ath_softc *sc) + { + struct ath_led *led; +@@ -103,8 +122,10 @@ void ath_deinit_leds(struct ath_softc *s + + void ath_init_leds(struct ath_softc *sc) + { ++ struct ath9k_platform_data *pdata = sc->dev->platform_data; + char led_name[32]; + const char *trigger; ++ int i; + + INIT_LIST_HEAD(&sc->leds); + +@@ -133,6 +154,12 @@ void ath_init_leds(struct ath_softc *sc) + trigger = ieee80211_get_radio_led_name(sc->hw); + + ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, 1); ++ ++ if (!pdata) ++ return; ++ ++ for (i = 0; i < pdata->num_leds; i++) ++ ath_create_platform_led(sc, &pdata->leds[i]); + } + #endif + diff --git a/package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch b/package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch new file mode 100644 index 000000000..53889d19c --- /dev/null +++ b/package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch @@ -0,0 +1,98 @@ +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -715,6 +715,8 @@ struct ieee80211_sub_if_data { + + /* bitmap of allowed (non-MCS) rate indexes for rate control */ + u32 rc_rateidx_mask[IEEE80211_NUM_BANDS]; ++ ++ bool rc_has_mcs_mask[IEEE80211_NUM_BANDS]; + u8 rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN]; + + union { +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2160,9 +2160,20 @@ static int ieee80211_set_bitrate_mask(st + } + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) { ++ struct ieee80211_supported_band *sband = wiphy->bands[i]; ++ + sdata->rc_rateidx_mask[i] = mask->control[i].legacy; + memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs, + sizeof(mask->control[i].mcs)); ++ ++ sdata->rc_has_mcs_mask[i] = false; ++ if (!sband) ++ continue; ++ ++ if (memcmp(sdata->rc_rateidx_mcs_mask[i], ++ sband->ht_cap.mcs.rx_mask, ++ sizeof(sband->ht_cap.mcs.rx_mask)) != 0) ++ sdata->rc_has_mcs_mask[i] = true; + } + + return 0; +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -3721,7 +3721,7 @@ void ieee80211_send_bar(struct ieee80211 + * (deprecated; this will be removed once drivers get updated to use + * rate_idx_mask) + * @rate_idx_mask: user-requested (legacy) rate mask +- * @rate_idx_mcs_mask: user-requested MCS rate mask ++ * @rate_idx_mcs_mask: user-requested MCS rate mask (NULL if not in use) + * @bss: whether this frame is sent out in AP or IBSS mode + */ + struct ieee80211_tx_rate_control { +@@ -3733,7 +3733,7 @@ struct ieee80211_tx_rate_control { + bool rts, short_preamble; + u8 max_rate_idx; + u32 rate_idx_mask; +- u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN]; ++ u8 *rate_idx_mcs_mask; + bool bss; + }; + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -631,9 +631,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021 + txrc.max_rate_idx = -1; + else + txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; +- memcpy(txrc.rate_idx_mcs_mask, +- tx->sdata->rc_rateidx_mcs_mask[info->band], +- sizeof(txrc.rate_idx_mcs_mask)); ++ ++ if (tx->sdata->rc_has_mcs_mask[info->band]) ++ txrc.rate_idx_mcs_mask = ++ tx->sdata->rc_rateidx_mcs_mask[info->band]; ++ + txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP || + tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT || + tx->sdata->vif.type == NL80211_IFTYPE_ADHOC); +@@ -2447,8 +2449,6 @@ struct sk_buff *ieee80211_beacon_get_tim + txrc.max_rate_idx = -1; + else + txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; +- memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band], +- sizeof(txrc.rate_idx_mcs_mask)); + txrc.bss = true; + rate_control_get_rate(sdata, NULL, &txrc); + +--- a/net/mac80211/rate.c ++++ b/net/mac80211/rate.c +@@ -461,9 +461,12 @@ void rate_control_get_rate(struct ieee80 + * the common case. + */ + mask = sdata->rc_rateidx_mask[info->band]; +- memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band], +- sizeof(mcs_mask)); +- if (mask != (1 << txrc->sband->n_bitrates) - 1) { ++ if (mask != (1 << txrc->sband->n_bitrates) - 1 || txrc->rate_idx_mcs_mask) { ++ if (txrc->rate_idx_mcs_mask) ++ memcpy(mcs_mask, txrc->rate_idx_mcs_mask, sizeof(mcs_mask)); ++ else ++ memset(mcs_mask, 0xff, sizeof(mcs_mask)); ++ + if (sta) { + /* Filter out rates that the STA does not support */ + mask &= sta->sta.supp_rates[info->band]; diff --git a/package/mac80211/patches/551-ath9k_optimize_interrupt_mitigation.patch b/package/mac80211/patches/551-ath9k_optimize_interrupt_mitigation.patch new file mode 100644 index 000000000..2afc4deb4 --- /dev/null +++ b/package/mac80211/patches/551-ath9k_optimize_interrupt_mitigation.patch @@ -0,0 +1,30 @@ +--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c +@@ -240,21 +240,19 @@ static bool ar9003_hw_get_isr(struct ath + + *masked = isr & ATH9K_INT_COMMON; + +- if (ah->config.rx_intr_mitigation) ++ if (ah->config.rx_intr_mitigation) { + if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) + *masked |= ATH9K_INT_RXLP; +- +- if (ah->config.tx_intr_mitigation) +- if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM)) +- *masked |= ATH9K_INT_TX; +- +- if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR)) ++ } else if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR)) + *masked |= ATH9K_INT_RXLP; + + if (isr & AR_ISR_HP_RXOK) + *masked |= ATH9K_INT_RXHP; + +- if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) { ++ if (ah->config.tx_intr_mitigation) { ++ if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM)) ++ *masked |= ATH9K_INT_TX; ++ } else if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) { + *masked |= ATH9K_INT_TX; + + if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { diff --git a/package/mac80211/patches/560-ath9k_reduce_ani_interval.patch b/package/mac80211/patches/560-ath9k_reduce_ani_interval.patch new file mode 100644 index 000000000..e2a0d124a --- /dev/null +++ b/package/mac80211/patches/560-ath9k_reduce_ani_interval.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath9k/ani.h ++++ b/drivers/net/wireless/ath/ath9k/ani.h +@@ -51,7 +51,7 @@ + #define ATH9K_ANI_PERIOD 300 + + /* in ms */ +-#define ATH9K_ANI_POLLINTERVAL 1000 ++#define ATH9K_ANI_POLLINTERVAL 100 + + #define HAL_NOISE_IMMUNE_MAX 4 + #define HAL_SPUR_IMMUNE_MAX 7 diff --git a/package/mac80211/patches/561-ath9k_revert_initval_change.patch b/package/mac80211/patches/561-ath9k_revert_initval_change.patch new file mode 100644 index 000000000..49aea350c --- /dev/null +++ b/package/mac80211/patches/561-ath9k_revert_initval_change.patch @@ -0,0 +1,19 @@ +--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +@@ -778,11 +778,11 @@ static const u32 ar9300Common_rx_gain_ta + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, +- {0x0000a080, 0x1a1a1a1a}, +- {0x0000a084, 0x1a1a1a1a}, +- {0x0000a088, 0x1a1a1a1a}, +- {0x0000a08c, 0x1a1a1a1a}, +- {0x0000a090, 0x171a1a1a}, ++ {0x0000a080, 0x22222229}, ++ {0x0000a084, 0x1d1d1d1d}, ++ {0x0000a088, 0x1d1d1d1d}, ++ {0x0000a08c, 0x1d1d1d1d}, ++ {0x0000a090, 0x171d1d1d}, + {0x0000a094, 0x11111717}, + {0x0000a098, 0x00030311}, + {0x0000a09c, 0x00000000}, diff --git a/package/mac80211/patches/562-ath9k_add_idle_hack.patch b/package/mac80211/patches/562-ath9k_add_idle_hack.patch new file mode 100644 index 000000000..10fac17bd --- /dev/null +++ b/package/mac80211/patches/562-ath9k_add_idle_hack.patch @@ -0,0 +1,20 @@ +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1087,6 +1087,7 @@ static void ath9k_remove_interface(struc + ath9k_calculate_summary_state(hw, NULL); + + mutex_unlock(&sc->mutex); ++ ath9k_config(hw, IEEE80211_CONF_CHANGE_IDLE); + ath9k_ps_restore(sc); + } + +@@ -1139,7 +1140,8 @@ int ath9k_config(struct ieee80211_hw *hw + mutex_lock(&sc->mutex); + + if (changed & IEEE80211_CONF_CHANGE_IDLE) { +- sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); ++ sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE) && ++ !sc->nvifs; + if (sc->ps_idle) { + ath_cancel_work(sc); + ath9k_stop_btcoex(sc); diff --git a/package/mac80211/patches/563-ath9k_rx_dma_stop_check.patch b/package/mac80211/patches/563-ath9k_rx_dma_stop_check.patch new file mode 100644 index 000000000..606eb1c63 --- /dev/null +++ b/package/mac80211/patches/563-ath9k_rx_dma_stop_check.patch @@ -0,0 +1,28 @@ +--- a/drivers/net/wireless/ath/ath9k/mac.c ++++ b/drivers/net/wireless/ath/ath9k/mac.c +@@ -689,7 +689,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw + { + #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ + struct ath_common *common = ath9k_hw_common(ah); +- u32 mac_status, last_mac_status = 0; ++ u32 mac_status = 0, last_mac_status = 0; + int i; + + /* Enable access to the DMA observation bus */ +@@ -719,6 +719,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw + } + + if (i == 0) { ++ if (!AR_SREV_9300_20_OR_LATER(ah) && ++ (mac_status & 0x700) == 0) { ++ /* ++ * DMA is idle but the MAC is still stuck ++ * processing events ++ */ ++ *reset = true; ++ return true; ++ } ++ + ath_err(common, + "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x DMADBG_7=0x%08x\n", + AH_RX_STOP_DMA_TIMEOUT / 1000, diff --git a/package/mac80211/patches/564-ath9k_debugfs_diag.patch b/package/mac80211/patches/564-ath9k_debugfs_diag.patch new file mode 100644 index 000000000..2cf2a73e0 --- /dev/null +++ b/package/mac80211/patches/564-ath9k_debugfs_diag.patch @@ -0,0 +1,139 @@ +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1678,6 +1678,50 @@ static const struct file_operations fops + }; + + ++static ssize_t read_file_diag(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_hw *ah = sc->sc_ah; ++ char buf[32]; ++ unsigned int len; ++ ++ len = sprintf(buf, "0x%08lx\n", ah->diag); ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_diag(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_hw *ah = sc->sc_ah; ++ unsigned long diag; ++ char buf[32]; ++ ssize_t len; ++ ++ len = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ if (strict_strtoul(buf, 0, &diag)) ++ return -EINVAL; ++ ++ ah->diag = diag; ++ ath9k_hw_update_diag(ah); ++ ++ return count; ++} ++ ++static const struct file_operations fops_diag = { ++ .read = read_file_diag, ++ .write = write_file_diag, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++ + int ath9k_init_debug(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); +@@ -1760,5 +1804,8 @@ int ath9k_init_debug(struct ath_hw *ah) + debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, + sc, &fops_chanbw); + ++ debugfs_create_file("diag", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, ++ sc, &fops_diag); ++ + return 0; + } +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -498,6 +498,12 @@ enum { + ATH9K_RESET_COLD, + }; + ++enum { ++ ATH_DIAG_DISABLE_RX, ++ ATH_DIAG_DISABLE_TX, ++ ATH_DIAG_TRIGGER_ERROR, ++}; ++ + struct ath9k_hw_version { + u32 magic; + u16 devid; +@@ -741,6 +747,8 @@ struct ath_hw { + u32 rfkill_polarity; + u32 ah_flags; + ++ unsigned long diag; ++ + bool htc_reset_init; + + enum nl80211_iftype opmode; +@@ -1007,6 +1015,7 @@ void ath9k_hw_set_sta_beacon_timers(stru + bool ath9k_hw_check_alive(struct ath_hw *ah); + + bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); ++void ath9k_hw_update_diag(struct ath_hw *ah); + + #ifdef CONFIG_ATH9K_DEBUGFS + void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause); +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1749,6 +1749,20 @@ fail: + return -EINVAL; + } + ++void ath9k_hw_update_diag(struct ath_hw *ah) ++{ ++ if (test_bit(ATH_DIAG_DISABLE_RX, &ah->diag)) ++ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); ++ else ++ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); ++ ++ if (test_bit(ATH_DIAG_DISABLE_TX, &ah->diag)) ++ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK); ++ else ++ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK); ++} ++EXPORT_SYMBOL(ath9k_hw_update_diag); ++ + int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, + struct ath9k_hw_cal_data *caldata, bool fastcc) + { +@@ -2026,6 +2040,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st + } + + ath9k_hw_apply_gpio_override(ah); ++ ath9k_hw_update_diag(ah); + + return 0; + } +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -476,6 +476,11 @@ irqreturn_t ath_isr(int irq, void *dev) + ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ + status &= ah->imask; /* discard unasked-for bits */ + ++ if (test_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag)) { ++ status |= ATH9K_INT_FATAL; ++ clear_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag); ++ } ++ + /* + * If there are no status bits set, then this interrupt was not + * for me (should have been caught above). diff --git a/package/mac80211/patches/565-ath9k_disable_paprd.patch b/package/mac80211/patches/565-ath9k_disable_paprd.patch new file mode 100644 index 000000000..079986d60 --- /dev/null +++ b/package/mac80211/patches/565-ath9k_disable_paprd.patch @@ -0,0 +1,72 @@ +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1767,6 +1767,8 @@ int ath9k_init_debug(struct ath_hw *ah) + sc->debug.debugfs_phy, sc, &fops_tx_chainmask); + debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR, + sc->debug.debugfs_phy, sc, &fops_disable_ani); ++ debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, ++ &sc->sc_ah->config.enable_paprd); + debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, + sc, &fops_regidx); + debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -2521,10 +2521,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw + pCap->rx_status_len = sizeof(struct ar9003_rxs); + pCap->tx_desc_len = sizeof(struct ar9003_txc); + pCap->txs_len = sizeof(struct ar9003_txs); +- if (!ah->config.paprd_disable && +- ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && +- !AR_SREV_9462(ah)) +- pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; + } else { + pCap->tx_desc_len = sizeof(struct ath_desc); + if (AR_SREV_9280_20(ah)) +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -236,7 +236,6 @@ enum ath9k_hw_caps { + ATH9K_HW_CAP_LDPC = BIT(6), + ATH9K_HW_CAP_FASTCLOCK = BIT(7), + ATH9K_HW_CAP_SGI_20 = BIT(8), +- ATH9K_HW_CAP_PAPRD = BIT(9), + ATH9K_HW_CAP_ANT_DIV_COMB = BIT(10), + ATH9K_HW_CAP_2GHZ = BIT(11), + ATH9K_HW_CAP_5GHZ = BIT(12), +@@ -287,12 +286,12 @@ struct ath9k_ops_config { + u8 pcie_clock_req; + u32 pcie_waen; + u8 analog_shiftreg; +- u8 paprd_disable; + u32 ofdm_trig_low; + u32 ofdm_trig_high; + u32 cck_trig_high; + u32 cck_trig_low; + u32 enable_ani; ++ u32 enable_paprd; + int serialize_regmode; + bool rx_intr_mitigation; + bool tx_intr_mitigation; +--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +@@ -2982,6 +2982,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(st + case EEP_RX_MASK: + return pBase->txrxMask & 0xf; + case EEP_PAPRD: ++ if (AR_SREV_9462(ah)) ++ return false; ++ if (!ah->config.enable_paprd); ++ return false; + return !!(pBase->featureEnable & BIT(5)); + case EEP_CHAIN_MASK_REDUCE: + return (pBase->miscConfiguration >> 0x3) & 0x1; +--- a/drivers/net/wireless/ath/ath9k/link.c ++++ b/drivers/net/wireless/ath/ath9k/link.c +@@ -423,7 +423,7 @@ set_timer: + cal_interval = min(cal_interval, (u32)short_cal_interval); + + mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); +- if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { ++ if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && ah->caldata) { + if (!ah->caldata->paprd_done) + ieee80211_queue_work(sc->hw, &sc->paprd_work); + else if (!ah->paprd_table_write_done) diff --git a/package/mac80211/patches/566-ath9k_use_ieee80211_free_txskb.patch b/package/mac80211/patches/566-ath9k_use_ieee80211_free_txskb.patch new file mode 100644 index 000000000..dd484662b --- /dev/null +++ b/package/mac80211/patches/566-ath9k_use_ieee80211_free_txskb.patch @@ -0,0 +1,149 @@ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -66,8 +66,7 @@ static void ath_tx_update_baw(struct ath + static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, + struct ath_txq *txq, + struct ath_atx_tid *tid, +- struct sk_buff *skb, +- bool dequeue); ++ struct sk_buff *skb); + + enum { + MCS_HT20, +@@ -176,7 +175,15 @@ static void ath_tx_flush_tid(struct ath_ + fi = get_frame_info(skb); + bf = fi->bf; + +- if (bf && fi->retries) { ++ if (!bf) { ++ bf = ath_tx_setup_buffer(sc, txq, tid, skb); ++ if (!bf) { ++ ieee80211_free_txskb(sc->hw, skb); ++ continue; ++ } ++ } ++ ++ if (fi->retries) { + list_add_tail(&bf->list, &bf_head); + ath_tx_update_baw(sc, tid, bf->bf_state.seqno); + ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); +@@ -785,10 +792,13 @@ static enum ATH_AGGR_STATUS ath_tx_form_ + fi = get_frame_info(skb); + bf = fi->bf; + if (!fi->bf) +- bf = ath_tx_setup_buffer(sc, txq, tid, skb, true); ++ bf = ath_tx_setup_buffer(sc, txq, tid, skb); + +- if (!bf) ++ if (!bf) { ++ __skb_unlink(skb, &tid->buf_q); ++ ieee80211_free_txskb(sc->hw, skb); + continue; ++ } + + bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR; + seqno = bf->bf_state.seqno; +@@ -1731,9 +1741,11 @@ static void ath_tx_send_ampdu(struct ath + return; + } + +- bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); +- if (!bf) ++ bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); ++ if (!bf) { ++ ieee80211_free_txskb(sc->hw, skb); + return; ++ } + + bf->bf_state.bf_type = BUF_AMPDU; + INIT_LIST_HEAD(&bf_head); +@@ -1757,11 +1769,6 @@ static void ath_tx_send_normal(struct at + struct ath_buf *bf; + + bf = fi->bf; +- if (!bf) +- bf = ath_tx_setup_buffer(sc, txq, tid, skb, false); +- +- if (!bf) +- return; + + INIT_LIST_HEAD(&bf_head); + list_add_tail(&bf->list, &bf_head); +@@ -1835,8 +1842,7 @@ u8 ath_txchainmask_reduction(struct ath_ + static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, + struct ath_txq *txq, + struct ath_atx_tid *tid, +- struct sk_buff *skb, +- bool dequeue) ++ struct sk_buff *skb) + { + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_frame_info *fi = get_frame_info(skb); +@@ -1848,7 +1854,7 @@ static struct ath_buf *ath_tx_setup_buff + bf = ath_tx_get_buffer(sc); + if (!bf) { + ath_dbg(common, XMIT, "TX buffers are full\n"); +- goto error; ++ return NULL; + } + + ATH_TXBUF_RESET(bf); +@@ -1877,18 +1883,12 @@ static struct ath_buf *ath_tx_setup_buff + ath_err(ath9k_hw_common(sc->sc_ah), + "dma_mapping_error() on TX\n"); + ath_tx_return_buffer(sc, bf); +- goto error; ++ return NULL; + } + + fi->bf = bf; + + return bf; +- +-error: +- if (dequeue) +- __skb_unlink(skb, &tid->buf_q); +- dev_kfree_skb_any(skb); +- return NULL; + } + + /* FIXME: tx power */ +@@ -1917,9 +1917,14 @@ static void ath_tx_start_dma(struct ath_ + */ + ath_tx_send_ampdu(sc, tid, skb, txctl); + } else { +- bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); +- if (!bf) ++ bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb); ++ if (!bf) { ++ if (txctl->paprd) ++ dev_kfree_skb_any(skb); ++ else ++ ieee80211_free_txskb(sc->hw, skb); + return; ++ } + + bf->bf_state.bfs_paprd = txctl->paprd; + +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -775,7 +775,7 @@ static void ath9k_tx(struct ieee80211_hw + + return; + exit: +- dev_kfree_skb_any(skb); ++ ieee80211_free_txskb(hw, skb); + } + + static void ath9k_stop(struct ieee80211_hw *hw) +--- a/drivers/net/wireless/ath/ath9k/beacon.c ++++ b/drivers/net/wireless/ath/ath9k/beacon.c +@@ -120,7 +120,7 @@ static void ath9k_tx_cabq(struct ieee802 + + if (ath_tx_start(hw, skb, &txctl) != 0) { + ath_dbg(common, XMIT, "CABQ TX failed\n"); +- dev_kfree_skb_any(skb); ++ ieee80211_free_txskb(hw, skb); + } + } + diff --git a/package/mac80211/patches/600-rt2x00-disable-pci-code-if-CONFIG_PCI-not-defined.patch b/package/mac80211/patches/600-rt2x00-disable-pci-code-if-CONFIG_PCI-not-defined.patch new file mode 100644 index 000000000..a7609ede4 --- /dev/null +++ b/package/mac80211/patches/600-rt2x00-disable-pci-code-if-CONFIG_PCI-not-defined.patch @@ -0,0 +1,18 @@ +--- a/drivers/net/wireless/rt2x00/rt2x00pci.c ++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c +@@ -208,6 +208,7 @@ void rt2x00pci_uninitialize(struct rt2x0 + } + EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); + ++#ifdef CONFIG_PCI + /* + * PCI driver handlers. + */ +@@ -392,6 +393,7 @@ int rt2x00pci_resume(struct pci_dev *pci + } + EXPORT_SYMBOL_GPL(rt2x00pci_resume); + #endif /* CONFIG_PM */ ++#endif /* CONFIG_PCI */ + + /* + * rt2x00pci module information. diff --git a/package/mac80211/patches/601-rt2x00-set_pci_mwi.patch b/package/mac80211/patches/601-rt2x00-set_pci_mwi.patch new file mode 100644 index 000000000..9ff50b7bf --- /dev/null +++ b/package/mac80211/patches/601-rt2x00-set_pci_mwi.patch @@ -0,0 +1,13 @@ +--- a/drivers/net/wireless/rt2x00/rt2x00pci.c ++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c +@@ -273,8 +273,10 @@ int rt2x00pci_probe(struct pci_dev *pci_ + + pci_set_master(pci_dev); + ++#ifdef CONFIG_PCI_SET_MWI + if (pci_set_mwi(pci_dev)) + ERROR_PROBE("MWI not available.\n"); ++#endif + + if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) { + ERROR_PROBE("PCI DMA not supported.\n"); diff --git a/package/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch b/package/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch new file mode 100644 index 000000000..6c80c3dfa --- /dev/null +++ b/package/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch @@ -0,0 +1,32 @@ +--- /dev/null ++++ b/include/linux/rt2x00_platform.h +@@ -0,0 +1,19 @@ ++/* ++ * Platform data definition for the rt2x00 driver ++ * ++ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++ ++#ifndef _RT2X00_PLATFORM_H ++#define _RT2X00_PLATFORM_H ++ ++struct rt2x00_platform_data { ++ char *eeprom_file_name; ++}; ++ ++#endif /* _RT2X00_PLATFORM_H */ +--- a/drivers/net/wireless/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/rt2x00/rt2x00.h +@@ -39,6 +39,7 @@ + #include <linux/input-polldev.h> + #include <linux/kfifo.h> + #include <linux/hrtimer.h> ++#include <linux/rt2x00_platform.h> + + #include <net/mac80211.h> + diff --git a/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch new file mode 100644 index 000000000..4f35ae899 --- /dev/null +++ b/package/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch @@ -0,0 +1,274 @@ +--- /dev/null ++++ b/drivers/net/wireless/rt2x00/rt2x00eeprom.c +@@ -0,0 +1,98 @@ ++/* ++ Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> ++ Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com> ++ <http://rt2x00.serialmonkey.com> ++ ++ 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; if not, write to the ++ Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ Module: rt2x00lib ++ Abstract: rt2x00 eeprom file loading routines. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++ ++#include "rt2x00.h" ++#include "rt2x00lib.h" ++ ++static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ const struct firmware *ee; ++ char *ee_name; ++ int retval; ++ ++ ee_name = rt2x00dev->ops->lib->get_eeprom_file_name(rt2x00dev); ++ if (!ee_name) { ++ ERROR(rt2x00dev, ++ "Invalid EEPROM filename.\n" ++ "Please file bug report to %s.\n", DRV_PROJECT); ++ return -EINVAL; ++ } ++ ++ INFO(rt2x00dev, "Loading EEPROM data from '%s'.\n", ee_name); ++ ++ retval = request_firmware(&ee, ee_name, rt2x00dev->dev); ++ if (retval) { ++ ERROR(rt2x00dev, "Failed to request EEPROM.\n"); ++ return retval; ++ } ++ ++ if (!ee || !ee->size || !ee->data) { ++ ERROR(rt2x00dev, "Failed to read EEPROM file.\n"); ++ retval = -ENOENT; ++ goto err_exit; ++ } ++ ++ if (ee->size != rt2x00dev->ops->eeprom_size) { ++ ERROR(rt2x00dev, ++ "EEPROM file size is invalid, it should be %d bytes\n", ++ rt2x00dev->ops->eeprom_size); ++ retval = -EINVAL; ++ goto err_release_ee; ++ } ++ ++ rt2x00dev->eeprom_file = ee; ++ return 0; ++ ++err_release_ee: ++ release_firmware(ee); ++err_exit: ++ return retval; ++} ++ ++int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ int retval; ++ ++ if (!test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) ++ return 0; ++ ++ if (!rt2x00dev->eeprom_file) { ++ retval = rt2x00lib_request_eeprom_file(rt2x00dev); ++ if (retval) ++ return retval; ++ } ++ ++ return 0; ++} ++ ++void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ release_firmware(rt2x00dev->eeprom_file); ++ rt2x00dev->eeprom_file = NULL; ++} +--- a/drivers/net/wireless/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/rt2x00/rt2x00.h +@@ -560,6 +560,7 @@ struct rt2x00lib_ops { + const u8 *data, const size_t len); + int (*load_firmware) (struct rt2x00_dev *rt2x00dev, + const u8 *data, const size_t len); ++ char *(*get_eeprom_file_name) (struct rt2x00_dev *rt2x00dev); + + /* + * Device initialization/deinitialization handlers. +@@ -721,6 +722,7 @@ enum rt2x00_capability_flags { + REQUIRE_SW_SEQNO, + REQUIRE_HT_TX_DESC, + REQUIRE_PS_AUTOWAKE, ++ REQUIRE_EEPROM_FILE, + + /* + * Capabilities +@@ -976,6 +978,11 @@ struct rt2x00_dev { + const struct firmware *fw; + + /* ++ * EEPROM image. ++ */ ++ const struct firmware *eeprom_file; ++ ++ /* + * FIFO for storing tx status reports between isr and tasklet. + */ + DECLARE_KFIFO_PTR(txstatus_fifo, u32); +--- a/drivers/net/wireless/rt2x00/rt2x00lib.h ++++ b/drivers/net/wireless/rt2x00/rt2x00lib.h +@@ -322,6 +322,22 @@ static inline void rt2x00lib_free_firmwa + #endif /* CONFIG_RT2X00_LIB_FIRMWARE */ + + /* ++ * EEPROM file handlers. ++ */ ++#ifdef CONFIG_RT2X00_LIB_EEPROM ++int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev); ++void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev); ++#else ++static inline int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ return 0; ++} ++static inline void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++} ++#endif /* CONFIG_RT2X00_LIB_EEPROM_FILE */ ++ ++/* + * Debugfs handlers. + */ + #ifdef CONFIG_RT2X00_LIB_DEBUGFS +--- a/drivers/net/wireless/rt2x00/Kconfig ++++ b/drivers/net/wireless/rt2x00/Kconfig +@@ -60,6 +60,7 @@ config RT2800PCI + select RT2X00_LIB_PCI if PCI + select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X + select RT2X00_LIB_FIRMWARE ++ select RT2X00_LIB_EEPROM + select RT2X00_LIB_CRYPTO + select CRC_CCITT + select EEPROM_93CX6 +@@ -212,6 +213,9 @@ config RT2X00_LIB_FIRMWARE + config RT2X00_LIB_CRYPTO + boolean + ++config RT2X00_LIB_EEPROM ++ boolean ++ + config RT2X00_LIB_LEDS + boolean + default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) +--- a/drivers/net/wireless/rt2x00/Makefile ++++ b/drivers/net/wireless/rt2x00/Makefile +@@ -7,6 +7,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) + + rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o + rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o + rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o ++rt2x00lib-$(CONFIG_RT2X00_LIB_EEPROM) += rt2x00eeprom.o + + obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o + obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o +--- a/drivers/net/wireless/rt2x00/rt2800pci.c ++++ b/drivers/net/wireless/rt2x00/rt2800pci.c +@@ -89,20 +89,10 @@ static void rt2800pci_mcu_status(struct + rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); + } + +-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) + static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) + { +- void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); +- +- memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); +- +- iounmap(base_addr); ++ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE); + } +-#else +-static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) +-{ +-} +-#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ + + #ifdef CONFIG_PCI + static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) +@@ -322,6 +312,20 @@ static int rt2800pci_write_firmware(stru + } + + /* ++ * EEPROM file functions. ++ */ ++static char *rt2800pci_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) ++{ ++ struct rt2x00_platform_data *pdata; ++ ++ pdata = rt2x00dev->dev->platform_data; ++ if (pdata) ++ return pdata->eeprom_file_name; ++ ++ return NULL; ++} ++ ++/* + * Initialization functions. + */ + static bool rt2800pci_get_entry_state(struct queue_entry *entry) +@@ -1033,6 +1037,7 @@ static const struct rt2x00lib_ops rt2800 + .get_firmware_name = rt2800pci_get_firmware_name, + .check_firmware = rt2800_check_firmware, + .load_firmware = rt2800_load_firmware, ++ .get_eeprom_file_name = rt2800pci_get_eeprom_file_name, + .initialize = rt2x00pci_initialize, + .uninitialize = rt2x00pci_uninitialize, + .get_entry_state = rt2800pci_get_entry_state, +--- a/drivers/net/wireless/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c +@@ -1163,6 +1163,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de + + rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + ++ retval = rt2x00lib_load_eeprom_file(rt2x00dev); ++ if (retval) ++ goto exit; ++ + /* + * Initialize work. + */ +@@ -1287,6 +1291,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ + */ + if (rt2x00dev->drv_data) + kfree(rt2x00dev->drv_data); ++ ++ /* ++ * Free EEPROM image. ++ */ ++ rt2x00lib_free_eeprom_file(rt2x00dev); + } + EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); + +--- a/drivers/net/wireless/rt2x00/rt2x00soc.c ++++ b/drivers/net/wireless/rt2x00/rt2x00soc.c +@@ -94,6 +94,7 @@ int rt2x00soc_probe(struct platform_devi + rt2x00dev->hw = hw; + rt2x00dev->irq = platform_get_irq(pdev, 0); + rt2x00dev->name = pdev->dev.driver->name; ++ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags); + + rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC); + diff --git a/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch b/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch new file mode 100644 index 000000000..5331b2678 --- /dev/null +++ b/package/mac80211/patches/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch @@ -0,0 +1,10 @@ +--- a/config.mk ++++ b/config.mk +@@ -624,6 +624,7 @@ export CONFIG_RT2X00=y + export CONFIG_RT2X00_LIB=m + export CONFIG_RT2800_LIB=m + export CONFIG_RT2X00_LIB_FIRMWARE=y ++export CONFIG_RT2X00_LIB_EEPROM=y + export CONFIG_RT2X00_LIB_CRYPTO=y + # export CONFIG_RT2X00_LIB_SOC=y + ifdef CONFIG_COMPAT_KERNEL_2_6_25 diff --git a/package/mac80211/patches/605-rt2x00-pci-eeprom.patch b/package/mac80211/patches/605-rt2x00-pci-eeprom.patch new file mode 100644 index 000000000..fbc86199a --- /dev/null +++ b/package/mac80211/patches/605-rt2x00-pci-eeprom.patch @@ -0,0 +1,46 @@ +--- a/drivers/net/wireless/rt2x00/rt2800pci.c ++++ b/drivers/net/wireless/rt2x00/rt2800pci.c +@@ -89,7 +89,7 @@ static void rt2800pci_mcu_status(struct + rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); + } + +-static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) ++static void rt2800pci_read_eeprom_file(struct rt2x00_dev *rt2x00dev) + { + memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE); + } +@@ -976,8 +976,9 @@ static irqreturn_t rt2800pci_interrupt(i + */ + static void rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev) + { +- if (rt2x00_is_soc(rt2x00dev)) +- rt2800pci_read_eeprom_soc(rt2x00dev); ++ if (rt2x00_is_soc(rt2x00dev) || ++ test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) ++ rt2800pci_read_eeprom_file(rt2x00dev); + else if (rt2800pci_efuse_detect(rt2x00dev)) + rt2800pci_read_eeprom_efuse(rt2x00dev); + else +--- a/drivers/net/wireless/rt2x00/rt2x00pci.c ++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c +@@ -255,6 +255,7 @@ exit: + int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) + { + struct ieee80211_hw *hw; ++ struct rt2x00_platform_data *pdata; + struct rt2x00_dev *rt2x00dev; + int retval; + u16 chip; +@@ -300,6 +301,12 @@ int rt2x00pci_probe(struct pci_dev *pci_ + rt2x00dev->irq = pci_dev->irq; + rt2x00dev->name = pci_name(pci_dev); + ++ /* if we get passed the name of a eeprom_file_name, then use this in ++ favour of the eeprom */ ++ pdata = rt2x00dev->dev->platform_data; ++ if (pdata && pdata->eeprom_file_name) ++ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags); ++ + if (pci_is_pcie(pci_dev)) + rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); + else diff --git a/package/mac80211/patches/606-rt2x00_no_realign.patch b/package/mac80211/patches/606-rt2x00_no_realign.patch new file mode 100644 index 000000000..e0a920a58 --- /dev/null +++ b/package/mac80211/patches/606-rt2x00_no_realign.patch @@ -0,0 +1,67 @@ +[RFC] rt2x00: For drivers that only need L2 padding don't realign frames + +Signed-off-by: Helmut Schaa <helmut.schaa@...> +--- + +Ivo, Gertjan, do you remeber by any chance why this alignment stuff was added +in the first place? Was it because of DMA restrictions? + +While doing some profiling on the rt3052 SoC I noticed that 30-40% time was +spent in memmove calls. And the culprit is the memmove aligning the payload +to a 4byte boundary since that has to move a whole bunch of data. + +Interesstingly the legacy drivers insert an l2pad between the header and the +payload but doesn't realign the payload itself to a 4-byte boundary. Hence, +I came up with this patch and indeed CPU usage improves impressively. + +Only tested on rt2800pci! + +Thanks, +Helmut + + drivers/net/wireless/rt2x00/rt2x00queue.c | 30 +++------------------------- + 1 files changed, 4 insertions(+), 26 deletions(-) + +--- a/drivers/net/wireless/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/rt2x00/rt2x00queue.c +@@ -151,36 +151,14 @@ void rt2x00queue_align_frame(struct sk_b + void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) + { + unsigned int payload_length = skb->len - header_length; +- unsigned int header_align = ALIGN_SIZE(skb, 0); +- unsigned int payload_align = ALIGN_SIZE(skb, header_length); + unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0; + +- /* +- * Adjust the header alignment if the payload needs to be moved more +- * than the header. +- */ +- if (payload_align > header_align) +- header_align += 4; +- +- /* There is nothing to do if no alignment is needed */ +- if (!header_align) ++ if (!l2pad) + return; + +- /* Reserve the amount of space needed in front of the frame */ +- skb_push(skb, header_align); +- +- /* +- * Move the header. +- */ +- memmove(skb->data, skb->data + header_align, header_length); +- +- /* Move the payload, if present and if required */ +- if (payload_length && payload_align) +- memmove(skb->data + header_length + l2pad, +- skb->data + header_length + l2pad + payload_align, +- payload_length); +- +- /* Trim the skb to the correct size */ ++ /* insert l2pad -> Move header */ ++ skb_push(skb, l2pad); ++ memmove(skb->data, skb->data + l2pad, header_length); + skb_trim(skb, header_length + l2pad + payload_length); + } + diff --git a/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch new file mode 100644 index 000000000..57abb07ab --- /dev/null +++ b/package/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch @@ -0,0 +1,47 @@ +--- a/include/linux/rt2x00_platform.h ++++ b/include/linux/rt2x00_platform.h +@@ -14,6 +14,9 @@ + + struct rt2x00_platform_data { + char *eeprom_file_name; ++ ++ int disable_2ghz; ++ int disable_5ghz; + }; + + #endif /* _RT2X00_PLATFORM_H */ +--- a/drivers/net/wireless/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c +@@ -834,6 +834,22 @@ static int rt2x00lib_probe_hw_modes(stru + unsigned int num_rates; + unsigned int i; + ++ if (rt2x00dev->dev->platform_data) { ++ struct rt2x00_platform_data *pdata; ++ ++ pdata = rt2x00dev->dev->platform_data; ++ if (pdata->disable_2ghz) ++ spec->supported_bands &= ~SUPPORT_BAND_2GHZ; ++ if (pdata->disable_5ghz) ++ spec->supported_bands &= ~SUPPORT_BAND_5GHZ; ++ } ++ ++ if ((spec->supported_bands & SUPPORT_BAND_BOTH) == 0) { ++ ERROR(rt2x00dev, "No supported bands\n"); ++ return -EINVAL; ++ } ++ ++ + num_rates = 0; + if (spec->supported_rates & SUPPORT_RATE_CCK) + num_rates += 4; +--- a/drivers/net/wireless/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/rt2x00/rt2x00.h +@@ -425,6 +425,7 @@ struct hw_mode_spec { + unsigned int supported_bands; + #define SUPPORT_BAND_2GHZ 0x00000001 + #define SUPPORT_BAND_5GHZ 0x00000002 ++#define SUPPORT_BAND_BOTH (SUPPORT_BAND_2GHZ | SUPPORT_BAND_5GHZ) + + unsigned int supported_rates; + #define SUPPORT_RATE_CCK 0x00000001 diff --git a/package/mac80211/patches/608-add_platform_data_mac_addr.patch b/package/mac80211/patches/608-add_platform_data_mac_addr.patch new file mode 100644 index 000000000..c1b22e7a2 --- /dev/null +++ b/package/mac80211/patches/608-add_platform_data_mac_addr.patch @@ -0,0 +1,63 @@ +--- a/include/linux/rt2x00_platform.h ++++ b/include/linux/rt2x00_platform.h +@@ -14,6 +14,7 @@ + + struct rt2x00_platform_data { + char *eeprom_file_name; ++ const u8 *mac_address; + + int disable_2ghz; + int disable_5ghz; +--- a/drivers/net/wireless/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c +@@ -825,6 +825,18 @@ static void rt2x00lib_rate(struct ieee80 + entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE; + } + ++const u8 *rt2x00lib_get_mac_address(struct rt2x00_dev *rt2x00dev) ++{ ++ struct rt2x00_platform_data *pdata; ++ ++ pdata = rt2x00dev->dev->platform_data; ++ if (!pdata) ++ return NULL; ++ ++ return pdata->mac_address; ++} ++EXPORT_SYMBOL_GPL(rt2x00lib_get_mac_address); ++ + static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, + struct hw_mode_spec *spec) + { +--- a/drivers/net/wireless/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/rt2x00/rt2x00.h +@@ -1280,6 +1280,7 @@ static inline void rt2x00debug_dump_fram + */ + u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif); ++const u8 *rt2x00lib_get_mac_address(struct rt2x00_dev *rt2x00dev); + + /* + * Interrupt context handlers. +--- a/drivers/net/wireless/rt2x00/rt61pci.c ++++ b/drivers/net/wireless/rt2x00/rt61pci.c +@@ -2392,6 +2392,7 @@ static int rt61pci_validate_eeprom(struc + u32 reg; + u16 word; + u8 *mac; ++ const u8 *pdata_mac; + s8 value; + + rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); +@@ -2412,7 +2413,11 @@ static int rt61pci_validate_eeprom(struc + /* + * Start validation of the data that has been read. + */ ++ pdata_mac = rt2x00lib_get_mac_address(rt2x00dev); + mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); ++ if (pdata_mac) ++ memcpy(mac, pdata_mac, 6); ++ + if (!is_valid_ether_addr(mac)) { + eth_random_addr(mac); + EEPROM(rt2x00dev, "MAC: %pM\n", mac); diff --git a/package/mac80211/patches/620-rt2x00-support-rt3352.patch b/package/mac80211/patches/620-rt2x00-support-rt3352.patch new file mode 100644 index 000000000..bb2086daa --- /dev/null +++ b/package/mac80211/patches/620-rt2x00-support-rt3352.patch @@ -0,0 +1,464 @@ +From 03839951515b0ea2b21d649b1fe7b63f9817d0c8 Mon Sep 17 00:00:00 2001 +From: Daniel Golle <dgolle@allnet.de> +Date: Sun, 9 Sep 2012 14:24:39 +0300 +Subject: [PATCH] rt2x00: add MediaTek/RaLink Rt3352 WiSoC + +Support for the RT3352 WiSoC was developed for and tested with the ALL5002 +devboard running OpenWrt. For now, this supports only devices with internal +TXALC. Corrections were made according to the remarks of Stanislaw Gruszka and +Gertjan van Wingerde, thank you guys for reviewing! + +Signed-off-by: Daniel Golle <dgolle@allnet.de> +Signed-off-by: John W. Linville <linville@tuxdriver.com> +--- + drivers/net/wireless/rt2x00/rt2800.h | 5 + + drivers/net/wireless/rt2x00/rt2800lib.c | 211 +++++++++++++++++++++++++++++++- + drivers/net/wireless/rt2x00/rt2x00.h | 1 + + 3 files changed, 212 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h +index e13916f..6d67c3e 100644 +--- a/drivers/net/wireless/rt2x00/rt2800.h ++++ b/drivers/net/wireless/rt2x00/rt2800.h +@@ -1943,6 +1943,11 @@ struct mac_iveiv_entry { + #define BBP47_TSSI_ADC6 FIELD8(0x80) + + /* ++ * BBP 49 ++ */ ++#define BBP49_UPDATE_FLAG FIELD8(0x01) ++ ++/* + * BBP 109 + */ + #define BBP109_TX0_POWER FIELD8(0x0f) +diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c +index a04e222..9e09367 100644 +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c +@@ -1615,6 +1615,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) + case 1: + if (rt2x00_rt(rt2x00dev, RT3070) || + rt2x00_rt(rt2x00dev, RT3090) || ++ rt2x00_rt(rt2x00dev, RT3352) || + rt2x00_rt(rt2x00dev, RT3390)) { + rt2x00_eeprom_read(rt2x00dev, + EEPROM_NIC_CONF1, &eeprom); +@@ -2053,6 +2054,60 @@ static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev, + } + } + ++static void rt2800_config_channel_rf3322(struct rt2x00_dev *rt2x00dev, ++ struct ieee80211_conf *conf, ++ struct rf_channel *rf, ++ struct channel_info *info) ++{ ++ u8 rfcsr; ++ ++ rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); ++ rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); ++ ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x42); ++ rt2800_rfcsr_write(rt2x00dev, 12, 0x1c); ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x00); ++ ++ if (info->default_power1 > POWER_BOUND) ++ rt2800_rfcsr_write(rt2x00dev, 47, POWER_BOUND); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 47, info->default_power1); ++ ++ if (info->default_power2 > POWER_BOUND) ++ rt2800_rfcsr_write(rt2x00dev, 48, POWER_BOUND); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 48, info->default_power2); ++ ++ rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); ++ if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND) ++ rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND); ++ else ++ rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); ++ ++ rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); ++ ++ rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); ++ ++ if ( rt2x00dev->default_ant.tx_chain_num == 2 ) ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); ++ else ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); ++ ++ if ( rt2x00dev->default_ant.rx_chain_num == 2 ) ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); ++ else ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); ++ ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); ++ ++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); ++ ++ rt2800_rfcsr_write(rt2x00dev, 31, 80); ++} ++ + static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf, + struct rf_channel *rf, +@@ -2182,6 +2237,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + case RF3290: + rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info); + break; ++ case RF3322: ++ rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); ++ break; + case RF5360: + case RF5370: + case RF5372: +@@ -2194,6 +2252,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + } + + if (rt2x00_rf(rt2x00dev, RF3290) || ++ rt2x00_rf(rt2x00dev, RF3322) || + rt2x00_rf(rt2x00dev, RF5360) || + rt2x00_rf(rt2x00dev, RF5370) || + rt2x00_rf(rt2x00dev, RF5372) || +@@ -2212,10 +2271,17 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + /* + * Change BBP settings + */ +- rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); +- rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); +- rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); +- rt2800_bbp_write(rt2x00dev, 86, 0); ++ if (rt2x00_rt(rt2x00dev, RT3352)) { ++ rt2800_bbp_write(rt2x00dev, 27, 0x0); ++ rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 27, 0x20); ++ rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain); ++ } else { ++ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 86, 0); ++ } + + if (rf->channel <= 14) { + if (!rt2x00_rt(rt2x00dev, RT5390) && +@@ -2310,6 +2376,15 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + rt2800_register_read(rt2x00dev, CH_IDLE_STA, ®); + rt2800_register_read(rt2x00dev, CH_BUSY_STA, ®); + rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, ®); ++ ++ /* ++ * Clear update flag ++ */ ++ if (rt2x00_rt(rt2x00dev, RT3352)) { ++ rt2800_bbp_read(rt2x00dev, 49, &bbp); ++ rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0); ++ rt2800_bbp_write(rt2x00dev, 49, bbp); ++ } + } + + static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) +@@ -2998,6 +3073,10 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); + rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030); ++ } else if (rt2x00_rt(rt2x00dev, RT3352)) { ++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); + } else if (rt2x00_rt(rt2x00dev, RT3572)) { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); +@@ -3378,6 +3457,11 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + rt2800_wait_bbp_ready(rt2x00dev))) + return -EACCES; + ++ if (rt2x00_rt(rt2x00dev, RT3352)) { ++ rt2800_bbp_write(rt2x00dev, 3, 0x00); ++ rt2800_bbp_write(rt2x00dev, 4, 0x50); ++ } ++ + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { +@@ -3388,15 +3472,20 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + + if (rt2800_is_305x_soc(rt2x00dev) || + rt2x00_rt(rt2x00dev, RT3290) || ++ rt2x00_rt(rt2x00dev, RT3352) || + rt2x00_rt(rt2x00dev, RT3572) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) + rt2800_bbp_write(rt2x00dev, 31, 0x08); + ++ if (rt2x00_rt(rt2x00dev, RT3352)) ++ rt2800_bbp_write(rt2x00dev, 47, 0x48); ++ + rt2800_bbp_write(rt2x00dev, 65, 0x2c); + rt2800_bbp_write(rt2x00dev, 66, 0x38); + + if (rt2x00_rt(rt2x00dev, RT3290) || ++ rt2x00_rt(rt2x00dev, RT3352) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) + rt2800_bbp_write(rt2x00dev, 68, 0x0b); +@@ -3405,6 +3494,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + rt2800_bbp_write(rt2x00dev, 69, 0x16); + rt2800_bbp_write(rt2x00dev, 73, 0x12); + } else if (rt2x00_rt(rt2x00dev, RT3290) || ++ rt2x00_rt(rt2x00dev, RT3352) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { + rt2800_bbp_write(rt2x00dev, 69, 0x12); +@@ -3436,6 +3526,10 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + } else if (rt2800_is_305x_soc(rt2x00dev)) { + rt2800_bbp_write(rt2x00dev, 78, 0x0e); + rt2800_bbp_write(rt2x00dev, 80, 0x08); ++ } else if (rt2x00_rt(rt2x00dev, RT3352)) { ++ rt2800_bbp_write(rt2x00dev, 78, 0x0e); ++ rt2800_bbp_write(rt2x00dev, 80, 0x08); ++ rt2800_bbp_write(rt2x00dev, 81, 0x37); + } else { + rt2800_bbp_write(rt2x00dev, 81, 0x37); + } +@@ -3465,18 +3559,21 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + rt2800_bbp_write(rt2x00dev, 84, 0x99); + + if (rt2x00_rt(rt2x00dev, RT3290) || ++ rt2x00_rt(rt2x00dev, RT3352) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) + rt2800_bbp_write(rt2x00dev, 86, 0x38); + else + rt2800_bbp_write(rt2x00dev, 86, 0x00); + +- if (rt2x00_rt(rt2x00dev, RT5392)) ++ if (rt2x00_rt(rt2x00dev, RT3352) || ++ rt2x00_rt(rt2x00dev, RT5392)) + rt2800_bbp_write(rt2x00dev, 88, 0x90); + + rt2800_bbp_write(rt2x00dev, 91, 0x04); + + if (rt2x00_rt(rt2x00dev, RT3290) || ++ rt2x00_rt(rt2x00dev, RT3352) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) + rt2800_bbp_write(rt2x00dev, 92, 0x02); +@@ -3493,6 +3590,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || + rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || + rt2x00_rt(rt2x00dev, RT3290) || ++ rt2x00_rt(rt2x00dev, RT3352) || + rt2x00_rt(rt2x00dev, RT3572) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392) || +@@ -3502,6 +3600,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + rt2800_bbp_write(rt2x00dev, 103, 0x00); + + if (rt2x00_rt(rt2x00dev, RT3290) || ++ rt2x00_rt(rt2x00dev, RT3352) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) + rt2800_bbp_write(rt2x00dev, 104, 0x92); +@@ -3510,6 +3609,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + rt2800_bbp_write(rt2x00dev, 105, 0x01); + else if (rt2x00_rt(rt2x00dev, RT3290)) + rt2800_bbp_write(rt2x00dev, 105, 0x1c); ++ else if (rt2x00_rt(rt2x00dev, RT3352)) ++ rt2800_bbp_write(rt2x00dev, 105, 0x34); + else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) + rt2800_bbp_write(rt2x00dev, 105, 0x3c); +@@ -3519,11 +3620,16 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 106, 0x03); ++ else if (rt2x00_rt(rt2x00dev, RT3352)) ++ rt2800_bbp_write(rt2x00dev, 106, 0x05); + else if (rt2x00_rt(rt2x00dev, RT5392)) + rt2800_bbp_write(rt2x00dev, 106, 0x12); + else + rt2800_bbp_write(rt2x00dev, 106, 0x35); + ++ if (rt2x00_rt(rt2x00dev, RT3352)) ++ rt2800_bbp_write(rt2x00dev, 120, 0x50); ++ + if (rt2x00_rt(rt2x00dev, RT3290) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) +@@ -3534,6 +3640,9 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + rt2800_bbp_write(rt2x00dev, 135, 0xf6); + } + ++ if (rt2x00_rt(rt2x00dev, RT3352)) ++ rt2800_bbp_write(rt2x00dev, 137, 0x0f); ++ + if (rt2x00_rt(rt2x00dev, RT3071) || + rt2x00_rt(rt2x00dev, RT3090) || + rt2x00_rt(rt2x00dev, RT3390) || +@@ -3574,6 +3683,28 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) + rt2800_bbp_write(rt2x00dev, 3, value); + } + ++ if (rt2x00_rt(rt2x00dev, RT3352)) { ++ rt2800_bbp_write(rt2x00dev, 163, 0xbd); ++ /* Set ITxBF timeout to 0x9c40=1000msec */ ++ rt2800_bbp_write(rt2x00dev, 179, 0x02); ++ rt2800_bbp_write(rt2x00dev, 180, 0x00); ++ rt2800_bbp_write(rt2x00dev, 182, 0x40); ++ rt2800_bbp_write(rt2x00dev, 180, 0x01); ++ rt2800_bbp_write(rt2x00dev, 182, 0x9c); ++ rt2800_bbp_write(rt2x00dev, 179, 0x00); ++ /* Reprogram the inband interface to put right values in RXWI */ ++ rt2800_bbp_write(rt2x00dev, 142, 0x04); ++ rt2800_bbp_write(rt2x00dev, 143, 0x3b); ++ rt2800_bbp_write(rt2x00dev, 142, 0x06); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa0); ++ rt2800_bbp_write(rt2x00dev, 142, 0x07); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa1); ++ rt2800_bbp_write(rt2x00dev, 142, 0x08); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa2); ++ ++ rt2800_bbp_write(rt2x00dev, 148, 0xc8); ++ } ++ + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { + int ant, div_mode; +@@ -3707,6 +3838,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) + !rt2x00_rt(rt2x00dev, RT3071) && + !rt2x00_rt(rt2x00dev, RT3090) && + !rt2x00_rt(rt2x00dev, RT3290) && ++ !rt2x00_rt(rt2x00dev, RT3352) && + !rt2x00_rt(rt2x00dev, RT3390) && + !rt2x00_rt(rt2x00dev, RT3572) && + !rt2x00_rt(rt2x00dev, RT5390) && +@@ -3903,6 +4035,70 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) + rt2800_rfcsr_write(rt2x00dev, 30, 0x00); + rt2800_rfcsr_write(rt2x00dev, 31, 0x00); + return 0; ++ } else if (rt2x00_rt(rt2x00dev, RT3352)) { ++ rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); ++ rt2800_rfcsr_write(rt2x00dev, 1, 0x23); ++ rt2800_rfcsr_write(rt2x00dev, 2, 0x50); ++ rt2800_rfcsr_write(rt2x00dev, 3, 0x18); ++ rt2800_rfcsr_write(rt2x00dev, 4, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 5, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x33); ++ rt2800_rfcsr_write(rt2x00dev, 7, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 8, 0xf1); ++ rt2800_rfcsr_write(rt2x00dev, 9, 0x02); ++ rt2800_rfcsr_write(rt2x00dev, 10, 0xd2); ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x42); ++ rt2800_rfcsr_write(rt2x00dev, 12, 0x1c); ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 14, 0x5a); ++ rt2800_rfcsr_write(rt2x00dev, 15, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 16, 0x01); ++ rt2800_rfcsr_write(rt2x00dev, 18, 0x45); ++ rt2800_rfcsr_write(rt2x00dev, 19, 0x02); ++ rt2800_rfcsr_write(rt2x00dev, 20, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 21, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 22, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 23, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 25, 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 26, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 27, 0x03); ++ rt2800_rfcsr_write(rt2x00dev, 28, 0x03); ++ rt2800_rfcsr_write(rt2x00dev, 29, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 30, 0x10); ++ rt2800_rfcsr_write(rt2x00dev, 31, 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 32, 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 33, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 34, 0x01); ++ rt2800_rfcsr_write(rt2x00dev, 35, 0x03); ++ rt2800_rfcsr_write(rt2x00dev, 36, 0xbd); ++ rt2800_rfcsr_write(rt2x00dev, 37, 0x3c); ++ rt2800_rfcsr_write(rt2x00dev, 38, 0x5f); ++ rt2800_rfcsr_write(rt2x00dev, 39, 0xc5); ++ rt2800_rfcsr_write(rt2x00dev, 40, 0x33); ++ rt2800_rfcsr_write(rt2x00dev, 41, 0x5b); ++ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); ++ rt2800_rfcsr_write(rt2x00dev, 43, 0xdb); ++ rt2800_rfcsr_write(rt2x00dev, 44, 0xdb); ++ rt2800_rfcsr_write(rt2x00dev, 45, 0xdb); ++ rt2800_rfcsr_write(rt2x00dev, 46, 0xdd); ++ rt2800_rfcsr_write(rt2x00dev, 47, 0x0d); ++ rt2800_rfcsr_write(rt2x00dev, 48, 0x14); ++ rt2800_rfcsr_write(rt2x00dev, 49, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 50, 0x2d); ++ rt2800_rfcsr_write(rt2x00dev, 51, 0x7f); ++ rt2800_rfcsr_write(rt2x00dev, 52, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 53, 0x52); ++ rt2800_rfcsr_write(rt2x00dev, 54, 0x1b); ++ rt2800_rfcsr_write(rt2x00dev, 55, 0x7f); ++ rt2800_rfcsr_write(rt2x00dev, 56, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 57, 0x52); ++ rt2800_rfcsr_write(rt2x00dev, 58, 0x1b); ++ rt2800_rfcsr_write(rt2x00dev, 59, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 60, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 61, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 62, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 63, 0x00); + } else if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); +@@ -4104,6 +4300,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) + rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19); + } else if (rt2x00_rt(rt2x00dev, RT3071) || + rt2x00_rt(rt2x00dev, RT3090) || ++ rt2x00_rt(rt2x00dev, RT3352) || + rt2x00_rt(rt2x00dev, RT3390) || + rt2x00_rt(rt2x00dev, RT3572)) { + drv_data->calibration_bw20 = +@@ -4566,6 +4763,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) + case RT3071: + case RT3090: + case RT3290: ++ case RT3352: + case RT3390: + case RT3572: + case RT5390: +@@ -4588,6 +4786,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) + case RF3052: + case RF3290: + case RF3320: ++ case RF3322: + case RF5360: + case RF5370: + case RF5372: +@@ -4612,6 +4811,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) + + if (rt2x00_rt(rt2x00dev, RT3070) || + rt2x00_rt(rt2x00dev, RT3090) || ++ rt2x00_rt(rt2x00dev, RT3352) || + rt2x00_rt(rt2x00dev, RT3390)) { + value = rt2x00_get_field16(eeprom, + EEPROM_NIC_CONF1_ANT_DIVERSITY); +@@ -4904,6 +5104,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) + rt2x00_rf(rt2x00dev, RF3022) || + rt2x00_rf(rt2x00dev, RF3290) || + rt2x00_rf(rt2x00dev, RF3320) || ++ rt2x00_rf(rt2x00dev, RF3322) || + rt2x00_rf(rt2x00dev, RF5360) || + rt2x00_rf(rt2x00dev, RF5370) || + rt2x00_rf(rt2x00dev, RF5372) || +diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h +index f991e8b..49375c8 100644 +--- a/drivers/net/wireless/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/rt2x00/rt2x00.h +@@ -188,6 +188,7 @@ struct rt2x00_chip { + #define RT3071 0x3071 + #define RT3090 0x3090 /* 2.4GHz PCIe */ + #define RT3290 0x3290 ++#define RT3352 0x3352 /* WSOC */ + #define RT3390 0x3390 + #define RT3572 0x3572 + #define RT3593 0x3593 +-- +1.7.12.2 + diff --git a/package/mac80211/patches/621-rt2x00-fix-rt3352-lnagain.patch b/package/mac80211/patches/621-rt2x00-fix-rt3352-lnagain.patch new file mode 100644 index 000000000..824c3810d --- /dev/null +++ b/package/mac80211/patches/621-rt2x00-fix-rt3352-lnagain.patch @@ -0,0 +1,30 @@ +From d0ae5f33c0221339a50bd1005c569934417003a5 Mon Sep 17 00:00:00 2001 +From: Daniel Golle <dgolle@allnet.de> +Date: Thu, 4 Oct 2012 00:34:01 +0200 +Subject: [PATCH] rt2x00/rt3352: Fix lnagain assignment to use register 66. +To: users@rt2x00.serialmonkey.com +Cc: gwingerde@gmail.com + +--- + drivers/net/wireless/rt2x00/rt2800lib.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c +index 540c94f..01dc889 100644 +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c +@@ -2252,9 +2252,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + */ + if (rt2x00_rt(rt2x00dev, RT3352)) { + rt2800_bbp_write(rt2x00dev, 27, 0x0); +- rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 27, 0x20); +- rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); + } else { + rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); +-- +1.7.12.2 + diff --git a/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch new file mode 100644 index 000000000..7ebc4f12d --- /dev/null +++ b/package/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch @@ -0,0 +1,10 @@ +--- a/drivers/net/wireless/mwl8k.c ++++ b/drivers/net/wireless/mwl8k.c +@@ -5302,6 +5302,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) = { ++ { PCI_VDEVICE(MARVELL, 0x2a02), .driver_data = MWL8363, }, + { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, }, + { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, }, + { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, }, diff --git a/package/mac80211/patches/800-b43-gpio-mask-module-option.patch b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch new file mode 100644 index 000000000..55ab0aa3a --- /dev/null +++ b/package/mac80211/patches/800-b43-gpio-mask-module-option.patch @@ -0,0 +1,37 @@ +--- a/drivers/net/wireless/b43/b43.h ++++ b/drivers/net/wireless/b43/b43.h +@@ -807,6 +807,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 */ ++ int gpiomask; /* GPIO LED mask as a module parameter */ + + /* PHY/Radio device. */ + 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"); + MODULE_FIRMWARE("b43/ucode5.fw"); + MODULE_FIRMWARE("b43/ucode9.fw"); + ++static int modparam_gpiomask = 0x000F; ++module_param_named(gpiomask, modparam_gpiomask, int, 0444); ++MODULE_PARM_DESC(gpiomask, ++ "GPIO mask for LED control (default 0x000F)"); ++ + static int modparam_bad_frames_preempt; + module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); + MODULE_PARM_DESC(bad_frames_preempt, +@@ -2688,10 +2693,10 @@ static int b43_gpio_init(struct b43_wlde + u32 mask, set; + + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); +- b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF); ++ b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, modparam_gpiomask); + + mask = 0x0000001F; +- set = 0x0000000F; ++ set = modparam_gpiomask; + if (dev->dev->chip_id == 0x4301) { + mask |= 0x0060; + set |= 0x0060; diff --git a/package/mac80211/patches/810-b43_no_pio.patch b/package/mac80211/patches/810-b43_no_pio.patch new file mode 100644 index 000000000..f511795b1 --- /dev/null +++ b/package/mac80211/patches/810-b43_no_pio.patch @@ -0,0 +1,75 @@ +--- a/drivers/net/wireless/b43/Makefile ++++ b/drivers/net/wireless/b43/Makefile +@@ -20,7 +20,7 @@ b43-y += xmit.o + b43-y += lo.o + b43-y += wa.o + b43-y += dma.o +-b43-y += pio.o ++b43-$(CONFIG_B43_PIO) += pio.o + b43-y += rfkill.o + b43-$(CONFIG_B43_LEDS) += leds.o + b43-$(CONFIG_B43_PCMCIA) += pcmcia.o +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -1885,10 +1885,12 @@ static void b43_do_interrupt_thread(stru + dma_reason[0], dma_reason[1], + dma_reason[2], dma_reason[3], + dma_reason[4], dma_reason[5]); ++#ifdef CONFIG_B43_PIO + b43err(dev->wl, "This device does not support DMA " + "on your system. It will now be switched to PIO.\n"); + /* Fall back to PIO transfers if we get fatal DMA errors! */ + dev->use_pio = true; ++#endif + b43_controller_restart(dev, "DMA error"); + return; + } +--- a/drivers/net/wireless/b43/pio.h ++++ b/drivers/net/wireless/b43/pio.h +@@ -150,7 +150,7 @@ static inline void b43_piorx_write32(str + b43_write32(q->dev, q->mmio_base + offset, value); + } + +- ++#ifdef CONFIG_B43_PIO + int b43_pio_init(struct b43_wldev *dev); + void b43_pio_free(struct b43_wldev *dev); + +@@ -161,5 +161,37 @@ void b43_pio_rx(struct b43_pio_rxqueue * + + void b43_pio_tx_suspend(struct b43_wldev *dev); + void b43_pio_tx_resume(struct b43_wldev *dev); ++#else ++static inline int b43_pio_init(struct b43_wldev *dev) ++{ ++ return 0; ++} ++ ++static inline void b43_pio_free(struct b43_wldev *dev) ++{ ++} ++ ++static inline int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb) ++{ ++ return 0; ++} ++ ++static inline void b43_pio_handle_txstatus(struct b43_wldev *dev, ++ const struct b43_txstatus *status) ++{ ++} ++ ++static inline void b43_pio_rx(struct b43_pio_rxqueue *q) ++{ ++} ++ ++static inline void b43_pio_tx_suspend(struct b43_wldev *dev) ++{ ++} ++ ++static inline void b43_pio_tx_resume(struct b43_wldev *dev) ++{ ++} ++#endif /* CONFIG_B43_PIO */ + + #endif /* B43_PIO_H_ */ diff --git a/package/mac80211/patches/820-b43-add-antenna-control.patch b/package/mac80211/patches/820-b43-add-antenna-control.patch new file mode 100644 index 000000000..551213d5f --- /dev/null +++ b/package/mac80211/patches/820-b43-add-antenna-control.patch @@ -0,0 +1,131 @@ +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -1529,7 +1529,7 @@ static void b43_write_beacon_template(st + len, ram_offset, shm_size_offset, rate); + + /* Write the PHY TX control parameters. */ +- antenna = B43_ANTENNA_DEFAULT; ++ antenna = dev->tx_antenna; + antenna = b43_antenna_to_phyctl(antenna); + ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); + /* We can't send beacons with short preamble. Would get PHY errors. */ +@@ -3049,8 +3049,8 @@ static int b43_chip_init(struct b43_wlde + + /* Select the antennae */ + if (phy->ops->set_rx_antenna) +- phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT); +- b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT); ++ phy->ops->set_rx_antenna(dev, dev->rx_antenna); ++ b43_mgmtframe_txantenna(dev, dev->tx_antenna); + + if (phy->type == B43_PHYTYPE_B) { + value16 = b43_read16(dev, 0x005E); +@@ -3794,7 +3794,6 @@ static int b43_op_config(struct ieee8021 + struct b43_wldev *dev; + struct b43_phy *phy; + struct ieee80211_conf *conf = &hw->conf; +- int antenna; + int err = 0; + bool reload_bss = false; + +@@ -3848,11 +3847,9 @@ static int b43_op_config(struct ieee8021 + } + + /* Antennas for RX and management frame TX. */ +- antenna = B43_ANTENNA_DEFAULT; +- b43_mgmtframe_txantenna(dev, antenna); +- antenna = B43_ANTENNA_DEFAULT; ++ b43_mgmtframe_txantenna(dev, dev->tx_antenna); + if (phy->ops->set_rx_antenna) +- phy->ops->set_rx_antenna(dev, antenna); ++ phy->ops->set_rx_antenna(dev, dev->rx_antenna); + + if (wl->radio_enabled != phy->radio_on) { + if (wl->radio_enabled) { +@@ -4974,6 +4971,47 @@ static int b43_op_get_survey(struct ieee + return 0; + } + ++static int b43_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) ++{ ++ struct b43_wl *wl = hw_to_b43_wl(hw); ++ struct b43_wldev *dev = wl->current_dev; ++ ++ if (tx_ant == 1 && rx_ant == 1) { ++ dev->tx_antenna = B43_ANTENNA0; ++ dev->rx_antenna = B43_ANTENNA0; ++ } ++ else if (tx_ant == 2 && rx_ant == 2) { ++ dev->tx_antenna = B43_ANTENNA1; ++ dev->rx_antenna = B43_ANTENNA1; ++ } ++ else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) { ++ dev->tx_antenna = B43_ANTENNA_DEFAULT; ++ dev->rx_antenna = B43_ANTENNA_DEFAULT; ++ } ++ else { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++ ++static int b43_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) ++{ ++ struct b43_wl *wl = hw_to_b43_wl(hw); ++ struct b43_wldev *dev = wl->current_dev; ++ ++ switch (dev->tx_antenna) { ++ case B43_ANTENNA0: ++ *tx_ant = 1; *rx_ant = 1; break; ++ case B43_ANTENNA1: ++ *tx_ant = 2; *rx_ant = 2; break; ++ case B43_ANTENNA_DEFAULT: ++ *tx_ant = 3; *rx_ant = 3; break; ++ } ++ return 0; ++} ++ + static const struct ieee80211_ops b43_hw_ops = { + .tx = b43_op_tx, + .conf_tx = b43_op_conf_tx, +@@ -4995,6 +5033,8 @@ static const struct ieee80211_ops b43_hw + .sw_scan_complete = b43_op_sw_scan_complete_notifier, + .get_survey = b43_op_get_survey, + .rfkill_poll = b43_rfkill_poll, ++ .set_antenna = b43_op_set_antenna, ++ .get_antenna = b43_op_get_antenna, + }; + + /* Hard-reset the chip. Do not call this directly. +@@ -5241,6 +5281,8 @@ static int b43_one_core_attach(struct b4 + if (!wldev) + goto out; + ++ wldev->rx_antenna = B43_ANTENNA_DEFAULT; ++ wldev->tx_antenna = B43_ANTENNA_DEFAULT; + wldev->use_pio = b43_modparam_pio; + wldev->dev = dev; + wldev->wl = wl; +@@ -5331,6 +5373,9 @@ static struct b43_wl *b43_wireless_init( + + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + ++ hw->wiphy->available_antennas_rx = 0x3; ++ hw->wiphy->available_antennas_tx = 0x3; ++ + wl->hw_registred = false; + hw->max_rates = 2; + SET_IEEE80211_DEV(hw, dev->dev); +--- a/drivers/net/wireless/b43/b43.h ++++ b/drivers/net/wireless/b43/b43.h +@@ -808,6 +808,8 @@ struct b43_wldev { + bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ + bool use_pio; /* TRUE if next init should use PIO */ + int gpiomask; /* GPIO LED mask as a module parameter */ ++ int rx_antenna; /* Used RX antenna (B43_ANTENNAxxx) */ ++ int tx_antenna; /* Used TX antenna (B43_ANTENNAxxx) */ + + /* PHY/Radio device. */ + struct b43_phy phy; diff --git a/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch b/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch new file mode 100644 index 000000000..ce9ad7d5c --- /dev/null +++ b/package/mac80211/patches/830-b43-workaround-pcie-bcm4716.patch @@ -0,0 +1,134 @@ +From 4f214b1ead0af7439921637645cb63f378516175 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 21 Jan 2012 18:48:38 +0100 +Subject: [PATCH 33/34] b43: add workaround for b43 on pcie bus of bcm4716. + +bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder +transactions. As a fix, a read after write is performed on certain +places in the code. Older chips and the newer 5357 family don't require +this fix. +This code is based on the brcmsmac driver. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + drivers/net/wireless/b43/b43.h | 26 ++++++++++++++++++++++++++ + drivers/net/wireless/b43/bus.h | 10 ++++++++++ + drivers/net/wireless/b43/phy_common.c | 6 ++++++ + drivers/net/wireless/b43/phy_n.c | 10 +++++----- + 4 files changed, 47 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/b43/b43.h ++++ b/drivers/net/wireless/b43/b43.h +@@ -1048,6 +1048,32 @@ static inline bool b43_using_pio_transfe + return dev->__using_pio_transfers; + } + ++/* ++ * bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder ++ * transactions. As a fix, a read after write is performed on certain places ++ * in the code. Older chips and the newer 5357 family don't require this fix. ++ */ ++#ifdef CONFIG_BCM47XX_BCMA ++#include <asm/mach-bcm47xx/bcm47xx.h> ++static inline void b43_wflush16(struct b43_wldev *dev, u16 offset, u16 value) ++{ ++ if (b43_bus_host_is_pci(dev->dev) && ++ bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA && ++ (bcm47xx_bus.bcma.bus.chipinfo.id == 0x4716 || ++ bcm47xx_bus.bcma.bus.chipinfo.id == 0x5300)) { ++ b43_write16(dev, offset, value); ++ b43_read16(dev, offset); ++ } else { ++ b43_write16(dev, offset, value); ++ } ++} ++#else ++static inline void b43_wflush16(struct b43_wldev *dev, u16 offset, u16 value) ++{ ++ b43_write16(dev, offset, value); ++} ++#endif ++ + /* Message printing */ + __printf(2, 3) void b43info(struct b43_wl *wl, const char *fmt, ...); + __printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...); +--- a/drivers/net/wireless/b43/bus.h ++++ b/drivers/net/wireless/b43/bus.h +@@ -60,6 +60,16 @@ static inline bool b43_bus_host_is_sdio( + return (dev->bus_type == B43_BUS_SSB && + dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO); + } ++static inline bool b43_bus_host_is_pci(struct b43_bus_dev *dev) ++{ ++ if (dev->bus_type == B43_BUS_SSB) ++ return (dev->sdev->bus->bustype == SSB_BUSTYPE_PCI); ++#ifdef CONFIG_B43_BCMA ++ if (dev->bus_type == B43_BUS_BCMA) ++ return (dev->bdev->bus->hosttype == BCMA_HOSTTYPE_PCI); ++#endif ++ return false; ++} + + 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); +--- a/drivers/net/wireless/b43/phy_common.c ++++ b/drivers/net/wireless/b43/phy_common.c +@@ -266,6 +266,12 @@ void b43_phy_write(struct b43_wldev *dev + { + assert_mac_suspended(dev); + dev->phy.ops->phy_write(dev, reg, value); ++#ifdef CONFIG_BCM47XX ++ if (b43_bus_host_is_pci(dev->dev) && reg == 0x72) { ++ b43_read16(dev, B43_MMIO_PHY_VER); ++ return; ++ } ++#endif + if (++dev->phy.writes_counter == B43_MAX_WRITES_IN_ROW) { + b43_read16(dev, B43_MMIO_PHY_VER); + dev->phy.writes_counter = 0; +--- a/drivers/net/wireless/b43/phy_n.c ++++ b/drivers/net/wireless/b43/phy_n.c +@@ -5423,14 +5423,14 @@ static inline void check_phyreg(struct b + static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg) + { + check_phyreg(dev, reg); +- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); ++ b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg); + return b43_read16(dev, B43_MMIO_PHY_DATA); + } + + static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value) + { + check_phyreg(dev, reg); +- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); ++ b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg); + b43_write16(dev, B43_MMIO_PHY_DATA, value); + } + +@@ -5438,7 +5438,7 @@ static void b43_nphy_op_maskset(struct b + u16 set) + { + check_phyreg(dev, reg); +- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); ++ b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg); + b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set); + } + +@@ -5449,7 +5449,7 @@ static u16 b43_nphy_op_radio_read(struct + /* N-PHY needs 0x100 for read access */ + reg |= 0x100; + +- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); ++ b43_wflush16(dev, B43_MMIO_RADIO_CONTROL, reg); + return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); + } + +@@ -5458,7 +5458,7 @@ static void b43_nphy_op_radio_write(stru + /* Register 1 is a 32-bit register. */ + B43_WARN_ON(reg == 1); + +- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); ++ b43_wflush16(dev, B43_MMIO_RADIO_CONTROL, reg); + b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); + } + diff --git a/package/mac80211/patches/849-brcmsmac-add-device-found-on-some-SoCs-like-the-bcm4.patch b/package/mac80211/patches/849-brcmsmac-add-device-found-on-some-SoCs-like-the-bcm4.patch new file mode 100644 index 000000000..f70a261f0 --- /dev/null +++ b/package/mac80211/patches/849-brcmsmac-add-device-found-on-some-SoCs-like-the-bcm4.patch @@ -0,0 +1,39 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +@@ -94,6 +94,7 @@ MODULE_FIRMWARE("brcm/bcm43xx_hdr-0.fw") + + /* recognized BCMA Core IDs */ + static struct bcma_device_id brcms_coreid_table[] = { ++// BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 17, BCMA_ANY_CLASS), + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS), + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS), + BCMA_CORETABLE_END +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -734,7 +734,7 @@ static void brcms_c_ucode_bsinit(struct + brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs); + + /* do band-specific ucode IHR, SHM, and SCR inits */ +- if (D11REV_IS(wlc_hw->corerev, 23)) { ++ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) { + if (BRCMS_ISNPHY(wlc_hw->band)) + brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16); + else +@@ -2259,7 +2259,7 @@ static void brcms_ucode_download(struct + if (wlc_hw->ucode_loaded) + return; + +- if (D11REV_IS(wlc_hw->corerev, 23)) { ++ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) { + if (BRCMS_ISNPHY(wlc_hw->band)) { + brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo, + ucode->bcm43xx_16_mimosz); +@@ -3221,7 +3221,7 @@ static void brcms_b_coreinit(struct brcm + + sflags = bcma_aread32(core, BCMA_IOST); + +- if (D11REV_IS(wlc_hw->corerev, 23)) { ++ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) { + if (BRCMS_ISNPHY(wlc_hw->band)) + brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16); + else diff --git a/package/mac80211/patches/850-brcmsmac-add-support-for-BCM43224.patch b/package/mac80211/patches/850-brcmsmac-add-support-for-BCM43224.patch new file mode 100644 index 000000000..b135c7d3f --- /dev/null +++ b/package/mac80211/patches/850-brcmsmac-add-support-for-BCM43224.patch @@ -0,0 +1,29 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -4135,6 +4135,7 @@ void brcms_c_wme_setparams(struct brcms_ + M_EDCF_QINFO + + wme_ac2fifo[aci] * M_EDCF_QLEN + i, + *shm_entry++); ++ printk("dummy\n"); + } + + if (suspend) { +@@ -4537,7 +4538,8 @@ static int brcms_b_attach(struct brcms_c + + /* check device id(srom, nvram etc.) to set bands */ + if (wlc_hw->deviceid == BCM43224_D11N_ID || +- wlc_hw->deviceid == BCM43224_D11N_ID_VEN1) ++ wlc_hw->deviceid == BCM43224_D11N_ID_VEN1 || ++ wlc_hw->deviceid == BCM43224_CHIP_ID) + /* Dualband boards */ + wlc_hw->_nbands = 2; + else +@@ -5797,7 +5799,7 @@ static bool brcms_c_chipmatch_pci(struct + return false; + } + +- if (device == BCM43224_D11N_ID_VEN1) ++ if (device == BCM43224_D11N_ID_VEN1 || device == BCM43224_CHIP_ID) + return true; + if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID)) + return true; diff --git a/package/mac80211/patches/851-brcmsmac-start-adding-support-for-core-rev-28.patch b/package/mac80211/patches/851-brcmsmac-start-adding-support-for-core-rev-28.patch new file mode 100644 index 000000000..198af613c --- /dev/null +++ b/package/mac80211/patches/851-brcmsmac-start-adding-support-for-core-rev-28.patch @@ -0,0 +1,75 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +@@ -97,6 +97,7 @@ static struct bcma_device_id brcms_corei + // BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 17, BCMA_ANY_CLASS), + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS), + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS), ++// BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 28, BCMA_ANY_CLASS), + BCMA_CORETABLE_END + }; + MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -734,7 +734,7 @@ static void brcms_c_ucode_bsinit(struct + brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs); + + /* do band-specific ucode IHR, SHM, and SCR inits */ +- if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) { ++ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23) || D11REV_IS(wlc_hw->corerev, 28)) { + if (BRCMS_ISNPHY(wlc_hw->band)) + brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16); + else +@@ -2259,7 +2259,7 @@ static void brcms_ucode_download(struct + if (wlc_hw->ucode_loaded) + return; + +- if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) { ++ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23) || D11REV_IS(wlc_hw->corerev, 28)) { + if (BRCMS_ISNPHY(wlc_hw->band)) { + brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo, + ucode->bcm43xx_16_mimosz); +@@ -3221,7 +3221,7 @@ static void brcms_b_coreinit(struct brcm + + sflags = bcma_aread32(core, BCMA_IOST); + +- if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) { ++ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23) || D11REV_IS(wlc_hw->corerev, 28)) { + if (BRCMS_ISNPHY(wlc_hw->band)) + brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16); + else +@@ -5818,6 +5818,8 @@ static bool brcms_c_chipmatch_soc(struct + + if (chipinfo->id == BCMA_CHIP_ID_BCM4716) + return true; ++ if (chipinfo->id == BCMA_CHIP_ID_BCM5357) ++ return true; + + pr_err("unknown chip id %04x\n", chipinfo->id); + return false; +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h +@@ -65,7 +65,7 @@ + #define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */ + + /* max # supported core revisions (0 .. MAXCOREREV - 1) */ +-#define MAXCOREREV 28 ++#define MAXCOREREV 29 + + /* Double check that unsupported cores are not enabled */ + #if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV) +--- a/drivers/net/wireless/brcm80211/brcmsmac/types.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h +@@ -93,11 +93,11 @@ + #define BOARD_GPIO_13 0x2000 + + /* **** Core type/rev defaults **** */ +-#define D11CONF 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 ++#define D11CONF 0x1fffffb0 /* Supported D11 revs: 4, 5, 7-27 + * also need to update wlc.h MAXCOREREV + */ + +-#define NCONF 0x000001ff /* Supported nphy revs: ++#define NCONF 0x000002ff /* Supported nphy revs: + * 0 4321a0 + * 1 4321a1 + * 2 4321b0/b1/c0/c1 |