* [PATCH 6/7] ath9k: Print ANI statistics in debugfs
From: Sujith Manoharan @ 2013-06-03 3:49 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <1370231369-16241-1-git-send-email-sujith@msujith.org>
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/ani.h | 2 -
drivers/net/wireless/ath/ath9k/debug.c | 81 +++++++++++++++++++++++++++-------
2 files changed, 64 insertions(+), 19 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index c585e05..78b9fa9 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -111,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/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 53c0658..2721f52 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,
@@ -1727,8 +1774,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,
--
1.8.3
^ permalink raw reply related
* [PATCH 5/7] ath9k: Set ofdmWeakSigDetect directly
From: Sujith Manoharan @ 2013-06-03 3:49 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <1370231369-16241-1-git-send-email-sujith@msujith.org>
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
The macros ATH9K_ANI_USE_OFDM_WEAK_SIG can be removed.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/ani.c | 6 +-----
drivers/net/wireless/ath/ath9k/ani.h | 6 +-----
drivers/net/wireless/ath/ath9k/ar5008_phy.c | 2 +-
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 2 +-
4 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 734e72d..ba0bad6 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -505,14 +505,10 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
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->ofdmWeakSigDetect = true;
ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 07079f2..c585e05 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -34,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
@@ -107,7 +103,7 @@ struct ar5416AniState {
u8 mrcCCK;
u8 spurImmunityLevel;
u8 firstepLevel;
- u8 ofdmWeakSigDetect;
+ bool ofdmWeakSigDetect;
u32 listenTime;
u32 ofdmPhyErrCount;
u32 cckPhyErrCount;
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 391da5a..92b79a2 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -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/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index e1714d7..53562a4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1214,7 +1214,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;
}
--
1.8.3
^ permalink raw reply related
* [PATCH 4/7] ath9k: Simplify ANI initialization
From: Sujith Manoharan @ 2013-06-03 3:49 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <1370231369-16241-1-git-send-email-sujith@msujith.org>
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
The check "enable_ani" is not required since it is always
set to true and the logic for disabling/enabling ANI via
debugfs is done at a higher layer.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/ani.c | 13 +++++--------
drivers/net/wireless/ath/ath9k/ani.h | 4 ----
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 6 ++----
drivers/net/wireless/ath/ath9k/hw.c | 4 +---
drivers/net/wireless/ath/ath9k/hw.h | 2 --
drivers/net/wireless/ath/ath9k/link.c | 8 ++------
6 files changed, 10 insertions(+), 27 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 7ecd40f..734e72d 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -118,7 +118,7 @@ static void ath9k_ani_restart(struct ath_hw *ah)
{
struct ar5416AniState *aniState;
- if (!DO_ANI(ah))
+ if (!ah->curchan)
return;
aniState = &ah->curchan->ani;
@@ -195,7 +195,7 @@ 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;
@@ -251,7 +251,7 @@ 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;
@@ -297,7 +297,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
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);
@@ -415,7 +415,7 @@ 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;
@@ -524,9 +524,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
ah->aniperiod = ATH9K_ANI_PERIOD;
ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL;
- if (ah->config.enable_ani)
- ah->proc_phyerr |= HAL_PROCESS_ANI;
-
ath9k_ani_restart(ah);
ath9k_enable_mib_counters(ah);
}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index dddb136..07079f2 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 */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 2a67b57..34869c2 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -814,8 +814,7 @@ void ath9k_htc_ani_work(struct work_struct *work)
}
/* Verify whether we must check ANI */
- if (ah->config.enable_ani &&
- (timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
+ if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
aniflag = true;
common->ani.checkani_timer = timestamp;
}
@@ -845,8 +844,7 @@ set_timer:
* short calibration and long calibration.
*/
cal_interval = ATH_LONG_CALINTERVAL;
- if (ah->config.enable_ani)
- cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
+ cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
if (!common->ani.caldone)
cal_interval = min(cal_interval, (u32)short_cal_interval);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index c71027c..d813ab8 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;
}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index e3c3997..301b19e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -289,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;
@@ -852,7 +851,6 @@ struct ath_hw {
u32 globaltxtimeout;
/* ANI */
- u32 proc_phyerr;
u32 aniperiod;
enum ath9k_ani_cmd ani_function;
u32 ani_skip_count;
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index cc422a4..fff5d3c 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -390,9 +390,7 @@ void ath_ani_calibrate(unsigned long data)
}
/* Verify whether we must check ANI */
- if (sc->sc_ah->config.enable_ani
- && (timestamp - common->ani.checkani_timer) >=
- ah->config.ani_poll_interval) {
+ if ((timestamp - common->ani.checkani_timer) >= ah->config.ani_poll_interval) {
aniflag = true;
common->ani.checkani_timer = timestamp;
}
@@ -427,9 +425,7 @@ set_timer:
* short calibration and long calibration.
*/
cal_interval = ATH_LONG_CALINTERVAL;
- if (sc->sc_ah->config.enable_ani)
- cal_interval = min(cal_interval,
- (u32)ah->config.ani_poll_interval);
+ cal_interval = min(cal_interval, (u32)ah->config.ani_poll_interval);
if (!common->ani.caldone)
cal_interval = min(cal_interval, (u32)short_cal_interval);
--
1.8.3
^ permalink raw reply related
* [PATCH 3/7] ath9k: Remove unused structure ath_dbg_bb_mac_samp
From: Sujith Manoharan @ 2013-06-03 3:49 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <1370231369-16241-1-git-send-email-sujith@msujith.org>
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/debug.h | 39 ----------------------------------
1 file changed, 39 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 223418d..fc67919 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;
--
1.8.3
^ permalink raw reply related
* [PATCH 1/7] ath9k: Return early for invalid rates
From: Sujith Manoharan @ 2013-06-03 3:49 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Process and update the internal RSSI average, which
is used by ANI, after verifying that the received
frame has valid rate information.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/recv.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index b4b758d..865e043 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -955,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;
--
1.8.3
^ permalink raw reply related
* [PATCH 2/7] ath9k: Enable WoW only for AR9462
From: Sujith Manoharan @ 2013-06-03 3:49 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <1370231369-16241-1-git-send-email-sujith@msujith.org>
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
The only card with which WoW has been tested and verified is
AR9462. Do not enable it for all cards since WoW is really quirky
and needs to be tested properly with each chip.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/ar9002_hw.c | 4 -
drivers/net/wireless/ath/ath9k/ar9002_initvals.h | 14 --
drivers/net/wireless/ath/ath9k/hw.c | 9 +-
drivers/net/wireless/ath/ath9k/hw.h | 9 +-
drivers/net/wireless/ath/ath9k/init.c | 4 -
drivers/net/wireless/ath/ath9k/main.c | 34 +----
drivers/net/wireless/ath/ath9k/wow.c | 168 ++++-------------------
7 files changed, 35 insertions(+), 207 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 830daa1..8dc2d08 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -38,10 +38,6 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah)
else
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9280PciePhy_clkreq_always_on_L1_9280);
-#ifdef CONFIG_PM_SLEEP
- INIT_INI_ARRAY(&ah->iniPcieSerdesWow,
- ar9280PciePhy_awow);
-#endif
if (AR_SREV_9287_11_OR_LATER(ah)) {
INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
index beb6162..4d18c66 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
@@ -925,20 +925,6 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
{0x00004044, 0x00000000},
};
-static const u32 ar9280PciePhy_awow[][2] = {
- /* Addr allmodes */
- {0x00004040, 0x9248fd00},
- {0x00004040, 0x24924924},
- {0x00004040, 0xa8000019},
- {0x00004040, 0x13160820},
- {0x00004040, 0xe5980560},
- {0x00004040, 0xc01dcffd},
- {0x00004040, 0x1aaabe41},
- {0x00004040, 0xbe105554},
- {0x00004040, 0x00043007},
- {0x00004044, 0x00000000},
-};
-
static const u32 ar9285Modes_9285_1_2[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 2caf7de..c71027c 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2604,13 +2604,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->hw_caps |= ATH9K_HW_CAP_RTT;
}
- if (AR_SREV_9280_20_OR_LATER(ah)) {
- pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE |
- ATH9K_HW_WOW_PATTERN_MATCH_EXACT;
-
- if (AR_SREV_9280(ah))
- pCap->hw_caps |= ATH9K_HW_WOW_PATTERN_MATCH_DWORD;
- }
+ if (AR_SREV_9462(ah))
+ pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE;
if (AR_SREV_9300_20_OR_LATER(ah) &&
ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index ae30343..e3c3997 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),
};
/*
@@ -882,9 +880,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 +1160,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 9fc4d67..522c198 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -797,21 +797,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/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 6c147b8..e5b186b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2006,7 +2006,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];
@@ -2076,36 +2075,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/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 9f85630..81c88dd 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -34,17 +34,6 @@ const char *ath9k_hw_wow_event_to_string(u32 wow_event)
}
EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
-static void ath9k_hw_config_serdes_wow_sleep(struct ath_hw *ah)
-{
- int i;
-
- for (i = 0; i < ah->iniPcieSerdesWow.ia_rows; i++)
- REG_WRITE(ah, INI_RA(&ah->iniPcieSerdesWow, i, 0),
- INI_RA(&ah->iniPcieSerdesWow, i, 1));
-
- usleep_range(1000, 1500);
-}
-
static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
@@ -58,15 +47,8 @@ static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
return;
- } else {
- if (!AR_SREV_9300_20_OR_LATER(ah))
- REG_WRITE(ah, AR_RXDP, 0x0);
}
- /* AR9280 WoW has sleep issue, do not set it to sleep */
- if (AR_SREV_9280_20(ah))
- return;
-
REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
}
@@ -84,27 +66,16 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
/* set the transmit buffer */
ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
-
- if (!(AR_SREV_9300_20_OR_LATER(ah)))
- ctl[0] += (KAL_ANTENNA_MODE << 25);
-
ctl[1] = 0;
ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */
ctl[4] = 0;
ctl[7] = (ah->txchainmask) << 2;
-
- if (AR_SREV_9300_20_OR_LATER(ah))
- ctl[2] = 0xf << 16; /* tx_tries 0 */
- else
- ctl[2] = 0x7 << 16; /* tx_tries 0 */
-
+ ctl[2] = 0xf << 16; /* tx_tries 0 */
for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
- /* for AR9300 family 13 descriptor words */
- if (AR_SREV_9300_20_OR_LATER(ah))
- REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
+ REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
(KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
@@ -183,9 +154,6 @@ void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
- if (!AR_SREV_9285_12_OR_LATER(ah))
- return;
-
if (pattern_count < 4) {
/* Pattern 0-3 uses AR_WOW_LENGTH1 register */
set = (pattern_len & AR_WOW_LENGTH_MAX) <<
@@ -207,6 +175,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
{
u32 wow_status = 0;
u32 val = 0, rval;
+
/*
* read the WoW status register to know
* the wakeup reason
@@ -223,19 +192,14 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
val &= ah->wow_event_mask;
if (val) {
-
if (val & AR_WOW_MAGIC_PAT_FOUND)
wow_status |= AH_WOW_MAGIC_PATTERN_EN;
-
if (AR_WOW_PATTERN_FOUND(val))
wow_status |= AH_WOW_USER_PATTERN_EN;
-
if (val & AR_WOW_KEEP_ALIVE_FAIL)
wow_status |= AH_WOW_LINK_CHANGE;
-
if (val & AR_WOW_BEACON_FAIL)
wow_status |= AH_WOW_BEACON_MISS;
-
}
/*
@@ -255,17 +219,6 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
/*
- * tie reset register for AR9002 family of chipsets
- * NB: not tieing it back might have some repurcussions.
- */
-
- if (!AR_SREV_9300_20_OR_LATER(ah)) {
- REG_SET_BIT(ah, AR_WA, AR_WA_UNTIE_RESET_EN |
- AR_WA_POR_SHORT | AR_WA_RESET_EN);
- }
-
-
- /*
* restore the beacon threshold to init value
*/
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
@@ -277,8 +230,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
* reset to our Chip's Power On Reset so that any PCI-E
* reset from the bus will not reset our chip
*/
-
- if (AR_SREV_9280_20_OR_LATER(ah) && ah->is_pciexpress)
+ if (ah->is_pciexpress)
ath9k_hw_configpcipowersave(ah, false);
ah->wow_event_mask = 0;
@@ -298,7 +250,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
* are from the 'pattern_enable' in this function and
* 'pattern_count' of ath9k_hw_wow_apply_pattern()
*/
-
wow_event_mask = ah->wow_event_mask;
/*
@@ -306,50 +257,15 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
* WOW sleep, we do want the Reset from the PCI-E to disturb
* our hw state
*/
-
if (ah->is_pciexpress) {
-
/*
* we need to untie the internal POR (power-on-reset)
* to the external PCI-E reset. We also need to tie
* the PCI-E Phy reset to the PCI-E reset.
*/
-
- if (AR_SREV_9300_20_OR_LATER(ah)) {
- set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
- clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
- REG_RMW(ah, AR_WA, set, clr);
- } else {
- if (AR_SREV_9285(ah) || AR_SREV_9287(ah))
- set = AR9285_WA_DEFAULT;
- else
- set = AR9280_WA_DEFAULT;
-
- /*
- * In AR9280 and AR9285, bit 14 in WA register
- * (disable L1) should only be set when device
- * enters D3 state and be cleared when device
- * comes back to D0
- */
-
- if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
- set |= AR_WA_D3_L1_DISABLE;
-
- clr = AR_WA_UNTIE_RESET_EN;
- set |= AR_WA_RESET_EN | AR_WA_POR_SHORT;
- REG_RMW(ah, AR_WA, set, clr);
-
- /*
- * for WoW sleep, we reprogram the SerDes so that the
- * PLL and CLK REQ are both enabled. This uses more
- * power but otherwise WoW sleep is unstable and the
- * chip may disappear.
- */
-
- if (AR_SREV_9285_12_OR_LATER(ah))
- ath9k_hw_config_serdes_wow_sleep(ah);
-
- }
+ set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
+ clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
+ REG_RMW(ah, AR_WA, set, clr);
}
/*
@@ -378,7 +294,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
* Program default values for pattern backoff, aifs/slot/KAL count,
* beacon miss timeout, KAL timeout, etc.
*/
-
set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
REG_SET_BIT(ah, AR_WOW_PATTERN, set);
@@ -398,7 +313,7 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
/*
* Keep alive timo in ms except AR9280
*/
- if (!pattern_enable || AR_SREV_9280(ah))
+ if (!pattern_enable)
set = AR_WOW_KEEP_ALIVE_NEVER;
else
set = KAL_TIMEOUT * 32;
@@ -420,7 +335,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
/*
* Configure MAC WoW Registers
*/
-
set = 0;
/* Send keep alive timeouts anyway */
clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
@@ -430,16 +344,9 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
else
set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
- /*
- * FIXME: For now disable keep alive frame
- * failure. This seems to sometimes trigger
- * unnecessary wake up with AR9485 chipsets.
- */
set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
-
REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
-
/*
* we are relying on a bmiss failure. ensure we have
* enough threshold to prevent false positives
@@ -473,14 +380,8 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
set |= AR_WOW_MAC_INTR_EN;
REG_RMW(ah, AR_WOW_PATTERN, set, clr);
- /*
- * For AR9285 and later version of chipsets
- * enable WoW pattern match for packets less
- * than 256 bytes for all patterns
- */
- if (AR_SREV_9285_12_OR_LATER(ah))
- REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
- AR_WOW_PATTERN_SUPPORTED);
+ REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
+ AR_WOW_PATTERN_SUPPORTED);
/*
* Set the power states appropriately and enable PME
@@ -488,43 +389,32 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
clr = 0;
set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
AR_PMCTRL_PWR_PM_CTRL_ENA;
- /*
- * This is needed for AR9300 chipsets to wake-up
- * the host.
- */
- if (AR_SREV_9300_20_OR_LATER(ah))
- clr = AR_PCIE_PM_CTRL_ENA;
+ clr = AR_PCIE_PM_CTRL_ENA;
REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
- if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
- /*
- * this is needed to prevent the chip waking up
- * the host within 3-4 seconds with certain
- * platform/BIOS. The fix is to enable
- * D1 & D3 to match original definition and
- * also match the OTP value. Anyway this
- * is more related to SW WOW.
- */
- clr = AR_PMCTRL_PWR_STATE_D1D3;
- REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
-
- set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
- REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
- }
-
+ /*
+ * this is needed to prevent the chip waking up
+ * the host within 3-4 seconds with certain
+ * platform/BIOS. The fix is to enable
+ * D1 & D3 to match original definition and
+ * also match the OTP value. Anyway this
+ * is more related to SW WOW.
+ */
+ clr = AR_PMCTRL_PWR_STATE_D1D3;
+ REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
+ set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
+ REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
- if (AR_SREV_9300_20_OR_LATER(ah)) {
- /* to bring down WOW power low margin */
- set = BIT(13);
- REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
- /* HW WoW */
- clr = BIT(5);
- REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
- }
+ /* to bring down WOW power low margin */
+ set = BIT(13);
+ REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
+ /* HW WoW */
+ clr = BIT(5);
+ REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
ath9k_hw_set_powermode_wow_sleep(ah);
ah->wow_event_mask = wow_event_mask;
--
1.8.3
^ permalink raw reply related
* Wireless LED always on
From: Gordian Klein @ 2013-06-03 2:58 UTC (permalink / raw)
To: linux-wireless
Hello,
i have a Sony Vaio SVS1511V9EB with an Intel(R) Centrino(R) Advanced-N
6235 AGN wireless card. The card is working fine, but the wireless LED
on my laptop is always on. No matter if i disable the wifi device via
NetworkManager or "rfkill block all". I set the iwlwifi led_mode
parameter to 1 (and to 2 for testing), but this didnt do anything to the
LED, it was constantly on. Id like it to be off when the wifi device is
disabled.
This is a log of dmesg:
# dmesg | grep iwl[ 3.955915] iwlwifi 0000:02:00.0: irq 46 for MSI/MSI-X
[ 3.965170] iwlwifi 0000:02:00.0: loaded firmware version 18.168.6.1
[ 3.972206] iwlwifi 0000:02:00.0: CONFIG_IWLWIFI_DEBUG enabled
[ 3.972211] iwlwifi 0000:02:00.0: CONFIG_IWLWIFI_DEBUGFS enabled
[ 3.972213] iwlwifi 0000:02:00.0: CONFIG_IWLWIFI_DEVICE_TRACING disabled
[ 3.972216] iwlwifi 0000:02:00.0: CONFIG_IWLWIFI_DEVICE_TESTMODE disabled
[ 3.972218] iwlwifi 0000:02:00.0: CONFIG_IWLWIFI_P2P disabled
[ 3.972221] iwlwifi 0000:02:00.0: Detected Intel(R) Centrino(R)
Advanced-N 6235 AGN, REV=0xB0
[ 3.972302] iwlwifi 0000:02:00.0: L1 Enabled; Disabling L0S
[ 3.992851] ieee80211 phy0: Selected rate control algorithm 'iwl-agn-rs'
[ 4.977782] iwlwifi 0000:02:00.0: L1 Enabled; Disabling L0S
[ 4.985059] iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
[ 5.359698] iwlwifi 0000:02:00.0: L1 Enabled; Disabling L0S
[ 5.366473] iwlwifi 0000:02:00.0: Radio type=0x2-0x1-0x0
I verified the led_mode parameter is set correctly with :
# cat /sys/module/iwlwifi/parameters/led_mode
1
I am running openSuse 12.2 x64 with Kernel 3.9.3-10.g06ad9d8-desktop.
Thanks for any hint.
Gordian
^ permalink raw reply
* Re: [PATCH -next 3/3] cw1200: Replace use of 'struct resource' with 'int' for GPIO fields.
From: Julian Calaby @ 2013-06-02 23:36 UTC (permalink / raw)
To: Solomon Peachy; +Cc: linux-wireless
In-Reply-To: <1370181183-11424-3-git-send-email-pizza@shaftnet.org>
Hi Solomon,
One very minor nit.
On Sun, Jun 2, 2013 at 11:53 PM, Solomon Peachy <pizza@shaftnet.org> wrote:
> The only advantage of 'struct resource' is that it lets us assign names
> as part of the platform data. Unfortunately since we are using platform
> data, we are already limited to a single instance of each driver,
> rendering this moot.
>
> So, replace the struct resources with ints, resulting in cleaner code.
>
> This was based on a suggestion from Arnd Bergmann.
>
> Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
> ---
> drivers/net/wireless/cw1200/cw1200_sagrad.c | 49 +++-----------------------
> drivers/net/wireless/cw1200/cw1200_sdio.c | 50 ++++++++++++---------------
> drivers/net/wireless/cw1200/cw1200_spi.c | 33 ++++++++----------
> include/linux/platform_data/cw1200_platform.h | 12 +++----
> 4 files changed, 47 insertions(+), 97 deletions(-)
>
> diff --git a/drivers/net/wireless/cw1200/cw1200_sagrad.c b/drivers/net/wireless/cw1200/cw1200_sagrad.c
> index 14c2a18..3f884ac 100644
> --- a/drivers/net/wireless/cw1200/cw1200_sagrad.c
> +++ b/drivers/net/wireless/cw1200/cw1200_sagrad.c
> @@ -68,9 +45,9 @@ 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],
> + .reset = GPIO_RF_RESET, /* Replace as appropriate */
> + .powerup = GPIO_RF_POWERUP, /* Replace as appropriate */
> + .irq = GPIO_TO_IRQ(GPIO_RF_IRQ), /* Replace as appropriate */
You might want to mark these "Replace as appropriate" bits with a
comment at the start indicating that these need to be set for the
platform data or modified as appropriate. I haven't looked at the rest
of the driver, so you've probably documented this already, but it
can't hurt to say that twice.
Maybe:
/* If your device doesn't support Device Tree, you'll need to enable
* this and set the GPIO pins as appropriate.
*/
Also, at least in Vim, if "XXX", "FIXME" or "TODO" appear in comments,
they get highlighted, so it might be worth adding one of those,
(probably "TODO") to the comments so that this is a touch easier to
find.
Thanks,
--
Julian Calaby
Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/
.Plan: http://sites.google.com/site/juliancalaby/
^ permalink raw reply
* wireless-testing: lockdep warning in __ieee80211_request_smps
From: Jakub Kicinski @ 2013-06-02 23:32 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
Hi,
bringing interface up for the first time (or changing PS
settings) cause following warning in current wireless-testing:
WARNING: at /home/kuba/wireless-testing/net/mac80211/cfg.c:2321 __ieee80211_request_smps+0xc5/0xf0 [mac80211]()
Modules linked in: rt2800usb rt2x00usb ...
CPU: 1 PID: 1945 Comm: ifconfig Not tainted 3.10.0-rc3-wl+ #1
Hardware name: Gigabyte Technology Co., Ltd. GA-MA790XT-UD4P/GA-MA790XT-UD4P, BIOS F9b 08/17/2012
0000000000000009 ffff88021872bb48 ffffffff815d82ad ffff88021872bb88
ffffffff8103db10 ffff88021872bb78 ffff88021f8eaac0 0000000000000001
ffff8802188d09e0 ffff88021f8eab58 0000000000000001 ffff88021872bb98
Call Trace:
[<ffffffff815d82ad>] dump_stack+0x19/0x1b
[<ffffffff8103db10>] warn_slowpath_common+0x70/0xa0
[<ffffffff8103db5a>] warn_slowpath_null+0x1a/0x20
[<ffffffffa07345f5>] __ieee80211_request_smps+0xc5/0xf0 [mac80211]
[<ffffffffa07346a1>] ieee80211_set_power_mgmt+0x81/0x100 [mac80211]
[<ffffffffa03abf95>] cfg80211_netdev_notifier_call+0x3e5/0x620 [cfg80211]
[<ffffffff815c0358>] ? dp_device_event+0x48/0x110
[<ffffffff815e26bd>] notifier_call_chain+0x4d/0x70
[<ffffffff8106b80e>] __raw_notifier_call_chain+0xe/0x10
[<ffffffff8106b826>] raw_notifier_call_chain+0x16/0x20
[<ffffffff814d2396>] call_netdevice_notifiers+0x36/0x60
[<ffffffff814d9658>] __dev_notify_flags+0x38/0x90
[<ffffffff814d96f5>] dev_change_flags+0x45/0x70
[<ffffffff81552e79>] devinet_ioctl+0x639/0x720
[<ffffffff814ebc20>] ? dev_ioctl+0x260/0x750
[<ffffffff815536b5>] inet_ioctl+0x75/0x90
[<ffffffff814bc950>] sock_do_ioctl+0x30/0x70
[<ffffffff81289c08>] ? avc_has_perm_flags+0x28/0x1e0
[<ffffffff814be714>] sock_ioctl+0x84/0x2b0
[<ffffffff81175537>] do_vfs_ioctl+0x97/0x640
[<ffffffff8128ab0a>] ? inode_has_perm.isra.24.constprop.66+0x2a/0x30
[<ffffffff8128b807>] ? file_has_perm+0x97/0xb0
[<ffffffff81175b71>] SyS_ioctl+0x91/0xb0
[<ffffffff812f1629>] ? lockdep_sys_exit_thunk+0x35/0x67
[<ffffffff815e6f42>] system_call_fastpath+0x16/0x1b
It seems that wdev.mtx lock is neither held in
nl80211_set_power_save nor in cfg80211_netdev_notifier_call.
I couldn't find any patch addressing this, is it a known
issue?
-- kuba
^ permalink raw reply
* Re: [PATCH] cw1200: fix some obvious mistakes
From: Linus Walleij @ 2013-06-02 19:38 UTC (permalink / raw)
To: Solomon Peachy
Cc: Arnd Bergmann, linux-kernel@vger.kernel.org, John W. Linville,
Wei Yongjun, Dmitry Tarnyagin, Ajitpal Singh, linux-wireless
In-Reply-To: <20130602144725.GC3875@shaftnet.org>
On Sun, Jun 2, 2013 at 4:47 PM, Solomon Peachy <pizza@shaftnet.org> wrote:
>> In fact my mobile phone has a cw1200 chip that was working until
>> recently. Now it just crashes when I do 'ifconfig wlan0 up'
>> or enable WLAN in the Android settings menu. :(
>>
>> I'm not blaming you for that ;-)
>
> What model, out of curiousity?
FYI the CW1200 is used in for example:
http://en.wikipedia.org/wiki/Samsung_Galaxy_S_Advance
http://en.wikipedia.org/wiki/Samsung_Galaxy_S_III_Mini
http://en.wikipedia.org/wiki/Sony_Xperia_P
http://en.wikipedia.org/wiki/Sony_Xperia_U
http://en.wikipedia.org/wiki/Sony_Xperia_sola
(plus some others)
Yours,
Linus Walleij
^ permalink raw reply
* Re: [rt2x00-users] [PATCH 3.10-rc] wireless: rt2x00: rt2800: fix hardware antenna diversity for RT5370G
From: Jakub Kicinski @ 2013-06-02 15:38 UTC (permalink / raw)
To: Gertjan van Wingerde
Cc: Xose Vazquez Perez, users@rt2x00.serialmonkey.com,
linux-wireless@vger.kernel.org
In-Reply-To: <86F5D1A2-7E2C-4EE5-9D29-C66306833C35@gmail.com>
Hi!
Any progress on this patch?
-- Kuba
On Wed, 8 May 2013 00:30:22 +0200, Gertjan van Wingerde wrote:
> Hi Xose,
>
> Sent from my iPad
>
> On 7 mei 2013, at 22:03, Xose Vazquez Perez <xose.vazquez@gmail.com> wrote:
>
> > RT5370G has hardware RX antenna diversity like RT5390R.
> >
> > based on 2012_03_22_RT5572_Linux_STA_v2.6.0.0_DPO
>
> I'll check this patch tomorrow, when I get back home.
>
> In the meantime some style related comments below.
>
> >
> > Cc: Ivo van Doorn <IvDoorn@gmail.com>
> > Cc: Gertjan van Wingerde <gwingerde@gmail.com>
> > Cc: Helmut Schaa <helmut.schaa@googlemail.com>
> > Cc: John W. Linville <linville@tuxdriver.com>
> > Cc: users@rt2x00.serialmonkey.com
> > Cc: linux-wireless@vger.kernel.org
> > Tested-by: wnewbie72@gmail.com
> > Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
> > ---
> > drivers/net/wireless/rt2x00/rt2800.h | 3 ++-
> > drivers/net/wireless/rt2x00/rt2800lib.c | 8 +++++---
> > 2 files changed, 7 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
> > index a7630d5..6e84eee 100644
> > --- a/drivers/net/wireless/rt2x00/rt2800.h
> > +++ b/drivers/net/wireless/rt2x00/rt2800.h
> > @@ -89,7 +89,8 @@
> > #define REV_RT3090E 0x0211
> > #define REV_RT3390E 0x0211
> > #define REV_RT5390F 0x0502
> > -#define REV_RT5390R 0x1502
> > +#define REV_RT5370G 0x0503 /* hardware RX antenna diversity */
> > +#define REV_RT5390R 0x1502 /* hardware RX antenna diversity */
> > #define REV_RT5592C 0x0221
>
> Please don't the comments to the chipset revision definitions. These macros are usually used all over the place; there is no need to specify this here.
>
> >
> > #define DEFAULT_RSSI_OFFSET 120
> > diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> > index b52d70c..e202ec7 100644
> > --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> > +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> > @@ -4311,8 +4311,9 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
> > rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
> > }
> >
> > - /* This chip has hardware antenna diversity*/
> > - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390R)) {
> > + /* These chips have hardware RX antenna diversity */
> > + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390R) ||
> > + rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5370G)) {
> > rt2800_bbp_write(rt2x00dev, 150, 0); /* Disable Antenna Software OFDM */
> > rt2800_bbp_write(rt2x00dev, 151, 0); /* Disable Antenna Software CCK */
> > rt2800_bbp_write(rt2x00dev, 154, 0); /* Clear previously selected antenna */
>
> With respect to the comment change: are you sure this is only about RX antenna diversity?
>
> Also, I'm wondering if the change to the if condition brings us everything that is wanted. Checking the same chipset for different minimal revisions doesn't make a whole lot of sense to me.
> Sure, you are fixing later RT5370 revisions here, but may be botching up early RT5390 revisions here at the same time
>
> > @@ -5554,7 +5555,8 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
> > rt2x00dev->default_ant.rx = ANTENNA_A;
> > }
> >
> > - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390R)) {
> > + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390R) ||
> > + rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5370G)) {
> > rt2x00dev->default_ant.tx = ANTENNA_HW_DIVERSITY; /* Unused */
> > rt2x00dev->default_ant.rx = ANTENNA_HW_DIVERSITY; /* Unused */
> > }
>
> The same comment on the if conditions apply here.
>
> ---
> Gertjan
> _______________________________________________
> users mailing list
> users@rt2x00.serialmonkey.com
> http://rt2x00.serialmonkey.com/mailman/listinfo/users_rt2x00.serialmonkey.com
>
^ permalink raw reply
* [PATCH -next 2/2] cw1200: rename the cw1200 platform definition header
From: Solomon Peachy @ 2013-06-02 15:35 UTC (permalink / raw)
To: linux-wireless; +Cc: Solomon Peachy
In-Reply-To: <1370187332-18813-1-git-send-email-pizza@shaftnet.org>
My previous patch just moved the file, but it also needed to be renamed
to conform to proper conventions.
Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
---
drivers/net/wireless/cw1200/cw1200_sdio.c | 2 +-
drivers/net/wireless/cw1200/cw1200_spi.c | 2 +-
include/linux/platform_data/cw1200_platform.h | 81 ---------------------------
include/linux/platform_data/net-cw1200.h | 81 +++++++++++++++++++++++++++
4 files changed, 83 insertions(+), 83 deletions(-)
delete mode 100644 include/linux/platform_data/cw1200_platform.h
create mode 100644 include/linux/platform_data/net-cw1200.h
diff --git a/drivers/net/wireless/cw1200/cw1200_sdio.c b/drivers/net/wireless/cw1200/cw1200_sdio.c
index 913a3eb..808257e 100644
--- a/drivers/net/wireless/cw1200/cw1200_sdio.c
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -21,7 +21,7 @@
#include "cw1200.h"
#include "hwbus.h"
-#include <linux/platform_data/cw1200_platform.h>
+#include <linux/platform_data/net-cw1200.h>
#include "hwio.h"
MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index 5eacf9e..61406e7 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -26,7 +26,7 @@
#include "cw1200.h"
#include "hwbus.h"
-#include <linux/platform_data/cw1200_platform.h>
+#include <linux/platform_data/net-cw1200.h>
#include "hwio.h"
MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
diff --git a/include/linux/platform_data/cw1200_platform.h b/include/linux/platform_data/cw1200_platform.h
deleted file mode 100644
index c6fbc3c..0000000
--- a/include/linux/platform_data/cw1200_platform.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2011
- *
- * Author: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#ifndef CW1200_PLAT_H_INCLUDED
-#define CW1200_PLAT_H_INCLUDED
-
-struct cw1200_platform_data_spi {
- u8 spi_bits_per_word; /* REQUIRED */
- u16 ref_clk; /* REQUIRED (in KHz) */
-
- /* All others are optional */
- bool have_5ghz;
- int reset; /* GPIO to RSTn signal (0 disables) */
- int powerup; /* GPIO to POWERUP signal (0 disables) */
- int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
- bool enable); /* Control 3v3 / 1v8 supply */
- int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata,
- bool enable); /* Control CLK32K */
- const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
- const char *sdd_file; /* if NULL, will use default for detected hw type */
-};
-
-struct cw1200_platform_data_sdio {
- u16 ref_clk; /* REQUIRED (in KHz) */
-
- /* All others are optional */
- bool have_5ghz;
- bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
- int reset; /* GPIO to RSTn signal (0 disables) */
- int powerup; /* GPIO to POWERUP signal (0 disables) */
- int irq; /* IRQ line or 0 to use SDIO IRQ */
- int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
- bool enable); /* Control 3v3 / 1v8 supply */
- int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
- bool enable); /* Control CLK32K */
- const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
- const char *sdd_file; /* if NULL, will use default for detected hw type */
-};
-
-
-/* An example of SPI support in your board setup file:
-
- static struct cw1200_platform_data_spi cw1200_platform_data = {
- .ref_clk = 38400,
- .spi_bits_per_word = 16,
- .reset = GPIO_RF_RESET,
- .powerup = GPIO_RF_POWERUP,
- .macaddr = wifi_mac_addr,
- .sdd_file = "sdd_sagrad_1091_1098.bin",
- };
- static struct spi_board_info myboard_spi_devices[] __initdata = {
- {
- .modalias = "cw1200_wlan_spi",
- .max_speed_hz = 52000000,
- .bus_num = 0,
- .irq = WIFI_IRQ,
- .platform_data = &cw1200_platform_data,
- .chip_select = 0,
- },
- };
-
- */
-
-/* An example of SDIO support in your board setup file:
-
- static struct cw1200_platform_data_sdio my_cw1200_platform_data = {
- .ref_clk = 38400,
- .have_5ghz = false,
- .sdd_file = "sdd_myplatform.bin",
- };
- cw1200_sdio_set_platform_data(&my_cw1200_platform_data);
-
- */
-
-void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata);
-
-#endif /* CW1200_PLAT_H_INCLUDED */
diff --git a/include/linux/platform_data/net-cw1200.h b/include/linux/platform_data/net-cw1200.h
new file mode 100644
index 0000000..c6fbc3c
--- /dev/null
+++ b/include/linux/platform_data/net-cw1200.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CW1200_PLAT_H_INCLUDED
+#define CW1200_PLAT_H_INCLUDED
+
+struct cw1200_platform_data_spi {
+ u8 spi_bits_per_word; /* REQUIRED */
+ u16 ref_clk; /* REQUIRED (in KHz) */
+
+ /* All others are optional */
+ bool have_5ghz;
+ int reset; /* GPIO to RSTn signal (0 disables) */
+ int powerup; /* GPIO to POWERUP signal (0 disables) */
+ int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
+ bool enable); /* Control 3v3 / 1v8 supply */
+ int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata,
+ bool enable); /* Control CLK32K */
+ const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
+ const char *sdd_file; /* if NULL, will use default for detected hw type */
+};
+
+struct cw1200_platform_data_sdio {
+ u16 ref_clk; /* REQUIRED (in KHz) */
+
+ /* All others are optional */
+ bool have_5ghz;
+ bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
+ int reset; /* GPIO to RSTn signal (0 disables) */
+ int powerup; /* GPIO to POWERUP signal (0 disables) */
+ int irq; /* IRQ line or 0 to use SDIO IRQ */
+ int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
+ bool enable); /* Control 3v3 / 1v8 supply */
+ int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
+ bool enable); /* Control CLK32K */
+ const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
+ const char *sdd_file; /* if NULL, will use default for detected hw type */
+};
+
+
+/* An example of SPI support in your board setup file:
+
+ static struct cw1200_platform_data_spi cw1200_platform_data = {
+ .ref_clk = 38400,
+ .spi_bits_per_word = 16,
+ .reset = GPIO_RF_RESET,
+ .powerup = GPIO_RF_POWERUP,
+ .macaddr = wifi_mac_addr,
+ .sdd_file = "sdd_sagrad_1091_1098.bin",
+ };
+ static struct spi_board_info myboard_spi_devices[] __initdata = {
+ {
+ .modalias = "cw1200_wlan_spi",
+ .max_speed_hz = 52000000,
+ .bus_num = 0,
+ .irq = WIFI_IRQ,
+ .platform_data = &cw1200_platform_data,
+ .chip_select = 0,
+ },
+ };
+
+ */
+
+/* An example of SDIO support in your board setup file:
+
+ static struct cw1200_platform_data_sdio my_cw1200_platform_data = {
+ .ref_clk = 38400,
+ .have_5ghz = false,
+ .sdd_file = "sdd_myplatform.bin",
+ };
+ cw1200_sdio_set_platform_data(&my_cw1200_platform_data);
+
+ */
+
+void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata);
+
+#endif /* CW1200_PLAT_H_INCLUDED */
--
1.8.2.1
^ permalink raw reply related
* [PATCH -next 1/2] cw1200: Rework SDIO platform support to prevent build problems.
From: Solomon Peachy @ 2013-06-02 15:35 UTC (permalink / raw)
To: linux-wireless; +Cc: Solomon Peachy
Based on discussions with And Bergmann, this patch changes the SDIO
platform code to default to supporting the Sagrad devices, allowing for
it to be overridden in board setup code. This renders the cw1200_sagrad
module suplerflous, so it is now removed.
It also moves the documentation that was in the cw1200_sagrad source to
the platform header.
Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
---
drivers/net/wireless/cw1200/Kconfig | 17 ++---
drivers/net/wireless/cw1200/Makefile | 2 -
drivers/net/wireless/cw1200/cw1200_sagrad.c | 106 --------------------------
drivers/net/wireless/cw1200/cw1200_sdio.c | 26 ++++++-
include/linux/platform_data/cw1200_platform.h | 37 ++++++++-
5 files changed, 66 insertions(+), 122 deletions(-)
delete mode 100644 drivers/net/wireless/cw1200/cw1200_sagrad.c
diff --git a/drivers/net/wireless/cw1200/Kconfig b/drivers/net/wireless/cw1200/Kconfig
index 13e3611..7a585d4 100644
--- a/drivers/net/wireless/cw1200/Kconfig
+++ b/drivers/net/wireless/cw1200/Kconfig
@@ -13,20 +13,19 @@ config CW1200_WLAN_SDIO
depends on CW1200 && MMC
help
Enable support for the CW1200 connected via an SDIO bus.
+ By default this driver only supports the Sagrad SG901-1091/1098 EVK
+ and similar designs that utilize a hardware reset circuit. To
+ support different CW1200 SDIO designs you will need to override
+ the default platform data by calling cw1200_sdio_set_platform_data()
+ in your board setup file.
config CW1200_WLAN_SPI
tristate "Support SPI platforms"
depends on CW1200 && SPI
help
- Enables support for the CW1200 connected via a SPI bus.
-
-config CW1200_WLAN_SAGRAD
- tristate "Support Sagrad SG901-1091/1098 modules"
- depends on CW1200_WLAN_SDIO
- help
- This provides the platform data glue to support the
- Sagrad SG901-1091/1098 modules in their standard SDIO EVK.
- It also includes example SPI platform data.
+ Enables support for the CW1200 connected via a SPI bus. You will
+ need to add appropriate platform data glue in your board setup
+ file.
menu "Driver debug features"
depends on CW1200 && DEBUG_FS
diff --git a/drivers/net/wireless/cw1200/Makefile b/drivers/net/wireless/cw1200/Makefile
index 1aa3682..bc6cbf9 100644
--- a/drivers/net/wireless/cw1200/Makefile
+++ b/drivers/net/wireless/cw1200/Makefile
@@ -16,9 +16,7 @@ cw1200_core-$(CONFIG_PM) += pm.o
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/cw1200_sagrad.c b/drivers/net/wireless/cw1200/cw1200_sagrad.c
deleted file mode 100644
index 3f884ac..0000000
--- a/drivers/net/wireless/cw1200/cw1200_sagrad.c
+++ /dev/null
@@ -1,106 +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/platform_data/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
-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 = GPIO_RF_RESET, /* Replace as appropriate */
- .powerup = GPIO_RF_POWERUP, /* Replace as appropriate */
- .irq = GPIO_TO_IRQ(GPIO_RF_IRQ), /* Replace as appropriate */
-#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
-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 = GPIO_RF_RESET, /* Replace as appropriate */
- .powerup = GPIO_RF_POWERUP, /* Replace as appropriate */
- .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 e78bb37..913a3eb 100644
--- a/drivers/net/wireless/cw1200/cw1200_sdio.c
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -30,6 +30,21 @@ MODULE_LICENSE("GPL");
#define SDIO_BLOCK_SIZE (512)
+/* 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;
@@ -262,7 +277,7 @@ static struct hwbus_ops cw1200_sdio_hwbus_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 hwbus_priv *self;
int status;
@@ -281,7 +296,7 @@ static int cw1200_sdio_probe(struct sdio_func *func,
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);
@@ -376,7 +391,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;
@@ -398,7 +414,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/include/linux/platform_data/cw1200_platform.h b/include/linux/platform_data/cw1200_platform.h
index 4454c16..c6fbc3c 100644
--- a/include/linux/platform_data/cw1200_platform.h
+++ b/include/linux/platform_data/cw1200_platform.h
@@ -41,6 +41,41 @@ struct cw1200_platform_data_sdio {
const char *sdd_file; /* if NULL, will use default for detected hw type */
};
-const void *cw1200_get_platform_data(void);
+
+/* An example of SPI support in your board setup file:
+
+ static struct cw1200_platform_data_spi cw1200_platform_data = {
+ .ref_clk = 38400,
+ .spi_bits_per_word = 16,
+ .reset = GPIO_RF_RESET,
+ .powerup = GPIO_RF_POWERUP,
+ .macaddr = wifi_mac_addr,
+ .sdd_file = "sdd_sagrad_1091_1098.bin",
+ };
+ static struct spi_board_info myboard_spi_devices[] __initdata = {
+ {
+ .modalias = "cw1200_wlan_spi",
+ .max_speed_hz = 52000000,
+ .bus_num = 0,
+ .irq = WIFI_IRQ,
+ .platform_data = &cw1200_platform_data,
+ .chip_select = 0,
+ },
+ };
+
+ */
+
+/* An example of SDIO support in your board setup file:
+
+ static struct cw1200_platform_data_sdio my_cw1200_platform_data = {
+ .ref_clk = 38400,
+ .have_5ghz = false,
+ .sdd_file = "sdd_myplatform.bin",
+ };
+ cw1200_sdio_set_platform_data(&my_cw1200_platform_data);
+
+ */
+
+void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata);
#endif /* CW1200_PLAT_H_INCLUDED */
--
1.8.2.1
^ permalink raw reply related
* Re: [PATCH] cw1200: fix some obvious mistakes
From: Solomon Peachy @ 2013-06-02 14:47 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel, John W. Linville, Wei Yongjun, Dmitry Tarnyagin,
Ajitpal Singh, linux-wireless
In-Reply-To: <8513280.folT80711V@wuerfel>
[-- Attachment #1: Type: text/plain, Size: 5800 bytes --]
On Sun, Jun 02, 2013 at 03:59:12PM +0200, Arnd Bergmann wrote:
> The driver doesn't reliably build, and I'm trying to fix it.
> From my perspective, we can just mark it 'depends on !ARM'
> to get it off my radar, but other people are doing build
> testing on x86 and will run into the same issues.
AFAIK the only remaining build problem is when CONFIG_CW1200_SAGRAD is
not defined so there's no "platform" data provided.
> If the hardware cannot be identified from register access, the
> information should get passed through firmware. On most architectures
> that means device tree data, on x86 that would be ACPI tables.
The cw1200 has specific reset sequencing requirements. Some designs use
a hardware reset circuit (such as the Sagrad EVK/Reference design), but
most others use GPIOs for cost resons.
Without that reset sequence, the device will never attach itself to the
SDIO bus so we will never get to the point where we can probe it via
register accesses (and program the DPLL value) to discern enough
information to load the appropriate firmware.
(The DPLL value is part of the so-called 'SDD' file, but that file is
also tied to the specific implemntation. You have to love those
chicken-and-egg problems...)
> The code does not look particularly off-the-shelf though:
> static struct resource cw1200_href_resources[] = {
That code is #ifdef'd out, and was purely left there as a reference.
It's gone now. :)
> We can use platform_data if there is convincing evidence that people
> are going to be using that in mainline kernels. However, your SDIO driver
> doesn't actually do that, it just hardcodes settings in cw1200_sagrad.c
> and calls a local function to get that data, rather than getting the data
> from the dev_get_platdata() in it's probe callback at a point where
> it knows the device is actually there.
As I mentioned earlier, we don't know the device is there until after we
get enough information from the platform_data to power it up and deal
with the finiky reset sequence.
Basically the Sagrad SD-slot-form-factor EVK is a special case only
meant for evaluation purposes. The "normal" use case for thise driver
is a hard-wired, permanently attached design.
> If we only care about two cases a) a default sagrad card that can use
> hardcoded data and b) a board that uses the same chip and requires
> custom data, then I would suggest including the sagrad data in the
> sdio driver as a default (as my patch does) but allow overriding
> it with platform data.
Yes, those are the only use cases we care about. And that sounds like a
viable approach, so I'll code that up.
I guess adding a function along the lines of
"cw1200_sdio_set_platform_data()" (to be called by the board/platform
setup code) would be the right way to do this?
As an aside, I wish I'd received this feedback a couple of months ago.
> The problem with this is that it is impossible to build a kernel that
> supports both, or even two devices of the same type.
Adding proper devicetree support will solve this problem down the line,
but I don't think there's any way to fix this for non-DT systems thanks
to that chicken-and-egg probing situation.
(I wish I had a DT-capable platform handy to develop against..)
> I mean arch/arm/mach-nomadik, which is the platform that originally
> defined NOMADIK_GPIO_TO_IRQ(). Note that in recent kernels, mach-ux500
> also uses this macro internally, but it's already gone in nomadik
> and will stop working in ux500 in the future.
Ah, okay. FWIW that was a leftover bit from the original driver authors
who'd tied the code rather tightly to the ux500 platform. That
reference is gone now in any case.
> I don't mind the backports supporting that, but we should probably
> move on in mainline. The existance of backports is no excuse for
> keeping around broken code.
I already have one patch queued up for backports to re-enable <2.6.36
support, and I have no problem adding more.
That said, until all SDIO/SPI-supporting targets in the mainline are
converted to a devicetree (or equivalent) model, I imagine the
platform_data crap will have to remain.
> just look in include/linux/platform_data/. The most common type for
> gpio numbers is 'int'.
I've already posted a patch that converts them over.
> Sorry for misinterpreting that, the cw1200_sagrad file really looked
> like it was written for some out-of-tree board and subsequently
> all lines that didn't compile got commented out.
No problem. I just needed to make it clear that this driver did in fact
work -- and it also compiled cleanly on x86_64 as long as the sagrad
symbol was defined.
> In fact my mobile phone has a cw1200 chip that was working until
> recently. Now it just crashes when I do 'ifconfig wlan0 up'
> or enable WLAN in the Android settings menu. :(
>
> I'm not blaming you for that ;-)
What model, out of curiousity?
> I think the most important part is separating the generic sagrad
> add-on card code from any platform-specific code and removing the
> use of cw1200_get_platform_data() function that breaks the build.
I'll convert SDIO driver to using the sagrad data as default and add a
'set_platform_data' sort of function to allow it to be optionally
overridden. It shouldn't take long, and I'll post the patch as soon as
I'm finished.
(I don't know how long it'll take to get merged though.. none of the
already-posted followup cw1200 patches have been merged into
wireless-next yet)
- Solomon
--
Solomon Peachy pizza at shaftnet dot org
Delray Beach, FL ^^ (email/xmpp) ^^
Quidquid latine dictum sit, altum viditur.
[-- Attachment #2: Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply
* Re: [PATCH] cw1200: fix some obvious mistakes
From: Arnd Bergmann @ 2013-06-02 13:59 UTC (permalink / raw)
To: Solomon Peachy
Cc: linux-kernel, John W. Linville, Wei Yongjun, Dmitry Tarnyagin,
Ajitpal Singh, linux-wireless
In-Reply-To: <20130602122954.GA3875@shaftnet.org>
On Sunday 02 June 2013 08:29:54 Solomon Peachy wrote:
> On Sun, Jun 02, 2013 at 12:37:21AM +0200, Arnd Bergmann wrote:
> > I got compile errors with the cw1200, which has lead me to take a
> > closer look. It seems the driver still has a number of issues,
> > and this addresses some of them and marks others as FIXME:
>
> In short, NACK, at least not as posted.
>
> The concerns are legitimate, but the time to object to such fundamental
> stuff was at some point during the past *seven* rounds of patches I
> posted over a period of nearly as many months.
The driver doesn't reliably build, and I'm trying to fix it.
>From my perspective, we can just mark it 'depends on !ARM'
to get it off my radar, but other people are doing build
testing on x86 and will run into the same issues.
> > * The cw1200_sagrad.c file should not be there, hardcoding
> > hardware configuration in .c files has been obsolete since
> > Linux-2.4, so we should just remove it. Most of that file
> > was already commented out since it does not compile.
>
> The problem with the cw1200 is that you need certain information about
> the hardware design in order to initialize it; this information has to
> come from somewhere.
If the hardware cannot be identified from register access, the
information should get passed through firmware. On most architectures
that means device tree data, on x86 that would be ACPI tables.
> The Sagrad wifi devices are available in a standard SD form factor
> reference design that plugs into a standard SDIO-supporing slot. The
> cw1200_sagrad module is there to support these off-the-shelf devices.
The code does not look particularly off-the-shelf though:
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",
},
};
There is nothing generic about that.
> Requiring users to recompile their kernel or update their devicetree
> data for what amounts to an off-the-shelf hot-pluggable device is simply
> not acceptable.
That was the intention of the patch. Right now, you require users
to modify cw1200_sagrad.c.
> At the same time, if people plop the sagrad device directly on their
> board (or independently do a chip-down design) they may need to make
> changes to the platform data depending on how closely it tracks the
> Sagrad reference design.
We can use platform_data if there is convincing evidence that people
are going to be using that in mainline kernels. However, your SDIO driver
doesn't actually do that, it just hardcodes settings in cw1200_sagrad.c
and calls a local function to get that data, rather than getting the data
from the dev_get_platdata() in it's probe callback at a point where
it knows the device is actually there.
> Further complicating things, there's no way to alter the SDIO
> vendor/device IDs that the device reports in order to distingish between
> any of this.
>
> If you have a better suggestion on how to handle this set of conflicting
> requirements then I'm all ears, but it's rather pointless to object to
> code that's ugly because it has to support ugly hardware.
>
> (That said, the commented-out bits in cw1200_sagrad are mostly there for
> documentation purposes, and it could be moved to a proper documentation
> file instead.)
I think a better place for that would be the include/linux/platform_data
header file.
If we only care about two cases a) a default sagrad card that can use
hardcoded data and b) a board that uses the same chip and requires
custom data, then I would suggest including the sagrad data in the
sdio driver as a default (as my patch does) but allow overriding
it with platform data.
> > * Move the parts of cw1200_sagrad.c that actually got used into
> > cw1200_sdio.c, because it doesn't build otherwise.
>
> The idea was that either you build cw1200_sagrad or provide your own
> platform_data. I separated all of the implemenation-specific code out
> as cleanly as I could.
The problem with this is that it is impossible to build a kernel that
supports both, or even two devices of the same type.
> > * Make the platform_data for the sdio driver private to
> > cw1200_sdio.c. The platform that was referenced here is
> > going to use device tree based probing only in the future,
> > which means the platform data has to go away anyway.
>
> When you say "the platform" what are you referring to? SDIO? There's
> no mention of any specific board (or even arch/subarch) in cw1200_sdio
> or cw1200_sagrad.
I mean arch/arm/mach-nomadik, which is the platform that originally
defined NOMADIK_GPIO_TO_IRQ(). Note that in recent kernels, mach-ux500
also uses this macro internally, but it's already gone in nomadik
and will stop working in ux500 in the future.
> In the real world, this driver will have to support non-devicetree
> operation for as long as Linux does, and indeed longer, thanks to
> compat-drivers/backports.
I don't mind the backports supporting that, but we should probably
move on in mainline. The existance of backports is no excuse for
keeping around broken code.
> And for what it's worth, none of the platforms I have access to have
> devicetree support since I'm stuck using vendor-supplied kernels.
Out of tree platforms are also not really an issue, since you already
need to patch the kernel. You can patch it some more to add platform
data back.
> > * Add comments about passing GPIO numbers in platform_data:
> > You should not use IORESOURCE_IO, which is for legacy ISA
> > I/O ports on PCs, not for GPIOs.
>
> Fair enough. The use of resources was something already in the driver
> when I inherited it, but I've seen this pattern a lot elsewhere. Is
> there a specific driver I should reference instead?
just look in include/linux/platform_data/. The most common type for
gpio numbers is 'int'.
> > It may actually be easier to remove the sdio driver entirely,
> > since it clearly doesn't work and requires a lot of cleanup.
>
> Several hundred thousand in-the-field devices already deployed with this
> driver clearly disagree with you.
Sorry for misinterpreting that, the cw1200_sagrad file really looked
like it was written for some out-of-tree board and subsequently
all lines that didn't compile got commented out.
> I've personally tested this driver on six different hardware platforms,
> using mainline kernels for some and vendor-supplied kernels for others.
I was only talking about mainline kernels, obviously the driver has
worked somewhere before, but that is not the point if the working
version is not the one that got merged.
In fact my mobile phone has a cw1200 chip that was working until
recently. Now it just crashes when I do 'ifconfig wlan0 up'
or enable WLAN in the Android settings menu. :(
I'm not blaming you for that ;-)
> With module-down and SD-slot designs. Others have tested other
> platforms. Every configurable option and line item in both the SPI and
> SDIO platform data is there because it needs to be in order to support
> the variety of hardware designs already in the wild.
>
> This driver will also be part of the compat-drivers/backports project,
> and as such has to work within that framework as well.
>
> If you have constructive suggestions on how to handle this set of
> requirements in a cleaner manner, I'm all ears.
I think the most important part is separating the generic sagrad
add-on card code from any platform-specific code and removing the
use of cw1200_get_platform_data() function that breaks the build.
Arnd
^ permalink raw reply
* [PATCH -next 3/3] cw1200: Replace use of 'struct resource' with 'int' for GPIO fields.
From: Solomon Peachy @ 2013-06-02 13:53 UTC (permalink / raw)
To: linux-wireless; +Cc: Solomon Peachy
In-Reply-To: <1370181183-11424-1-git-send-email-pizza@shaftnet.org>
The only advantage of 'struct resource' is that it lets us assign names
as part of the platform data. Unfortunately since we are using platform
data, we are already limited to a single instance of each driver,
rendering this moot.
So, replace the struct resources with ints, resulting in cleaner code.
This was based on a suggestion from Arnd Bergmann.
Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
---
drivers/net/wireless/cw1200/cw1200_sagrad.c | 49 +++-----------------------
drivers/net/wireless/cw1200/cw1200_sdio.c | 50 ++++++++++++---------------
drivers/net/wireless/cw1200/cw1200_spi.c | 33 ++++++++----------
include/linux/platform_data/cw1200_platform.h | 12 +++----
4 files changed, 47 insertions(+), 97 deletions(-)
diff --git a/drivers/net/wireless/cw1200/cw1200_sagrad.c b/drivers/net/wireless/cw1200/cw1200_sagrad.c
index 14c2a18..3f884ac 100644
--- a/drivers/net/wireless/cw1200/cw1200_sagrad.c
+++ b/drivers/net/wireless/cw1200/cw1200_sagrad.c
@@ -21,29 +21,6 @@ MODULE_LICENSE("GPL");
/* #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)
{
@@ -68,9 +45,9 @@ 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],
+ .reset = GPIO_RF_RESET, /* Replace as appropriate */
+ .powerup = GPIO_RF_POWERUP, /* Replace as appropriate */
+ .irq = GPIO_TO_IRQ(GPIO_RF_IRQ), /* Replace as appropriate */
#endif
.power_ctrl = cw1200_power_ctrl,
.clk_ctrl = cw1200_clk_ctrl,
@@ -80,22 +57,6 @@ static struct cw1200_platform_data_sdio cw1200_platform_data = {
#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)
{
@@ -118,8 +79,8 @@ static int cw1200_clk_ctrl(const struct cw1200_platform_data_spi *pdata,
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],
+ .reset = GPIO_RF_RESET, /* Replace as appropriate */
+ .powerup = GPIO_RF_POWERUP, /* Replace as appropriate */
.power_ctrl = cw1200_power_ctrl,
.clk_ctrl = cw1200_clk_ctrl,
/* .macaddr = ??? */
diff --git a/drivers/net/wireless/cw1200/cw1200_sdio.c b/drivers/net/wireless/cw1200/cw1200_sdio.c
index a725693..e78bb37 100644
--- a/drivers/net/wireless/cw1200/cw1200_sdio.c
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -106,7 +106,6 @@ static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
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 +122,15 @@ static int cw1200_request_irq(struct hwbus_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;
@@ -163,8 +162,8 @@ static int cw1200_sdio_irq_unsubscribe(struct hwbus_priv *self)
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 +174,10 @@ static int cw1200_sdio_irq_unsubscribe(struct hwbus_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 +190,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->powerup;
-
/* 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,13 +220,13 @@ 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;
@@ -253,7 +247,7 @@ 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;
}
@@ -275,7 +269,7 @@ static int cw1200_sdio_probe(struct sdio_func *func,
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;
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index c4ddee8..5eacf9e 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -267,12 +267,10 @@ static int cw1200_spi_irq_unsubscribe(struct hwbus_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)
@@ -285,19 +283,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->powerup;
-
/* 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 */
@@ -318,13 +313,13 @@ 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;
diff --git a/include/linux/platform_data/cw1200_platform.h b/include/linux/platform_data/cw1200_platform.h
index c168fa5..4454c16 100644
--- a/include/linux/platform_data/cw1200_platform.h
+++ b/include/linux/platform_data/cw1200_platform.h
@@ -14,8 +14,8 @@ struct cw1200_platform_data_spi {
/* All others are optional */
bool have_5ghz;
- const struct resource *reset; /* GPIO to RSTn signal */
- const struct resource *powerup; /* GPIO to POWERUP signal */
+ int reset; /* GPIO to RSTn signal (0 disables) */
+ int powerup; /* GPIO to POWERUP signal (0 disables) */
int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
bool enable); /* Control 3v3 / 1v8 supply */
int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata,
@@ -28,11 +28,11 @@ struct cw1200_platform_data_sdio {
u16 ref_clk; /* REQUIRED (in KHz) */
/* All others are optional */
- const struct resource *irq; /* if using GPIO for IRQ */
bool have_5ghz;
- bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
- const struct resource *reset; /* GPIO to RSTn signal */
- const struct resource *powerup; /* GPIO to POWERUP signal */
+ bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
+ int reset; /* GPIO to RSTn signal (0 disables) */
+ int powerup; /* GPIO to POWERUP signal (0 disables) */
+ int irq; /* IRQ line or 0 to use SDIO IRQ */
int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
bool enable); /* Control 3v3 / 1v8 supply */
int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
--
1.8.2.1
^ permalink raw reply related
* [PATCH -next 2/3] cw1200: Reference correct 'powerup' GPIO signal.
From: Solomon Peachy @ 2013-06-02 13:53 UTC (permalink / raw)
To: linux-wireless; +Cc: Solomon Peachy
In-Reply-To: <1370181183-11424-1-git-send-email-pizza@shaftnet.org>
Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
---
drivers/net/wireless/cw1200/cw1200_sdio.c | 2 +-
drivers/net/wireless/cw1200/cw1200_spi.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/cw1200/cw1200_sdio.c b/drivers/net/wireless/cw1200/cw1200_sdio.c
index d5bdbeb..a725693 100644
--- a/drivers/net/wireless/cw1200/cw1200_sdio.c
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -194,7 +194,7 @@ 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;
+ const struct resource *powerup = pdata->powerup;
/* Ensure I/Os are pulled low */
if (reset) {
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index d77848a..c4ddee8 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -286,7 +286,7 @@ 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;
+ const struct resource *powerup = pdata->powerup;
/* Ensure I/Os are pulled low */
if (reset) {
--
1.8.2.1
^ permalink raw reply related
* [PATCH -next 1/3] cw1200: move platform_data header to correct location.
From: Solomon Peachy @ 2013-06-02 13:53 UTC (permalink / raw)
To: linux-wireless; +Cc: Solomon Peachy
(As suggested by Arnd Bergmann)
Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
---
drivers/net/wireless/cw1200/cw1200_sagrad.c | 2 +-
drivers/net/wireless/cw1200/cw1200_sdio.c | 2 +-
drivers/net/wireless/cw1200/cw1200_spi.c | 2 +-
include/linux/cw1200_platform.h | 46 ---------------------------
include/linux/platform_data/cw1200_platform.h | 46 +++++++++++++++++++++++++++
5 files changed, 49 insertions(+), 49 deletions(-)
delete mode 100644 include/linux/cw1200_platform.h
create mode 100644 include/linux/platform_data/cw1200_platform.h
diff --git a/drivers/net/wireless/cw1200/cw1200_sagrad.c b/drivers/net/wireless/cw1200/cw1200_sagrad.c
index a5ada0e..14c2a18 100644
--- a/drivers/net/wireless/cw1200/cw1200_sagrad.c
+++ b/drivers/net/wireless/cw1200/cw1200_sagrad.c
@@ -10,7 +10,7 @@
*/
#include <linux/module.h>
-#include <linux/cw1200_platform.h>
+#include <linux/platform_data/cw1200_platform.h>
MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
MODULE_DESCRIPTION("ST-Ericsson CW1200 Platform glue driver");
diff --git a/drivers/net/wireless/cw1200/cw1200_sdio.c b/drivers/net/wireless/cw1200/cw1200_sdio.c
index 0865f92..d5bdbeb 100644
--- a/drivers/net/wireless/cw1200/cw1200_sdio.c
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -21,7 +21,7 @@
#include "cw1200.h"
#include "hwbus.h"
-#include <linux/cw1200_platform.h>
+#include <linux/platform_data/cw1200_platform.h>
#include "hwio.h"
MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index 22db584..d77848a 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -26,7 +26,7 @@
#include "cw1200.h"
#include "hwbus.h"
-#include <linux/cw1200_platform.h>
+#include <linux/platform_data/cw1200_platform.h>
#include "hwio.h"
MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
diff --git a/include/linux/cw1200_platform.h b/include/linux/cw1200_platform.h
deleted file mode 100644
index c168fa5..0000000
--- a/include/linux/cw1200_platform.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2011
- *
- * Author: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#ifndef CW1200_PLAT_H_INCLUDED
-#define CW1200_PLAT_H_INCLUDED
-
-struct cw1200_platform_data_spi {
- u8 spi_bits_per_word; /* REQUIRED */
- u16 ref_clk; /* REQUIRED (in KHz) */
-
- /* All others are optional */
- bool have_5ghz;
- const struct resource *reset; /* GPIO to RSTn signal */
- const struct resource *powerup; /* GPIO to POWERUP signal */
- int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
- bool enable); /* Control 3v3 / 1v8 supply */
- int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata,
- bool enable); /* Control CLK32K */
- const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
- const char *sdd_file; /* if NULL, will use default for detected hw type */
-};
-
-struct cw1200_platform_data_sdio {
- u16 ref_clk; /* REQUIRED (in KHz) */
-
- /* All others are optional */
- const struct resource *irq; /* if using GPIO for IRQ */
- bool have_5ghz;
- bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
- const struct resource *reset; /* GPIO to RSTn signal */
- const struct resource *powerup; /* GPIO to POWERUP signal */
- int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
- bool enable); /* Control 3v3 / 1v8 supply */
- int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
- bool enable); /* Control CLK32K */
- const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
- const char *sdd_file; /* if NULL, will use default for detected hw type */
-};
-
-const void *cw1200_get_platform_data(void);
-
-#endif /* CW1200_PLAT_H_INCLUDED */
diff --git a/include/linux/platform_data/cw1200_platform.h b/include/linux/platform_data/cw1200_platform.h
new file mode 100644
index 0000000..c168fa5
--- /dev/null
+++ b/include/linux/platform_data/cw1200_platform.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef CW1200_PLAT_H_INCLUDED
+#define CW1200_PLAT_H_INCLUDED
+
+struct cw1200_platform_data_spi {
+ u8 spi_bits_per_word; /* REQUIRED */
+ u16 ref_clk; /* REQUIRED (in KHz) */
+
+ /* All others are optional */
+ bool have_5ghz;
+ const struct resource *reset; /* GPIO to RSTn signal */
+ const struct resource *powerup; /* GPIO to POWERUP signal */
+ int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
+ bool enable); /* Control 3v3 / 1v8 supply */
+ int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata,
+ bool enable); /* Control CLK32K */
+ const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
+ const char *sdd_file; /* if NULL, will use default for detected hw type */
+};
+
+struct cw1200_platform_data_sdio {
+ u16 ref_clk; /* REQUIRED (in KHz) */
+
+ /* All others are optional */
+ const struct resource *irq; /* if using GPIO for IRQ */
+ bool have_5ghz;
+ bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
+ const struct resource *reset; /* GPIO to RSTn signal */
+ const struct resource *powerup; /* GPIO to POWERUP signal */
+ int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
+ bool enable); /* Control 3v3 / 1v8 supply */
+ int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
+ bool enable); /* Control CLK32K */
+ const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
+ const char *sdd_file; /* if NULL, will use default for detected hw type */
+};
+
+const void *cw1200_get_platform_data(void);
+
+#endif /* CW1200_PLAT_H_INCLUDED */
--
1.8.2.1
^ permalink raw reply related
* Re: [PATCH] cw1200: fix some obvious mistakes
From: Solomon Peachy @ 2013-06-02 13:27 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel, John W. Linville, Wei Yongjun, Dmitry Tarnyagin,
Ajitpal Singh, linux-wireless
In-Reply-To: <20130602122954.GA3875@shaftnet.org>
[-- Attachment #1: Type: text/plain, Size: 1181 bytes --]
On Sun, Jun 02, 2013 at 08:29:54AM -0400, Solomon Peachy wrote:
> > * Add comments about passing GPIO numbers in platform_data:
> > You should not use IORESOURCE_IO, which is for legacy ISA
> > I/O ports on PCs, not for GPIOs.
>
> Fair enough. The use of resources was something already in the driver
> when I inherited it, but I've seen this pattern a lot elsewhere. Is
> there a specific driver I should reference instead?
Reading linux/ioport.h I don't see a type that seems to be a better fit.
It's not MEM, REG, IRQ, DMA, or BUS. IO seems to be the only type that
fits.
The reason the driver uses struct resources instead of straight-up
numeric GPIO fields is for the 'name' field in the resources.
Given that the use of platform_data pretty much makes it impossible to
have more than one of these devices in a system at a time, there doesn't
seem to be a point to using named resources.
So I'll change these resource lists to using straight-up ints.
- Solomon
--
Solomon Peachy pizza at shaftnet dot org
Delray Beach, FL ^^ (email/xmpp) ^^
Quidquid latine dictum sit, altum viditur.
[-- Attachment #2: Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply
* Re: [PATCH] cw1200: fix some obvious mistakes
From: Solomon Peachy @ 2013-06-02 12:29 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-kernel, John W. Linville, Wei Yongjun, Dmitry Tarnyagin,
Ajitpal Singh, linux-wireless
In-Reply-To: <1370126241-2528420-1-git-send-email-arnd@arndb.de>
[-- Attachment #1: Type: text/plain, Size: 4974 bytes --]
On Sun, Jun 02, 2013 at 12:37:21AM +0200, Arnd Bergmann wrote:
> I got compile errors with the cw1200, which has lead me to take a
> closer look. It seems the driver still has a number of issues,
> and this addresses some of them and marks others as FIXME:
In short, NACK, at least not as posted.
The concerns are legitimate, but the time to object to such fundamental
stuff was at some point during the past *seven* rounds of patches I
posted over a period of nearly as many months.
Most of the objections you are raising are for deliberate
design/implementation decisions I made to deal with the realities of the
requirements of the cw1200 design and already-in-the-wild hardware that
this driver has to support.
> * The cw1200_sagrad.c file should not be there, hardcoding
> hardware configuration in .c files has been obsolete since
> Linux-2.4, so we should just remove it. Most of that file
> was already commented out since it does not compile.
The problem with the cw1200 is that you need certain information about
the hardware design in order to initialize it; this information has to
come from somewhere.
The Sagrad wifi devices are available in a standard SD form factor
reference design that plugs into a standard SDIO-supporing slot. The
cw1200_sagrad module is there to support these off-the-shelf devices.
Requiring users to recompile their kernel or update their devicetree
data for what amounts to an off-the-shelf hot-pluggable device is simply
not acceptable.
At the same time, if people plop the sagrad device directly on their
board (or independently do a chip-down design) they may need to make
changes to the platform data depending on how closely it tracks the
Sagrad reference design.
Further complicating things, there's no way to alter the SDIO
vendor/device IDs that the device reports in order to distingish between
any of this.
If you have a better suggestion on how to handle this set of conflicting
requirements then I'm all ears, but it's rather pointless to object to
code that's ugly because it has to support ugly hardware.
(That said, the commented-out bits in cw1200_sagrad are mostly there for
documentation purposes, and it could be moved to a proper documentation
file instead.)
> * Move the parts of cw1200_sagrad.c that actually got used into
> cw1200_sdio.c, because it doesn't build otherwise.
The idea was that either you build cw1200_sagrad or provide your own
platform_data. I separated all of the implemenation-specific code out
as cleanly as I could.
> * Make the platform_data for the sdio driver private to
> cw1200_sdio.c. The platform that was referenced here is
> going to use device tree based probing only in the future,
> which means the platform data has to go away anyway.
When you say "the platform" what are you referring to? SDIO? There's
no mention of any specific board (or even arch/subarch) in cw1200_sdio
or cw1200_sagrad.
In the real world, this driver will have to support non-devicetree
operation for as long as Linux does, and indeed longer, thanks to
compat-drivers/backports.
And for what it's worth, none of the platforms I have access to have
devicetree support since I'm stuck using vendor-supplied kernels.
> * Move the platform_data for the spi driver to
> include/linux/platform_data/net-cw1200.h where all other
> drivers have their platform_data.
Not all drivers, but fair enough.
> * Add comments about passing GPIO numbers in platform_data:
> You should not use IORESOURCE_IO, which is for legacy ISA
> I/O ports on PCs, not for GPIOs.
Fair enough. The use of resources was something already in the driver
when I inherited it, but I've seen this pattern a lot elsewhere. Is
there a specific driver I should reference instead?
> It may actually be easier to remove the sdio driver entirely,
> since it clearly doesn't work and requires a lot of cleanup.
Several hundred thousand in-the-field devices already deployed with this
driver clearly disagree with you.
I've personally tested this driver on six different hardware platforms,
using mainline kernels for some and vendor-supplied kernels for others.
With module-down and SD-slot designs. Others have tested other
platforms. Every configurable option and line item in both the SPI and
SDIO platform data is there because it needs to be in order to support
the variety of hardware designs already in the wild.
This driver will also be part of the compat-drivers/backports project,
and as such has to work within that framework as well.
If you have constructive suggestions on how to handle this set of
requirements in a cleaner manner, I'm all ears.
- Solomon
--
Solomon Peachy pizza at shaftnet dot org
Delray Beach, FL ^^ (email/xmpp) ^^
Quidquid latine dictum sit, altum viditur.
[-- Attachment #2: Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply
* [PATCH] cw1200: fix some obvious mistakes
From: Arnd Bergmann @ 2013-06-01 22:37 UTC (permalink / raw)
To: linux-kernel
Cc: Arnd Bergmann, Solomon Peachy, John W. Linville, Wei Yongjun,
Dmitry Tarnyagin, Ajitpal Singh, linux-wireless
I got compile errors with the cw1200, which has lead me to take a
closer look. It seems the driver still has a number of issues,
and this addresses some of them and marks others as FIXME:
* The cw1200_sagrad.c file should not be there, hardcoding
hardware configuration in .c files has been obsolete since
Linux-2.4, so we should just remove it. Most of that file
was already commented out since it does not compile.
* Move the parts of cw1200_sagrad.c that actually got used into
cw1200_sdio.c, because it doesn't build otherwise.
* Make the platform_data for the sdio driver private to
cw1200_sdio.c. The platform that was referenced here is
going to use device tree based probing only in the future,
which means the platform data has to go away anyway.
* Move the platform_data for the spi driver to
include/linux/platform_data/net-cw1200.h where all other
drivers have their platform_data.
* Add comments about passing GPIO numbers in platform_data:
You should not use IORESOURCE_IO, which is for legacy ISA
I/O ports on PCs, not for GPIOs.
It may actually be easier to remove the sdio driver entirely,
since it clearly doesn't work and requires a lot of cleanup.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Solomon Peachy <pizza@shaftnet.org>
Cc: John W. Linville <linville@tuxdriver.com>
Cc: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Cc: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
Cc: Ajitpal Singh <ajitpal.singh@stericsson.com>
Cc: linux-wireless@vger.kernel.org
---
drivers/net/wireless/cw1200/Kconfig | 8 --
drivers/net/wireless/cw1200/Makefile | 2 -
drivers/net/wireless/cw1200/cw1200_sagrad.c | 145 ---------------------
drivers/net/wireless/cw1200/cw1200_sdio.c | 72 ++++++++--
drivers/net/wireless/cw1200/cw1200_spi.c | 2 +-
.../net-cw1200.h} | 20 +--
6 files changed, 62 insertions(+), 187 deletions(-)
delete mode 100644 drivers/net/wireless/cw1200/cw1200_sagrad.c
rename include/linux/{cw1200_platform.h => platform_data/net-cw1200.h} (53%)
diff --git a/drivers/net/wireless/cw1200/Kconfig b/drivers/net/wireless/cw1200/Kconfig
index 13e3611..c3142d4 100644
--- a/drivers/net/wireless/cw1200/Kconfig
+++ b/drivers/net/wireless/cw1200/Kconfig
@@ -20,14 +20,6 @@ config CW1200_WLAN_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
diff --git a/drivers/net/wireless/cw1200/Makefile b/drivers/net/wireless/cw1200/Makefile
index 1aa3682..bc6cbf9 100644
--- a/drivers/net/wireless/cw1200/Makefile
+++ b/drivers/net/wireless/cw1200/Makefile
@@ -16,9 +16,7 @@ cw1200_core-$(CONFIG_PM) += pm.o
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/cw1200_sagrad.c b/drivers/net/wireless/cw1200/cw1200_sagrad.c
deleted file mode 100644
index a5ada0e..0000000
--- a/drivers/net/wireless/cw1200/cw1200_sagrad.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Platform glue data for ST-Ericsson CW1200 driver
- *
- * Copyright (c) 2013, Sagrad, Inc
- * Author: Solomon Peachy <speachy@sagrad.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/cw1200_platform.h>
-
-MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
-MODULE_DESCRIPTION("ST-Ericsson CW1200 Platform glue driver");
-MODULE_LICENSE("GPL");
-
-/* Define just one of these. Feel free to customize as needed */
-#define SAGRAD_1091_1098_EVK_SDIO
-/* #define SAGRAD_1091_1098_EVK_SPI */
-
-#ifdef SAGRAD_1091_1098_EVK_SDIO
-#if 0
-static struct resource cw1200_href_resources[] = {
- {
- .start = 215, /* fix me as appropriate */
- .end = 215, /* ditto */
- .flags = IORESOURCE_IO,
- .name = "cw1200_wlan_reset",
- },
- {
- .start = 216, /* fix me as appropriate */
- .end = 216, /* ditto */
- .flags = IORESOURCE_IO,
- .name = "cw1200_wlan_powerup",
- },
- {
- .start = NOMADIK_GPIO_TO_IRQ(216), /* fix me as appropriate */
- .end = NOMADIK_GPIO_TO_IRQ(216), /* ditto */
- .flags = IORESOURCE_IRQ,
- .name = "cw1200_wlan_irq",
- },
-};
-#endif
-
-static int cw1200_power_ctrl(const struct cw1200_platform_data_sdio *pdata,
- bool enable)
-{
- /* Control 3v3 and 1v8 to hardware as appropriate */
- /* Note this is not needed if it's controlled elsewhere or always on */
-
- /* May require delay for power to stabilize */
- return 0;
-}
-
-static int cw1200_clk_ctrl(const struct cw1200_platform_data_sdio *pdata,
- bool enable)
-{
- /* Turn CLK_32K off and on as appropriate. */
- /* Note this is not needed if it's always on */
-
- /* May require delay for clock to stabilize */
- return 0;
-}
-
-static struct cw1200_platform_data_sdio cw1200_platform_data = {
- .ref_clk = 38400,
- .have_5ghz = false,
-#if 0
- .reset = &cw1200_href_resources[0],
- .powerup = &cw1200_href_resources[1],
- .irq = &cw1200_href_resources[2],
-#endif
- .power_ctrl = cw1200_power_ctrl,
- .clk_ctrl = cw1200_clk_ctrl,
-/* .macaddr = ??? */
- .sdd_file = "sdd_sagrad_1091_1098.bin",
-};
-#endif
-
-#ifdef SAGRAD_1091_1098_EVK_SPI
-/* Note that this is an example of integrating into your board support file */
-static struct resource cw1200_href_resources[] = {
- {
- .start = GPIO_RF_RESET,
- .end = GPIO_RF_RESET,
- .flags = IORESOURCE_IO,
- .name = "cw1200_wlan_reset",
- },
- {
- .start = GPIO_RF_POWERUP,
- .end = GPIO_RF_POWERUP,
- .flags = IORESOURCE_IO,
- .name = "cw1200_wlan_powerup",
- },
-};
-
-static int cw1200_power_ctrl(const struct cw1200_platform_data_spi *pdata,
- bool enable)
-{
- /* Control 3v3 and 1v8 to hardware as appropriate */
- /* Note this is not needed if it's controlled elsewhere or always on */
-
- /* May require delay for power to stabilize */
- return 0;
-}
-static int cw1200_clk_ctrl(const struct cw1200_platform_data_spi *pdata,
- bool enable)
-{
- /* Turn CLK_32K off and on as appropriate. */
- /* Note this is not needed if it's always on */
-
- /* May require delay for clock to stabilize */
- return 0;
-}
-
-static struct cw1200_platform_data_spi cw1200_platform_data = {
- .ref_clk = 38400,
- .spi_bits_per_word = 16,
- .reset = &cw1200_href_resources[0],
- .powerup = &cw1200_href_resources[1],
- .power_ctrl = cw1200_power_ctrl,
- .clk_ctrl = cw1200_clk_ctrl,
-/* .macaddr = ??? */
- .sdd_file = "sdd_sagrad_1091_1098.bin",
-};
-static struct spi_board_info myboard_spi_devices[] __initdata = {
- {
- .modalias = "cw1200_wlan_spi",
- .max_speed_hz = 10000000, /* 52MHz Max */
- .bus_num = 0,
- .irq = WIFI_IRQ,
- .platform_data = &cw1200_platform_data,
- .chip_select = 0,
- },
-};
-#endif
-
-
-const void *cw1200_get_platform_data(void)
-{
- return &cw1200_platform_data;
-}
-EXPORT_SYMBOL_GPL(cw1200_get_platform_data);
diff --git a/drivers/net/wireless/cw1200/cw1200_sdio.c b/drivers/net/wireless/cw1200/cw1200_sdio.c
index 863510d..721e392 100644
--- a/drivers/net/wireless/cw1200/cw1200_sdio.c
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -20,7 +20,6 @@
#include "cw1200.h"
#include "sbus.h"
-#include <linux/cw1200_platform.h>
#include "hwio.h"
MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
@@ -29,6 +28,27 @@ MODULE_LICENSE("GPL");
#define SDIO_BLOCK_SIZE (512)
+/* FIXME: include this into sbus_priv */
+struct cw1200_platform_data_sdio {
+ u16 ref_clk; /* REQUIRED (in KHz) */
+
+ /* All others are optional */
+ /* FIXME: just do gpio_to_irq */
+ const struct resource *irq; /* if using GPIO for IRQ */
+ bool have_5ghz;
+ bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
+ /* FIXME: GPIO numbers are not resources */
+ const struct resource *reset; /* GPIO to RSTn signal */
+ const struct resource *powerup; /* GPIO to POWERUP signal */
+ int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
+ bool enable); /* Control 3v3 / 1v8 supply */
+ int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
+ bool enable); /* Control CLK32K */
+ /* FIXME: us of_get_mac_address */
+ const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
+ const char *sdd_file; /* if NULL, will use default for detected hw type */
+};
+
struct sbus_priv {
struct sdio_func *func;
struct cw1200_common *core;
@@ -265,6 +285,38 @@ static struct sbus_ops cw1200_sdio_sbus_ops = {
.power_mgmt = cw1200_sdio_pm,
};
+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;
+}
+
+/*
+ * FIXME: These are just defaults, the driver needs a proper DT binding
+ * to extract the other values and override these if necessary
+ */
+static struct cw1200_platform_data_sdio cw1200_platform_data = {
+ .ref_clk = 38400,
+ .have_5ghz = false,
+ .power_ctrl = cw1200_power_ctrl,
+ .clk_ctrl = cw1200_clk_ctrl,
+ .sdd_file = "sdd_sagrad_1091_1098.bin",
+};
+
/* 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)
@@ -286,7 +338,8 @@ static int cw1200_sdio_probe(struct sdio_func *func,
func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
- self->pdata = cw1200_get_platform_data();
+ /* FIXME: get this from DT */
+ self->pdata = &cw1200_platform_data;
self->func = func;
sdio_set_drvdata(func, self);
sdio_claim_host(func);
@@ -377,13 +430,11 @@ static struct sdio_driver sdio_driver = {
/* Init Module function -> Called by insmod */
static int __init cw1200_sdio_init(void)
{
- const struct cw1200_platform_data_sdio *pdata;
int ret;
- pdata = cw1200_get_platform_data();
-
- if (cw1200_sdio_on(pdata)) {
- ret = -1;
+ /* FIXME: must not touch hardware until we know the hardware is present */
+ if (cw1200_sdio_on(&cw1200_platform_data)) {
+ ret = -ENODEV;
goto err;
}
@@ -394,19 +445,16 @@ static int __init cw1200_sdio_init(void)
return 0;
err:
- cw1200_sdio_off(pdata);
+ cw1200_sdio_off(&cw1200_platform_data);
return ret;
}
/* Called at Driver Unloading */
static void __exit cw1200_sdio_exit(void)
{
- const struct cw1200_platform_data_sdio *pdata;
- pdata = cw1200_get_platform_data();
sdio_unregister_driver(&sdio_driver);
- cw1200_sdio_off(pdata);
+ cw1200_sdio_off(&cw1200_platform_data);
}
-
module_init(cw1200_sdio_init);
module_exit(cw1200_sdio_exit);
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index 75adef0..ef05916 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -25,7 +25,7 @@
#include "cw1200.h"
#include "sbus.h"
-#include <linux/cw1200_platform.h>
+#include <linux/platform_data/net-cw1200.h>
#include "hwio.h"
MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
diff --git a/include/linux/cw1200_platform.h b/include/linux/platform_data/net-cw1200.h
similarity index 53%
rename from include/linux/cw1200_platform.h
rename to include/linux/platform_data/net-cw1200.h
index c168fa5..8f006ac 100644
--- a/include/linux/cw1200_platform.h
+++ b/include/linux/platform_data/net-cw1200.h
@@ -14,6 +14,7 @@ struct cw1200_platform_data_spi {
/* All others are optional */
bool have_5ghz;
+ /* FIXME: use simple numbers rather than resources for GPIO */
const struct resource *reset; /* GPIO to RSTn signal */
const struct resource *powerup; /* GPIO to POWERUP signal */
int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
@@ -24,23 +25,4 @@ struct cw1200_platform_data_spi {
const char *sdd_file; /* if NULL, will use default for detected hw type */
};
-struct cw1200_platform_data_sdio {
- u16 ref_clk; /* REQUIRED (in KHz) */
-
- /* All others are optional */
- const struct resource *irq; /* if using GPIO for IRQ */
- bool have_5ghz;
- bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
- const struct resource *reset; /* GPIO to RSTn signal */
- const struct resource *powerup; /* GPIO to POWERUP signal */
- int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
- bool enable); /* Control 3v3 / 1v8 supply */
- int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
- bool enable); /* Control CLK32K */
- const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
- const char *sdd_file; /* if NULL, will use default for detected hw type */
-};
-
-const void *cw1200_get_platform_data(void);
-
#endif /* CW1200_PLAT_H_INCLUDED */
--
1.8.1.2
^ permalink raw reply related
* Re: BK, VI, VO tx queue stopped unexpectedly
From: Johannes Berg @ 2013-06-01 21:47 UTC (permalink / raw)
To: Huawei Yang; +Cc: linux-wireless
In-Reply-To: <20130601110149.GA6504@gmail.com>
On Sat, 2013-06-01 at 19:01 +0800, Huawei Yang wrote:
> Hi guys
>
> I am writing a nl80211/cfg80211 driver for my wifi chip. I am testing
> my chip under the AP mode with hostapd. I use the kernel 3.0. I start
> the AP and check that all four tx queues are start, then I start a udp
> stream of BE from Ap to the station. After that I find other three tx
> queues stopped. I am sure that my driver dose not stop them. Is this a
> kernel machinesm ?
No mac80211? In that case, it has to be your driver ... if the queues
are really stopped. Or maybe you just leaked the frames and messed up
completely that way...
johannes
^ permalink raw reply
* Re: [PATCH] cfg80211: fix deadlock in cfg80211_leave_mesh()
From: Bob Copeland @ 2013-06-01 21:30 UTC (permalink / raw)
To: Thomas Pedersen; +Cc: Johannes Berg, linux-wireless, open11s
In-Reply-To: <CAG6hwVNZ4oDGsZTLO0gqQ2eWV-C7rxQZ2F=PiR9-URc44FxgKw@mail.gmail.com>
On Sat, Jun 01, 2013 at 01:53:35PM -0700, Thomas Pedersen wrote:
> wdev->mtx is already held). But it does look weird for cfg80211 to
> drop a lock on behalf of the driver.
This did cross my mind, but I thought maybe it made sense to do
it there to make it easier to reason about the code -- if dropped
in mac80211, someone reading the code would have no idea.
--
Bob Copeland %% www.bobcopeland.com
^ permalink raw reply
* Re: [PATCH] cfg80211: fix deadlock in cfg80211_leave_mesh()
From: Thomas Pedersen @ 2013-06-01 20:53 UTC (permalink / raw)
To: Bob Copeland; +Cc: Johannes Berg, linux-wireless, open11s
In-Reply-To: <20130601131916.GA2484@localhost>
On Sat, Jun 1, 2013 at 6:19 AM, Bob Copeland <me@bobcopeland.com> wrote:
> As of "cfg80211/mac80211: use cfg80211 wdev mutex in mac80211",
> mac80211 expects to be able to take the wdev mutex around sdata
> accesses. This causes a recursive deadlock since
> __cfg80211_leave_mesh() already holds the wdev mutex. Removing
> the sdata_lock() calls in ieee80211_stop_mesh() alone won't fix
> this, as the cancel_work_sync() in mesh runs the iface work,
> and various work items also want to take the wdev lock (not
> just in mesh, see e.g. ieee80211_sta_rx_queued_mgmt().)
>
> We don't seem to need the wdev lock held over rdev_leave_mesh()
> anyway, so drop it before calling.
>
> Fixes:
> [ 75.571222] =============================================
> [ 75.571222] [ INFO: possible recursive locking detected ]
> [ 75.571222] 3.10.0-rc1-a8cd57b+ #113 Not tainted
> [ 75.571222] ---------------------------------------------
> [ 75.571222] iw/2597 is trying to acquire lock:
> [ 75.571222] (&wdev->mtx){+.+.+.}, at: [<ffffffffa0115180>] ieee80211_stop_mesh+0x60/0x160 [mac80211]
> [ 75.571222]
> [ 75.571222] but task is already holding lock:
> [ 75.571222] (&wdev->mtx){+.+.+.}, at: [<ffffffffa0035fa5>] cfg80211_leave_mesh+0x35/0x370 [cfg80211]
> [ 75.571222]
> [ 75.571222] other info that might help us debug this:
> [ 75.571222] Possible unsafe locking scenario:
> [ 75.571222]
> [ 75.571222] CPU0
> [ 75.571222] ----
> [ 75.571222] lock(&wdev->mtx);
> [ 75.571222] lock(&wdev->mtx);
> [ 75.571222]
> [ 75.571222] *** DEADLOCK ***
> [ 75.571222]
> [ 75.571222] May be due to missing lock nesting notation
> [ 75.571222]
> [ 75.571222] 4 locks held by iw/2597:
> [ 75.571222] #0: (cb_lock){++++++}, at: [<ffffffff8165a4cd>] genl_rcv+0x1d/0x40
> [ 75.571222] #1: (genl_mutex){+.+.+.}, at: [<ffffffff8165a997>] genl_lock+0x17/0x20
> [ 75.571222] #2: (rtnl_mutex){+.+.+.}, at: [<ffffffff81638e47>] rtnl_lock+0x17/0x20
> [ 75.571222] #3: (&wdev->mtx){+.+.+.}, at: [<ffffffffa0035fa5>] cfg80211_leave_mesh+0x35/0x370 [cfg80211]
> [ 75.571222]
> [ 75.571222] stack backtrace:
> [ 75.571222] CPU: 1 PID: 2597 Comm: iw Not tainted 3.10.0-rc1-a8cd57b+ #113
> [ 75.571222] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007
> [ 75.571222] ffffffff82155790 ffff8800035c5768 ffffffff817b8335 ffff8800035c5868
> [ 75.571222] ffffffff810a3da2 0000000000000000 0000000000000000 0000000000000002
> [ 75.571222] 0000000000000046 00000000035c5818 ffffffff82155790 ffff8800057e2360
> [ 75.571222] Call Trace:
> [ 75.571222] [<ffffffff817b8335>] dump_stack+0x19/0x1b
> [ 75.571222] [<ffffffff810a3da2>] __lock_acquire+0xba2/0x1d30
> [ 75.571222] [<ffffffff817c0bed>] ? _raw_spin_unlock_irqrestore+0x4d/0x70
> [ 75.571222] [<ffffffff810a615d>] ? trace_hardirqs_on_caller+0x16d/0x200
> [ 75.571222] [<ffffffff810a568a>] lock_acquire+0x17a/0x200
> [ 75.571222] [<ffffffffa0115180>] ? ieee80211_stop_mesh+0x60/0x160 [mac80211]
> [ 75.571222] [<ffffffff817bd4fe>] mutex_lock_nested+0x6e/0x380
> [ 75.571222] [<ffffffffa0115180>] ? ieee80211_stop_mesh+0x60/0x160 [mac80211]
> [ 75.571222] [<ffffffffa00b26b2>] ? ieee80211_bss_info_change_notify+0x202/0x3d0 [mac80211]
> [ 75.571222] [<ffffffffa0115180>] ieee80211_stop_mesh+0x60/0x160 [mac80211]
> [ 75.571222] [<ffffffffa00d195d>] ieee80211_leave_mesh+0x1d/0x30 [mac80211]
> [ 75.571222] [<ffffffffa00360f8>] cfg80211_leave_mesh+0x188/0x370 [cfg80211]
> [ 75.571222] [<ffffffffa000dfb9>] nl80211_leave_mesh+0x19/0x20 [cfg80211]
> [ 75.571222] [<ffffffff8165a756>] genl_family_rcv_msg+0x266/0x2e0
> [ 75.571222] [<ffffffff8165a9a0>] ? genl_lock+0x20/0x20
> [ 75.571222] [<ffffffff8165aa2e>] genl_rcv_msg+0x8e/0xc0
> [ 75.571222] [<ffffffff8165a1ce>] netlink_rcv_skb+0x6e/0xd0
> [ 75.571222] [<ffffffff8165a4cd>] ? genl_rcv+0x1d/0x40
> [ 75.571222] [<ffffffff8165a4dc>] genl_rcv+0x2c/0x40
> [ 75.571222] [<ffffffff81659b6a>] netlink_unicast+0x11a/0x1f0
> [ 75.571222] [<ffffffff812a11b5>] ? sock_has_perm+0x5/0x1f0
> [ 75.571222] [<ffffffff81659f4d>] netlink_sendmsg+0x30d/0x360
> [ 75.571222] [<ffffffff8160f196>] sock_sendmsg+0xa6/0xd0
> [ 75.571222] [<ffffffff810a4fde>] ? lock_release_non_nested+0xae/0x2e0
> [ 75.571222] [<ffffffff8160f529>] __sys_sendmsg+0x369/0x390
> [ 75.571222] [<ffffffff81071723>] ? up_read+0x23/0x40
> [ 75.571222] [<ffffffff817c4e64>] ? __do_page_fault+0x4b4/0x570
> [ 75.571222] [<ffffffff8117d27d>] ? dput+0x13d/0x1d0
> [ 75.571222] [<ffffffff81184c6c>] ? fget_light+0x12c/0x430
> [ 75.571222] [<ffffffff8161084d>] SyS_sendmsg+0x4d/0x80
> [ 75.571222] [<ffffffff817c9e02>] system_call_fastpath+0x16/0x1b
>
> Signed-off-by: Bob Copeland <me@bobcopeland.com>
>
> ---
> I don't like dropping locks, but I can't see any races added by
> this -- join/leave are already serialized by rtnl and I didn't see
> leave_mesh using the wdev fields in a way that would matter -- but
> let me know if I missed something. We could also split out the
> cancel_work_sync into a separate (unlocked) op but this approach
> seems simpler. Thoughts?
>
> net/wireless/mesh.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
> index 5dfb289..6344a81 100644
> --- a/net/wireless/mesh.c
> +++ b/net/wireless/mesh.c
> @@ -250,7 +250,9 @@ static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
> if (!wdev->mesh_id_len)
> return -ENOTCONN;
>
> + wdev_unlock(wdev);
> err = rdev_leave_mesh(rdev, dev);
> + wdev_lock(wdev);
Since the sdata_lock() will be taken later, I don't think there should
be any races here. Other calls to mbss_info_change_notify() either
take the lock from the mac80211 workqueue or not at all (since
wdev->mtx is already held). But it does look weird for cfg80211 to
drop a lock on behalf of the driver. I'm also a little worried this
special case will make it harder to predict future deadlocks in the
mesh code. Maybe we should punt the beacon update to the workqueue? :)
--
Thomas
^ permalink raw reply
* Re: Intel Centrino Advanced N 6200 and Debian 7
From: Marc Marí @ 2013-06-01 19:57 UTC (permalink / raw)
To: Arend van Spriel; +Cc: linux-wireless
In-Reply-To: <51AA4A7A.3010101@broadcom.com>
I had (and I have it somewhere) a Broadcom 43227 card. When I was
using Debian 6 (I used it for a long time, then I wanted to change,
and I changed to Fedora, but now I'll go back to Debian), I had to
download and compile the drivers from Broadcom page, because neither
wl or b43 drivers made the card work.
Regards
Marc
2013/6/1 Arend van Spriel <arend@broadcom.com>:
> On 06/01/2013 07:57 PM, Marc Marí wrote:
>>
>> Hello everyone
>>
>> I recently changed my wireless card from a Broadcom (very bad
>> supported) to a Intel Centrino Advanced N 6200. In Fedora, it works
>> well, but I prefer Debian, and I'll change again, but in a Debian 7
>> live CD (I need my laptop, so I can't stay several days with a half
>> installation) the wifi doesn't work (kernel 3.2.0-4). This is the
>> error
>
>
> What Broadcom wireless card did you have?
>
> Regards,
> Arend
>
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox