* Re: [RFC] ath9k: update hw configuration for virtual wiphys
From: Luis R. Rodriguez @ 2009-10-29 1:36 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: Jouni.Malinen, linux-wireless, ath9k-devel
In-Reply-To: <1256762627-1574-1-git-send-email-lrodriguez@atheros.com>
On Wed, Oct 28, 2009 at 04:43:47PM -0400, Luis R. Rodriguez wrote:
> ath9k supports its own virtual wiphys. The hardware code
> relies on the ieee80211_hw for the present interface but
> with recent changes introduced the common->hw was never
> updated and is required for virtual wiphys.
>
> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
> ---
>
> Jouni, it seems this the right place for this, do you agree?
>
> drivers/net/wireless/ath/ath9k/virtual.c | 5 +++++
> 1 files changed, 5 insertions(+), 0 deletions(-)
Here is a bigger alternative to that 5-line patch. What it
illustrates is that the the current virtual wiphy needs to be kept
record of for asynchronous events one way or another. I list
the events below.
Luis
From: Luis R. Rodriguez <lrodriguez@atheros.com>
Subject: [PATCH] ath9k: update hw configuration for virtual wiphys
ath9k supports its own virtual wiphys. The hardware code
relies on the ieee80211_hw for the present interface but
with recent changes introduced the common->hw was never
updated and is required for virtual wiphys. Instead of
relying on the common->hw pointer remove it and instead
require all hw code to pass the currently used ieee80211_hw
struct used.
Worth noting though is that at specific events we need
the hw code to access the hw configuration and during
those events the driver has currently no way of knowing
what the currently used virtual wiphy. For now we stick
to using the sc->hw for those events. These events are:
Interrupt:
* ISR --> ATH9K_INT_MIB --> ath9k_hw_procmibevent()
* tasklet --> ATH9K_INT_FATAL --> ath_reset()
* beacon tasklet --> ath_reset()
Timer:
* ath_ani_calibrate -->
ath9k_hw_reset_calvalid()
ath9k_hw_ani_monitor()
Xmit:
* ath_tx_complete_poll_work --> needreset --> ath_reset() (Xmit hang check)
* tasklet --> tx --> ath_tx_complete_aggr() --> needreset --> ath_reset()
* tasklet --> ath_draintxq --> ath_tx_complete_aggr() --> needreset --> ath_reset()
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath.h | 1 -
drivers/net/wireless/ath/ath5k/base.c | 1 -
drivers/net/wireless/ath/ath9k/ani.c | 21 +++---
drivers/net/wireless/ath/ath9k/ani.h | 5 +-
drivers/net/wireless/ath/ath9k/ath9k.h | 8 ++-
drivers/net/wireless/ath/ath9k/beacon.c | 4 +-
drivers/net/wireless/ath/ath9k/calib.c | 20 +++---
drivers/net/wireless/ath/ath9k/calib.h | 3 +-
drivers/net/wireless/ath/ath9k/hw.c | 115 ++++++++++++++++++-----------
drivers/net/wireless/ath/ath9k/hw.h | 11 ++-
drivers/net/wireless/ath/ath9k/main.c | 44 +++++++-----
drivers/net/wireless/ath/ath9k/virtual.c | 6 +-
drivers/net/wireless/ath/ath9k/xmit.c | 6 +-
13 files changed, 150 insertions(+), 95 deletions(-)
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 5e19a73..e97f5c9 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -62,7 +62,6 @@ struct ath_bus_ops {
struct ath_common {
void *ah;
void *priv;
- struct ieee80211_hw *hw;
int debug_mask;
enum ath_device_state state;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 07c1e52..523b359 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -594,7 +594,6 @@ ath5k_pci_probe(struct pci_dev *pdev,
common = ath5k_hw_common(sc->ah);
common->ops = &ath5k_common_ops;
common->ah = sc->ah;
- common->hw = hw;
common->cachelsz = csz << 2; /* convert to bytes */
/* Initialize device */
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 2a0cd64..dd87cbd 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -273,9 +273,10 @@ static void ath9k_ani_restart(struct ath_hw *ah)
aniState->cckPhyErrCount = 0;
}
-static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
+static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah,
+ struct ieee80211_hw *hw)
{
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+ struct ieee80211_conf *conf = &hw->conf;
struct ar5416AniState *aniState;
int32_t rssi;
@@ -345,9 +346,10 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
}
}
-static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
+static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah,
+ struct ieee80211_hw *hw)
{
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+ struct ieee80211_conf *conf = &hw->conf;
struct ar5416AniState *aniState;
int32_t rssi;
@@ -545,6 +547,7 @@ void ath9k_ani_reset(struct ath_hw *ah)
}
void ath9k_hw_ani_monitor(struct ath_hw *ah,
+ struct ieee80211_hw *hw,
struct ath9k_channel *chan)
{
struct ar5416AniState *aniState;
@@ -619,12 +622,12 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
} else if (aniState->listenTime > ah->aniperiod) {
if (aniState->ofdmPhyErrCount > aniState->listenTime *
aniState->ofdmTrigHigh / 1000) {
- ath9k_hw_ani_ofdm_err_trigger(ah);
+ ath9k_hw_ani_ofdm_err_trigger(ah, hw);
ath9k_ani_restart(ah);
} else if (aniState->cckPhyErrCount >
aniState->listenTime * aniState->cckTrigHigh /
1000) {
- ath9k_hw_ani_cck_err_trigger(ah);
+ ath9k_hw_ani_cck_err_trigger(ah, hw);
ath9k_ani_restart(ah);
}
}
@@ -708,7 +711,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
* any of the MIB counters overflow/trigger so don't assume we're
* here because a PHY error counter triggered.
*/
-void ath9k_hw_procmibevent(struct ath_hw *ah)
+void ath9k_hw_procmibevent(struct ath_hw *ah, struct ieee80211_hw *hw)
{
u32 phyCnt1, phyCnt2;
@@ -750,9 +753,9 @@ void ath9k_hw_procmibevent(struct ath_hw *ah)
* check will never be true.
*/
if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
- ath9k_hw_ani_ofdm_err_trigger(ah);
+ ath9k_hw_ani_ofdm_err_trigger(ah, hw);
if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
- ath9k_hw_ani_cck_err_trigger(ah);
+ ath9k_hw_ani_cck_err_trigger(ah, hw);
/* NB: always restart to insure the h/w counters are reset */
ath9k_ani_restart(ah);
}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 4e1ab94..ac0592e 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -17,6 +17,8 @@
#ifndef ANI_H
#define ANI_H
+#include "hw.h"
+
#define HAL_PROCESS_ANI 0x00000001
#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
@@ -110,12 +112,13 @@ struct ar5416Stats {
void ath9k_ani_reset(struct ath_hw *ah);
void ath9k_hw_ani_monitor(struct ath_hw *ah,
+ struct ieee80211_hw *hw,
struct ath9k_channel *chan);
void ath9k_enable_mib_counters(struct ath_hw *ah);
void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
u32 *rxf_pcnt, u32 *txf_pcnt);
-void ath9k_hw_procmibevent(struct ath_hw *ah);
+void ath9k_hw_procmibevent(struct ath_hw *ah, struct ieee80211_hw *hw);
void ath9k_hw_ani_setup(struct ath_hw *ah);
void ath9k_hw_ani_init(struct ath_hw *ah);
void ath9k_hw_ani_disable(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 13dd020..3b551a7 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -341,7 +341,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush);
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
int ath_tx_setup(struct ath_softc *sc, int haltype);
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
+void ath_drain_all_txq(struct ath_softc *sc,
+ struct ieee80211_hw *hw,
+ bool retry_tx);
void ath_draintxq(struct ath_softc *sc,
struct ath_txq *txq, bool retry_tx);
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
@@ -654,8 +656,8 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
void ath_update_chainmask(struct ath_softc *sc, int is_ht);
int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
struct ath9k_channel *hchan);
-void ath_radio_enable(struct ath_softc *sc);
-void ath_radio_disable(struct ath_softc *sc);
+void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw);
+void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
#ifdef CONFIG_PCI
int ath_pci_init(void);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index b10c884..0797207 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -385,6 +385,7 @@ void ath_beacon_tasklet(unsigned long data)
struct ath_buf *bf = NULL;
struct ieee80211_vif *vif;
struct ath_wiphy *aphy;
+ struct ieee80211_hw *hw;
int slot;
u32 bfaddr, bc = 0, tsftu;
u64 tsf;
@@ -442,6 +443,7 @@ void ath_beacon_tasklet(unsigned long data)
slot = ATH_BCBUF - slot - 1;
vif = sc->beacon.bslot[slot];
aphy = sc->beacon.bslot_aphy[slot];
+ hw = aphy->hw;
ath_print(common, ATH_DBG_BEACON,
"slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
@@ -476,7 +478,7 @@ void ath_beacon_tasklet(unsigned long data)
sc->beacon.updateslot = COMMIT; /* commit next beacon */
sc->beacon.slotupdate = slot;
} else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
- ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
+ ath9k_hw_setslottime(sc->sc_ah, &hw->conf, sc->beacon.slottime);
sc->beacon.updateslot = OK;
}
if (bfaddr != 0) {
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 238a574..cb42861 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -279,10 +279,9 @@ static bool ath9k_hw_per_calibration(struct ath_hw *ah,
/* Assumes you are talking about the currently configured channel */
static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
+ struct ieee80211_conf *conf,
enum ath9k_cal_types calType)
{
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
switch (calType & ah->supp_cals) {
case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
return true;
@@ -560,10 +559,10 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
}
/* This is done for the currently configured channel */
-bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
+bool ath9k_hw_reset_calvalid(struct ath_hw *ah, struct ieee80211_hw *hw)
{
struct ath_common *common = ath9k_hw_common(ah);
- struct ieee80211_conf *conf = &common->hw->conf;
+ struct ieee80211_conf *conf = &hw->conf;
struct ath9k_cal_list *currCal = ah->cal_list_curr;
if (!ah->curchan)
@@ -582,7 +581,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
return true;
}
- if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
+ if (!ath9k_hw_iscal_supported(ah, conf, currCal->calData->calType))
return true;
ath_print(common, ATH_DBG_CALIBRATE,
@@ -1121,8 +1120,11 @@ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
return true;
}
-bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
+bool ath9k_hw_init_cal(struct ath_hw *ah,
+ struct ieee80211_hw *hw,
+ struct ath9k_channel *chan)
{
+ struct ieee80211_conf *conf = &hw->conf;
struct ath_common *common = ath9k_hw_common(ah);
if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) {
@@ -1174,19 +1176,19 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
/* Enable IQ, ADC Gain and ADC DC offset CALs */
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
- if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
+ if (ath9k_hw_iscal_supported(ah, conf, ADC_GAIN_CAL)) {
INIT_CAL(&ah->adcgain_caldata);
INSERT_CAL(ah, &ah->adcgain_caldata);
ath_print(common, ATH_DBG_CALIBRATE,
"enabling ADC Gain Calibration.\n");
}
- if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
+ if (ath9k_hw_iscal_supported(ah, conf, ADC_DC_CAL)) {
INIT_CAL(&ah->adcdc_caldata);
INSERT_CAL(ah, &ah->adcdc_caldata);
ath_print(common, ATH_DBG_CALIBRATE,
"enabling ADC DC Calibration.\n");
}
- if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
+ if (ath9k_hw_iscal_supported(ah, conf, IQ_MISMATCH_CAL)) {
INIT_CAL(&ah->iq_caldata);
INSERT_CAL(ah, &ah->iq_caldata);
ath_print(common, ATH_DBG_CALIBRATE,
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index b2c873e..ff7b3c1 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -120,7 +120,7 @@ struct ath9k_pacal_info{
int8_t skipcount; /* No. of times the PACAL to be skipped */
};
-bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
+bool ath9k_hw_reset_calvalid(struct ath_hw *ah, struct ieee80211_hw *hw);
void ath9k_hw_start_nfcal(struct ath_hw *ah);
void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
int16_t ath9k_hw_getnf(struct ath_hw *ah,
@@ -130,6 +130,7 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
u8 rxchainmask, bool longcal);
bool ath9k_hw_init_cal(struct ath_hw *ah,
+ struct ieee80211_hw *hw,
struct ath9k_channel *chan);
#endif /* CALIB_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 111ff04..f08cc61 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -26,7 +26,9 @@
#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
-static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan);
+static void ath9k_hw_set_regs(struct ath_hw *ah,
+ struct ieee80211_hw *hw,
+ struct ath9k_channel *chan);
static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
struct ar5416_eeprom_def *pEepData,
u32 reg, u32 value);
@@ -52,10 +54,10 @@ module_exit(ath9k_exit);
/* Helper Functions */
/********************/
-static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
+static u32 ath9k_hw_mac_usec(struct ath_hw *ah,
+ struct ieee80211_conf *conf,
+ u32 clks)
{
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
if (!ah->curchan) /* should really check for CCK instead */
return clks / ATH9K_CLOCK_RATE_CCK;
if (conf->channel->band == IEEE80211_BAND_2GHZ)
@@ -64,20 +66,20 @@ static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
}
-static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
+static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah,
+ struct ieee80211_conf *conf,
+ u32 clks)
{
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
if (conf_is_ht40(conf))
- return ath9k_hw_mac_usec(ah, clks) / 2;
+ return ath9k_hw_mac_usec(ah, conf, clks) / 2;
else
- return ath9k_hw_mac_usec(ah, clks);
+ return ath9k_hw_mac_usec(ah, conf, clks);
}
-static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
+static u32 ath9k_hw_mac_clks(struct ath_hw *ah,
+ struct ieee80211_conf *conf,
+ u32 usecs)
{
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
if (!ah->curchan) /* should really check for CCK instead */
return usecs *ATH9K_CLOCK_RATE_CCK;
if (conf->channel->band == IEEE80211_BAND_2GHZ)
@@ -85,14 +87,14 @@ static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM;
}
-static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
+static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah,
+ struct ieee80211_conf *conf,
+ u32 usecs)
{
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
if (conf_is_ht40(conf))
- return ath9k_hw_mac_clks(ah, usecs) * 2;
+ return ath9k_hw_mac_clks(ah, conf, usecs) * 2;
else
- return ath9k_hw_mac_clks(ah, usecs);
+ return ath9k_hw_mac_clks(ah, conf, usecs);
}
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
@@ -1205,31 +1207,43 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
}
}
-static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
+static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah,
+ struct ieee80211_conf *conf,
+ u32 us)
{
- if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
+ if (us > ath9k_hw_mac_to_usec(ah,
+ conf,
+ MS(0xffffffff, AR_TIME_OUT_ACK))) {
ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
"bad ack timeout %u\n", us);
ah->acktimeout = (u32) -1;
return false;
} else {
- REG_RMW_FIELD(ah, AR_TIME_OUT,
- AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
+ REG_RMW_FIELD(ah,
+ AR_TIME_OUT,
+ AR_TIME_OUT_ACK,
+ ath9k_hw_mac_to_clks(ah, conf, us));
ah->acktimeout = us;
return true;
}
}
-static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
+static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah,
+ struct ieee80211_conf *conf,
+ u32 us)
{
- if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
+ if (us > ath9k_hw_mac_to_usec(ah,
+ conf,
+ MS(0xffffffff, AR_TIME_OUT_CTS))) {
ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
"bad cts timeout %u\n", us);
ah->ctstimeout = (u32) -1;
return false;
} else {
- REG_RMW_FIELD(ah, AR_TIME_OUT,
- AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
+ REG_RMW_FIELD(ah,
+ AR_TIME_OUT,
+ AR_TIME_OUT_CTS,
+ ath9k_hw_mac_to_clks(ah, conf, us));
ah->ctstimeout = us;
return true;
}
@@ -1249,7 +1263,8 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
}
}
-static void ath9k_hw_init_user_settings(struct ath_hw *ah)
+static void ath9k_hw_init_user_settings(struct ath_hw *ah,
+ struct ieee80211_conf *conf)
{
ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
ah->misc_mode);
@@ -1258,11 +1273,11 @@ static void ath9k_hw_init_user_settings(struct ath_hw *ah)
REG_WRITE(ah, AR_PCU_MISC,
REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
if (ah->slottime != (u32) -1)
- ath9k_hw_setslottime(ah, ah->slottime);
+ ath9k_hw_setslottime(ah, conf, ah->slottime);
if (ah->acktimeout != (u32) -1)
- ath9k_hw_set_ack_timeout(ah, ah->acktimeout);
+ ath9k_hw_set_ack_timeout(ah, conf, ah->acktimeout);
if (ah->ctstimeout != (u32) -1)
- ath9k_hw_set_cts_timeout(ah, ah->ctstimeout);
+ ath9k_hw_set_cts_timeout(ah, conf, ah->ctstimeout);
if (ah->globaltxtimeout != (u32) -1)
ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
}
@@ -1431,6 +1446,7 @@ static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
}
static int ath9k_hw_process_ini(struct ath_hw *ah,
+ struct ieee80211_hw *hw,
struct ath9k_channel *chan)
{
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -1537,7 +1553,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
}
ath9k_hw_override_ini(ah, chan);
- ath9k_hw_set_regs(ah, chan);
+ ath9k_hw_set_regs(ah, hw, chan);
ath9k_hw_init_chain_masks(ah);
if (OLC_FOR_AR9280_20_LATER)
@@ -1818,8 +1834,11 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
}
}
-static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan)
+static void ath9k_hw_set_regs(struct ath_hw *ah,
+ struct ieee80211_hw *hw,
+ struct ath9k_channel *chan)
{
+ struct ieee80211_conf *conf = &hw->conf;
u32 phymode;
u32 enableDacFifo = 0;
@@ -1840,7 +1859,7 @@ static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan)
}
REG_WRITE(ah, AR_PHY_TURBO, phymode);
- ath9k_hw_set11nmac2040(ah);
+ ath9k_hw_set11nmac2040(ah, conf);
REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
@@ -1866,6 +1885,7 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
}
static bool ath9k_hw_channel_change(struct ath_hw *ah,
+ struct ieee80211_hw *hw,
struct ath9k_channel *chan)
{
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -1891,7 +1911,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
return false;
}
- ath9k_hw_set_regs(ah, chan);
+ ath9k_hw_set_regs(ah, hw, chan);
r = ah->ath9k_hw_rf_set_freq(ah, chan);
if (r) {
@@ -1940,10 +1960,13 @@ static void ath9k_enable_rfkill(struct ath_hw *ah)
REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
}
-int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
- bool bChannelChange)
+int ath9k_hw_reset(struct ath_hw *ah,
+ struct ieee80211_hw *hw,
+ struct ath9k_channel *chan,
+ bool bChannelChange)
{
struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_conf *conf = &hw->conf;
u32 saveLedState;
struct ath9k_channel *curchan = ah->curchan;
u32 saveDefAntenna;
@@ -1969,7 +1992,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
!(AR_SREV_9280(ah) || IS_CHAN_A_5MHZ_SPACED(chan) ||
IS_CHAN_A_5MHZ_SPACED(ah->curchan))) {
- if (ath9k_hw_channel_change(ah, chan)) {
+ if (ath9k_hw_channel_change(ah, hw, chan)) {
ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah);
return 0;
@@ -2029,7 +2052,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
}
- r = ath9k_hw_process_ini(ah, chan);
+ r = ath9k_hw_process_ini(ah, hw, chan);
if (r)
return r;
@@ -2095,7 +2118,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
ath9k_enable_rfkill(ah);
- ath9k_hw_init_user_settings(ah);
+ ath9k_hw_init_user_settings(ah, conf);
if (AR_SREV_9287_12_OR_LATER(ah)) {
REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
@@ -2132,7 +2155,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_init_bb(ah, chan);
- if (!ath9k_hw_init_cal(ah, chan))
+ if (!ath9k_hw_init_cal(ah, hw, chan))
return -EIO;
rx_chainmask = ah->rxchainmask;
@@ -3710,24 +3733,28 @@ void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
}
EXPORT_SYMBOL(ath9k_hw_set_tsfadjust);
-bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
+bool ath9k_hw_setslottime(struct ath_hw *ah,
+ struct ieee80211_conf *conf,
+ u32 us)
{
- if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
+ if (us < ATH9K_SLOT_TIME_9 ||
+ us > ath9k_hw_mac_to_usec(ah, conf, 0xffff)) {
ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
"bad slot time %u\n", us);
ah->slottime = (u32) -1;
return false;
} else {
- REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
+ REG_WRITE(ah,
+ AR_D_GBL_IFS_SLOT,
+ ath9k_hw_mac_to_clks(ah, conf, us));
ah->slottime = us;
return true;
}
}
EXPORT_SYMBOL(ath9k_hw_setslottime);
-void ath9k_hw_set11nmac2040(struct ath_hw *ah)
+void ath9k_hw_set11nmac2040(struct ath_hw *ah, struct ieee80211_conf *conf)
{
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
u32 macmode;
if (conf_is_ht40(conf) && !ah->config.cwm_ignore_extcca)
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index c7b0c4d..a7ae7ac 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -20,6 +20,7 @@
#include <linux/if_ether.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <net/mac80211.h>
#include "mac.h"
#include "ani.h"
@@ -635,7 +636,9 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
const char *ath9k_hw_probe(u16 vendorid, u16 devid);
void ath9k_hw_detach(struct ath_hw *ah);
int ath9k_hw_init(struct ath_hw *ah);
-int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+int ath9k_hw_reset(struct ath_hw *ah,
+ struct ieee80211_hw *hw,
+ struct ath9k_channel *chan,
bool bChannelChange);
void ath9k_hw_fill_cap_info(struct ath_hw *ah);
bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
@@ -689,8 +692,10 @@ u64 ath9k_hw_gettsf64(struct ath_hw *ah);
void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
void ath9k_hw_reset_tsf(struct ath_hw *ah);
void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
-bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
-void ath9k_hw_set11nmac2040(struct ath_hw *ah);
+bool ath9k_hw_setslottime(struct ath_hw *ah,
+ struct ieee80211_conf *conf,
+ u32 us);
+void ath9k_hw_set11nmac2040(struct ath_hw *ah, struct ieee80211_conf *conf);
void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
const struct ath9k_beacon_state *bs);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 9fefc51..4dec8c0 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -303,7 +303,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
- struct ieee80211_conf *conf = &common->hw->conf;
+ struct ieee80211_conf *conf = &hw->conf;
bool fastcc = true, stopped;
struct ieee80211_channel *channel = hw->conf.channel;
int r;
@@ -323,7 +323,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
* the relevant bits of the h/w.
*/
ath9k_hw_set_interrupts(ah, 0);
- ath_drain_all_txq(sc, false);
+ ath_drain_all_txq(sc, hw, false);
stopped = ath_stoprecv(sc);
/* XXX: do not flush receive queue here. We don't want
@@ -340,7 +340,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, hchan, fastcc);
+ r = ath9k_hw_reset(ah, hw, hchan, fastcc);
if (r) {
ath_print(common, ATH_DBG_FATAL,
"Unable to reset channel (%u Mhz) "
@@ -381,6 +381,8 @@ static void ath_ani_calibrate(unsigned long data)
struct ath_softc *sc = (struct ath_softc *)data;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
+ /* XXX: this is not right when using a virtual wiphy */
+ struct ieee80211_hw *hw = sc->hw;
bool longcal = false;
bool shortcal = false;
bool aniflag = false;
@@ -423,7 +425,7 @@ static void ath_ani_calibrate(unsigned long data)
} else {
if ((timestamp - sc->ani.resetcal_timer) >=
ATH_RESTART_CALINTERVAL) {
- sc->ani.caldone = ath9k_hw_reset_calvalid(ah);
+ sc->ani.caldone = ath9k_hw_reset_calvalid(ah, hw);
if (sc->ani.caldone)
sc->ani.resetcal_timer = timestamp;
}
@@ -439,7 +441,7 @@ static void ath_ani_calibrate(unsigned long data)
if (longcal || shortcal || aniflag) {
/* Call ANI routine if necessary */
if (aniflag)
- ath9k_hw_ani_monitor(ah, ah->curchan);
+ ath9k_hw_ani_monitor(ah, hw, ah->curchan);
/* Perform calibration if necessary */
if (longcal || shortcal) {
@@ -663,7 +665,8 @@ irqreturn_t ath_isr(int irq, void *dev)
* it will clear whatever condition caused
* the interrupt.
*/
- ath9k_hw_procmibevent(ah);
+ /* XXX: the sc->hw is bogus here when using virtual wiphys */
+ ath9k_hw_procmibevent(ah, sc->hw);
ath9k_hw_set_interrupts(ah, sc->imask);
}
@@ -1200,7 +1203,7 @@ fail:
ath_deinit_leds(sc);
}
-void ath_radio_enable(struct ath_softc *sc)
+void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
@@ -1214,7 +1217,7 @@ void ath_radio_enable(struct ath_softc *sc)
ah->curchan = ath_get_curchannel(sc, sc->hw);
spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, ah->curchan, false);
+ r = ath9k_hw_reset(ah, hw, ah->curchan, false);
if (r) {
ath_print(common, ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) ",
@@ -1245,7 +1248,7 @@ void ath_radio_enable(struct ath_softc *sc)
ath9k_ps_restore(sc);
}
-void ath_radio_disable(struct ath_softc *sc)
+void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
{
struct ath_hw *ah = sc->sc_ah;
struct ieee80211_channel *channel = sc->hw->conf.channel;
@@ -1261,7 +1264,7 @@ void ath_radio_disable(struct ath_softc *sc)
/* Disable interrupts */
ath9k_hw_set_interrupts(ah, 0);
- ath_drain_all_txq(sc, false); /* clear pending tx frames */
+ ath_drain_all_txq(sc, hw, false); /* clear pending tx frames */
ath_stoprecv(sc); /* turn off frame recv */
ath_flushrecv(sc); /* flush recv queue */
@@ -1269,7 +1272,7 @@ void ath_radio_disable(struct ath_softc *sc)
ah->curchan = ath_get_curchannel(sc, sc->hw);
spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, ah->curchan, false);
+ r = ath9k_hw_reset(ah, hw, ah->curchan, false);
if (r) {
ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) "
@@ -1652,7 +1655,6 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
common->ops = &ath9k_common_ops;
common->bus_ops = bus_ops;
common->ah = ah;
- common->hw = sc->hw;
common->priv = sc;
common->debug_mask = ath9k_debug;
@@ -1988,16 +1990,22 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
+ /*
+ * XXX: the sc->hw may not be the active one,
+ * we may actually be on a virtual wiphy aphy->hw
+ * but currently have no way of knowing which is the
+ * active one.
+ */
struct ieee80211_hw *hw = sc->hw;
int r;
ath9k_hw_set_interrupts(ah, 0);
- ath_drain_all_txq(sc, retry_tx);
+ ath_drain_all_txq(sc, hw, retry_tx);
ath_stoprecv(sc);
ath_flushrecv(sc);
spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
+ r = ath9k_hw_reset(ah, hw, sc->sc_ah->curchan, false);
if (r)
ath_print(common, ATH_DBG_FATAL,
"Unable to reset hardware; reset status %d\n", r);
@@ -2308,7 +2316,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
* and then setup of the interrupt mask.
*/
spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, init_channel, false);
+ r = ath9k_hw_reset(ah, hw, init_channel, false);
if (r) {
ath_print(common, ATH_DBG_FATAL,
"Unable to reset hardware; reset status %d "
@@ -2539,7 +2547,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
ath9k_hw_set_interrupts(ah, 0);
if (!(sc->sc_flags & SC_OP_INVALID)) {
- ath_drain_all_txq(sc, false);
+ ath_drain_all_txq(sc, hw, false);
ath_stoprecv(sc);
ath9k_hw_phy_disable(ah);
} else
@@ -2704,7 +2712,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
disable_radio = true;
}
else if (all_wiphys_idle) {
- ath_radio_enable(sc);
+ ath_radio_enable(sc, hw);
ath_print(common, ATH_DBG_CONFIG,
"not-idle: enabling radio\n");
}
@@ -2781,7 +2789,7 @@ skip_chan_change:
if (disable_radio) {
ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
- ath_radio_disable(sc);
+ ath_radio_disable(sc, hw);
}
mutex_unlock(&sc->mutex);
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index bc7d173..2dcbfbd 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -508,6 +508,8 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
sc->wiphy_select_failures++;
if (time_after(jiffies, sc->wiphy_select_first_fail + HZ / 2))
{
+ struct ieee80211_hw *hw = aphy->hw;
+
printk(KERN_DEBUG "ath9k: Previous wiphy select timed "
"out; disable/enable hw to recover\n");
__ath9k_wiphy_mark_all_paused(sc);
@@ -521,8 +523,8 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
* frame being completed)
*/
spin_unlock_bh(&sc->wiphy_lock);
- ath_radio_disable(sc);
- ath_radio_enable(sc);
+ ath_radio_disable(sc, hw);
+ ath_radio_enable(sc, hw);
ieee80211_queue_work(aphy->sc->hw,
&aphy->sc->chan_work);
return -EBUSY; /* previous select still in progress */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 2a4efcb..e6c6d35 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1053,7 +1053,9 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
}
}
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
+void ath_drain_all_txq(struct ath_softc *sc,
+ struct ieee80211_hw *hw,
+ bool retry_tx)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -1082,7 +1084,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
"Unable to stop TxDMA. Reset HAL!\n");
spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
+ r = ath9k_hw_reset(ah, hw, sc->sc_ah->curchan, true);
if (r)
ath_print(common, ATH_DBG_FATAL,
"Unable to reset hardware; reset status %d\n",
--
1.6.0.4
^ permalink raw reply related
* Re: LinuxUSB_AR2524-3.0.0.56_2009May_pathset
From: Hin-Tak Leung @ 2009-10-29 7:08 UTC (permalink / raw)
To: daniel.schmitt; +Cc: zd1211-devs, linux-wireless
In-Reply-To: <375b18c40b54ff9adc56af39431b864e.squirrel@unimail.uni-dortmund.de>
--- On Thu, 29/10/09, Daniel Schmitt <daniel.schmitt@udo.edu> wrote:
> Hello Hin-Tak,
>
> this URL does not work either:
> http://htl10.users.sourceforge.net/LinuxUSB_AR2524-3.0.0.56_2009May_pathset/
>
> Can you please mail me a .tar.bz-archive of the patches you
> did for the
> ZD1211 3.00 Vendor driver?
> I want to get AP mode running and this doesn't work with
> zd1211rw driver.
>
> Thanks,
> Daniel
>
>
Sorry, I moved it slightly:
http://htl10.users.sourceforge.net/patchsets/LinuxUSB_AR2524-3.0.0.56/
and withdrawn patch 04 (which I inherit from somebody), which seems to be not needed and breaks 64-bit platform; there were also two new patches which ports it forward to 2.6.30/2.6.31 since I last wrote.
^ permalink raw reply
* [PATCH] mac80211: introduce ieee80211_beacon_get_tim()
From: Johannes Berg @ 2009-10-29 7:30 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
Compared to ieee80211_beacon_get(), the new function
ieee80211_beacon_get_tim() returns information on the
location and length of the TIM IE, which some drivers
need in order to generate the TIM on the device. The
old function, ieee80211_beacon_get(), becomes a small
static inline wrapper around the new one to not break
all drivers.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
Will allow a cleanup of a number of drivers ... that parsing code has
irked me for a while now. But for now I'll leave it to the driver
maintainers to use this new function :)
include/net/mac80211.h | 42 ++++++++++++++++++++++++++++++++++--------
net/mac80211/tx.c | 17 ++++++++++++++---
2 files changed, 48 insertions(+), 11 deletions(-)
--- wireless-testing.orig/include/net/mac80211.h 2009-10-29 08:26:31.000000000 +0100
+++ wireless-testing/include/net/mac80211.h 2009-10-29 08:27:27.000000000 +0100
@@ -1743,19 +1743,45 @@ void ieee80211_tx_status_irqsafe(struct
struct sk_buff *skb);
/**
- * ieee80211_beacon_get - beacon generation function
+ * ieee80211_beacon_get_tim - beacon generation function
* @hw: pointer obtained from ieee80211_alloc_hw().
* @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
+ * @tim_offset: pointer to variable that will receive the TIM IE offset.
+ * Set to 0 if invalid (in non-AP modes).
+ * @tim_length: pointer to variable that will receive the TIM IE length,
+ * (including the ID and length bytes!).
+ * Set to 0 if invalid (in non-AP modes).
+ *
+ * If the driver implements beaconing modes, it must use this function to
+ * obtain the beacon frame/template.
*
* If the beacon frames are generated by the host system (i.e., not in
- * hardware/firmware), the low-level driver uses this function to receive
- * the next beacon frame from the 802.11 code. The low-level is responsible
- * for calling this function before beacon data is needed (e.g., based on
- * hardware interrupt). Returned skb is used only once and low-level driver
- * is responsible for freeing it.
+ * hardware/firmware), the driver uses this function to get each beacon
+ * frame from mac80211 -- it is responsible for calling this function
+ * before the beacon is needed (e.g. based on hardware interrupt).
+ *
+ * If the beacon frames are generated by the device, then the driver
+ * must use the returned beacon as the template and change the TIM IE
+ * according to the current DTIM parameters/TIM bitmap.
+ *
+ * The driver is responsible for freeing the returned skb.
+ */
+struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ u16 *tim_offset, u16 *tim_length);
+
+/**
+ * ieee80211_beacon_get - beacon generation function
+ * @hw: pointer obtained from ieee80211_alloc_hw().
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
+ *
+ * See ieee80211_beacon_get_tim().
*/
-struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif);
+static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ return ieee80211_beacon_get_tim(hw, vif, NULL, NULL);
+}
/**
* ieee80211_rts_get - RTS frame generation function
--- wireless-testing.orig/net/mac80211/tx.c 2009-10-29 08:26:31.000000000 +0100
+++ wireless-testing/net/mac80211/tx.c 2009-10-29 08:27:27.000000000 +0100
@@ -2012,8 +2012,9 @@ static void ieee80211_beacon_add_tim(str
}
}
-struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ u16 *tim_offset, u16 *tim_length)
{
struct ieee80211_local *local = hw_to_local(hw);
struct sk_buff *skb = NULL;
@@ -2030,6 +2031,11 @@ struct sk_buff *ieee80211_beacon_get(str
sdata = vif_to_sdata(vif);
+ if (tim_offset)
+ *tim_offset = 0;
+ if (tim_length)
+ *tim_length = 0;
+
if (sdata->vif.type == NL80211_IFTYPE_AP) {
ap = &sdata->u.ap;
beacon = rcu_dereference(ap->beacon);
@@ -2065,6 +2071,11 @@ struct sk_buff *ieee80211_beacon_get(str
spin_unlock_irqrestore(&local->sta_lock, flags);
}
+ if (tim_offset)
+ *tim_offset = beacon->head_len;
+ if (tim_length)
+ *tim_length = skb->len - beacon->head_len;
+
if (beacon->tail)
memcpy(skb_put(skb, beacon->tail_len),
beacon->tail, beacon->tail_len);
@@ -2141,7 +2152,7 @@ struct sk_buff *ieee80211_beacon_get(str
rcu_read_unlock();
return skb;
}
-EXPORT_SYMBOL(ieee80211_beacon_get);
+EXPORT_SYMBOL(ieee80211_beacon_get_tim);
void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
const void *frame, size_t frame_len,
^ permalink raw reply
* [PATCH 2.6.32] mac80211: fix addba timer
From: Johannes Berg @ 2009-10-29 7:34 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
The addba timer function acquires the sta spinlock,
but at the same time we try to del_timer_sync() it
under the spinlock which can produce deadlocks.
To fix this, always del_timer_sync() the timer in
ieee80211_process_addba_resp() and add it again
after checking the conditions, if necessary.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
Looks like I forgot to send this when I made it and then hid it in the
middle of my patch pile and forgot!
net/mac80211/agg-tx.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
--- wireless-testing.orig/net/mac80211/agg-tx.c 2009-10-27 09:06:13.000000000 +0100
+++ wireless-testing/net/mac80211/agg-tx.c 2009-10-29 08:32:15.000000000 +0100
@@ -666,26 +666,25 @@ void ieee80211_process_addba_resp(struct
state = &sta->ampdu_mlme.tid_state_tx[tid];
+ del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
+
spin_lock_bh(&sta->lock);
- if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
- spin_unlock_bh(&sta->lock);
- return;
- }
+ if (!(*state & HT_ADDBA_REQUESTED_MSK))
+ goto timer_still_needed;
if (mgmt->u.action.u.addba_resp.dialog_token !=
sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
- spin_unlock_bh(&sta->lock);
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
- return;
+ goto timer_still_needed;
}
- del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
+
if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
== WLAN_STATUS_SUCCESS) {
u8 curstate = *state;
@@ -699,5 +698,11 @@ void ieee80211_process_addba_resp(struct
} else {
___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
}
+
+ goto out;
+
+ timer_still_needed:
+ add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
+ out:
spin_unlock_bh(&sta->lock);
}
^ permalink raw reply
* [PATCH] mac80211: deprecate qual value
From: Johannes Berg @ 2009-10-29 7:41 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
This value is unused by mac80211, because it was only
be used by wireless extensions, and turned out to not
be useful there because the quality value needs to be
comparable between scan results and the current value
which is impossible when the qual value is calculated
taking into account noise, for example.
Since it is unused anyway, this patch deprecates it
in the hope that drivers will remove their sometimes
quite expensive calculations of the value.
I'm open to actual uses of the value, but the best
way of using it seems to be what the Intel drivers do
which should probably be generalised if we have noise
values from the hardware.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
include/net/mac80211.h | 2 +-
net/mac80211/debugfs_sta.c | 2 --
net/mac80211/rx.c | 1 -
net/mac80211/sta_info.h | 2 --
4 files changed, 1 insertion(+), 6 deletions(-)
--- wireless-testing.orig/include/net/mac80211.h 2009-10-29 08:35:37.000000000 +0100
+++ wireless-testing/include/net/mac80211.h 2009-10-29 08:40:25.000000000 +0100
@@ -552,7 +552,7 @@ struct ieee80211_rx_status {
int freq;
int signal;
int noise;
- int qual;
+ int __deprecated qual;
int antenna;
int rate_idx;
int flag;
--- wireless-testing.orig/net/mac80211/debugfs_sta.c 2009-10-29 08:32:19.000000000 +0100
+++ wireless-testing/net/mac80211/debugfs_sta.c 2009-10-29 08:40:25.000000000 +0100
@@ -57,7 +57,6 @@ STA_FILE(tx_filtered, tx_filtered_count,
STA_FILE(tx_retry_failed, tx_retry_failed, LU);
STA_FILE(tx_retry_count, tx_retry_count, LU);
STA_FILE(last_signal, last_signal, D);
-STA_FILE(last_qual, last_qual, D);
STA_FILE(last_noise, last_noise, D);
STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU);
@@ -233,7 +232,6 @@ void ieee80211_sta_debugfs_add(struct st
DEBUGFS_ADD(tx_retry_failed);
DEBUGFS_ADD(tx_retry_count);
DEBUGFS_ADD(last_signal);
- DEBUGFS_ADD(last_qual);
DEBUGFS_ADD(last_noise);
DEBUGFS_ADD(wep_weak_iv_count);
DEBUGFS_ADD(ht_capa);
--- wireless-testing.orig/net/mac80211/rx.c 2009-10-28 22:22:48.000000000 +0100
+++ wireless-testing/net/mac80211/rx.c 2009-10-29 08:40:25.000000000 +0100
@@ -859,7 +859,6 @@ ieee80211_rx_h_sta_process(struct ieee80
sta->rx_fragments++;
sta->rx_bytes += rx->skb->len;
sta->last_signal = rx->status->signal;
- sta->last_qual = rx->status->qual;
sta->last_noise = rx->status->noise;
/*
--- wireless-testing.orig/net/mac80211/sta_info.h 2009-10-28 22:22:48.000000000 +0100
+++ wireless-testing/net/mac80211/sta_info.h 2009-10-29 08:40:25.000000000 +0100
@@ -193,7 +193,6 @@ struct sta_ampdu_mlme {
* @rx_fragments: number of received MPDUs
* @rx_dropped: number of dropped MPDUs from this STA
* @last_signal: signal of last received frame from this STA
- * @last_qual: qual of last received frame from this STA
* @last_noise: noise of last received frame from this STA
* @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
* @tx_filtered_count: number of frames the hardware filtered for this STA
@@ -259,7 +258,6 @@ struct sta_info {
unsigned long rx_fragments;
unsigned long rx_dropped;
int last_signal;
- int last_qual;
int last_noise;
__le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
^ permalink raw reply
* [PATCH] mac80211: make CALL_TXH a statement
From: Johannes Berg @ 2009-10-29 7:43 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
The multi-line code in this macro wasn't wrapped
in do {} while (0) so we cannot use it in an if()
branch safely in the future -- fix that.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
net/mac80211/tx.c | 34 ++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)
--- wireless-testing.orig/net/mac80211/tx.c 2009-10-06 14:57:11.000000000 +0200
+++ wireless-testing/net/mac80211/tx.c 2009-10-06 14:57:39.000000000 +0200
@@ -1201,23 +1201,25 @@ static int invoke_tx_handlers(struct iee
struct sk_buff *skb = tx->skb;
ieee80211_tx_result res = TX_DROP;
-#define CALL_TXH(txh) \
- res = txh(tx); \
- if (res != TX_CONTINUE) \
- goto txh_done;
-
- CALL_TXH(ieee80211_tx_h_check_assoc)
- CALL_TXH(ieee80211_tx_h_ps_buf)
- CALL_TXH(ieee80211_tx_h_select_key)
- CALL_TXH(ieee80211_tx_h_michael_mic_add)
- CALL_TXH(ieee80211_tx_h_rate_ctrl)
- CALL_TXH(ieee80211_tx_h_misc)
- CALL_TXH(ieee80211_tx_h_sequence)
- CALL_TXH(ieee80211_tx_h_fragment)
+#define CALL_TXH(txh) \
+ do { \
+ res = txh(tx); \
+ if (res != TX_CONTINUE) \
+ goto txh_done; \
+ } while (0)
+
+ CALL_TXH(ieee80211_tx_h_check_assoc);
+ CALL_TXH(ieee80211_tx_h_ps_buf);
+ CALL_TXH(ieee80211_tx_h_select_key);
+ CALL_TXH(ieee80211_tx_h_michael_mic_add);
+ CALL_TXH(ieee80211_tx_h_rate_ctrl);
+ CALL_TXH(ieee80211_tx_h_misc);
+ CALL_TXH(ieee80211_tx_h_sequence);
+ CALL_TXH(ieee80211_tx_h_fragment);
/* handlers after fragment must be aware of tx info fragmentation! */
- CALL_TXH(ieee80211_tx_h_stats)
- CALL_TXH(ieee80211_tx_h_encrypt)
- CALL_TXH(ieee80211_tx_h_calculate_duration)
+ CALL_TXH(ieee80211_tx_h_stats);
+ CALL_TXH(ieee80211_tx_h_encrypt);
+ CALL_TXH(ieee80211_tx_h_calculate_duration);
#undef CALL_TXH
txh_done:
^ permalink raw reply
* Re: pull request: wireless-2.6 2009-10-28
From: David Miller @ 2009-10-29 8:07 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20091028205346.GE2856@tuxdriver.com>
From: "John W. Linville" <linville@tuxdriver.com>
Date: Wed, 28 Oct 2009 16:53:46 -0400
> Here is a collection of fixes (mostly (almost-)one-liners) intended
> for 2.6.32. There are a couple of fixes relating to behavior when an
> association failes, as well as spelling fixes, simply endian fixes,
> a MAINTAINERS change...I don't think there is anything controversial
> here...
>
> Please let me know if there are problems!
Pulled, thanks a lot John.
^ permalink raw reply
* [PATCH] mac80211: fix reason code output endianness
From: Johannes Berg @ 2009-10-29 9:09 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
When HT debugging is enabled and we receive a DelBA
frame we print out the reason code in the wrong byte
order. Fix that so we don't get weird values printed.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
net/mac80211/ht.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- wireless-testing.orig/net/mac80211/ht.c 2009-10-29 10:07:41.000000000 +0100
+++ wireless-testing/net/mac80211/ht.c 2009-10-29 10:07:49.000000000 +0100
@@ -153,7 +153,7 @@ void ieee80211_process_delba(struct ieee
if (net_ratelimit())
printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n",
mgmt->sa, initiator ? "initiator" : "recipient", tid,
- mgmt->u.action.u.delba.reason_code);
+ le16_to_cpu(mgmt->u.action.u.delba.reason_code));
#endif /* CONFIG_MAC80211_HT_DEBUG */
if (initiator == WLAN_BACK_INITIATOR)
^ permalink raw reply
* Re: pull request: wireless-next-2.6 2009-10-28
From: Bartlomiej Zolnierkiewicz @ 2009-10-29 11:12 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel, John W. Linville
In-Reply-To: <200910282256.00407.bzolnier@gmail.com>
On Wednesday 28 October 2009 22:56:00 Bartlomiej Zolnierkiewicz wrote:
> On Wednesday 28 October 2009 22:10:32 John W. Linville wrote:
> > Dave,
> >
> > I let my patches pile-up! Yikes!!
> >
> > This request includes the usual ton of stuff for -next -- driver
> > updates, fixes for some earlier -next stuff, a few cfg80211 changes to
> > accomodate the libertas driver, etc. Of note is the rt2800pci support
> > added to the rt2x00 family.
>
> Unfortunately rt2800pci support is non-functioning at the moment... :(
>
> > Pleaset let me know if there are problems!
>
> I find it rather disappointing that all my review comments regarding
> rt2800pci support were just completely ignored and then the initial
> patch was merged just as it was..
>
> The way rt2800usb and rt2800pci drivers are designed really results
> in making the task of adding working support for RT28x0 and RT30x0
> chipsets to rt2x00 infrastructure more difficult and time consuming
> than it should be... :(
What is even more disappointing (especially after all that "working with"
preaching) is that the patch is now in net-next-2.6..
--
Bartlomiej Zolnierkiewicz
^ permalink raw reply
* [PATCH] mac80211: unconditionally set IEEE80211_TX_CTL_SEND_AFTER_DTIM
From: Johannes Berg @ 2009-10-29 11:19 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
When mac80211 is asked to buffer multicast frames
in AP mode, it will not set the flag indicating
that the frames should be sent after the DTIM
beacon for those frames buffered in software. Fix
this little inconsistency by always setting that
flag in the buffering code path.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
Drivers still need to know since they usually have to put such frames
onto a separate queue...
net/mac80211/tx.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
--- wireless-testing.orig/net/mac80211/tx.c 2009-10-29 12:15:05.000000000 +0100
+++ wireless-testing/net/mac80211/tx.c 2009-10-29 12:18:04.000000000 +0100
@@ -317,12 +317,11 @@ ieee80211_tx_h_multicast_ps_buf(struct i
if (!atomic_read(&tx->sdata->bss->num_sta_ps))
return TX_CONTINUE;
- /* buffered in hardware */
- if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING)) {
- info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
+ info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
+ /* device releases frame after DTIM beacon */
+ if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING))
return TX_CONTINUE;
- }
/* buffered in mac80211 */
if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
^ permalink raw reply
* [PATCH] wl1271: fix init loop timeout
From: Luciano Coelho @ 2009-10-29 11:20 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, juha_motorsportcom
The check after the loop which checks whether the initialization timed-out
was wrong. If the initialization would succeed exactly in the 20000th time
(the value set for INIT_LOOP), the driver would bail out and claim that
initialization failed.
Reported-by: Juha Leppanen <juha_motorsportcom@luukku.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Reviewed-by: Janne Ylalehto <janne.ylalehto@nokia.com>
---
drivers/net/wireless/wl12xx/wl1271_boot.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index ba4a2b4..8678bea 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -380,7 +380,7 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
}
}
- if (loop >= INIT_LOOP) {
+ if (loop > INIT_LOOP) {
wl1271_error("timeout waiting for the hardware to "
"complete initialization");
return -EIO;
--
1.5.6.5
^ permalink raw reply related
* [PATCH] firmware_class: make request_firmware_nowait more useful
From: Johannes Berg @ 2009-10-29 11:36 UTC (permalink / raw)
To: Greg KH
Cc: linux-wireless, linux-kernel, Ming Lei, Catalin Marinas,
David Woodhouse, Pavel Roskin, Abhay Salunke
Unfortunately, one cannot hold on to the struct firmware
that request_firmware_nowait() hands off, which is needed
in some cases. Allow this by requiring the callback to
free it (via release_firmware).
Additionally, give it a gfp_t parameter -- all the current
users call it from a GFP_KERNEL context so the GFP_ATOMIC
isn't necessary. This also marks an API break which is
useful in a sense, although that is obviously not the
primary purpose of this change.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
drivers/base/firmware_class.c | 14 ++++++--------
drivers/firmware/dell_rbu.c | 9 +++++++--
drivers/serial/ucc_uart.c | 8 +++++---
drivers/staging/comedi/drivers/usbdux.c | 5 ++++-
drivers/staging/comedi/drivers/usbduxfast.c | 5 ++++-
drivers/usb/atm/ueagle-atm.c | 7 ++++---
include/linux/firmware.h | 5 +++--
7 files changed, 33 insertions(+), 20 deletions(-)
--- wireless-testing.orig/drivers/base/firmware_class.c 2009-10-26 16:45:18.000000000 +0100
+++ wireless-testing/drivers/base/firmware_class.c 2009-10-26 17:08:10.000000000 +0100
@@ -601,12 +601,9 @@ request_firmware_work_func(void *arg)
}
ret = _request_firmware(&fw, fw_work->name, fw_work->device,
fw_work->uevent);
- if (ret < 0)
- fw_work->cont(NULL, fw_work->context);
- else {
- fw_work->cont(fw, fw_work->context);
- release_firmware(fw);
- }
+
+ fw_work->cont(fw, fw_work->context);
+
module_put(fw_work->module);
kfree(fw_work);
return ret;
@@ -619,6 +616,7 @@ request_firmware_work_func(void *arg)
* is non-zero else the firmware copy must be done manually.
* @name: name of firmware file
* @device: device for which firmware is being loaded
+ * @gfp: allocation flags
* @context: will be passed over to @cont, and
* @fw may be %NULL if firmware request fails.
* @cont: function will be called asynchronously when the firmware
@@ -631,12 +629,12 @@ request_firmware_work_func(void *arg)
int
request_firmware_nowait(
struct module *module, int uevent,
- const char *name, struct device *device, void *context,
+ const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
struct task_struct *task;
struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
- GFP_ATOMIC);
+ gfp);
if (!fw_work)
return -ENOMEM;
--- wireless-testing.orig/include/linux/firmware.h 2009-10-26 16:45:53.000000000 +0100
+++ wireless-testing/include/linux/firmware.h 2009-10-26 17:03:56.000000000 +0100
@@ -4,6 +4,7 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/compiler.h>
+#include <linux/gfp.h>
#define FW_ACTION_NOHOTPLUG 0
#define FW_ACTION_HOTPLUG 1
@@ -38,7 +39,7 @@ int request_firmware(const struct firmwa
struct device *device);
int request_firmware_nowait(
struct module *module, int uevent,
- const char *name, struct device *device, void *context,
+ const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context));
void release_firmware(const struct firmware *fw);
@@ -51,7 +52,7 @@ static inline int request_firmware(const
}
static inline int request_firmware_nowait(
struct module *module, int uevent,
- const char *name, struct device *device, void *context,
+ const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
return -EINVAL;
--- wireless-testing.orig/drivers/firmware/dell_rbu.c 2009-10-26 16:49:06.000000000 +0100
+++ wireless-testing/drivers/firmware/dell_rbu.c 2009-10-26 16:49:52.000000000 +0100
@@ -544,9 +544,12 @@ static void callbackfn_rbu(const struct
{
rbu_data.entry_created = 0;
- if (!fw || !fw->size)
+ if (!fw)
return;
+ if (!fw->size)
+ goto out;
+
spin_lock(&rbu_data.lock);
if (!strcmp(image_type, "mono")) {
if (!img_update_realloc(fw->size))
@@ -568,6 +571,8 @@ static void callbackfn_rbu(const struct
} else
pr_debug("invalid image type specified.\n");
spin_unlock(&rbu_data.lock);
+ out:
+ release_firmware(fw);
}
static ssize_t read_rbu_image_type(struct kobject *kobj,
@@ -615,7 +620,7 @@ static ssize_t write_rbu_image_type(stru
spin_unlock(&rbu_data.lock);
req_firm_rc = request_firmware_nowait(THIS_MODULE,
FW_ACTION_NOHOTPLUG, "dell_rbu",
- &rbu_device->dev, &context,
+ &rbu_device->dev, GFP_KERNEL, &context,
callbackfn_rbu);
if (req_firm_rc) {
printk(KERN_ERR
--- wireless-testing.orig/drivers/serial/ucc_uart.c 2009-10-26 16:50:04.000000000 +0100
+++ wireless-testing/drivers/serial/ucc_uart.c 2009-10-26 16:51:10.000000000 +0100
@@ -1179,16 +1179,18 @@ static void uart_firmware_cont(const str
if (firmware->header.length != fw->size) {
dev_err(dev, "invalid firmware\n");
- return;
+ goto out;
}
ret = qe_upload_firmware(firmware);
if (ret) {
dev_err(dev, "could not load firmware\n");
- return;
+ goto out;
}
firmware_loaded = 1;
+ out:
+ release_firmware(fw);
}
static int ucc_uart_probe(struct of_device *ofdev,
@@ -1247,7 +1249,7 @@ static int ucc_uart_probe(struct of_devi
*/
ret = request_firmware_nowait(THIS_MODULE,
FW_ACTION_HOTPLUG, filename, &ofdev->dev,
- &ofdev->dev, uart_firmware_cont);
+ GFP_KERNEL, &ofdev->dev, uart_firmware_cont);
if (ret) {
dev_err(&ofdev->dev,
"could not load firmware %s\n",
--- wireless-testing.orig/drivers/staging/comedi/drivers/usbdux.c 2009-10-26 16:51:16.000000000 +0100
+++ wireless-testing/drivers/staging/comedi/drivers/usbdux.c 2009-10-26 16:51:52.000000000 +0100
@@ -2327,9 +2327,11 @@ static void usbdux_firmware_request_comp
if (ret) {
dev_err(&usbdev->dev,
"Could not upload firmware (err=%d)\n", ret);
- return;
+ goto out;
}
comedi_usb_auto_config(usbdev, BOARDNAME);
+ out:
+ release_firmware(fw);
}
/* allocate memory for the urbs and initialise them */
@@ -2580,6 +2582,7 @@ static int usbduxsub_probe(struct usb_in
FW_ACTION_HOTPLUG,
"usbdux_firmware.bin",
&udev->dev,
+ GFP_KERNEL,
usbduxsub + index,
usbdux_firmware_request_complete_handler);
--- wireless-testing.orig/drivers/staging/comedi/drivers/usbduxfast.c 2009-10-26 17:01:20.000000000 +0100
+++ wireless-testing/drivers/staging/comedi/drivers/usbduxfast.c 2009-10-26 17:01:47.000000000 +0100
@@ -1451,10 +1451,12 @@ static void usbduxfast_firmware_request_
if (ret) {
dev_err(&usbdev->dev,
"Could not upload firmware (err=%d)\n", ret);
- return;
+ goto out;
}
comedi_usb_auto_config(usbdev, BOARDNAME);
+ out:
+ release_firmware(fw);
}
/*
@@ -1569,6 +1571,7 @@ static int usbduxfastsub_probe(struct us
FW_ACTION_HOTPLUG,
"usbduxfast_firmware.bin",
&udev->dev,
+ GFP_KERNEL,
usbduxfastsub + index,
usbduxfast_firmware_request_complete_handler);
--- wireless-testing.orig/drivers/usb/atm/ueagle-atm.c 2009-10-26 17:01:48.000000000 +0100
+++ wireless-testing/drivers/usb/atm/ueagle-atm.c 2009-10-26 17:03:29.000000000 +0100
@@ -667,12 +667,12 @@ static void uea_upload_pre_firmware(cons
else
uea_info(usb, "firmware uploaded\n");
- uea_leaves(usb);
- return;
+ goto err;
err_fw_corrupted:
uea_err(usb, "firmware is corrupted\n");
err:
+ release_firmware(fw_entry);
uea_leaves(usb);
}
@@ -705,7 +705,8 @@ static int uea_load_firmware(struct usb_
break;
}
- ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware);
+ ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev,
+ GFP_KERNEL, usb, uea_upload_pre_firmware);
if (ret)
uea_err(usb, "firmware %s is not available\n", fw_name);
else
^ permalink raw reply
* Re: pull request: wireless-next-2.6 2009-10-28
From: David Miller @ 2009-10-29 12:15 UTC (permalink / raw)
To: bzolnier; +Cc: linux-wireless, netdev, linux-kernel, linville
In-Reply-To: <200910291212.41656.bzolnier@gmail.com>
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Thu, 29 Oct 2009 12:12:41 +0100
> What is even more disappointing (especially after all that "working with"
> preaching) is that the patch is now in net-next-2.6..
John is the wireless maintainer, I take his tree in since the changes
in there have his blessing.
If you have a problem with some change in there, work it out with him
and he'll send the fixed up changes to me thereafterwards.
I don't really see what the big deal is, any change can be reverted.
^ permalink raw reply
* ath5k AP issues
From: Michael Buesch @ 2009-10-29 12:30 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Luis Rodriguez
[-- Attachment #1: Type: text/plain, Size: 709 bytes --]
Attached is a wireshark log. Let me explain what you see in there:
I have an ath5k AP and the powersaving n810 device as STA.
What I try to do is ping the n810. You can see that at the start of the log.
Packet #31 is a ping to the n810. #42, too. and so on...
You see that the n810 does not reply. (not even with an 802.11 ack)
I guess the n810 is in PS at that time.
Also note that the TIM sent by the AP is empty.
What I did at #135 is _simultaneously_ ping from the n810 to the ath5k.
At that point suddenly both pings running on both ends start to succeed.
This is with a vanilla 2.6.31.5 kernel, but I can also reproduce this with
compat-wireless and compat-wireless-stable.
--
Greetings, Michael.
[-- Attachment #2: capture --]
[-- Type: application/octet-stream, Size: 41364 bytes --]
^ permalink raw reply
* Re: pull request: wireless-next-2.6 2009-10-28
From: Bartlomiej Zolnierkiewicz @ 2009-10-29 12:45 UTC (permalink / raw)
To: David Miller; +Cc: linux-wireless, netdev, linux-kernel, linville
In-Reply-To: <20091029.051509.119751790.davem@davemloft.net>
On Thursday 29 October 2009 13:15:09 David Miller wrote:
> From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
> Date: Thu, 29 Oct 2009 12:12:41 +0100
>
> > What is even more disappointing (especially after all that "working with"
> > preaching) is that the patch is now in net-next-2.6..
>
> John is the wireless maintainer, I take his tree in since the changes
> in there have his blessing.
>
> If you have a problem with some change in there, work it out with him
> and he'll send the fixed up changes to me thereafterwards.
What do you mean by that?
That *I* should be fixing the patch in question instead of the submitter?
Do some different rules apply in the networking than in other parts of
the kernel that I'm not aware of?
There were valid concerns raised on the initial rt2800pci patch submission,
yet two days later patch is in John's tree, after few more days it is in yours
tree and happily on his way into 2.6.33.
Until issues mentioned in:
http://lkml.org/lkml/2009/10/17/81
are addressed rt2800pci shouldn't be queued for Linus' tree.
[ Please note that this driver doesn't work at all currently so the standard
argument of having hardware support early upstream cannot be applied here. ]
--
Bartlomiej Zolnierkiewicz
^ permalink raw reply
* Re: pull request: wireless-next-2.6 2009-10-28
From: David Miller @ 2009-10-29 12:59 UTC (permalink / raw)
To: bzolnier; +Cc: linux-wireless, netdev, linux-kernel, linville
In-Reply-To: <200910291345.05888.bzolnier@gmail.com>
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Thu, 29 Oct 2009 13:45:05 +0100
> That *I* should be fixing the patch in question instead of the
> submitter?
I'm saying that you should work with John to have him send a revert or
whatever to me.
^ permalink raw reply
* Re: ath5k AP issues
From: Michael Buesch @ 2009-10-29 13:06 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Luis Rodriguez
In-Reply-To: <200910291330.26172.mb@bu3sch.de>
On Thursday 29 October 2009 13:30:24 Michael Buesch wrote:
> Attached is a wireshark log. Let me explain what you see in there:
>
> I have an ath5k AP and the powersaving n810 device as STA.
> What I try to do is ping the n810. You can see that at the start of the log.
>
> Packet #31 is a ping to the n810. #42, too. and so on...
> You see that the n810 does not reply. (not even with an 802.11 ack)
> I guess the n810 is in PS at that time.
> Also note that the TIM sent by the AP is empty.
>
> What I did at #135 is _simultaneously_ ping from the n810 to the ath5k.
> At that point suddenly both pings running on both ends start to succeed.
>
> This is with a vanilla 2.6.31.5 kernel, but I can also reproduce this with
> compat-wireless and compat-wireless-stable.
>
This is dmesg log with verbose PS debugging enabled.
[265617.902457] phy0: Allocated STA 00:1d:6e:9b:c5:a6
[265617.903187] phy0: Inserted STA 00:1d:6e:9b:c5:a6
[265620.539771] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 enters power save mode
Here I start pinging the n810. No dmesg messages appear and pinging does not work.
When I start pinging _from_ the n810, the following messages appear:
[265660.078055] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 exits power save mode
[265660.078066] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 sending 0 filtered/0 PS frames since STA not sleeping anymore
[265660.289206] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 enters power save mode
[265660.938988] STA 00:1d:6e:9b:c5:a6 aid 1: PS buffer (entries before 0)
[265660.985997] STA 00:1d:6e:9b:c5:a6 aid 1: PS Poll (entries after 0)
[265660.986016] wlan0: STA 00:1d:6e:9b:c5:a6 in PS mode, but pspoll set -> send frame
[265661.008310] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 exits power save mode
[265661.008321] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 sending 0 filtered/0 PS frames since STA not sleeping anymore
[265661.226915] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 enters power save mode
--
Greetings, Michael.
^ permalink raw reply
* Re: ath5k AP issues
From: Johannes Berg @ 2009-10-29 13:29 UTC (permalink / raw)
To: Michael Buesch; +Cc: linux-wireless, Luis Rodriguez, Bob Copeland
In-Reply-To: <200910291330.26172.mb@bu3sch.de>
[-- Attachment #1: Type: text/plain, Size: 617 bytes --]
On Thu, 2009-10-29 at 13:30 +0100, Michael Buesch wrote:
> Attached is a wireshark log. Let me explain what you see in there:
>
> I have an ath5k AP and the powersaving n810 device as STA.
> What I try to do is ping the n810. You can see that at the start of the log.
>
> Packet #31 is a ping to the n810. #42, too. and so on...
It's not a ping, it's an ARP. The problem is that the TIM IE never
indicates multicast traffic although multicast traffic is being sent.
But in later packets you can see that it's not buffered correctly at all
-- soemtimes it's sent after DTIM count 1 beacons.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: ath5k AP issues
From: Michael Buesch @ 2009-10-29 13:31 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, Luis Rodriguez, Bob Copeland
In-Reply-To: <200910291406.03422.mb@bu3sch.de>
On Thursday 29 October 2009 14:06:01 Michael Buesch wrote:
> On Thursday 29 October 2009 13:30:24 Michael Buesch wrote:
> > Attached is a wireshark log. Let me explain what you see in there:
> >
> > I have an ath5k AP and the powersaving n810 device as STA.
> > What I try to do is ping the n810. You can see that at the start of the log.
> >
> > Packet #31 is a ping to the n810. #42, too. and so on...
> > You see that the n810 does not reply. (not even with an 802.11 ack)
> > I guess the n810 is in PS at that time.
> > Also note that the TIM sent by the AP is empty.
> >
> > What I did at #135 is _simultaneously_ ping from the n810 to the ath5k.
> > At that point suddenly both pings running on both ends start to succeed.
> >
> > This is with a vanilla 2.6.31.5 kernel, but I can also reproduce this with
> > compat-wireless and compat-wireless-stable.
> >
>
> This is dmesg log with verbose PS debugging enabled.
>
> [265617.902457] phy0: Allocated STA 00:1d:6e:9b:c5:a6
> [265617.903187] phy0: Inserted STA 00:1d:6e:9b:c5:a6
> [265620.539771] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 enters power save mode
>
> Here I start pinging the n810. No dmesg messages appear and pinging does not work.
>
> When I start pinging _from_ the n810, the following messages appear:
>
> [265660.078055] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 exits power save mode
> [265660.078066] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 sending 0 filtered/0 PS frames since STA not sleeping anymore
> [265660.289206] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 enters power save mode
> [265660.938988] STA 00:1d:6e:9b:c5:a6 aid 1: PS buffer (entries before 0)
> [265660.985997] STA 00:1d:6e:9b:c5:a6 aid 1: PS Poll (entries after 0)
> [265660.986016] wlan0: STA 00:1d:6e:9b:c5:a6 in PS mode, but pspoll set -> send frame
> [265661.008310] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 exits power save mode
> [265661.008321] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 sending 0 filtered/0 PS frames since STA not sleeping anymore
> [265661.226915] wlan0: STA 00:1d:6e:9b:c5:a6 aid 1 enters power save mode
>
>
Ok, to sum up some discussion from IRC:
The initial packets that fail are not pings, but ARPs. Which are broadcast frames.
The access point simply fails to notify the station via DTIM for the pending
multicast frames, so it stays in PS. Unicast and the corresponding TIM bitmap works properly,
which also explains why it works once we got a successful ARP (and it didn't expire, yet).
So there is a DTIM problem with multicast frames in ath5k.
--
Greetings, Michael.
^ permalink raw reply
* Re: pull request: wireless-next-2.6 2009-10-28
From: Bartlomiej Zolnierkiewicz @ 2009-10-29 13:35 UTC (permalink / raw)
To: David Miller; +Cc: linux-wireless, netdev, linux-kernel, linville
In-Reply-To: <20091029.055901.24976117.davem@davemloft.net>
On Thursday 29 October 2009 13:59:01 David Miller wrote:
> From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
> Date: Thu, 29 Oct 2009 13:45:05 +0100
>
> > That *I* should be fixing the patch in question instead of the
> > submitter?
>
> I'm saying that you should work with John to have him send a revert or
> whatever to me.
This is your responsibility to deal with your downstream maintainers,
not mine and since you have accepted John's patch I'm asking you to
revert rt2800pci patch from your tree.
--
Bartlomiej Zolnierkiewicz
^ permalink raw reply
* Re: pull request: wireless-next-2.6 2009-10-28
From: Pekka Enberg @ 2009-10-29 13:52 UTC (permalink / raw)
To: Bartlomiej Zolnierkiewicz
Cc: David Miller, linux-wireless, netdev, linux-kernel, linville
In-Reply-To: <200910291435.54203.bzolnier@gmail.com>
Hi Bart,
On Thu, Oct 29, 2009 at 3:35 PM, Bartlomiej Zolnierkiewicz
<bzolnier@gmail.com> wrote:
>> I'm saying that you should work with John to have him send a revert or
>> whatever to me.
>
> This is your responsibility to deal with your downstream maintainers,
> not mine and since you have accepted John's patch I'm asking you to
> revert rt2800pci patch from your tree.
So why don't you just send a patch to fix it up? I see you're doing
lots of cleanups to the staging drivers, why not direct some of that
energy to the drivers/net/wireless ones?
Pekka
^ permalink raw reply
* Re: pull request: wireless-next-2.6 2009-10-28
From: David Miller @ 2009-10-29 13:53 UTC (permalink / raw)
To: bzolnier; +Cc: linux-wireless, netdev, linux-kernel, linville
In-Reply-To: <200910291435.54203.bzolnier@gmail.com>
From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Thu, 29 Oct 2009 14:35:54 +0100
> This is your responsibility to deal with your downstream maintainers,
> not mine and since you have accepted John's patch I'm asking you to
> revert rt2800pci patch from your tree.
That's not how it works Bart. You should not be asking 'me' to do
anything on wireless bits, there is absolutely no reason to bypass
John in the workflow.
^ permalink raw reply
* mesh support for rt73
From: Dan Rosenqvist @ 2009-10-29 13:19 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org
Hi,
I'm currently trying to set up a small 802.11s mesh network. As I've come to understand there's no support for mesh networking at the moment for rt 73 based cards (using DWL-G122 C1).
Is it possible to implement the changes mentioned in http://linuxwireless.org/en/developers/Documentation/mac80211/API to support mesh networks for rt 73 as well?
Is there someone out there currently working on this? Otherwise, how could I contribute to make this work?
Regards,
Dan
^ permalink raw reply
* Re: [PATCH] firmware_class: make request_firmware_nowait more useful
From: Marcel Holtmann @ 2009-10-29 13:58 UTC (permalink / raw)
To: Johannes Berg
Cc: Greg KH, linux-wireless, linux-kernel, Ming Lei, Catalin Marinas,
David Woodhouse, Pavel Roskin, Abhay Salunke
In-Reply-To: <1256816162.3865.110.camel@johannes.local>
Hi Johannes,
> Unfortunately, one cannot hold on to the struct firmware
> that request_firmware_nowait() hands off, which is needed
> in some cases. Allow this by requiring the callback to
> free it (via release_firmware).
>
> Additionally, give it a gfp_t parameter -- all the current
> users call it from a GFP_KERNEL context so the GFP_ATOMIC
> isn't necessary. This also marks an API break which is
> useful in a sense, although that is obviously not the
> primary purpose of this change.
>
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
I had a look at this one and looks good to me and makes perfect sense.
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply
* Re: pull request: wireless-next-2.6 2009-10-28
From: Bartlomiej Zolnierkiewicz @ 2009-10-29 14:13 UTC (permalink / raw)
To: David Miller; +Cc: linux-wireless, netdev, linux-kernel, linville
In-Reply-To: <20091029.065336.119302168.davem@davemloft.net>
On Thursday 29 October 2009 14:53:36 David Miller wrote:
> From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
> Date: Thu, 29 Oct 2009 14:35:54 +0100
>
> > This is your responsibility to deal with your downstream maintainers,
> > not mine and since you have accepted John's patch I'm asking you to
> > revert rt2800pci patch from your tree.
>
> That's not how it works Bart. You should not be asking 'me' to do
> anything on wireless bits, there is absolutely no reason to bypass
> John in the workflow.
John has chosen to ignore my concerns and you are sending me back to him?
I like ping-pong but as a sport.
--
Bartlomiej Zolnierkiewicz
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox