mac80211: update to wireless-testing 2014-11-04
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 43210
This commit is contained in:
parent
82e2aeb599
commit
740c755805
65 changed files with 37 additions and 3205 deletions
|
@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk
|
|||
|
||||
PKG_NAME:=mac80211
|
||||
|
||||
PKG_VERSION:=2014-10-08
|
||||
PKG_VERSION:=2014-11-04
|
||||
PKG_RELEASE:=1
|
||||
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
|
||||
PKG_BACKPORT_VERSION:=
|
||||
PKG_MD5SUM:=20e9de70e63fd9649d61d4670a9cc1bd
|
||||
PKG_MD5SUM:=d0b64853fb78cfd1d6cb639327811e2a
|
||||
|
||||
PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -1825,6 +1825,11 @@ void ieee80211_remove_interfaces(struct
|
||||
@@ -1859,6 +1859,11 @@ void ieee80211_remove_interfaces(struct
|
||||
}
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
unregister_netdevice_many(&unreg_list);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/.local-symbols
|
||||
+++ b/.local-symbols
|
||||
@@ -416,42 +416,6 @@ USB_CDC_PHONET=
|
||||
@@ -423,42 +423,6 @@ USB_CDC_PHONET=
|
||||
USB_IPHETH=
|
||||
USB_SIERRA_NET=
|
||||
USB_VL600=
|
||||
|
|
|
@ -246,7 +246,7 @@
|
|||
struct {
|
||||
--- a/net/mac80211/wpa.c
|
||||
+++ b/net/mac80211/wpa.c
|
||||
@@ -304,15 +304,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
|
||||
@@ -302,15 +302,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
|
||||
}
|
||||
|
||||
|
||||
|
@ -271,7 +271,7 @@
|
|||
/*
|
||||
* Mask FC: zero subtype b4 b5 b6 (if not mgmt)
|
||||
* Retry, PwrMgt, MoreData; set Protected
|
||||
@@ -334,21 +341,20 @@ static void ccmp_special_blocks(struct s
|
||||
@@ -332,21 +339,20 @@ static void ccmp_special_blocks(struct s
|
||||
else
|
||||
qos_tid = 0;
|
||||
|
||||
|
@ -300,7 +300,7 @@
|
|||
|
||||
/* AAD (extra authenticate-only data) / masked 802.11 header
|
||||
* FC | A1 | A2 | A3 | SC | [A4] | [QC] */
|
||||
@@ -404,8 +410,7 @@ static int ccmp_encrypt_skb(struct ieee8
|
||||
@@ -402,8 +408,7 @@ static int ccmp_encrypt_skb(struct ieee8
|
||||
u8 *pos;
|
||||
u8 pn[6];
|
||||
u64 pn64;
|
||||
|
@ -310,7 +310,7 @@
|
|||
|
||||
if (info->control.hw_key &&
|
||||
!(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
|
||||
@@ -461,9 +466,9 @@ static int ccmp_encrypt_skb(struct ieee8
|
||||
@@ -457,9 +462,9 @@ static int ccmp_encrypt_skb(struct ieee8
|
||||
return 0;
|
||||
|
||||
pos += IEEE80211_CCMP_HDR_LEN;
|
||||
|
@ -323,7 +323,7 @@
|
|||
|
||||
return 0;
|
||||
}
|
||||
@@ -526,16 +531,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
|
||||
@@ -522,16 +527,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
|
||||
}
|
||||
|
||||
if (!(status->flag & RX_FLAG_DECRYPTED)) {
|
||||
|
|
|
@ -2,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
|
|||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -846,7 +846,6 @@ static int ieee80211_stop_ap(struct wiph
|
||||
@@ -848,7 +848,6 @@ static int ieee80211_stop_ap(struct wiph
|
||||
sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
|
||||
|
||||
__sta_info_flush(sdata, true);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
static int ieee80211_ifa6_changed(struct notifier_block *nb,
|
||||
unsigned long data, void *arg)
|
||||
{
|
||||
@@ -1038,14 +1038,14 @@ int ieee80211_register_hw(struct ieee802
|
||||
@@ -1044,14 +1044,14 @@ int ieee80211_register_hw(struct ieee802
|
||||
goto fail_pm_qos;
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
|||
local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
|
||||
result = register_inet6addr_notifier(&local->ifa6_notifier);
|
||||
if (result)
|
||||
@@ -1054,13 +1054,13 @@ int ieee80211_register_hw(struct ieee802
|
||||
@@ -1060,13 +1060,13 @@ int ieee80211_register_hw(struct ieee802
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
|||
fail_ifa:
|
||||
pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
|
||||
&local->network_latency_notifier);
|
||||
@@ -1105,10 +1105,10 @@ void ieee80211_unregister_hw(struct ieee
|
||||
@@ -1111,10 +1111,10 @@ void ieee80211_unregister_hw(struct ieee
|
||||
|
||||
pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
|
||||
&local->network_latency_notifier);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1895,7 +1895,7 @@ static int ieee80211_scan(struct wiphy *
|
||||
@@ -1947,7 +1947,7 @@ static int ieee80211_scan(struct wiphy *
|
||||
* the frames sent while scanning on other channel will be
|
||||
* lost)
|
||||
*/
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
From: Karl Beldan <karl.beldan@rivierawaves.com>
|
||||
Date: Tue, 7 Oct 2014 15:53:38 +0200
|
||||
Subject: [PATCH] mac80211/trivial: fix typo in starting baserate for
|
||||
rts_cts_rate_idx
|
||||
|
||||
Fixes: 5253ffb8 ("mac80211: always pick a basic rate to tx RTS/CTS for pre-HT rates")
|
||||
Signed-off-by: Karl Beldan <karl.beldan@rivierawaves.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rate.c
|
||||
+++ b/net/mac80211/rate.c
|
||||
@@ -448,7 +448,7 @@ static void rate_fixup_ratelist(struct i
|
||||
*/
|
||||
if (!(rates[0].flags & IEEE80211_TX_RC_MCS)) {
|
||||
u32 basic_rates = vif->bss_conf.basic_rates;
|
||||
- s8 baserate = basic_rates ? ffs(basic_rates - 1) : 0;
|
||||
+ s8 baserate = basic_rates ? ffs(basic_rates) - 1 : 0;
|
||||
|
||||
rate = &sband->bitrates[rates[0].idx];
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Wed, 22 Oct 2014 18:44:03 +0200
|
||||
Subject: [PATCH] ath10k: add SURVEY_INFO_IN_USE for current channel on survey
|
||||
Subject: [PATCH] ath10k: add SURVEY_INFO_IN_USE for current channel on
|
||||
survey
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -3975,6 +3975,9 @@ static int ath10k_get_survey(struct ieee
|
||||
@@ -4044,6 +4044,9 @@ static int ath10k_get_survey(struct ieee
|
||||
|
||||
survey->channel = &sband->channels[idx];
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:08 +0530
|
||||
Subject: [PATCH] ath9k: Use sta_state() callback
|
||||
|
||||
Instead of using the sta_add()/sta_remove() callbacks,
|
||||
use the sta_state() callback since this gives
|
||||
more fine-grained control.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -1547,6 +1547,31 @@ static int ath9k_sta_remove(struct ieee8
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int ath9k_sta_state(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_vif *vif,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ enum ieee80211_sta_state old_state,
|
||||
+ enum ieee80211_sta_state new_state)
|
||||
+{
|
||||
+ struct ath_softc *sc = hw->priv;
|
||||
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (old_state == IEEE80211_STA_AUTH &&
|
||||
+ new_state == IEEE80211_STA_ASSOC) {
|
||||
+ ret = ath9k_sta_add(hw, vif, sta);
|
||||
+ ath_dbg(common, CONFIG,
|
||||
+ "Add station: %pM\n", sta->addr);
|
||||
+ } else if (old_state == IEEE80211_STA_ASSOC &&
|
||||
+ new_state == IEEE80211_STA_AUTH) {
|
||||
+ ret = ath9k_sta_remove(hw, vif, sta);
|
||||
+ ath_dbg(common, CONFIG,
|
||||
+ "Remove station: %pM\n", sta->addr);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void ath9k_sta_set_tx_filter(struct ath_hw *ah,
|
||||
struct ath_node *an,
|
||||
bool set)
|
||||
@@ -2471,8 +2496,7 @@ struct ieee80211_ops ath9k_ops = {
|
||||
.remove_interface = ath9k_remove_interface,
|
||||
.config = ath9k_config,
|
||||
.configure_filter = ath9k_configure_filter,
|
||||
- .sta_add = ath9k_sta_add,
|
||||
- .sta_remove = ath9k_sta_remove,
|
||||
+ .sta_state = ath9k_sta_state,
|
||||
.sta_notify = ath9k_sta_notify,
|
||||
.conf_tx = ath9k_conf_tx,
|
||||
.bss_info_changed = ath9k_bss_info_changed,
|
|
@ -1,82 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:09 +0530
|
||||
Subject: [PATCH] ath9k: Enable multi-channel properly
|
||||
|
||||
In MCC mode, currently the decision to enable
|
||||
the multi-channel state machine is done
|
||||
based on the association status if one of
|
||||
the interfaces assigned to a context is in
|
||||
station mode.
|
||||
|
||||
This allows the driver to switch to the other
|
||||
context before the current station is able to
|
||||
complete the 4-way handshake in case it is
|
||||
required and this causes problems.
|
||||
|
||||
Instead, enable multi-channel mode when the
|
||||
station moves to the authorized state. This
|
||||
disallows an early switch to the other channel.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -362,7 +362,7 @@ enum ath_chanctx_event {
|
||||
ATH_CHANCTX_EVENT_BEACON_SENT,
|
||||
ATH_CHANCTX_EVENT_TSF_TIMER,
|
||||
ATH_CHANCTX_EVENT_BEACON_RECEIVED,
|
||||
- ATH_CHANCTX_EVENT_ASSOC,
|
||||
+ ATH_CHANCTX_EVENT_AUTHORIZED,
|
||||
ATH_CHANCTX_EVENT_SWITCH,
|
||||
ATH_CHANCTX_EVENT_ASSIGN,
|
||||
ATH_CHANCTX_EVENT_UNASSIGN,
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -171,7 +171,7 @@ static const char *chanctx_event_string(
|
||||
case_rtn_string(ATH_CHANCTX_EVENT_BEACON_SENT);
|
||||
case_rtn_string(ATH_CHANCTX_EVENT_TSF_TIMER);
|
||||
case_rtn_string(ATH_CHANCTX_EVENT_BEACON_RECEIVED);
|
||||
- case_rtn_string(ATH_CHANCTX_EVENT_ASSOC);
|
||||
+ case_rtn_string(ATH_CHANCTX_EVENT_AUTHORIZED);
|
||||
case_rtn_string(ATH_CHANCTX_EVENT_SWITCH);
|
||||
case_rtn_string(ATH_CHANCTX_EVENT_ASSIGN);
|
||||
case_rtn_string(ATH_CHANCTX_EVENT_UNASSIGN);
|
||||
@@ -510,7 +510,7 @@ void ath_chanctx_event(struct ath_softc
|
||||
|
||||
ath_chanctx_setup_timer(sc, tsf_time);
|
||||
break;
|
||||
- case ATH_CHANCTX_EVENT_ASSOC:
|
||||
+ case ATH_CHANCTX_EVENT_AUTHORIZED:
|
||||
if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE ||
|
||||
avp->chanctx != sc->cur_chan)
|
||||
break;
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -1569,6 +1569,13 @@ static int ath9k_sta_state(struct ieee80
|
||||
"Remove station: %pM\n", sta->addr);
|
||||
}
|
||||
|
||||
+ if (ath9k_is_chanctx_enabled()) {
|
||||
+ if (old_state == IEEE80211_STA_ASSOC &&
|
||||
+ new_state == IEEE80211_STA_AUTHORIZED)
|
||||
+ ath_chanctx_event(sc, vif,
|
||||
+ ATH_CHANCTX_EVENT_AUTHORIZED);
|
||||
+ }
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1761,12 +1768,6 @@ static void ath9k_bss_info_changed(struc
|
||||
avp->assoc = bss_conf->assoc;
|
||||
|
||||
ath9k_calculate_summary_state(sc, avp->chanctx);
|
||||
-
|
||||
- if (ath9k_is_chanctx_enabled()) {
|
||||
- if (bss_conf->assoc)
|
||||
- ath_chanctx_event(sc, vif,
|
||||
- ATH_CHANCTX_EVENT_ASSOC);
|
||||
- }
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_IBSS) {
|
|
@ -1,37 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:10 +0530
|
||||
Subject: [PATCH] ath9k: Process beacons properly
|
||||
|
||||
When the current operating channel context has
|
||||
been marked as ATH_CHANCTX_STATE_FORCE_ACTIVE,
|
||||
do not process beacons that might be received,
|
||||
since we have to wait for the station to become
|
||||
authorized.
|
||||
|
||||
Also, since the cached TSF value will be zero
|
||||
initially do not rearm the timer in this
|
||||
case when a beacon is received, since it results
|
||||
in spurious values.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -495,10 +495,15 @@ void ath_chanctx_event(struct ath_softc
|
||||
sc->cur_chan == &sc->offchannel.chan)
|
||||
break;
|
||||
|
||||
- ath_chanctx_adjust_tbtt_delta(sc);
|
||||
sc->sched.beacon_pending = false;
|
||||
sc->sched.beacon_miss = 0;
|
||||
|
||||
+ if (sc->sched.state == ATH_CHANCTX_STATE_FORCE_ACTIVE ||
|
||||
+ !sc->cur_chan->tsf_val)
|
||||
+ break;
|
||||
+
|
||||
+ ath_chanctx_adjust_tbtt_delta(sc);
|
||||
+
|
||||
/* TSF time might have been updated by the incoming beacon,
|
||||
* need update the channel switch timer to reflect the change.
|
||||
*/
|
|
@ -1,108 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:11 +0530
|
||||
Subject: [PATCH] ath9k: Unify reset API
|
||||
|
||||
Instead of having ath_reset_internal() and ath_reset()
|
||||
as two separate calls to perform a HW reset, have
|
||||
one function. This makes sure that the behavior will
|
||||
be the same at all callsites.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -540,7 +540,6 @@ static inline void ath_chanctx_check_act
|
||||
|
||||
#endif /* CPTCFG_ATH9K_CHANNEL_CONTEXT */
|
||||
|
||||
-int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan);
|
||||
void ath_startrecv(struct ath_softc *sc);
|
||||
bool ath_stoprecv(struct ath_softc *sc);
|
||||
u32 ath_calcrxfilter(struct ath_softc *sc);
|
||||
@@ -1069,7 +1068,7 @@ void ath9k_tasklet(unsigned long data);
|
||||
int ath_cabq_update(struct ath_softc *);
|
||||
u8 ath9k_parse_mpdudensity(u8 mpdudensity);
|
||||
irqreturn_t ath_isr(int irq, void *dev);
|
||||
-int ath_reset(struct ath_softc *sc);
|
||||
+int ath_reset(struct ath_softc *sc, struct ath9k_channel *hchan);
|
||||
void ath_cancel_work(struct ath_softc *sc);
|
||||
void ath_restart_work(struct ath_softc *sc);
|
||||
int ath9k_init_device(u16 devid, struct ath_softc *sc,
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -66,7 +66,7 @@ static int ath_set_channel(struct ath_so
|
||||
}
|
||||
|
||||
hchan = &sc->sc_ah->channels[pos];
|
||||
- r = ath_reset_internal(sc, hchan);
|
||||
+ r = ath_reset(sc, hchan);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -270,7 +270,7 @@ static bool ath_complete_reset(struct at
|
||||
return true;
|
||||
}
|
||||
|
||||
-int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
|
||||
+static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
@@ -598,12 +598,12 @@ chip_reset:
|
||||
#undef SCHED_INTR
|
||||
}
|
||||
|
||||
-int ath_reset(struct ath_softc *sc)
|
||||
+int ath_reset(struct ath_softc *sc, struct ath9k_channel *hchan)
|
||||
{
|
||||
int r;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
- r = ath_reset_internal(sc, NULL);
|
||||
+ r = ath_reset_internal(sc, hchan);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
return r;
|
||||
@@ -623,7 +623,9 @@ void ath_reset_work(struct work_struct *
|
||||
{
|
||||
struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work);
|
||||
|
||||
- ath_reset(sc);
|
||||
+ ath9k_ps_wakeup(sc);
|
||||
+ ath_reset_internal(sc, NULL);
|
||||
+ ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
/**********************/
|
||||
@@ -2044,7 +2046,7 @@ void __ath9k_flush(struct ieee80211_hw *
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
if (!drain_txq)
|
||||
- ath_reset(sc);
|
||||
+ ath_reset(sc, NULL);
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath9k/tx99.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/tx99.c
|
||||
@@ -99,7 +99,7 @@ static struct sk_buff *ath9k_build_tx99_
|
||||
|
||||
static void ath9k_tx99_deinit(struct ath_softc *sc)
|
||||
{
|
||||
- ath_reset(sc);
|
||||
+ ath_reset(sc, NULL);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_tx99_stop(sc);
|
||||
@@ -127,7 +127,7 @@ static int ath9k_tx99_init(struct ath_so
|
||||
memset(&txctl, 0, sizeof(txctl));
|
||||
txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
|
||||
|
||||
- ath_reset(sc);
|
||||
+ ath_reset(sc, NULL);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:12 +0530
|
||||
Subject: [PATCH] ath9k: Set ATH_OP_HW_RESET before HW reset
|
||||
|
||||
When a HW reset is done, the interrupt tasklet is
|
||||
disabled before ISRs are disabled in the HW. This
|
||||
allows a small window where the HW can still generate
|
||||
interrupts. Since the tasklet is disabled and not killed,
|
||||
it is not scheduled but deferred for execution at a later
|
||||
time.
|
||||
|
||||
This happens because ATH_OP_HW_RESET is not set when ath_reset()
|
||||
is called. When the hw_reset_work workqueue is used, this
|
||||
problem doesn't arise because ATH_OP_HW_RESET is set
|
||||
and the ISR bails out.
|
||||
|
||||
Set ATH_OP_HW_RESET properly in ath_reset() to avoid
|
||||
this race - all the ath_reset_internal() callers have
|
||||
been converted to use ath_reset() in the previous patch.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -598,10 +598,17 @@ chip_reset:
|
||||
#undef SCHED_INTR
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * This function is called when a HW reset cannot be deferred
|
||||
+ * and has to be immediate.
|
||||
+ */
|
||||
int ath_reset(struct ath_softc *sc, struct ath9k_channel *hchan)
|
||||
{
|
||||
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
int r;
|
||||
|
||||
+ set_bit(ATH_OP_HW_RESET, &common->op_flags);
|
||||
+
|
||||
ath9k_ps_wakeup(sc);
|
||||
r = ath_reset_internal(sc, hchan);
|
||||
ath9k_ps_restore(sc);
|
||||
@@ -609,6 +616,11 @@ int ath_reset(struct ath_softc *sc, stru
|
||||
return r;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * When a HW reset can be deferred, it is added to the
|
||||
+ * hw_reset_work workqueue, but we set ATH_OP_HW_RESET before
|
||||
+ * queueing.
|
||||
+ */
|
||||
void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
|
@ -1,29 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:13 +0530
|
||||
Subject: [PATCH] ath9k: Disable beacon tasklet during reset
|
||||
|
||||
When a chip reset is done, all running timers,
|
||||
tasklets etc. are stopped but the beacon tasklet
|
||||
is left running. Fix this.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -281,6 +281,7 @@ static int ath_reset_internal(struct ath
|
||||
__ath_cancel_work(sc);
|
||||
|
||||
tasklet_disable(&sc->intr_tq);
|
||||
+ tasklet_disable(&sc->bcon_tasklet);
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
if (!sc->cur_chan->offchannel) {
|
||||
@@ -326,6 +327,7 @@ static int ath_reset_internal(struct ath
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
+ tasklet_enable(&sc->bcon_tasklet);
|
||||
tasklet_enable(&sc->intr_tq);
|
||||
|
||||
return r;
|
|
@ -1,36 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:14 +0530
|
||||
Subject: [PATCH] ath9k: Clear NoA schedule properly
|
||||
|
||||
When an active context transitions to inactive
|
||||
state, the NoA schedule needs to be removed
|
||||
for the context that has beaconing enabled.
|
||||
Not doing this will affect p2p clients.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -356,6 +356,21 @@ void ath_chanctx_event(struct ath_softc
|
||||
"Move chanctx state from WAIT_FOR_TIMER to WAIT_FOR_BEACON\n");
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * When a context becomes inactive, for example,
|
||||
+ * disassociation of a station context, the NoA
|
||||
+ * attribute needs to be removed from subsequent
|
||||
+ * beacons.
|
||||
+ */
|
||||
+ if (!ctx->active && avp->noa_duration &&
|
||||
+ sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON) {
|
||||
+ avp->noa_duration = 0;
|
||||
+ avp->periodic_noa = false;
|
||||
+
|
||||
+ ath_dbg(common, CHAN_CTX,
|
||||
+ "Clearing NoA schedule\n");
|
||||
+ }
|
||||
+
|
||||
if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON)
|
||||
break;
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:15 +0530
|
||||
Subject: [PATCH] ath9k: Use configurable timeout for flush
|
||||
|
||||
The timeout value for flushing the TX queues
|
||||
is hardcoded at 200ms right now. Use a channel
|
||||
context-specific value instead to allow adjustments
|
||||
to the timeout in case MCC is enabled.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -345,6 +345,7 @@ struct ath_chanctx {
|
||||
u64 tsf_val;
|
||||
u32 last_beacon;
|
||||
|
||||
+ int flush_timeout;
|
||||
u16 txpower;
|
||||
bool offchannel;
|
||||
bool stopped;
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -117,6 +117,7 @@ void ath_chanctx_init(struct ath_softc *
|
||||
cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20);
|
||||
INIT_LIST_HEAD(&ctx->vifs);
|
||||
ctx->txpower = ATH_TXPOWER_MAX;
|
||||
+ ctx->flush_timeout = HZ / 5; /* 200ms */
|
||||
for (j = 0; j < ARRAY_SIZE(ctx->acq); j++)
|
||||
INIT_LIST_HEAD(&ctx->acq[j]);
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -2034,7 +2034,7 @@ void __ath9k_flush(struct ieee80211_hw *
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
- int timeout = HZ / 5; /* 200 ms */
|
||||
+ int timeout;
|
||||
bool drain_txq;
|
||||
|
||||
cancel_delayed_work_sync(&sc->tx_complete_work);
|
||||
@@ -2049,6 +2049,13 @@ void __ath9k_flush(struct ieee80211_hw *
|
||||
return;
|
||||
}
|
||||
|
||||
+ spin_lock_bh(&sc->chan_lock);
|
||||
+ timeout = sc->cur_chan->flush_timeout;
|
||||
+ spin_unlock_bh(&sc->chan_lock);
|
||||
+
|
||||
+ ath_dbg(common, CHAN_CTX,
|
||||
+ "Flush timeout: %d\n", jiffies_to_msecs(timeout));
|
||||
+
|
||||
if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc),
|
||||
timeout) > 0)
|
||||
drop = false;
|
|
@ -1,68 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:16 +0530
|
||||
Subject: [PATCH] ath9k: Fix MCC flush timeout
|
||||
|
||||
In MCC mode, the duration for a channel context
|
||||
is half the beacon interval and having a large
|
||||
flush timeout will adversely affect GO operation,
|
||||
since the default value of 200ms will overshoot
|
||||
the advertised NoA absence duration.
|
||||
|
||||
The scheduler initiates a channel context switch
|
||||
only when the slot duration for the current
|
||||
context expires, so there is no possibility of
|
||||
having a fixed timeout for flush.
|
||||
|
||||
Since the channel_switch_time is added to the
|
||||
absence duration when the GO sets up the NoA
|
||||
attribute, this is the maximum time that we
|
||||
have to flush the TX queues. The duration is very
|
||||
small, but we don't have a choice in MCC mode.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -199,6 +199,7 @@ static const char *chanctx_state_string(
|
||||
void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
+ struct ath_chanctx *ictx;
|
||||
struct ath_vif *avp;
|
||||
bool active = false;
|
||||
u8 n_active = 0;
|
||||
@@ -206,6 +207,8 @@ void ath_chanctx_check_active(struct ath
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
+ ictx = ctx;
|
||||
+
|
||||
list_for_each_entry(avp, &ctx->vifs, list) {
|
||||
struct ieee80211_vif *vif = avp->vif;
|
||||
|
||||
@@ -228,12 +231,23 @@ void ath_chanctx_check_active(struct ath
|
||||
n_active++;
|
||||
}
|
||||
|
||||
+ spin_lock_bh(&sc->chan_lock);
|
||||
+
|
||||
if (n_active <= 1) {
|
||||
+ ictx->flush_timeout = HZ / 5;
|
||||
clear_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags);
|
||||
+ spin_unlock_bh(&sc->chan_lock);
|
||||
return;
|
||||
}
|
||||
- if (test_and_set_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
|
||||
+
|
||||
+ ictx->flush_timeout = usecs_to_jiffies(sc->sched.channel_switch_time);
|
||||
+
|
||||
+ if (test_and_set_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) {
|
||||
+ spin_unlock_bh(&sc->chan_lock);
|
||||
return;
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_bh(&sc->chan_lock);
|
||||
|
||||
if (ath9k_is_chanctx_enabled()) {
|
||||
ath_chanctx_event(sc, NULL,
|
|
@ -1,43 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:17 +0530
|
||||
Subject: [PATCH] ath9k: Fix offchannel flush timeout
|
||||
|
||||
An offchannel operation also needs to have
|
||||
a flush timeout that doesn't exceed the NoA
|
||||
absence duration of a GO context, so use
|
||||
channel_switch_time. The first offchannel
|
||||
operation is set a flush timeout of 10ms since
|
||||
channel_switch_time will be zero.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -207,6 +207,26 @@ void ath_chanctx_check_active(struct ath
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
+ if (ctx == &sc->offchannel.chan) {
|
||||
+ spin_lock_bh(&sc->chan_lock);
|
||||
+
|
||||
+ if (likely(sc->sched.channel_switch_time))
|
||||
+ ctx->flush_timeout =
|
||||
+ usecs_to_jiffies(sc->sched.channel_switch_time);
|
||||
+ else
|
||||
+ ctx->flush_timeout =
|
||||
+ msecs_to_jiffies(10);
|
||||
+
|
||||
+ spin_unlock_bh(&sc->chan_lock);
|
||||
+
|
||||
+ /*
|
||||
+ * There is no need to iterate over the
|
||||
+ * active/assigned channel contexts if
|
||||
+ * the current context is offchannel.
|
||||
+ */
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
ictx = ctx;
|
||||
|
||||
list_for_each_entry(avp, &ctx->vifs, list) {
|
|
@ -1,125 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:18 +0530
|
||||
Subject: [PATCH] ath9k: Check for pending frames properly
|
||||
|
||||
Pending frames in the driver can be present
|
||||
either in the HW queues or SW. ath9k_has_pending_frames()
|
||||
currently checks for the HW queues first and then
|
||||
checks if any ACs are queued in the driver.
|
||||
|
||||
In MCC mode, we need to check the HW queues alone, since
|
||||
the SW queues are just marked as 'stopped' - they will
|
||||
be processed in the next context switch. But since we
|
||||
don't differentiate this now, mention whether we want
|
||||
to check if there are frames in the SW queues.
|
||||
|
||||
* The flush() callback checks both HW and SW queues.
|
||||
* The tx_frames_pending() callback does the same.
|
||||
* The call to __ath9k_flush() in MCC mode checks HW queues alone.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -715,7 +715,8 @@ int ath_update_survey_stats(struct ath_s
|
||||
void ath_update_survey_nf(struct ath_softc *sc, int channel);
|
||||
void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
|
||||
void ath_ps_full_sleep(unsigned long data);
|
||||
-void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
|
||||
+void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
|
||||
+ bool sw_pending);
|
||||
|
||||
/**********/
|
||||
/* BTCOEX */
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -1137,10 +1137,11 @@ void ath_chanctx_set_next(struct ath_sof
|
||||
ath9k_chanctx_stop_queues(sc, sc->cur_chan);
|
||||
queues_stopped = true;
|
||||
|
||||
- __ath9k_flush(sc->hw, ~0, true);
|
||||
+ __ath9k_flush(sc->hw, ~0, true, false);
|
||||
|
||||
if (ath_chanctx_send_ps_frame(sc, true))
|
||||
- __ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO), false);
|
||||
+ __ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO),
|
||||
+ false, false);
|
||||
|
||||
send_ps = true;
|
||||
spin_lock_bh(&sc->chan_lock);
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -54,7 +54,8 @@ u8 ath9k_parse_mpdudensity(u8 mpdudensit
|
||||
}
|
||||
}
|
||||
|
||||
-static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq)
|
||||
+static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq,
|
||||
+ bool sw_pending)
|
||||
{
|
||||
bool pending = false;
|
||||
|
||||
@@ -65,6 +66,9 @@ static bool ath9k_has_pending_frames(str
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if (!sw_pending)
|
||||
+ goto out;
|
||||
+
|
||||
if (txq->mac80211_qnum >= 0) {
|
||||
struct list_head *list;
|
||||
|
||||
@@ -2003,7 +2007,8 @@ static void ath9k_set_coverage_class(str
|
||||
mutex_unlock(&sc->mutex);
|
||||
}
|
||||
|
||||
-static bool ath9k_has_tx_pending(struct ath_softc *sc)
|
||||
+static bool ath9k_has_tx_pending(struct ath_softc *sc,
|
||||
+ bool sw_pending)
|
||||
{
|
||||
int i, npend = 0;
|
||||
|
||||
@@ -2011,7 +2016,8 @@ static bool ath9k_has_tx_pending(struct
|
||||
if (!ATH_TXQ_SETUP(sc, i))
|
||||
continue;
|
||||
|
||||
- npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
|
||||
+ npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i],
|
||||
+ sw_pending);
|
||||
if (npend)
|
||||
break;
|
||||
}
|
||||
@@ -2025,11 +2031,12 @@ static void ath9k_flush(struct ieee80211
|
||||
struct ath_softc *sc = hw->priv;
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
- __ath9k_flush(hw, queues, drop);
|
||||
+ __ath9k_flush(hw, queues, drop, true);
|
||||
mutex_unlock(&sc->mutex);
|
||||
}
|
||||
|
||||
-void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||
+void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
|
||||
+ bool sw_pending)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@@ -2056,7 +2063,7 @@ void __ath9k_flush(struct ieee80211_hw *
|
||||
ath_dbg(common, CHAN_CTX,
|
||||
"Flush timeout: %d\n", jiffies_to_msecs(timeout));
|
||||
|
||||
- if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc),
|
||||
+ if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc, sw_pending),
|
||||
timeout) > 0)
|
||||
drop = false;
|
||||
|
||||
@@ -2079,7 +2086,7 @@ static bool ath9k_tx_frames_pending(stru
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
|
||||
- return ath9k_has_tx_pending(sc);
|
||||
+ return ath9k_has_tx_pending(sc, true);
|
||||
}
|
||||
|
||||
static int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
|
|
@ -1,33 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:19 +0530
|
||||
Subject: [PATCH] ath9k: Send AUTHORIZED event only for station mode
|
||||
|
||||
ATH_CHANCTX_EVENT_AUTHORIZED is required to trigger
|
||||
the MCC scheduler when a station interface becomes
|
||||
authorized. But, since the driver gets station state
|
||||
notifications when the current operating mode is AP
|
||||
too, make sure that we send ATH_CHANCTX_EVENT_AUTHORIZED
|
||||
only when the interface is in station mode.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -1590,10 +1590,12 @@ static int ath9k_sta_state(struct ieee80
|
||||
}
|
||||
|
||||
if (ath9k_is_chanctx_enabled()) {
|
||||
- if (old_state == IEEE80211_STA_ASSOC &&
|
||||
- new_state == IEEE80211_STA_AUTHORIZED)
|
||||
- ath_chanctx_event(sc, vif,
|
||||
- ATH_CHANCTX_EVENT_AUTHORIZED);
|
||||
+ if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
+ if (old_state == IEEE80211_STA_ASSOC &&
|
||||
+ new_state == IEEE80211_STA_AUTHORIZED)
|
||||
+ ath_chanctx_event(sc, vif,
|
||||
+ ATH_CHANCTX_EVENT_AUTHORIZED);
|
||||
+ }
|
||||
}
|
||||
|
||||
return ret;
|
|
@ -1,65 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:20 +0530
|
||||
Subject: [PATCH] ath9k: Fix address management
|
||||
|
||||
Since both the arguments need to satisfy
|
||||
the alignment requirements of ether_addr_copy(),
|
||||
use memcpy() in cases where there will be no
|
||||
big performance benefit and make sure that
|
||||
ether_addr_copy() calls use properly aligned
|
||||
arguments.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath.h
|
||||
+++ b/drivers/net/wireless/ath/ath.h
|
||||
@@ -147,7 +147,7 @@ struct ath_common {
|
||||
u16 cachelsz;
|
||||
u16 curaid;
|
||||
u8 macaddr[ETH_ALEN];
|
||||
- u8 curbssid[ETH_ALEN];
|
||||
+ u8 curbssid[ETH_ALEN] __aligned(2);
|
||||
u8 bssidmask[ETH_ALEN];
|
||||
|
||||
u32 rx_bufsize;
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -595,7 +595,7 @@ struct ath_vif {
|
||||
u16 seq_no;
|
||||
|
||||
/* BSS info */
|
||||
- u8 bssid[ETH_ALEN];
|
||||
+ u8 bssid[ETH_ALEN] __aligned(2);
|
||||
u16 aid;
|
||||
bool assoc;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -1057,7 +1057,7 @@ static void ath9k_set_offchannel_state(s
|
||||
|
||||
eth_zero_addr(common->curbssid);
|
||||
eth_broadcast_addr(common->bssidmask);
|
||||
- ether_addr_copy(common->macaddr, vif->addr);
|
||||
+ memcpy(common->macaddr, vif->addr, ETH_ALEN);
|
||||
common->curaid = 0;
|
||||
ah->opmode = vif->type;
|
||||
ah->imask &= ~ATH9K_INT_SWBA;
|
||||
@@ -1098,7 +1098,7 @@ void ath9k_calculate_summary_state(struc
|
||||
ath9k_calculate_iter_data(sc, ctx, &iter_data);
|
||||
|
||||
if (iter_data.has_hw_macaddr)
|
||||
- ether_addr_copy(common->macaddr, iter_data.hw_macaddr);
|
||||
+ memcpy(common->macaddr, iter_data.hw_macaddr, ETH_ALEN);
|
||||
|
||||
memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
|
||||
ath_hw_setbssidmask(common);
|
||||
@@ -1785,7 +1785,7 @@ static void ath9k_bss_info_changed(struc
|
||||
ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n",
|
||||
bss_conf->bssid, bss_conf->assoc);
|
||||
|
||||
- ether_addr_copy(avp->bssid, bss_conf->bssid);
|
||||
+ memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
|
||||
avp->aid = bss_conf->aid;
|
||||
avp->assoc = bss_conf->assoc;
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:21 +0530
|
||||
Subject: [PATCH] ath9k: Add a function to check for an active GO
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -469,6 +469,7 @@ void ath_chanctx_set_next(struct ath_sof
|
||||
void ath_offchannel_next(struct ath_softc *sc);
|
||||
void ath_scan_complete(struct ath_softc *sc, bool abort);
|
||||
void ath_roc_complete(struct ath_softc *sc, bool abort);
|
||||
+struct ath_chanctx* ath_is_go_chanctx_present(struct ath_softc *sc);
|
||||
|
||||
#else
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -146,6 +146,36 @@ void ath_chanctx_set_channel(struct ath_
|
||||
|
||||
#ifdef CPTCFG_ATH9K_CHANNEL_CONTEXT
|
||||
|
||||
+/*************/
|
||||
+/* Utilities */
|
||||
+/*************/
|
||||
+
|
||||
+struct ath_chanctx* ath_is_go_chanctx_present(struct ath_softc *sc)
|
||||
+{
|
||||
+ struct ath_chanctx *ctx;
|
||||
+ struct ath_vif *avp;
|
||||
+ struct ieee80211_vif *vif;
|
||||
+
|
||||
+ spin_lock_bh(&sc->chan_lock);
|
||||
+
|
||||
+ ath_for_each_chanctx(sc, ctx) {
|
||||
+ if (!ctx->active)
|
||||
+ continue;
|
||||
+
|
||||
+ list_for_each_entry(avp, &ctx->vifs, list) {
|
||||
+ vif = avp->vif;
|
||||
+
|
||||
+ if (ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_P2P_GO) {
|
||||
+ spin_unlock_bh(&sc->chan_lock);
|
||||
+ return ctx;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_bh(&sc->chan_lock);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
/**********************************************************/
|
||||
/* Functions to handle the channel context state machine. */
|
||||
/**********************************************************/
|
|
@ -1,134 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:22 +0530
|
||||
Subject: [PATCH] ath9k: Check for active GO in mgd_prepare_tx()
|
||||
|
||||
If a GO interface is active when we receive a
|
||||
mgd_prepare_tx() call, then we need to send
|
||||
out a new NoA before switching to a new context.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -385,6 +385,7 @@ struct ath_chanctx_sched {
|
||||
bool wait_switch;
|
||||
bool force_noa_update;
|
||||
bool extend_absence;
|
||||
+ bool mgd_prepare_tx;
|
||||
enum ath_chanctx_state state;
|
||||
u8 beacon_miss;
|
||||
|
||||
@@ -977,6 +978,7 @@ struct ath_softc {
|
||||
struct ath_chanctx_sched sched;
|
||||
struct ath_offchannel offchannel;
|
||||
struct ath_chanctx *next_chan;
|
||||
+ struct completion go_beacon;
|
||||
#endif
|
||||
|
||||
unsigned long driver_data;
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -421,6 +421,9 @@ void ath_chanctx_event(struct ath_softc
|
||||
"Move chanctx state from WAIT_FOR_TIMER to WAIT_FOR_BEACON\n");
|
||||
}
|
||||
|
||||
+ if (sc->sched.mgd_prepare_tx)
|
||||
+ sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
|
||||
+
|
||||
/*
|
||||
* When a context becomes inactive, for example,
|
||||
* disassociation of a station context, the NoA
|
||||
@@ -547,6 +550,15 @@ void ath_chanctx_event(struct ath_softc
|
||||
}
|
||||
|
||||
sc->sched.beacon_pending = false;
|
||||
+
|
||||
+ if (sc->sched.mgd_prepare_tx) {
|
||||
+ sc->sched.mgd_prepare_tx = false;
|
||||
+ complete(&sc->go_beacon);
|
||||
+ ath_dbg(common, CHAN_CTX,
|
||||
+ "Beacon sent, complete go_beacon\n");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON)
|
||||
break;
|
||||
|
||||
@@ -1263,6 +1275,8 @@ void ath9k_init_channel_context(struct a
|
||||
(unsigned long)sc);
|
||||
setup_timer(&sc->sched.timer, ath_chanctx_timer,
|
||||
(unsigned long)sc);
|
||||
+
|
||||
+ init_completion(&sc->go_beacon);
|
||||
}
|
||||
|
||||
void ath9k_deinit_channel_context(struct ath_softc *sc)
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -2474,7 +2474,11 @@ static void ath9k_mgd_prepare_tx(struct
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_vif *avp = (struct ath_vif *) vif->drv_priv;
|
||||
+ struct ath_beacon_config *cur_conf;
|
||||
+ struct ath_chanctx *go_ctx;
|
||||
+ unsigned long timeout;
|
||||
bool changed = false;
|
||||
+ u32 beacon_int;
|
||||
|
||||
if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
|
||||
return;
|
||||
@@ -2485,19 +2489,46 @@ static void ath9k_mgd_prepare_tx(struct
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
spin_lock_bh(&sc->chan_lock);
|
||||
- if (sc->next_chan || (sc->cur_chan != avp->chanctx)) {
|
||||
- sc->next_chan = avp->chanctx;
|
||||
+ if (sc->next_chan || (sc->cur_chan != avp->chanctx))
|
||||
changed = true;
|
||||
+ spin_unlock_bh(&sc->chan_lock);
|
||||
+
|
||||
+ if (!changed)
|
||||
+ goto out;
|
||||
+
|
||||
+ go_ctx = ath_is_go_chanctx_present(sc);
|
||||
+
|
||||
+ if (go_ctx) {
|
||||
+ /*
|
||||
+ * Wait till the GO interface gets a chance
|
||||
+ * to send out an NoA.
|
||||
+ */
|
||||
+ spin_lock_bh(&sc->chan_lock);
|
||||
+ sc->sched.mgd_prepare_tx = true;
|
||||
+ cur_conf = &go_ctx->beacon;
|
||||
+ beacon_int = TU_TO_USEC(cur_conf->beacon_interval);
|
||||
+ spin_unlock_bh(&sc->chan_lock);
|
||||
+
|
||||
+ timeout = usecs_to_jiffies(beacon_int);
|
||||
+ init_completion(&sc->go_beacon);
|
||||
+
|
||||
+ if (wait_for_completion_timeout(&sc->go_beacon,
|
||||
+ timeout) == 0)
|
||||
+ ath_dbg(common, CHAN_CTX,
|
||||
+ "Failed to send new NoA\n");
|
||||
}
|
||||
+
|
||||
ath_dbg(common, CHAN_CTX,
|
||||
- "%s: Set chanctx state to FORCE_ACTIVE, changed: %d\n",
|
||||
- __func__, changed);
|
||||
+ "%s: Set chanctx state to FORCE_ACTIVE for vif: %pM\n",
|
||||
+ __func__, vif->addr);
|
||||
+
|
||||
+ spin_lock_bh(&sc->chan_lock);
|
||||
+ sc->next_chan = avp->chanctx;
|
||||
sc->sched.state = ATH_CHANCTX_STATE_FORCE_ACTIVE;
|
||||
spin_unlock_bh(&sc->chan_lock);
|
||||
|
||||
- if (changed)
|
||||
- ath_chanctx_set_next(sc, true);
|
||||
-
|
||||
+ ath_chanctx_set_next(sc, true);
|
||||
+out:
|
||||
mutex_unlock(&sc->mutex);
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:23 +0530
|
||||
Subject: [PATCH] ath9k: Use a helper function for offchannel NoA
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -366,6 +366,32 @@ static void ath_chanctx_setup_timer(stru
|
||||
"Setup chanctx timer with timeout: %d ms\n", jiffies_to_msecs(tsf_time));
|
||||
}
|
||||
|
||||
+static void ath_chanctx_offchannel_noa(struct ath_softc *sc,
|
||||
+ struct ath_chanctx *ctx,
|
||||
+ struct ath_vif *avp,
|
||||
+ u32 tsf_time)
|
||||
+{
|
||||
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
+
|
||||
+ avp->noa_index++;
|
||||
+ avp->offchannel_start = tsf_time;
|
||||
+ avp->offchannel_duration = sc->sched.offchannel_duration;
|
||||
+
|
||||
+ ath_dbg(common, CHAN_CTX,
|
||||
+ "offchannel noa_duration: %d, noa_start: %d, noa_index: %d\n",
|
||||
+ avp->offchannel_duration,
|
||||
+ avp->offchannel_start,
|
||||
+ avp->noa_index);
|
||||
+
|
||||
+ /*
|
||||
+ * When multiple contexts are active, the NoA
|
||||
+ * has to be recalculated and advertised after
|
||||
+ * an offchannel operation.
|
||||
+ */
|
||||
+ if (ctx->active && avp->noa_duration)
|
||||
+ avp->noa_duration = 0;
|
||||
+}
|
||||
+
|
||||
void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
|
||||
enum ath_chanctx_event ev)
|
||||
{
|
||||
@@ -461,24 +487,7 @@ void ath_chanctx_event(struct ath_softc
|
||||
* values and increment the index.
|
||||
*/
|
||||
if (sc->next_chan == &sc->offchannel.chan) {
|
||||
- avp->noa_index++;
|
||||
- avp->offchannel_start = tsf_time;
|
||||
- avp->offchannel_duration = sc->sched.offchannel_duration;
|
||||
-
|
||||
- ath_dbg(common, CHAN_CTX,
|
||||
- "offchannel noa_duration: %d, noa_start: %d, noa_index: %d\n",
|
||||
- avp->offchannel_duration,
|
||||
- avp->offchannel_start,
|
||||
- avp->noa_index);
|
||||
-
|
||||
- /*
|
||||
- * When multiple contexts are active, the NoA
|
||||
- * has to be recalculated and advertised after
|
||||
- * an offchannel operation.
|
||||
- */
|
||||
- if (ctx->active && avp->noa_duration)
|
||||
- avp->noa_duration = 0;
|
||||
-
|
||||
+ ath_chanctx_offchannel_noa(sc, ctx, avp, tsf_time);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:24 +0530
|
||||
Subject: [PATCH] ath9k: Use a helper function to set NoA
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -392,6 +392,39 @@ static void ath_chanctx_offchannel_noa(s
|
||||
avp->noa_duration = 0;
|
||||
}
|
||||
|
||||
+static void ath_chanctx_set_periodic_noa(struct ath_softc *sc,
|
||||
+ struct ath_vif *avp,
|
||||
+ struct ath_beacon_config *cur_conf,
|
||||
+ u32 tsf_time,
|
||||
+ u32 beacon_int)
|
||||
+{
|
||||
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
+
|
||||
+ avp->noa_index++;
|
||||
+ avp->noa_start = tsf_time;
|
||||
+
|
||||
+ if (sc->sched.extend_absence)
|
||||
+ avp->noa_duration = (3 * beacon_int / 2) +
|
||||
+ sc->sched.channel_switch_time;
|
||||
+ else
|
||||
+ avp->noa_duration =
|
||||
+ TU_TO_USEC(cur_conf->beacon_interval) / 2 +
|
||||
+ sc->sched.channel_switch_time;
|
||||
+
|
||||
+ if (test_bit(ATH_OP_SCANNING, &common->op_flags) ||
|
||||
+ sc->sched.extend_absence)
|
||||
+ avp->periodic_noa = false;
|
||||
+ else
|
||||
+ avp->periodic_noa = true;
|
||||
+
|
||||
+ ath_dbg(common, CHAN_CTX,
|
||||
+ "noa_duration: %d, noa_start: %d, noa_index: %d, periodic: %d\n",
|
||||
+ avp->noa_duration,
|
||||
+ avp->noa_start,
|
||||
+ avp->noa_index,
|
||||
+ avp->periodic_noa);
|
||||
+}
|
||||
+
|
||||
void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
|
||||
enum ath_chanctx_event ev)
|
||||
{
|
||||
@@ -521,31 +554,9 @@ void ath_chanctx_event(struct ath_softc
|
||||
* announcement.
|
||||
*/
|
||||
if (ctx->active &&
|
||||
- (!avp->noa_duration || sc->sched.force_noa_update)) {
|
||||
- avp->noa_index++;
|
||||
- avp->noa_start = tsf_time;
|
||||
-
|
||||
- if (sc->sched.extend_absence)
|
||||
- avp->noa_duration = (3 * beacon_int / 2) +
|
||||
- sc->sched.channel_switch_time;
|
||||
- else
|
||||
- avp->noa_duration =
|
||||
- TU_TO_USEC(cur_conf->beacon_interval) / 2 +
|
||||
- sc->sched.channel_switch_time;
|
||||
-
|
||||
- if (test_bit(ATH_OP_SCANNING, &common->op_flags) ||
|
||||
- sc->sched.extend_absence)
|
||||
- avp->periodic_noa = false;
|
||||
- else
|
||||
- avp->periodic_noa = true;
|
||||
-
|
||||
- ath_dbg(common, CHAN_CTX,
|
||||
- "noa_duration: %d, noa_start: %d, noa_index: %d, periodic: %d\n",
|
||||
- avp->noa_duration,
|
||||
- avp->noa_start,
|
||||
- avp->noa_index,
|
||||
- avp->periodic_noa);
|
||||
- }
|
||||
+ (!avp->noa_duration || sc->sched.force_noa_update))
|
||||
+ ath_chanctx_set_periodic_noa(sc, avp, cur_conf,
|
||||
+ tsf_time, beacon_int);
|
||||
|
||||
if (ctx->active && sc->sched.force_noa_update)
|
||||
sc->sched.force_noa_update = false;
|
|
@ -1,68 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:25 +0530
|
||||
Subject: [PATCH] ath9k: Use a helper function for bmiss
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -366,6 +366,31 @@ static void ath_chanctx_setup_timer(stru
|
||||
"Setup chanctx timer with timeout: %d ms\n", jiffies_to_msecs(tsf_time));
|
||||
}
|
||||
|
||||
+static void ath_chanctx_handle_bmiss(struct ath_softc *sc,
|
||||
+ struct ath_chanctx *ctx,
|
||||
+ struct ath_vif *avp)
|
||||
+{
|
||||
+ /*
|
||||
+ * Clear the extend_absence flag if it had been
|
||||
+ * set during the previous beacon transmission,
|
||||
+ * since we need to revert to the normal NoA
|
||||
+ * schedule.
|
||||
+ */
|
||||
+ if (ctx->active && sc->sched.extend_absence) {
|
||||
+ avp->noa_duration = 0;
|
||||
+ sc->sched.extend_absence = false;
|
||||
+ }
|
||||
+
|
||||
+ /* If at least two consecutive beacons were missed on the STA
|
||||
+ * chanctx, stay on the STA channel for one extra beacon period,
|
||||
+ * to resync the timer properly.
|
||||
+ */
|
||||
+ if (ctx->active && sc->sched.beacon_miss >= 2) {
|
||||
+ avp->noa_duration = 0;
|
||||
+ sc->sched.extend_absence = true;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void ath_chanctx_offchannel_noa(struct ath_softc *sc,
|
||||
struct ath_chanctx *ctx,
|
||||
struct ath_vif *avp,
|
||||
@@ -524,25 +549,7 @@ void ath_chanctx_event(struct ath_softc
|
||||
break;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Clear the extend_absence flag if it had been
|
||||
- * set during the previous beacon transmission,
|
||||
- * since we need to revert to the normal NoA
|
||||
- * schedule.
|
||||
- */
|
||||
- if (ctx->active && sc->sched.extend_absence) {
|
||||
- avp->noa_duration = 0;
|
||||
- sc->sched.extend_absence = false;
|
||||
- }
|
||||
-
|
||||
- /* If at least two consecutive beacons were missed on the STA
|
||||
- * chanctx, stay on the STA channel for one extra beacon period,
|
||||
- * to resync the timer properly.
|
||||
- */
|
||||
- if (ctx->active && sc->sched.beacon_miss >= 2) {
|
||||
- avp->noa_duration = 0;
|
||||
- sc->sched.extend_absence = true;
|
||||
- }
|
||||
+ ath_chanctx_handle_bmiss(sc, ctx, avp);
|
||||
|
||||
/* Prevent wrap-around issues */
|
||||
if (avp->noa_duration && tsf_time - avp->noa_start > BIT(30))
|
|
@ -1,38 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:26 +0530
|
||||
Subject: [PATCH] ath9k: Fix RoC expiration
|
||||
|
||||
mac80211 has to be notified when a RoC period
|
||||
expires in the driver. In MCC mode, since the
|
||||
offchannel/RoC timer is set with the requested
|
||||
duration, ieee80211_remain_on_channel_expired() needs
|
||||
to be called when the timer expires.
|
||||
|
||||
But, currently it is done after we move back to
|
||||
the operating channel. This is incorrect - fix this
|
||||
by calling ieee80211_remain_on_channel_expired() when
|
||||
the RoC timer expires and in ath_roc_complete() when
|
||||
the RoC request is aborted.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -894,7 +894,7 @@ void ath_roc_complete(struct ath_softc *
|
||||
|
||||
sc->offchannel.roc_vif = NULL;
|
||||
sc->offchannel.roc_chan = NULL;
|
||||
- if (!abort)
|
||||
+ if (abort)
|
||||
ieee80211_remain_on_channel_expired(sc->hw);
|
||||
ath_offchannel_next(sc);
|
||||
ath9k_ps_restore(sc);
|
||||
@@ -1028,6 +1028,7 @@ static void ath_offchannel_timer(unsigne
|
||||
case ATH_OFFCHANNEL_ROC_WAIT:
|
||||
ctx = ath_chanctx_get_oper_chan(sc, false);
|
||||
sc->offchannel.state = ATH_OFFCHANNEL_ROC_DONE;
|
||||
+ ieee80211_remain_on_channel_expired(sc->hw);
|
||||
ath_chanctx_switch(sc, ctx, NULL);
|
||||
break;
|
||||
default:
|
|
@ -1,85 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:27 +0530
|
||||
Subject: [PATCH] ath9k: Send oneshot NoA
|
||||
|
||||
This patch makes sure that a GO interface
|
||||
sends out a new NoA schedule with 200ms duration
|
||||
when mgd_prepare_tx() is called.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -620,6 +620,7 @@ struct ath_vif {
|
||||
u32 noa_start;
|
||||
u32 noa_duration;
|
||||
bool periodic_noa;
|
||||
+ bool oneshot_noa;
|
||||
};
|
||||
|
||||
struct ath9k_vif_iter_data {
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -450,6 +450,27 @@ static void ath_chanctx_set_periodic_noa
|
||||
avp->periodic_noa);
|
||||
}
|
||||
|
||||
+static void ath_chanctx_set_oneshot_noa(struct ath_softc *sc,
|
||||
+ struct ath_vif *avp,
|
||||
+ u32 tsf_time,
|
||||
+ u32 duration)
|
||||
+{
|
||||
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
+
|
||||
+ avp->noa_index++;
|
||||
+ avp->noa_start = tsf_time;
|
||||
+ avp->periodic_noa = false;
|
||||
+ avp->oneshot_noa = true;
|
||||
+ avp->noa_duration = duration + sc->sched.channel_switch_time;
|
||||
+
|
||||
+ ath_dbg(common, CHAN_CTX,
|
||||
+ "oneshot noa_duration: %d, noa_start: %d, noa_index: %d, periodic: %d\n",
|
||||
+ avp->noa_duration,
|
||||
+ avp->noa_start,
|
||||
+ avp->noa_index,
|
||||
+ avp->periodic_noa);
|
||||
+}
|
||||
+
|
||||
void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
|
||||
enum ath_chanctx_event ev)
|
||||
{
|
||||
@@ -476,6 +497,14 @@ void ath_chanctx_event(struct ath_softc
|
||||
if (avp->offchannel_duration)
|
||||
avp->offchannel_duration = 0;
|
||||
|
||||
+ if (avp->oneshot_noa) {
|
||||
+ avp->noa_duration = 0;
|
||||
+ avp->oneshot_noa = false;
|
||||
+
|
||||
+ ath_dbg(common, CHAN_CTX,
|
||||
+ "Clearing oneshot NoA\n");
|
||||
+ }
|
||||
+
|
||||
if (avp->chanctx != sc->cur_chan) {
|
||||
ath_dbg(common, CHAN_CTX,
|
||||
"Contexts differ, not preparing beacon\n");
|
||||
@@ -551,6 +580,18 @@ void ath_chanctx_event(struct ath_softc
|
||||
|
||||
ath_chanctx_handle_bmiss(sc, ctx, avp);
|
||||
|
||||
+ /*
|
||||
+ * If a mgd_prepare_tx() has been called by mac80211,
|
||||
+ * a one-shot NoA needs to be sent. This can happen
|
||||
+ * with one or more active channel contexts - in both
|
||||
+ * cases, a new NoA schedule has to be advertised.
|
||||
+ */
|
||||
+ if (sc->sched.mgd_prepare_tx) {
|
||||
+ ath_chanctx_set_oneshot_noa(sc, avp, tsf_time,
|
||||
+ jiffies_to_usecs(HZ / 5));
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
/* Prevent wrap-around issues */
|
||||
if (avp->noa_duration && tsf_time - avp->noa_start > BIT(30))
|
||||
avp->noa_duration = 0;
|
|
@ -1,68 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:28 +0530
|
||||
Subject: [PATCH] ath9k: Fix HW scan abort
|
||||
|
||||
Instead of using ATH_CHANCTX_EVENT_ASSIGN to abort
|
||||
a HW scan when a new interface becomes active, use the
|
||||
mgd_prepare_tx() callback. This allows us to make
|
||||
sure that the GO's channel becomes operational by
|
||||
using flush_work().
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -743,22 +743,6 @@ void ath_chanctx_event(struct ath_softc
|
||||
ieee80211_queue_work(sc->hw, &sc->chanctx_work);
|
||||
break;
|
||||
case ATH_CHANCTX_EVENT_ASSIGN:
|
||||
- /*
|
||||
- * When adding a new channel context, check if a scan
|
||||
- * is in progress and abort it since the addition of
|
||||
- * a new channel context is usually followed by VIF
|
||||
- * assignment, in which case we have to start multi-channel
|
||||
- * operation.
|
||||
- */
|
||||
- if (test_bit(ATH_OP_SCANNING, &common->op_flags)) {
|
||||
- ath_dbg(common, CHAN_CTX,
|
||||
- "Aborting HW scan to add new context\n");
|
||||
-
|
||||
- spin_unlock_bh(&sc->chan_lock);
|
||||
- del_timer_sync(&sc->offchannel.timer);
|
||||
- ath_scan_complete(sc, true);
|
||||
- spin_lock_bh(&sc->chan_lock);
|
||||
- }
|
||||
break;
|
||||
case ATH_CHANCTX_EVENT_CHANGE:
|
||||
break;
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -2365,7 +2365,6 @@ static int ath9k_add_chanctx(struct ieee
|
||||
conf->def.chan->center_freq);
|
||||
|
||||
ath_chanctx_set_channel(sc, ctx, &conf->def);
|
||||
- ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_ASSIGN);
|
||||
|
||||
mutex_unlock(&sc->mutex);
|
||||
return 0;
|
||||
@@ -2496,6 +2495,19 @@ static void ath9k_mgd_prepare_tx(struct
|
||||
if (!changed)
|
||||
goto out;
|
||||
|
||||
+ if (test_bit(ATH_OP_SCANNING, &common->op_flags)) {
|
||||
+ ath_dbg(common, CHAN_CTX,
|
||||
+ "%s: Aborting HW scan\n", __func__);
|
||||
+
|
||||
+ mutex_unlock(&sc->mutex);
|
||||
+
|
||||
+ del_timer_sync(&sc->offchannel.timer);
|
||||
+ ath_scan_complete(sc, true);
|
||||
+ flush_work(&sc->chanctx_work);
|
||||
+
|
||||
+ mutex_lock(&sc->mutex);
|
||||
+ }
|
||||
+
|
||||
go_ctx = ath_is_go_chanctx_present(sc);
|
||||
|
||||
if (go_ctx) {
|
|
@ -1,95 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:29 +0530
|
||||
Subject: [PATCH] ath9k: Improve flush() in mcc mode
|
||||
|
||||
The flush timeout in MCC mode is very small, since
|
||||
we are constrained by the time slice for each
|
||||
channel context, but since only the HW queues are
|
||||
flushed when switching contexts, it is acceptable.
|
||||
|
||||
Since the SW queues are also emptied in the mac80211 flush()
|
||||
callback, a larger duration is needed. Add an override
|
||||
argument to __ath9k_flush() and set it when flush()
|
||||
is called in MCC mode. This allows the driver to
|
||||
drain both the SW and HW queues.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -719,7 +719,7 @@ void ath_update_survey_nf(struct ath_sof
|
||||
void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
|
||||
void ath_ps_full_sleep(unsigned long data);
|
||||
void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
|
||||
- bool sw_pending);
|
||||
+ bool sw_pending, bool timeout_override);
|
||||
|
||||
/**********/
|
||||
/* BTCOEX */
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -1232,11 +1232,11 @@ void ath_chanctx_set_next(struct ath_sof
|
||||
ath9k_chanctx_stop_queues(sc, sc->cur_chan);
|
||||
queues_stopped = true;
|
||||
|
||||
- __ath9k_flush(sc->hw, ~0, true, false);
|
||||
+ __ath9k_flush(sc->hw, ~0, true, false, false);
|
||||
|
||||
if (ath_chanctx_send_ps_frame(sc, true))
|
||||
__ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO),
|
||||
- false, false);
|
||||
+ false, false, false);
|
||||
|
||||
send_ps = true;
|
||||
spin_lock_bh(&sc->chan_lock);
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -2031,14 +2031,33 @@ static void ath9k_flush(struct ieee80211
|
||||
u32 queues, bool drop)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
+
|
||||
+ if (ath9k_is_chanctx_enabled()) {
|
||||
+ if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
|
||||
+ goto flush;
|
||||
|
||||
+ /*
|
||||
+ * If MCC is active, extend the flush timeout
|
||||
+ * and wait for the HW/SW queues to become
|
||||
+ * empty. This needs to be done outside the
|
||||
+ * sc->mutex lock to allow the channel scheduler
|
||||
+ * to switch channel contexts.
|
||||
+ *
|
||||
+ * The vif queues have been stopped in mac80211,
|
||||
+ * so there won't be any incoming frames.
|
||||
+ */
|
||||
+ __ath9k_flush(hw, queues, drop, true, true);
|
||||
+ return;
|
||||
+ }
|
||||
+flush:
|
||||
mutex_lock(&sc->mutex);
|
||||
- __ath9k_flush(hw, queues, drop, true);
|
||||
+ __ath9k_flush(hw, queues, drop, true, false);
|
||||
mutex_unlock(&sc->mutex);
|
||||
}
|
||||
|
||||
void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
|
||||
- bool sw_pending)
|
||||
+ bool sw_pending, bool timeout_override)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@@ -2059,7 +2078,10 @@ void __ath9k_flush(struct ieee80211_hw *
|
||||
}
|
||||
|
||||
spin_lock_bh(&sc->chan_lock);
|
||||
- timeout = sc->cur_chan->flush_timeout;
|
||||
+ if (timeout_override)
|
||||
+ timeout = HZ / 5;
|
||||
+ else
|
||||
+ timeout = sc->cur_chan->flush_timeout;
|
||||
spin_unlock_bh(&sc->chan_lock);
|
||||
|
||||
ath_dbg(common, CHAN_CTX,
|
|
@ -1,60 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Fri, 17 Oct 2014 07:40:30 +0530
|
||||
Subject: [PATCH] ath9k: Do not start BA when scanning
|
||||
|
||||
mac80211 currently has a race which can be hit
|
||||
with this sequence:
|
||||
|
||||
* Start a scan operation.
|
||||
* TX BA is initiated by ieee80211_start_tx_ba_session().
|
||||
* Driver sets up internal state and calls
|
||||
ieee80211_start_tx_ba_cb_irqsafe().
|
||||
* mac80211 adds a packet to sdata->skb_queue with
|
||||
type IEEE80211_SDATA_QUEUE_AGG_START.
|
||||
* ieee80211_iface_work() doesn't process the
|
||||
packet because scan is in progress.
|
||||
* ADDBA response timer expires and the sta/tid is
|
||||
torn down.
|
||||
* Driver receives BA stop notification and calls
|
||||
ieee80211_stop_tx_ba_cb_irqsafe().
|
||||
* This is also added to the queue by mac80211.
|
||||
* Now, scan finishes.
|
||||
|
||||
At this point, the queued up packets might be processed
|
||||
if some other operation schedules the sdata work. Since
|
||||
the tids have been cleaned up already, warnings are hit.
|
||||
|
||||
If this doesn't happen, the packets are left in the queue
|
||||
until the interface is torn down.
|
||||
|
||||
Since initiating a BA session when scan is in progress
|
||||
leads to flaky connections, especially in MCC mode, we
|
||||
can drop the TX BA request. This improves connectivity
|
||||
with legacy clients in MCC mode.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -1885,6 +1885,7 @@ static int ath9k_ampdu_action(struct iee
|
||||
u16 tid, u16 *ssn, u8 buf_size)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
bool flush = false;
|
||||
int ret = 0;
|
||||
|
||||
@@ -1896,6 +1897,12 @@ static int ath9k_ampdu_action(struct iee
|
||||
case IEEE80211_AMPDU_RX_STOP:
|
||||
break;
|
||||
case IEEE80211_AMPDU_TX_START:
|
||||
+ if (ath9k_is_chanctx_enabled()) {
|
||||
+ if (test_bit(ATH_OP_SCANNING, &common->op_flags)) {
|
||||
+ ret = -EBUSY;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
ath9k_ps_wakeup(sc);
|
||||
ret = ath_tx_aggr_start(sc, sta, tid, ssn);
|
||||
if (!ret)
|
|
@ -1,259 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Sat, 18 Oct 2014 13:23:34 +0200
|
||||
Subject: [PATCH] ath9k_hw: make support for PC-OEM cards optional
|
||||
|
||||
The initvals use up quite a bit of space, and PC-OEM support is
|
||||
typically not needed on embedded systems
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/Kconfig
|
||||
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
|
||||
@@ -151,6 +151,11 @@ config ATH9K_CHANNEL_CONTEXT
|
||||
for multi-channel concurrency. Enable this if P2P PowerSave support
|
||||
is required.
|
||||
|
||||
+config ATH9K_PCOEM
|
||||
+ bool "Atheros ath9k support for PC OEM cards" if EXPERT
|
||||
+ depends on ATH9K
|
||||
+ default y
|
||||
+
|
||||
config ATH9K_HTC
|
||||
tristate "Atheros HTC based wireless cards support"
|
||||
depends on m
|
||||
--- a/drivers/net/wireless/ath/ath9k/Makefile
|
||||
+++ b/drivers/net/wireless/ath/ath9k/Makefile
|
||||
@@ -32,7 +32,6 @@ ath9k_hw-y:= \
|
||||
ar5008_phy.o \
|
||||
ar9002_calib.o \
|
||||
ar9003_calib.o \
|
||||
- ar9003_rtt.o \
|
||||
calib.o \
|
||||
eeprom.o \
|
||||
eeprom_def.o \
|
||||
@@ -50,6 +49,8 @@ ath9k_hw-$(CPTCFG_ATH9K_WOW) += ar9003_w
|
||||
ath9k_hw-$(CPTCFG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
|
||||
ar9003_mci.o
|
||||
|
||||
+ath9k_hw-$(CPTCFG_ATH9K_PCOEM) += ar9003_rtt.o
|
||||
+
|
||||
ath9k_hw-$(CPTCFG_ATH9K_DYNACK) += dynack.o
|
||||
|
||||
obj-$(CPTCFG_ATH9K_HW) += ath9k_hw.o
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.h
|
||||
@@ -17,6 +17,7 @@
|
||||
#ifndef AR9003_RTT_H
|
||||
#define AR9003_RTT_H
|
||||
|
||||
+#ifdef CPTCFG_ATH9K_PCOEM
|
||||
void ar9003_hw_rtt_enable(struct ath_hw *ah);
|
||||
void ar9003_hw_rtt_disable(struct ath_hw *ah);
|
||||
void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask);
|
||||
@@ -25,5 +26,40 @@ void ar9003_hw_rtt_load_hist(struct ath_
|
||||
void ar9003_hw_rtt_fill_hist(struct ath_hw *ah);
|
||||
void ar9003_hw_rtt_clear_hist(struct ath_hw *ah);
|
||||
bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
+#else
|
||||
+static inline void ar9003_hw_rtt_enable(struct ath_hw *ah)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void ar9003_hw_rtt_disable(struct ath_hw *ah)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline bool ar9003_hw_rtt_force_restore(struct ath_hw *ah)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static inline void ar9003_hw_rtt_load_hist(struct ath_hw *ah)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void ar9003_hw_rtt_fill_hist(struct ath_hw *ah)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void ar9003_hw_rtt_clear_hist(struct ath_hw *ah)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
+#endif
|
||||
|
||||
#endif
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.h
|
||||
@@ -244,13 +244,20 @@ enum ath9k_hw_caps {
|
||||
ATH9K_HW_CAP_2GHZ = BIT(11),
|
||||
ATH9K_HW_CAP_5GHZ = BIT(12),
|
||||
ATH9K_HW_CAP_APM = BIT(13),
|
||||
+#ifdef CPTCFG_ATH9K_PCOEM
|
||||
ATH9K_HW_CAP_RTT = BIT(14),
|
||||
ATH9K_HW_CAP_MCI = BIT(15),
|
||||
- ATH9K_HW_CAP_DFS = BIT(16),
|
||||
- ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(17),
|
||||
- ATH9K_HW_CAP_PAPRD = BIT(18),
|
||||
- ATH9K_HW_CAP_FCC_BAND_SWITCH = BIT(19),
|
||||
- ATH9K_HW_CAP_BT_ANT_DIV = BIT(20),
|
||||
+ ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(16),
|
||||
+ ATH9K_HW_CAP_BT_ANT_DIV = BIT(17),
|
||||
+#else
|
||||
+ ATH9K_HW_CAP_RTT = 0,
|
||||
+ ATH9K_HW_CAP_MCI = 0,
|
||||
+ ATH9K_HW_WOW_DEVICE_CAPABLE = 0,
|
||||
+ ATH9K_HW_CAP_BT_ANT_DIV = 0,
|
||||
+#endif
|
||||
+ ATH9K_HW_CAP_DFS = BIT(18),
|
||||
+ ATH9K_HW_CAP_PAPRD = BIT(19),
|
||||
+ ATH9K_HW_CAP_FCC_BAND_SWITCH = BIT(20),
|
||||
};
|
||||
|
||||
/*
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -362,6 +362,9 @@ static void ath9k_init_pcoem_platform(st
|
||||
struct ath9k_hw_capabilities *pCap = &ah->caps;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
+ if (!IS_ENABLED(CPTCFG_ATH9K_PCOEM))
|
||||
+ return;
|
||||
+
|
||||
if (common->bus_ops->ath_bus_type != ATH_PCI)
|
||||
return;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/pci.c
|
||||
@@ -30,6 +30,7 @@ static const struct pci_device_id ath_pc
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
|
||||
|
||||
+#ifdef CPTCFG_ATH9K_PCOEM
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x002A,
|
||||
PCI_VENDOR_ID_AZWAVE,
|
||||
@@ -82,6 +83,7 @@ static const struct pci_device_id ath_pc
|
||||
PCI_VENDOR_ID_AZWAVE,
|
||||
0x2C37),
|
||||
.driver_data = ATH9K_PCI_BT_ANT_DIV },
|
||||
+#endif
|
||||
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
|
||||
@@ -102,6 +104,7 @@ static const struct pci_device_id ath_pc
|
||||
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
|
||||
|
||||
+#ifdef CPTCFG_ATH9K_PCOEM
|
||||
/* PCI-E CUS198 */
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0032,
|
||||
@@ -294,10 +297,12 @@ static const struct pci_device_id ath_pc
|
||||
PCI_VENDOR_ID_ASUSTEK,
|
||||
0x850D),
|
||||
.driver_data = ATH9K_PCI_NO_PLL_PWRSAVE },
|
||||
+#endif
|
||||
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */
|
||||
|
||||
+#ifdef CPTCFG_ATH9K_PCOEM
|
||||
/* PCI-E CUS217 */
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0034,
|
||||
@@ -657,6 +662,7 @@ static const struct pci_device_id ath_pc
|
||||
/* PCI-E AR9565 (WB335) */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0036),
|
||||
.driver_data = ATH9K_PCI_BT_ANT_DIV },
|
||||
+#endif
|
||||
|
||||
{ 0 }
|
||||
};
|
||||
--- a/drivers/net/wireless/ath/ath9k/reg.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/reg.h
|
||||
@@ -892,10 +892,21 @@
|
||||
(AR_SREV_9330((_ah)) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9330_12))
|
||||
|
||||
+#ifdef CPTCFG_ATH9K_PCOEM
|
||||
+#define AR_SREV_9462(_ah) \
|
||||
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462))
|
||||
#define AR_SREV_9485(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485))
|
||||
+#define AR_SREV_9565(_ah) \
|
||||
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
|
||||
+#else
|
||||
+#define AR_SREV_9462(_ah) 0
|
||||
+#define AR_SREV_9485(_ah) 0
|
||||
+#define AR_SREV_9565(_ah) 0
|
||||
+#endif
|
||||
+
|
||||
#define AR_SREV_9485_11_OR_LATER(_ah) \
|
||||
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485) && \
|
||||
+ (AR_SREV_9485(_ah) && \
|
||||
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9485_11))
|
||||
#define AR_SREV_9485_OR_LATER(_ah) \
|
||||
(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485))
|
||||
@@ -915,34 +926,30 @@
|
||||
(AR_SREV_9285_12_OR_LATER(_ah) && \
|
||||
((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
|
||||
|
||||
-#define AR_SREV_9462(_ah) \
|
||||
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462))
|
||||
#define AR_SREV_9462_20(_ah) \
|
||||
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
|
||||
+ (AR_SREV_9462(_ah) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20))
|
||||
#define AR_SREV_9462_21(_ah) \
|
||||
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
|
||||
+ (AR_SREV_9462(_ah) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_21))
|
||||
#define AR_SREV_9462_20_OR_LATER(_ah) \
|
||||
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
|
||||
+ (AR_SREV_9462(_ah) && \
|
||||
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20))
|
||||
#define AR_SREV_9462_21_OR_LATER(_ah) \
|
||||
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
|
||||
+ (AR_SREV_9462(_ah) && \
|
||||
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_21))
|
||||
|
||||
-#define AR_SREV_9565(_ah) \
|
||||
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
|
||||
#define AR_SREV_9565_10(_ah) \
|
||||
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
|
||||
+ (AR_SREV_9565(_ah) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10))
|
||||
#define AR_SREV_9565_101(_ah) \
|
||||
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
|
||||
+ (AR_SREV_9565(_ah) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_101))
|
||||
#define AR_SREV_9565_11(_ah) \
|
||||
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
|
||||
+ (AR_SREV_9565(_ah) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_11))
|
||||
#define AR_SREV_9565_11_OR_LATER(_ah) \
|
||||
- (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
|
||||
+ (AR_SREV_9565(_ah) && \
|
||||
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9565_11))
|
||||
|
||||
#define AR_SREV_9550(_ah) \
|
||||
--- a/.local-symbols
|
||||
+++ b/.local-symbols
|
||||
@@ -124,6 +124,7 @@ ATH9K_HW=
|
||||
ATH9K_COMMON=
|
||||
ATH9K_DFS_DEBUGFS=
|
||||
ATH9K_BTCOEX_SUPPORT=
|
||||
+ATH9K_PCOEM=
|
||||
ATH9K=
|
||||
ATH9K_PCI=
|
||||
ATH9K_AHB=
|
|
@ -1,22 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Sat, 18 Oct 2014 13:25:26 +0200
|
||||
Subject: [PATCH] ath9k_hw: remove support for UB124 tx gain table
|
||||
|
||||
UB124 is a USB based reference design not supported by ath9k or
|
||||
ath9k_htc.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
|
||||
@@ -670,9 +670,6 @@ static void ar9003_tx_gain_table_mode5(s
|
||||
if (AR_SREV_9485_11_OR_LATER(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485Modes_green_ob_db_tx_gain_1_1);
|
||||
- else if (AR_SREV_9340(ah))
|
||||
- INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
- ar9340Modes_ub124_tx_gain_table_1p0);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_type5_tx_gain_table);
|
|
@ -1,33 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Sat, 18 Oct 2014 13:31:52 +0200
|
||||
Subject: [PATCH] ath9k: fix processing RXORN interrupts
|
||||
|
||||
The "goto chip_reset" is a bit misleading, because it does not actually
|
||||
issue a chip reset. Instead it is bypassing processing of other
|
||||
interrupts and assumes that the tasklet will issue a chip reset.
|
||||
|
||||
In the case of RXORN this does not happen, so bypassing processing of
|
||||
other interrupts will simply allow them to fire again. Even if RXORN
|
||||
was triggering a reset, it is not critical enough to need the bypass
|
||||
here.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -545,11 +545,10 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
sched = true;
|
||||
|
||||
/*
|
||||
- * If a FATAL or RXORN interrupt is received, we have to reset the
|
||||
- * chip immediately.
|
||||
+ * If a FATAL interrupt is received, we have to reset the chip
|
||||
+ * immediately.
|
||||
*/
|
||||
- if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) &&
|
||||
- !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
|
||||
+ if (status & ATH9K_INT_FATAL)
|
||||
goto chip_reset;
|
||||
|
||||
if ((ah->config.hw_hang_checks & HW_BB_WATCHDOG) &&
|
|
@ -1,69 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Sat, 18 Oct 2014 13:36:41 +0200
|
||||
Subject: [PATCH] ath9k: clean up debugfs print of reset causes
|
||||
|
||||
Reduce code duplication
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||
@@ -852,36 +852,30 @@ static ssize_t read_file_reset(struct fi
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
+ static const char * const reset_cause[__RESET_TYPE_MAX] = {
|
||||
+ [RESET_TYPE_BB_HANG] = "Baseband Hang",
|
||||
+ [RESET_TYPE_BB_WATCHDOG] = "Baseband Watchdog",
|
||||
+ [RESET_TYPE_FATAL_INT] = "Fatal HW Error",
|
||||
+ [RESET_TYPE_TX_ERROR] = "TX HW error",
|
||||
+ [RESET_TYPE_TX_GTT] = "Transmit timeout",
|
||||
+ [RESET_TYPE_TX_HANG] = "TX Path Hang",
|
||||
+ [RESET_TYPE_PLL_HANG] = "PLL RX Hang",
|
||||
+ [RESET_TYPE_MAC_HANG] = "MAC Hang",
|
||||
+ [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon",
|
||||
+ [RESET_TYPE_MCI] = "MCI Reset",
|
||||
+ };
|
||||
char buf[512];
|
||||
unsigned int len = 0;
|
||||
+ int i;
|
||||
|
||||
- len += scnprintf(buf + len, sizeof(buf) - len,
|
||||
- "%17s: %2d\n", "Baseband Hang",
|
||||
- sc->debug.stats.reset[RESET_TYPE_BB_HANG]);
|
||||
- len += scnprintf(buf + len, sizeof(buf) - len,
|
||||
- "%17s: %2d\n", "Baseband Watchdog",
|
||||
- sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]);
|
||||
- len += scnprintf(buf + len, sizeof(buf) - len,
|
||||
- "%17s: %2d\n", "Fatal HW Error",
|
||||
- sc->debug.stats.reset[RESET_TYPE_FATAL_INT]);
|
||||
- len += scnprintf(buf + len, sizeof(buf) - len,
|
||||
- "%17s: %2d\n", "TX HW error",
|
||||
- sc->debug.stats.reset[RESET_TYPE_TX_ERROR]);
|
||||
- len += scnprintf(buf + len, sizeof(buf) - len,
|
||||
- "%17s: %2d\n", "TX Path Hang",
|
||||
- sc->debug.stats.reset[RESET_TYPE_TX_HANG]);
|
||||
- len += scnprintf(buf + len, sizeof(buf) - len,
|
||||
- "%17s: %2d\n", "PLL RX Hang",
|
||||
- sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
|
||||
- len += scnprintf(buf + len, sizeof(buf) - len,
|
||||
- "%17s: %2d\n", "MAC Hang",
|
||||
- sc->debug.stats.reset[RESET_TYPE_MAC_HANG]);
|
||||
- len += scnprintf(buf + len, sizeof(buf) - len,
|
||||
- "%17s: %2d\n", "Stuck Beacon",
|
||||
- sc->debug.stats.reset[RESET_TYPE_BEACON_STUCK]);
|
||||
- len += scnprintf(buf + len, sizeof(buf) - len,
|
||||
- "%17s: %2d\n", "MCI Reset",
|
||||
- sc->debug.stats.reset[RESET_TYPE_MCI]);
|
||||
+ for (i = 0; i < ARRAY_SIZE(reset_cause); i++) {
|
||||
+ if (!reset_cause[i])
|
||||
+ continue;
|
||||
+
|
||||
+ len += scnprintf(buf + len, sizeof(buf) - len,
|
||||
+ "%17s: %2d\n", reset_cause[i],
|
||||
+ sc->debug.stats.reset[i]);
|
||||
+ }
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
|
@ -1,185 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Sat, 18 Oct 2014 13:37:32 +0200
|
||||
Subject: [PATCH] ath9k: restart hardware after noise floor calibration
|
||||
failure
|
||||
|
||||
When NF calibration fails, the radio often becomes deaf. The usual
|
||||
hardware hang checks do not detect this, so it's better to issue a reset
|
||||
when that happens.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
|
||||
@@ -657,14 +657,13 @@ static void ar9002_hw_olc_temp_compensat
|
||||
ar9280_hw_olc_temp_compensation(ah);
|
||||
}
|
||||
|
||||
-static bool ar9002_hw_calibrate(struct ath_hw *ah,
|
||||
- struct ath9k_channel *chan,
|
||||
- u8 rxchainmask,
|
||||
- bool longcal)
|
||||
+static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
+ u8 rxchainmask, bool longcal)
|
||||
{
|
||||
bool iscaldone = true;
|
||||
struct ath9k_cal_list *currCal = ah->cal_list_curr;
|
||||
bool nfcal, nfcal_pending = false;
|
||||
+ int ret;
|
||||
|
||||
nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
|
||||
if (ah->caldata)
|
||||
@@ -698,7 +697,9 @@ static bool ar9002_hw_calibrate(struct a
|
||||
* NF is slow time-variant, so it is OK to use a
|
||||
* historical value.
|
||||
*/
|
||||
- ath9k_hw_loadnf(ah, ah->curchan);
|
||||
+ ret = ath9k_hw_loadnf(ah, ah->curchan);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
if (longcal) {
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
|
||||
@@ -121,13 +121,12 @@ static bool ar9003_hw_per_calibration(st
|
||||
return iscaldone;
|
||||
}
|
||||
|
||||
-static bool ar9003_hw_calibrate(struct ath_hw *ah,
|
||||
- struct ath9k_channel *chan,
|
||||
- u8 rxchainmask,
|
||||
- bool longcal)
|
||||
+static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
+ u8 rxchainmask, bool longcal)
|
||||
{
|
||||
bool iscaldone = true;
|
||||
struct ath9k_cal_list *currCal = ah->cal_list_curr;
|
||||
+ int ret;
|
||||
|
||||
/*
|
||||
* For given calibration:
|
||||
@@ -163,7 +162,9 @@ static bool ar9003_hw_calibrate(struct a
|
||||
* NF is slow time-variant, so it is OK to use a historical
|
||||
* value.
|
||||
*/
|
||||
- ath9k_hw_loadnf(ah, ah->curchan);
|
||||
+ ret = ath9k_hw_loadnf(ah, ah->curchan);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
|
||||
/* start NF calibration, without updating BB NF register */
|
||||
ath9k_hw_start_nfcal(ah, false);
|
||||
--- a/drivers/net/wireless/ath/ath9k/calib.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/calib.c
|
||||
@@ -234,7 +234,7 @@ void ath9k_hw_start_nfcal(struct ath_hw
|
||||
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
|
||||
}
|
||||
|
||||
-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
+int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath9k_nfcal_hist *h = NULL;
|
||||
unsigned i, j;
|
||||
@@ -301,7 +301,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah,
|
||||
ath_dbg(common, ANY,
|
||||
"Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
|
||||
REG_READ(ah, AR_PHY_AGC_CONTROL));
|
||||
- return;
|
||||
+ return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -322,6 +322,8 @@ void ath9k_hw_loadnf(struct ath_hw *ah,
|
||||
}
|
||||
}
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/calib.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/calib.h
|
||||
@@ -109,7 +109,7 @@ struct ath9k_pacal_info{
|
||||
|
||||
bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
|
||||
void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update);
|
||||
-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
+int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan);
|
||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||
@@ -863,6 +863,7 @@ static ssize_t read_file_reset(struct fi
|
||||
[RESET_TYPE_MAC_HANG] = "MAC Hang",
|
||||
[RESET_TYPE_BEACON_STUCK] = "Stuck Beacon",
|
||||
[RESET_TYPE_MCI] = "MCI Reset",
|
||||
+ [RESET_TYPE_CALIBRATION] = "Calibration error",
|
||||
};
|
||||
char buf[512];
|
||||
unsigned int len = 0;
|
||||
--- a/drivers/net/wireless/ath/ath9k/debug.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/debug.h
|
||||
@@ -49,6 +49,7 @@ enum ath_reset_type {
|
||||
RESET_TYPE_MAC_HANG,
|
||||
RESET_TYPE_BEACON_STUCK,
|
||||
RESET_TYPE_MCI,
|
||||
+ RESET_TYPE_CALIBRATION,
|
||||
__RESET_TYPE_MAX
|
||||
};
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
|
||||
@@ -41,10 +41,9 @@ static inline void ath9k_hw_set_desc_lin
|
||||
ath9k_hw_ops(ah)->set_desc_link(ds, link);
|
||||
}
|
||||
|
||||
-static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
|
||||
- struct ath9k_channel *chan,
|
||||
- u8 rxchainmask,
|
||||
- bool longcal)
|
||||
+static inline int ath9k_hw_calibrate(struct ath_hw *ah,
|
||||
+ struct ath9k_channel *chan,
|
||||
+ u8 rxchainmask, bool longcal)
|
||||
{
|
||||
return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.h
|
||||
@@ -688,10 +688,8 @@ struct ath_hw_ops {
|
||||
bool power_off);
|
||||
void (*rx_enable)(struct ath_hw *ah);
|
||||
void (*set_desc_link)(void *ds, u32 link);
|
||||
- bool (*calibrate)(struct ath_hw *ah,
|
||||
- struct ath9k_channel *chan,
|
||||
- u8 rxchainmask,
|
||||
- bool longcal);
|
||||
+ int (*calibrate)(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
+ u8 rxchainmask, bool longcal);
|
||||
bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked,
|
||||
u32 *sync_cause_p);
|
||||
void (*set_txdesc)(struct ath_hw *ah, void *ds,
|
||||
--- a/drivers/net/wireless/ath/ath9k/link.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/link.c
|
||||
@@ -371,9 +371,15 @@ void ath_ani_calibrate(unsigned long dat
|
||||
|
||||
/* Perform calibration if necessary */
|
||||
if (longcal || shortcal) {
|
||||
- common->ani.caldone =
|
||||
- ath9k_hw_calibrate(ah, ah->curchan,
|
||||
- ah->rxchainmask, longcal);
|
||||
+ int ret = ath9k_hw_calibrate(ah, ah->curchan, ah->rxchainmask,
|
||||
+ longcal);
|
||||
+ if (ret < 0) {
|
||||
+ common->ani.caldone = 0;
|
||||
+ ath9k_queue_reset(sc, RESET_TYPE_CALIBRATION);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ common->ani.caldone = ret;
|
||||
}
|
||||
|
||||
ath_dbg(common, ANI,
|
|
@ -1,63 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Sat, 18 Oct 2014 13:39:11 +0200
|
||||
Subject: [PATCH] ath9k_hw: do not run NF and periodic calibration at the
|
||||
same time
|
||||
|
||||
It can cause inconsistent calibration results or in some cases turn the
|
||||
radio deaf.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
|
||||
@@ -660,27 +660,26 @@ static void ar9002_hw_olc_temp_compensat
|
||||
static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
u8 rxchainmask, bool longcal)
|
||||
{
|
||||
- bool iscaldone = true;
|
||||
struct ath9k_cal_list *currCal = ah->cal_list_curr;
|
||||
- bool nfcal, nfcal_pending = false;
|
||||
+ bool nfcal, nfcal_pending = false, percal_pending;
|
||||
int ret;
|
||||
|
||||
nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
|
||||
if (ah->caldata)
|
||||
nfcal_pending = test_bit(NFCAL_PENDING, &ah->caldata->cal_flags);
|
||||
|
||||
- if (currCal && !nfcal &&
|
||||
- (currCal->calState == CAL_RUNNING ||
|
||||
- currCal->calState == CAL_WAITING)) {
|
||||
- iscaldone = ar9002_hw_per_calibration(ah, chan,
|
||||
- rxchainmask, currCal);
|
||||
- if (iscaldone) {
|
||||
- ah->cal_list_curr = currCal = currCal->calNext;
|
||||
-
|
||||
- if (currCal->calState == CAL_WAITING) {
|
||||
- iscaldone = false;
|
||||
- ath9k_hw_reset_calibration(ah, currCal);
|
||||
- }
|
||||
+ percal_pending = (currCal &&
|
||||
+ (currCal->calState == CAL_RUNNING ||
|
||||
+ currCal->calState == CAL_WAITING));
|
||||
+
|
||||
+ if (percal_pending && !nfcal) {
|
||||
+ if (!ar9002_hw_per_calibration(ah, chan, rxchainmask, currCal))
|
||||
+ return 0;
|
||||
+
|
||||
+ ah->cal_list_curr = currCal = currCal->calNext;
|
||||
+ if (currCal->calState == CAL_WAITING) {
|
||||
+ ath9k_hw_reset_calibration(ah, currCal);
|
||||
+ return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -710,7 +709,7 @@ static int ar9002_hw_calibrate(struct at
|
||||
}
|
||||
}
|
||||
|
||||
- return iscaldone;
|
||||
+ return !percal_pending;
|
||||
}
|
||||
|
||||
/* Carrier leakage Calibration fix */
|
|
@ -1,36 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Sat, 18 Oct 2014 13:42:03 +0200
|
||||
Subject: [PATCH] ath9k_hw: start initial NF calibration after PA
|
||||
calibration on <AR9003
|
||||
|
||||
This makes the initial NF calibration less likely to fail.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
|
||||
@@ -856,6 +856,8 @@ static bool ar9002_hw_init_cal(struct at
|
||||
|
||||
/* Do PA Calibration */
|
||||
ar9002_hw_pa_cal(ah, true);
|
||||
+ ath9k_hw_loadnf(ah, chan);
|
||||
+ ath9k_hw_start_nfcal(ah, true);
|
||||
|
||||
if (ah->caldata)
|
||||
set_bit(NFCAL_PENDING, &ah->caldata->cal_flags);
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -1953,8 +1953,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
||||
if (ath9k_hw_mci_is_enabled(ah))
|
||||
ar9003_mci_check_bt(ah);
|
||||
|
||||
- ath9k_hw_loadnf(ah, chan);
|
||||
- ath9k_hw_start_nfcal(ah, true);
|
||||
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
+ ath9k_hw_loadnf(ah, chan);
|
||||
+ ath9k_hw_start_nfcal(ah, true);
|
||||
+ }
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
ar9003_hw_bb_watchdog_config(ah);
|
|
@ -1,92 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Sat, 18 Oct 2014 18:24:15 +0200
|
||||
Subject: [PATCH] ath9k: add support for endian swap of eeprom from
|
||||
platform data
|
||||
|
||||
On some devices (especially little-endian ones), the flash EEPROM data
|
||||
has a different endian, which needs to be detected.
|
||||
Add a flag to the platform data to allow overriding that behavior
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
|
||||
@@ -262,7 +262,7 @@ static int ath9k_hw_def_check_eeprom(str
|
||||
{
|
||||
struct ar5416_eeprom_def *eep = &ah->eeprom.def;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
- u16 *eepdata, temp, magic, magic2;
|
||||
+ u16 *eepdata, temp, magic;
|
||||
u32 sum = 0, el;
|
||||
bool need_swap = false;
|
||||
int i, addr, size;
|
||||
@@ -272,27 +272,16 @@ static int ath9k_hw_def_check_eeprom(str
|
||||
return false;
|
||||
}
|
||||
|
||||
- if (!ath9k_hw_use_flash(ah)) {
|
||||
- ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic);
|
||||
-
|
||||
- if (magic != AR5416_EEPROM_MAGIC) {
|
||||
- magic2 = swab16(magic);
|
||||
-
|
||||
- if (magic2 == AR5416_EEPROM_MAGIC) {
|
||||
- size = sizeof(struct ar5416_eeprom_def);
|
||||
- need_swap = true;
|
||||
- eepdata = (u16 *) (&ah->eeprom);
|
||||
-
|
||||
- for (addr = 0; addr < size / sizeof(u16); addr++) {
|
||||
- temp = swab16(*eepdata);
|
||||
- *eepdata = temp;
|
||||
- eepdata++;
|
||||
- }
|
||||
- } else {
|
||||
- ath_err(common,
|
||||
- "Invalid EEPROM Magic. Endianness mismatch.\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
+ if (swab16(magic) == AR5416_EEPROM_MAGIC &&
|
||||
+ !(ah->ah_flags & AH_NO_EEP_SWAP)) {
|
||||
+ size = sizeof(struct ar5416_eeprom_def);
|
||||
+ need_swap = true;
|
||||
+ eepdata = (u16 *) (&ah->eeprom);
|
||||
+
|
||||
+ for (addr = 0; addr < size / sizeof(u16); addr++) {
|
||||
+ temp = swab16(*eepdata);
|
||||
+ *eepdata = temp;
|
||||
+ eepdata++;
|
||||
}
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.h
|
||||
@@ -731,6 +731,7 @@ enum ath_cal_list {
|
||||
#define AH_USE_EEPROM 0x1
|
||||
#define AH_UNPLUGGED 0x2 /* The card has been physically removed. */
|
||||
#define AH_FASTCC 0x4
|
||||
+#define AH_NO_EEP_SWAP 0x8 /* Do not swap EEPROM data */
|
||||
|
||||
struct ath_hw {
|
||||
struct ath_ops reg_ops;
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -531,6 +531,8 @@ static int ath9k_init_softc(u16 devid, s
|
||||
ah->is_clk_25mhz = pdata->is_clk_25mhz;
|
||||
ah->get_mac_revision = pdata->get_mac_revision;
|
||||
ah->external_reset = pdata->external_reset;
|
||||
+ if (!pdata->endian_check)
|
||||
+ ah->ah_flags |= AH_NO_EEP_SWAP;
|
||||
}
|
||||
|
||||
common->ops = &ah->reg_ops;
|
||||
--- a/include/linux/ath9k_platform.h
|
||||
+++ b/include/linux/ath9k_platform.h
|
||||
@@ -31,6 +31,7 @@ struct ath9k_platform_data {
|
||||
u32 gpio_mask;
|
||||
u32 gpio_val;
|
||||
|
||||
+ bool endian_check;
|
||||
bool is_clk_25mhz;
|
||||
bool tx_gain_buffalo;
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Sat, 18 Oct 2014 18:27:23 +0200
|
||||
Subject: [PATCH] ath9k: allow disabling bands via platform data
|
||||
|
||||
Some devices have multiple bands enables in the EEPROM data, even though
|
||||
they are only calibrated for one. Allow platform data to disable
|
||||
unsupported bands.
|
||||
|
||||
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -2344,17 +2344,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
|
||||
}
|
||||
|
||||
eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
|
||||
- if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) {
|
||||
- ath_err(common,
|
||||
- "no band has been marked as supported in EEPROM\n");
|
||||
- return -EINVAL;
|
||||
+
|
||||
+ if (eeval & AR5416_OPFLAGS_11A) {
|
||||
+ if (ah->disable_5ghz)
|
||||
+ ath_warn(common, "disabling 5GHz band\n");
|
||||
+ else
|
||||
+ pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
|
||||
}
|
||||
|
||||
- if (eeval & AR5416_OPFLAGS_11A)
|
||||
- pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
|
||||
+ if (eeval & AR5416_OPFLAGS_11G) {
|
||||
+ if (ah->disable_2ghz)
|
||||
+ ath_warn(common, "disabling 2GHz band\n");
|
||||
+ else
|
||||
+ pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
|
||||
+ }
|
||||
|
||||
- if (eeval & AR5416_OPFLAGS_11G)
|
||||
- pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
|
||||
+ if ((pCap->hw_caps & (ATH9K_HW_CAP_2GHZ | ATH9K_HW_CAP_5GHZ)) == 0) {
|
||||
+ ath_err(common, "both bands are disabled\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
if (AR_SREV_9485(ah) ||
|
||||
AR_SREV_9285(ah) ||
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.h
|
||||
@@ -930,6 +930,8 @@ struct ath_hw {
|
||||
bool is_clk_25mhz;
|
||||
int (*get_mac_revision)(void);
|
||||
int (*external_reset)(void);
|
||||
+ bool disable_2ghz;
|
||||
+ bool disable_5ghz;
|
||||
|
||||
const struct firmware *eeprom_blob;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -531,6 +531,8 @@ static int ath9k_init_softc(u16 devid, s
|
||||
ah->is_clk_25mhz = pdata->is_clk_25mhz;
|
||||
ah->get_mac_revision = pdata->get_mac_revision;
|
||||
ah->external_reset = pdata->external_reset;
|
||||
+ ah->disable_2ghz = pdata->disable_2ghz;
|
||||
+ ah->disable_5ghz = pdata->disable_5ghz;
|
||||
if (!pdata->endian_check)
|
||||
ah->ah_flags |= AH_NO_EEP_SWAP;
|
||||
}
|
||||
--- a/include/linux/ath9k_platform.h
|
||||
+++ b/include/linux/ath9k_platform.h
|
||||
@@ -34,6 +34,8 @@ struct ath9k_platform_data {
|
||||
bool endian_check;
|
||||
bool is_clk_25mhz;
|
||||
bool tx_gain_buffalo;
|
||||
+ bool disable_2ghz;
|
||||
+ bool disable_5ghz;
|
||||
|
||||
int (*get_mac_revision)(void);
|
||||
int (*external_reset)(void);
|
|
@ -1,39 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Sat, 18 Oct 2014 18:31:49 +0200
|
||||
Subject: [PATCH] ath9k: use a random MAC address if the EEPROM address
|
||||
is invalid
|
||||
|
||||
Based on OpenWrt patch by Gabor Juhos
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/bitops.h>
|
||||
+#include <linux/etherdevice.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "hw.h"
|
||||
@@ -446,8 +447,16 @@ static int ath9k_hw_init_macaddr(struct
|
||||
common->macaddr[2 * i] = eeval >> 8;
|
||||
common->macaddr[2 * i + 1] = eeval & 0xff;
|
||||
}
|
||||
- if (sum == 0 || sum == 0xffff * 3)
|
||||
- return -EADDRNOTAVAIL;
|
||||
+ if (!is_valid_ether_addr(common->macaddr)) {
|
||||
+ ath_err(common,
|
||||
+ "eeprom contains invalid mac address: %pM\n",
|
||||
+ common->macaddr);
|
||||
+
|
||||
+ random_ether_addr(common->macaddr);
|
||||
+ ath_err(common,
|
||||
+ "random mac address will be used: %pM\n",
|
||||
+ common->macaddr);
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Tue, 21 Oct 2014 19:23:02 +0530
|
||||
Subject: [PATCH] ath9k: Enable HW queue control only for MCC
|
||||
|
||||
Enabling HW queue control for normal (non-mcc) mode
|
||||
causes problems with queue management, resulting
|
||||
in traffic stall. Since it is mainly required for
|
||||
fairness in MCC mode, disable it for the general case.
|
||||
|
||||
Bug: https://dev.openwrt.org/ticket/18164
|
||||
|
||||
Cc: Felix Fietkau <nbd@openwrt.org>
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -741,6 +741,32 @@ static const struct ieee80211_iface_comb
|
||||
#endif
|
||||
};
|
||||
|
||||
+#ifdef CPTCFG_ATH9K_CHANNEL_CONTEXT
|
||||
+static void ath9k_set_mcc_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
+{
|
||||
+ struct ath_hw *ah = sc->sc_ah;
|
||||
+ struct ath_common *common = ath9k_hw_common(ah);
|
||||
+
|
||||
+ if (!ath9k_is_chanctx_enabled())
|
||||
+ return;
|
||||
+
|
||||
+ hw->flags |= IEEE80211_HW_QUEUE_CONTROL;
|
||||
+ hw->queues = ATH9K_NUM_TX_QUEUES;
|
||||
+ hw->offchannel_tx_hw_queue = hw->queues - 1;
|
||||
+ hw->wiphy->interface_modes &= ~ BIT(NL80211_IFTYPE_WDS);
|
||||
+ hw->wiphy->iface_combinations = if_comb_multi;
|
||||
+ hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_multi);
|
||||
+ hw->wiphy->max_scan_ssids = 255;
|
||||
+ hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
|
||||
+ hw->wiphy->max_remain_on_channel_duration = 10000;
|
||||
+ hw->chanctx_data_size = sizeof(void *);
|
||||
+ hw->extra_beacon_tailroom =
|
||||
+ sizeof(struct ieee80211_p2p_noa_attr) + 9;
|
||||
+
|
||||
+ ath_dbg(common, CHAN_CTX, "Use channel contexts\n");
|
||||
+}
|
||||
+#endif /* CPTCFG_ATH9K_CHANNEL_CONTEXT */
|
||||
+
|
||||
static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@@ -753,7 +779,6 @@ static void ath9k_set_hw_capab(struct at
|
||||
IEEE80211_HW_SPECTRUM_MGMT |
|
||||
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
|
||||
IEEE80211_HW_SUPPORTS_RC_TABLE |
|
||||
- IEEE80211_HW_QUEUE_CONTROL |
|
||||
IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
|
||||
|
||||
if (ath9k_ps_enable)
|
||||
@@ -788,24 +813,6 @@ static void ath9k_set_hw_capab(struct at
|
||||
hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
|
||||
}
|
||||
|
||||
-#ifdef CPTCFG_ATH9K_CHANNEL_CONTEXT
|
||||
-
|
||||
- if (ath9k_is_chanctx_enabled()) {
|
||||
- hw->wiphy->interface_modes &= ~ BIT(NL80211_IFTYPE_WDS);
|
||||
- hw->wiphy->iface_combinations = if_comb_multi;
|
||||
- hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_multi);
|
||||
- hw->wiphy->max_scan_ssids = 255;
|
||||
- hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
|
||||
- hw->wiphy->max_remain_on_channel_duration = 10000;
|
||||
- hw->chanctx_data_size = sizeof(void *);
|
||||
- hw->extra_beacon_tailroom =
|
||||
- sizeof(struct ieee80211_p2p_noa_attr) + 9;
|
||||
-
|
||||
- ath_dbg(common, CHAN_CTX, "Use channel contexts\n");
|
||||
- }
|
||||
-
|
||||
-#endif /* CPTCFG_ATH9K_CHANNEL_CONTEXT */
|
||||
-
|
||||
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
||||
@@ -815,12 +822,7 @@ static void ath9k_set_hw_capab(struct at
|
||||
hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
|
||||
hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
|
||||
|
||||
- /* allow 4 queues per channel context +
|
||||
- * 1 cab queue + 1 offchannel tx queue
|
||||
- */
|
||||
- hw->queues = ATH9K_NUM_TX_QUEUES;
|
||||
- /* last queue for offchannel */
|
||||
- hw->offchannel_tx_hw_queue = hw->queues - 1;
|
||||
+ hw->queues = 4;
|
||||
hw->max_rates = 4;
|
||||
hw->max_listen_interval = 10;
|
||||
hw->max_rate_tries = 10;
|
||||
@@ -844,6 +846,9 @@ static void ath9k_set_hw_capab(struct at
|
||||
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
|
||||
&common->sbands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
+#ifdef CPTCFG_ATH9K_CHANNEL_CONTEXT
|
||||
+ ath9k_set_mcc_capab(sc, hw);
|
||||
+#endif
|
||||
ath9k_init_wow(hw);
|
||||
ath9k_cmn_reload_chainmask(ah);
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -1181,6 +1181,9 @@ static void ath9k_assign_hw_queues(struc
|
||||
{
|
||||
int i;
|
||||
|
||||
+ if (!ath9k_is_chanctx_enabled())
|
||||
+ return;
|
||||
+
|
||||
for (i = 0; i < IEEE80211_NUM_ACS; i++)
|
||||
vif->hw_queue[i] = i;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/xmit.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
|
||||
@@ -169,7 +169,10 @@ static void ath_txq_skb_done(struct ath_
|
||||
|
||||
if (txq->stopped &&
|
||||
txq->pending_frames < sc->tx.txq_max_pending[q]) {
|
||||
- ieee80211_wake_queue(sc->hw, info->hw_queue);
|
||||
+ if (ath9k_is_chanctx_enabled())
|
||||
+ ieee80211_wake_queue(sc->hw, info->hw_queue);
|
||||
+ else
|
||||
+ ieee80211_wake_queue(sc->hw, q);
|
||||
txq->stopped = false;
|
||||
}
|
||||
}
|
||||
@@ -2247,7 +2250,10 @@ int ath_tx_start(struct ieee80211_hw *hw
|
||||
fi->txq = q;
|
||||
if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
|
||||
!txq->stopped) {
|
||||
- ieee80211_stop_queue(sc->hw, info->hw_queue);
|
||||
+ if (ath9k_is_chanctx_enabled())
|
||||
+ ieee80211_stop_queue(sc->hw, info->hw_queue);
|
||||
+ else
|
||||
+ ieee80211_stop_queue(sc->hw, q);
|
||||
txq->stopped = true;
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Wed, 22 Oct 2014 15:21:22 +0200
|
||||
Subject: [PATCH] ath: use CTL region from cfg80211 if unset in EEPROM
|
||||
|
||||
Many AP devices do not have the proper regulatory domain programmed in
|
||||
EEPROM. Instead they expect the software to set the appropriate region.
|
||||
For these devices, the country code defaults to US, and the driver uses
|
||||
the US CTL tables as well.
|
||||
On devices bought in Europe this can lead to tx power being set too high
|
||||
on the band edges, even if the cfg80211 regdomain is set correctly.
|
||||
Fix this issue by taking into account the DFS region, but only when the
|
||||
EEPROM regdomain is set to default.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath.h
|
||||
+++ b/drivers/net/wireless/ath/ath.h
|
||||
@@ -80,6 +80,7 @@ struct reg_dmn_pair_mapping {
|
||||
|
||||
struct ath_regulatory {
|
||||
char alpha2[2];
|
||||
+ enum nl80211_dfs_regions region;
|
||||
u16 country_code;
|
||||
u16 max_power_level;
|
||||
u16 current_rd;
|
||||
--- a/drivers/net/wireless/ath/regd.c
|
||||
+++ b/drivers/net/wireless/ath/regd.c
|
||||
@@ -515,6 +515,7 @@ void ath_reg_notifier_apply(struct wiphy
|
||||
if (!request)
|
||||
return;
|
||||
|
||||
+ reg->region = request->dfs_region;
|
||||
switch (request->initiator) {
|
||||
case NL80211_REGDOM_SET_BY_CORE:
|
||||
/*
|
||||
@@ -779,6 +780,19 @@ u32 ath_regd_get_band_ctl(struct ath_reg
|
||||
return SD_NO_CTL;
|
||||
}
|
||||
|
||||
+ if (ath_regd_get_eepromRD(reg) == CTRY_DEFAULT) {
|
||||
+ switch (reg->region) {
|
||||
+ case NL80211_DFS_FCC:
|
||||
+ return CTL_FCC;
|
||||
+ case NL80211_DFS_ETSI:
|
||||
+ return CTL_ETSI;
|
||||
+ case NL80211_DFS_JP:
|
||||
+ return CTL_MKK;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
switch (band) {
|
||||
case IEEE80211_BAND_2GHZ:
|
||||
return reg->regpair->reg_2ghz_ctl;
|
|
@ -1,162 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Wed, 22 Oct 2014 12:21:44 +0530
|
||||
Subject: [PATCH] ath9k: Update AR9580 initvals
|
||||
|
||||
This fixes RX sensitivity issues with AR9580.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
|
||||
@@ -24,7 +24,149 @@
|
||||
|
||||
#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble
|
||||
|
||||
-#define ar9580_1p0_radio_core ar9300_2p2_radio_core
|
||||
+static const u32 ar9580_1p0_radio_core[][2] = {
|
||||
+ /* Addr allmodes */
|
||||
+ {0x00016000, 0x36db2db6},
|
||||
+ {0x00016004, 0x6db6db40},
|
||||
+ {0x00016008, 0x73f00000},
|
||||
+ {0x0001600c, 0x00000000},
|
||||
+ {0x00016040, 0x7f80fff8},
|
||||
+ {0x0001604c, 0x76d005b5},
|
||||
+ {0x00016050, 0x556cf031},
|
||||
+ {0x00016054, 0x13449440},
|
||||
+ {0x00016058, 0x0c51c92c},
|
||||
+ {0x0001605c, 0x3db7fffc},
|
||||
+ {0x00016060, 0xfffffffc},
|
||||
+ {0x00016064, 0x000f0278},
|
||||
+ {0x0001606c, 0x6db60000},
|
||||
+ {0x00016080, 0x00000000},
|
||||
+ {0x00016084, 0x0e48048c},
|
||||
+ {0x00016088, 0x54214514},
|
||||
+ {0x0001608c, 0x119f481e},
|
||||
+ {0x00016090, 0x24926490},
|
||||
+ {0x00016098, 0xd2888888},
|
||||
+ {0x000160a0, 0x0a108ffe},
|
||||
+ {0x000160a4, 0x812fc370},
|
||||
+ {0x000160a8, 0x423c8000},
|
||||
+ {0x000160b4, 0x92480080},
|
||||
+ {0x000160c0, 0x00adb6d0},
|
||||
+ {0x000160c4, 0x6db6db60},
|
||||
+ {0x000160c8, 0x6db6db6c},
|
||||
+ {0x000160cc, 0x01e6c000},
|
||||
+ {0x00016100, 0x3fffbe01},
|
||||
+ {0x00016104, 0xfff80000},
|
||||
+ {0x00016108, 0x00080010},
|
||||
+ {0x00016144, 0x02084080},
|
||||
+ {0x00016148, 0x00000000},
|
||||
+ {0x00016280, 0x058a0001},
|
||||
+ {0x00016284, 0x3d840208},
|
||||
+ {0x00016288, 0x05a20408},
|
||||
+ {0x0001628c, 0x00038c07},
|
||||
+ {0x00016290, 0x00000004},
|
||||
+ {0x00016294, 0x458a214f},
|
||||
+ {0x00016380, 0x00000000},
|
||||
+ {0x00016384, 0x00000000},
|
||||
+ {0x00016388, 0x00800700},
|
||||
+ {0x0001638c, 0x00800700},
|
||||
+ {0x00016390, 0x00800700},
|
||||
+ {0x00016394, 0x00000000},
|
||||
+ {0x00016398, 0x00000000},
|
||||
+ {0x0001639c, 0x00000000},
|
||||
+ {0x000163a0, 0x00000001},
|
||||
+ {0x000163a4, 0x00000001},
|
||||
+ {0x000163a8, 0x00000000},
|
||||
+ {0x000163ac, 0x00000000},
|
||||
+ {0x000163b0, 0x00000000},
|
||||
+ {0x000163b4, 0x00000000},
|
||||
+ {0x000163b8, 0x00000000},
|
||||
+ {0x000163bc, 0x00000000},
|
||||
+ {0x000163c0, 0x000000a0},
|
||||
+ {0x000163c4, 0x000c0000},
|
||||
+ {0x000163c8, 0x14021402},
|
||||
+ {0x000163cc, 0x00001402},
|
||||
+ {0x000163d0, 0x00000000},
|
||||
+ {0x000163d4, 0x00000000},
|
||||
+ {0x00016400, 0x36db2db6},
|
||||
+ {0x00016404, 0x6db6db40},
|
||||
+ {0x00016408, 0x73f00000},
|
||||
+ {0x0001640c, 0x00000000},
|
||||
+ {0x00016440, 0x7f80fff8},
|
||||
+ {0x0001644c, 0x76d005b5},
|
||||
+ {0x00016450, 0x556cf031},
|
||||
+ {0x00016454, 0x13449440},
|
||||
+ {0x00016458, 0x0c51c92c},
|
||||
+ {0x0001645c, 0x3db7fffc},
|
||||
+ {0x00016460, 0xfffffffc},
|
||||
+ {0x00016464, 0x000f0278},
|
||||
+ {0x0001646c, 0x6db60000},
|
||||
+ {0x00016500, 0x3fffbe01},
|
||||
+ {0x00016504, 0xfff80000},
|
||||
+ {0x00016508, 0x00080010},
|
||||
+ {0x00016544, 0x02084080},
|
||||
+ {0x00016548, 0x00000000},
|
||||
+ {0x00016780, 0x00000000},
|
||||
+ {0x00016784, 0x00000000},
|
||||
+ {0x00016788, 0x00800700},
|
||||
+ {0x0001678c, 0x00800700},
|
||||
+ {0x00016790, 0x00800700},
|
||||
+ {0x00016794, 0x00000000},
|
||||
+ {0x00016798, 0x00000000},
|
||||
+ {0x0001679c, 0x00000000},
|
||||
+ {0x000167a0, 0x00000001},
|
||||
+ {0x000167a4, 0x00000001},
|
||||
+ {0x000167a8, 0x00000000},
|
||||
+ {0x000167ac, 0x00000000},
|
||||
+ {0x000167b0, 0x00000000},
|
||||
+ {0x000167b4, 0x00000000},
|
||||
+ {0x000167b8, 0x00000000},
|
||||
+ {0x000167bc, 0x00000000},
|
||||
+ {0x000167c0, 0x000000a0},
|
||||
+ {0x000167c4, 0x000c0000},
|
||||
+ {0x000167c8, 0x14021402},
|
||||
+ {0x000167cc, 0x00001402},
|
||||
+ {0x000167d0, 0x00000000},
|
||||
+ {0x000167d4, 0x00000000},
|
||||
+ {0x00016800, 0x36db2db6},
|
||||
+ {0x00016804, 0x6db6db40},
|
||||
+ {0x00016808, 0x73f00000},
|
||||
+ {0x0001680c, 0x00000000},
|
||||
+ {0x00016840, 0x7f80fff8},
|
||||
+ {0x0001684c, 0x76d005b5},
|
||||
+ {0x00016850, 0x556cf031},
|
||||
+ {0x00016854, 0x13449440},
|
||||
+ {0x00016858, 0x0c51c92c},
|
||||
+ {0x0001685c, 0x3db7fffc},
|
||||
+ {0x00016860, 0xfffffffc},
|
||||
+ {0x00016864, 0x000f0278},
|
||||
+ {0x0001686c, 0x6db60000},
|
||||
+ {0x00016900, 0x3fffbe01},
|
||||
+ {0x00016904, 0xfff80000},
|
||||
+ {0x00016908, 0x00080010},
|
||||
+ {0x00016944, 0x02084080},
|
||||
+ {0x00016948, 0x00000000},
|
||||
+ {0x00016b80, 0x00000000},
|
||||
+ {0x00016b84, 0x00000000},
|
||||
+ {0x00016b88, 0x00800700},
|
||||
+ {0x00016b8c, 0x00800700},
|
||||
+ {0x00016b90, 0x00800700},
|
||||
+ {0x00016b94, 0x00000000},
|
||||
+ {0x00016b98, 0x00000000},
|
||||
+ {0x00016b9c, 0x00000000},
|
||||
+ {0x00016ba0, 0x00000001},
|
||||
+ {0x00016ba4, 0x00000001},
|
||||
+ {0x00016ba8, 0x00000000},
|
||||
+ {0x00016bac, 0x00000000},
|
||||
+ {0x00016bb0, 0x00000000},
|
||||
+ {0x00016bb4, 0x00000000},
|
||||
+ {0x00016bb8, 0x00000000},
|
||||
+ {0x00016bbc, 0x00000000},
|
||||
+ {0x00016bc0, 0x000000a0},
|
||||
+ {0x00016bc4, 0x000c0000},
|
||||
+ {0x00016bc8, 0x14021402},
|
||||
+ {0x00016bcc, 0x00001402},
|
||||
+ {0x00016bd0, 0x00000000},
|
||||
+ {0x00016bd4, 0x00000000},
|
||||
+};
|
||||
|
||||
#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
Date: Wed, 22 Oct 2014 12:21:45 +0530
|
||||
Subject: [PATCH] ath9k: Update AR955x initvals
|
||||
|
||||
* Fix a 11b/EVM issue by adjusting
|
||||
FIR filter coefficients.
|
||||
|
||||
* Fix a problem with receiving probe request
|
||||
frames sent at 11b rate.
|
||||
|
||||
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h
|
||||
@@ -507,7 +507,7 @@ static const u32 ar955x_1p0_baseband_cor
|
||||
{0x00009d04, 0x40206c10},
|
||||
{0x00009d08, 0x009c4060},
|
||||
{0x00009d0c, 0x9883800a},
|
||||
- {0x00009d10, 0x01834061},
|
||||
+ {0x00009d10, 0x01884061},
|
||||
{0x00009d14, 0x00c0040b},
|
||||
{0x00009d18, 0x00000000},
|
||||
{0x00009e08, 0x0038230c},
|
||||
@@ -545,9 +545,9 @@ static const u32 ar955x_1p0_baseband_cor
|
||||
{0x0000a370, 0x00000000},
|
||||
{0x0000a390, 0x00000001},
|
||||
{0x0000a394, 0x00000444},
|
||||
- {0x0000a398, 0x1f020503},
|
||||
- {0x0000a39c, 0x29180c03},
|
||||
- {0x0000a3a0, 0x9a8b6844},
|
||||
+ {0x0000a398, 0x001f0e0f},
|
||||
+ {0x0000a39c, 0x0075393f},
|
||||
+ {0x0000a3a0, 0xb79f6427},
|
||||
{0x0000a3a4, 0x00000000},
|
||||
{0x0000a3a8, 0xaaaaaaaa},
|
||||
{0x0000a3ac, 0x3c466478},
|
|
@ -1,43 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Wed, 22 Oct 2014 17:55:50 +0200
|
||||
Subject: [PATCH] mac80211: add support for driver tx power reporting
|
||||
|
||||
The configured tx power is often limited by hardware capabilities,
|
||||
channel settings, antenna configuration, etc.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -2838,6 +2838,9 @@ enum ieee80211_roc_type {
|
||||
* @get_expected_throughput: extract the expected throughput towards the
|
||||
* specified station. The returned value is expressed in Kbps. It returns 0
|
||||
* if the RC algorithm does not have proper data to provide.
|
||||
+ *
|
||||
+ * @get_txpower: get current maximum tx power (in dBm) based on configuration
|
||||
+ * and hardware limits.
|
||||
*/
|
||||
struct ieee80211_ops {
|
||||
void (*tx)(struct ieee80211_hw *hw,
|
||||
@@ -3039,6 +3042,8 @@ struct ieee80211_ops {
|
||||
int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
|
||||
void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
|
||||
u32 (*get_expected_throughput)(struct ieee80211_sta *sta);
|
||||
+ int (*get_txpower)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
+ int *dbm);
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -2081,6 +2081,9 @@ static int ieee80211_get_tx_power(struct
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||
|
||||
+ if (local->ops->get_txpower)
|
||||
+ return local->ops->get_txpower(&local->hw, &sdata->vif, dbm);
|
||||
+
|
||||
if (!local->use_chanctx)
|
||||
*dbm = local->hw.conf.power_level;
|
||||
else
|
|
@ -1,31 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Wed, 22 Oct 2014 18:16:14 +0200
|
||||
Subject: [PATCH] ath9k_common: always update value in
|
||||
ath9k_cmn_update_txpow
|
||||
|
||||
In some cases the limit may be the same as reg->power_limit, but the
|
||||
actual value that the hardware uses is not up to date. In that case, a
|
||||
wrong value for current tx power is tracked internally.
|
||||
Fix this by unconditionally updating it.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/common.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/common.c
|
||||
@@ -368,11 +368,11 @@ void ath9k_cmn_update_txpow(struct ath_h
|
||||
{
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
|
||||
|
||||
- if (reg->power_limit != new_txpow) {
|
||||
+ if (reg->power_limit != new_txpow)
|
||||
ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
|
||||
- /* read back in case value is clamped */
|
||||
- *txpower = reg->max_power_level;
|
||||
- }
|
||||
+
|
||||
+ /* read back in case value is clamped */
|
||||
+ *txpower = reg->max_power_level;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_cmn_update_txpow);
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
From: Karsten Wiese <fzuuzf@googlemail.com>
|
||||
Date: Wed, 22 Oct 2014 15:47:32 +0200
|
||||
Subject: [PATCH] rtl8192cu: Fix for rtlwifi's bluetooth coexist
|
||||
functionality
|
||||
|
||||
Initialize function pointer with a function indicating bt coexist is not there.
|
||||
Prevents Ooops.
|
||||
|
||||
Signed-off-by: Karsten Wiese <fzuuzf@googlemail.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
|
||||
@@ -101,6 +101,12 @@ static void rtl92cu_deinit_sw_vars(struc
|
||||
}
|
||||
}
|
||||
|
||||
+/* get bt coexist status */
|
||||
+static bool rtl92cu_get_btc_status(void)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static struct rtl_hal_ops rtl8192cu_hal_ops = {
|
||||
.init_sw_vars = rtl92cu_init_sw_vars,
|
||||
.deinit_sw_vars = rtl92cu_deinit_sw_vars,
|
||||
@@ -148,6 +154,7 @@ static struct rtl_hal_ops rtl8192cu_hal_
|
||||
.phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback,
|
||||
.dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower,
|
||||
.fill_h2c_cmd = rtl92c_fill_h2c_cmd,
|
||||
+ .get_btc_status = rtl92cu_get_btc_status,
|
||||
};
|
||||
|
||||
static struct rtl_mod_params rtl92cu_mod_params = {
|
|
@ -1,33 +0,0 @@
|
|||
From: Karsten Wiese <fzuuzf@googlemail.com>
|
||||
Date: Wed, 22 Oct 2014 15:47:33 +0200
|
||||
Subject: [PATCH] rtl8192cu: Call ieee80211_register_hw from rtl_usb_probe
|
||||
|
||||
In a previous patch the call to ieee80211_register_hw was moved from the
|
||||
load firmware callback to the rtl_pci_probe only.
|
||||
rt8192cu also uses this callback. Currently it doesnt create a wlan%d device.
|
||||
Fill in the call to ieee80211_register_hw in rtl_usb_probe.
|
||||
|
||||
Signed-off-by: Karsten Wiese <fzuuzf@googlemail.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/rtlwifi/usb.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/usb.c
|
||||
@@ -1117,7 +1117,18 @@ int rtl_usb_probe(struct usb_interface *
|
||||
}
|
||||
rtlpriv->cfg->ops->init_sw_leds(hw);
|
||||
|
||||
+ err = ieee80211_register_hw(hw);
|
||||
+ if (err) {
|
||||
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
+ "Can't register mac80211 hw.\n");
|
||||
+ err = -ENODEV;
|
||||
+ goto error_out;
|
||||
+ }
|
||||
+ rtlpriv->mac80211.mac80211_registered = 1;
|
||||
+
|
||||
+ set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
|
||||
return 0;
|
||||
+
|
||||
error_out:
|
||||
rtl_deinit_core(hw);
|
||||
_rtl_usb_io_handler_release(hw);
|
|
@ -1,107 +0,0 @@
|
|||
From: Karsten Wiese <fzuuzf@googlemail.com>
|
||||
Date: Wed, 22 Oct 2014 15:47:34 +0200
|
||||
Subject: [PATCH] rtl8192cu: Prevent Ooops under rtl92c_set_fw_rsvdpagepkt
|
||||
|
||||
rtl92c_set_fw_rsvdpagepkt is used by rtl8192cu and its pci sibling rtl8192ce.
|
||||
rtl_cmd_send_packet crashes when called inside rtl8192cu because it works on
|
||||
memory allocated only by rtl8192ce.
|
||||
Fix the crash by calling a dummy function when used in rtl8192cu.
|
||||
Comparision with the realtek vendor driver makes me think, something is missing in
|
||||
the dummy function.
|
||||
Short test as WPA2 station show good results connected to an 802.11g basestation.
|
||||
Traffic stops after few MBytes as WPA2 station connected to an 802.11n basestation.
|
||||
|
||||
Signed-off-by: Karsten Wiese <fzuuzf@googlemail.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
|
||||
@@ -656,7 +656,8 @@ static u8 reserved_page_packet[TOTAL_RES
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
-void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
|
||||
+void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw,
|
||||
+ bool (*cmd_send_packet)(struct ieee80211_hw *, struct sk_buff *))
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
@@ -722,7 +723,10 @@ void rtl92c_set_fw_rsvdpagepkt(struct ie
|
||||
memcpy((u8 *)skb_put(skb, totalpacketlen),
|
||||
&reserved_page_packet, totalpacketlen);
|
||||
|
||||
- rtstatus = rtl_cmd_send_packet(hw, skb);
|
||||
+ if (cmd_send_packet)
|
||||
+ rtstatus = cmd_send_packet(hw, skb);
|
||||
+ else
|
||||
+ rtstatus = rtl_cmd_send_packet(hw, skb);
|
||||
|
||||
if (rtstatus)
|
||||
b_dlok = true;
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
|
||||
@@ -109,7 +109,9 @@ void rtl92c_fill_h2c_cmd(struct ieee8021
|
||||
u32 cmd_len, u8 *p_cmdbuffer);
|
||||
void rtl92c_firmware_selfreset(struct ieee80211_hw *hw);
|
||||
void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
|
||||
-void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
|
||||
+void rtl92c_set_fw_rsvdpagepkt
|
||||
+ (struct ieee80211_hw *hw,
|
||||
+ bool (*cmd_send_packet)(struct ieee80211_hw *, struct sk_buff *));
|
||||
void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
|
||||
void usb_writeN_async(struct rtl_priv *rtlpriv, u32 addr, void *data, u16 len);
|
||||
void rtl92c_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
|
||||
@@ -459,7 +459,7 @@ void rtl92ce_set_hw_reg(struct ieee80211
|
||||
rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
|
||||
tmp_reg422 & (~BIT(6)));
|
||||
|
||||
- rtl92c_set_fw_rsvdpagepkt(hw, 0);
|
||||
+ rtl92c_set_fw_rsvdpagepkt(hw, NULL);
|
||||
|
||||
_rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0);
|
||||
_rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4));
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
|
||||
@@ -1592,6 +1592,20 @@ void rtl92cu_get_hw_reg(struct ieee80211
|
||||
}
|
||||
}
|
||||
|
||||
+bool usb_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
+{
|
||||
+ /* Currently nothing happens here.
|
||||
+ * Traffic stops after some seconds in WPA2 802.11n mode.
|
||||
+ * Maybe because rtl8192cu chip should be set from here?
|
||||
+ * If I understand correctly, the realtek vendor driver sends some urbs
|
||||
+ * if its "here".
|
||||
+ *
|
||||
+ * This is maybe necessary:
|
||||
+ * rtlpriv->cfg->ops->fill_tx_cmddesc(hw, buffer, 1, 1, skb);
|
||||
+ */
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
@@ -1939,7 +1953,8 @@ void rtl92cu_set_hw_reg(struct ieee80211
|
||||
recover = true;
|
||||
rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
|
||||
tmp_reg422 & (~BIT(6)));
|
||||
- rtl92c_set_fw_rsvdpagepkt(hw, 0);
|
||||
+ rtl92c_set_fw_rsvdpagepkt(hw,
|
||||
+ &usb_cmd_send_packet);
|
||||
_rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0);
|
||||
_rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4));
|
||||
if (recover)
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
|
||||
@@ -104,7 +104,6 @@ bool rtl92cu_gpio_radio_on_off_checking(
|
||||
void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
|
||||
int rtl92c_download_fw(struct ieee80211_hw *hw);
|
||||
void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
|
||||
-void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished);
|
||||
void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
|
||||
void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
|
||||
u8 element_id, u32 cmd_len, u8 *p_cmdbuffer);
|
|
@ -1,23 +0,0 @@
|
|||
From: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Mon, 27 Oct 2014 11:50:28 +0100
|
||||
Subject: [PATCH] mac80211: flush keys for AP mode on ieee80211_do_stop
|
||||
|
||||
Userspace can add keys to an AP mode interface before start_ap has been
|
||||
called. If there have been no calls to start_ap/stop_ap in the mean
|
||||
time, the keys will still be around when the interface is brought down.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -931,9 +931,6 @@ static void ieee80211_do_stop(struct iee
|
||||
* another CPU.
|
||||
*/
|
||||
ieee80211_free_keys(sdata, true);
|
||||
-
|
||||
- /* fall through */
|
||||
- case NL80211_IFTYPE_AP:
|
||||
skb_queue_purge(&sdata->skb_queue);
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Mon, 3 Nov 2014 14:29:09 +0100
|
||||
Subject: [PATCH] mac80211: fix use-after-free in defragmentation
|
||||
|
||||
Upon receiving the last fragment, all but the first fragment
|
||||
are freed, but the multicast check for statistics at the end
|
||||
of the function refers to the current skb (the last fragment)
|
||||
causing a use-after-free bug.
|
||||
|
||||
Since multicast frames cannot be fragmented and we check for
|
||||
this early in the function, just modify that check to also
|
||||
do the accounting to fix the issue.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Reported-by: Yosef Khyal <yosefx.khyal@intel.com>
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -1678,11 +1678,14 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||
sc = le16_to_cpu(hdr->seq_ctrl);
|
||||
frag = sc & IEEE80211_SCTL_FRAG;
|
||||
|
||||
- if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
|
||||
- is_multicast_ether_addr(hdr->addr1))) {
|
||||
- /* not fragmented */
|
||||
+ if (likely(!ieee80211_has_morefrags(fc) && frag == 0))
|
||||
+ goto out;
|
||||
+
|
||||
+ if (is_multicast_ether_addr(hdr->addr1)) {
|
||||
+ rx->local->dot11MulticastReceivedFrameCount++;
|
||||
goto out;
|
||||
}
|
||||
+
|
||||
I802_DEBUG_INC(rx->local->rx_handlers_fragments);
|
||||
|
||||
if (skb_linearize(rx->skb))
|
||||
@@ -1775,10 +1778,7 @@ ieee80211_rx_h_defragment(struct ieee802
|
||||
out:
|
||||
if (rx->sta)
|
||||
rx->sta->rx_packets++;
|
||||
- if (is_multicast_ether_addr(hdr->addr1))
|
||||
- rx->local->dot11MulticastReceivedFrameCount++;
|
||||
- else
|
||||
- ieee80211_led_rx(rx->local);
|
||||
+ ieee80211_led_rx(rx->local);
|
||||
return RX_CONTINUE;
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@
|
|||
---help---
|
||||
--- a/.local-symbols
|
||||
+++ b/.local-symbols
|
||||
@@ -112,6 +112,7 @@ RTL8187_LEDS=
|
||||
@@ -116,6 +116,7 @@ RTL8187_LEDS=
|
||||
ATH_COMMON=
|
||||
ATH_CARDS=
|
||||
ATH_DEBUG=
|
||||
|
|
|
@ -11,7 +11,7 @@ drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++
|
|||
|
||||
--- a/drivers/net/wireless/ath/ath5k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath5k/debug.c
|
||||
@@ -822,6 +822,97 @@ static const struct file_operations fops
|
||||
@@ -823,6 +823,97 @@ static const struct file_operations fops
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
|
@ -109,7 +109,7 @@ drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++
|
|||
|
||||
/* debugfs: queues etc */
|
||||
|
||||
@@ -1009,6 +1100,9 @@ ath5k_debug_init_device(struct ath5k_hw
|
||||
@@ -1010,6 +1101,9 @@ ath5k_debug_init_device(struct ath5k_hw
|
||||
debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah,
|
||||
&fops_beacon);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -2214,6 +2214,7 @@ struct cfg80211_qos_map {
|
||||
@@ -2245,6 +2245,7 @@ struct cfg80211_qos_map {
|
||||
* (as advertised by the nl80211 feature flag.)
|
||||
* @get_tx_power: store the current TX power into the dbm variable;
|
||||
* return 0 if successful
|
||||
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
* @set_wds_peer: set the WDS peer for a WDS interface
|
||||
*
|
||||
@@ -2450,6 +2451,7 @@ struct cfg80211_ops {
|
||||
@@ -2495,6 +2496,7 @@ struct cfg80211_ops {
|
||||
enum nl80211_tx_power_setting type, int mbm);
|
||||
int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
int *dbm);
|
||||
|
@ -18,7 +18,7 @@
|
|||
const u8 *addr);
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -1075,6 +1075,7 @@ enum ieee80211_smps_mode {
|
||||
@@ -1078,6 +1078,7 @@ enum ieee80211_smps_mode {
|
||||
*
|
||||
* @power_level: requested transmit power (in dBm), backward compatibility
|
||||
* value only that is set to the minimum of all interfaces
|
||||
|
@ -26,7 +26,7 @@
|
|||
*
|
||||
* @chandef: the channel definition to tune to
|
||||
* @radar_enabled: whether radar detection is enabled
|
||||
@@ -1096,6 +1097,7 @@ struct ieee80211_conf {
|
||||
@@ -1099,6 +1100,7 @@ struct ieee80211_conf {
|
||||
u32 flags;
|
||||
int power_level, dynamic_ps_timeout;
|
||||
int max_sleep_period;
|
||||
|
@ -36,7 +36,7 @@
|
|||
u8 ps_dtim_period;
|
||||
--- a/include/uapi/linux/nl80211.h
|
||||
+++ b/include/uapi/linux/nl80211.h
|
||||
@@ -1638,6 +1638,9 @@ enum nl80211_commands {
|
||||
@@ -1656,6 +1656,9 @@ enum nl80211_commands {
|
||||
* @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see
|
||||
* &enum nl80211_smps_mode.
|
||||
*
|
||||
|
@ -46,7 +46,7 @@
|
|||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
*/
|
||||
@@ -1990,6 +1993,8 @@ enum nl80211_attrs {
|
||||
@@ -2008,6 +2011,8 @@ enum nl80211_attrs {
|
||||
|
||||
NL80211_ATTR_SMPS_MODE,
|
||||
|
||||
|
@ -57,7 +57,7 @@
|
|||
__NL80211_ATTR_AFTER_LAST,
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -2091,6 +2091,19 @@ static int ieee80211_get_tx_power(struct
|
||||
@@ -2155,6 +2155,19 @@ static int ieee80211_get_tx_power(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@
|
|||
static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *addr)
|
||||
{
|
||||
@@ -3572,6 +3585,7 @@ const struct cfg80211_ops mac80211_confi
|
||||
@@ -3723,6 +3736,7 @@ const struct cfg80211_ops mac80211_confi
|
||||
.set_wiphy_params = ieee80211_set_wiphy_params,
|
||||
.set_tx_power = ieee80211_set_tx_power,
|
||||
.get_tx_power = ieee80211_get_tx_power,
|
||||
|
@ -87,7 +87,7 @@
|
|||
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1280,6 +1280,7 @@ struct ieee80211_local {
|
||||
@@ -1330,6 +1330,7 @@ struct ieee80211_local {
|
||||
int dynamic_ps_forced_timeout;
|
||||
|
||||
int user_power_level; /* in dBm, for all interfaces */
|
||||
|
@ -119,7 +119,7 @@
|
|||
if (local->hw.conf.power_level != power) {
|
||||
changed |= IEEE80211_CONF_CHANGE_POWER;
|
||||
local->hw.conf.power_level = power;
|
||||
@@ -585,6 +591,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(
|
||||
@@ -578,6 +584,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
|
||||
IEEE80211_RADIOTAP_MCS_HAVE_BW;
|
||||
local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
|
||||
IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
|
||||
|
@ -137,7 +137,7 @@
|
|||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@@ -2179,6 +2180,20 @@ static int nl80211_set_wiphy(struct sk_b
|
||||
@@ -2184,6 +2185,20 @@ static int nl80211_set_wiphy(struct sk_b
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
void (*spectral_scan_trigger)(struct ath_hw *ah);
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
@@ -1796,6 +1796,26 @@ static void ar9003_hw_tx99_set_txpower(s
|
||||
@@ -1799,6 +1799,26 @@ static void ar9003_hw_tx99_set_txpower(s
|
||||
ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_14], 0));
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
|||
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
@@ -1831,6 +1851,7 @@ void ar9003_hw_attach_phy_ops(struct ath
|
||||
@@ -1834,6 +1854,7 @@ void ar9003_hw_attach_phy_ops(struct ath
|
||||
priv_ops->set_radar_params = ar9003_hw_set_radar_params;
|
||||
priv_ops->fast_chan_change = ar9003_hw_fast_chan_change;
|
||||
|
||||
|
@ -110,7 +110,7 @@
|
|||
static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
|
||||
@@ -1232,9 +1232,30 @@ static void ar5008_hw_set_radar_conf(str
|
||||
@@ -1235,9 +1235,30 @@ static void ar5008_hw_set_radar_conf(str
|
||||
conf->radar_inband = 8;
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@
|
|||
static const u32 ar5416_cca_regs[6] = {
|
||||
AR_PHY_CCA,
|
||||
AR_PHY_CH1_CCA,
|
||||
@@ -1249,6 +1270,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
|
||||
@@ -1252,6 +1273,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/.local-symbols
|
||||
+++ b/.local-symbols
|
||||
@@ -285,6 +285,7 @@ RT2X00_LIB_FIRMWARE=
|
||||
@@ -289,6 +289,7 @@ RT2X00_LIB_FIRMWARE=
|
||||
RT2X00_LIB_CRYPTO=
|
||||
RT2X00_LIB_LEDS=
|
||||
RT2X00_LIB_DEBUGFS=
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/drivers/net/wireless/ath/ath10k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
|
||||
@@ -250,7 +250,10 @@ static int ath10k_download_and_run_otp(s
|
||||
@@ -280,7 +280,10 @@ static int ath10k_download_and_run_otp(s
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
|
||||
|
||||
|
|
Loading…
Reference in a new issue