mac80211: update to wireless-testing 2011-11-15

SVN-Revision: 29240
This commit is contained in:
Felix Fietkau 2011-11-18 11:27:19 +00:00
parent ae90aa4efd
commit 0838e883f2
31 changed files with 544 additions and 708 deletions

View file

@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=mac80211
PKG_VERSION:=2011-11-04
PKG_VERSION:=2011-11-15
PKG_RELEASE:=1
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
PKG_MD5SUM:=baed52c81864c72887a6d3a88447e0d0
PKG_MD5SUM:=0bb667c7fecbc244840d806df0604661
PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)

View file

@ -59,7 +59,7 @@
static int __init compat_init(void)
{
/* pm-qos for kernels <= 2.6.24, this is a no-op on newer kernels */
@@ -45,15 +56,15 @@ static int __init compat_init(void)
@@ -46,7 +57,8 @@ static int __init compat_init(void)
COMPAT_BASE_TREE " " COMPAT_BASE_TREE_VERSION
"\n");
@ -69,12 +69,13 @@
}
module_init(compat_init);
static void __exit compat_exit(void)
{
@@ -55,7 +67,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);

View file

@ -51,7 +51,7 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
@@ -65,9 +65,9 @@ static inline struct sk_buff *netdev_all
@@ -68,9 +68,9 @@ static inline struct sk_buff *netdev_all
return skb;
}

View file

@ -147,7 +147,7 @@
+#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/moduleparam.h>
#include <linux/module.h>
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -1,3 +1,4 @@

View file

