summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c57
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h12
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_initvals.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c81
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h39
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h13
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c34
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/wow.c168
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.c2
-rw-r--r--drivers/net/wireless/cw1200/Kconfig17
-rw-r--r--drivers/net/wireless/cw1200/Makefile4
-rw-r--r--drivers/net/wireless/cw1200/bh.c20
-rw-r--r--drivers/net/wireless/cw1200/cw1200.h11
-rw-r--r--drivers/net/wireless/cw1200/cw1200_sagrad.c145
-rw-r--r--drivers/net/wireless/cw1200/cw1200_sdio.c127
-rw-r--r--drivers/net/wireless/cw1200/cw1200_spi.c93
-rw-r--r--drivers/net/wireless/cw1200/debug.c26
-rw-r--r--drivers/net/wireless/cw1200/fwio.c10
-rw-r--r--drivers/net/wireless/cw1200/hwbus.h33
-rw-r--r--drivers/net/wireless/cw1200/hwio.c31
-rw-r--r--drivers/net/wireless/cw1200/main.c24
-rw-r--r--drivers/net/wireless/cw1200/pm.c6
-rw-r--r--drivers/net/wireless/cw1200/pm.h11
-rw-r--r--drivers/net/wireless/cw1200/sbus.h37
-rw-r--r--drivers/net/wireless/cw1200/txrx.c5
-rw-r--r--drivers/net/wireless/cw1200/wsm.c3
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c14
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c4
-rw-r--r--include/linux/cw1200_platform.h46
-rw-r--r--include/linux/platform_data/net-cw1200.h81
-rw-r--r--include/net/cfg80211.h3
-rw-r--r--include/uapi/linux/nl80211.h4
-rw-r--r--net/mac80211/cfg.c13
-rw-r--r--net/mac80211/driver-ops.h3
-rw-r--r--net/mac80211/iface.c29
-rw-r--r--net/mac80211/tx.c5
-rw-r--r--net/mac80211/util.c6
-rw-r--r--net/wireless/nl80211.c10
50 files changed, 556 insertions, 780 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 7ecd40f..e91725b 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -118,10 +118,10 @@ static void ath9k_ani_restart(struct ath_hw *ah)
{
struct ar5416AniState *aniState;
- if (!DO_ANI(ah))
+ if (!ah->curchan)
return;
- aniState = &ah->curchan->ani;
+ aniState = &ah->ani;
aniState->listenTime = 0;
ENABLE_REGWRITE_BUFFER(ah);
@@ -143,7 +143,7 @@ static void ath9k_ani_restart(struct ath_hw *ah)
static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
bool scan)
{
- struct ar5416AniState *aniState = &ah->curchan->ani;
+ struct ar5416AniState *aniState = &ah->ani;
struct ath_common *common = ath9k_hw_common(ah);
const struct ani_ofdm_level_entry *entry_ofdm;
const struct ani_cck_level_entry *entry_cck;
@@ -195,10 +195,10 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
{
struct ar5416AniState *aniState;
- if (!DO_ANI(ah))
+ if (!ah->curchan)
return;
- aniState = &ah->curchan->ani;
+ aniState = &ah->ani;
if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false);
@@ -210,7 +210,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel,
bool scan)
{
- struct ar5416AniState *aniState = &ah->curchan->ani;
+ struct ar5416AniState *aniState = &ah->ani;
struct ath_common *common = ath9k_hw_common(ah);
const struct ani_ofdm_level_entry *entry_ofdm;
const struct ani_cck_level_entry *entry_cck;
@@ -251,10 +251,10 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
{
struct ar5416AniState *aniState;
- if (!DO_ANI(ah))
+ if (!ah->curchan)
return;
- aniState = &ah->curchan->ani;
+ aniState = &ah->ani;
if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1,
@@ -269,7 +269,7 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
{
struct ar5416AniState *aniState;
- aniState = &ah->curchan->ani;
+ aniState = &ah->ani;
/* lower OFDM noise immunity */
if (aniState->ofdmNoiseImmunityLevel > 0 &&
@@ -292,12 +292,12 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
*/
void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
{
- struct ar5416AniState *aniState = &ah->curchan->ani;
+ struct ar5416AniState *aniState = &ah->ani;
struct ath9k_channel *chan = ah->curchan;
struct ath_common *common = ath9k_hw_common(ah);
int ofdm_nil, cck_nil;
- if (!DO_ANI(ah))
+ if (!ah->curchan)
return;
BUG_ON(aniState == NULL);
@@ -380,7 +380,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- struct ar5416AniState *aniState = &ah->curchan->ani;
+ struct ar5416AniState *aniState = &ah->ani;
u32 phyCnt1, phyCnt2;
int32_t listenTime;
@@ -415,10 +415,10 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
struct ath_common *common = ath9k_hw_common(ah);
u32 ofdmPhyErrRate, cckPhyErrRate;
- if (!DO_ANI(ah))
+ if (!ah->curchan)
return;
- aniState = &ah->curchan->ani;
+ aniState = &ah->ani;
if (!ath9k_hw_ani_read_counters(ah))
return;
@@ -490,32 +490,22 @@ EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
void ath9k_hw_ani_init(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- int i;
+ struct ar5416AniState *ani = &ah->ani;
ath_dbg(common, ANI, "Initialize ANI\n");
ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
-
ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
- for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
- struct ath9k_channel *chan = &ah->channels[i];
- struct ar5416AniState *ani = &chan->ani;
-
- ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
-
- ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
-
- ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
-
- ani->ofdmsTurn = true;
-
- ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
- ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
- ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
- }
+ ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+ ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+ ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
+ ani->ofdmsTurn = true;
+ ani->ofdmWeakSigDetect = true;
+ ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
+ ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
/*
* since we expect some ongoing maintenance on the tables, let's sanity
@@ -524,9 +514,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
ah->aniperiod = ATH9K_ANI_PERIOD;
ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL;
- if (ah->config.enable_ani)
- ah->proc_phyerr |= HAL_PROCESS_ANI;
-
ath9k_ani_restart(ah);
ath9k_enable_mib_counters(ah);
}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index dddb136..78b9fa9 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -17,10 +17,6 @@
#ifndef ANI_H
#define ANI_H
-#define HAL_PROCESS_ANI 0x00000001
-
-#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI) && ah->curchan)
-
#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
/* units are errors per second */
@@ -38,11 +34,7 @@
#define ATH9K_ANI_CCK_TRIG_LOW 300
#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
-#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
-#define ATH9K_ANI_CCK_WEAK_SIG_THR false
-
#define ATH9K_ANI_SPUR_IMMUNE_LVL 3
-
#define ATH9K_ANI_FIRSTEP_LVL 2
#define ATH9K_ANI_RSSI_THR_HIGH 40
@@ -111,7 +103,7 @@ struct ar5416AniState {
u8 mrcCCK;
u8 spurImmunityLevel;
u8 firstepLevel;
- u8 ofdmWeakSigDetect;
+ bool ofdmWeakSigDetect;
u32 listenTime;
u32 ofdmPhyErrCount;
u32 cckPhyErrCount;
@@ -119,8 +111,6 @@ struct ar5416AniState {
};
struct ar5416Stats {
- u32 ast_ani_niup;
- u32 ast_ani_nidown;
u32 ast_ani_spurup;
u32 ast_ani_spurdown;
u32 ast_ani_ofdmon;
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 391da5ad..d1acfe9 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -931,7 +931,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
{
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
- struct ar5416AniState *aniState = &chan->ani;
+ struct ar5416AniState *aniState = &ah->ani;
s32 value, value2;
switch (cmd & ah->ani_function) {
@@ -1207,7 +1207,7 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
- struct ar5416AniState *aniState = &chan->ani;
+ struct ar5416AniState *aniState = &ah->ani;
struct ath9k_ani_default *iniDef;
u32 val;
@@ -1251,7 +1251,7 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
/* these levels just got reset to defaults by the INI */
aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
- aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
+ aniState->ofdmWeakSigDetect = true;
aniState->mrcCCK = false; /* not available on pre AR9003 */
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 830daa1..8dc2d08 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -38,10 +38,6 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah)
else
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9280PciePhy_clkreq_always_on_L1_9280);
-#ifdef CONFIG_PM_SLEEP
- INIT_INI_ARRAY(&ah->iniPcieSerdesWow,
- ar9280PciePhy_awow);
-#endif
if (AR_SREV_9287_11_OR_LATER(ah)) {
INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
index beb6162..4d18c66 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
@@ -925,20 +925,6 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
{0x00004044, 0x00000000},
};
-static const u32 ar9280PciePhy_awow[][2] = {
- /* Addr allmodes */
- {0x00004040, 0x9248fd00},
- {0x00004040, 0x24924924},
- {0x00004040, 0xa8000019},
- {0x00004040, 0x13160820},
- {0x00004040, 0xe5980560},
- {0x00004040, 0xc01dcffd},
- {0x00004040, 0x1aaabe41},
- {0x00004040, 0xbe105554},
- {0x00004040, 0x00043007},
- {0x00004044, 0x00000000},
-};
-
static const u32 ar9285Modes_9285_1_2[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 301bf72..5163abd 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -469,6 +469,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
rxs->rs_status = 0;
rxs->rs_flags = 0;
+ rxs->flag = 0;
rxs->rs_datalen = rxsp->status2 & AR_DataLen;
rxs->rs_tstamp = rxsp->status3;
@@ -493,8 +494,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
- rxs->rs_flags = (rxsp->status4 & AR_GI) ? ATH9K_RX_GI : 0;
- rxs->rs_flags |= (rxsp->status4 & AR_2040) ? ATH9K_RX_2040 : 0;
+ rxs->flag |= (rxsp->status4 & AR_GI) ? RX_FLAG_SHORT_GI : 0;
+ rxs->flag |= (rxsp->status4 & AR_2040) ? RX_FLAG_40MHZ : 0;
rxs->evm0 = rxsp->status6;
rxs->evm1 = rxsp->status7;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 2bf6548..0d05350 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -904,7 +904,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
{
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
- struct ar5416AniState *aniState = &chan->ani;
+ struct ar5416AniState *aniState = &ah->ani;
s32 value, value2;
switch (cmd & ah->ani_function) {
@@ -1172,7 +1172,7 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
struct ath9k_ani_default *iniDef;
u32 val;
- aniState = &ah->curchan->ani;
+ aniState = &ah->ani;
iniDef = &aniState->iniDef;
ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
@@ -1213,7 +1213,7 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
/* these levels just got reset to defaults by the INI */
aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
- aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
+ aniState->ofdmWeakSigDetect = true;
aniState->mrcCCK = true;
}
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index fc96ad3..7852f6e 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -173,25 +173,69 @@ static const struct file_operations fops_rx_chainmask = {
.llseek = default_llseek,
};
-static ssize_t read_file_disable_ani(struct file *file, char __user *user_buf,
+static ssize_t read_file_ani(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- char buf[32];
- unsigned int len;
+ struct ath_hw *ah = sc->sc_ah;
+ unsigned int len = 0, size = 1024;
+ ssize_t retval = 0;
+ char *buf;
- len = sprintf(buf, "%d\n", common->disable_ani);
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ buf = kzalloc(size, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ if (common->disable_ani) {
+ len += snprintf(buf + len, size - len, "%s: %s\n",
+ "ANI", "DISABLED");
+ goto exit;
+ }
+
+ len += snprintf(buf + len, size - len, "%15s: %s\n",
+ "ANI", "ENABLED");
+ len += snprintf(buf + len, size - len, "%15s: %u\n",
+ "ANI RESET", ah->stats.ast_ani_reset);
+ len += snprintf(buf + len, size - len, "%15s: %u\n",
+ "SPUR UP", ah->stats.ast_ani_spurup);
+ len += snprintf(buf + len, size - len, "%15s: %u\n",
+ "SPUR DOWN", ah->stats.ast_ani_spurup);
+ len += snprintf(buf + len, size - len, "%15s: %u\n",
+ "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon);
+ len += snprintf(buf + len, size - len, "%15s: %u\n",
+ "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff);
+ len += snprintf(buf + len, size - len, "%15s: %u\n",
+ "MRC-CCK ON", ah->stats.ast_ani_ccklow);
+ len += snprintf(buf + len, size - len, "%15s: %u\n",
+ "MRC-CCK OFF", ah->stats.ast_ani_cckhigh);
+ len += snprintf(buf + len, size - len, "%15s: %u\n",
+ "FIR-STEP UP", ah->stats.ast_ani_stepup);
+ len += snprintf(buf + len, size - len, "%15s: %u\n",
+ "FIR-STEP DOWN", ah->stats.ast_ani_stepdown);
+ len += snprintf(buf + len, size - len, "%15s: %u\n",
+ "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero);
+ len += snprintf(buf + len, size - len, "%15s: %u\n",
+ "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs);
+ len += snprintf(buf + len, size - len, "%15s: %u\n",
+ "CCK ERRORS", ah->stats.ast_ani_cckerrs);
+exit:
+ if (len > size)
+ len = size;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
}
-static ssize_t write_file_disable_ani(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
+static ssize_t write_file_ani(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- unsigned long disable_ani;
+ unsigned long ani;
char buf[32];
ssize_t len;
@@ -200,12 +244,15 @@ static ssize_t write_file_disable_ani(struct file *file,
return -EFAULT;
buf[len] = '\0';
- if (strict_strtoul(buf, 0, &disable_ani))
+ if (strict_strtoul(buf, 0, &ani))
+ return -EINVAL;
+
+ if (ani < 0 || ani > 1)
return -EINVAL;
- common->disable_ani = !!disable_ani;
+ common->disable_ani = !ani;
- if (disable_ani) {
+ if (common->disable_ani) {
clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
ath_stop_ani(sc);
} else {
@@ -215,9 +262,9 @@ static ssize_t write_file_disable_ani(struct file *file,
return count;
}
-static const struct file_operations fops_disable_ani = {
- .read = read_file_disable_ani,
- .write = write_file_disable_ani,
+static const struct file_operations fops_ani = {
+ .read = read_file_ani,
+ .write = write_file_ani,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
@@ -1719,8 +1766,8 @@ int ath9k_init_debug(struct ath_hw *ah)
sc->debug.debugfs_phy, sc, &fops_rx_chainmask);
debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
- debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR,
- sc->debug.debugfs_phy, sc, &fops_disable_ani);
+ debugfs_create_file("ani", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy, sc, &fops_ani);
debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
&sc->sc_ah->config.enable_paprd);
debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 62da19c..9719378 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -251,45 +251,6 @@ struct ath_stats {
u32 reset[__RESET_TYPE_MAX];
};
-#define ATH_DBG_MAX_SAMPLES 10
-struct ath_dbg_bb_mac_samp {
- u32 dma_dbg_reg_vals[ATH9K_NUM_DMA_DEBUG_REGS];
- u32 pcu_obs, pcu_cr, noise;
- struct {
- u64 jiffies;
- int8_t rssi_ctl0;
- int8_t rssi_ctl1;
- int8_t rssi_ctl2;
- int8_t rssi_ext0;
- int8_t rssi_ext1;
- int8_t rssi_ext2;
- int8_t rssi;
- bool isok;
- u8 rts_fail_cnt;
- u8 data_fail_cnt;
- u8 rateindex;
- u8 qid;
- u8 tid;
- u32 ba_low;
- u32 ba_high;
- } ts[ATH_DBG_MAX_SAMPLES];
- struct {
- u64 jiffies;
- int8_t rssi_ctl0;
- int8_t rssi_ctl1;
- int8_t rssi_ctl2;
- int8_t rssi_ext0;
- int8_t rssi_ext1;
- int8_t rssi_ext2;
- int8_t rssi;
- bool is_mybeacon;
- u8 antenna;
- u8 rate;
- } rs[ATH_DBG_MAX_SAMPLES];
- struct ath_cycle_counters cc;
- struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
-};
-
struct ath9k_debug {
struct dentry *debugfs_phy;
u32 regidx;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 2a67b57..34869c2 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -814,8 +814,7 @@ void ath9k_htc_ani_work(struct work_struct *work)
}
/* Verify whether we must check ANI */
- if (ah->config.enable_ani &&
- (timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
+ if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
aniflag = true;
common->ani.checkani_timer = timestamp;
}
@@ -845,8 +844,7 @@ set_timer:
* short calibration and long calibration.
*/
cal_interval = ATH_LONG_CALINTERVAL;
- if (ah->config.enable_ani)
- cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
+ cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
if (!common->ani.caldone)
cal_interval = min(cal_interval, (u32)short_cal_interval);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index a263ccc..a13f6ce 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -452,7 +452,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
ah->config.pcie_clock_req = 0;
ah->config.pcie_waen = 0;
ah->config.analog_shiftreg = 1;
- ah->config.enable_ani = true;
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
ah->config.spurchans[i][0] = AR_NO_SPUR;
@@ -549,8 +548,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
ah->eep_ops->get_eeprom_ver(ah),
ah->eep_ops->get_eeprom_rev(ah));
- if (ah->config.enable_ani)
- ath9k_hw_ani_init(ah);
+ ath9k_hw_ani_init(ah);
return 0;
}
@@ -2595,13 +2593,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->hw_caps |= ATH9K_HW_CAP_RTT;
}
- if (AR_SREV_9280_20_OR_LATER(ah)) {
- pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE |
- ATH9K_HW_WOW_PATTERN_MATCH_EXACT;
-
- if (AR_SREV_9280(ah))
- pCap->hw_caps |= ATH9K_HW_WOW_PATTERN_MATCH_DWORD;
- }
+ if (AR_SREV_9462(ah))
+ pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE;
if (AR_SREV_9300_20_OR_LATER(ah) &&
ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index ae30343..7d259b7 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -246,9 +246,7 @@ enum ath9k_hw_caps {
ATH9K_HW_CAP_MCI = BIT(15),
ATH9K_HW_CAP_DFS = BIT(16),
ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(17),
- ATH9K_HW_WOW_PATTERN_MATCH_EXACT = BIT(18),
- ATH9K_HW_WOW_PATTERN_MATCH_DWORD = BIT(19),
- ATH9K_HW_CAP_PAPRD = BIT(20),
+ ATH9K_HW_CAP_PAPRD = BIT(18),
};
/*
@@ -291,7 +289,6 @@ struct ath9k_ops_config {
u32 ofdm_trig_high;
u32 cck_trig_high;
u32 cck_trig_low;
- u32 enable_ani;
u32 enable_paprd;
int serialize_regmode;
bool rx_intr_mitigation;
@@ -423,7 +420,6 @@ struct ath9k_hw_cal_data {
struct ath9k_channel {
struct ieee80211_channel *chan;
- struct ar5416AniState ani;
u16 channel;
u32 channelFlags;
u32 chanmode;
@@ -854,10 +850,10 @@ struct ath_hw {
u32 globaltxtimeout;
/* ANI */
- u32 proc_phyerr;
u32 aniperiod;
enum ath9k_ani_cmd ani_function;
u32 ani_skip_count;
+ struct ar5416AniState ani;
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
struct ath_btcoex_hw btcoex_hw;
@@ -882,9 +878,6 @@ struct ath_hw {
struct ar5416IniArray iniBank6;
struct ar5416IniArray iniAddac;
struct ar5416IniArray iniPcieSerdes;
-#ifdef CONFIG_PM_SLEEP
- struct ar5416IniArray iniPcieSerdesWow;
-#endif
struct ar5416IniArray iniPcieSerdesLowPower;
struct ar5416IniArray iniModesFastClock;
struct ar5416IniArray iniAdditional;
@@ -1165,8 +1158,6 @@ static inline void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
}
#endif
-
-
#define ATH9K_CLOCK_RATE_CCK 22
#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index c7b888f..979bde3 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -21,6 +21,7 @@
#include <linux/ath9k_platform.h>
#include <linux/module.h>
#include <linux/relay.h>
+#include <net/ieee80211_radiotap.h>
#include "ath9k.h"
@@ -766,12 +767,19 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
IEEE80211_HW_SUPPORTS_RC_TABLE;
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
- hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+ hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+
+ if (AR_SREV_9280_20_OR_LATER(ah))
+ hw->radiotap_mcs_details |=
+ IEEE80211_RADIOTAP_MCS_HAVE_STBC;
+ }
if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
hw->flags |= IEEE80211_HW_MFP_CAPABLE;
+ hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
+
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_P2P_CLIENT) |
@@ -792,21 +800,17 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
#ifdef CONFIG_PM_SLEEP
-
if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
device_can_wakeup(sc->dev)) {
-
hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
WIPHY_WOWLAN_DISCONNECT;
hw->wiphy->wowlan.n_patterns = MAX_NUM_USER_PATTERN;
hw->wiphy->wowlan.pattern_min_len = 1;
hw->wiphy->wowlan.pattern_max_len = MAX_PATTERN_SIZE;
-
}
atomic_set(&sc->wow_sleep_proc_intr, -1);
atomic_set(&sc->wow_got_bmiss_intr, -1);
-
#endif
hw->queues = 4;
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index cc422a4..fff5d3c 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -390,9 +390,7 @@ void ath_ani_calibrate(unsigned long data)
}
/* Verify whether we must check ANI */
- if (sc->sc_ah->config.enable_ani
- && (timestamp - common->ani.checkani_timer) >=
- ah->config.ani_poll_interval) {
+ if ((timestamp - common->ani.checkani_timer) >= ah->config.ani_poll_interval) {
aniflag = true;
common->ani.checkani_timer = timestamp;
}
@@ -427,9 +425,7 @@ set_timer:
* short calibration and long calibration.
*/
cal_interval = ATH_LONG_CALINTERVAL;
- if (sc->sc_ah->config.enable_ani)
- cal_interval = min(cal_interval,
- (u32)ah->config.ani_poll_interval);
+ cal_interval = min(cal_interval, (u32)ah->config.ani_poll_interval);
if (!common->ani.caldone)
cal_interval = min(cal_interval, (u32)short_cal_interval);
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 498fee0..d055e38 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -547,6 +547,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
rs->rs_status = 0;
rs->rs_flags = 0;
+ rs->flag = 0;
rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
rs->rs_tstamp = ads.AR_RcvTimestamp;
@@ -586,10 +587,17 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
rs->rs_moreaggr =
(ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
- rs->rs_flags =
- (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
- rs->rs_flags |=
- (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
+
+ /* directly mapped flags for ieee80211_rx_status */
+ rs->flag |=
+ (ads.ds_rxstatus3 & AR_GI) ? RX_FLAG_SHORT_GI : 0;
+ rs->flag |=
+ (ads.ds_rxstatus3 & AR_2040) ? RX_FLAG_40MHZ : 0;
+ if (AR_SREV_9280_20_OR_LATER(ah))
+ rs->flag |=
+ (ads.ds_rxstatus3 & AR_STBC) ?
+ /* we can only Nss=1 STBC */
+ (1 << RX_FLAG_STBC_SHIFT) : 0;
if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 5865f92..b02dfce 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -149,6 +149,7 @@ struct ath_rx_status {
u32 evm2;
u32 evm3;
u32 evm4;
+ u32 flag; /* see enum mac80211_rx_flags */
};
struct ath_htc_rx_status {
@@ -533,7 +534,8 @@ struct ar5416_desc {
#define AR_2040 0x00000002
#define AR_Parallel40 0x00000004
#define AR_Parallel40_S 2
-#define AR_RxStatusRsvd30 0x000000f8
+#define AR_STBC 0x00000008 /* on ar9280 and later */
+#define AR_RxStatusRsvd30 0x000000f0
#define AR_RxAntenna 0xffffff00
#define AR_RxAntenna_S 8
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a1630d1..cc5a98b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2003,7 +2003,6 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_hw_capabilities *pcaps = &ah->caps;
int pattern_count = 0;
int i, byte_cnt;
u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
@@ -2073,36 +2072,9 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
/* Create Disassociate pattern mask */
- if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_EXACT) {
-
- if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_DWORD) {
- /*
- * for AR9280, because of hardware limitation, the
- * first 4 bytes have to be matched for all patterns.
- * the mask for disassociation and de-auth pattern
- * matching need to enable the first 4 bytes.
- * also the duration field needs to be filled.
- */
- dis_deauth_mask[0] = 0xf0;
-
- /*
- * fill in duration field
- FIXME: what is the exact value ?
- */
- dis_deauth_pattern[2] = 0xff;
- dis_deauth_pattern[3] = 0xff;
- } else {
- dis_deauth_mask[0] = 0xfe;
- }
-
- dis_deauth_mask[1] = 0x03;
- dis_deauth_mask[2] = 0xc0;
- } else {
- dis_deauth_mask[0] = 0xef;
- dis_deauth_mask[1] = 0x3f;
- dis_deauth_mask[2] = 0x00;
- dis_deauth_mask[3] = 0xfc;
- }
+ dis_deauth_mask[0] = 0xfe;
+ dis_deauth_mask[1] = 0x03;
+ dis_deauth_mask[2] = 0xc0;
ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 8be2b5d..865e043 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -868,10 +868,7 @@ static int ath9k_process_rate(struct ath_common *common,
if (rx_stats->rs_rate & 0x80) {
/* HT rate */
rxs->flag |= RX_FLAG_HT;
- if (rx_stats->rs_flags & ATH9K_RX_2040)
- rxs->flag |= RX_FLAG_40MHZ;
- if (rx_stats->rs_flags & ATH9K_RX_GI)
- rxs->flag |= RX_FLAG_SHORT_GI;
+ rxs->flag |= rx_stats->flag;
rxs->rate_idx = rx_stats->rs_rate & 0x7f;
return 0;
}
@@ -958,11 +955,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
if (rx_stats->rs_more)
return 0;
- ath9k_process_rssi(common, hw, hdr, rx_stats);
-
if (ath9k_process_rate(common, hw, rx_stats, rx_status))
return -EINVAL;
+ ath9k_process_rssi(common, hw, hdr, rx_stats);
+
rx_status->band = hw->conf.chandef.chan->band;
rx_status->freq = hw->conf.chandef.chan->center_freq;
rx_status->signal = ah->noise + rx_stats->rs_rssi;
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 9f85630..81c88dd 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -34,17 +34,6 @@ const char *ath9k_hw_wow_event_to_string(u32 wow_event)
}
EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
-static void ath9k_hw_config_serdes_wow_sleep(struct ath_hw *ah)
-{
- int i;
-
- for (i = 0; i < ah->iniPcieSerdesWow.ia_rows; i++)
- REG_WRITE(ah, INI_RA(&ah->iniPcieSerdesWow, i, 0),
- INI_RA(&ah->iniPcieSerdesWow, i, 1));
-
- usleep_range(1000, 1500);
-}
-
static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
@@ -58,15 +47,8 @@ static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
return;
- } else {
- if (!AR_SREV_9300_20_OR_LATER(ah))
- REG_WRITE(ah, AR_RXDP, 0x0);
}
- /* AR9280 WoW has sleep issue, do not set it to sleep */
- if (AR_SREV_9280_20(ah))
- return;
-
REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
}
@@ -84,27 +66,16 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
/* set the transmit buffer */
ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
-
- if (!(AR_SREV_9300_20_OR_LATER(ah)))
- ctl[0] += (KAL_ANTENNA_MODE << 25);
-
ctl[1] = 0;
ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */
ctl[4] = 0;
ctl[7] = (ah->txchainmask) << 2;
-
- if (AR_SREV_9300_20_OR_LATER(ah))
- ctl[2] = 0xf << 16; /* tx_tries 0 */
- else
- ctl[2] = 0x7 << 16; /* tx_tries 0 */
-
+ ctl[2] = 0xf << 16; /* tx_tries 0 */
for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
- /* for AR9300 family 13 descriptor words */
- if (AR_SREV_9300_20_OR_LATER(ah))
- REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
+ REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
(KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
@@ -183,9 +154,6 @@ void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
- if (!AR_SREV_9285_12_OR_LATER(ah))
- return;
-
if (pattern_count < 4) {
/* Pattern 0-3 uses AR_WOW_LENGTH1 register */
set = (pattern_len & AR_WOW_LENGTH_MAX) <<
@@ -207,6 +175,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
{
u32 wow_status = 0;
u32 val = 0, rval;
+
/*
* read the WoW status register to know
* the wakeup reason
@@ -223,19 +192,14 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
val &= ah->wow_event_mask;
if (val) {
-
if (val & AR_WOW_MAGIC_PAT_FOUND)
wow_status |= AH_WOW_MAGIC_PATTERN_EN;
-
if (AR_WOW_PATTERN_FOUND(val))
wow_status |= AH_WOW_USER_PATTERN_EN;
-
if (val & AR_WOW_KEEP_ALIVE_FAIL)
wow_status |= AH_WOW_LINK_CHANGE;
-
if (val & AR_WOW_BEACON_FAIL)
wow_status |= AH_WOW_BEACON_MISS;
-
}
/*
@@ -255,17 +219,6 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
/*
- * tie reset register for AR9002 family of chipsets
- * NB: not tieing it back might have some repurcussions.
- */
-
- if (!AR_SREV_9300_20_OR_LATER(ah)) {
- REG_SET_BIT(ah, AR_WA, AR_WA_UNTIE_RESET_EN |
- AR_WA_POR_SHORT | AR_WA_RESET_EN);
- }
-
-
- /*
* restore the beacon threshold to init value
*/
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
@@ -277,8 +230,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
* reset to our Chip's Power On Reset so that any PCI-E
* reset from the bus will not reset our chip
*/
-
- if (AR_SREV_9280_20_OR_LATER(ah) && ah->is_pciexpress)
+ if (ah->is_pciexpress)
ath9k_hw_configpcipowersave(ah, false);
ah->wow_event_mask = 0;
@@ -298,7 +250,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
* are from the 'pattern_enable' in this function and
* 'pattern_count' of ath9k_hw_wow_apply_pattern()
*/
-
wow_event_mask = ah->wow_event_mask;
/*
@@ -306,50 +257,15 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
* WOW sleep, we do want the Reset from the PCI-E to disturb
* our hw state
*/
-
if (ah->is_pciexpress) {
-
/*
* we need to untie the internal POR (power-on-reset)
* to the external PCI-E reset. We also need to tie
* the PCI-E Phy reset to the PCI-E reset.
*/
-
- if (AR_SREV_9300_20_OR_LATER(ah)) {
- set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
- clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
- REG_RMW(ah, AR_WA, set, clr);
- } else {
- if (AR_SREV_9285(ah) || AR_SREV_9287(ah))
- set = AR9285_WA_DEFAULT;
- else
- set = AR9280_WA_DEFAULT;
-
- /*
- * In AR9280 and AR9285, bit 14 in WA register
- * (disable L1) should only be set when device
- * enters D3 state and be cleared when device
- * comes back to D0
- */
-
- if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
- set |= AR_WA_D3_L1_DISABLE;
-
- clr = AR_WA_UNTIE_RESET_EN;
- set |= AR_WA_RESET_EN | AR_WA_POR_SHORT;
- REG_RMW(ah, AR_WA, set, clr);
-
- /*
- * for WoW sleep, we reprogram the SerDes so that the
- * PLL and CLK REQ are both enabled. This uses more
- * power but otherwise WoW sleep is unstable and the
- * chip may disappear.
- */
-
- if (AR_SREV_9285_12_OR_LATER(ah))
- ath9k_hw_config_serdes_wow_sleep(ah);
-
- }
+ set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
+ clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
+ REG_RMW(ah, AR_WA, set, clr);
}
/*
@@ -378,7 +294,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
* Program default values for pattern backoff, aifs/slot/KAL count,
* beacon miss timeout, KAL timeout, etc.
*/
-
set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
REG_SET_BIT(ah, AR_WOW_PATTERN, set);
@@ -398,7 +313,7 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
/*
* Keep alive timo in ms except AR9280
*/
- if (!pattern_enable || AR_SREV_9280(ah))
+ if (!pattern_enable)
set = AR_WOW_KEEP_ALIVE_NEVER;
else
set = KAL_TIMEOUT * 32;
@@ -420,7 +335,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
/*
* Configure MAC WoW Registers
*/
-
set = 0;
/* Send keep alive timeouts anyway */
clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
@@ -430,16 +344,9 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
else
set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
- /*
- * FIXME: For now disable keep alive frame
- * failure. This seems to sometimes trigger
- * unnecessary wake up with AR9485 chipsets.
- */
set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
-
REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
-
/*
* we are relying on a bmiss failure. ensure we have
* enough threshold to prevent false positives
@@ -473,14 +380,8 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
set |= AR_WOW_MAC_INTR_EN;
REG_RMW(ah, AR_WOW_PATTERN, set, clr);
- /*
- * For AR9285 and later version of chipsets
- * enable WoW pattern match for packets less
- * than 256 bytes for all patterns
- */
- if (AR_SREV_9285_12_OR_LATER(ah))
- REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
- AR_WOW_PATTERN_SUPPORTED);
+ REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
+ AR_WOW_PATTERN_SUPPORTED);
/*
* Set the power states appropriately and enable PME
@@ -488,43 +389,32 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
clr = 0;
set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
AR_PMCTRL_PWR_PM_CTRL_ENA;
- /*
- * This is needed for AR9300 chipsets to wake-up
- * the host.
- */
- if (AR_SREV_9300_20_OR_LATER(ah))
- clr = AR_PCIE_PM_CTRL_ENA;
+ clr = AR_PCIE_PM_CTRL_ENA;
REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
- if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
- /*
- * this is needed to prevent the chip waking up
- * the host within 3-4 seconds with certain
- * platform/BIOS. The fix is to enable
- * D1 & D3 to match original definition and
- * also match the OTP value. Anyway this
- * is more related to SW WOW.
- */
- clr = AR_PMCTRL_PWR_STATE_D1D3;
- REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
-
- set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
- REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
- }
-
+ /*
+ * this is needed to prevent the chip waking up
+ * the host within 3-4 seconds with certain
+ * platform/BIOS. The fix is to enable
+ * D1 & D3 to match original definition and
+ * also match the OTP value. Anyway this
+ * is more related to SW WOW.
+ */
+ clr = AR_PMCTRL_PWR_STATE_D1D3;
+ REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
+ set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
+ REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
- if (AR_SREV_9300_20_OR_LATER(ah)) {
- /* to bring down WOW power low margin */
- set = BIT(13);
- REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
- /* HW WoW */
- clr = BIT(5);
- REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
- }
+ /* to bring down WOW power low margin */
+ set = BIT(13);
+ REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
+ /* HW WoW */
+ clr = BIT(5);
+ REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
ath9k_hw_set_powermode_wow_sleep(ah);
ah->wow_event_mask = wow_event_mask;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index 1585cc5..bd98285 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -900,7 +900,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
if (supr_status) {
update_rate = false;
if (supr_status == TX_STATUS_SUPR_BADCH) {
- brcms_err(wlc->hw->d11core,
+ brcms_dbg_ht(wlc->hw->d11core,
"%s: Pkt tx suppressed, illegal channel possibly %d\n",
__func__, CHSPEC_CHANNEL(
wlc->default_bss->chanspec));
diff --git a/drivers/net/wireless/cw1200/Kconfig b/drivers/net/wireless/cw1200/Kconfig
index 13e3611..7a585d4 100644
--- a/drivers/net/wireless/cw1200/Kconfig
+++ b/drivers/net/wireless/cw1200/Kconfig
@@ -13,20 +13,19 @@ config CW1200_WLAN_SDIO
depends on CW1200 && MMC
help
Enable support for the CW1200 connected via an SDIO bus.
+ By default this driver only supports the Sagrad SG901-1091/1098 EVK
+ and similar designs that utilize a hardware reset circuit. To
+ support different CW1200 SDIO designs you will need to override
+ the default platform data by calling cw1200_sdio_set_platform_data()
+ in your board setup file.
config CW1200_WLAN_SPI
tristate "Support SPI platforms"
depends on CW1200 && SPI
help
- Enables support for the CW1200 connected via a SPI bus.
-
-config CW1200_WLAN_SAGRAD
- tristate "Support Sagrad SG901-1091/1098 modules"
- depends on CW1200_WLAN_SDIO
- help
- This provides the platform data glue to support the
- Sagrad SG901-1091/1098 modules in their standard SDIO EVK.
- It also includes example SPI platform data.
+ Enables support for the CW1200 connected via a SPI bus. You will
+ need to add appropriate platform data glue in your board setup
+ file.
menu "Driver debug features"
depends on CW1200 && DEBUG_FS
diff --git a/drivers/net/wireless/cw1200/Makefile b/drivers/net/wireless/cw1200/Makefile
index c197372..bc6cbf9 100644
--- a/drivers/net/wireless/cw1200/Makefile
+++ b/drivers/net/wireless/cw1200/Makefile
@@ -8,17 +8,15 @@ cw1200_core-y := \
wsm.o \
sta.o \
scan.o \
- pm.o \
debug.o
cw1200_core-$(CONFIG_CW1200_ITP) += itp.o
+cw1200_core-$(CONFIG_PM) += pm.o
# CFLAGS_sta.o += -DDEBUG
cw1200_wlan_sdio-y := cw1200_sdio.o
cw1200_wlan_spi-y := cw1200_spi.o
-cw1200_wlan_sagrad-y := cw1200_sagrad.o
obj-$(CONFIG_CW1200) += cw1200_core.o
obj-$(CONFIG_CW1200_WLAN_SDIO) += cw1200_wlan_sdio.o
obj-$(CONFIG_CW1200_WLAN_SPI) += cw1200_wlan_spi.o
-obj-$(CONFIG_CW1200_WLAN_SAGRAD) += cw1200_wlan_sagrad.o
diff --git a/drivers/net/wireless/cw1200/bh.c b/drivers/net/wireless/cw1200/bh.c
index cf7375f..324b57001 100644
--- a/drivers/net/wireless/cw1200/bh.c
+++ b/drivers/net/wireless/cw1200/bh.c
@@ -23,7 +23,7 @@
#include "bh.h"
#include "hwio.h"
#include "wsm.h"
-#include "sbus.h"
+#include "hwbus.h"
#include "debug.h"
#include "fwio.h"
@@ -103,7 +103,7 @@ void cw1200_irq_handler(struct cw1200_common *priv)
pr_debug("[BH] irq.\n");
/* Disable Interrupts! */
- /* NOTE: sbus_ops->lock already held */
+ /* NOTE: hwbus_ops->lock already held */
__cw1200_irq_enable(priv, 0);
if (/* WARN_ON */(priv->bh_error))
@@ -265,8 +265,8 @@ static int cw1200_bh_rx_helper(struct cw1200_common *priv,
* to the NEXT Message length + 2 Bytes for SKB */
read_len = read_len + 2;
- alloc_len = priv->sbus_ops->align_size(
- priv->sbus_priv, read_len);
+ alloc_len = priv->hwbus_ops->align_size(
+ priv->hwbus_priv, read_len);
/* Check if not exceeding CW1200 capabilities */
if (WARN_ON_ONCE(alloc_len > EFFECTIVE_BUF_SIZE)) {
@@ -384,8 +384,8 @@ static int cw1200_bh_tx_helper(struct cw1200_common *priv,
atomic_add(1, &priv->bh_tx);
- tx_len = priv->sbus_ops->align_size(
- priv->sbus_priv, tx_len);
+ tx_len = priv->hwbus_ops->align_size(
+ priv->hwbus_priv, tx_len);
/* Check if not exceeding CW1200 capabilities */
if (WARN_ON_ONCE(tx_len > EFFECTIVE_BUF_SIZE))
@@ -597,15 +597,15 @@ static int cw1200_bh(void *arg)
done:
/* Re-enable device interrupts */
- priv->sbus_ops->lock(priv->sbus_priv);
+ priv->hwbus_ops->lock(priv->hwbus_priv);
__cw1200_irq_enable(priv, 1);
- priv->sbus_ops->unlock(priv->sbus_priv);
+ priv->hwbus_ops->unlock(priv->hwbus_priv);
}
/* Explicitly disable device interrupts */
- priv->sbus_ops->lock(priv->sbus_priv);
+ priv->hwbus_ops->lock(priv->hwbus_priv);
__cw1200_irq_enable(priv, 0);
- priv->sbus_ops->unlock(priv->sbus_priv);
+ priv->hwbus_ops->unlock(priv->hwbus_priv);
if (!term) {
pr_err("[BH] Fatal error, exiting.\n");
diff --git a/drivers/net/wireless/cw1200/cw1200.h b/drivers/net/wireless/cw1200/cw1200.h
index 2aa17ca..95320f2 100644
--- a/drivers/net/wireless/cw1200/cw1200.h
+++ b/drivers/net/wireless/cw1200/cw1200.h
@@ -19,7 +19,6 @@
#define CW1200_H
#include <linux/wait.h>
-#include <linux/version.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <net/mac80211.h>
@@ -31,7 +30,7 @@
#include "pm.h"
/* Forward declarations */
-struct sbus_ops;
+struct hwbus_ops;
struct task_struct;
struct cw1200_debug_priv;
struct firmware;
@@ -110,8 +109,8 @@ struct cw1200_common {
u8 mac_addr[ETH_ALEN];
/* Hardware interface */
- const struct sbus_ops *sbus_ops;
- struct sbus_priv *sbus_priv;
+ const struct hwbus_ops *hwbus_ops;
+ struct hwbus_priv *hwbus_priv;
/* Hardware information */
enum {
@@ -299,8 +298,8 @@ struct cw1200_sta_priv {
};
/* interfaces for the drivers */
-int cw1200_core_probe(const struct sbus_ops *sbus_ops,
- struct sbus_priv *sbus,
+int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
+ struct hwbus_priv *hwbus,
struct device *pdev,
struct cw1200_common **pself,
int ref_clk, const u8 *macaddr,
diff --git a/drivers/net/wireless/cw1200/cw1200_sagrad.c b/drivers/net/wireless/cw1200/cw1200_sagrad.c
deleted file mode 100644
index a5ada0e..0000000
--- a/drivers/net/wireless/cw1200/cw1200_sagrad.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Platform glue data for ST-Ericsson CW1200 driver
- *
- * Copyright (c) 2013, Sagrad, Inc
- * Author: Solomon Peachy <speachy@sagrad.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/cw1200_platform.h>
-
-MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
-MODULE_DESCRIPTION("ST-Ericsson CW1200 Platform glue driver");
-MODULE_LICENSE("GPL");
-
-/* Define just one of these. Feel free to customize as needed */
-#define SAGRAD_1091_1098_EVK_SDIO
-/* #define SAGRAD_1091_1098_EVK_SPI */
-
-#ifdef SAGRAD_1091_1098_EVK_SDIO
-#if 0
-static struct resource cw1200_href_resources[] = {
- {
- .start = 215, /* fix me as appropriate */
- .end = 215, /* ditto */
- .flags = IORESOURCE_IO,
- .name = "cw1200_wlan_reset",
- },
- {
- .start = 216, /* fix me as appropriate */
- .end = 216, /* ditto */
- .flags = IORESOURCE_IO,
- .name = "cw1200_wlan_powerup",
- },
- {
- .start = NOMADIK_GPIO_TO_IRQ(216), /* fix me as appropriate */
- .end = NOMADIK_GPIO_TO_IRQ(216), /* ditto */
- .flags = IORESOURCE_IRQ,
- .name = "cw1200_wlan_irq",
- },
-};
-#endif
-
-static int cw1200_power_ctrl(const struct cw1200_platform_data_sdio *pdata,
- bool enable)
-{
- /* Control 3v3 and 1v8 to hardware as appropriate */
- /* Note this is not needed if it's controlled elsewhere or always on */
-
- /* May require delay for power to stabilize */
- return 0;
-}
-
-static int cw1200_clk_ctrl(const struct cw1200_platform_data_sdio *pdata,
- bool enable)
-{
- /* Turn CLK_32K off and on as appropriate. */
- /* Note this is not needed if it's always on */
-
- /* May require delay for clock to stabilize */
- return 0;
-}
-
-static struct cw1200_platform_data_sdio cw1200_platform_data = {
- .ref_clk = 38400,
- .have_5ghz = false,
-#if 0
- .reset = &cw1200_href_resources[0],
- .powerup = &cw1200_href_resources[1],
- .irq = &cw1200_href_resources[2],
-#endif
- .power_ctrl = cw1200_power_ctrl,
- .clk_ctrl = cw1200_clk_ctrl,
-/* .macaddr = ??? */
- .sdd_file = "sdd_sagrad_1091_1098.bin",
-};
-#endif
-
-#ifdef SAGRAD_1091_1098_EVK_SPI
-/* Note that this is an example of integrating into your board support file */
-static struct resource cw1200_href_resources[] = {
- {
- .start = GPIO_RF_RESET,
- .end = GPIO_RF_RESET,
- .flags = IORESOURCE_IO,
- .name = "cw1200_wlan_reset",
- },
- {
- .start = GPIO_RF_POWERUP,
- .end = GPIO_RF_POWERUP,
- .flags = IORESOURCE_IO,
- .name = "cw1200_wlan_powerup",
- },
-};
-
-static int cw1200_power_ctrl(const struct cw1200_platform_data_spi *pdata,
- bool enable)
-{
- /* Control 3v3 and 1v8 to hardware as appropriate */
- /* Note this is not needed if it's controlled elsewhere or always on */
-
- /* May require delay for power to stabilize */
- return 0;
-}
-static int cw1200_clk_ctrl(const struct cw1200_platform_data_spi *pdata,
- bool enable)
-{
- /* Turn CLK_32K off and on as appropriate. */
- /* Note this is not needed if it's always on */
-
- /* May require delay for clock to stabilize */
- return 0;
-}
-
-static struct cw1200_platform_data_spi cw1200_platform_data = {
- .ref_clk = 38400,
- .spi_bits_per_word = 16,
- .reset = &cw1200_href_resources[0],
- .powerup = &cw1200_href_resources[1],
- .power_ctrl = cw1200_power_ctrl,
- .clk_ctrl = cw1200_clk_ctrl,
-/* .macaddr = ??? */
- .sdd_file = "sdd_sagrad_1091_1098.bin",
-};
-static struct spi_board_info myboard_spi_devices[] __initdata = {
- {
- .modalias = "cw1200_wlan_spi",
- .max_speed_hz = 10000000, /* 52MHz Max */
- .bus_num = 0,
- .irq = WIFI_IRQ,
- .platform_data = &cw1200_platform_data,
- .chip_select = 0,
- },
-};
-#endif
-
-
-const void *cw1200_get_platform_data(void)
-{
- return &cw1200_platform_data;
-}
-EXPORT_SYMBOL_GPL(cw1200_get_platform_data);
diff --git a/drivers/net/wireless/cw1200/cw1200_sdio.c b/drivers/net/wireless/cw1200/cw1200_sdio.c
index f6e2219..bb1f405 100644
--- a/drivers/net/wireless/cw1200/cw1200_sdio.c
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -9,7 +9,6 @@
* published by the Free Software Foundation.
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/delay.h>
@@ -20,8 +19,8 @@
#include <net/mac80211.h>
#include "cw1200.h"
-#include "sbus.h"
-#include <linux/cw1200_platform.h>
+#include "hwbus.h"
+#include <linux/platform_data/net-cw1200.h>
#include "hwio.h"
MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
@@ -30,7 +29,22 @@ MODULE_LICENSE("GPL");
#define SDIO_BLOCK_SIZE (512)
-struct sbus_priv {
+/* Default platform data for Sagrad modules */
+static struct cw1200_platform_data_sdio sagrad_109x_evk_platform_data = {
+ .ref_clk = 38400,
+ .have_5ghz = false,
+ .sdd_file = "sdd_sagrad_1091_1098.bin",
+};
+
+/* Allow platform data to be overridden */
+static struct cw1200_platform_data_sdio *global_plat_data = &sagrad_109x_evk_platform_data;
+
+void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata)
+{
+ global_plat_data = pdata;
+}
+
+struct hwbus_priv {
struct sdio_func *func;
struct cw1200_common *core;
const struct cw1200_platform_data_sdio *pdata;
@@ -49,35 +63,35 @@ static const struct sdio_device_id cw1200_sdio_ids[] = {
{ /* end: all zeroes */ },
};
-/* sbus_ops implemetation */
+/* hwbus_ops implemetation */
-static int cw1200_sdio_memcpy_fromio(struct sbus_priv *self,
+static int cw1200_sdio_memcpy_fromio(struct hwbus_priv *self,
unsigned int addr,
void *dst, int count)
{
return sdio_memcpy_fromio(self->func, dst, addr, count);
}
-static int cw1200_sdio_memcpy_toio(struct sbus_priv *self,
+static int cw1200_sdio_memcpy_toio(struct hwbus_priv *self,
unsigned int addr,
const void *src, int count)
{
return sdio_memcpy_toio(self->func, addr, (void *)src, count);
}
-static void cw1200_sdio_lock(struct sbus_priv *self)
+static void cw1200_sdio_lock(struct hwbus_priv *self)
{
sdio_claim_host(self->func);
}
-static void cw1200_sdio_unlock(struct sbus_priv *self)
+static void cw1200_sdio_unlock(struct hwbus_priv *self)
{
sdio_release_host(self->func);
}
static void cw1200_sdio_irq_handler(struct sdio_func *func)
{
- struct sbus_priv *self = sdio_get_drvdata(func);
+ struct hwbus_priv *self = sdio_get_drvdata(func);
/* note: sdio_host already claimed here. */
if (self->core)
@@ -91,7 +105,7 @@ static irqreturn_t cw1200_gpio_hardirq(int irq, void *dev_id)
static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
{
- struct sbus_priv *self = dev_id;
+ struct hwbus_priv *self = dev_id;
if (self->core) {
sdio_claim_host(self->func);
@@ -103,10 +117,9 @@ static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
}
}
-static int cw1200_request_irq(struct sbus_priv *self)
+static int cw1200_request_irq(struct hwbus_priv *self)
{
int ret;
- const struct resource *irq = self->pdata->irq;
u8 cccr;
cccr = sdio_f0_readb(self->func, SDIO_CCCR_IENx, &ret);
@@ -123,15 +136,15 @@ static int cw1200_request_irq(struct sbus_priv *self)
if (WARN_ON(ret))
goto err;
- ret = enable_irq_wake(irq->start);
+ ret = enable_irq_wake(self->pdata->irq);
if (WARN_ON(ret))
goto err;
/* Request the IRQ */
- ret = request_threaded_irq(irq->start, cw1200_gpio_hardirq,
+ ret = request_threaded_irq(self->pdata->irq, cw1200_gpio_hardirq,
cw1200_gpio_irq,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
- irq->name, self);
+ "cw1200_wlan_irq", self);
if (WARN_ON(ret))
goto err;
@@ -141,7 +154,7 @@ err:
return ret;
}
-static int cw1200_sdio_irq_subscribe(struct sbus_priv *self)
+static int cw1200_sdio_irq_subscribe(struct hwbus_priv *self)
{
int ret = 0;
@@ -156,15 +169,15 @@ static int cw1200_sdio_irq_subscribe(struct sbus_priv *self)
return ret;
}
-static int cw1200_sdio_irq_unsubscribe(struct sbus_priv *self)
+static int cw1200_sdio_irq_unsubscribe(struct hwbus_priv *self)
{
int ret = 0;
pr_debug("SW IRQ unsubscribe\n");
if (self->pdata->irq) {
- disable_irq_wake(self->pdata->irq->start);
- free_irq(self->pdata->irq->start, self);
+ disable_irq_wake(self->pdata->irq);
+ free_irq(self->pdata->irq, self);
} else {
sdio_claim_host(self->func);
ret = sdio_release_irq(self->func);
@@ -175,12 +188,10 @@ static int cw1200_sdio_irq_unsubscribe(struct sbus_priv *self)
static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata)
{
- const struct resource *reset = pdata->reset;
-
- if (reset) {
- gpio_set_value(reset->start, 0);
+ if (pdata->reset) {
+ gpio_set_value(pdata->reset, 0);
msleep(30); /* Min is 2 * CLK32K cycles */
- gpio_free(reset->start);
+ gpio_free(pdata->reset);
}
if (pdata->power_ctrl)
@@ -193,20 +204,17 @@ static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata)
static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata)
{
- const struct resource *reset = pdata->reset;
- const struct resource *powerup = pdata->reset;
-
/* Ensure I/Os are pulled low */
- if (reset) {
- gpio_request(reset->start, reset->name);
- gpio_direction_output(reset->start, 0);
+ if (pdata->reset) {
+ gpio_request(pdata->reset, "cw1200_wlan_reset");
+ gpio_direction_output(pdata->reset, 0);
}
- if (powerup) {
- gpio_request(powerup->start, powerup->name);
- gpio_direction_output(powerup->start, 0);
+ if (pdata->powerup) {
+ gpio_request(pdata->powerup, "cw1200_wlan_powerup");
+ gpio_direction_output(pdata->powerup, 0);
}
- if (reset || powerup)
- msleep(50); /* Settle time */
+ if (pdata->reset || pdata->powerup)
+ msleep(10); /* Settle time? */
/* Enable 3v3 and 1v8 to hardware */
if (pdata->power_ctrl) {
@@ -226,19 +234,19 @@ static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata)
}
/* Enable POWERUP signal */
- if (powerup) {
- gpio_set_value(powerup->start, 1);
+ if (pdata->powerup) {
+ gpio_set_value(pdata->powerup, 1);
msleep(250); /* or more..? */
}
/* Enable RSTn signal */
- if (reset) {
- gpio_set_value(reset->start, 1);
+ if (pdata->reset) {
+ gpio_set_value(pdata->reset, 1);
msleep(50); /* Or more..? */
}
return 0;
}
-static size_t cw1200_sdio_align_size(struct sbus_priv *self, size_t size)
+static size_t cw1200_sdio_align_size(struct hwbus_priv *self, size_t size)
{
if (self->pdata->no_nptb)
size = round_up(size, SDIO_BLOCK_SIZE);
@@ -248,18 +256,18 @@ static size_t cw1200_sdio_align_size(struct sbus_priv *self, size_t size)
return size;
}
-static int cw1200_sdio_pm(struct sbus_priv *self, bool suspend)
+static int cw1200_sdio_pm(struct hwbus_priv *self, bool suspend)
{
int ret = 0;
if (self->pdata->irq)
- ret = irq_set_irq_wake(self->pdata->irq->start, suspend);
+ ret = irq_set_irq_wake(self->pdata->irq, suspend);
return ret;
}
-static struct sbus_ops cw1200_sdio_sbus_ops = {
- .sbus_memcpy_fromio = cw1200_sdio_memcpy_fromio,
- .sbus_memcpy_toio = cw1200_sdio_memcpy_toio,
+static struct hwbus_ops cw1200_sdio_hwbus_ops = {
+ .hwbus_memcpy_fromio = cw1200_sdio_memcpy_fromio,
+ .hwbus_memcpy_toio = cw1200_sdio_memcpy_toio,
.lock = cw1200_sdio_lock,
.unlock = cw1200_sdio_unlock,
.align_size = cw1200_sdio_align_size,
@@ -268,26 +276,26 @@ static struct sbus_ops cw1200_sdio_sbus_ops = {
/* Probe Function to be called by SDIO stack when device is discovered */
static int cw1200_sdio_probe(struct sdio_func *func,
- const struct sdio_device_id *id)
+ const struct sdio_device_id *id)
{
- struct sbus_priv *self;
+ struct hwbus_priv *self;
int status;
pr_info("cw1200_wlan_sdio: Probe called\n");
- /* We are only able to handle the wlan function */
+ /* We are only able to handle the wlan function */
if (func->num != 0x01)
return -ENODEV;
self = kzalloc(sizeof(*self), GFP_KERNEL);
if (!self) {
- pr_err("Can't allocate SDIO sbus_priv.\n");
+ pr_err("Can't allocate SDIO hwbus_priv.\n");
return -ENOMEM;
}
func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
- self->pdata = cw1200_get_platform_data();
+ self->pdata = global_plat_data; /* FIXME */
self->func = func;
sdio_set_drvdata(func, self);
sdio_claim_host(func);
@@ -296,7 +304,7 @@ static int cw1200_sdio_probe(struct sdio_func *func,
status = cw1200_sdio_irq_subscribe(self);
- status = cw1200_core_probe(&cw1200_sdio_sbus_ops,
+ status = cw1200_core_probe(&cw1200_sdio_hwbus_ops,
self, &func->dev, &self->core,
self->pdata->ref_clk,
self->pdata->macaddr,
@@ -318,7 +326,7 @@ static int cw1200_sdio_probe(struct sdio_func *func,
* device is disconnected */
static void cw1200_sdio_disconnect(struct sdio_func *func)
{
- struct sbus_priv *self = sdio_get_drvdata(func);
+ struct hwbus_priv *self = sdio_get_drvdata(func);
if (self) {
cw1200_sdio_irq_unsubscribe(self);
@@ -334,11 +342,12 @@ static void cw1200_sdio_disconnect(struct sdio_func *func)
}
}
+#ifdef CONFIG_PM
static int cw1200_sdio_suspend(struct device *dev)
{
int ret;
struct sdio_func *func = dev_to_sdio_func(dev);
- struct sbus_priv *self = sdio_get_drvdata(func);
+ struct hwbus_priv *self = sdio_get_drvdata(func);
if (!cw1200_can_suspend(self->core))
return -EAGAIN;
@@ -360,15 +369,18 @@ static const struct dev_pm_ops cw1200_pm_ops = {
.suspend = cw1200_sdio_suspend,
.resume = cw1200_sdio_resume,
};
+#endif
static struct sdio_driver sdio_driver = {
.name = "cw1200_wlan_sdio",
.id_table = cw1200_sdio_ids,
.probe = cw1200_sdio_probe,
.remove = cw1200_sdio_disconnect,
+#ifdef CONFIG_PM
.drv = {
.pm = &cw1200_pm_ops,
}
+#endif
};
/* Init Module function -> Called by insmod */
@@ -377,7 +389,8 @@ static int __init cw1200_sdio_init(void)
const struct cw1200_platform_data_sdio *pdata;
int ret;
- pdata = cw1200_get_platform_data();
+ /* FIXME -- this won't support multiple devices */
+ pdata = global_plat_data;
if (cw1200_sdio_on(pdata)) {
ret = -1;
@@ -399,7 +412,9 @@ err:
static void __exit cw1200_sdio_exit(void)
{
const struct cw1200_platform_data_sdio *pdata;
- pdata = cw1200_get_platform_data();
+
+ /* FIXME -- this won't support multiple devices */
+ pdata = global_plat_data;
sdio_unregister_driver(&sdio_driver);
cw1200_sdio_off(pdata);
}
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index 04af685..e58f0a5 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -13,7 +13,6 @@
* published by the Free Software Foundation.
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/delay.h>
@@ -25,8 +24,8 @@
#include <linux/device.h>
#include "cw1200.h"
-#include "sbus.h"
-#include <linux/cw1200_platform.h>
+#include "hwbus.h"
+#include <linux/platform_data/net-cw1200.h>
#include "hwio.h"
MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
@@ -36,7 +35,7 @@ MODULE_ALIAS("spi:cw1200_wlan_spi");
/* #define SPI_DEBUG */
-struct sbus_priv {
+struct hwbus_priv {
struct spi_device *func;
struct cw1200_common *core;
const struct cw1200_platform_data_spi *pdata;
@@ -59,7 +58,7 @@ struct sbus_priv {
*/
-static int cw1200_spi_memcpy_fromio(struct sbus_priv *self,
+static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
unsigned int addr,
void *dst, int count)
{
@@ -120,7 +119,7 @@ static int cw1200_spi_memcpy_fromio(struct sbus_priv *self,
return ret;
}
-static int cw1200_spi_memcpy_toio(struct sbus_priv *self,
+static int cw1200_spi_memcpy_toio(struct hwbus_priv *self,
unsigned int addr,
const void *src, int count)
{
@@ -188,7 +187,7 @@ static int cw1200_spi_memcpy_toio(struct sbus_priv *self,
return rval;
}
-static void cw1200_spi_lock(struct sbus_priv *self)
+static void cw1200_spi_lock(struct hwbus_priv *self)
{
unsigned long flags;
@@ -210,7 +209,7 @@ static void cw1200_spi_lock(struct sbus_priv *self)
return;
}
-static void cw1200_spi_unlock(struct sbus_priv *self)
+static void cw1200_spi_unlock(struct hwbus_priv *self)
{
unsigned long flags;
@@ -222,7 +221,7 @@ static void cw1200_spi_unlock(struct sbus_priv *self)
static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
{
- struct sbus_priv *self = dev_id;
+ struct hwbus_priv *self = dev_id;
if (self->core) {
cw1200_irq_handler(self->core);
@@ -232,7 +231,7 @@ static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
}
}
-static int cw1200_spi_irq_subscribe(struct sbus_priv *self)
+static int cw1200_spi_irq_subscribe(struct hwbus_priv *self)
{
int ret;
@@ -256,7 +255,7 @@ exit:
return ret;
}
-static int cw1200_spi_irq_unsubscribe(struct sbus_priv *self)
+static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self)
{
int ret = 0;
@@ -269,12 +268,10 @@ static int cw1200_spi_irq_unsubscribe(struct sbus_priv *self)
static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
{
- const struct resource *reset = pdata->reset;
-
- if (reset) {
- gpio_set_value(reset->start, 0);
+ if (pdata->reset) {
+ gpio_set_value(pdata->reset, 0);
msleep(30); /* Min is 2 * CLK32K cycles */
- gpio_free(reset->start);
+ gpio_free(pdata->reset);
}
if (pdata->power_ctrl)
@@ -287,19 +284,16 @@ static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata)
{
- const struct resource *reset = pdata->reset;
- const struct resource *powerup = pdata->reset;
-
/* Ensure I/Os are pulled low */
- if (reset) {
- gpio_request(reset->start, reset->name);
- gpio_direction_output(reset->start, 0);
+ if (pdata->reset) {
+ gpio_request(pdata->reset, "cw1200_wlan_reset");
+ gpio_direction_output(pdata->reset, 0);
}
- if (powerup) {
- gpio_request(powerup->start, powerup->name);
- gpio_direction_output(powerup->start, 0);
+ if (pdata->powerup) {
+ gpio_request(pdata->powerup, "cw1200_wlan_powerup");
+ gpio_direction_output(pdata->powerup, 0);
}
- if (reset || powerup)
+ if (pdata->reset || pdata->powerup)
msleep(10); /* Settle time? */
/* Enable 3v3 and 1v8 to hardware */
@@ -320,31 +314,31 @@ static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata)
}
/* Enable POWERUP signal */
- if (powerup) {
- gpio_set_value(powerup->start, 1);
+ if (pdata->powerup) {
+ gpio_set_value(pdata->powerup, 1);
msleep(250); /* or more..? */
}
/* Enable RSTn signal */
- if (reset) {
- gpio_set_value(reset->start, 1);
+ if (pdata->reset) {
+ gpio_set_value(pdata->reset, 1);
msleep(50); /* Or more..? */
}
return 0;
}
-static size_t cw1200_spi_align_size(struct sbus_priv *self, size_t size)
+static size_t cw1200_spi_align_size(struct hwbus_priv *self, size_t size)
{
return size & 1 ? size + 1 : size;
}
-static int cw1200_spi_pm(struct sbus_priv *self, bool suspend)
+static int cw1200_spi_pm(struct hwbus_priv *self, bool suspend)
{
return irq_set_irq_wake(self->func->irq, suspend);
}
-static struct sbus_ops cw1200_spi_sbus_ops = {
- .sbus_memcpy_fromio = cw1200_spi_memcpy_fromio,
- .sbus_memcpy_toio = cw1200_spi_memcpy_toio,
+static struct hwbus_ops cw1200_spi_hwbus_ops = {
+ .hwbus_memcpy_fromio = cw1200_spi_memcpy_fromio,
+ .hwbus_memcpy_toio = cw1200_spi_memcpy_toio,
.lock = cw1200_spi_lock,
.unlock = cw1200_spi_unlock,
.align_size = cw1200_spi_align_size,
@@ -356,7 +350,7 @@ static int cw1200_spi_probe(struct spi_device *func)
{
const struct cw1200_platform_data_spi *plat_data =
func->dev.platform_data;
- struct sbus_priv *self;
+ struct hwbus_priv *self;
int status;
/* Sanity check speed */
@@ -390,7 +384,7 @@ static int cw1200_spi_probe(struct spi_device *func)
self = kzalloc(sizeof(*self), GFP_KERNEL);
if (!self) {
- pr_err("Can't allocate SPI sbus_priv.");
+ pr_err("Can't allocate SPI hwbus_priv.");
return -ENOMEM;
}
@@ -402,7 +396,7 @@ static int cw1200_spi_probe(struct spi_device *func)
status = cw1200_spi_irq_subscribe(self);
- status = cw1200_core_probe(&cw1200_spi_sbus_ops,
+ status = cw1200_core_probe(&cw1200_spi_hwbus_ops,
self, &func->dev, &self->core,
self->pdata->ref_clk,
self->pdata->macaddr,
@@ -421,7 +415,7 @@ static int cw1200_spi_probe(struct spi_device *func)
/* Disconnect Function to be called by SPI stack when device is disconnected */
static int cw1200_spi_disconnect(struct spi_device *func)
{
- struct sbus_priv *self = spi_get_drvdata(func);
+ struct hwbus_priv *self = spi_get_drvdata(func);
if (self) {
cw1200_spi_irq_unsubscribe(self);
@@ -436,9 +430,10 @@ static int cw1200_spi_disconnect(struct spi_device *func)
return 0;
}
+#ifdef CONFIG_PM
static int cw1200_spi_suspend(struct device *dev, pm_message_t state)
{
- struct sbus_priv *self = spi_get_drvdata(to_spi_device(dev));
+ struct hwbus_priv *self = spi_get_drvdata(to_spi_device(dev));
if (!cw1200_can_suspend(self->core))
return -EAGAIN;
@@ -451,6 +446,7 @@ static int cw1200_spi_resume(struct device *dev)
{
return 0;
}
+#endif
static struct spi_driver spi_driver = {
.probe = cw1200_spi_probe,
@@ -459,22 +455,11 @@ static struct spi_driver spi_driver = {
.name = "cw1200_wlan_spi",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
.suspend = cw1200_spi_suspend,
.resume = cw1200_spi_resume,
+#endif
},
};
-/* Init Module function -> Called by insmod */
-static int __init cw1200_spi_init(void)
-{
- return spi_register_driver(&spi_driver);
-}
-
-/* Called at Driver Unloading */
-static void __exit cw1200_spi_exit(void)
-{
- spi_unregister_driver(&spi_driver);
-}
-
-module_init(cw1200_spi_init);
-module_exit(cw1200_spi_exit);
+module_spi_driver(spi_driver);
diff --git a/drivers/net/wireless/cw1200/debug.c b/drivers/net/wireless/cw1200/debug.c
index b815181..1596b70 100644
--- a/drivers/net/wireless/cw1200/debug.c
+++ b/drivers/net/wireless/cw1200/debug.c
@@ -357,12 +357,6 @@ static const struct file_operations fops_counters = {
.owner = THIS_MODULE,
};
-static int cw1200_generic_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
#ifdef CONFIG_CW1200_ETF
static int cw1200_etf_out_show(struct seq_file *seq, void *v)
{
@@ -403,13 +397,13 @@ struct etf_req_msg;
static int etf_request(struct cw1200_common *priv,
struct etf_req_msg *msg, u32 len);
-#define MAX_RX_SZE 2600
+#define MAX_RX_SIZE 2600
struct etf_in_state {
struct cw1200_common *priv;
- u32 total_len;
- u8 buf[MAX_RX_SZE];
- u32 written;
+ u16 total_len;
+ u16 written;
+ u8 buf[MAX_RX_SIZE];
};
static int cw1200_etf_in_open(struct inode *inode, struct file *file)
@@ -454,6 +448,11 @@ static ssize_t cw1200_etf_in_write(struct file *file,
return -EFAULT;
}
+ if (etf->total_len > MAX_RX_SIZE) {
+ pr_err("requested length > MAX_RX_SIZE\n");
+ return -EINVAL;
+ }
+
written += sizeof(etf->total_len);
count -= sizeof(etf->total_len);
}
@@ -461,6 +460,11 @@ static ssize_t cw1200_etf_in_write(struct file *file,
if (!count)
goto done;
+ if (count > (etf->total_len - written)) {
+ pr_err("Tried to write > MAX_RX_SIZE\n");
+ return -EINVAL;
+ }
+
if (copy_from_user(etf->buf + etf->written, user_buf + written,
count)) {
pr_err("copy_from_user (payload %zu) failed\n", count);
@@ -511,7 +515,7 @@ static ssize_t cw1200_wsm_dumps(struct file *file,
}
static const struct file_operations fops_wsm_dumps = {
- .open = cw1200_generic_open,
+ .open = simple_open,
.write = cw1200_wsm_dumps,
.llseek = default_llseek,
};
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c
index ad01cd2..427c9f2 100644
--- a/drivers/net/wireless/cw1200/fwio.c
+++ b/drivers/net/wireless/cw1200/fwio.c
@@ -22,7 +22,7 @@
#include "cw1200.h"
#include "fwio.h"
#include "hwio.h"
-#include "sbus.h"
+#include "hwbus.h"
#include "bh.h"
static int cw1200_get_hw_type(u32 config_reg_val, int *major_revision)
@@ -489,9 +489,9 @@ int cw1200_load_firmware(struct cw1200_common *priv)
}
/* Enable interrupt signalling */
- priv->sbus_ops->lock(priv->sbus_priv);
+ priv->hwbus_ops->lock(priv->hwbus_priv);
ret = __cw1200_irq_enable(priv, 1);
- priv->sbus_ops->unlock(priv->sbus_priv);
+ priv->hwbus_ops->unlock(priv->hwbus_priv);
if (ret < 0)
goto unsubscribe;
@@ -518,8 +518,8 @@ out:
unsubscribe:
/* Disable interrupt signalling */
- priv->sbus_ops->lock(priv->sbus_priv);
+ priv->hwbus_ops->lock(priv->hwbus_priv);
ret = __cw1200_irq_enable(priv, 0);
- priv->sbus_ops->unlock(priv->sbus_priv);
+ priv->hwbus_ops->unlock(priv->hwbus_priv);
return ret;
}
diff --git a/drivers/net/wireless/cw1200/hwbus.h b/drivers/net/wireless/cw1200/hwbus.h
new file mode 100644
index 0000000..8b2fc83
--- /dev/null
+++ b/drivers/net/wireless/cw1200/hwbus.h
@@ -0,0 +1,33 @@
+/*
+ * Common hwbus abstraction layer interface for cw1200 wireless driver
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef CW1200_HWBUS_H
+#define CW1200_HWBUS_H
+
+struct hwbus_priv;
+
+void cw1200_irq_handler(struct cw1200_common *priv);
+
+/* This MUST be wrapped with hwbus_ops->lock/unlock! */
+int __cw1200_irq_enable(struct cw1200_common *priv, int enable);
+
+struct hwbus_ops {
+ int (*hwbus_memcpy_fromio)(struct hwbus_priv *self, unsigned int addr,
+ void *dst, int count);
+ int (*hwbus_memcpy_toio)(struct hwbus_priv *self, unsigned int addr,
+ const void *src, int count);
+ void (*lock)(struct hwbus_priv *self);
+ void (*unlock)(struct hwbus_priv *self);
+ size_t (*align_size)(struct hwbus_priv *self, size_t size);
+ int (*power_mgmt)(struct hwbus_priv *self, bool suspend);
+};
+
+#endif /* CW1200_HWBUS_H */
diff --git a/drivers/net/wireless/cw1200/hwio.c b/drivers/net/wireless/cw1200/hwio.c
index 1af7b3d..dad3fb3 100644
--- a/drivers/net/wireless/cw1200/hwio.c
+++ b/drivers/net/wireless/cw1200/hwio.c
@@ -18,7 +18,7 @@
#include "cw1200.h"
#include "hwio.h"
-#include "sbus.h"
+#include "hwbus.h"
/* Sdio addr is 4*spi_addr */
#define SPI_REG_ADDR_TO_SDIO(spi_reg_addr) ((spi_reg_addr) << 2)
@@ -46,7 +46,7 @@ static int __cw1200_reg_read(struct cw1200_common *priv, u16 addr,
addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
- return priv->sbus_ops->sbus_memcpy_fromio(priv->sbus_priv,
+ return priv->hwbus_ops->hwbus_memcpy_fromio(priv->hwbus_priv,
sdio_reg_addr_17bit,
buf, buf_len);
}
@@ -61,7 +61,7 @@ static int __cw1200_reg_write(struct cw1200_common *priv, u16 addr,
addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
- return priv->sbus_ops->sbus_memcpy_toio(priv->sbus_priv,
+ return priv->hwbus_ops->hwbus_memcpy_toio(priv->hwbus_priv,
sdio_reg_addr_17bit,
buf, buf_len);
}
@@ -100,9 +100,9 @@ int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf,
size_t buf_len)
{
int ret;
- priv->sbus_ops->lock(priv->sbus_priv);
+ priv->hwbus_ops->lock(priv->hwbus_priv);
ret = __cw1200_reg_read(priv, addr, buf, buf_len, 0);
- priv->sbus_ops->unlock(priv->sbus_priv);
+ priv->hwbus_ops->unlock(priv->hwbus_priv);
return ret;
}
@@ -110,9 +110,9 @@ int cw1200_reg_write(struct cw1200_common *priv, u16 addr, const void *buf,
size_t buf_len)
{
int ret;
- priv->sbus_ops->lock(priv->sbus_priv);
+ priv->hwbus_ops->lock(priv->hwbus_priv);
ret = __cw1200_reg_write(priv, addr, buf, buf_len, 0);
- priv->sbus_ops->unlock(priv->sbus_priv);
+ priv->hwbus_ops->unlock(priv->hwbus_priv);
return ret;
}
@@ -121,7 +121,7 @@ int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len)
int ret, retry = 1;
int buf_id_rx = priv->buf_id_rx;
- priv->sbus_ops->lock(priv->sbus_priv);
+ priv->hwbus_ops->lock(priv->hwbus_priv);
while (retry <= MAX_RETRY) {
ret = __cw1200_reg_read(priv,
@@ -138,7 +138,7 @@ int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len)
}
}
- priv->sbus_ops->unlock(priv->sbus_priv);
+ priv->hwbus_ops->unlock(priv->hwbus_priv);
return ret;
}
@@ -148,7 +148,7 @@ int cw1200_data_write(struct cw1200_common *priv, const void *buf,
int ret, retry = 1;
int buf_id_tx = priv->buf_id_tx;
- priv->sbus_ops->lock(priv->sbus_priv);
+ priv->hwbus_ops->lock(priv->hwbus_priv);
while (retry <= MAX_RETRY) {
ret = __cw1200_reg_write(priv,
@@ -165,7 +165,7 @@ int cw1200_data_write(struct cw1200_common *priv, const void *buf,
}
}
- priv->sbus_ops->unlock(priv->sbus_priv);
+ priv->hwbus_ops->unlock(priv->hwbus_priv);
return ret;
}
@@ -178,10 +178,9 @@ int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
if ((buf_len / 2) >= 0x1000) {
pr_err("Can't read more than 0xfff words.\n");
return -EINVAL;
- goto out;
}
- priv->sbus_ops->lock(priv->sbus_priv);
+ priv->hwbus_ops->lock(priv->hwbus_priv);
/* Write address */
ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
if (ret < 0) {
@@ -230,7 +229,7 @@ int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
}
out:
- priv->sbus_ops->unlock(priv->sbus_priv);
+ priv->hwbus_ops->unlock(priv->hwbus_priv);
return ret;
}
@@ -244,7 +243,7 @@ int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
return -EINVAL;
}
- priv->sbus_ops->lock(priv->sbus_priv);
+ priv->hwbus_ops->lock(priv->hwbus_priv);
/* Write address */
ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
@@ -262,7 +261,7 @@ int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
}
out:
- priv->sbus_ops->unlock(priv->sbus_priv);
+ priv->hwbus_ops->unlock(priv->hwbus_priv);
return ret;
}
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c
index 8426d3d..2ea1bad 100644
--- a/drivers/net/wireless/cw1200/main.c
+++ b/drivers/net/wireless/cw1200/main.c
@@ -31,7 +31,7 @@
#include "cw1200.h"
#include "txrx.h"
-#include "sbus.h"
+#include "hwbus.h"
#include "fwio.h"
#include "hwio.h"
#include "bh.h"
@@ -234,8 +234,10 @@ static const struct ieee80211_ops cw1200_ops = {
.get_stats = cw1200_get_stats,
.ampdu_action = cw1200_ampdu_action,
.flush = cw1200_flush,
+#ifdef CONFIG_PM
.suspend = cw1200_wow_suspend,
.resume = cw1200_wow_resume,
+#endif
/* Intentionally not offloaded: */
/*.channel_switch = cw1200_channel_switch, */
/*.remain_on_channel = cw1200_remain_on_channel, */
@@ -292,10 +294,12 @@ static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO);
+#ifdef CONFIG_PM
/* Support only for limited wowlan functionalities */
hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
WIPHY_WOWLAN_DISCONNECT;
hw->wiphy->wowlan.n_patterns = 0;
+#endif
hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
@@ -419,18 +423,22 @@ static int cw1200_register_common(struct ieee80211_hw *dev)
goto done;
#endif
+#ifdef CONFIG_PM
err = cw1200_pm_init(&priv->pm_state, priv);
if (err) {
pr_err("Cannot init PM. (%d).\n",
err);
return err;
}
+#endif
err = ieee80211_register_hw(dev);
if (err) {
pr_err("Cannot register device (%d).\n",
err);
+#ifdef CONFIG_PM
cw1200_pm_deinit(&priv->pm_state);
+#endif
return err;
}
@@ -482,7 +490,9 @@ static void cw1200_unregister_common(struct ieee80211_hw *dev)
cw1200_queue_deinit(&priv->tx_queue[i]);
cw1200_queue_stats_deinit(&priv->tx_queue_stats);
+#ifdef CONFIG_PM
cw1200_pm_deinit(&priv->pm_state);
+#endif
}
/* Clock is in KHz */
@@ -518,8 +528,8 @@ u32 cw1200_dpll_from_clk(u16 clk_khz)
}
}
-int cw1200_core_probe(const struct sbus_ops *sbus_ops,
- struct sbus_priv *sbus,
+int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
+ struct hwbus_priv *hwbus,
struct device *pdev,
struct cw1200_common **core,
int ref_clk, const u8 *macaddr,
@@ -546,8 +556,8 @@ int cw1200_core_probe(const struct sbus_ops *sbus_ops,
if (cw1200_sdd_path)
priv->sdd_path = cw1200_sdd_path;
- priv->sbus_ops = sbus_ops;
- priv->sbus_priv = sbus;
+ priv->hwbus_ops = hwbus_ops;
+ priv->hwbus_priv = hwbus;
priv->pdev = pdev;
SET_IEEE80211_DEV(priv->hw, pdev);
@@ -606,9 +616,9 @@ EXPORT_SYMBOL_GPL(cw1200_core_probe);
void cw1200_core_release(struct cw1200_common *self)
{
/* Disable device interrupts */
- self->sbus_ops->lock(self->sbus_priv);
+ self->hwbus_ops->lock(self->hwbus_priv);
__cw1200_irq_enable(self, 0);
- self->sbus_ops->unlock(self->sbus_priv);
+ self->hwbus_ops->unlock(self->hwbus_priv);
/* And then clean up */
cw1200_unregister_common(self->hw);
diff --git a/drivers/net/wireless/cw1200/pm.c b/drivers/net/wireless/cw1200/pm.c
index 79edfb9..b37abb9 100644
--- a/drivers/net/wireless/cw1200/pm.c
+++ b/drivers/net/wireless/cw1200/pm.c
@@ -15,7 +15,7 @@
#include "pm.h"
#include "sta.h"
#include "bh.h"
-#include "sbus.h"
+#include "hwbus.h"
#define CW1200_BEACON_SKIPPING_MULTIPLIER 3
@@ -264,7 +264,7 @@ int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
pm_state->suspend_state = state;
/* Enable IRQ wake */
- ret = priv->sbus_ops->power_mgmt(priv->sbus_priv, true);
+ ret = priv->hwbus_ops->power_mgmt(priv->hwbus_priv, true);
if (ret) {
wiphy_err(priv->hw->wiphy,
"PM request failed: %d. WoW is disabled.\n", ret);
@@ -313,7 +313,7 @@ int cw1200_wow_resume(struct ieee80211_hw *hw)
pm_state->suspend_state = NULL;
/* Disable IRQ wake */
- priv->sbus_ops->power_mgmt(priv->sbus_priv, false);
+ priv->hwbus_ops->power_mgmt(priv->hwbus_priv, false);
/* Scan.lock must be released before BH is resumed other way
* in case when BSS_LOST command arrived the processing of the
diff --git a/drivers/net/wireless/cw1200/pm.h b/drivers/net/wireless/cw1200/pm.h
index 516d967..3ed90ff 100644
--- a/drivers/net/wireless/cw1200/pm.h
+++ b/drivers/net/wireless/cw1200/pm.h
@@ -25,14 +25,19 @@ struct cw1200_pm_state {
spinlock_t lock; /* Protect access */
};
+#ifdef CONFIG_PM
int cw1200_pm_init(struct cw1200_pm_state *pm,
struct cw1200_common *priv);
void cw1200_pm_deinit(struct cw1200_pm_state *pm);
-void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
- unsigned long tmo);
int cw1200_wow_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wowlan);
int cw1200_wow_resume(struct ieee80211_hw *hw);
int cw1200_can_suspend(struct cw1200_common *priv);
-
+void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
+ unsigned long tmo);
+#else
+static inline void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
+ unsigned long tmo) {
+}
+#endif
#endif
diff --git a/drivers/net/wireless/cw1200/sbus.h b/drivers/net/wireless/cw1200/sbus.h
deleted file mode 100644
index 603fd25..0000000
--- a/drivers/net/wireless/cw1200/sbus.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Common sbus abstraction layer interface for cw1200 wireless driver
- *
- * Copyright (c) 2010, ST-Ericsson
- * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef CW1200_SBUS_H
-#define CW1200_SBUS_H
-
-/*
- * sbus priv forward definition.
- * Implemented and instantiated in particular modules.
- */
-struct sbus_priv;
-
-void cw1200_irq_handler(struct cw1200_common *priv);
-
-/* This MUST be wrapped with sbus_ops->lock/unlock! */
-int __cw1200_irq_enable(struct cw1200_common *priv, int enable);
-
-struct sbus_ops {
- int (*sbus_memcpy_fromio)(struct sbus_priv *self, unsigned int addr,
- void *dst, int count);
- int (*sbus_memcpy_toio)(struct sbus_priv *self, unsigned int addr,
- const void *src, int count);
- void (*lock)(struct sbus_priv *self);
- void (*unlock)(struct sbus_priv *self);
- size_t (*align_size)(struct sbus_priv *self, size_t size);
- int (*power_mgmt)(struct sbus_priv *self, bool suspend);
-};
-
-#endif /* CW1200_SBUS_H */
diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c
index 0e40890..a254747 100644
--- a/drivers/net/wireless/cw1200/txrx.c
+++ b/drivers/net/wireless/cw1200/txrx.c
@@ -190,13 +190,12 @@ static void tx_policy_build(const struct cw1200_common *priv,
policy->retry_count += retries;
}
- pr_debug("[TX policy] Policy (%zu): %d:%d, %d:%d, %d:%d, %d:%d, %d:%d\n",
+ pr_debug("[TX policy] Policy (%zu): %d:%d, %d:%d, %d:%d, %d:%d\n",
count,
rates[0].idx, rates[0].count,
rates[1].idx, rates[1].count,
rates[2].idx, rates[2].count,
- rates[3].idx, rates[3].count,
- rates[4].idx, rates[4].count);
+ rates[3].idx, rates[3].count);
}
static inline bool tx_policy_is_equal(const struct tx_policy *wanted,
diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c
index 4db6cc1..3ab25f6 100644
--- a/drivers/net/wireless/cw1200/wsm.c
+++ b/drivers/net/wireless/cw1200/wsm.c
@@ -12,7 +12,6 @@
#include <linux/skbuff.h>
#include <linux/wait.h>
-#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/random.h>
@@ -930,6 +929,8 @@ static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf)
}
event = kzalloc(sizeof(struct cw1200_wsm_event), GFP_KERNEL);
+ if (!event)
+ return -ENOMEM;
event->evt.id = __le32_to_cpu(WSM_GET32(buf));
event->evt.data = __le32_to_cpu(WSM_GET32(buf));
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 15920aa..f8ab193 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -6242,8 +6242,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
if ((val & 0x0000ff00) != 0)
pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff);
- pci_set_power_state(pci_dev, PCI_D0);
-
if (!ipw2100_hw_is_adapter_in_system(dev)) {
printk(KERN_WARNING DRV_NAME
"Device not found via register read.\n");
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index f297690..2ed296c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -84,6 +84,15 @@ static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
.types = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP),
},
+ {
+ .max = 1,
+ .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO),
+ },
+ {
+ .max = 1,
+ .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
+ },
};
static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
@@ -164,7 +173,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
hw->chanctx_data_size = sizeof(u16);
hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_AP);
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_GO) |
+ BIT(NL80211_IFTYPE_P2P_DEVICE);
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_DISABLE_BEACON_HINTS |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 69bbf6f..cb34c78 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2169,6 +2169,7 @@ static const struct ieee80211_iface_limit hwsim_if_limits[] = {
#endif
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_P2P_GO) },
+ { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) },
};
static struct ieee80211_iface_combination hwsim_if_comb = {
@@ -2294,7 +2295,8 @@ static int __init init_mac80211_hwsim(void)
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_MESH_POINT);
+ BIT(NL80211_IFTYPE_MESH_POINT) |
+ BIT(NL80211_IFTYPE_P2P_DEVICE);
hw->flags = IEEE80211_HW_MFP_CAPABLE |
IEEE80211_HW_SIGNAL_DBM |
diff --git a/include/linux/cw1200_platform.h b/include/linux/cw1200_platform.h
deleted file mode 100644
index c168fa5..0000000
--- a/include/linux/cw1200_platform.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2011
- *
- * Author: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#ifndef CW1200_PLAT_H_INCLUDED
-#define CW1200_PLAT_H_INCLUDED
-
-struct cw1200_platform_data_spi {
- u8 spi_bits_per_word; /* REQUIRED */
- u16 ref_clk; /* REQUIRED (in KHz) */
-
- /* All others are optional */
- bool have_5ghz;
- const struct resource *reset; /* GPIO to RSTn signal */
- const struct resource *powerup; /* GPIO to POWERUP signal */
- int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
- bool enable); /* Control 3v3 / 1v8 supply */
- int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata,
- bool enable); /* Control CLK32K */
- const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
- const char *sdd_file; /* if NULL, will use default for detected hw type */
-};
-
-struct cw1200_platform_data_sdio {
- u16 ref_clk; /* REQUIRED (in KHz) */
-
- /* All others are optional */
- const struct resource *irq; /* if using GPIO for IRQ */
- bool have_5ghz;
- bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
- const struct resource *reset; /* GPIO to RSTn signal */
- const struct resource *powerup; /* GPIO to POWERUP signal */
- int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
- bool enable); /* Control 3v3 / 1v8 supply */
- int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
- bool enable); /* Control CLK32K */
- const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
- const char *sdd_file; /* if NULL, will use default for detected hw type */
-};
-
-const void *cw1200_get_platform_data(void);
-
-#endif /* CW1200_PLAT_H_INCLUDED */
diff --git a/include/linux/platform_data/net-cw1200.h b/include/linux/platform_data/net-cw1200.h
new file mode 100644
index 0000000..c6fbc3c
--- /dev/null
+++ b/include/linux/platform_data/net-cw1200.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CW1200_PLAT_H_INCLUDED
+#define CW1200_PLAT_H_INCLUDED
+
+struct cw1200_platform_data_spi {
+ u8 spi_bits_per_word; /* REQUIRED */
+ u16 ref_clk; /* REQUIRED (in KHz) */
+
+ /* All others are optional */
+ bool have_5ghz;
+ int reset; /* GPIO to RSTn signal (0 disables) */
+ int powerup; /* GPIO to POWERUP signal (0 disables) */
+ int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
+ bool enable); /* Control 3v3 / 1v8 supply */
+ int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata,
+ bool enable); /* Control CLK32K */
+ const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
+ const char *sdd_file; /* if NULL, will use default for detected hw type */
+};
+
+struct cw1200_platform_data_sdio {
+ u16 ref_clk; /* REQUIRED (in KHz) */
+
+ /* All others are optional */
+ bool have_5ghz;
+ bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
+ int reset; /* GPIO to RSTn signal (0 disables) */
+ int powerup; /* GPIO to POWERUP signal (0 disables) */
+ int irq; /* IRQ line or 0 to use SDIO IRQ */
+ int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
+ bool enable); /* Control 3v3 / 1v8 supply */
+ int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
+ bool enable); /* Control CLK32K */
+ const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
+ const char *sdd_file; /* if NULL, will use default for detected hw type */
+};
+
+
+/* An example of SPI support in your board setup file:
+
+ static struct cw1200_platform_data_spi cw1200_platform_data = {
+ .ref_clk = 38400,
+ .spi_bits_per_word = 16,
+ .reset = GPIO_RF_RESET,
+ .powerup = GPIO_RF_POWERUP,
+ .macaddr = wifi_mac_addr,
+ .sdd_file = "sdd_sagrad_1091_1098.bin",
+ };
+ static struct spi_board_info myboard_spi_devices[] __initdata = {
+ {
+ .modalias = "cw1200_wlan_spi",
+ .max_speed_hz = 52000000,
+ .bus_num = 0,
+ .irq = WIFI_IRQ,
+ .platform_data = &cw1200_platform_data,
+ .chip_select = 0,
+ },
+ };
+
+ */
+
+/* An example of SDIO support in your board setup file:
+
+ static struct cw1200_platform_data_sdio my_cw1200_platform_data = {
+ .ref_clk = 38400,
+ .have_5ghz = false,
+ .sdd_file = "sdd_myplatform.bin",
+ };
+ cw1200_sdio_set_platform_data(&my_cw1200_platform_data);
+
+ */
+
+void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata);
+
+#endif /* CW1200_PLAT_H_INCLUDED */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b3b076a..6dd1959 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -961,6 +961,7 @@ struct station_info {
* @MONITOR_FLAG_CONTROL: pass control frames
* @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering
* @MONITOR_FLAG_COOK_FRAMES: report frames after processing
+ * @MONITOR_FLAG_ACTIVE: active monitor, ACKs frames on its MAC address
*/
enum monitor_flags {
MONITOR_FLAG_FCSFAIL = 1<<NL80211_MNTR_FLAG_FCSFAIL,
@@ -968,6 +969,7 @@ enum monitor_flags {
MONITOR_FLAG_CONTROL = 1<<NL80211_MNTR_FLAG_CONTROL,
MONITOR_FLAG_OTHER_BSS = 1<<NL80211_MNTR_FLAG_OTHER_BSS,
MONITOR_FLAG_COOK_FRAMES = 1<<NL80211_MNTR_FLAG_COOK_FRAMES,
+ MONITOR_FLAG_ACTIVE = 1<<NL80211_MNTR_FLAG_ACTIVE,
};
/**
@@ -2867,7 +2869,6 @@ struct cfg80211_cached_keys;
* @mgmt_registrations_lock: lock for the list
* @mtx: mutex used to lock data in this struct, may be used by drivers
* and some API functions require it held
- * @cleanup_work: work struct used for cleanup that can't be done directly
* @beacon_interval: beacon interval used on this device for transmitting
* beacons, 0 when not valid
* @address: The address for this device, valid only if @netdev is %NULL
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 32b060e..5920715 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2428,6 +2428,8 @@ enum nl80211_survey_info {
* @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering
* @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing.
* overrides all other flags.
+ * @NL80211_MNTR_FLAG_ACTIVE: use the configured MAC address
+ * and ACK incoming unicast packets.
*
* @__NL80211_MNTR_FLAG_AFTER_LAST: internal use
* @NL80211_MNTR_FLAG_MAX: highest possible monitor flag
@@ -2439,6 +2441,7 @@ enum nl80211_mntr_flags {
NL80211_MNTR_FLAG_CONTROL,
NL80211_MNTR_FLAG_OTHER_BSS,
NL80211_MNTR_FLAG_COOK_FRAMES,
+ NL80211_MNTR_FLAG_ACTIVE,
/* keep last */
__NL80211_MNTR_FLAG_AFTER_LAST,
@@ -3595,6 +3598,7 @@ enum nl80211_feature_flags {
NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14,
NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15,
NL80211_FEATURE_USERSPACE_MPM = 1 << 16,
+ NL80211_FEATURE_ACTIVE_MONITOR = 1 << 17,
};
/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 232edf7..3062210 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -73,16 +73,19 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
struct ieee80211_local *local = sdata->local;
if (ieee80211_sdata_running(sdata)) {
+ u32 mask = MONITOR_FLAG_COOK_FRAMES |
+ MONITOR_FLAG_ACTIVE;
+
/*
- * Prohibit MONITOR_FLAG_COOK_FRAMES to be
- * changed while the interface is up.
+ * Prohibit MONITOR_FLAG_COOK_FRAMES and
+ * MONITOR_FLAG_ACTIVE to be changed while the
+ * interface is up.
* Else we would need to add a lot of cruft
* to update everything:
* cooked_mntrs, monitor and all fif_* counters
* reconfigure hardware
*/
- if ((*flags & MONITOR_FLAG_COOK_FRAMES) !=
- (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
+ if ((*flags & mask) != (sdata->u.mntr_flags & mask))
return -EBUSY;
ieee80211_adjust_monitor_flags(sdata, -1);
@@ -2375,7 +2378,9 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
local->dynamic_ps_forced_timeout = timeout;
/* no change, but if automatic follow powersave */
+ sdata_lock(sdata);
__ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
+ sdata_unlock(sdata);
if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 169664c..b931c96 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -146,7 +146,8 @@ static inline int drv_add_interface(struct ieee80211_local *local,
if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
(sdata->vif.type == NL80211_IFTYPE_MONITOR &&
- !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))))
+ !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF) &&
+ !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))))
return -EINVAL;
trace_drv_add_interface(local, sdata);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index ceef644..7cabaf2 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -159,7 +159,8 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
-static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
+static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr,
+ bool check_dup)
{
struct ieee80211_sub_if_data *sdata;
u64 new, mask, tmp;
@@ -179,10 +180,13 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
+ if (!check_dup)
+ return ret;
mutex_lock(&local->iflist_mtx);
list_for_each_entry(sdata, &local->interfaces, list) {
- if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
+ !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
continue;
m = sdata->vif.addr;
@@ -204,12 +208,17 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct sockaddr *sa = addr;
+ bool check_dup = true;
int ret;
if (ieee80211_sdata_running(sdata))
return -EBUSY;
- ret = ieee80211_verify_mac(sdata->local, sa->sa_data);
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
+ !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+ check_dup = false;
+
+ ret = ieee80211_verify_mac(sdata->local, sa->sa_data, check_dup);
if (ret)
return ret;
@@ -541,7 +550,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
break;
}
- if (local->monitors == 0 && local->open_count == 0) {
+ if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) {
+ res = drv_add_interface(local, sdata);
+ if (res)
+ goto err_stop;
+ } else if (local->monitors == 0 && local->open_count == 0) {
res = ieee80211_add_virtual_monitor(local);
if (res)
goto err_stop;
@@ -919,7 +932,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
mutex_lock(&local->mtx);
ieee80211_recalc_idle(local);
mutex_unlock(&local->mtx);
- break;
+
+ if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+ break;
+
+ /* fall through */
default:
if (going_down)
drv_remove_interface(local, sdata);
@@ -1068,7 +1085,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
.ndo_start_xmit = ieee80211_monitor_start_xmit,
.ndo_set_rx_mode = ieee80211_set_multicast_list,
.ndo_change_mtu = ieee80211_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = ieee80211_change_mac,
.ndo_select_queue = ieee80211_monitor_select_queue,
};
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 9972e07..34be933 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -398,13 +398,14 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
if (ieee80211_has_order(hdr->frame_control))
return TX_CONTINUE;
+ if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
+ info->hw_queue = tx->sdata->vif.cab_queue;
+
/* no stations in PS mode */
if (!atomic_read(&ps->num_sta_ps))
return TX_CONTINUE;
info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
- if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
- info->hw_queue = tx->sdata->vif.cab_queue;
/* device releases frame after DTIM beacon */
if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING))
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 2a8d759..89a8377 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -560,6 +560,9 @@ void ieee80211_iterate_active_interfaces(
list_for_each_entry(sdata, &local->interfaces, list) {
switch (sdata->vif.type) {
case NL80211_IFTYPE_MONITOR:
+ if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+ continue;
+ break;
case NL80211_IFTYPE_AP_VLAN:
continue;
default:
@@ -598,6 +601,9 @@ void ieee80211_iterate_active_interfaces_atomic(
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
switch (sdata->vif.type) {
case NL80211_IFTYPE_MONITOR:
+ if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+ continue;
+ break;
case NL80211_IFTYPE_AP_VLAN:
continue;
default:
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index fb6abcb..31d265f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2227,6 +2227,7 @@ static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
[NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
[NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
[NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
+ [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
};
static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
@@ -2338,6 +2339,10 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
change = true;
}
+ if (flags && (*flags & NL80211_MNTR_FLAG_ACTIVE) &&
+ !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
+ return -EOPNOTSUPP;
+
if (change)
err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
else
@@ -2395,6 +2400,11 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
&flags);
+
+ if (!err && (flags & NL80211_MNTR_FLAG_ACTIVE) &&
+ !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
+ return -EOPNOTSUPP;
+
wdev = rdev_add_virtual_intf(rdev,
nla_data(info->attrs[NL80211_ATTR_IFNAME]),
type, err ? NULL : &flags, &params);
OpenPOWER on IntegriCloud