mac80211: update to 2011-08-10

SVN-Revision: 27958
This commit is contained in:
Felix Fietkau 2011-08-11 13:52:27 +00:00
parent ce2ced7311
commit 400f75a1b6
62 changed files with 547 additions and 5247 deletions

View file

@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=mac80211
PKG_VERSION:=2011-06-22
PKG_RELEASE:=2
PKG_VERSION:=2011-08-10
PKG_RELEASE:=1
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
PKG_MD5SUM:=3ffdd5cecedcf4236f599bdbc55ba10d
PKG_MD5SUM:=fb2ee04eaafbdf4117c475ba78f8f5b9
PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)

View file

@ -1,6 +1,6 @@
--- a/config.mk
+++ b/config.mk
@@ -337,8 +337,8 @@ CONFIG_BCMA_HOST_PCI=y
@@ -339,8 +339,8 @@ CONFIG_B43_BCMA_PIO=y
CONFIG_P54_PCI=m

View file

@ -9,7 +9,7 @@
ifeq ($(CONFIG_MAC80211),y)
$(error "ERROR: you have MAC80211 compiled into the kernel, CONFIG_MAC80211=y, as such you cannot replace its mac80211 driver. You need this set to CONFIG_MAC80211=m. If you are using Fedora upgrade your kernel as later version should this set as modular. For further information on Fedora see https://bugzilla.redhat.com/show_bug.cgi?id=470143. If you are using your own kernel recompile it and make mac80211 modular")
@@ -646,10 +646,10 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27
@@ -649,10 +649,10 @@ endif #CONFIG_COMPAT_KERNEL_2_6_27
# We need the backported rfkill module on kernel < 2.6.31.
# In more recent kernel versions use the in kernel rfkill module.
ifdef CONFIG_COMPAT_KERNEL_2_6_31

View file

@ -19,7 +19,7 @@
else
include $(KLIB_BUILD)/.config
endif
@@ -314,7 +313,8 @@ CONFIG_IPW2200_QOS=y
@@ -315,7 +314,8 @@ CONFIG_IPW2200_QOS=y
# % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
endif #CONFIG_WIRELESS_EXT
@ -29,7 +29,7 @@
# Sonics Silicon Backplane
CONFIG_SSB_SPROM=y
@@ -327,7 +327,7 @@ endif #CONFIG_PCMCIA
@@ -328,7 +328,7 @@ endif #CONFIG_PCMCIA
# CONFIG_SSB_DEBUG=y
CONFIG_SSB_DRIVER_PCICORE=y
CONFIG_B43_SSB=y
@ -38,7 +38,7 @@
CONFIG_BCMA=m
CONFIG_BCMA_BLOCKIO=y
@@ -534,7 +534,6 @@ endif #CONFIG_SPI_MASTER end of SPI driv
@@ -537,7 +537,6 @@ endif #CONFIG_SPI_MASTER end of SPI driv
ifdef CONFIG_MMC

View file

@ -11,7 +11,7 @@
obj-$(CONFIG_COMPAT_STAGING) += drivers/staging/ath6kl/
--- a/config.mk
+++ b/config.mk
@@ -329,9 +329,9 @@ CONFIG_SSB_DRIVER_PCICORE=y
@@ -330,9 +330,9 @@ CONFIG_SSB_DRIVER_PCICORE=y
CONFIG_B43_SSB=y
endif #__CONFIG_SSB
@ -22,5 +22,5 @@
+# CONFIG_BCMA_BLOCKIO=y
+# CONFIG_BCMA_HOST_PCI=y
# CONFIG_BCMA_DEBUG=y
# CONFIG_B43_BCMA=y
CONFIG_B43_BCMA=y
CONFIG_B43_BCMA_PIO=y

View file

@ -9,7 +9,7 @@
endif #CONFIG_STAGING
# mac80211 test driver
@@ -365,13 +365,13 @@ endif #CONFIG_CRC_ITU_T
@@ -367,13 +367,13 @@ endif #CONFIG_CRC_ITU_T
CONFIG_MWL8K=m
# Ethernet drivers go here
@ -28,7 +28,7 @@
endif #CONFIG_COMPAT_KERNEL_2_6_27
ifdef CONFIG_WIRELESS_EXT
@@ -431,21 +431,21 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
@@ -434,21 +434,21 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
# Note: this depends on CONFIG_USB_NET_RNDIS_HOST and CONFIG_USB_NET_CDCETHER
# it also requires new RNDIS_HOST and CDC_ETHER modules which we add
ifdef CONFIG_COMPAT_KERNEL_2_6_29

View file

@ -1,6 +1,6 @@
--- a/config.mk
+++ b/config.mk
@@ -517,7 +517,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv
@@ -520,7 +520,7 @@ endif #CONFIG_SPI_MASTER end of SPI driv
ifdef CONFIG_MMC

View file

@ -7,5 +7,5 @@
-CONFIG_B43_PHY_N=y
+# CONFIG_B43_PHY_N=y
# CONFIG_B43_PHY_HT=y
# CONFIG_B43_PHY_LCN=y
# CONFIG_B43_FORCE_PIO=y
# CONFIG_B43_DEBUG=y

View file

@ -1,6 +1,6 @@
--- a/config.mk
+++ b/config.mk
@@ -327,7 +327,7 @@ CONFIG_RTL8180=m
@@ -329,7 +329,7 @@ CONFIG_RTL8180=m
CONFIG_ADM8211=m
@ -9,7 +9,7 @@
CONFIG_RT2400PCI=m
CONFIG_RT2500PCI=m
ifdef CONFIG_CRC_CCITT
@@ -466,7 +466,7 @@ CONFIG_RT2800USB_RT35XX=y
@@ -469,7 +469,7 @@ CONFIG_RT2800USB_RT35XX=y
# CONFIG_RT2800USB_RT53XX=y
CONFIG_RT2800USB_UNKNOWN=y
endif #CONFIG_CRC_CCITT

View file

