diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-06-11 20:16:44 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-06-11 20:16:44 +0200 |
commit | 8e00cc12618ef525483954707fcd356c7f280e18 (patch) | |
tree | 6a3f19ab5435e751ef4d8ce3e1861d12124a3026 /drivers | |
parent | iwlwifi: include export.h instead of module.h (diff) | |
parent | cw1200: Fix an assorted pile of checkpatch warnings. (diff) | |
download | linux-8e00cc12618ef525483954707fcd356c7f280e18.tar.xz linux-8e00cc12618ef525483954707fcd356c7f280e18.zip |
Merge remote-tracking branch 'wireless-next/master' into iwlwifi-next
Diffstat (limited to 'drivers')
48 files changed, 526 insertions, 2042 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 7ecd40f07a74..e91725bf401c 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 dddb1361039a..78b9fa9f6455 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 391da5ad6a99..d1acfe98918a 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 830daa12feb6..8dc2d089cdef 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 beb6162cf97c..4d18c66a6790 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 301bf72c53bf..5163abd3937c 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 2bf6548dd143..0d053503b8bf 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 fc96ad3a135b..7852f6e59964 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 62da19c6f4e0..9719378f7c73 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 2a67b57c3ecb..34869c2405aa 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 a263ccc00a47..a13f6cea2ba7 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 ae3034374bc4..7d259b7dc254 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 c7b888f22703..979bde3b8f9e 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 cc422a4dfa17..fff5d3ccc663 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 498fee04afa0..d055e389abfc 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 5865f92998e1..b02dfce964b4 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 a1630d1ee3c9..cc5a98b8d187 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 8be2b5d8c155..865e043e8aa6 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 9f8563091bea..81c88dd606dc 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 1585cc5bf866..bd982856d385 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 13e36119ae9f..0880742eab17 100644 --- a/drivers/net/wireless/cw1200/Kconfig +++ b/drivers/net/wireless/cw1200/Kconfig @@ -13,34 +13,18 @@ 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. - -menu "Driver debug features" - depends on CW1200 && DEBUG_FS - -config CW1200_ETF - bool "Enable CW1200 Engineering Test Framework hooks" - help - If you don't know what this is, just say N. - -config CW1200_ITP - bool "Enable ITP access" - help - If you don't know what this is, just say N. - -endmenu + Enables support for the CW1200 connected via a SPI bus. You will + need to add appropriate platform data glue in your board setup + file. endif diff --git a/drivers/net/wireless/cw1200/Makefile b/drivers/net/wireless/cw1200/Makefile index c19737276be2..b086aac6547a 100644 --- a/drivers/net/wireless/cw1200/Makefile +++ b/drivers/net/wireless/cw1200/Makefile @@ -8,17 +8,14 @@ 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 cf7375f92fb3..c1ec2a4dd8c0 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" @@ -31,7 +31,8 @@ static int cw1200_bh(void *arg); #define DOWNLOAD_BLOCK_SIZE_WR (0x1000 - 4) /* an SPI message cannot be bigger than (2"12-1)*2 bytes - * "*2" to cvt to bytes */ + * "*2" to cvt to bytes + */ #define MAX_SZ_RD_WR_BUFFERS (DOWNLOAD_BLOCK_SIZE_WR*2) #define PIGGYBACK_CTRL_REG (2) #define EFFECTIVE_BUF_SIZE (MAX_SZ_RD_WR_BUFFERS - PIGGYBACK_CTRL_REG) @@ -103,7 +104,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)) @@ -217,7 +218,8 @@ static int cw1200_device_wakeup(struct cw1200_common *priv) return ret; /* If the device returns WLAN_RDY as 1, the device is active and will - * remain active. */ + * remain active. + */ if (ctrl_reg & ST90TDS_CONT_RDY_BIT) { pr_debug("[BH] Device awake.\n"); return 1; @@ -262,11 +264,12 @@ static int cw1200_bh_rx_helper(struct cw1200_common *priv, } /* Add SIZE of PIGGYBACK reg (CONTROL Reg) - * to the NEXT Message length + 2 Bytes for SKB */ + * 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 +387,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 +600,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 2aa17ca60ba8..243e96353d13 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,16 +30,11 @@ #include "pm.h" /* Forward declarations */ -struct sbus_ops; +struct hwbus_ops; struct task_struct; struct cw1200_debug_priv; struct firmware; -#ifdef CONFIG_CW1200_ETF -extern int etf_mode; -extern char *etf_firmware; -#endif - #define CW1200_MAX_CTRL_FRAME_LEN (0x1000) #define CW1200_MAX_STA_IN_AP_MODE (5) @@ -110,8 +104,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 { @@ -213,7 +207,8 @@ struct cw1200_common { /* Scan status */ struct cw1200_scan scan; /* Keep cw1200 awake (WUP = 1) 1 second after each scan to avoid - * FW issue with sleeping/waking up. */ + * FW issue with sleeping/waking up. + */ atomic_t recent_scan; struct delayed_work clear_recent_scan_work; @@ -288,10 +283,6 @@ struct cw1200_common { struct work_struct linkid_reset_work; u8 action_frame_sa[ETH_ALEN]; u8 action_linkid; - -#ifdef CONFIG_CW1200_ETF - struct sk_buff_head etf_q; -#endif }; struct cw1200_sta_priv { @@ -299,8 +290,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 a5ada0eda1dd..000000000000 --- 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 f6e22192d80a..ebdcdf44f155 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, @@ -315,10 +323,11 @@ static int cw1200_sdio_probe(struct sdio_func *func, } /* Disconnect Function to be called by SDIO stack when - * device is disconnected */ + * 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 +343,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 +370,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 +390,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 +413,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 04af68534854..953bd1904d3d 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; @@ -48,18 +47,16 @@ struct sbus_priv { #define SET_WRITE 0x7FFF /* usage: and operation */ #define SET_READ 0x8000 /* usage: or operation */ -/* - Notes on byte ordering: +/* Notes on byte ordering: LE: B0 B1 B2 B3 BE: B3 B2 B1 B0 Hardware expects 32-bit data to be written as 16-bit BE words: B1 B0 B3 B2 - */ -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 +117,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 +185,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 +207,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 +219,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 +229,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 +253,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 +266,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 +282,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 +312,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 +348,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 +382,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 +394,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 +413,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 +428,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 +444,7 @@ static int cw1200_spi_resume(struct device *dev) { return 0; } +#endif static struct spi_driver spi_driver = { .probe = cw1200_spi_probe, @@ -459,22 +453,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 b815181802e0..e323b4d54338 100644 --- a/drivers/net/wireless/cw1200/debug.c +++ b/drivers/net/wireless/cw1200/debug.c @@ -357,140 +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) -{ - struct cw1200_common *priv = seq->private; - struct sk_buff *skb; - u32 len = 0; - - skb = skb_dequeue(&priv->etf_q); - - if (skb) - len = skb->len; - - seq_write(seq, &len, sizeof(len)); - - if (skb) { - seq_write(seq, skb->data, len); - kfree_skb(skb); - } - - return 0; -} - -static int cw1200_etf_out_open(struct inode *inode, struct file *file) -{ - return single_open(file, &cw1200_etf_out_show, - inode->i_private); -} - -static const struct file_operations fops_etf_out = { - .open = cw1200_etf_out_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner = THIS_MODULE, -}; - -struct etf_req_msg; -static int etf_request(struct cw1200_common *priv, - struct etf_req_msg *msg, u32 len); - -#define MAX_RX_SZE 2600 - -struct etf_in_state { - struct cw1200_common *priv; - u32 total_len; - u8 buf[MAX_RX_SZE]; - u32 written; -}; - -static int cw1200_etf_in_open(struct inode *inode, struct file *file) -{ - struct etf_in_state *etf = kmalloc(sizeof(struct etf_in_state), - GFP_KERNEL); - - if (!etf) - return -ENOMEM; - - etf->written = 0; - etf->total_len = 0; - etf->priv = inode->i_private; - - file->private_data = etf; - - return 0; -} - -static int cw1200_etf_in_release(struct inode *inode, struct file *file) -{ - kfree(file->private_data); - return 0; -} - -static ssize_t cw1200_etf_in_write(struct file *file, - const char __user *user_buf, size_t count, loff_t *ppos) -{ - struct etf_in_state *etf = file->private_data; - - ssize_t written = 0; - - if (!etf->total_len) { - if (count < sizeof(etf->total_len)) { - pr_err("count < sizeof(total_len)\n"); - return -EINVAL; - } - - if (copy_from_user(&etf->total_len, user_buf, - sizeof(etf->total_len))) { - pr_err("copy_from_user (len) failed\n"); - return -EFAULT; - } - - written += sizeof(etf->total_len); - count -= sizeof(etf->total_len); - } - - if (!count) - goto done; - - if (copy_from_user(etf->buf + etf->written, user_buf + written, - count)) { - pr_err("copy_from_user (payload %zu) failed\n", count); - return -EFAULT; - } - - written += count; - etf->written += count; - - if (etf->written >= etf->total_len) { - if (etf_request(etf->priv, (struct etf_req_msg *)etf->buf, - etf->total_len)) { - pr_err("etf_request failed\n"); - return -EIO; - } - } - -done: - return written; -} - -static const struct file_operations fops_etf_in = { - .open = cw1200_etf_in_open, - .release = cw1200_etf_in_release, - .write = cw1200_etf_in_write, - .llseek = default_llseek, - .owner = THIS_MODULE, -}; -#endif /* CONFIG_CW1200_ETF */ - static ssize_t cw1200_wsm_dumps(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { @@ -511,7 +377,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, }; @@ -538,27 +404,10 @@ int cw1200_debug_init(struct cw1200_common *priv) priv, &fops_counters)) goto err; -#ifdef CONFIG_CW1200_ETF - if (etf_mode) { - skb_queue_head_init(&priv->etf_q); - - if (!debugfs_create_file("etf_out", S_IRUSR, d->debugfs_phy, - priv, &fops_etf_out)) - goto err; - if (!debugfs_create_file("etf_in", S_IWUSR, d->debugfs_phy, - priv, &fops_etf_in)) - goto err; - } -#endif /* CONFIG_CW1200_ETF */ - if (!debugfs_create_file("wsm_dumps", S_IWUSR, d->debugfs_phy, priv, &fops_wsm_dumps)) goto err; - ret = cw1200_itp_init(priv); - if (ret) - goto err; - return 0; err: @@ -572,93 +421,8 @@ void cw1200_debug_release(struct cw1200_common *priv) { struct cw1200_debug_priv *d = priv->debug; if (d) { - cw1200_itp_release(priv); + debugfs_remove_recursive(d->debugfs_phy); priv->debug = NULL; kfree(d); } } - -#ifdef CONFIG_CW1200_ETF -struct cw1200_sdd { - u8 id; - u8 len; - u8 data[]; -}; - -struct etf_req_msg { - u32 id; - u32 len; - u8 data[]; -}; - -static int parse_sdd_file(struct cw1200_common *priv, u8 *data, u32 length) -{ - struct cw1200_sdd *ie; - - while (length > 0) { - ie = (struct cw1200_sdd *)data; - if (ie->id == SDD_REFERENCE_FREQUENCY_ELT_ID) { - priv->hw_refclk = cpu_to_le16(*((u16 *)ie->data)); - pr_info("Using Reference clock frequency %d KHz\n", - priv->hw_refclk); - break; - } - - length -= ie->len + sizeof(*ie); - data += ie->len + sizeof(*ie); - } - return 0; -} - -char *etf_firmware; - -#define ST90TDS_START_ADAPTER 0x09 /* Loads firmware too */ -#define ST90TDS_STOP_ADAPTER 0x0A -#define ST90TDS_CONFIG_ADAPTER 0x0E /* Send configuration params */ -#define ST90TDS_SBUS_READ 0x13 -#define ST90TDS_SBUS_WRITE 0x14 -#define ST90TDS_GET_DEVICE_OPTION 0x19 -#define ST90TDS_SET_DEVICE_OPTION 0x1A -#define ST90TDS_SEND_SDD 0x1D /* SDD File used to find DPLL */ - -#include "fwio.h" - -static int etf_request(struct cw1200_common *priv, - struct etf_req_msg *msg, - u32 len) -{ - int rval = -1; - switch (msg->id) { - case ST90TDS_START_ADAPTER: - etf_firmware = "cw1200_etf.bin"; - pr_info("ETF_START (len %d, '%s')\n", len, etf_firmware); - rval = cw1200_load_firmware(priv); - break; - case ST90TDS_STOP_ADAPTER: - pr_info("ETF_STOP (unhandled)\n"); - break; - case ST90TDS_SEND_SDD: - pr_info("ETF_SDD\n"); - rval = parse_sdd_file(priv, msg->data, msg->len); - break; - case ST90TDS_CONFIG_ADAPTER: - pr_info("ETF_CONFIG_ADAP (unhandled)\n"); - break; - case ST90TDS_SBUS_READ: - pr_info("ETF_SBUS_READ (unhandled)\n"); - break; - case ST90TDS_SBUS_WRITE: - pr_info("ETF_SBUS_WRITE (unhandled)\n"); - break; - case ST90TDS_SET_DEVICE_OPTION: - pr_info("ETF_SET_DEV_OPT (unhandled)\n"); - break; - default: - pr_info("ETF_PASSTHRU (0x%08x)\n", msg->id); - rval = wsm_raw_cmd(priv, (u8 *)msg, len); - break; - } - - return rval; -} -#endif /* CONFIG_CW1200_ETF */ diff --git a/drivers/net/wireless/cw1200/debug.h b/drivers/net/wireless/cw1200/debug.h index 1fea5b29a819..b525aba53bfc 100644 --- a/drivers/net/wireless/cw1200/debug.h +++ b/drivers/net/wireless/cw1200/debug.h @@ -12,8 +12,6 @@ #ifndef CW1200_DEBUG_H_INCLUDED #define CW1200_DEBUG_H_INCLUDED -#include "itp.h" - struct cw1200_debug_priv { struct dentry *debugfs_phy; int tx; @@ -30,9 +28,6 @@ struct cw1200_debug_priv { int ba_acc; int ba_cnt_rx; int ba_acc_rx; -#ifdef CONFIG_CW1200_ITP - struct cw1200_itp itp; -#endif /* CONFIG_CW1200_ITP */ }; int cw1200_debug_init(struct cw1200_common *priv); diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c index ad01cd2a59ec..acdff0f7f952 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) @@ -139,11 +139,6 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv) val32 &= ~ST90TDS_CONFIG_CPU_CLK_DIS_BIT; REG_WRITE(ST90TDS_CONFIG_REG_ID, val32); -#ifdef CONFIG_CW1200_ETF - if (etf_mode) - fw_path = etf_firmware; -#endif - /* Load a firmware file */ ret = request_firmware(&firmware, fw_path, priv->pdev); if (ret) { @@ -489,9 +484,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 +513,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 000000000000..8b2fc831c3de --- /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 1af7b3d421b2..dad3fb331818 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/hwio.h b/drivers/net/wireless/cw1200/hwio.h index 7ee73fe32ccf..563329cfead6 100644 --- a/drivers/net/wireless/cw1200/hwio.h +++ b/drivers/net/wireless/cw1200/hwio.h @@ -97,9 +97,8 @@ struct download_cntl_t { #define CW1200_APB(addr) (PAC_SHARED_MEMORY_SILICON + (addr)) -/* *************************************************************** -*Device register definitions -*************************************************************** */ +/* Device register definitions */ + /* WBF - SPI Register Addresses */ #define ST90TDS_ADDR_ID_BASE (0x0000) /* 16/32 bits */ diff --git a/drivers/net/wireless/cw1200/itp.c b/drivers/net/wireless/cw1200/itp.c deleted file mode 100644 index c0730bb49b75..000000000000 --- a/drivers/net/wireless/cw1200/itp.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers - * ITP code - * - * 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. - */ - -#include <linux/module.h> -#include <linux/debugfs.h> -#include <linux/poll.h> -#include <linux/time.h> -#include <linux/random.h> -#include <linux/kallsyms.h> -#include <net/mac80211.h> -#include "cw1200.h" -#include "debug.h" -#include "itp.h" -#include "sta.h" - -static int __cw1200_itp_open(struct cw1200_common *priv); -static int __cw1200_itp_close(struct cw1200_common *priv); -static void cw1200_itp_rx_start(struct cw1200_common *priv); -static void cw1200_itp_rx_stop(struct cw1200_common *priv); -static void cw1200_itp_rx_stats(struct cw1200_common *priv); -static void cw1200_itp_rx_reset(struct cw1200_common *priv); -static void cw1200_itp_tx_stop(struct cw1200_common *priv); -static void cw1200_itp_handle(struct cw1200_common *priv, - struct sk_buff *skb); -static void cw1200_itp_err(struct cw1200_common *priv, - int err, - int arg); -static void __cw1200_itp_tx_stop(struct cw1200_common *priv); - -static ssize_t cw1200_itp_read(struct file *file, - char __user *user_buf, size_t count, loff_t *ppos) -{ - struct cw1200_common *priv = file->private_data; - struct cw1200_itp *itp = &priv->debug->itp; - struct sk_buff *skb; - int ret; - - if (skb_queue_empty(&itp->log_queue)) - return 0; - - skb = skb_dequeue(&itp->log_queue); - ret = copy_to_user(user_buf, skb->data, skb->len); - *ppos += skb->len; - skb->data[skb->len] = 0; - pr_debug("[ITP] >>> %s", skb->data); - consume_skb(skb); - - return skb->len - ret; -} - -static ssize_t cw1200_itp_write(struct file *file, - const char __user *user_buf, size_t count, loff_t *ppos) -{ - struct cw1200_common *priv = file->private_data; - struct sk_buff *skb; - - if (!count || count > 1024) - return -EINVAL; - skb = dev_alloc_skb(count + 1); - if (!skb) - return -ENOMEM; - skb_trim(skb, 0); - skb_put(skb, count + 1); - if (copy_from_user(skb->data, user_buf, count)) { - kfree_skb(skb); - return -EFAULT; - } - skb->data[count] = 0; - - cw1200_itp_handle(priv, skb); - consume_skb(skb); - return count; -} - -static unsigned int cw1200_itp_poll(struct file *file, poll_table *wait) -{ - struct cw1200_common *priv = file->private_data; - struct cw1200_itp *itp = &priv->debug->itp; - unsigned int mask = 0; - - poll_wait(file, &itp->read_wait, wait); - - if (!skb_queue_empty(&itp->log_queue)) - mask |= POLLIN | POLLRDNORM; - - mask |= POLLOUT | POLLWRNORM; - - return mask; -} - -static int cw1200_itp_open(struct inode *inode, struct file *file) -{ - struct cw1200_common *priv = inode->i_private; - struct cw1200_itp *itp = &priv->debug->itp; - int ret = 0; - - file->private_data = priv; - if (atomic_inc_return(&itp->open_count) == 1) { - ret = __cw1200_itp_open(priv); - if (ret && !atomic_dec_return(&itp->open_count)) - __cw1200_itp_close(priv); - } else { - atomic_dec(&itp->open_count); - ret = -EBUSY; - } - - return ret; -} - -static int cw1200_itp_close(struct inode *inode, struct file *file) -{ - struct cw1200_common *priv = file->private_data; - struct cw1200_itp *itp = &priv->debug->itp; - if (!atomic_dec_return(&itp->open_count)) { - __cw1200_itp_close(priv); - wake_up(&itp->close_wait); - } - return 0; -} - -static const struct file_operations fops_itp = { - .open = cw1200_itp_open, - .read = cw1200_itp_read, - .write = cw1200_itp_write, - .poll = cw1200_itp_poll, - .release = cw1200_itp_close, - .llseek = default_llseek, - .owner = THIS_MODULE, -}; - -static void cw1200_itp_fill_pattern(u8 *data, int size, - enum cw1200_itp_data_modes mode) -{ - if (size <= 0) - return; - - switch (mode) { - default: - case ITP_DATA_ZEROS: - memset(data, 0x0, size); - break; - case ITP_DATA_ONES: - memset(data, 0xff, size); - break; - case ITP_DATA_ZERONES: - memset(data, 0x55, size); - break; - case ITP_DATA_RANDOM: - get_random_bytes(data, size); - break; - } - return; -} - -static void cw1200_itp_tx_work(struct work_struct *work) -{ - struct cw1200_itp *itp = container_of(work, struct cw1200_itp, - tx_work.work); - struct cw1200_common *priv = itp->priv; - atomic_set(&priv->bh_tx, 1); - wake_up(&priv->bh_wq); -} - -static void cw1200_itp_tx_finish(struct work_struct *work) -{ - struct cw1200_itp *itp = container_of(work, struct cw1200_itp, - tx_finish.work); - __cw1200_itp_tx_stop(itp->priv); -} - -int cw1200_itp_init(struct cw1200_common *priv) -{ - struct cw1200_itp *itp = &priv->debug->itp; - - itp->priv = priv; - atomic_set(&itp->open_count, 0); - atomic_set(&itp->stop_tx, 0); - atomic_set(&itp->awaiting_confirm, 0); - skb_queue_head_init(&itp->log_queue); - spin_lock_init(&itp->tx_lock); - init_waitqueue_head(&itp->read_wait); - init_waitqueue_head(&itp->write_wait); - init_waitqueue_head(&itp->close_wait); - INIT_DELAYED_WORK(&itp->tx_work, cw1200_itp_tx_work); - INIT_DELAYED_WORK(&itp->tx_finish, cw1200_itp_tx_finish); - itp->data = NULL; - itp->hdr_len = WSM_TX_EXTRA_HEADROOM + - sizeof(struct ieee80211_hdr_3addr); - - if (!debugfs_create_file("itp", S_IRUSR | S_IWUSR, - priv->debug->debugfs_phy, priv, &fops_itp)) - return -ENOMEM; - - return 0; -} - -void cw1200_itp_release(struct cw1200_common *priv) -{ - struct cw1200_itp *itp = &priv->debug->itp; - - wait_event_interruptible(itp->close_wait, - !atomic_read(&itp->open_count)); - - WARN_ON(atomic_read(&itp->open_count)); - - skb_queue_purge(&itp->log_queue); - cw1200_itp_tx_stop(priv); -} - -static int __cw1200_itp_open(struct cw1200_common *priv) -{ - struct cw1200_itp *itp = &priv->debug->itp; - - if (!priv->vif) - return -EINVAL; - if (priv->join_status) - return -EINVAL; - itp->saved_channel = priv->channel; - if (!priv->channel) - priv->channel = &priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0]; - wsm_set_bssid_filtering(priv, false); - cw1200_itp_rx_reset(priv); - return 0; -} - -static int __cw1200_itp_close(struct cw1200_common *priv) -{ - struct cw1200_itp *itp = &priv->debug->itp; - if (atomic_read(&itp->test_mode) == TEST_MODE_RX_TEST) - cw1200_itp_rx_stop(priv); - cw1200_itp_tx_stop(priv); - cw1200_disable_listening(priv); - cw1200_update_filtering(priv); - priv->channel = itp->saved_channel; - return 0; -} - -bool cw1200_is_itp(struct cw1200_common *priv) -{ - struct cw1200_itp *itp = &priv->debug->itp; - return atomic_read(&itp->open_count) != 0; -} - -static void cw1200_itp_rx_reset(struct cw1200_common *priv) -{ - struct cw1200_itp *itp = &priv->debug->itp; - itp->rx_cnt = 0; - itp->rx_rssi = 0; - itp->rx_rssi_max = -1000; - itp->rx_rssi_min = 1000; -} - -static void cw1200_itp_rx_start(struct cw1200_common *priv) -{ - struct cw1200_itp *itp = &priv->debug->itp; - - pr_debug("[ITP] RX start, band = %d, ch = %d\n", - itp->band, itp->ch); - atomic_set(&itp->test_mode, TEST_MODE_RX_TEST); - cw1200_update_listening(priv, false); - priv->channel = &priv->hw-> - wiphy->bands[itp->band]->channels[itp->ch]; - cw1200_update_listening(priv, true); - wsm_set_bssid_filtering(priv, false); -} - -static void cw1200_itp_rx_stop(struct cw1200_common *priv) -{ - struct cw1200_itp *itp = &priv->debug->itp; - pr_debug("[ITP] RX stop\n"); - atomic_set(&itp->test_mode, TEST_MODE_NO_TEST); - cw1200_itp_rx_reset(priv); -} - -static void cw1200_itp_rx_stats(struct cw1200_common *priv) -{ - struct cw1200_itp *itp = &priv->debug->itp; - struct sk_buff *skb; - char buf[128]; - int len, ret; - struct wsm_mib_counters_table counters; - - ret = wsm_get_counters_table(priv, &counters); - - if (ret) - cw1200_itp_err(priv, -EBUSY, 20); - - if (!itp->rx_cnt) - len = snprintf(buf, sizeof(buf), "1,0,0,0,0,%d\n", - counters.rx_packet_errors); - else - len = snprintf(buf, sizeof(buf), "1,%d,%ld,%d,%d,%d\n", - itp->rx_cnt, - itp->rx_cnt ? itp->rx_rssi / itp->rx_cnt : 0, - itp->rx_rssi_min, itp->rx_rssi_max, - counters.rx_packet_errors); - - if (len <= 0) { - cw1200_itp_err(priv, -EBUSY, 21); - return; - } - - skb = dev_alloc_skb(len); - if (!skb) { - cw1200_itp_err(priv, -ENOMEM, 22); - return; - } - - itp->rx_cnt = 0; - itp->rx_rssi = 0; - itp->rx_rssi_max = -1000; - itp->rx_rssi_min = 1000; - - skb_trim(skb, 0); - skb_put(skb, len); - - memcpy(skb->data, buf, len); - skb_queue_tail(&itp->log_queue, skb); - wake_up(&itp->read_wait); -} - -static void cw1200_itp_tx_start(struct cw1200_common *priv) -{ - struct wsm_tx *tx; - struct ieee80211_hdr_3addr *hdr; - struct cw1200_itp *itp = &priv->debug->itp; - struct wsm_mib_association_mode assoc_mode = { - .flags = WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE, - .preamble = itp->preamble, - }; - int len; - u8 da_addr[6] = ITP_DEFAULT_DA_ADDR; - - /* Rates index 4 and 5 are not supported */ - if (itp->rate > 3) - itp->rate += 2; - - pr_debug("[ITP] TX start: band = %d, ch = %d, rate = %d, preamble = %d, number = %d, data_mode = %d, interval = %d, power = %d, data_len = %d\n", - itp->band, itp->ch, itp->rate, itp->preamble, - itp->number, itp->data_mode, itp->interval_us, - itp->power, itp->data_len); - - len = itp->hdr_len + itp->data_len; - - itp->data = kmalloc(len, GFP_KERNEL); - tx = (struct wsm_tx *)itp->data; - tx->hdr.len = itp->data_len + itp->hdr_len; - tx->hdr.id = __cpu_to_le16(0x0004 | 1 << 6); - tx->max_tx_rate = itp->rate; - tx->queue_id = 3; - tx->more = 0; - tx->flags = 0xc; - tx->packet_id = 0x55ff55; - tx->reserved = 0; - tx->expire_time = 1; - - if (itp->preamble == ITP_PREAMBLE_GREENFIELD) - tx->ht_tx_parameters = WSM_HT_TX_GREENFIELD; - else if (itp->preamble == ITP_PREAMBLE_MIXED) - tx->ht_tx_parameters = WSM_HT_TX_MIXED; - - hdr = (struct ieee80211_hdr_3addr *)&itp->data[sizeof(struct wsm_tx)]; - memset(hdr, 0, sizeof(*hdr)); - hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS); - memcpy(hdr->addr1, da_addr, ETH_ALEN); - memcpy(hdr->addr2, priv->vif->addr, ETH_ALEN); - memcpy(hdr->addr3, da_addr, ETH_ALEN); - - cw1200_itp_fill_pattern(&itp->data[itp->hdr_len], - itp->data_len, itp->data_mode); - - cw1200_update_listening(priv, false); - priv->channel = &priv->hw->wiphy->bands[itp->band]->channels[itp->ch]; - WARN_ON(wsm_set_output_power(priv, itp->power)); - if (itp->preamble == ITP_PREAMBLE_SHORT || - itp->preamble == ITP_PREAMBLE_LONG) - WARN_ON(wsm_set_association_mode(priv, - &assoc_mode)); - wsm_set_bssid_filtering(priv, false); - cw1200_update_listening(priv, true); - - spin_lock_bh(&itp->tx_lock); - atomic_set(&itp->test_mode, TEST_MODE_TX_TEST); - atomic_set(&itp->awaiting_confirm, 0); - atomic_set(&itp->stop_tx, 0); - atomic_set(&priv->bh_tx, 1); - ktime_get_ts(&itp->last_sent); - wake_up(&priv->bh_wq); - spin_unlock_bh(&itp->tx_lock); -} - -void __cw1200_itp_tx_stop(struct cw1200_common *priv) -{ - struct cw1200_itp *itp = &priv->debug->itp; - spin_lock_bh(&itp->tx_lock); - kfree(itp->data); - itp->data = NULL; - atomic_set(&itp->test_mode, TEST_MODE_NO_TEST); - spin_unlock_bh(&itp->tx_lock); -} - -static void cw1200_itp_tx_stop(struct cw1200_common *priv) -{ - struct cw1200_itp *itp = &priv->debug->itp; - pr_debug("[ITP] TX stop\n"); - atomic_set(&itp->stop_tx, 1); - flush_workqueue(priv->workqueue); - - /* time for FW to confirm all tx requests */ - msleep(500); - - __cw1200_itp_tx_stop(priv); -} - -static int cw1200_print_fw_version(struct cw1200_common *priv, - u8 *buf, size_t len) -{ - return snprintf(buf, len, "%s %d.%d", - cw1200_fw_types[priv->wsm_caps.fw_type], - priv->wsm_caps.fw_ver, - priv->wsm_caps.fw_build); -} - -static void cw1200_itp_get_version(struct cw1200_common *priv, - enum cw1200_itp_version_type type) -{ - struct cw1200_itp *itp = &priv->debug->itp; - struct sk_buff *skb; - char buf[ITP_BUF_SIZE]; - size_t size = 0; - int len; - pr_debug("[ITP] print %s version\n", - type == ITP_CHIP_ID ? "chip" : "firmware"); - - len = snprintf(buf, ITP_BUF_SIZE, "2,"); - if (len <= 0) { - cw1200_itp_err(priv, -EINVAL, 40); - return; - } - size += len; - - switch (type) { - case ITP_CHIP_ID: - len = cw1200_print_fw_version(priv, buf+size, - ITP_BUF_SIZE - size); - - if (len <= 0) { - cw1200_itp_err(priv, -EINVAL, 41); - return; - } - size += len; - break; - case ITP_FW_VER: - len = snprintf(buf+size, ITP_BUF_SIZE - size, - "%d.%d", priv->wsm_caps.hw_id, - priv->wsm_caps.hw_subid); - if (len <= 0) { - cw1200_itp_err(priv, -EINVAL, 42); - return; - } - size += len; - break; - default: - cw1200_itp_err(priv, -EINVAL, 43); - break; - } - - len = snprintf(buf+size, ITP_BUF_SIZE-size, "\n"); - if (len <= 0) { - cw1200_itp_err(priv, -EINVAL, 44); - return; - } - size += len; - - skb = dev_alloc_skb(size); - if (!skb) { - cw1200_itp_err(priv, -ENOMEM, 45); - return; - } - - skb_trim(skb, 0); - skb_put(skb, size); - - memcpy(skb->data, buf, size); - skb_queue_tail(&itp->log_queue, skb); - wake_up(&itp->read_wait); -} - -int cw1200_itp_get_tx(struct cw1200_common *priv, u8 **data, - size_t *tx_len, int *burst) -{ - struct cw1200_itp *itp; - struct timespec now; - int time_left_us; - - if (!priv->debug) - return 0; - - itp = &priv->debug->itp; - - if (!itp) - return 0; - - spin_lock_bh(&itp->tx_lock); - if (atomic_read(&itp->test_mode) != TEST_MODE_TX_TEST) - goto out; - - if (atomic_read(&itp->stop_tx)) - goto out; - - if (itp->number == 0) { - atomic_set(&itp->stop_tx, 1); - queue_delayed_work(priv->workqueue, &itp->tx_finish, HZ/10); - goto out; - } - - if (!itp->data) - goto out; - - if (priv->hw_bufs_used >= 2) { - if (!atomic_read(&priv->bh_rx)) - atomic_set(&priv->bh_rx, 1); - atomic_set(&priv->bh_tx, 1); - goto out; - } - - ktime_get_ts(&now); - time_left_us = (itp->last_sent.tv_sec - now.tv_sec)*1000000 + - (itp->last_sent.tv_nsec - now.tv_nsec)/1000 + - itp->interval_us; - - if (time_left_us > ITP_TIME_THRES_US) { - queue_delayed_work(priv->workqueue, &itp->tx_work, - ITP_US_TO_MS(time_left_us)*HZ/1000); - goto out; - } - - if (time_left_us > 50) - udelay(time_left_us); - - if (itp->number > 0) - itp->number--; - - *data = itp->data; - *tx_len = itp->data_len + itp->hdr_len; - - if (itp->data_mode == ITP_DATA_RANDOM) - cw1200_itp_fill_pattern(&itp->data[itp->hdr_len], - itp->data_len, itp->data_mode); - *burst = 2; - atomic_set(&priv->bh_tx, 1); - ktime_get_ts(&itp->last_sent); - atomic_add(1, &itp->awaiting_confirm); - spin_unlock_bh(&itp->tx_lock); - return 1; - -out: - spin_unlock_bh(&itp->tx_lock); - return 0; -} - -bool cw1200_itp_rxed(struct cw1200_common *priv, struct sk_buff *skb) -{ - struct cw1200_itp *itp = &priv->debug->itp; - struct ieee80211_rx_status *rx = IEEE80211_SKB_RXCB(skb); - int signal; - - if (atomic_read(&itp->test_mode) != TEST_MODE_RX_TEST) - return cw1200_is_itp(priv); - if (rx->freq != priv->channel->center_freq) - return true; - - signal = rx->signal; - itp->rx_cnt++; - itp->rx_rssi += signal; - if (itp->rx_rssi_min > rx->signal) - itp->rx_rssi_min = rx->signal; - if (itp->rx_rssi_max < rx->signal) - itp->rx_rssi_max = rx->signal; - - return true; -} - -void cw1200_itp_wake_up_tx(struct cw1200_common *priv) -{ - wake_up(&priv->debug->itp.write_wait); -} - -bool cw1200_itp_tx_running(struct cw1200_common *priv) -{ - if (atomic_read(&priv->debug->itp.awaiting_confirm) || - atomic_read(&priv->debug->itp.test_mode) == - TEST_MODE_TX_TEST) { - atomic_sub(1, &priv->debug->itp.awaiting_confirm); - return true; - } - return false; -} - -static void cw1200_itp_handle(struct cw1200_common *priv, - struct sk_buff *skb) -{ - struct cw1200_itp *itp = &priv->debug->itp; - const struct wiphy *wiphy = priv->hw->wiphy; - int cmd; - int ret; - - pr_debug("[ITP] <<< %s", skb->data); - if (sscanf(skb->data, "%d", &cmd) != 1) { - cw1200_itp_err(priv, -EINVAL, 1); - return; - } - - switch (cmd) { - case 1: /* RX test */ - if (atomic_read(&itp->test_mode)) { - cw1200_itp_err(priv, -EBUSY, 0); - return; - } - ret = sscanf(skb->data, "%d,%d,%d", - &cmd, &itp->band, &itp->ch); - if (ret != 3) { - cw1200_itp_err(priv, -EINVAL, ret + 1); - return; - } - if (itp->band >= 2) { - cw1200_itp_err(priv, -EINVAL, 2); - } else if (!wiphy->bands[itp->band]) { - cw1200_itp_err(priv, -EINVAL, 2); - } else if (itp->ch >= wiphy->bands[itp->band]->n_channels) { - cw1200_itp_err(priv, -EINVAL, 3); - } else { - cw1200_itp_rx_stats(priv); - cw1200_itp_rx_start(priv); - } - break; - case 2: /* RX stat */ - cw1200_itp_rx_stats(priv); - break; - case 3: /* RX/TX stop */ - if (atomic_read(&itp->test_mode) == TEST_MODE_RX_TEST) { - cw1200_itp_rx_stats(priv); - cw1200_itp_rx_stop(priv); - } else if (atomic_read(&itp->test_mode) == TEST_MODE_TX_TEST) { - cw1200_itp_tx_stop(priv); - } else { - cw1200_itp_err(priv, -EBUSY, 0); - } - break; - case 4: /* TX start */ - if (atomic_read(&itp->test_mode) != TEST_MODE_NO_TEST) { - cw1200_itp_err(priv, -EBUSY, 0); - return; - } - ret = sscanf(skb->data, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", - &cmd, &itp->band, &itp->ch, &itp->rate, - &itp->preamble, &itp->number, &itp->data_mode, - &itp->interval_us, &itp->power, &itp->data_len); - if (ret != 10) { - cw1200_itp_err(priv, -EINVAL, ret + 1); - return; - } - if (itp->band >= 2) { - cw1200_itp_err(priv, -EINVAL, 2); - } else if (!wiphy->bands[itp->band]) { - cw1200_itp_err(priv, -EINVAL, 2); - } else if (itp->ch >= wiphy->bands[itp->band]->n_channels) { - cw1200_itp_err(priv, -EINVAL, 3); - } else if (itp->rate >= 20) { - cw1200_itp_err(priv, -EINVAL, 4); - } else if (itp->preamble >= ITP_PREAMBLE_MAX) { - cw1200_itp_err(priv, -EINVAL, 5); - } else if (itp->data_mode >= ITP_DATA_MAX_MODE) { - cw1200_itp_err(priv, -EINVAL, 7); - } else if (itp->data_len < ITP_MIN_DATA_SIZE || - itp->data_len > (priv->wsm_caps.input_buffer_size - itp->hdr_len)) { - cw1200_itp_err(priv, -EINVAL, 8); - } else { - cw1200_itp_tx_start(priv); - } - break; - case 5: - cw1200_itp_get_version(priv, ITP_CHIP_ID); - break; - case 6: - cw1200_itp_get_version(priv, ITP_FW_VER); - break; - } -} - -static void cw1200_itp_err(struct cw1200_common *priv, - int err, int arg) -{ - struct cw1200_itp *itp = &priv->debug->itp; - struct sk_buff *skb; - static char buf[255]; - int len; - - len = snprintf(buf, sizeof(buf), "%d,%d\n", - err, arg); - if (len <= 0) - return; - - skb = dev_alloc_skb(len); - if (!skb) - return; - - skb_trim(skb, 0); - skb_put(skb, len); - - memcpy(skb->data, buf, len); - skb_queue_tail(&itp->log_queue, skb); - wake_up(&itp->read_wait); - - len = sprint_symbol(buf, - (unsigned long)__builtin_return_address(0)); - if (len <= 0) - return; - pr_debug("[ITP] error %d,%d from %s\n", - err, arg, buf); -} diff --git a/drivers/net/wireless/cw1200/itp.h b/drivers/net/wireless/cw1200/itp.h deleted file mode 100644 index 1e9dfb7fcadc..000000000000 --- a/drivers/net/wireless/cw1200/itp.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * ITP code for ST-Ericsson CW1200 mac80211 driver - * - * Copyright (c) 2011, 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_ITP_H_INCLUDED -#define CW1200_ITP_H_INCLUDED - -struct cw200_common; -struct wsm_tx_confirm; -struct dentry; - -#ifdef CONFIG_CW1200_ITP - -/*extern*/ struct ieee80211_channel; - -#define TEST_MODE_NO_TEST (0) -#define TEST_MODE_RX_TEST (1) -#define TEST_MODE_TX_TEST (2) -#define ITP_DEFAULT_DA_ADDR {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} -#define ITP_MIN_DATA_SIZE 6 -#define ITP_MAX_DATA_SIZE 1600 -#define ITP_TIME_THRES_US 10000 -#define ITP_US_TO_MS(x) ((x)/1000) -#define ITP_MS_TO_US(x) ((x)*1000) -#define ITP_BUF_SIZE 255 - - -enum cw1200_itp_data_modes { - ITP_DATA_ZEROS, - ITP_DATA_ONES, - ITP_DATA_ZERONES, - ITP_DATA_RANDOM, - ITP_DATA_MAX_MODE, -}; - -enum cw1200_itp_version_type { - ITP_CHIP_ID, - ITP_FW_VER, -}; - -enum cw1200_itp_preamble_type { - ITP_PREAMBLE_LONG, - ITP_PREAMBLE_SHORT, - ITP_PREAMBLE_OFDM, - ITP_PREAMBLE_MIXED, - ITP_PREAMBLE_GREENFIELD, - ITP_PREAMBLE_MAX, -}; - - -struct cw1200_itp { - struct cw1200_common *priv; - atomic_t open_count; - atomic_t awaiting_confirm; - struct sk_buff_head log_queue; - wait_queue_head_t read_wait; - wait_queue_head_t write_wait; - wait_queue_head_t close_wait; - struct ieee80211_channel *saved_channel; - atomic_t stop_tx; - struct delayed_work tx_work; - struct delayed_work tx_finish; - spinlock_t tx_lock; - struct timespec last_sent; - atomic_t test_mode; - int rx_cnt; - long rx_rssi; - int rx_rssi_max; - int rx_rssi_min; - unsigned band; - unsigned ch; - unsigned rate; - unsigned preamble; - unsigned int number; - unsigned data_mode; - int interval_us; - int power; - u8 *data; - int hdr_len; - int data_len; -}; - -int cw1200_itp_init(struct cw1200_common *priv); -void cw1200_itp_release(struct cw1200_common *priv); - -bool cw1200_is_itp(struct cw1200_common *priv); -bool cw1200_itp_rxed(struct cw1200_common *priv, struct sk_buff *skb); -void cw1200_itp_wake_up_tx(struct cw1200_common *priv); -int cw1200_itp_get_tx(struct cw1200_common *priv, u8 **data, - size_t *tx_len, int *burst); -bool cw1200_itp_tx_running(struct cw1200_common *priv); - -#else /* CONFIG_CW1200_ITP */ - -static inline int cw1200_itp_init(struct cw1200_common *priv) -{ - return 0; -} - -static inline void cw1200_itp_release(struct cw1200_common *priv) -{ -} - -static inline bool cw1200_is_itp(struct cw1200_common *priv) -{ - return false; -} - -static inline bool cw1200_itp_rxed(struct cw1200_common *priv, - struct sk_buff *skb) -{ - return false; -} - - -static inline void cw1200_itp_consume_txed(struct cw1200_common *priv) -{ -} - -static inline void cw1200_itp_wake_up_tx(struct cw1200_common *priv) -{ -} - -static inline int cw1200_itp_get_tx(struct cw1200_common *priv, u8 **data, - size_t *tx_len, int *burst) -{ - return 0; -} - -static inline bool cw1200_itp_tx_running(struct cw1200_common *priv) -{ - return false; -} - -#endif /* CONFIG_CW1200_ITP */ - -#endif /* CW1200_ITP_H_INCLUDED */ diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c index 8426d3d7607e..9f9adb4fbfb8 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" @@ -61,12 +61,6 @@ int cw1200_power_mode = wsm_power_mode_quiescent; module_param(cw1200_power_mode, int, 0644); MODULE_PARM_DESC(cw1200_power_mode, "WSM power mode. 0 == active, 1 == doze, 2 == quiescent (default)"); -#ifdef CONFIG_CW1200_ETF -int etf_mode; -module_param(etf_mode, int, 0644); -MODULE_PARM_DESC(etf_mode, "Enable EngineeringTestingFramework operation"); -#endif - #define RATETAB_ENT(_rate, _rateid, _flags) \ { \ .bitrate = (_rate), \ @@ -234,8 +228,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 +288,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; @@ -414,29 +412,25 @@ static int cw1200_register_common(struct ieee80211_hw *dev) struct cw1200_common *priv = dev->priv; int err; -#ifdef CONFIG_CW1200_ETF - if (etf_mode) - 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; } -#ifdef CONFIG_CW1200_ETF -done: -#endif cw1200_debug_init(priv); pr_info("Registered as '%s'\n", wiphy_name(dev->wiphy)); @@ -453,13 +447,7 @@ static void cw1200_unregister_common(struct ieee80211_hw *dev) struct cw1200_common *priv = dev->priv; int i; -#ifdef CONFIG_CW1200_ETF - if (!etf_mode) { -#endif - ieee80211_unregister_hw(dev); -#ifdef CONFIG_CW1200_ETF - } -#endif + ieee80211_unregister_hw(dev); del_timer_sync(&priv->mcast_timeout); cw1200_unregister_bh(priv); @@ -482,7 +470,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 +508,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 +536,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); @@ -558,11 +548,6 @@ int cw1200_core_probe(const struct sbus_ops *sbus_ops, if (err) goto err1; -#ifdef CONFIG_CW1200_ETF - if (etf_mode) - goto skip_fw; -#endif - err = cw1200_load_firmware(priv); if (err) goto err2; @@ -584,9 +569,6 @@ int cw1200_core_probe(const struct sbus_ops *sbus_ops, /* Enable multi-TX confirmation */ wsm_use_multi_tx_conf(priv, true); -#ifdef CONFIG_CW1200_ETF -skip_fw: -#endif err = cw1200_register_common(dev); if (err) goto err2; @@ -606,9 +588,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 79edfb93b292..b37abb9f0453 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 516d9671dd1e..3ed90ff22bb8 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 603fd25eaa4a..000000000000 --- 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/sta.c b/drivers/net/wireless/cw1200/sta.c index 679c55f15c67..4cd0352b508d 100644 --- a/drivers/net/wireless/cw1200/sta.c +++ b/drivers/net/wireless/cw1200/sta.c @@ -483,15 +483,14 @@ void cw1200_update_filtering(struct cw1200_common *priv) bf_tbl.num = __cpu_to_le32(3); } - /* - * When acting as p2p client being connected to p2p GO, in order to - * receive frames from a different p2p device, turn off bssid filter. - * - * WARNING: FW dependency! - * This can only be used with FW WSM371 and its successors. - * In that FW version even with bssid filter turned off, - * device will block most of the unwanted frames. - */ + /* When acting as p2p client being connected to p2p GO, in order to + * receive frames from a different p2p device, turn off bssid filter. + * + * WARNING: FW dependency! + * This can only be used with FW WSM371 and its successors. + * In that FW version even with bssid filter turned off, + * device will block most of the unwanted frames. + */ if (is_p2p) bssid_filtering = false; @@ -1015,17 +1014,17 @@ void cw1200_event_handler(struct work_struct *work) /* RSSI: signed Q8.0, RCPI: unsigned Q7.1 * RSSI = RCPI / 2 - 110 */ - int rcpiRssi = (int)(event->evt.data & 0xFF); + int rcpi_rssi = (int)(event->evt.data & 0xFF); int cqm_evt; if (priv->cqm_use_rssi) - rcpiRssi = (s8)rcpiRssi; + rcpi_rssi = (s8)rcpi_rssi; else - rcpiRssi = rcpiRssi / 2 - 110; + rcpi_rssi = rcpi_rssi / 2 - 110; - cqm_evt = (rcpiRssi <= priv->cqm_rssi_thold) ? + cqm_evt = (rcpi_rssi <= priv->cqm_rssi_thold) ? NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW : NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; - pr_debug("[CQM] RSSI event: %d.\n", rcpiRssi); + pr_debug("[CQM] RSSI event: %d.\n", rcpi_rssi); ieee80211_cqm_rssi_notify(priv->vif, cqm_evt, GFP_KERNEL); break; @@ -1068,8 +1067,7 @@ void cw1200_bss_params_work(struct work_struct *work) /* ******************************************************************** */ /* Internal API */ -/* - * This function is called to Parse the SDD file +/* This function is called to Parse the SDD file * to extract listen_interval and PTA related information * sdd is a TLV: u8 id, u8 len, u8 data[] */ diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c index 0e40890e1993..44ca10cb0d39 100644 --- a/drivers/net/wireless/cw1200/txrx.c +++ b/drivers/net/wireless/cw1200/txrx.c @@ -75,9 +75,6 @@ static void tx_policy_build(const struct cw1200_common *priv, BUG_ON(rates[0].idx < 0); memset(policy, 0, sizeof(*policy)); - /* minstrel is buggy a little bit, so distille - * incoming rates first. */ - /* Sort rates in descending order. */ for (i = 1; i < count; ++i) { if (rates[i].idx < 0) { @@ -108,7 +105,8 @@ static void tx_policy_build(const struct cw1200_common *priv, count = i + 1; /* Re-fill policy trying to keep every requested rate and with - * respect to the global max tx retransmission count. */ + * respect to the global max tx retransmission count. + */ if (limit < count) limit = count; if (total > limit) { @@ -129,7 +127,6 @@ static void tx_policy_build(const struct cw1200_common *priv, if (count == 2 && !(rates[0].flags & IEEE80211_TX_RC_MCS) && rates[0].idx > 4 && rates[0].count > 2 && rates[1].idx < 2) { - /* ">> 1" is an equivalent of "/ 2", but faster */ int mid_rate = (rates[0].idx + 4) >> 1; /* Decrease number of retries for the initial rate */ @@ -151,7 +148,8 @@ static void tx_policy_build(const struct cw1200_common *priv, /* Fallback to 1 Mbps is a really bad thing, * so let's try to increase probability of * successful transmission on the lowest g rate - * even more */ + * even more + */ if (rates[0].count >= 3) { --rates[0].count; ++rates[2].count; @@ -190,13 +188,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, @@ -221,7 +218,8 @@ static int tx_policy_find(struct tx_policy_cache *cache, { /* O(n) complexity. Not so good, but there's only 8 entries in * the cache. - * Also lru helps to reduce search time. */ + * Also lru helps to reduce search time. + */ struct tx_policy_cache_entry *it; /* First search for policy in "used" list */ list_for_each_entry(it, &cache->used, link) { @@ -265,7 +263,8 @@ void tx_policy_clean(struct cw1200_common *priv) for (idx = 0; idx < TX_POLICY_CACHE_SIZE; idx++) { entry = &cache->cache[idx]; /* Policy usage count should be 0 at this time as all queues - should be empty */ + should be empty + */ if (WARN_ON(entry->policy.usage_count)) { entry->policy.usage_count = 0; list_move(&entry->link, &cache->free); @@ -320,7 +319,8 @@ static int tx_policy_get(struct cw1200_common *priv, struct tx_policy_cache_entry *entry; *renew = true; /* If policy is not found create a new one - * using the oldest entry in "free" list */ + * using the oldest entry in "free" list + */ entry = list_entry(cache->free.prev, struct tx_policy_cache_entry, link); entry->policy = wanted; @@ -613,7 +613,8 @@ cw1200_tx_h_bt(struct cw1200_common *priv, priv->listen_interval, mgt_frame->u.assoc_req.listen_interval); /* Replace listen interval derieved from - * the one read from SDD */ + * the one read from SDD + */ mgt_frame->u.assoc_req.listen_interval = priv->listen_interval; } @@ -668,7 +669,8 @@ cw1200_tx_h_rate_policy(struct cw1200_common *priv, pr_debug("[TX] TX policy renew.\n"); /* It's not so optimal to stop TX queues every now and then. * Better to reimplement task scheduling with - * a counter. TODO. */ + * a counter. TODO. + */ wsm_lock_tx_async(priv); cw1200_tx_queues_lock(priv); if (queue_work(priv->workqueue, @@ -833,8 +835,7 @@ static int cw1200_handle_pspoll(struct cw1200_common *priv, priv->pspoll_mask |= pspoll_mask; drop = 0; - /* Do not report pspols if data for given link id is - * queued already. */ + /* Do not report pspols if data for given link id is queued already. */ for (i = 0; i < 4; ++i) { if (cw1200_queue_get_num_queued(&priv->tx_queue[i], pspoll_mask)) { @@ -862,9 +863,6 @@ void cw1200_tx_confirm_cb(struct cw1200_common *priv, pr_debug("[TX] TX confirm: %d, %d.\n", arg->status, arg->ack_failures); - if (cw1200_itp_tx_running(priv)) - return; - if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) { /* STA is stopped. */ return; @@ -928,7 +926,8 @@ void cw1200_tx_confirm_cb(struct cw1200_common *priv, cw1200_debug_txed(priv); if (arg->flags & WSM_TX_STATUS_AGGREGATION) { /* Do not report aggregation to mac80211: - * it confuses minstrel a lot. */ + * it confuses minstrel a lot. + */ /* tx->flags |= IEEE80211_TX_STAT_AMPDU; */ cw1200_debug_txed_agg(priv); } @@ -1002,8 +1001,7 @@ void cw1200_skb_dtor(struct cw1200_common *priv, txpriv->raw_link_id, txpriv->tid); tx_policy_put(priv, txpriv->rate_id); } - if (!cw1200_is_itp(priv)) - ieee80211_tx_status(priv->hw, skb); + ieee80211_tx_status(priv->hw, skb); } void cw1200_rx_cb(struct cw1200_common *priv, @@ -1049,7 +1047,8 @@ void cw1200_rx_cb(struct cw1200_common *priv, ieee80211_is_action(frame->frame_control) && (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)) { /* Link ID already exists for the ACTION frame. - * Reset and Remap */ + * Reset and Remap + */ WARN_ON(work_pending(&priv->linkid_reset_work)); memcpy(&priv->action_frame_sa[0], ieee80211_get_SA(frame), ETH_ALEN); @@ -1079,7 +1078,6 @@ void cw1200_rx_cb(struct cw1200_common *priv, if (cw1200_handle_pspoll(priv, skb)) goto drop; - hdr->mactime = 0; /* Not supported by WSM */ hdr->band = ((arg->channel_number & 0xff00) || (arg->channel_number > 14)) ? IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; @@ -1107,7 +1105,8 @@ void cw1200_rx_cb(struct cw1200_common *priv, hdr->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED; /* Oops... There is no fast way to ask mac80211 about - * IV/ICV lengths. Even defineas are not exposed.*/ + * IV/ICV lengths. Even defineas are not exposed. + */ switch (WSM_RX_STATUS_ENCRYPTION(arg->flags)) { case WSM_RX_STATUS_WEP: iv_len = 4 /* WEP_IV_LEN */; @@ -1154,6 +1153,8 @@ void cw1200_rx_cb(struct cw1200_common *priv, hdr->mactime = le64_to_cpu(hdr->mactime); if (skb->len >= 8) skb_trim(skb, skb->len - 8); + } else { + hdr->mactime = 0; } cw1200_debug_rxed(priv); @@ -1197,7 +1198,8 @@ void cw1200_rx_cb(struct cw1200_common *priv, /* Stay awake after frame is received to give * userspace chance to react and acquire appropriate - * wakelock. */ + * wakelock. + */ if (ieee80211_is_auth(frame->frame_control)) grace_period = 5 * HZ; else if (ieee80211_is_deauth(frame->frame_control)) @@ -1206,9 +1208,7 @@ void cw1200_rx_cb(struct cw1200_common *priv, grace_period = 1 * HZ; cw1200_pm_stay_awake(&priv->pm_state, grace_period); - if (cw1200_itp_rxed(priv, skb)) { - consume_skb(skb); - } else if (early_data) { + if (early_data) { spin_lock_bh(&priv->ps_state_lock); /* Double-check status with lock held */ if (entry->status == CW1200_LINK_SOFT) diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c index 4db6cc16879c..d95094fdcc50 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> @@ -22,7 +21,6 @@ #include "bh.h" #include "sta.h" #include "debug.h" -#include "itp.h" #define WSM_CMD_TIMEOUT (2 * HZ) /* With respect to interrupt loss */ #define WSM_CMD_START_TIMEOUT (7 * HZ) @@ -930,6 +928,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)); @@ -1106,15 +1106,11 @@ static int wsm_cmd_send(struct cw1200_common *priv, else pr_debug("[WSM] >>> 0x%.4X (%zu)\n", cmd, buf_len); - /* - * Due to buggy SPI on CW1200, we need to + /* Due to buggy SPI on CW1200, we need to * pad the message by a few bytes to ensure * that it's completely received. */ -#ifdef CONFIG_CW1200_ETF - if (!etf_mode) -#endif - buf_len += 4; + buf_len += 4; /* Fill HI message header */ /* BH will add sequence number */ @@ -1165,29 +1161,6 @@ done: return ret; } -#ifdef CONFIG_CW1200_ETF -int wsm_raw_cmd(struct cw1200_common *priv, u8 *data, size_t len) -{ - struct wsm_buf *buf = &priv->wsm_cmd_buf; - int ret; - - u16 *cmd = (u16 *)(data + 2); - - wsm_cmd_lock(priv); - - WSM_PUT(buf, data + 4, len - 4); /* Skip over header (u16+u16) */ - - ret = wsm_cmd_send(priv, buf, NULL, __le16_to_cpu(*cmd), WSM_CMD_TIMEOUT); - - wsm_cmd_unlock(priv); - return ret; - -nomem: - wsm_cmd_unlock(priv); - return -ENOMEM; -} -#endif /* CONFIG_CW1200_ETF */ - /* ******************************************************************** */ /* WSM TX port control */ @@ -1343,34 +1316,6 @@ int wsm_handle_rx(struct cw1200_common *priv, u16 id, pr_debug("[WSM] <<< 0x%.4X (%td)\n", id, wsm_buf.end - wsm_buf.begin); -#ifdef CONFIG_CW1200_ETF - if (etf_mode) { - struct sk_buff *skb = alloc_skb(wsm_buf.end - wsm_buf.begin, GFP_KERNEL); - - /* Strip out Sequence num before passing up */ - wsm->id = __le16_to_cpu(wsm->id); - wsm->id &= 0x0FFF; - wsm->id = __cpu_to_le16(wsm->id); - - memcpy(skb_put(skb, wsm_buf.end - wsm_buf.begin), - wsm_buf.begin, - wsm_buf.end - wsm_buf.begin); - skb_queue_tail(&priv->etf_q, skb); - - /* Special case for startup */ - if (id == WSM_STARTUP_IND_ID) { - wsm_startup_indication(priv, &wsm_buf); - } else if (id & 0x0400) { - spin_lock(&priv->wsm_cmd.lock); - priv->wsm_cmd.done = 1; - spin_unlock(&priv->wsm_cmd.lock); - wake_up(&priv->wsm_cmd_wq); - } - - goto out; - } -#endif - if (id == WSM_TX_CONFIRM_IND_ID) { ret = wsm_tx_confirm(priv, &wsm_buf, link_id); } else if (id == WSM_MULTI_TX_CONFIRM_ID) { @@ -1732,12 +1677,6 @@ int wsm_get_tx(struct cw1200_common *priv, u8 **data, /* More is used only for broadcasts. */ bool more = false; -#ifdef CONFIG_CW1200_ITP - count = cw1200_itp_get_tx(priv, data, tx_len, burst); - if (count) - return count; -#endif - if (priv->wsm_cmd.ptr) { /* CMD request */ ++count; spin_lock(&priv->wsm_cmd.lock); diff --git a/drivers/net/wireless/cw1200/wsm.h b/drivers/net/wireless/cw1200/wsm.h index 8d902d6a7dc4..2816171f7a1d 100644 --- a/drivers/net/wireless/cw1200/wsm.h +++ b/drivers/net/wireless/cw1200/wsm.h @@ -314,13 +314,16 @@ struct cw1200_common; #define WSM_JOIN_FLAGS_P2P_GO BIT(1) /* Force to join BSS with the BSSID and the * SSID specified without waiting for beacons. The - * ProbeForJoin parameter is ignored. */ + * ProbeForJoin parameter is ignored. + */ #define WSM_JOIN_FLAGS_FORCE BIT(2) /* Give probe request/response higher - * priority over the BT traffic */ + * priority over the BT traffic + */ #define WSM_JOIN_FLAGS_PRIO BIT(3) /* Issue immediate join confirmation and use - * join complete to notify about completion */ + * join complete to notify about completion + */ #define WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND BIT(5) /* Key types */ @@ -1015,22 +1018,19 @@ struct wsm_add_key { u16 reserved; union { struct { - u8 peer[6]; /* MAC address of the - * peer station */ + u8 peer[6]; /* MAC address of the peer station */ u8 reserved; u8 keylen; /* Key length in bytes */ u8 keydata[16]; /* Key data */ } __packed wep_pairwise; struct { - u8 keyid; /* Unique per key identifier - * (0..3) */ + u8 keyid; /* Unique per key identifier (0..3) */ u8 keylen; /* Key length in bytes */ u16 reserved; u8 keydata[16]; /* Key data */ } __packed wep_group; struct { - u8 peer[6]; /* MAC address of the - * peer station */ + u8 peer[6]; /* MAC address of the peer station */ u16 reserved; u8 keydata[16]; /* TKIP key data */ u8 rx_mic_key[8]; /* Rx MIC key */ @@ -1044,8 +1044,7 @@ struct wsm_add_key { u8 rx_seqnum[8]; /* Receive Sequence Counter */ } __packed tkip_group; struct { - u8 peer[6]; /* MAC address of the - * peer station */ + u8 peer[6]; /* MAC address of the peer station */ u16 reserved; u8 keydata[16]; /* AES key data */ } __packed aes_pairwise; @@ -1056,8 +1055,7 @@ struct wsm_add_key { u8 rx_seqnum[8]; /* Receive Sequence Counter */ } __packed aes_group; struct { - u8 peer[6]; /* MAC address of the - * peer station */ + u8 peer[6]; /* MAC address of the peer station */ u8 keyid; /* Key ID */ u8 reserved; u8 keydata[16]; /* WAPI key data */ @@ -1550,7 +1548,8 @@ struct wsm_tx_rate_retry_policy { * finishes. * BIT(3) - Count initial frame transmission as part of * rate retry counting but not as a retry - * attempt */ + * attempt + */ u8 flags; u8 rate_recoveries; u8 reserved[3]; @@ -1618,24 +1617,24 @@ static inline int wsm_set_udp_port_filter(struct cw1200_common *priv, #define D11_MAX_SSID_LEN (32) struct wsm_p2p_device_type { - __le16 categoryId; + __le16 category_id; u8 oui[4]; - __le16 subCategoryId; + __le16 subcategory_id; } __packed; struct wsm_p2p_device_info { struct wsm_p2p_device_type primaryDevice; u8 reserved1[3]; - u8 devNameSize; - u8 localDevName[D11_MAX_SSID_LEN]; + u8 devname_size; + u8 local_devname[D11_MAX_SSID_LEN]; u8 reserved2[3]; - u8 numSecDevSupported; - struct wsm_p2p_device_type secondaryDevices[0]; + u8 num_secdev_supported; + struct wsm_p2p_device_type secdevs[0]; } __packed; /* 4.36 SetWCDMABand - WO */ struct wsm_cdma_band { - u8 WCDMA_Band; + u8 wcdma_band; u8 reserved[3]; } __packed; @@ -1668,19 +1667,19 @@ struct wsm_ht_protection { #define WSM_GPIO_ALL_PINS 0xFF struct wsm_gpio_command { - u8 GPIO_Command; + u8 command; u8 pin; __le16 config; } __packed; /* 4.41 TSFCounter - RO */ struct wsm_tsf_counter { - __le64 TSF_Counter; + __le64 tsf_counter; } __packed; /* 4.43 Keep alive period */ struct wsm_keep_alive_period { - __le16 keepAlivePeriod; + __le16 period; u8 reserved[2]; } __packed; @@ -1688,7 +1687,7 @@ static inline int wsm_keep_alive_period(struct cw1200_common *priv, int period) { struct wsm_keep_alive_period arg = { - .keepAlivePeriod = __cpu_to_le16(period), + .period = __cpu_to_le16(period), }; return wsm_write_mib(priv, WSM_MIB_ID_KEEP_ALIVE_PERIOD, &arg, sizeof(arg)); @@ -1739,13 +1738,13 @@ static inline int wsm_set_arp_ipv4_filter(struct cw1200_common *priv, /* P2P Power Save Mode Info - 4.31 */ struct wsm_p2p_ps_modeinfo { - u8 oppPsCTWindow; + u8 opp_ps_ct_window; u8 count; u8 reserved; - u8 dtimCount; + u8 dtim_count; __le32 duration; __le32 interval; - __le32 startTime; + __le32 start_time; } __packed; static inline int wsm_set_p2p_ps_modeinfo(struct cw1200_common *priv, @@ -1871,9 +1870,4 @@ static inline u8 wsm_queue_id_to_wsm(u8 queue_id) return queue_mapping[queue_id]; } - -#ifdef CONFIG_CW1200_ETF -int wsm_raw_cmd(struct cw1200_common *priv, u8 *data, size_t len); -#endif - #endif /* CW1200_HWIO_H_INCLUDED */ diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 15920aaa5dd6..f8ab193009cd 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 795f65cf6332..1767a8849591 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 69bbf6fdd2d3..cb34c7895f2a 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/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 2c12311467a9..5efbbbdca701 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -1170,12 +1170,6 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, rt2x00queue_reset(queue); - queue->limit = qdesc->entry_num; - queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10); - queue->data_size = qdesc->data_size; - queue->desc_size = qdesc->desc_size; - queue->winfo_size = qdesc->winfo_size; - /* * Allocate all queue entries. */ @@ -1284,9 +1278,38 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) } } +static const struct data_queue_desc * +rt2x00queue_get_qdesc_by_qid(struct rt2x00_dev *rt2x00dev, + enum data_queue_qid qid) +{ + switch (qid) { + case QID_RX: + return rt2x00dev->ops->rx; + + case QID_AC_BE: + case QID_AC_BK: + case QID_AC_VO: + case QID_AC_VI: + return rt2x00dev->ops->tx; + + case QID_BEACON: + return rt2x00dev->ops->bcn; + + case QID_ATIM: + return rt2x00dev->ops->atim; + + default: + break; + } + + return NULL; +} + static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, struct data_queue *queue, enum data_queue_qid qid) { + const struct data_queue_desc *qdesc; + mutex_init(&queue->status_lock); spin_lock_init(&queue->tx_lock); spin_lock_init(&queue->index_lock); @@ -1297,6 +1320,15 @@ static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, queue->aifs = 2; queue->cw_min = 5; queue->cw_max = 10; + + qdesc = rt2x00queue_get_qdesc_by_qid(rt2x00dev, qid); + BUG_ON(!qdesc); + + queue->limit = qdesc->entry_num; + queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10); + queue->data_size = qdesc->data_size; + queue->desc_size = qdesc->desc_size; + queue->winfo_size = qdesc->winfo_size; } int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index 19a765532603..47875ba09ff8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -842,7 +842,7 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( long val_y, ele_c = 0; u8 ofdm_index[2]; s8 cck_index = 0; - u8 ofdm_index_old[2]; + u8 ofdm_index_old[2] = {0, 0}; s8 cck_index_old = 0; u8 index; int i; |