@ -1,6 +1,6 @@
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -844,7 +844,6 @@ static void table_flush_by_iface(struct
@@ -841,7 +841,6 @@ static void table_flush_by_iface(struct
struct hlist_node *p;
int i;

View file

@ -1,6 +1,363 @@
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -118,7 +118,7 @@ void ath9k_ps_restore(struct ath_softc *
if (--sc->ps_usecount != 0)
goto unlock;
- if (sc->ps_idle)
+ if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK))
mode = ATH9K_PM_FULL_SLEEP;
else if (sc->ps_enabled &&
!(sc->ps_flags & (PS_WAIT_FOR_BEACON |
@@ -332,7 +332,8 @@ static int ath_reset_internal(struct ath
hchan = ah->curchan;
}
- if (fastcc && !ath9k_hw_check_alive(ah))
+ if (fastcc && (ah->chip_fullsleep ||
+ !ath9k_hw_check_alive(ah)))
fastcc = false;
if (!ath_prepare_reset(sc, retry_tx, flush))
@@ -882,82 +883,6 @@ chip_reset:
#undef SCHED_INTR
}
-static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
-{
- struct ath_hw *ah = sc->sc_ah;
- struct ath_common *common = ath9k_hw_common(ah);
- struct ieee80211_channel *channel = hw->conf.channel;
- int r;
-
- ath9k_ps_wakeup(sc);
- spin_lock_bh(&sc->sc_pcu_lock);
- atomic_set(&ah->intr_ref_cnt, -1);
-
- ath9k_hw_configpcipowersave(ah, false);
-
- if (!ah->curchan)
- ah->curchan = ath9k_cmn_get_curchannel(sc->hw, ah);
-
- r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
- if (r) {
- ath_err(common,
- "Unable to reset channel (%u MHz), reset status %d\n",
- channel->center_freq, r);
- }
-
- ath_complete_reset(sc, true);
-
- /* Enable LED */
- ath9k_hw_cfg_output(ah, ah->led_pin,
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- ath9k_hw_set_gpio(ah, ah->led_pin, 0);
-
- spin_unlock_bh(&sc->sc_pcu_lock);
-
- ath9k_ps_restore(sc);
-}
-
-void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
-{
- struct ath_hw *ah = sc->sc_ah;
- struct ieee80211_channel *channel = hw->conf.channel;
- int r;
-
- ath9k_ps_wakeup(sc);
-
- ath_cancel_work(sc);
-
- spin_lock_bh(&sc->sc_pcu_lock);
-
- /*
- * Keep the LED on when the radio is disabled
- * during idle unassociated state.
- */
- if (!sc->ps_idle) {
- ath9k_hw_set_gpio(ah, ah->led_pin, 1);
- ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
- }
-
- ath_prepare_reset(sc, false, true);
-
- if (!ah->curchan)
- ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
-
- r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
- if (r) {
- ath_err(ath9k_hw_common(sc->sc_ah),
- "Unable to reset channel (%u MHz), reset status %d\n",
- channel->center_freq, r);
- }
-
- ath9k_hw_phy_disable(ah);
-
- ath9k_hw_configpcipowersave(ah, true);
-
- spin_unlock_bh(&sc->sc_pcu_lock);
- ath9k_ps_restore(sc);
-}
-
static int ath_reset(struct ath_softc *sc, bool retry_tx)
{
int r;
@@ -1093,6 +1018,9 @@ static int ath9k_start(struct ieee80211_
* and then setup of the interrupt mask.
*/
spin_lock_bh(&sc->sc_pcu_lock);
+
+ atomic_set(&ah->intr_ref_cnt, -1);
+
r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
if (r) {
ath_err(common,
@@ -1131,6 +1059,18 @@ static int ath9k_start(struct ieee80211_
goto mutex_unlock;
}
+ if (ah->led_pin >= 0) {
+ ath9k_hw_cfg_output(ah, ah->led_pin,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_set_gpio(ah, ah->led_pin, 0);
+ }
+
+ /*
+ * Reset key cache to sane defaults (all entries cleared) instead of
+ * semi-random values after suspend/resume.
+ */
+ ath9k_cmn_init_crypto(sc->sc_ah);
+
spin_unlock_bh(&sc->sc_pcu_lock);
if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
@@ -1176,6 +1116,13 @@ static void ath9k_tx(struct ieee80211_hw
}
}
+ /*
+ * Cannot tx while the hardware is in full sleep, it first needs a full
+ * chip reset to recover from that
+ */
+ if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP))
+ goto exit;
+
if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) {
/*
* We are using PS-Poll and mac80211 can request TX while in
@@ -1222,6 +1169,7 @@ static void ath9k_stop(struct ieee80211_
struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
+ bool prev_idle;
mutex_lock(&sc->mutex);
@@ -1252,35 +1200,45 @@ static void ath9k_stop(struct ieee80211_
* before setting the invalid flag. */
ath9k_hw_disable_interrupts(ah);
- if (!(sc->sc_flags & SC_OP_INVALID)) {
- ath_drain_all_txq(sc, false);
- ath_stoprecv(sc);
- ath9k_hw_phy_disable(ah);
- } else
- sc->rx.rxlink = NULL;
+ spin_unlock_bh(&sc->sc_pcu_lock);
+
+ /* we can now sync irq and kill any running tasklets, since we already
+ * disabled interrupts and not holding a spin lock */
+ synchronize_irq(sc->irq);
+ tasklet_kill(&sc->intr_tq);
+ tasklet_kill(&sc->bcon_tasklet);
+
+ prev_idle = sc->ps_idle;
+ sc->ps_idle = true;
+
+ spin_lock_bh(&sc->sc_pcu_lock);
+
+ if (ah->led_pin >= 0) {
+ ath9k_hw_set_gpio(ah, ah->led_pin, 1);
+ ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
+ }
+
+ ath_prepare_reset(sc, false, true);
if (sc->rx.frag) {
dev_kfree_skb_any(sc->rx.frag);
sc->rx.frag = NULL;
}
- /* disable HAL and put h/w to sleep */
- ath9k_hw_disable(ah);
+ if (!ah->curchan)
+ ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
- spin_unlock_bh(&sc->sc_pcu_lock);
+ ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
+ ath9k_hw_phy_disable(ah);
- /* we can now sync irq and kill any running tasklets, since we already
- * disabled interrupts and not holding a spin lock */
- synchronize_irq(sc->irq);
- tasklet_kill(&sc->intr_tq);
- tasklet_kill(&sc->bcon_tasklet);
+ ath9k_hw_configpcipowersave(ah, true);
- ath9k_ps_restore(sc);
+ spin_unlock_bh(&sc->sc_pcu_lock);
- sc->ps_idle = true;
- ath_radio_disable(sc, hw);
+ ath9k_ps_restore(sc);
sc->sc_flags |= SC_OP_INVALID;
+ sc->ps_idle = prev_idle;
mutex_unlock(&sc->mutex);
@@ -1620,8 +1578,8 @@ static int ath9k_config(struct ieee80211
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &hw->conf;
- bool disable_radio = false;
+ ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex);
/*
@@ -1632,13 +1590,8 @@ static int ath9k_config(struct ieee80211
*/
if (changed & IEEE80211_CONF_CHANGE_IDLE) {
sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
- if (!sc->ps_idle) {
- ath_radio_enable(sc, hw);
- ath_dbg(common, ATH_DBG_CONFIG,
- "not-idle: enabling radio\n");
- } else {
- disable_radio = true;
- }
+ if (sc->ps_idle)
+ ath_cancel_work(sc);
}
/*
@@ -1745,18 +1698,12 @@ static int ath9k_config(struct ieee80211
ath_dbg(common, ATH_DBG_CONFIG,
"Set power: %d\n", conf->power_level);
sc->config.txpowlimit = 2 * conf->power_level;
- ath9k_ps_wakeup(sc);
ath9k_cmn_update_txpow(ah, sc->curtxpow,
sc->config.txpowlimit, &sc->curtxpow);
- ath9k_ps_restore(sc);
- }
-
- if (disable_radio) {
- ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
- ath_radio_disable(sc, hw);
}
mutex_unlock(&sc->mutex);
+ ath9k_ps_restore(sc);
return 0;
}
@@ -2324,9 +2271,6 @@ static void ath9k_flush(struct ieee80211
return;
}
- if (drop)
- timeout = 1;
-
for (j = 0; j < timeout; j++) {
bool npend = false;
@@ -2344,21 +2288,22 @@ static void ath9k_flush(struct ieee80211
}
if (!npend)
- goto out;
+ break;
}
- ath9k_ps_wakeup(sc);
- spin_lock_bh(&sc->sc_pcu_lock);
- drain_txq = ath_drain_all_txq(sc, false);
- spin_unlock_bh(&sc->sc_pcu_lock);
+ if (drop) {
+ ath9k_ps_wakeup(sc);
+ spin_lock_bh(&sc->sc_pcu_lock);
+ drain_txq = ath_drain_all_txq(sc, false);
+ spin_unlock_bh(&sc->sc_pcu_lock);
- if (!drain_txq)
- ath_reset(sc, false);
+ if (!drain_txq)
+ ath_reset(sc, false);
- ath9k_ps_restore(sc);
- ieee80211_wake_queues(hw);
+ ath9k_ps_restore(sc);
+ ieee80211_wake_queues(hw);
+ }
-out:
ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
mutex_unlock(&sc->mutex);
}
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -307,12 +307,11 @@ static int ath_pci_suspend(struct device
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath_softc *sc = hw->priv;
- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
-
/* The device has to be moved to FULLSLEEP forcibly.
* Otherwise the chip never moved to full sleep,
* when no interface is up.
*/
+ ath9k_hw_disable(sc->sc_ah);
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
return 0;
@@ -334,22 +333,6 @@ static int ath_pci_resume(struct device
if ((val & 0x0000ff00) != 0)
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
- ath9k_ps_wakeup(sc);
- /* Enable LED */
- ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
-
- /*
- * Reset key cache to sane defaults (all entries cleared) instead of
- * semi-random values after suspend/resume.
- */
- ath9k_cmn_init_crypto(sc->sc_ah);
- ath9k_ps_restore(sc);
-
- sc->ps_idle = true;
- ath_radio_disable(sc, hw);
-
return 0;
}
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1955,7 +1955,7 @@ static void ath_tx_complete(struct ath_s
skb_pull(skb, padsize);
}
- if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) {
+ if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) {
sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK;
ath_dbg(common, ATH_DBG_PS,
"Going back to sleep after having received TX status (0x%lx)\n",
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1122,6 +1122,7 @@ struct cfg80211_ibss_params {
@@ -1130,6 +1130,7 @@ struct cfg80211_ibss_params {
u8 *ssid;
u8 *bssid;
struct ieee80211_channel *channel;
@ -8,9 +365,9 @@
u8 *ie;
u8 ssid_len, ie_len;
u16 beacon_interval;
@@ -3188,6 +3189,16 @@ void cfg80211_gtk_rekey_notify(struct ne
void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
const u8 *bssid, bool preauth, gfp_t gfp);
@@ -3292,6 +3293,16 @@ void cfg80211_report_obss_beacon(struct
const u8 *frame, size_t len,
int freq, gfp_t gfp);
+/**
+ * cfg80211_can_use_ext_chan - test if ht40 on extension channel can be used
@ -27,7 +384,7 @@
/* wiphy_printk helpers, similar to dev_printk */
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -180,6 +180,10 @@ static void ieee80211_send_addba_resp(st
@@ -182,6 +182,10 @@ static void ieee80211_send_addba_resp(st
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
else if (sdata->vif.type == NL80211_IFTYPE_STATION)
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
@ -40,12 +397,12 @@
IEEE80211_STYPE_ACTION);
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -77,10 +77,13 @@ static void ieee80211_send_addba_request
memcpy(mgmt->da, da, ETH_ALEN);
@@ -79,10 +79,13 @@ 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_AP_VLAN ||
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)
@ -55,9 +412,9 @@
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);
@@ -397,7 +400,9 @@ int ieee80211_start_tx_ba_session(struct
*/
@@ -394,7 +397,9 @@ int ieee80211_start_tx_ba_session(struct
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
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_AP &&
@ -84,7 +441,7 @@
TEST(TDLS_PEER_AUTH));
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -199,6 +199,8 @@ void ieee80211_send_delba(struct ieee802
@@ -201,6 +201,8 @@ void ieee80211_send_delba(struct ieee802
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);
@ -103,7 +460,7 @@
lockdep_assert_held(&ifibss->mtx);
@@ -104,8 +105,16 @@ static void __ieee80211_sta_join_ibss(st
@@ -105,8 +106,16 @@ static void __ieee80211_sta_join_ibss(st
sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
@ -122,7 +479,7 @@
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
sband = local->hw.wiphy->bands[chan->band];
@@ -171,6 +180,18 @@ static void __ieee80211_sta_join_ibss(st
@@ -172,6 +181,18 @@ static void __ieee80211_sta_join_ibss(st
memcpy(skb_put(skb, ifibss->ie_len),
ifibss->ie, ifibss->ie_len);
@ -141,7 +498,7 @@
if (local->hw.queues >= 4) {
pos = skb_put(skb, 9);
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
@@ -194,6 +215,7 @@ static void __ieee80211_sta_join_ibss(st
@@ -195,6 +216,7 @@ static void __ieee80211_sta_join_ibss(st
bss_change |= BSS_CHANGED_BEACON;
bss_change |= BSS_CHANGED_BEACON_ENABLED;
bss_change |= BSS_CHANGED_BASIC_RATES;
@ -149,7 +506,7 @@
bss_change |= BSS_CHANGED_IBSS;
sdata->vif.bss_conf.ibss_joined = true;
ieee80211_bss_info_change_notify(sdata, bss_change);
@@ -266,6 +288,7 @@ static void ieee80211_rx_bss_info(struct
@@ -268,6 +290,7 @@ static void ieee80211_rx_bss_info(struct
u64 beacon_timestamp, rx_timestamp;
u32 supp_rates = 0;
enum ieee80211_band band = rx_status->band;
@ -157,7 +514,7 @@
if (elems->ds_params && elems->ds_params_len == 1)
freq = ieee80211_channel_to_frequency(elems->ds_params[0],
@@ -275,7 +298,10 @@ static void ieee80211_rx_bss_info(struct
@@ -277,7 +300,10 @@ static void ieee80211_rx_bss_info(struct
channel = ieee80211_get_channel(local->hw.wiphy, freq);
@ -169,7 +526,7 @@
return;
if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
@@ -313,8 +339,41 @@ static void ieee80211_rx_bss_info(struct
@@ -315,8 +341,41 @@ static void ieee80211_rx_bss_info(struct
GFP_ATOMIC);
}
@ -213,7 +570,7 @@
rcu_read_unlock();
}
@@ -896,10 +955,15 @@ int ieee80211_ibss_join(struct ieee80211
@@ -898,10 +957,15 @@ int ieee80211_ibss_join(struct ieee80211
struct sk_buff *skb;
skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
@ -233,7 +590,7 @@
params->ie_len);
if (!skb)
return -ENOMEM;
@@ -920,13 +984,15 @@ int ieee80211_ibss_join(struct ieee80211
@@ -922,13 +986,15 @@ int ieee80211_ibss_join(struct ieee80211
sdata->vif.bss_conf.beacon_int = params->beacon_interval;
sdata->u.ibss.channel = params->channel;
@ -253,7 +610,7 @@
if (params->ie) {
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -465,6 +465,7 @@ struct ieee80211_if_ibss {
@@ -470,6 +470,7 @@ struct ieee80211_if_ibss {
u8 ssid_len, ie_len;
u8 *ie;
struct ieee80211_channel *channel;
@ -261,28 +618,6 @@
unsigned long ibss_join_req;
/* probe response/beacon for IBSS */
@@ -1339,6 +1340,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);
+u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband,
+ u16 cap);
+u8 *ieee80211_ie_build_ht_info(u8 *pos,
+ struct ieee80211_sta_ht_cap *ht_cap,
+ struct ieee80211_channel *channel,
+ enum nl80211_channel_type channel_type);
/* internal work items */
void ieee80211_work_init(struct ieee80211_local *local);
@@ -1367,6 +1374,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);
+enum nl80211_channel_type
+ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info);
#ifdef CONFIG_MAC80211_NOINLINE
#define debug_noinline noinline
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -178,7 +178,6 @@ static int ieee80211_do_open(struct net_
@ -293,7 +628,7 @@
u32 changed = 0;
int res;
u32 hw_reconf_flags = 0;
@@ -290,27 +289,6 @@ static int ieee80211_do_open(struct net_
@@ -309,27 +308,6 @@ static int ieee80211_do_open(struct net_
set_bit(SDATA_STATE_RUNNING, &sdata->state);
@ -321,17 +656,17 @@
/*
* set_multicast_list will be invoked by the networking core
* which will check whether any increments here were done in
@@ -344,8 +322,7 @@ static int ieee80211_do_open(struct net_
@@ -356,8 +334,7 @@ static int ieee80211_do_open(struct net_
netif_tx_start_all_queues(dev);
return 0;
- err_del_interface:
- drv_remove_interface(local, &sdata->vif);
- drv_remove_interface(local, sdata);
+
err_stop:
if (!local->open_count)
drv_stop(local);
@@ -716,6 +693,70 @@ static void ieee80211_if_setup(struct ne
@@ -732,6 +709,70 @@ static void ieee80211_if_setup(struct ne
dev->destructor = free_netdev;
}
@ -402,7 +737,7 @@
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
@@ -820,6 +861,9 @@ static void ieee80211_iface_work(struct
@@ -836,6 +877,9 @@ static void ieee80211_iface_work(struct
break;
ieee80211_mesh_rx_queued_mgmt(sdata, skb);
break;
@ -412,11 +747,76 @@
default:
WARN(1, "frame for unexpected interface type");
break;
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1359,9 +1359,6 @@ static void __ieee80211_connection_loss(
ieee80211_set_disassoc(sdata, true, true);
mutex_unlock(&ifmgd->mtx);
- mutex_lock(&local->mtx);
- ieee80211_recalc_idle(local);
- mutex_unlock(&local->mtx);
/*
* must be outside lock due to cfg80211,
* but that's not a problem.
@@ -1370,6 +1367,10 @@ static void __ieee80211_connection_loss(
IEEE80211_STYPE_DEAUTH,
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
NULL, true);
+
+ mutex_lock(&local->mtx);
+ ieee80211_recalc_idle(local);
+ mutex_unlock(&local->mtx);
}
void ieee80211_beacon_connection_loss_work(struct work_struct *work)
@@ -2136,9 +2137,6 @@ static void ieee80211_sta_connection_los
ieee80211_set_disassoc(sdata, true, true);
mutex_unlock(&ifmgd->mtx);
- mutex_lock(&local->mtx);
- ieee80211_recalc_idle(local);
- mutex_unlock(&local->mtx);
/*
* must be outside lock due to cfg80211,
* but that's not a problem.
@@ -2146,6 +2144,11 @@ static void ieee80211_sta_connection_los
ieee80211_send_deauth_disassoc(sdata, bssid,
IEEE80211_STYPE_DEAUTH, reason,
NULL, true);
+
+ mutex_lock(&local->mtx);
+ ieee80211_recalc_idle(local);
+ mutex_unlock(&local->mtx);
+
mutex_lock(&ifmgd->mtx);
}
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -212,8 +212,6 @@ static void ieee80211_hw_roc_start(struc
return;
}
- ieee80211_recalc_idle(local);
-
if (local->hw_roc_skb) {
sdata = IEEE80211_DEV_TO_SUB_IF(local->hw_roc_dev);
ieee80211_tx_skb(sdata, local->hw_roc_skb);
@@ -227,6 +225,8 @@ static void ieee80211_hw_roc_start(struc
GFP_KERNEL);
}
+ ieee80211_recalc_idle(local);
+
mutex_unlock(&local->mtx);
}
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2211,7 +2211,9 @@ ieee80211_rx_h_action(struct ieee80211_r
*/
@@ -2250,7 +2250,9 @@ ieee80211_rx_h_action(struct ieee80211_r
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
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_AP &&
@ -425,7 +825,7 @@
break;
/* verify action_code is present */
@@ -2426,13 +2428,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
@@ -2465,13 +2467,14 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
if (!ieee80211_vif_is_mesh(&sdata->vif) &&
sdata->vif.type != NL80211_IFTYPE_ADHOC &&
@ -442,7 +842,7 @@
break;
case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
@@ -2775,10 +2778,16 @@ static int prepare_for_handlers(struct i
@@ -2818,10 +2821,16 @@ static int prepare_for_handlers(struct i
}
break;
case NL80211_IFTYPE_WDS:
@ -471,7 +871,7 @@
* @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.
@@ -61,7 +60,6 @@ enum ieee80211_sta_info_flags {
@@ -62,7 +61,6 @@ enum ieee80211_sta_info_flags {
WLAN_STA_SHORT_PREAMBLE,
WLAN_STA_ASSOC_AP,
WLAN_STA_WME,
@ -479,181 +879,6 @@
WLAN_STA_CLEAR_PS_FILT,
WLAN_STA_MFP,
WLAN_STA_BLOCK_BA,
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -836,23 +836,8 @@ int ieee80211_build_preq_ies(struct ieee
offset = noffset;
}
- if (sband->ht_cap.ht_supported) {
- u16 cap = sband->ht_cap.cap;
- __le16 tmp;
-
- *pos++ = WLAN_EID_HT_CAPABILITY;
- *pos++ = sizeof(struct ieee80211_ht_cap);
- memset(pos, 0, sizeof(struct ieee80211_ht_cap));
- tmp = cpu_to_le16(cap);
- memcpy(pos, &tmp, sizeof(u16));
- pos += sizeof(u16);
- *pos++ = sband->ht_cap.ampdu_factor |
- (sband->ht_cap.ampdu_density <<
- IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
- memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
- pos += sizeof(sband->ht_cap.mcs);
- pos += 2 + 4 + 1; /* ext info, BF cap, antsel */
- }
+ if (sband->ht_cap.ht_supported)
+ pos = ieee80211_ie_build_ht_cap(pos, sband, sband->ht_cap.cap);
/*
* If adding more here, adjust code in main.c
@@ -1443,3 +1428,100 @@ int ieee80211_add_ext_srates_ie(struct i
}
return 0;
}
+
+u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband,
+ u16 cap)
+{
+ __le16 tmp;
+
+ *pos++ = WLAN_EID_HT_CAPABILITY;
+ *pos++ = sizeof(struct ieee80211_ht_cap);
+ memset(pos, 0, sizeof(struct ieee80211_ht_cap));
+
+ /* capability flags */
+ tmp = cpu_to_le16(cap);
+ memcpy(pos, &tmp, sizeof(u16));
+ pos += sizeof(u16);
+
+ /* AMPDU parameters */
+ *pos++ = sband->ht_cap.ampdu_factor |
+ (sband->ht_cap.ampdu_density <<
+ IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
+
+ /* MCS set */
+ memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
+ pos += sizeof(sband->ht_cap.mcs);
+
+ /* extended capabilities */
+ pos += sizeof(__le16);
+
+ /* BF capabilities */
+ pos += sizeof(__le32);
+
+ /* antenna selection */
+ pos += sizeof(u8);
+
+ return pos;
+}
+
+u8 *ieee80211_ie_build_ht_info(u8 *pos,
+ struct ieee80211_sta_ht_cap *ht_cap,
+ struct ieee80211_channel *channel,
+ enum nl80211_channel_type channel_type)
+{
+ struct ieee80211_ht_info *ht_info;
+ /* Build HT Information */
+ *pos++ = WLAN_EID_HT_INFORMATION;
+ *pos++ = sizeof(struct ieee80211_ht_info);
+ ht_info = (struct ieee80211_ht_info *)pos;
+ ht_info->control_chan =
+ ieee80211_frequency_to_channel(channel->center_freq);
+ switch (channel_type) {
+ case NL80211_CHAN_HT40MINUS:
+ ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+ break;
+ case NL80211_CHAN_HT40PLUS:
+ ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+ break;
+ case NL80211_CHAN_HT20:
+ default:
+ ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
+ break;
+ }
+ if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+ ht_info->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
+ ht_info->operation_mode = 0x0000;
+ ht_info->stbc_param = 0x0000;
+
+ /* It seems that Basic MCS set and Supported MCS set
+ are identical for the first 10 bytes */
+ memset(&ht_info->basic_set, 0, 16);
+ memcpy(&ht_info->basic_set, &ht_cap->mcs, 10);
+
+ return pos + sizeof(struct ieee80211_ht_info);
+}
+
+enum nl80211_channel_type
+ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info)
+{
+ enum nl80211_channel_type channel_type;
+
+ if (!ht_info)
+ return NL80211_CHAN_NO_HT;
+
+ switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+ case IEEE80211_HT_PARAM_CHA_SEC_NONE:
+ channel_type = NL80211_CHAN_HT20;
+ break;
+ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+ channel_type = NL80211_CHAN_HT40PLUS;
+ break;
+ case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+ channel_type = NL80211_CHAN_HT40MINUS;
+ break;
+ default:
+ channel_type = NL80211_CHAN_NO_HT;
+ }
+
+ return channel_type;
+}
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -118,7 +118,6 @@ static void ieee80211_add_ht_ie(struct s
u8 *pos;
u32 flags = channel->flags;
u16 cap = sband->ht_cap.cap;
- __le16 tmp;
if (!sband->ht_cap.ht_supported)
return;
@@ -169,34 +168,8 @@ static void ieee80211_add_ht_ie(struct s
}
/* reserve and fill IE */
-
pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
- *pos++ = WLAN_EID_HT_CAPABILITY;
- *pos++ = sizeof(struct ieee80211_ht_cap);
- memset(pos, 0, sizeof(struct ieee80211_ht_cap));
-
- /* capability flags */
- tmp = cpu_to_le16(cap);
- memcpy(pos, &tmp, sizeof(u16));
- pos += sizeof(u16);
-
- /* AMPDU parameters */
- *pos++ = sband->ht_cap.ampdu_factor |
- (sband->ht_cap.ampdu_density <<
- IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
-
- /* MCS set */
- memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
- pos += sizeof(sband->ht_cap.mcs);
-
- /* extended capabilities */
- pos += sizeof(__le16);
-
- /* BF capabilities */
- pos += sizeof(__le32);
-
- /* antenna selection */
- pos += sizeof(u8);
+ ieee80211_ie_build_ht_cap(pos, sband, cap);
}
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -44,9 +44,9 @@ rdev_freq_to_chan(struct cfg80211_regist
@ -690,7 +915,7 @@
"allowed to initiate communication\n");
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4574,13 +4574,34 @@ static int nl80211_join_ibss(struct sk_b
@@ -4604,13 +4604,34 @@ static int nl80211_join_ibss(struct sk_b
ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}

View file

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

View file

@ -1,14 +1,14 @@
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -16,6 +16,7 @@
@@ -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"
@@ -464,8 +465,16 @@ static int ath9k_hw_init_macaddr(struct
@@ -465,8 +466,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/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -193,6 +193,10 @@ ath_reg_apply_beaconing_flags(struct wip
@@ -194,6 +194,10 @@ ath_reg_apply_beaconing_flags(struct wip
u32 bandwidth = 0;
int r;
@ -11,7 +11,7 @@
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (!wiphy->bands[band])
@@ -252,6 +256,10 @@ ath_reg_apply_active_scan_flags(struct w
@@ -253,6 +257,10 @@ ath_reg_apply_active_scan_flags(struct w
u32 bandwidth = 0;
int r;
@ -20,9 +20,9 @@
+#endif
+
sband = wiphy->bands[IEEE80211_BAND_2GHZ];
/*
@@ -299,6 +307,10 @@ static void ath_reg_apply_radar_flags(st
if (!sband)
return;
@@ -302,6 +310,10 @@ static void ath_reg_apply_radar_flags(st
struct ieee80211_channel *ch;
unsigned int i;
@ -33,7 +33,7 @@
if (!wiphy->bands[IEEE80211_BAND_5GHZ])
return;
@@ -466,6 +478,10 @@ ath_regd_init_wiphy(struct ath_regulator
@@ -469,6 +481,10 @@ ath_regd_init_wiphy(struct ath_regulator
{
const struct ieee80211_regdomain *regd;

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -37,7 +37,8 @@
@@ -38,7 +38,8 @@
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
/* We allow IBSS on these on a case by case basis by regulatory domain */
@ -10,7 +10,7 @@
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)
@@ -55,57 +56,56 @@
@@ -56,57 +57,56 @@
#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \
ATH9K_5GHZ_5725_5850

View file

@ -1,6 +1,6 @@
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1654,6 +1654,8 @@ void regulatory_hint_11d(struct wiphy *w
@@ -1656,6 +1656,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))
@@ -1860,6 +1862,8 @@ static void restore_regulatory_settings(
@@ -1862,6 +1864,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
@@ -1486,15 +1486,6 @@ static int ath9k_add_interface(struct ie
@@ -1448,15 +1448,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);
@@ -1520,15 +1511,6 @@ static int ath9k_change_interface(struct
@@ -1482,15 +1473,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/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1610,6 +1610,53 @@ static const struct file_operations fops
@@ -1616,6 +1616,53 @@ static const struct file_operations fops
};
@ -54,7 +54,7 @@
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
@@ -1668,6 +1715,9 @@ int ath9k_init_debug(struct ath_hw *ah)
@@ -1674,6 +1721,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
@@ -1714,8 +1714,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
@@ -1715,8 +1715,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
@@ -364,7 +364,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
@@ -387,8 +387,8 @@ static void ath9k_hw_init_config(struct
@@ -388,8 +388,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
@@ -120,7 +120,7 @@ void ath_descdma_cleanup(struct ath_soft
@@ -121,7 +121,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
@@ -587,6 +587,7 @@ struct ath_softc {
@@ -591,6 +591,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
@@ -1718,6 +1718,9 @@ int ath9k_init_debug(struct ath_hw *ah)
@@ -1724,6 +1724,9 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_eeprom);
@ -22,7 +22,7 @@
sc->debug.sampidx = 0;
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1649,9 +1649,10 @@ static int ath9k_config(struct ieee80211
@@ -1606,9 +1606,10 @@ static int ath9k_config(struct ieee80211
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
struct ieee80211_channel *curchan = hw->conf.channel;
@ -34,7 +34,7 @@
unsigned long flags;
if (ah->curchan)
@@ -1704,7 +1705,23 @@ static int ath9k_config(struct ieee80211
@@ -1661,7 +1662,23 @@ static int ath9k_config(struct ieee80211
memset(&sc->survey[pos], 0, sizeof(struct survey_info));
}
@ -61,7 +61,7 @@
return -EINVAL;
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1548,6 +1548,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st
@@ -1549,6 +1549,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st
caldata->rtt_hist.num_readings)
allow_fbs = true;

View file

@ -1,6 +1,6 @@
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -239,7 +239,9 @@ void ieee80211_bss_info_change_notify(st
@@ -237,7 +237,9 @@ void ieee80211_bss_info_change_notify(st
u32 changed)
{
struct ieee80211_local *local = sdata->local;
@ -10,7 +10,7 @@
if (!changed)
return;
@@ -269,6 +271,22 @@ void ieee80211_bss_info_change_notify(st
@@ -267,6 +269,22 @@ void ieee80211_bss_info_change_notify(st
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP:

View file

@ -1,6 +1,6 @@
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -683,6 +683,7 @@ static const struct net_device_ops ieee8
@@ -699,6 +699,7 @@ static const struct net_device_ops ieee8
static void ieee80211_if_setup(struct net_device *dev)
{
ether_setup(dev);

View file

@ -1,6 +1,6 @@
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -815,7 +815,7 @@ enum ieee80211_smps_mode {
@@ -816,7 +816,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
@@ -1615,7 +1615,7 @@ static int ieee80211_get_tx_power(struct
@@ -1677,7 +1677,7 @@ static int ieee80211_get_tx_power(struct
{
struct ieee80211_local *local = wiphy_priv(wiphy);
@ -22,7 +22,7 @@
}
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -210,6 +210,7 @@ int ieee80211_hw_config(struct ieee80211
@@ -208,6 +208,7 @@ int ieee80211_hw_config(struct ieee80211
if (local->hw.conf.power_level != power) {
changed |= IEEE80211_CONF_CHANGE_POWER;

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
@@ -1684,6 +1684,8 @@ static int ath9k_config(struct ieee80211
return -EINVAL;
}
@ -9,11 +9,11 @@
/*
* 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
@@ -1699,6 +1701,7 @@ static int ath9k_config(struct ieee80211
sc->config.txpowlimit = 2 * conf->power_level;
ath9k_cmn_update_txpow(ah, sc->curtxpow,
sc->config.txpowlimit, &sc->curtxpow);
ath9k_ps_restore(sc);
+ conf->cur_power_level = sc->curtxpow / 2;
}
if (disable_radio) {
mutex_unlock(&sc->mutex);

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -237,6 +237,7 @@ struct ath_atx_tid {
@@ -238,6 +238,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;
@@ -282,6 +283,9 @@ struct ath_tx_control {
@@ -284,6 +285,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
@@ -1679,6 +1679,10 @@ int ath9k_init_debug(struct ath_hw *ah)
@@ -1685,6 +1685,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);
@ -57,7 +57,7 @@
while (bf) {
u16 seqno = bf->bf_state.seqno;
@@ -821,6 +831,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
@@ -824,6 +834,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
ath_tx_addto_baw(sc, tid, seqno);
bf->bf_state.ndelim = ndelim;
@ -65,7 +65,7 @@
__skb_unlink(skb, &tid->buf_q);
list_add_tail(&bf->list, bf_q);
if (bf_prev)
@@ -1680,6 +1691,8 @@ static void ath_tx_send_ampdu(struct ath
@@ -1683,6 +1694,8 @@ static void ath_tx_send_ampdu(struct ath
/* Add sub-frame to BAW */
ath_tx_addto_baw(sc, tid, bf->bf_state.seqno);
@ -74,7 +74,7 @@
/* Queue to h/w without aggregation */
TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
bf->bf_lastbf = bf;
@@ -1808,23 +1821,13 @@ error:
@@ -1811,23 +1824,13 @@ error:
/* FIXME: tx power */
static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
@ -100,7 +100,7 @@
if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
/*
@@ -1859,6 +1862,7 @@ int ath_tx_start(struct ieee80211_hw *hw
@@ -1862,6 +1865,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;
@ -108,7 +108,7 @@
int padpos, padsize;
int frmlen = skb->len + FCS_LEN;
int q;
@@ -1901,6 +1905,24 @@ int ath_tx_start(struct ieee80211_hw *hw
@@ -1904,6 +1908,24 @@ int ath_tx_start(struct ieee80211_hw *hw
setup_frame_info(hw, skb, frmlen);
@ -133,7 +133,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.
@@ -1915,7 +1937,7 @@ int ath_tx_start(struct ieee80211_hw *hw
@@ -1918,7 +1940,7 @@ int ath_tx_start(struct ieee80211_hw *hw
}
spin_unlock_bh(&txq->axq_lock);

View file

@ -51,7 +51,7 @@
} else {
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -542,7 +542,7 @@ struct ath_ant_comb {
@@ -546,7 +546,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/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1381,10 +1381,16 @@ static bool ath9k_hw_set_reset_reg(struc
@@ -1382,10 +1382,16 @@ static bool ath9k_hw_set_reset_reg(struc
static bool ath9k_hw_chip_reset(struct ath_hw *ah,
struct ath9k_channel *chan)
{

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -963,34 +963,6 @@ static ssize_t read_file_recv(struct fil
@@ -969,34 +969,6 @@ static ssize_t read_file_recv(struct fil
"%18s : %10u\n", "DECRYPT BUSY ERR",
sc->debug.stats.rxstats.decrypt_busy_err);
@ -35,7 +35,7 @@
PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
@@ -1067,16 +1039,6 @@ void ath_debug_stat_rx(struct ath_softc
@@ -1073,16 +1045,6 @@ void ath_debug_stat_rx(struct ath_softc
RX_PHY_ERR_INC(phyerr);
}

View file

@ -1,6 +1,6 @@
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -683,6 +683,9 @@ enum mac80211_rx_flags {
@@ -684,6 +684,9 @@ enum mac80211_rx_flags {
* @mactime: value in microseconds of the 64-bit Time Synchronization Function
* (TSF) timer when the first data symbol (MPDU) arrived at the hardware.
* @band: the active band when this frame was received
@ -10,7 +10,7 @@
* @freq: frequency the radio was tuned to when receiving this frame, in MHz
* @signal: signal strength when receiving this frame, either in dBm, in dB or
* unspecified depending on the hardware capabilities flags
@@ -696,6 +699,10 @@ enum mac80211_rx_flags {
@@ -697,6 +700,10 @@ enum mac80211_rx_flags {
struct ieee80211_rx_status {
u64 mactime;
enum ieee80211_band band;
@ -23,7 +23,7 @@
int antenna;
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -300,6 +300,11 @@ struct sta_info {
@@ -302,6 +302,11 @@ struct sta_info {
unsigned long rx_dropped;
int last_signal;
struct ewma avg_signal;
@ -37,7 +37,7 @@
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1244,6 +1244,7 @@ ieee80211_rx_h_sta_process(struct ieee80
@@ -1267,6 +1267,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;
@ -45,7 +45,7 @@
if (!sta)
return RX_CONTINUE;
@@ -1286,6 +1287,19 @@ ieee80211_rx_h_sta_process(struct ieee80
@@ -1309,6 +1310,19 @@ ieee80211_rx_h_sta_process(struct ieee80
sta->last_signal = status->signal;
ewma_add(&sta->avg_signal, -status->signal);
@ -78,7 +78,7 @@
kfree(sta);
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -498,6 +498,8 @@ struct station_parameters {
@@ -505,6 +505,8 @@ struct station_parameters {
* @STATION_INFO_CONNECTED_TIME: @connected_time filled
* @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
* @STATION_INFO_STA_FLAGS: @sta_flags filled
@ -87,7 +87,7 @@
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -518,7 +520,9 @@ enum station_info_flags {
@@ -525,7 +527,9 @@ enum station_info_flags {
STATION_INFO_BSS_PARAM = 1<<15,
STATION_INFO_CONNECTED_TIME = 1<<16,
STATION_INFO_ASSOC_REQ_IES = 1<<17,
@ -98,7 +98,7 @@
};
/**
@@ -598,6 +602,9 @@ struct sta_bss_parameters {
@@ -605,6 +609,9 @@ struct sta_bss_parameters {
* @plink_state: mesh peer link state
* @signal: signal strength of last received packet in dBm
* @signal_avg: signal strength average in dBm
@ -108,7 +108,7 @@
* @txrate: current unicast bitrate from this station
* @rxrate: current unicast bitrate to this station
* @rx_packets: packets received from this station
@@ -627,6 +634,11 @@ struct station_info {
@@ -635,6 +642,11 @@ struct station_info {
u8 plink_state;
s8 signal;
s8 signal_avg;
@ -189,7 +189,7 @@
/* Record packet only when both main_rssi and alt_rssi is positive */
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -451,12 +451,12 @@ int ath9k_hw_process_rxdesc_edma(struct
@@ -452,12 +452,12 @@ int ath9k_hw_process_rxdesc_edma(struct
/* XXX: Keycache */
rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
@ -210,7 +210,7 @@
rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -558,25 +558,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
@@ -559,25 +559,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
rs->rs_rssi = ATH9K_RSSI_BAD;
@ -250,7 +250,7 @@
if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1041,12 +1041,12 @@ void ath_debug_stat_rx(struct ath_softc
@@ -1047,12 +1047,12 @@ void ath_debug_stat_rx(struct ath_softc
spin_lock(&sc->debug.samp_lock);
RX_SAMP_DBG(jiffies) = jiffies;
@ -271,7 +271,7 @@
RX_SAMP_DBG(rate) = rs->rs_rate;
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1549,6 +1549,8 @@ enum nl80211_sta_bss_param {
@@ -1621,6 +1621,8 @@ enum nl80211_sta_bss_param {
* containing info as possible, see &enum nl80211_sta_bss_param
* @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected
* @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
@ -280,7 +280,7 @@
* @__NL80211_STA_INFO_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribute
*/
@@ -1571,6 +1573,8 @@ enum nl80211_sta_info {
@@ -1643,6 +1645,8 @@ enum nl80211_sta_info {
NL80211_STA_INFO_BSS_PARAM,
NL80211_STA_INFO_CONNECTED_TIME,
NL80211_STA_INFO_STA_FLAGS,
@ -291,7 +291,7 @@
__NL80211_STA_INFO_AFTER_LAST,
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2257,6 +2257,33 @@ nla_put_failure:
@@ -2287,6 +2287,33 @@ nla_put_failure:
return false;
}
@ -325,7 +325,7 @@
static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
int flags, struct net_device *dev,
const u8 *mac_addr, struct station_info *sinfo)
@@ -2303,6 +2330,18 @@ static int nl80211_send_station(struct s
@@ -2333,6 +2360,18 @@ static int nl80211_send_station(struct s
if (sinfo->filled & STATION_INFO_SIGNAL_AVG)
NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG,
sinfo->signal_avg);

View file

@ -1,68 +0,0 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -619,6 +619,7 @@ struct ath_softc {
u16 curtxpow;
bool ps_enabled;
bool ps_idle;
+ bool ps_fullsleep;
short nbcnvifs;
short nvifs;
unsigned long ps_usecount;
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -118,9 +118,10 @@ void ath9k_ps_restore(struct ath_softc *
if (--sc->ps_usecount != 0)
goto unlock;
- if (sc->ps_idle)
+ if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK)) {
mode = ATH9K_PM_FULL_SLEEP;
- else if (sc->ps_enabled &&
+ sc->ps_fullsleep = true;
+ } else if (sc->ps_enabled &&
!(sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB |
PS_WAIT_FOR_PSPOLL_DATA |
@@ -275,6 +276,7 @@ static bool ath_complete_reset(struct at
sc->config.txpowlimit, &sc->curtxpow);
ath9k_hw_set_interrupts(ah);
ath9k_hw_enable_interrupts(ah);
+ sc->ps_fullsleep = false;
if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) {
if (sc->sc_flags & SC_OP_BEACONS)
@@ -332,7 +334,8 @@ static int ath_reset_internal(struct ath
hchan = ah->curchan;
}
- if (fastcc && !ath9k_hw_check_alive(ah))
+ if (fastcc && (sc->ps_fullsleep ||
+ !ath9k_hw_check_alive(ah)))
fastcc = false;
if (!ath_prepare_reset(sc, retry_tx, flush))
@@ -1173,6 +1176,13 @@ static void ath9k_tx(struct ieee80211_hw
}
}
+ /*
+ * Cannot tx while the hardware is in full sleep, it first needs a full
+ * chip reset to recover from that
+ */
+ if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP))
+ goto exit;
+
if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) {
/*
* We are using PS-Poll and mac80211 can request TX while in
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1983,7 +1983,7 @@ static void ath_tx_complete(struct ath_s
skb_pull(skb, padsize);
}
- if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) {
+ if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) {
sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK;
ath_dbg(common, ATH_DBG_PS,
"Going back to sleep after having received TX status (0x%lx)\n",

View file

@ -1,273 +0,0 @@
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -883,82 +883,6 @@ chip_reset:
#undef SCHED_INTR
}
-static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
-{
- struct ath_hw *ah = sc->sc_ah;
- struct ath_common *common = ath9k_hw_common(ah);
- struct ieee80211_channel *channel = hw->conf.channel;
- int r;
-
- ath9k_ps_wakeup(sc);
- spin_lock_bh(&sc->sc_pcu_lock);
- atomic_set(&ah->intr_ref_cnt, -1);
-
- ath9k_hw_configpcipowersave(ah, false);
-
- if (!ah->curchan)
- ah->curchan = ath9k_cmn_get_curchannel(sc->hw, ah);
-
- r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
- if (r) {
- ath_err(common,
- "Unable to reset channel (%u MHz), reset status %d\n",
- channel->center_freq, r);
- }
-
- ath_complete_reset(sc, true);
-
- /* Enable LED */
- ath9k_hw_cfg_output(ah, ah->led_pin,
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- ath9k_hw_set_gpio(ah, ah->led_pin, 0);
-
- spin_unlock_bh(&sc->sc_pcu_lock);
-
- ath9k_ps_restore(sc);
-}
-
-void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
-{
- struct ath_hw *ah = sc->sc_ah;
- struct ieee80211_channel *channel = hw->conf.channel;
- int r;
-
- ath9k_ps_wakeup(sc);
-
- ath_cancel_work(sc);
-
- spin_lock_bh(&sc->sc_pcu_lock);
-
- /*
- * Keep the LED on when the radio is disabled
- * during idle unassociated state.
- */
- if (!sc->ps_idle) {
- ath9k_hw_set_gpio(ah, ah->led_pin, 1);
- ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
- }
-
- ath_prepare_reset(sc, false, true);
-
- if (!ah->curchan)
- ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
-
- r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
- if (r) {
- ath_err(ath9k_hw_common(sc->sc_ah),
- "Unable to reset channel (%u MHz), reset status %d\n",
- channel->center_freq, r);
- }
-
- ath9k_hw_phy_disable(ah);
-
- ath9k_hw_configpcipowersave(ah, true);
-
- spin_unlock_bh(&sc->sc_pcu_lock);
- ath9k_ps_restore(sc);
-}
-
static int ath_reset(struct ath_softc *sc, bool retry_tx)
{
int r;
@@ -1094,6 +1018,9 @@ static int ath9k_start(struct ieee80211_
* and then setup of the interrupt mask.
*/
spin_lock_bh(&sc->sc_pcu_lock);
+
+ atomic_set(&ah->intr_ref_cnt, -1);
+
r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
if (r) {
ath_err(common,
@@ -1132,6 +1059,18 @@ static int ath9k_start(struct ieee80211_
goto mutex_unlock;
}
+ if (ah->led_pin >= 0) {
+ ath9k_hw_cfg_output(ah, ah->led_pin,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_set_gpio(ah, ah->led_pin, 0);
+ }
+
+ /*
+ * Reset key cache to sane defaults (all entries cleared) instead of
+ * semi-random values after suspend/resume.
+ */
+ ath9k_cmn_init_crypto(sc->sc_ah);
+
spin_unlock_bh(&sc->sc_pcu_lock);
if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
@@ -1229,6 +1168,7 @@ static void ath9k_stop(struct ieee80211_
struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
+ bool prev_idle;
mutex_lock(&sc->mutex);
@@ -1258,35 +1198,45 @@ static void ath9k_stop(struct ieee80211_
* before setting the invalid flag. */
ath9k_hw_disable_interrupts(ah);
- if (!(sc->sc_flags & SC_OP_INVALID)) {
- ath_drain_all_txq(sc, false);
- ath_stoprecv(sc);
- ath9k_hw_phy_disable(ah);
- } else
- sc->rx.rxlink = NULL;
+ spin_unlock_bh(&sc->sc_pcu_lock);
+
+ /* we can now sync irq and kill any running tasklets, since we already
+ * disabled interrupts and not holding a spin lock */
+ synchronize_irq(sc->irq);
+ tasklet_kill(&sc->intr_tq);
+ tasklet_kill(&sc->bcon_tasklet);
+
+ prev_idle = sc->ps_idle;
+ sc->ps_idle = true;
+
+ spin_lock_bh(&sc->sc_pcu_lock);
+
+ if (ah->led_pin >= 0) {
+ ath9k_hw_set_gpio(ah, ah->led_pin, 1);
+ ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
+ }
+
+ ath_prepare_reset(sc, false, true);
if (sc->rx.frag) {
dev_kfree_skb_any(sc->rx.frag);
sc->rx.frag = NULL;
}
- /* disable HAL and put h/w to sleep */
- ath9k_hw_disable(ah);
+ if (!ah->curchan)
+ ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
- spin_unlock_bh(&sc->sc_pcu_lock);
+ ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
+ ath9k_hw_phy_disable(ah);
- /* we can now sync irq and kill any running tasklets, since we already
- * disabled interrupts and not holding a spin lock */
- synchronize_irq(sc->irq);
- tasklet_kill(&sc->intr_tq);
- tasklet_kill(&sc->bcon_tasklet);
+ ath9k_hw_configpcipowersave(ah, true);
- ath9k_ps_restore(sc);
+ spin_unlock_bh(&sc->sc_pcu_lock);
- sc->ps_idle = true;
- ath_radio_disable(sc, hw);
+ ath9k_ps_restore(sc);
sc->sc_flags |= SC_OP_INVALID;
+ sc->ps_idle = prev_idle;
mutex_unlock(&sc->mutex);
@@ -1608,8 +1558,8 @@ static int ath9k_config(struct ieee80211
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &hw->conf;
- bool disable_radio = false;
+ ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex);
/*
@@ -1618,16 +1568,8 @@ static int ath9k_config(struct ieee80211
* of the changes. Likewise we must only disable the radio towards
* the end.
*/
- if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+ if (changed & IEEE80211_CONF_CHANGE_IDLE)
sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
- if (!sc->ps_idle) {
- ath_radio_enable(sc, hw);
- ath_dbg(common, ATH_DBG_CONFIG,
- "not-idle: enabling radio\n");
- } else {
- disable_radio = true;
- }
- }
/*
* We just prepare to enable PS. We have to wait until our AP has
@@ -1752,19 +1694,13 @@ static int ath9k_config(struct ieee80211
ath_dbg(common, ATH_DBG_CONFIG,
"Set power: %d\n", conf->power_level);
sc->config.txpowlimit = 2 * conf->power_level;
- ath9k_ps_wakeup(sc);
ath9k_cmn_update_txpow(ah, sc->curtxpow,
sc->config.txpowlimit, &sc->curtxpow);
- ath9k_ps_restore(sc);
conf->cur_power_level = sc->curtxpow / 2;
}
- if (disable_radio) {
- ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
- ath_radio_disable(sc, hw);
- }
-
mutex_unlock(&sc->mutex);
+ ath9k_ps_restore(sc);
return 0;
}
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -306,12 +306,11 @@ static int ath_pci_suspend(struct device
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath_softc *sc = hw->priv;
- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
-
/* The device has to be moved to FULLSLEEP forcibly.
* Otherwise the chip never moved to full sleep,
* when no interface is up.
*/
+ ath9k_hw_disable(sc->sc_ah);
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
return 0;
@@ -333,22 +332,6 @@ static int ath_pci_resume(struct device
if ((val & 0x0000ff00) != 0)
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
- ath9k_ps_wakeup(sc);
- /* Enable LED */
- ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
-
- /*
- * Reset key cache to sane defaults (all entries cleared) instead of
- * semi-random values after suspend/resume.
- */
- ath9k_cmn_init_crypto(sc->sc_ah);
- ath9k_ps_restore(sc);
-
- sc->ps_idle = true;
- ath_radio_disable(sc, hw);
-
return 0;
}

View file

@ -1,45 +0,0 @@
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2268,9 +2268,6 @@ static void ath9k_flush(struct ieee80211
return;
}
- if (drop)
- timeout = 1;
-
for (j = 0; j < timeout; j++) {
bool npend = false;
@@ -2288,21 +2285,22 @@ static void ath9k_flush(struct ieee80211
}
if (!npend)
- goto out;
+ break;
}
- ath9k_ps_wakeup(sc);
- spin_lock_bh(&sc->sc_pcu_lock);
- drain_txq = ath_drain_all_txq(sc, false);
- spin_unlock_bh(&sc->sc_pcu_lock);
+ if (drop) {
+ ath9k_ps_wakeup(sc);
+ spin_lock_bh(&sc->sc_pcu_lock);
+ drain_txq = ath_drain_all_txq(sc, false);
+ spin_unlock_bh(&sc->sc_pcu_lock);
- if (!drain_txq)
- ath_reset(sc, false);
+ if (!drain_txq)
+ ath_reset(sc, false);
- ath9k_ps_restore(sc);
- ieee80211_wake_queues(hw);
+ ath9k_ps_restore(sc);
+ ieee80211_wake_queues(hw);
+ }
-out:
ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
mutex_unlock(&sc->mutex);
}

View file

@ -117,7 +117,7 @@
/*
* Capabilities
@@ -960,6 +962,11 @@ struct rt2x00_dev {
@@ -961,6 +963,11 @@ struct rt2x00_dev {
const struct firmware *fw;
/*
@ -239,18 +239,18 @@
.get_entry_state = rt2800pci_get_entry_state,
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1142,6 +1142,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
@@ -1145,6 +1145,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
BIT(NL80211_IFTYPE_MESH_POINT) |
BIT(NL80211_IFTYPE_WDS);
+ retval = rt2x00lib_load_eeprom_file(rt2x00dev);
+ if (retval)
+ goto exit;
+
/*
* Let the driver probe the device to detect the capabilities.
* Initialize work.
*/
@@ -1243,6 +1247,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
@@ -1261,6 +1265,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
* Free queue structures.
*/
rt2x00queue_free(rt2x00dev);

View file

@ -1,8 +1,6 @@
Index: compat-wireless-2011-11-04/drivers/net/wireless/rt2x00/rt2800pci.c
===================================================================
--- compat-wireless-2011-11-04.orig/drivers/net/wireless/rt2x00/rt2800pci.c 2011-11-12 19:34:24.760314206 +0100
+++ compat-wireless-2011-11-04/drivers/net/wireless/rt2x00/rt2800pci.c 2011-11-12 19:34:24.956314211 +0100
@@ -84,7 +84,7 @@
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -84,7 +84,7 @@ static void rt2800pci_mcu_status(struct
rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
}
@ -11,7 +9,7 @@ Index: compat-wireless-2011-11-04/drivers/net/wireless/rt2x00/rt2800pci.c
{
memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE);
}
@@ -938,8 +938,9 @@
@@ -938,8 +938,9 @@ static int rt2800pci_validate_eeprom(str
/*
* Read EEPROM into buffer
*/
@ -23,11 +21,9 @@ Index: compat-wireless-2011-11-04/drivers/net/wireless/rt2x00/rt2800pci.c
else if (rt2800pci_efuse_detect(rt2x00dev))
rt2800pci_read_eeprom_efuse(rt2x00dev);
else
Index: compat-wireless-2011-11-04/drivers/net/wireless/rt2x00/rt2x00pci.c
===================================================================
--- compat-wireless-2011-11-04.orig/drivers/net/wireless/rt2x00/rt2x00pci.c 2011-11-12 19:34:24.704314204 +0100
+++ compat-wireless-2011-11-04/drivers/net/wireless/rt2x00/rt2x00pci.c 2011-11-12 19:34:24.956314211 +0100
@@ -255,6 +255,7 @@
--- 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;
@ -35,7 +31,7 @@ Index: compat-wireless-2011-11-04/drivers/net/wireless/rt2x00/rt2x00pci.c
struct rt2x00_dev *rt2x00dev;
int retval;
@@ -299,6 +300,12 @@
@@ -299,6 +300,12 @@ int rt2x00pci_probe(struct pci_dev *pci_
rt2x00dev->irq = pci_dev->irq;
rt2x00dev->name = pci_name(pci_dev);