@ -98,7 +98,7 @@
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -181,75 +181,52 @@ static int b43legacy_ratelimit(struct b4
@@ -180,75 +180,52 @@ static int b43legacy_ratelimit(struct b4
void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...)
{

View file

@ -1,12 +0,0 @@
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3728,7 +3728,9 @@ static int nl80211_dump_scan(struct sk_b
spin_lock_bh(&rdev->bss_lock);
cfg80211_bss_expire(rdev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0))
cb->seq = rdev->bss_generation;
+#endif
list_for_each_entry(scan, &rdev->bss_list, list) {
if (++idx <= start)

View file

@ -11,9 +11,9 @@
+endif
--- a/include/linux/compat-2.6.31.h
+++ b/include/linux/compat-2.6.31.h
@@ -199,6 +199,20 @@ void compat_synchronize_threaded_irq(str
#define list_entry_rcu(ptr, type, member) \
container_of(rcu_dereference(ptr), type, member)
@@ -202,6 +202,20 @@ void compat_synchronize_threaded_irq(str
#define skb_walk_frags(skb, iter) \
for (iter = skb_shinfo(skb)->frag_list; iter; iter = iter->next)
+#ifndef CONFIG_64BIT
+
@ -70,9 +70,9 @@
+
--- a/include/linux/compat-3.1.h
+++ b/include/linux/compat-3.1.h
@@ -24,6 +24,18 @@
#define genl_dump_check_consistent(...) do {} while(0)
@@ -36,6 +36,18 @@
.prod_id = { NULL, NULL, (v3), NULL }, \
.prod_id_hash = { 0, 0, (vh3), 0 }, }
+/*
+ * In many versions, several architectures do not seem to include an

View file

@ -1,11 +0,0 @@
--- a/drivers/net/wireless/b43/main.c~ 2011-07-23 00:33:46.573306410 +0200
+++ b/drivers/net/wireless/b43/main.c 2011-07-23 00:36:14.657726075 +0200
@@ -4955,7 +4955,7 @@
static void b43_wireless_core_detach(struct b43_wldev *dev)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
- if (dev->sdev->bus->bustype != SSB_BUSTYPE_SDIO)
+ if (dev->dev->sdev->bus->bustype != SSB_BUSTYPE_SDIO)
compat_destroy_threaded_irq(&dev->irq_compat);
#endif
/* We release firmware that late to not be required to re-request

View file

@ -33,7 +33,7 @@
#endif
--- a/config.mk
+++ b/config.mk
@@ -452,7 +452,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
@@ -455,7 +455,7 @@ endif #CONFIG_COMPAT_KERNEL_2_6_29
# This activates a threading fix for usb urb.
# this is mainline commit: b3e670443b7fb8a2d29831b62b44a039c283e351
# This fix will be included in some stable releases.

View file

@ -1,13 +1,3 @@
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -27,6 +27,7 @@
*
*****************************************************************************/
+#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
--- a/drivers/net/wireless/iwlegacy/iwl3945-base.c
+++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c
@@ -27,6 +27,7 @@
@ -27,7 +17,7 @@
+#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/slab.h>
#include <linux/hardirq.h>
--- a/drivers/net/wireless/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/libertas_tf/if_usb.c
@@ -9,6 +9,7 @@
@ -47,7 +37,7 @@
+#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/slab.h>
#include <linux/hardirq.h>
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -4,6 +4,7 @@
@ -107,7 +97,7 @@
+#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/sched.h>
#include <linux/hardirq.h>
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -21,6 +21,7 @@
@ -137,7 +127,7 @@
+#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/moduleparam.h>
#include <linux/hardirq.h>
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -2,6 +2,7 @@

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath5k/initvals.c
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
@@ -58,8 +58,14 @@ static const struct ath5k_ini ar5210_ini
@@ -57,8 +57,14 @@ static const struct ath5k_ini ar5210_ini
{ AR5K_IMR, 0 },
{ AR5K_IER, AR5K_IER_DISABLE },
{ AR5K_BSR, 0, AR5K_INI_READ },
@ -17,7 +17,7 @@
{ AR5K_RXNOFRM, 8 },
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -787,10 +787,18 @@ void ath5k_hw_dma_init(struct ath5k_hw *
@@ -786,10 +786,18 @@ void ath5k_hw_dma_init(struct ath5k_hw *
* guess we can tweak it and see how it goes ;-)
*/
if (ah->ah_version != AR5K_AR5210) {

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1038,6 +1038,7 @@ struct cfg80211_ibss_params {
@@ -1045,6 +1045,7 @@ struct cfg80211_ibss_params {
u8 *ssid;
u8 *bssid;
struct ieee80211_channel *channel;
@ -8,7 +8,7 @@
u8 *ie;
u8 ssid_len, ie_len;
u16 beacon_interval;
@@ -2539,6 +2540,12 @@ struct cfg80211_bss *cfg80211_get_bss(st
@@ -2478,6 +2479,12 @@ struct cfg80211_bss *cfg80211_get_bss(st
const u8 *bssid,
const u8 *ssid, size_t ssid_len,
u16 capa_mask, u16 capa_val);
@ -21,9 +21,147 @@
static inline struct cfg80211_bss *
cfg80211_get_ibss(struct wiphy *wiphy,
struct ieee80211_channel *channel,
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4351,13 +4351,41 @@ static int nl80211_join_ibss(struct sk_b
ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}
- ibss.channel = ieee80211_get_channel(wiphy,
- nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+ if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
+ enum nl80211_channel_type channel_type;
+
+ channel_type = nla_get_u32(
+ info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
+ if (channel_type != NL80211_CHAN_NO_HT &&
+ channel_type != NL80211_CHAN_HT20 &&
+ channel_type != NL80211_CHAN_HT40PLUS &&
+ channel_type != NL80211_CHAN_HT40MINUS)
+ return -EINVAL;
+ ibss.channel_type = channel_type;
+ } else {
+ ibss.channel_type = NL80211_CHAN_NO_HT;
+ }
+
+ ibss.channel = rdev_freq_to_chan(rdev,
+ nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
+ ibss.channel_type);
if (!ibss.channel ||
+ ibss.channel->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
- ibss.channel->flags & IEEE80211_CHAN_DISABLED)
+ ibss.channel->flags & IEEE80211_CHAN_RADAR)
return -EINVAL;
+ /* Both channels should be able to initiate communication */
+ if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
+ ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
+ !can_beacon_sec_chan(&rdev->wiphy, ibss.channel,
+ ibss.channel_type)) {
+ printk(KERN_DEBUG
+ "cfg80211: Secondary channel not "
+ "allowed to initiate communication\n");
+ return -EINVAL;
+ }
+
ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -44,7 +44,7 @@ rdev_freq_to_chan(struct cfg80211_regist
return chan;
}
-static bool can_beacon_sec_chan(struct wiphy *wiphy,
+bool can_beacon_sec_chan(struct wiphy *wiphy,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type)
{
@@ -75,6 +75,7 @@ static bool can_beacon_sec_chan(struct w
return true;
}
+EXPORT_SYMBOL(can_beacon_sec_chan);
int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, int freq,
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -441,6 +441,9 @@ cfg80211_can_add_interface(struct cfg802
struct ieee80211_channel *
rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
int freq, enum nl80211_channel_type channel_type);
+bool can_beacon_sec_chan(struct wiphy *wiphy,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type);
int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, int freq,
enum nl80211_channel_type channel_type);
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -365,6 +365,19 @@ struct cfg80211_bss *cfg80211_get_bss(st
const u8 *ssid, size_t ssid_len,
u16 capa_mask, u16 capa_val)
{
+ /* call HT version with no HT requirements */
+ return cfg80211_get_bss_ht(wiphy, channel, bssid, ssid, ssid_len,
+ capa_mask, capa_val, NL80211_CHAN_NO_HT);
+}
+EXPORT_SYMBOL(cfg80211_get_bss);
+
+struct cfg80211_bss *cfg80211_get_bss_ht(struct wiphy *wiphy,
+ struct ieee80211_channel *channel,
+ const u8 *bssid,
+ const u8 *ssid, size_t ssid_len,
+ u16 capa_mask, u16 capa_val,
+ enum nl80211_channel_type require_ht)
+{
struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
struct cfg80211_internal_bss *bss, *res = NULL;
unsigned long now = jiffies;
@@ -374,8 +387,26 @@ struct cfg80211_bss *cfg80211_get_bss(st
list_for_each_entry(bss, &dev->bss_list, list) {
if ((bss->pub.capability & capa_mask) != capa_val)
continue;
- if (channel && bss->pub.channel != channel)
- continue;
+ if (channel) {
+ if (bss->pub.channel != channel)
+ continue;
+ if (require_ht != NL80211_CHAN_NO_HT) {
+ struct ieee80211_ht_info *ht_info;
+ ht_info = (struct ieee80211_ht_info *)
+ ieee80211_bss_get_ie(&bss->pub,
+ WLAN_EID_HT_INFORMATION);
+ if (!ht_info)
+ continue;
+ if (require_ht == NL80211_CHAN_HT40MINUS &&
+ !(ht_info->ht_param &
+ IEEE80211_HT_PARAM_CHA_SEC_BELOW))
+ continue;
+ if (require_ht == NL80211_CHAN_HT40PLUS &&
+ !(ht_info->ht_param &
+ IEEE80211_HT_PARAM_CHA_SEC_ABOVE))
+ continue;
+ }
+ }
/* Don't get expired BSS structs */
if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
!atomic_read(&bss->hold))
@@ -392,7 +423,7 @@ struct cfg80211_bss *cfg80211_get_bss(st
return NULL;
return &res->pub;
}
-EXPORT_SYMBOL(cfg80211_get_bss);
+EXPORT_SYMBOL(cfg80211_get_bss_ht);
struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
struct ieee80211_channel *channel,
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -439,6 +439,7 @@ struct ieee80211_if_ibss {
@@ -464,6 +464,7 @@ struct ieee80211_if_ibss {
u8 ssid_len, ie_len;
u8 *ie;
struct ieee80211_channel *channel;
@ -31,7 +169,7 @@
unsigned long ibss_join_req;
/* probe response/beacon for IBSS */
@@ -1121,6 +1122,7 @@ void ieee80211_ibss_notify_scan_complete
@@ -1151,6 +1152,7 @@ void ieee80211_ibss_notify_scan_complete
void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
u8 *bssid, u8 *addr, u32 supp_rates,
@ -39,7 +177,7 @@
gfp_t gfp);
int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
struct cfg80211_ibss_params *params);
@@ -1373,6 +1375,12 @@ void ieee80211_recalc_smps(struct ieee80
@@ -1405,6 +1407,12 @@ void ieee80211_recalc_smps(struct ieee80
size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
const u8 *ids, int n_ids, size_t offset);
size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
@ -52,7 +190,7 @@
/* internal work items */
void ieee80211_work_init(struct ieee80211_local *local);
@@ -1401,6 +1409,8 @@ ieee80211_get_channel_mode(struct ieee80
@@ -1433,6 +1441,8 @@ ieee80211_get_channel_mode(struct ieee80
bool ieee80211_set_channel_type(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
enum nl80211_channel_type chantype);
@ -63,7 +201,7 @@
#define debug_noinline noinline
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1007,23 +1007,8 @@ int ieee80211_build_preq_ies(struct ieee
@@ -1008,23 +1008,8 @@ int ieee80211_build_preq_ies(struct ieee
offset = noffset;
}
@ -89,10 +227,10 @@
/*
* If adding more here, adjust code in main.c
@@ -1464,3 +1449,100 @@ size_t ieee80211_ie_split_vendor(const u
return pos;
@@ -1548,3 +1533,100 @@ void ieee80211_disable_rssi_reports(stru
_ieee80211_enable_rssi_reports(sdata, 0, 0);
}
EXPORT_SYMBOL(ieee80211_disable_rssi_reports);
+
+u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband,
+ u16 cap)
@ -192,7 +330,7 @@
+}
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -117,7 +117,6 @@ static void ieee80211_add_ht_ie(struct s
@@ -118,7 +118,6 @@ static void ieee80211_add_ht_ie(struct s
u8 *pos;
u32 flags = channel->flags;
u16 cap = sband->ht_cap.cap;
@ -200,7 +338,7 @@
if (!sband->ht_cap.ht_supported)
return;
@@ -168,34 +167,8 @@ static void ieee80211_add_ht_ie(struct s
@@ -169,34 +168,8 @@ static void ieee80211_add_ht_ie(struct s
}
/* reserve and fill IE */
@ -236,124 +374,6 @@
}
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -365,6 +365,18 @@ struct cfg80211_bss *cfg80211_get_bss(st
const u8 *ssid, size_t ssid_len,
u16 capa_mask, u16 capa_val)
{
+ return cfg80211_get_bss_ht(wiphy, channel, bssid, ssid, ssid_len,
+ capa_mask, capa_val, NL80211_CHAN_NO_HT);
+}
+EXPORT_SYMBOL(cfg80211_get_bss);
+
+struct cfg80211_bss *cfg80211_get_bss_ht(struct wiphy *wiphy,
+ struct ieee80211_channel *channel,
+ const u8 *bssid,
+ const u8 *ssid, size_t ssid_len,
+ u16 capa_mask, u16 capa_val,
+ enum nl80211_channel_type channel_type)
+{
struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
struct cfg80211_internal_bss *bss, *res = NULL;
unsigned long now = jiffies;
@@ -374,8 +386,27 @@ struct cfg80211_bss *cfg80211_get_bss(st
list_for_each_entry(bss, &dev->bss_list, list) {
if ((bss->pub.capability & capa_mask) != capa_val)
continue;
- if (channel && bss->pub.channel != channel)
- continue;
+ if (channel) {
+ if (bss->pub.channel != channel)
+ continue;
+ if (channel_type == NL80211_CHAN_HT40MINUS ||
+ channel_type == NL80211_CHAN_HT40PLUS) {
+ struct ieee80211_ht_info *ht_info;
+ ht_info = (struct ieee80211_ht_info *)
+ ieee80211_bss_get_ie(&bss->pub,
+ WLAN_EID_HT_INFORMATION);
+ if (!ht_info)
+ continue;
+ if (channel_type == NL80211_CHAN_HT40MINUS &&
+ !(ht_info->ht_param &
+ IEEE80211_HT_PARAM_CHA_SEC_BELOW))
+ continue;
+ if (channel_type == NL80211_CHAN_HT40PLUS &&
+ !(ht_info->ht_param &
+ IEEE80211_HT_PARAM_CHA_SEC_ABOVE))
+ continue;
+ }
+ }
/* Don't get expired BSS structs */
if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
!atomic_read(&bss->hold))
@@ -392,7 +423,7 @@ struct cfg80211_bss *cfg80211_get_bss(st
return NULL;
return &res->pub;
}
-EXPORT_SYMBOL(cfg80211_get_bss);
+EXPORT_SYMBOL(cfg80211_get_bss_ht);
struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
struct ieee80211_channel *channel,
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4282,13 +4282,42 @@ static int nl80211_join_ibss(struct sk_b
ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}
- ibss.channel = ieee80211_get_channel(wiphy,
- nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+ if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
+ enum nl80211_channel_type channel_type;
+
+ channel_type = nla_get_u32(
+ info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
+ if (channel_type != NL80211_CHAN_NO_HT &&
+ channel_type != NL80211_CHAN_HT20 &&
+ channel_type != NL80211_CHAN_HT40PLUS &&
+ channel_type != NL80211_CHAN_HT40MINUS)
+ return -EINVAL;
+ ibss.channel_type = channel_type;
+ } else {
+ ibss.channel_type = NL80211_CHAN_NO_HT;
+ }
+
+ ibss.channel = rdev_freq_to_chan(rdev,
+ nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
+ ibss.channel_type);
+
if (!ibss.channel ||
+ ibss.channel->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
ibss.channel->flags & IEEE80211_CHAN_DISABLED)
return -EINVAL;
+#if 0
+ if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
+ ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
+ !can_beacon_sec_chan(&rdev->wiphy, ibss.chan, ibss.channel_type)) {
+ printk(KERN_DEBUG
+ "cfg80211: Secondary channel not "
+ "allowed to initiate communication\n");
+ return -EINVAL;
+ }
+#endif
+
ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -178,6 +178,8 @@ static void ieee80211_send_addba_resp(st
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
else if (sdata->vif.type == NL80211_IFTYPE_WDS)
memcpy(mgmt->bssid, da, ETH_ALEN);
+ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -84,6 +84,8 @@ static void ieee80211_send_addba_request
@ -388,7 +408,84 @@
IEEE80211_STYPE_ACTION);
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -64,6 +64,7 @@ static void ieee80211_rx_mgmt_auth_ibss(
@@ -35,6 +35,76 @@
#define IEEE80211_IBSS_MAX_STA_ENTRIES 128
+static bool ieee80211_can_use_ext_chan(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_channel *channel,
+ enum nl80211_channel_type channel_type)
+{
+ /* check if we are legally allowed to use HT extension channel */
+ if ((channel_type == NL80211_CHAN_HT40PLUS) ||
+ (channel_type == NL80211_CHAN_HT40MINUS)) {
+ int sec_freq = channel->center_freq +
+ (channel_type == NL80211_CHAN_HT40PLUS ? 20 : -20);
+ struct ieee80211_channel *sec_chan =
+ ieee80211_get_channel(sdata->wdev.wiphy, sec_freq);
+ if (!sec_chan || sec_chan->flags & (IEEE80211_CHAN_DISABLED |
+ IEEE80211_CHAN_PASSIVE_SCAN |
+ IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_RADAR)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void ieee80211_update_ht_elems(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_mgmt *mgmt,
+ struct ieee80211_ht_info *ht_info)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_supported_band *sband =
+ local->hw.wiphy->bands[local->oper_channel->band];
+ enum nl80211_channel_type channel_type =
+ ieee80211_ht_info_to_channel_type(ht_info);
+
+ if (!ieee80211_can_use_ext_chan(sdata, local->oper_channel, channel_type))
+ channel_type = NL80211_CHAN_HT20;
+
+ if (channel_type != local->_oper_channel_type) {
+ struct sk_buff *skb = rcu_dereference_protected(
+ sdata->u.ibss.presp,
+ lockdep_is_held(&ifibss->mtx));
+ struct sk_buff *nskb;
+ u8 *ht_ie;
+
+ /* update HT IE. If not yet existing, create one */
+ nskb = skb_copy(skb, GFP_ATOMIC);
+ ht_ie = (u8 *)cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
+ (const u8 *)(nskb->data + 24 +
+ sizeof(mgmt->u.beacon)),
+ nskb->len - 24 -
+ sizeof(mgmt->u.beacon));
+ if (!ht_ie)
+ ht_ie = skb_put(nskb, 4 +
+ sizeof(struct ieee80211_ht_cap) +
+ sizeof(struct ieee80211_ht_info));
+
+ ht_ie = ieee80211_ie_build_ht_cap(ht_ie, sband,
+ sband->ht_cap.cap);
+ ht_ie = ieee80211_ie_build_ht_info(ht_ie, &sband->ht_cap,
+ local->oper_channel, channel_type);
+ rcu_assign_pointer(sdata->u.ibss.presp, nskb);
+ kfree_skb(skb);
+
+ if(!ieee80211_set_channel_type(local, sdata, channel_type)) {
+ channel_type = NL80211_CHAN_HT20;
+ WARN_ON(!ieee80211_set_channel_type(local, sdata,
+ channel_type));
+ }
+
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
+ }
+
+}
static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt,
@@ -64,6 +134,7 @@ static void ieee80211_rx_mgmt_auth_ibss(
static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
const u8 *bssid, const int beacon_int,
struct ieee80211_channel *chan,
@ -396,24 +493,30 @@
const u32 basic_rates,
const u16 capability, u64 tsf)
{
@@ -104,8 +105,12 @@ static void __ieee80211_sta_join_ibss(st
@@ -104,8 +175,17 @@ static void __ieee80211_sta_join_ibss(st
sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
+ /* entering a legacy IBSS. Use given HT configuration. */
+ if (channel_type == NL80211_CHAN_NO_HT)
+ channel_type = ifibss->channel_type;
+
local->oper_channel = chan;
- WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
+ WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
+
+ /* if phy is on a different extension channel, setting ht40 will fail */
+ if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
+ channel_type = NL80211_CHAN_HT20;
+ WARN_ON(!ieee80211_set_channel_type(local, sdata,
+ channel_type));
+ }
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
sband = local->hw.wiphy->bands[chan->band];
@@ -171,6 +176,17 @@ static void __ieee80211_sta_join_ibss(st
@@ -171,6 +251,18 @@ static void __ieee80211_sta_join_ibss(st
memcpy(skb_put(skb, ifibss->ie_len),
ifibss->ie, ifibss->ie_len);
+ /* add HT capability and information IEs */
+ if (channel_type != NL80211_CHAN_NO_HT && sband->ht_cap.ht_supported) {
+ pos = skb_put(skb, 4 +
+ sizeof(struct ieee80211_ht_cap) +
@ -428,7 +531,7 @@
if (local->hw.queues >= 4) {
pos = skb_put(skb, 9);
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
@@ -219,6 +235,8 @@ static void ieee80211_sta_join_ibss(stru
@@ -219,6 +311,8 @@ static void ieee80211_sta_join_ibss(stru
u32 basic_rates;
int i, j;
u16 beacon_int = cbss->beacon_interval;
@ -437,7 +540,7 @@
lockdep_assert_held(&sdata->u.ibss.mtx);
@@ -242,9 +260,15 @@ static void ieee80211_sta_join_ibss(stru
@@ -242,9 +336,23 @@ static void ieee80211_sta_join_ibss(stru
}
}
@ -445,6 +548,14 @@
+ if (ht_info_ie)
+ channel_type = ieee80211_ht_info_to_channel_type(
+ (struct ieee80211_ht_info *) (ht_info_ie + 2));
+
+ if (!ieee80211_can_use_ext_chan(sdata, cbss->channel, channel_type)) {
+ channel_type = NL80211_CHAN_HT20;
+#ifdef CONFIG_MAC80211_IBSS_DEBUG
+ printk(KERN_DEBUG "%s: IBSS not allowed on secondary channel\n",
+ sdata->name);
+#endif
+ }
+
__ieee80211_sta_join_ibss(sdata, cbss->bssid,
beacon_int,
@ -453,7 +564,7 @@
basic_rates,
cbss->capability,
cbss->tsf);
@@ -310,11 +334,65 @@ static void ieee80211_rx_bss_info(struct
@@ -310,11 +418,24 @@ static void ieee80211_rx_bss_info(struct
} else
sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
mgmt->sa, supp_rates,
@ -467,62 +578,21 @@
+ if (elems->wmm_info)
+ set_sta_flags(sta, WLAN_STA_WME);
+
+ /* remote station uses ht */
+ if (elems->ht_info_elem) {
+ struct ieee80211_supported_band *sband =
+ local->hw.wiphy->bands[channel->band];
+ enum nl80211_channel_type channel_type;
+
+ channel_type =
+ ieee80211_ht_info_to_channel_type(
+ elems->ht_info_elem);
+ if (channel_type != local->_oper_channel_type) {
+ struct sk_buff *skb =
+ sdata->u.ibss.presp;
+ struct sk_buff *nskb;
+ u8 *ht_ie;
+
+ nskb = skb_copy(skb, GFP_ATOMIC);
+ ht_ie = (u8 *) cfg80211_find_ie(
+ WLAN_EID_HT_CAPABILITY,
+ nskb->data + 24 +
+ sizeof(mgmt->u.beacon),
+ nskb->len - 24 -
+ sizeof(mgmt->u.beacon));
+
+ if (!ht_ie)
+ ht_ie = skb_put(nskb, 4 +
+ sizeof(struct ieee80211_ht_cap) +
+ sizeof(struct ieee80211_ht_info));
+ ht_ie = ieee80211_ie_build_ht_cap(ht_ie,
+ sband,
+ sband->ht_cap.cap);
+ ht_ie = ieee80211_ie_build_ht_info(
+ ht_ie,
+ &sband->ht_cap,
+ channel,
+ channel_type);
+ sdata->u.ibss.presp = nskb;
+ kfree_skb(skb);
+
+ local->_oper_channel_type =
+ channel_type;
+ WARN_ON(!ieee80211_set_channel_type(
+ local,
+ sdata,
+ channel_type));
+ ieee80211_hw_config(local,
+ IEEE80211_CONF_CHANGE_CHANNEL);
+ }
+ ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
+ elems->ht_cap_elem,
+ &sta->sta.ht_cap);
+
+ ieee80211_update_ht_elems(sdata, mgmt,
+ elems->ht_info_elem);
+ ieee80211_ht_cap_ie_to_sta_ht_cap(
+ local->hw.wiphy->bands[
+ local->oper_channel->band],
+ elems->ht_cap_elem,
+ &sta->sta.ht_cap);
+ }
+ }
rcu_read_unlock();
}
@@ -404,7 +482,7 @@ static void ieee80211_rx_bss_info(struct
@@ -404,7 +525,7 @@ static void ieee80211_rx_bss_info(struct
ieee80211_sta_join_ibss(sdata, bss);
supp_rates = ieee80211_sta_get_rates(local, elems, band);
ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
@ -531,7 +601,7 @@
}
put_bss:
@@ -417,7 +495,8 @@ static void ieee80211_rx_bss_info(struct
@@ -417,7 +538,8 @@ static void ieee80211_rx_bss_info(struct
* must be callable in atomic context.
*/
struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
@ -541,7 +611,7 @@
gfp_t gfp)
{
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
@@ -458,6 +537,11 @@ struct sta_info *ieee80211_ibss_add_sta(
@@ -458,6 +580,11 @@ struct sta_info *ieee80211_ibss_add_sta(
sta->sta.supp_rates[band] = supp_rates |
ieee80211_mandatory_rates(local, band);
@ -553,7 +623,7 @@
rate_control_rate_init(sta);
/* If it fails, maybe we raced another insertion? */
@@ -556,8 +640,8 @@ static void ieee80211_sta_create_ibss(st
@@ -556,8 +683,8 @@ static void ieee80211_sta_create_ibss(st
sdata->drop_unencrypted = 0;
__ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
@ -564,7 +634,7 @@
}
/*
@@ -594,10 +678,10 @@ static void ieee80211_sta_find_ibss(stru
@@ -594,10 +721,10 @@ static void ieee80211_sta_find_ibss(stru
chan = ifibss->channel;
if (!is_zero_ether_addr(ifibss->bssid))
bssid = ifibss->bssid;
@ -577,7 +647,7 @@
if (cbss) {
struct ieee80211_bss *bss;
@@ -896,10 +980,15 @@ int ieee80211_ibss_join(struct ieee80211
@@ -896,10 +1023,15 @@ int ieee80211_ibss_join(struct ieee80211
struct sk_buff *skb;
skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
@ -597,7 +667,7 @@
params->ie_len);
if (!skb)
return -ENOMEM;
@@ -920,13 +1009,14 @@ int ieee80211_ibss_join(struct ieee80211
@@ -920,13 +1052,15 @@ int ieee80211_ibss_join(struct ieee80211
sdata->vif.bss_conf.beacon_int = params->beacon_interval;
sdata->u.ibss.channel = params->channel;
@ -607,15 +677,17 @@
/* fix ourselves to that channel now already */
if (params->channel_fixed) {
sdata->local->oper_channel = params->channel;
WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata,
- WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata,
- NL80211_CHAN_NO_HT));
+ params->channel_type));
+ if(!ieee80211_set_channel_type(sdata->local, sdata,
+ params->channel_type))
+ return -EINVAL;
}
if (params->ie) {
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2138,7 +2138,8 @@ ieee80211_rx_h_action(struct ieee80211_r
@@ -2148,7 +2148,8 @@ ieee80211_rx_h_action(struct ieee80211_r
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
sdata->vif.type != NL80211_IFTYPE_AP &&
@ -625,7 +697,7 @@
break;
/* verify action_code is present */
@@ -2654,7 +2655,8 @@ static int prepare_for_handlers(struct i
@@ -2666,7 +2667,8 @@ static int prepare_for_handlers(struct i
else
rate_idx = status->rate_idx;
rx->sta = ieee80211_ibss_add_sta(sdata, bssid,
@ -635,3 +707,14 @@
}
break;
case NL80211_IFTYPE_MESH_POINT:
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -186,6 +186,8 @@ static void ieee80211_send_addba_resp(st
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
else if (sdata->vif.type == NL80211_IFTYPE_WDS)
memcpy(mgmt->bssid, da, ETH_ALEN);
+ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -34,7 +34,7 @@ int ath9k_modparam_nohwcrypt;
@@ -35,7 +35,7 @@ int ath9k_modparam_nohwcrypt;
module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");

View file

@ -8,7 +8,7 @@
#include <asm/unaligned.h>
#include "hw.h"
@@ -453,8 +454,16 @@ static int ath9k_hw_init_macaddr(struct
@@ -460,8 +461,16 @@ static int ath9k_hw_init_macaddr(struct
common->macaddr[2 * i] = eeval >> 8;
common->macaddr[2 * i + 1] = eeval & 0xff;
}

View file

@ -1,6 +1,6 @@
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1643,6 +1643,8 @@ void regulatory_hint_11d(struct wiphy *w
@@ -1642,6 +1642,8 @@ void regulatory_hint_11d(struct wiphy *w
enum environment_cap env = ENVIRON_ANY;
struct regulatory_request *request;
@ -9,7 +9,7 @@
mutex_lock(&reg_mutex);
if (unlikely(!last_request))
@@ -1849,6 +1851,8 @@ static void restore_regulatory_settings(
@@ -1848,6 +1850,8 @@ static void restore_regulatory_settings(
void regulatory_hint_disconnect(void)
{

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1495,15 +1495,6 @@ static int ath9k_add_interface(struct ie
@@ -1499,15 +1499,6 @@ static int ath9k_add_interface(struct ie
}
}
@ -16,7 +16,7 @@
ath_dbg(common, ATH_DBG_CONFIG,
"Attach a VIF of type: %d\n", vif->type);
@@ -1529,15 +1520,6 @@ static int ath9k_change_interface(struct
@@ -1533,15 +1524,6 @@ static int ath9k_change_interface(struct
mutex_lock(&sc->mutex);
ath9k_ps_wakeup(sc);

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -95,13 +95,8 @@ ath5k_add_interface(struct ieee80211_hw
@@ -83,13 +83,8 @@ ath5k_add_interface(struct ieee80211_hw
goto end;
}
@ -9,30 +9,30 @@
- * We would need to operate the HW in ad-hoc mode to allow TSF updates
- * for the IBSS, but this breaks with additional AP or STA interfaces
- * at the moment. */
- if (sc->num_adhoc_vifs ||
- (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
- if (ah->num_adhoc_vifs ||
- (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
+ /* Don't allow more than one ad-hoc interface */
+ if (sc->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) {
ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n");
+ if (ah->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) {
ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n");
ret = -ELNRNG;
goto end;
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1883,7 +1883,7 @@ ath5k_beacon_send(struct ath5k_softc *sc
sc->bmisscount = 0;
@@ -1866,7 +1866,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
ah->bmisscount = 0;
}
- if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) ||
+ if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs + sc->num_adhoc_vifs > 1) ||
sc->opmode == NL80211_IFTYPE_MESH_POINT) {
- if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) ||
+ if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + ah->num_adhoc_vifs > 1) ||
ah->opmode == NL80211_IFTYPE_MESH_POINT) {
u64 tsf = ath5k_hw_get_tsf64(ah);
u32 tsftu = TSF_TO_TU(tsf);
@@ -1961,7 +1961,7 @@ ath5k_beacon_update_timers(struct ath5k_
@@ -1951,7 +1951,7 @@ ath5k_beacon_update_timers(struct ath5k_
u64 hw_tsf;
intval = sc->bintval & AR5K_BEACON_PERIOD;
- if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
+ if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs + sc->num_adhoc_vifs > 1) {
intval = ah->bintval & AR5K_BEACON_PERIOD;
- if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) {
+ if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + ah->num_adhoc_vifs > 1) {
intval /= ATH_BCBUF; /* staggered multi-bss beacons */
if (intval < 15)
ATH5K_WARN(sc, "intval %u is too low, min 15\n",
ATH5K_WARN(ah, "intval %u is too low, min 15\n",

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1035,6 +1035,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
@@ -1040,6 +1040,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
tsf_lo = 0;
mode = 0;
@ -8,7 +8,7 @@
/*
* Sanity check for fast flag
* Fast channel change only available
@@ -1042,6 +1043,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
@@ -1047,6 +1048,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
*/
if (fast && (ah->ah_radio != AR5K_RF2413) &&
(ah->ah_radio != AR5K_RF5413))

View file

@ -1,20 +0,0 @@
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1604,11 +1604,13 @@ int ath5k_hw_phy_calibrate(struct ath5k_
int ret;
if (ah->ah_radio == AR5K_RF5110)
- ret = ath5k_hw_rf5110_calibrate(ah, channel);
- else {
- ret = ath5k_hw_rf511x_iq_calibrate(ah);
+ return ath5k_hw_rf5110_calibrate(ah, channel);
+
+ ret = ath5k_hw_rf511x_iq_calibrate(ah);
+
+ if (ah->ah_radio == AR5K_RF5112 &&
+ (channel->hw_value & (CHANNEL_5GHZ | CHANNEL_OFDM)))
ath5k_hw_request_rfgain_probe(ah);
- }
return ret;
}

View file

@ -1,31 +0,0 @@
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -970,17 +970,20 @@ static int ath5k_hw_rfregs_init(struct a
}
/* Lower synth voltage on Rev 2 */
- ath5k_hw_rfb_op(ah, rf_regs, 2,
- AR5K_RF_HIGH_VC_CP, true);
+ if (ah->ah_radio == AR5K_RF5112 &&
+ (ah->ah_radio_5ghz_revision & AR5K_SREV_REV) > 0) {
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_HIGH_VC_CP, true);
- ath5k_hw_rfb_op(ah, rf_regs, 2,
- AR5K_RF_MID_VC_CP, true);
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_MID_VC_CP, true);
- ath5k_hw_rfb_op(ah, rf_regs, 2,
- AR5K_RF_LOW_VC_CP, true);
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_LOW_VC_CP, true);
- ath5k_hw_rfb_op(ah, rf_regs, 2,
- AR5K_RF_PUSH_UP, true);
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_PUSH_UP, true);
+ }
/* Decrease power consumption on 5213+ BaseBand */
if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {

View file

@ -1,10 +0,0 @@
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -105,6 +105,7 @@ bool ath5k_hw_chan_has_spur_noise(struct
if ((ah->ah_radio == AR5K_RF5112) ||
(ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_radio == AR5K_RF2413) ||
(ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
refclk_freq = 40;
else

View file

@ -1,10 +0,0 @@
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2422,6 +2422,7 @@ ath5k_init_softc(struct ath5k_softc *sc,
common->ah = sc->ah;
common->hw = hw;
common->priv = sc;
+ common->clockrate = 40;
/*
* Cache line size is used to size and align various

View file

@ -1,11 +0,0 @@
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2728,7 +2728,7 @@ ath5k_reset(struct ath5k_softc *sc, stru
ath5k_ani_init(ah, ani_mode);
- ah->ah_cal_next_full = jiffies;
+ ah->ah_cal_next_full = jiffies + msecs_to_jiffies(100);
ah->ah_cal_next_ani = jiffies;
ah->ah_cal_next_nf = jiffies;
ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);

View file

@ -1,27 +0,0 @@
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -233,7 +233,7 @@ static void ath5k_hw_init_core_clock(str
static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- u32 scal, spending;
+ u32 scal, spending, sclock;
/* Only set 32KHz settings if we have an external
* 32KHz crystal present */
@@ -317,6 +317,15 @@ static void ath5k_hw_set_sleep_clock(str
/* Set up tsf increment on each cycle */
AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_radio == AR5K_RF2316) ||
+ (ah->ah_radio == AR5K_RF2317))
+ sclock = 40 - 1;
+ else
+ sclock = 32 - 1;
+ AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, sclock);
}
}

View file

@ -1,18 +0,0 @@
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1287,15 +1287,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah,
*/
ath5k_hw_dma_init(ah);
-
- /* Enable 32KHz clock function for AR5212+ chips
- * Set clocks to 32KHz operation and use an
- * external 32KHz crystal when sleeping if one
- * exists */
- if (ah->ah_version == AR5K_AR5212 &&
- op_mode != NL80211_IFTYPE_AP)
- ath5k_hw_set_sleep_clock(ah, true);
-
/*
* Disable beacons and reset the TSF
*/

View file

@ -1,23 +0,0 @@
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1555,7 +1555,8 @@ ath5k_tx_queue(struct ieee80211_hw *hw,
goto drop_packet;
}
- if (txq->txq_len >= txq->txq_max)
+ if (txq->txq_len >= txq->txq_max &&
+ txq->qnum <= AR5K_TX_QUEUE_ID_DATA_MAX)
ieee80211_stop_queue(hw, txq->qnum);
spin_lock_irqsave(&sc->txbuflock, flags);
@@ -1931,6 +1932,10 @@ ath5k_beacon_send(struct ath5k_softc *sc
skb = ieee80211_get_buffered_bc(sc->hw, vif);
while (skb) {
ath5k_tx_queue(sc->hw, skb, sc->cabq);
+
+ if (sc->cabq->txq_len >= sc->cabq->txq_max)
+ break;
+
skb = ieee80211_get_buffered_bc(sc->hw, vif);
}

View file

@ -1,7 +1,7 @@
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1181,6 +1181,53 @@ static const struct file_operations fops
.llseek = default_llseek,/* read accesses f_pos */
@@ -1219,6 +1219,53 @@ static const struct file_operations fops
.llseek = default_llseek,
};
+static ssize_t read_file_eeprom(struct file *file, char __user *user_buf,
@ -54,7 +54,7 @@
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
@@ -1231,6 +1278,9 @@ int ath9k_init_debug(struct ath_hw *ah)
@@ -1273,6 +1320,9 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1656,8 +1656,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
@@ -1664,8 +1664,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
REG_WRITE(ah, AR_OBS, 8);
if (ah->config.rx_intr_mitigation) {

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -363,7 +363,7 @@ struct ath_vif {
@@ -366,7 +366,7 @@ struct ath_vif {
* number of beacon intervals, the game's up.
*/
#define BSTUCK_THRESH 9
@ -11,7 +11,7 @@
#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -374,8 +374,8 @@ static void ath9k_hw_init_config(struct
@@ -382,8 +382,8 @@ static void ath9k_hw_init_config(struct
{
int i;

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -117,7 +117,7 @@ void ath_descdma_cleanup(struct ath_soft
@@ -123,7 +123,7 @@ void ath_descdma_cleanup(struct ath_soft
/* RX / TX */
/***********/

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -586,6 +586,7 @@ struct ath_softc {
@@ -588,6 +588,7 @@ struct ath_softc {
struct ieee80211_hw *hw;
struct device *dev;
@ -10,7 +10,7 @@
struct survey_info *cur_survey;
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1281,6 +1281,9 @@ int ath9k_init_debug(struct ath_hw *ah)
@@ -1323,6 +1323,9 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_eeprom);

View file

@ -1,99 +0,0 @@
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -63,6 +63,19 @@ static s16 ath9k_hw_get_default_nf(struc
return ath9k_hw_get_nf_limits(ah, chan)->nominal;
}
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+ s8 noise = ATH_DEFAULT_NOISE_FLOOR;
+
+ if (chan && chan->noisefloor) {
+ s8 delta = chan->noisefloor -
+ ath9k_hw_get_default_nf(ah, chan);
+ if (delta > 0)
+ noise += delta;
+ }
+ return noise;
+}
+EXPORT_SYMBOL(ath9k_hw_getchan_noise);
static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
struct ath9k_hw_cal_data *cal,
@@ -378,6 +391,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, s
if (!caldata) {
chan->noisefloor = nf;
+ ah->noise = ath9k_hw_getchan_noise(ah, chan);
return false;
}
@@ -385,6 +399,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, s
caldata->nfcal_pending = false;
ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
chan->noisefloor = h[0].privNF;
+ ah->noise = ath9k_hw_getchan_noise(ah, chan);
return true;
}
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1488,6 +1488,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
memset(caldata, 0, sizeof(*caldata));
ath9k_init_nfcal_hist_buffer(ah, chan);
}
+ ah->noise = ath9k_hw_getchan_noise(ah, chan);
if (bChannelChange &&
(ah->chip_fullsleep != true) &&
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -688,6 +688,7 @@ struct ath_hw {
enum nl80211_iftype opmode;
enum ath9k_power_mode power_mode;
+ s8 noise;
struct ath9k_hw_cal_data *caldata;
struct ath9k_pacal_info pacal_info;
struct ar5416Stats stats;
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -163,7 +163,7 @@ static void ath_update_survey_nf(struct
if (chan->noisefloor) {
survey->filled |= SURVEY_INFO_NOISE_DBM;
- survey->noise = chan->noisefloor;
+ survey->noise = ath9k_hw_getchan_noise(ah, chan);
}
}
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -994,6 +994,8 @@ static int ath9k_rx_skb_preprocess(struc
struct ieee80211_rx_status *rx_status,
bool *decrypt_error)
{
+ struct ath_hw *ah = common->ah;
+
memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
/*
@@ -1014,7 +1016,7 @@ static int ath9k_rx_skb_preprocess(struc
rx_status->band = hw->conf.channel->band;
rx_status->freq = hw->conf.channel->center_freq;
- rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
+ rx_status->signal = ah->noise + rx_stats->rs_rssi;
rx_status->antenna = rx_stats->rs_antenna;
rx_status->flag |= RX_FLAG_MACTIME_MPDU;
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -108,6 +108,7 @@ void ath9k_init_nfcal_hist_buffer(struct
void ath9k_hw_bstuck_nfcal(struct ath_hw *ah);
void ath9k_hw_reset_calibration(struct ath_hw *ah,
struct ath9k_cal_list *currCal);
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
#endif /* CALIB_H */

View file

@ -1,6 +1,6 @@
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -779,7 +779,7 @@ enum ieee80211_smps_mode {
@@ -790,7 +790,7 @@ enum ieee80211_smps_mode {
*/
struct ieee80211_conf {
u32 flags;
@ -11,7 +11,7 @@
u16 listen_interval;
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1524,7 +1524,7 @@ static int ieee80211_get_tx_power(struct
@@ -1532,7 +1532,7 @@ static int ieee80211_get_tx_power(struct
{
struct ieee80211_local *local = wiphy_priv(wiphy);

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1727,6 +1727,8 @@ static int ath9k_config(struct ieee80211
@@ -1731,6 +1731,8 @@ static int ath9k_config(struct ieee80211
return -EINVAL;
}
@ -9,7 +9,7 @@
/*
* The most recent snapshot of channel->noisefloor for the old
* channel is only available after the hardware reset. Copy it to
@@ -1744,6 +1746,7 @@ static int ath9k_config(struct ieee80211
@@ -1748,6 +1750,7 @@ static int ath9k_config(struct ieee80211
ath9k_cmn_update_txpow(ah, sc->curtxpow,
sc->config.txpowlimit, &sc->curtxpow);
ath9k_ps_restore(sc);

View file

@ -1,13 +0,0 @@
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -737,7 +737,9 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
if (!AR_SREV_9300_20_OR_LATER(ah)) {
mac_status = REG_READ(ah, AR_DMADBG_7) & 0x7f0;
- if (mac_status == 0x1c0 && mac_status == last_mac_status) {
+ if (mac_status == last_mac_status &&
+ (mac_status == 0x1c0 ||
+ (AR_SREV_9100(ah) && mac_status == 0x020))) {
*reset = true;
break;
}

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -247,13 +247,16 @@ static void ath_tid_drain(struct ath_sof
@@ -248,13 +248,16 @@ static void ath_tid_drain(struct ath_sof
}
static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
@ -19,7 +19,7 @@
return;
hdr = (struct ieee80211_hdr *)skb->data;
@@ -358,6 +361,7 @@ static void ath_tx_complete_aggr(struct
@@ -359,6 +362,7 @@ static void ath_tx_complete_aggr(struct
int nframes;
u8 tidno;
bool clear_filter;
@ -27,7 +27,7 @@
skb = bf->bf_mpdu;
hdr = (struct ieee80211_hdr *)skb->data;
@@ -366,6 +370,10 @@ static void ath_tx_complete_aggr(struct
@@ -367,6 +371,10 @@ static void ath_tx_complete_aggr(struct
memcpy(rates, tx_info->control.rates, sizeof(rates));
@ -38,7 +38,7 @@
rcu_read_lock();
sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
@@ -449,7 +457,8 @@ static void ath_tx_complete_aggr(struct
@@ -451,7 +459,8 @@ static void ath_tx_complete_aggr(struct
} else if (fi->retries < ATH_MAX_SW_RETRIES) {
if (!(ts->ts_status & ATH9K_TXERR_FILT) ||
!an->sleeping)
@ -50,7 +50,7 @@
txpending = 1;
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -535,7 +535,7 @@ struct ath_ant_comb {
@@ -538,7 +538,7 @@ struct ath_ant_comb {
#define DEFAULT_CACHELINE 32
#define ATH_REGCLASSIDS_MAX 10
#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -200,6 +200,7 @@ struct ath_atx_ac {
@@ -206,6 +206,7 @@ struct ath_atx_ac {
};
struct ath_frame_info {
@ -8,7 +8,7 @@
int framelen;
u32 keyix;
enum ath9k_key_type keytype;
@@ -230,7 +231,7 @@ struct ath_buf {
@@ -235,7 +236,7 @@ struct ath_buf {
struct ath_atx_tid {
struct list_head list;
@ -30,7 +30,7 @@
goto done;
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -128,7 +128,7 @@ static void ath_tx_resume_tid(struct ath
@@ -129,7 +129,7 @@ static void ath_tx_resume_tid(struct ath
spin_lock_bh(&txq->axq_lock);
tid->paused = false;
@ -39,7 +39,7 @@
goto unlock;
ath_tx_queue_tid(txq, tid);
@@ -148,6 +148,7 @@ static struct ath_frame_info *get_frame_
@@ -149,6 +149,7 @@ static struct ath_frame_info *get_frame_
static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
struct ath_txq *txq = tid->ac->txq;
@ -47,7 +47,7 @@
struct ath_buf *bf;
struct list_head bf_head;
struct ath_tx_status ts;
@@ -158,12 +159,13 @@ static void ath_tx_flush_tid(struct ath_
@@ -159,12 +160,13 @@ static void ath_tx_flush_tid(struct ath_
memset(&ts, 0, sizeof(ts));
spin_lock_bh(&txq->axq_lock);
@ -64,8 +64,8 @@
- fi = get_frame_info(bf->bf_mpdu);
if (fi->retries) {
ath_tx_update_baw(sc, tid, fi->seqno);
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
@@ -218,6 +220,7 @@ static void ath_tid_drain(struct ath_sof
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1);
@@ -219,6 +221,7 @@ static void ath_tid_drain(struct ath_sof
struct ath_atx_tid *tid)
{
@ -73,7 +73,7 @@
struct ath_buf *bf;
struct list_head bf_head;
struct ath_tx_status ts;
@@ -226,14 +229,12 @@ static void ath_tid_drain(struct ath_sof
@@ -227,14 +230,12 @@ static void ath_tid_drain(struct ath_sof
memset(&ts, 0, sizeof(ts));
INIT_LIST_HEAD(&bf_head);
@ -92,7 +92,7 @@
if (fi->retries)
ath_tx_update_baw(sc, tid, fi->seqno);
@@ -351,7 +352,8 @@ static void ath_tx_complete_aggr(struct
@@ -352,7 +353,8 @@ static void ath_tx_complete_aggr(struct
struct ieee80211_tx_info *tx_info;
struct ath_atx_tid *tid = NULL;
struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
@ -102,7 +102,7 @@
u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
u32 ba[WME_BA_BMP_SIZE >> 5];
int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
@@ -428,8 +430,7 @@ static void ath_tx_complete_aggr(struct
@@ -430,8 +432,7 @@ static void ath_tx_complete_aggr(struct
}
}
@ -112,7 +112,7 @@
ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
while (bf) {
@@ -474,10 +475,10 @@ static void ath_tx_complete_aggr(struct
@@ -476,10 +477,10 @@ static void ath_tx_complete_aggr(struct
* Make sure the last desc is reclaimed if it
* not a holding desc.
*/
@ -126,7 +126,7 @@
if (!txpending || (tid->state & AGGR_CLEANUP)) {
/*
@@ -528,7 +529,7 @@ static void ath_tx_complete_aggr(struct
@@ -530,7 +531,7 @@ static void ath_tx_complete_aggr(struct
ath9k_hw_cleartxdesc(sc->sc_ah,
tbf->bf_desc);
@ -135,7 +135,7 @@
} else {
/*
* Clear descriptor status words for
@@ -543,21 +544,21 @@ static void ath_tx_complete_aggr(struct
@@ -545,21 +546,21 @@ static void ath_tx_complete_aggr(struct
* Put this buffer to the temporary pending
* queue to retain ordering
*/
@ -160,7 +160,7 @@
if (!an->sleeping)
ath_tx_queue_tid(txq, tid);
spin_unlock_bh(&txq->axq_lock);
@@ -722,19 +723,22 @@ static enum ATH_AGGR_STATUS ath_tx_form_
@@ -721,19 +722,22 @@ static enum ATH_AGGR_STATUS ath_tx_form_
int *aggr_len)
{
#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
@ -188,7 +188,7 @@
/* do not step over block-ack window */
if (!BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno)) {
@@ -785,7 +789,9 @@ static enum ATH_AGGR_STATUS ath_tx_form_
@@ -784,7 +788,9 @@ static enum ATH_AGGR_STATUS ath_tx_form_
if (!fi->retries)
ath_tx_addto_baw(sc, tid, fi->seqno);
ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
@ -199,7 +199,7 @@
if (bf_prev) {
bf_prev->bf_next = bf;
ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc,
@@ -793,7 +799,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
@@ -792,7 +798,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
}
bf_prev = bf;
@ -208,7 +208,7 @@
*aggr_len = al;
@@ -811,7 +817,7 @@ static void ath_tx_sched_aggr(struct ath
@@ -810,7 +816,7 @@ static void ath_tx_sched_aggr(struct ath
int aggr_len;
do {
@ -217,7 +217,7 @@
return;
INIT_LIST_HEAD(&bf_q);
@@ -933,7 +939,7 @@ bool ath_tx_aggr_sleep(struct ath_softc
@@ -931,7 +937,7 @@ bool ath_tx_aggr_sleep(struct ath_softc
spin_lock_bh(&txq->axq_lock);
@ -226,7 +226,7 @@
buffered = true;
tid->sched = false;
@@ -966,7 +972,7 @@ void ath_tx_aggr_wakeup(struct ath_softc
@@ -964,7 +970,7 @@ void ath_tx_aggr_wakeup(struct ath_softc
spin_lock_bh(&txq->axq_lock);
ac->clear_ps_filter = true;
@ -270,7 +270,7 @@
return bf;
}
@@ -2364,7 +2371,7 @@ void ath_tx_node_init(struct ath_softc *
@@ -2370,7 +2377,7 @@ void ath_tx_node_init(struct ath_softc *
tid->sched = false;
tid->paused = false;
tid->state &= ~AGGR_CLEANUP;

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -235,6 +235,7 @@ struct ath_atx_tid {
@@ -240,6 +240,7 @@ struct ath_atx_tid {
struct ath_node *an;
struct ath_atx_ac *ac;
unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
@ -8,7 +8,7 @@
u16 seq_start;
u16 seq_next;
u16 baw_size;
@@ -283,6 +284,9 @@ struct ath_tx_control {
@@ -286,6 +287,9 @@ struct ath_tx_control {
* (axq_qnum).
*/
struct ath_tx {
@ -20,7 +20,7 @@
spinlock_t txbuflock;
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1250,6 +1250,10 @@ int ath9k_init_debug(struct ath_hw *ah)
@@ -1288,6 +1288,10 @@ int ath9k_init_debug(struct ath_hw *ah)
sc, &fops_wiphy);
debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_xmit);
@ -33,7 +33,7 @@
debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -339,6 +339,14 @@ static void ath_tx_count_frames(struct a
@@ -340,6 +340,14 @@ static void ath_tx_count_frames(struct a
}
}
@ -48,16 +48,16 @@
static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf, struct list_head *bf_q,
@@ -433,6 +441,8 @@ static void ath_tx_complete_aggr(struct
@@ -435,6 +443,8 @@ static void ath_tx_complete_aggr(struct
__skb_queue_head_init(&bf_pending);
ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
+ tid->buf_pending -= nframes;
+
while (bf) {
txfail = txpending = 0;
txfail = txpending = sendbar = 0;
bf_next = bf->bf_next;
@@ -790,6 +800,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
@@ -789,6 +799,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
ath_tx_addto_baw(sc, tid, fi->seqno);
ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
@ -124,7 +124,7 @@
if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
/*
@@ -1824,6 +1824,7 @@ int ath_tx_start(struct ieee80211_hw *hw
@@ -1823,6 +1823,7 @@ int ath_tx_start(struct ieee80211_hw *hw
struct ieee80211_vif *vif = info->control.vif;
struct ath_softc *sc = hw->priv;
struct ath_txq *txq = txctl->txq;
@ -132,7 +132,7 @@
struct ath_buf *bf;
int padpos, padsize;
int frmlen = skb->len + FCS_LEN;
@@ -1857,6 +1858,7 @@ int ath_tx_start(struct ieee80211_hw *hw
@@ -1856,6 +1857,7 @@ int ath_tx_start(struct ieee80211_hw *hw
skb_push(skb, padsize);
memmove(skb->data, skb->data + padsize, padpos);
@ -140,7 +140,7 @@
}
if ((vif && vif->type != NL80211_IFTYPE_AP &&
@@ -1866,6 +1868,24 @@ int ath_tx_start(struct ieee80211_hw *hw
@@ -1865,6 +1867,24 @@ int ath_tx_start(struct ieee80211_hw *hw
setup_frame_info(hw, skb, frmlen);
@ -165,7 +165,7 @@
/*
* At this point, the vif, hw_key and sta pointers in the tx control
* info are no longer valid (overwritten by the ath_frame_info data.
@@ -1884,7 +1904,7 @@ int ath_tx_start(struct ieee80211_hw *hw
@@ -1883,7 +1903,7 @@ int ath_tx_start(struct ieee80211_hw *hw
}
spin_unlock_bh(&txq->axq_lock);

View file

@ -1,13 +0,0 @@
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -667,8 +667,10 @@ static void ath9k_init_band_txpower(stru
static void ath9k_init_txpower_limits(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath9k_channel *curchan = ah->curchan;
+ ah->txchainmask = common->tx_chainmask;
if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)

View file

@ -1,125 +0,0 @@
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -247,8 +247,7 @@ static u32 ath9k_hw_4k_get_eeprom(struct
}
static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
- struct ath9k_channel *chan,
- int16_t *pTxPowerIndexOffset)
+ struct ath9k_channel *chan)
{
struct ath_common *common = ath9k_hw_common(ah);
struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
@@ -358,8 +357,6 @@ static void ath9k_hw_set_4k_power_cal_ta
REGWRITE_BUFFER_FLUSH(ah);
}
}
-
- *pTxPowerIndexOffset = 0;
}
static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
@@ -582,7 +579,6 @@ static void ath9k_hw_4k_set_txpower(stru
struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
int16_t ratesArray[Ar5416RateSize];
- int16_t txPowerIndexOffset = 0;
u8 ht40PowerIncForPdadc = 2;
int i;
@@ -599,11 +595,10 @@ static void ath9k_hw_4k_set_txpower(stru
twiceMaxRegulatoryPower,
powerLimit);
- ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
+ ath9k_hw_set_4k_power_cal_table(ah, chan);
regulatory->max_power_level = 0;
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
- ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
if (ratesArray[i] > MAX_RATE_POWER)
ratesArray[i] = MAX_RATE_POWER;
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -306,8 +306,7 @@ static void ar9287_eeprom_olpc_set_pdadc
}
static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
- struct ath9k_channel *chan,
- int16_t *pTxPowerIndexOffset)
+ struct ath9k_channel *chan)
{
struct cal_data_per_freq_ar9287 *pRawDataset;
struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
@@ -446,8 +445,6 @@ static void ath9k_hw_set_ar9287_power_ca
REGWRITE_BUFFER_FLUSH(ah);
}
}
-
- *pTxPowerIndexOffset = 0;
}
static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
@@ -722,7 +719,6 @@ static void ath9k_hw_ar9287_set_txpower(
struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
int16_t ratesArray[Ar5416RateSize];
- int16_t txPowerIndexOffset = 0;
u8 ht40PowerIncForPdadc = 2;
int i;
@@ -738,11 +734,10 @@ static void ath9k_hw_ar9287_set_txpower(
twiceMaxRegulatoryPower,
powerLimit);
- ath9k_hw_set_ar9287_power_cal_table(ah, chan, &txPowerIndexOffset);
+ ath9k_hw_set_ar9287_power_cal_table(ah, chan);
regulatory->max_power_level = 0;
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
- ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
if (ratesArray[i] > MAX_RATE_POWER)
ratesArray[i] = MAX_RATE_POWER;
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -692,8 +692,7 @@ static void ath9k_adjust_pdadc_values(st
}
static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
- struct ath9k_channel *chan,
- int16_t *pTxPowerIndexOffset)
+ struct ath9k_channel *chan)
{
#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
#define SM_PDGAIN_B(x, y) \
@@ -857,7 +856,6 @@ static void ath9k_hw_set_def_power_cal_t
}
}
- *pTxPowerIndexOffset = 0;
#undef SM_PD_GAIN
#undef SM_PDGAIN_B
}
@@ -1145,7 +1143,6 @@ static void ath9k_hw_def_set_txpower(str
struct modal_eep_header *pModal =
&(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
int16_t ratesArray[Ar5416RateSize];
- int16_t txPowerIndexOffset = 0;
u8 ht40PowerIncForPdadc = 2;
int i, cck_ofdm_delta = 0;
@@ -1162,11 +1159,10 @@ static void ath9k_hw_def_set_txpower(str
twiceMaxRegulatoryPower,
powerLimit);
- ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
+ ath9k_hw_set_def_power_cal_table(ah, chan);
regulatory->max_power_level = 0;
for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
- ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
if (ratesArray[i] > MAX_RATE_POWER)
ratesArray[i] = MAX_RATE_POWER;
if (ratesArray[i] > regulatory->max_power_level)

View file

@ -1,83 +0,0 @@
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -4922,25 +4922,7 @@ static void ath9k_hw_ar9300_set_txpower(
"TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
}
- /*
- * This is the TX power we send back to driver core,
- * and it can use to pass to userspace to display our
- * currently configured TX power setting.
- *
- * Since power is rate dependent, use one of the indices
- * from the AR9300_Rates enum to select an entry from
- * targetPowerValT2[] to report. Currently returns the
- * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
- * as CCK power is less interesting (?).
- */
- i = ALL_TARGET_LEGACY_6_24; /* legacy */
- if (IS_CHAN_HT40(chan))
- i = ALL_TARGET_HT40_0_8_16; /* ht40 */
- else if (IS_CHAN_HT20(chan))
- i = ALL_TARGET_HT20_0_8_16; /* ht20 */
-
- ah->txpower_limit = targetPowerValT2[i];
- regulatory->max_power_level = targetPowerValT2[i];
+ ah->txpower_limit = regulatory->max_power_level;
/* Write target power array to registers */
ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -609,15 +609,6 @@ static void ath9k_hw_4k_set_txpower(stru
if (test)
return;
- /* Update regulatory */
- i = rate6mb;
- if (IS_CHAN_HT40(chan))
- i = rateHt40_0;
- else if (IS_CHAN_HT20(chan))
- i = rateHt20_0;
-
- regulatory->max_power_level = ratesArray[i];
-
if (AR_SREV_9280_20_OR_LATER(ah)) {
for (i = 0; i < Ar5416RateSize; i++)
ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -748,13 +748,6 @@ static void ath9k_hw_ar9287_set_txpower(
if (test)
return;
- if (IS_CHAN_2GHZ(chan))
- i = rate1l;
- else
- i = rate6mb;
-
- regulatory->max_power_level = ratesArray[i];
-
if (AR_SREV_9280_20_OR_LATER(ah)) {
for (i = 0; i < Ar5416RateSize; i++)
ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -1169,17 +1169,6 @@ static void ath9k_hw_def_set_txpower(str
regulatory->max_power_level = ratesArray[i];
}
- if (!test) {
- i = rate6mb;
-
- if (IS_CHAN_HT40(chan))
- i = rateHt40_0;
- else if (IS_CHAN_HT20(chan))
- i = rateHt20_0;
-
- regulatory->max_power_level = ratesArray[i];
- }
-
switch(ar5416_get_ntxchains(ah->txchainmask)) {
case 1:
break;

View file

@ -1,24 +0,0 @@
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2442,15 +2442,18 @@ void ath9k_hw_set_txpowerlimit(struct at
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ath9k_channel *chan = ah->curchan;
struct ieee80211_channel *channel = chan->chan;
+ int reg_pwr = min_t(int, MAX_RATE_POWER, regulatory->power_limit);
+ int chan_pwr = channel->max_power * 2;
+
+ if (test)
+ reg_pwr = chan_pwr = MAX_RATE_POWER;
regulatory->power_limit = min(limit, (u32) MAX_RATE_POWER);
ah->eep_ops->set_txpower(ah, chan,
ath9k_regd_get_ctl(regulatory, chan),
channel->max_antenna_gain * 2,
- channel->max_power * 2,
- min((u32) MAX_RATE_POWER,
- (u32) regulatory->power_limit), test);
+ chan_pwr, reg_pwr, test);
}
EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);

View file

@ -1,22 +0,0 @@
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -550,7 +550,8 @@ static void ath_tx_complete_aggr(struct
if (clear_filter)
tid->ac->clear_ps_filter = true;
list_splice(&bf_pending, &tid->buf_q);
- ath_tx_queue_tid(txq, tid);
+ if (!an->sleeping)
+ ath_tx_queue_tid(txq, tid);
spin_unlock_bh(&txq->axq_lock);
}
@@ -1410,7 +1411,8 @@ static void ath_tx_send_ampdu(struct ath
*/
TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
list_add_tail(&bf->list, &tid->buf_q);
- ath_tx_queue_tid(txctl->txq, tid);
+ if (!txctl->an || !txctl->an->sleeping)
+ ath_tx_queue_tid(txctl->txq, tid);
return;
}

View file

@ -1,64 +0,0 @@
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -109,8 +109,9 @@ static void ieee80211_send_addba_request
ieee80211_tx_skb(sdata, skb);
}
-void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
+void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
{
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct ieee80211_bar *bar;
@@ -138,6 +139,7 @@ void ieee80211_send_bar(struct ieee80211
IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
ieee80211_tx_skb(sdata, skb);
}
+EXPORT_SYMBOL(ieee80211_send_bar);
void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
struct tid_ampdu_tx *tid_tx)
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3007,6 +3007,19 @@ void ieee80211_remain_on_channel_expired
void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
const u8 *addr);
+/**
+ * ieee80211_send_bar - send a BlockAckReq frame
+ *
+ * can be used to flush pending frames from the peer's aggregation reorder
+ * buffer.
+ *
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ * @ra: the peer's destination address
+ * @tid: the TID of the aggregation session
+ * @ssn: the new starting sequence number for the receiver
+ */
+void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn);
+
/* Rate control API */
/**
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1225,7 +1225,6 @@ struct ieee80211_tx_status_rtap_hdr {
void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
struct ieee80211_ht_cap *ht_cap_ie,
struct ieee80211_sta_ht_cap *ht_cap);
-void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
const u8 *da, u16 tid,
u16 initiator, u16 reason_code);
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -239,7 +239,7 @@ void ieee80211_tx_status(struct ieee8021
tid = qc[0] & 0xf;
ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10)
& IEEE80211_SCTL_SEQ);
- ieee80211_send_bar(sta->sdata, hdr->addr1,
+ ieee80211_send_bar(&sta->sdata->vif, hdr->addr1,
tid, ssn);
}

View file

@ -1,157 +0,0 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -246,6 +246,7 @@ struct ath_atx_tid {
};
struct ath_node {
+ struct ieee80211_vif *vif;
#ifdef CONFIG_ATH9K_DEBUGFS
struct list_head list; /* for sc->nodes */
struct ieee80211_sta *sta; /* station struct we're part of */
@@ -274,7 +275,6 @@ struct ath_tx_control {
#define ATH_TX_ERROR 0x01
#define ATH_TX_XRETRY 0x02
-#define ATH_TX_BAR 0x04
/**
* @txq_map: Index is mac80211 queue number. This is
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1801,6 +1801,7 @@ static int ath9k_sta_add(struct ieee8021
struct ieee80211_key_conf ps_key = { };
ath_node_attach(sc, sta);
+ an->vif = vif;
if (vif->type != NL80211_IFTYPE_AP &&
vif->type != NL80211_IFTYPE_AP_VLAN)
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -51,7 +51,7 @@ static void ath_tx_send_normal(struct at
struct list_head *bf_head);
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
struct ath_txq *txq, struct list_head *bf_q,
- struct ath_tx_status *ts, int txok, int sendbar);
+ struct ath_tx_status *ts, int txok);
static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
struct list_head *head, bool internal);
static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len);
@@ -166,7 +166,7 @@ static void ath_tx_flush_tid(struct ath_
fi = get_frame_info(bf->bf_mpdu);
if (fi->retries) {
ath_tx_update_baw(sc, tid, fi->seqno);
- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1);
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
} else {
ath_tx_send_normal(sc, txq, NULL, &bf_head);
}
@@ -238,7 +238,7 @@ static void ath_tid_drain(struct ath_sof
ath_tx_update_baw(sc, tid, fi->seqno);
spin_unlock(&txq->axq_lock);
- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
spin_lock(&txq->axq_lock);
}
@@ -381,8 +381,7 @@ static void ath_tx_complete_aggr(struct
list_move_tail(&bf->list, &bf_head);
ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false);
- ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
- 0, 0);
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0);
bf = bf_next;
}
@@ -426,7 +425,7 @@ static void ath_tx_complete_aggr(struct
ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad);
while (bf) {
- txfail = txpending = sendbar = 0;
+ txfail = txpending = 0;
bf_next = bf->bf_next;
skb = bf->bf_mpdu;
@@ -489,7 +488,7 @@ static void ath_tx_complete_aggr(struct
}
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
- !txfail, sendbar);
+ !txfail);
} else {
/* retry the un-acked ones */
ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false);
@@ -514,7 +513,7 @@ static void ath_tx_complete_aggr(struct
nbad, 0, false);
ath_tx_complete_buf(sc, bf, txq,
&bf_head,
- ts, 0, 0);
+ ts, 0);
break;
}
@@ -564,6 +563,9 @@ static void ath_tx_complete_aggr(struct
}
}
+ if (sendbar || (tid->state & AGGR_CLEANUP))
+ ieee80211_send_bar(an->vif, sta->addr, tidno, tid->seq_start << 4);
+
rcu_read_unlock();
if (needreset)
@@ -900,6 +902,7 @@ void ath_tx_aggr_stop(struct ath_softc *
spin_unlock_bh(&txq->axq_lock);
ath_tx_flush_tid(sc, txtid);
+ ieee80211_send_bar(an->vif, sta->addr, tid, txtid->seq_start << 4);
}
bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an)
@@ -1178,7 +1181,7 @@ static void ath_drain_txq_list(struct at
ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0,
retry_tx);
else
- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
+ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
spin_lock_bh(&txq->axq_lock);
}
}
@@ -1885,9 +1888,6 @@ static void ath_tx_complete(struct ath_s
ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
- if (tx_flags & ATH_TX_BAR)
- tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
-
if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
/* Frame was ACKed */
tx_info->flags |= IEEE80211_TX_STAT_ACK;
@@ -1932,15 +1932,12 @@ static void ath_tx_complete(struct ath_s
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
struct ath_txq *txq, struct list_head *bf_q,
- struct ath_tx_status *ts, int txok, int sendbar)
+ struct ath_tx_status *ts, int txok)
{
struct sk_buff *skb = bf->bf_mpdu;
unsigned long flags;
int tx_flags = 0;
- if (sendbar)
- tx_flags = ATH_TX_BAR;
-
if (!txok) {
tx_flags |= ATH_TX_ERROR;
@@ -2056,7 +2053,7 @@ static void ath_tx_process_buffer(struct
if (ts->ts_status & ATH9K_TXERR_XRETRY)
bf->bf_state.bf_type |= BUF_XRETRY;
ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok, true);
- ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0);
+ ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok);
} else
ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true);

View file

@ -22,7 +22,7 @@
+#endif /* _RT2X00_PLATFORM_H */
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -38,6 +38,7 @@
@@ -39,6 +39,7 @@
#include <linux/input-polldev.h>
#include <linux/kfifo.h>
#include <linux/timer.h>

View file

@ -101,7 +101,7 @@
+}
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -538,6 +538,7 @@ struct rt2x00lib_ops {
@@ -539,6 +539,7 @@ struct rt2x00lib_ops {
const u8 *data, const size_t len);
int (*load_firmware) (struct rt2x00_dev *rt2x00dev,
const u8 *data, const size_t len);
@ -109,7 +109,7 @@
/*
* Device initialization/deinitialization handlers.
@@ -684,6 +685,7 @@ enum rt2x00_capability_flags {
@@ -685,6 +686,7 @@ enum rt2x00_capability_flags {
REQUIRE_SW_SEQNO,
REQUIRE_HT_TX_DESC,
REQUIRE_PS_AUTOWAKE,
@ -117,7 +117,7 @@
/*
* Capabilities
@@ -939,6 +941,11 @@ struct rt2x00_dev {
@@ -940,6 +942,11 @@ struct rt2x00_dev {
const struct firmware *fw;
/*
@ -208,7 +208,7 @@
#ifdef CONFIG_PCI
static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
@@ -315,6 +305,20 @@ static int rt2800pci_write_firmware(stru
@@ -311,6 +301,20 @@ static int rt2800pci_write_firmware(stru
}
/*
@ -229,7 +229,7 @@
* Initialization functions.
*/
static bool rt2800pci_get_entry_state(struct queue_entry *entry)
@@ -1057,6 +1061,7 @@ static const struct rt2x00lib_ops rt2800
@@ -1050,6 +1054,7 @@ static const struct rt2x00lib_ops rt2800
.get_firmware_name = rt2800pci_get_firmware_name,
.check_firmware = rt2800_check_firmware,
.load_firmware = rt2800_load_firmware,
@ -239,7 +239,7 @@
.get_entry_state = rt2800pci_get_entry_state,
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1122,6 +1122,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
@@ -1121,6 +1121,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
@ -250,7 +250,7 @@
/*
* Let the driver probe the device to detect the capabilities.
*/
@@ -1223,6 +1227,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
@@ -1222,6 +1226,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
* Free queue structures.
*/
rt2x00queue_free(rt2x00dev);

View file

@ -1,6 +1,6 @@
--- a/config.mk
+++ b/config.mk
@@ -578,6 +578,7 @@ CONFIG_RT2X00=y
@@ -581,6 +581,7 @@ CONFIG_RT2X00=y
CONFIG_RT2X00_LIB=m
CONFIG_RT2800_LIB=m
CONFIG_RT2X00_LIB_FIRMWARE=y

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -5194,6 +5194,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
@@ -5195,6 +5195,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -740,6 +740,7 @@ struct b43_wldev {
@@ -746,6 +746,7 @@ struct b43_wldev {
bool qos_enabled; /* TRUE, if QoS is used. */
bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */
bool use_pio; /* TRUE if next init should use PIO */
@ -10,7 +10,7 @@
struct b43_phy phy;
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -76,6 +76,11 @@ MODULE_FIRMWARE("b43/ucode16_mimo.fw");
@@ -75,6 +75,11 @@ MODULE_FIRMWARE("b43/ucode16_mimo.fw");
MODULE_FIRMWARE("b43/ucode5.fw");
MODULE_FIRMWARE("b43/ucode9.fw");
@ -22,7 +22,7 @@
static int modparam_bad_frames_preempt;
module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
MODULE_PARM_DESC(bad_frames_preempt,
@@ -2575,10 +2580,10 @@ static int b43_gpio_init(struct b43_wlde
@@ -2671,10 +2676,10 @@ static int b43_gpio_init(struct b43_wlde
& ~B43_MACCTL_GPOUTSMSK);
b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK)
@ -35,7 +35,7 @@
if (dev->dev->chip_id == 0x4301) {
mask |= 0x0060;
set |= 0x0060;
@@ -5137,10 +5142,10 @@ static void b43_print_driverinfo(void)
@@ -5441,10 +5446,10 @@ static void b43_print_driverinfo(void)
feat_sdio = "S";
#endif
printk(KERN_INFO "Broadcom 43xx driver loaded "

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -17,7 +17,7 @@ b43-y += xmit.o
@@ -19,7 +19,7 @@ b43-y += xmit.o
b43-y += lo.o
b43-y += wa.o
b43-y += dma.o
@ -11,7 +11,7 @@
b43-$(CONFIG_B43_PCMCIA) += pcmcia.o
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1834,9 +1834,11 @@ static void b43_do_interrupt_thread(stru
@@ -1884,9 +1884,11 @@ static void b43_do_interrupt_thread(stru
dma_reason[4], dma_reason[5]);
b43err(dev->wl, "This device does not support DMA "
"on your system. It will now be switched to PIO.\n");

File diff suppressed because it is too large Load diff

View file

@ -1,40 +0,0 @@
From f706821596d8a3dcda314c38b13d91f108fdc435 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Fri, 22 Jul 2011 17:10:29 +0200
Subject: [PATCH 21/22] b43: read correct register on bcma bus.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/net/wireless/b43/dma.c | 20 +++++++++++++++++---
1 files changed, 17 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -795,9 +795,23 @@ static u64 supported_dma_mask(struct b43
u32 tmp;
u16 mmio_base;
- tmp = b43_read32(dev, SSB_TMSHIGH);
- if (tmp & SSB_TMSHIGH_DMA64)
- return DMA_BIT_MASK(64);
+ switch (dev->dev->bus_type) {
+#ifdef CONFIG_B43_BCMA
+ case B43_BUS_BCMA:
+ tmp = bcma_aread32(dev->dev->bdev, BCMA_IOST);
+ if (tmp & BCMA_IOST_DMA64)
+ return DMA_BIT_MASK(64);
+ break;
+#endif
+#ifdef CONFIG_B43_SSB
+ case B43_BUS_SSB:
+ tmp = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
+ if (tmp & SSB_TMSHIGH_DMA64)
+ return DMA_BIT_MASK(64);
+ break;
+#endif
+ }
+
mmio_base = b43_dmacontroller_base(0, 0);
b43_write32(dev, mmio_base + B43_DMA32_TXCTL, B43_DMA32_TXADDREXT_MASK);
tmp = b43_read32(dev, mmio_base + B43_DMA32_TXCTL);

View file

@ -1,26 +0,0 @@
Fixes bug described in:
https://bugzilla.kernel.org/show_bug.cgi?id=39172
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
John: this is trivial and fixes quite ugly memory (linked list exactly)
corruption. I believe this fix should be taken for 3.1.
---
drivers/net/wireless/b43/bus.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
--- a/drivers/net/wireless/b43/bus.c
+++ b/drivers/net/wireless/b43/bus.c
@@ -244,10 +244,12 @@ void b43_bus_set_wldev(struct b43_bus_de
#ifdef CONFIG_B43_BCMA
case B43_BUS_BCMA:
bcma_set_drvdata(dev->bdev, wldev);
+ break;
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
ssb_set_drvdata(dev->sdev, wldev);
+ break;
#endif
}
}

View file

@ -1,21 +0,0 @@
From 46c79b0cdc60a974da409d641a69086694046ea0 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Fri, 22 Jul 2011 17:47:46 +0200
Subject: [PATCH 23/23] b43: add core rev 17 used on bcma SoC
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/net/wireless/b43/main.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -120,6 +120,7 @@ MODULE_PARM_DESC(pio, "Use PIO accesses
#ifdef CONFIG_B43_BCMA
static const struct bcma_device_id b43_bcma_tbl[] = {
+ BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),

View file

@ -1,101 +0,0 @@
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -326,6 +326,10 @@ static void b43_wireless_core_exit(struc
static int b43_wireless_core_init(struct b43_wldev *dev);
static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
static int b43_wireless_core_start(struct b43_wldev *dev);
+static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf,
+ u32 changed);
static int b43_ratelimit(struct b43_wl *wl)
{
@@ -3762,14 +3766,24 @@ static int b43_op_config(struct ieee8021
struct ieee80211_conf *conf = &hw->conf;
int antenna;
int err = 0;
+ bool reload_bss = false;
mutex_lock(&wl->mutex);
+ dev = wl->current_dev;
+
/* Switch the band (if necessary). This might change the active core. */
err = b43_switch_band(wl, conf->channel);
if (err)
goto out_unlock_mutex;
- dev = wl->current_dev;
+
+ /* Need to reload all settings if the core changed */
+ if (dev != wl->current_dev) {
+ dev = wl->current_dev;
+ changed = ~0;
+ reload_bss = true;
+ }
+
phy = &dev->phy;
if (conf_is_ht(conf))
@@ -3830,6 +3844,9 @@ out_mac_enable:
out_unlock_mutex:
mutex_unlock(&wl->mutex);
+ if (wl->vif && reload_bss)
+ b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
+
return err;
}
@@ -3918,7 +3935,8 @@ static void b43_op_bss_info_changed(stru
if (changed & BSS_CHANGED_BEACON_INT &&
(b43_is_mode(wl, NL80211_IFTYPE_AP) ||
b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
- b43_is_mode(wl, NL80211_IFTYPE_ADHOC)))
+ b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) &&
+ conf->beacon_int)
b43_set_beacon_int(dev, conf->beacon_int);
if (changed & BSS_CHANGED_BASIC_RATES)
@@ -4699,6 +4717,9 @@ static int b43_op_add_interface(struct i
out_mutex_unlock:
mutex_unlock(&wl->mutex);
+ if (err == 0)
+ b43_op_bss_info_changed(hw, vif, &vif->bss_conf, ~0);
+
return err;
}
@@ -4769,6 +4790,9 @@ static int b43_op_start(struct ieee80211
out_mutex_unlock:
mutex_unlock(&wl->mutex);
+ /* reload configuration */
+ b43_op_config(hw, ~0);
+
return err;
}
@@ -4925,10 +4949,18 @@ out:
if (err)
wl->current_dev = NULL; /* Failed to init the dev. */
mutex_unlock(&wl->mutex);
- if (err)
+
+ if (err) {
b43err(wl, "Controller restart FAILED\n");
- else
- b43info(wl, "Controller restarted\n");
+ return;
+ }
+
+ /* reload configuration */
+ b43_op_config(wl->hw, ~0);
+ if (wl->vif)
+ b43_op_bss_info_changed(wl->hw, wl->vif, &wl->vif->bss_conf, ~0);
+
+ b43info(wl, "Controller restarted\n");
}
static int b43_setup_bands(struct b43_wldev *dev,