* [PATCH 06/10] mac80211: minstrel: reduce MINSTREL_SCALE
From: Felix Fietkau @ 2016-12-14 19:46 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, thomas.huehn
In-Reply-To: <20161214194703.33429-1-nbd@nbd.name>
The loss of a bit of extra precision does not hurt the calculation, 12
bits is still enough to calculate probabilities well. Reducing the scale
makes it easier to avoid overflows
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/rc80211_minstrel.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 94b89b1..03716fd 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -14,7 +14,7 @@
#define SAMPLE_COLUMNS 10 /* number of columns in sample table */
/* scaled fraction values */
-#define MINSTREL_SCALE 16
+#define MINSTREL_SCALE 12
#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
--
2.10.1
^ permalink raw reply related
* [PATCH 09/10] mac80211: minstrel_ht: remove obsolete #if for >= 3 streams
From: Felix Fietkau @ 2016-12-14 19:47 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, thomas.huehn
In-Reply-To: <20161214194703.33429-1-nbd@nbd.name>
This was added during early development when 3x3 hardware was not very
common yet. This is completely unnecessary now.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/rc80211_minstrel_ht.c | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index ae45dcb..8e783e1 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -155,67 +155,47 @@ MODULE_PARM_DESC(minstrel_vht_only,
const struct mcs_group minstrel_mcs_groups[] = {
MCS_GROUP(1, 0, BW_20),
MCS_GROUP(2, 0, BW_20),
-#if MINSTREL_MAX_STREAMS >= 3
MCS_GROUP(3, 0, BW_20),
-#endif
MCS_GROUP(1, 1, BW_20),
MCS_GROUP(2, 1, BW_20),
-#if MINSTREL_MAX_STREAMS >= 3
MCS_GROUP(3, 1, BW_20),
-#endif
MCS_GROUP(1, 0, BW_40),
MCS_GROUP(2, 0, BW_40),
-#if MINSTREL_MAX_STREAMS >= 3
MCS_GROUP(3, 0, BW_40),
-#endif
MCS_GROUP(1, 1, BW_40),
MCS_GROUP(2, 1, BW_40),
-#if MINSTREL_MAX_STREAMS >= 3
MCS_GROUP(3, 1, BW_40),
-#endif
CCK_GROUP,
#ifdef CONFIG_MAC80211_RC_MINSTREL_VHT
VHT_GROUP(1, 0, BW_20),
VHT_GROUP(2, 0, BW_20),
-#if MINSTREL_MAX_STREAMS >= 3
VHT_GROUP(3, 0, BW_20),
-#endif
VHT_GROUP(1, 1, BW_20),
VHT_GROUP(2, 1, BW_20),
-#if MINSTREL_MAX_STREAMS >= 3
VHT_GROUP(3, 1, BW_20),
-#endif
VHT_GROUP(1, 0, BW_40),
VHT_GROUP(2, 0, BW_40),
-#if MINSTREL_MAX_STREAMS >= 3
VHT_GROUP(3, 0, BW_40),
-#endif
VHT_GROUP(1, 1, BW_40),
VHT_GROUP(2, 1, BW_40),
-#if MINSTREL_MAX_STREAMS >= 3
VHT_GROUP(3, 1, BW_40),
-#endif
VHT_GROUP(1, 0, BW_80),
VHT_GROUP(2, 0, BW_80),
-#if MINSTREL_MAX_STREAMS >= 3
VHT_GROUP(3, 0, BW_80),
-#endif
VHT_GROUP(1, 1, BW_80),
VHT_GROUP(2, 1, BW_80),
-#if MINSTREL_MAX_STREAMS >= 3
VHT_GROUP(3, 1, BW_80),
#endif
-#endif
};
static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
--
2.10.1
^ permalink raw reply related
* [PATCH 08/10] mac80211: minstrel: make prob_ewma u16 instead of u32
From: Felix Fietkau @ 2016-12-14 19:47 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, thomas.huehn
In-Reply-To: <20161214194703.33429-1-nbd@nbd.name>
Saves about 1.2 KiB memory per station
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/rc80211_minstrel.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index ea86e67..be6c3f3 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -59,7 +59,7 @@ struct minstrel_rate_stats {
/* statistis of packet delivery probability
* prob_ewma - exponential weighted moving average of prob
* prob_ewmsd - exp. weighted moving standard deviation of prob */
- unsigned int prob_ewma;
+ u16 prob_ewma;
u16 prob_ewmv;
/* maximum retry counts */
--
2.10.1
^ permalink raw reply related
* [PATCH 10/10] mac80211: minstrel: avoid port control frames for sampling
From: Felix Fietkau @ 2016-12-14 19:47 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, thomas.huehn
In-Reply-To: <20161214194703.33429-1-nbd@nbd.name>
From: Thomas Huehn <thomas.huehn@evernet-eg.de>
Makes connections more reliable
Signed-off-by: Thomas Huehn <thomas.huehn@evernet-eg.de>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/rc80211_minstrel.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 11a4cc3..3ebe440 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -367,6 +367,11 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
return;
#endif
+ /* Don't use EAPOL frames for sampling on non-mrr hw */
+ if (mp->hw->max_rates == 1 &&
+ (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO))
+ return;
+
delta = (mi->total_packets * sampling_ratio / 100) -
(mi->sample_packets + mi->sample_deferred / 2);
--
2.10.1
^ permalink raw reply related
* [PATCH 07/10] mac80211: minstrel: store probability variance instead of standard deviation
From: Felix Fietkau @ 2016-12-14 19:47 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, thomas.huehn
In-Reply-To: <20161214194703.33429-1-nbd@nbd.name>
This avoids the costly int_sqrt calls in the statistics update and moves
it to the debugfs code instead.
This also fixes an overflow in the previous standard deviation
calculation.
Signed-off-by: Thomas Huehn <thomas.huehn@evernet-eg.de>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/rc80211_minstrel.c | 8 ++++----
net/mac80211/rc80211_minstrel.h | 25 ++++++++++++++-----------
net/mac80211/rc80211_minstrel_debugfs.c | 8 ++++++--
net/mac80211/rc80211_minstrel_ht_debugfs.c | 8 ++++++--
4 files changed, 30 insertions(+), 19 deletions(-)
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index a284ea0..11a4cc3 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -168,10 +168,10 @@ minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
mrs->prob_ewma = cur_prob;
} else {
/* update exponential weighted moving variance */
- mrs->prob_ewmsd = minstrel_ewmsd(mrs->prob_ewmsd,
- cur_prob,
- mrs->prob_ewma,
- EWMA_LEVEL);
+ mrs->prob_ewmv = minstrel_ewmv(mrs->prob_ewmv,
+ cur_prob,
+ mrs->prob_ewma,
+ EWMA_LEVEL);
/*update exponential weighted moving avarage */
mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 03716fd..ea86e67 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -36,21 +36,16 @@ minstrel_ewma(int old, int new, int weight)
}
/*
- * Perform EWMSD (Exponentially Weighted Moving Standard Deviation) calculation
+ * Perform EWMV (Exponentially Weighted Moving Variance) calculation
*/
static inline int
-minstrel_ewmsd(int old_ewmsd, int cur_prob, int prob_ewma, int weight)
+minstrel_ewmv(int old_ewmv, int cur_prob, int prob_ewma, int weight)
{
- int diff, incr, tmp_var;
+ int diff, incr;
- /* calculate exponential weighted moving variance */
- diff = MINSTREL_TRUNC((cur_prob - prob_ewma) * 1000000);
+ diff = cur_prob - prob_ewma;
incr = (EWMA_DIV - weight) * diff / EWMA_DIV;
- tmp_var = old_ewmsd * old_ewmsd;
- tmp_var = weight * (tmp_var + diff * incr / 1000000) / EWMA_DIV;
-
- /* return standard deviation */
- return (u16) int_sqrt(tmp_var);
+ return weight * (old_ewmv + MINSTREL_TRUNC(diff * incr)) / EWMA_DIV;
}
struct minstrel_rate_stats {
@@ -65,7 +60,7 @@ struct minstrel_rate_stats {
* prob_ewma - exponential weighted moving average of prob
* prob_ewmsd - exp. weighted moving standard deviation of prob */
unsigned int prob_ewma;
- u16 prob_ewmsd;
+ u16 prob_ewmv;
/* maximum retry counts */
u8 retry_count;
@@ -151,6 +146,14 @@ struct minstrel_debugfs_info {
char buf[];
};
+/* Get EWMSD (Exponentially Weighted Moving Standard Deviation) * 10 */
+static inline int
+minstrel_get_ewmsd10(struct minstrel_rate_stats *mrs)
+{
+ unsigned int ewmv = mrs->prob_ewmv;
+ return int_sqrt(MINSTREL_TRUNC(ewmv * 1000 * 1000));
+}
+
extern const struct rate_control_ops mac80211_minstrel;
void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
void minstrel_remove_sta_debugfs(void *priv, void *priv_sta);
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
index ca0bafd..36fc971 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -93,6 +93,7 @@ minstrel_stats_open(struct inode *inode, struct file *file)
for (i = 0; i < mi->n_rates; i++) {
struct minstrel_rate *mr = &mi->r[i];
struct minstrel_rate_stats *mrs = &mi->r[i].stats;
+ unsigned int prob_ewmsd;
*(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' ';
*(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' ';
@@ -108,6 +109,7 @@ minstrel_stats_open(struct inode *inode, struct file *file)
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
+ prob_ewmsd = minstrel_get_ewmsd10(mrs);
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u"
" %3u %3u %-3u "
@@ -115,7 +117,7 @@ minstrel_stats_open(struct inode *inode, struct file *file)
tp_max / 10, tp_max % 10,
tp_avg / 10, tp_avg % 10,
eprob / 10, eprob % 10,
- mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
+ prob_ewmsd / 10, prob_ewmsd % 10,
mrs->retry_count,
mrs->last_success,
mrs->last_attempts,
@@ -159,6 +161,7 @@ minstrel_stats_csv_open(struct inode *inode, struct file *file)
for (i = 0; i < mi->n_rates; i++) {
struct minstrel_rate *mr = &mi->r[i];
struct minstrel_rate_stats *mrs = &mi->r[i].stats;
+ unsigned int prob_ewmsd;
p += sprintf(p, "%s" ,((i == mi->max_tp_rate[0]) ? "A" : ""));
p += sprintf(p, "%s" ,((i == mi->max_tp_rate[1]) ? "B" : ""));
@@ -174,13 +177,14 @@ minstrel_stats_csv_open(struct inode *inode, struct file *file)
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
+ prob_ewmsd = minstrel_get_ewmsd10(mrs);
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u,"
"%llu,%llu,%d,%d\n",
tp_max / 10, tp_max % 10,
tp_avg / 10, tp_avg % 10,
eprob / 10, eprob % 10,
- mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
+ prob_ewmsd / 10, prob_ewmsd % 10,
mrs->retry_count,
mrs->last_success,
mrs->last_attempts,
diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c
index 0cecd23..7d969e3 100644
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
@@ -41,6 +41,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
static const int bitrates[4] = { 10, 20, 55, 110 };
int idx = i * MCS_GROUP_RATES + j;
+ unsigned int prob_ewmsd;
if (!(mi->supported[i] & BIT(j)))
continue;
@@ -84,6 +85,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
+ prob_ewmsd = minstrel_get_ewmsd10(mrs);
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u"
" %3u %3u %-3u "
@@ -91,7 +93,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
tp_max / 10, tp_max % 10,
tp_avg / 10, tp_avg % 10,
eprob / 10, eprob % 10,
- mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
+ prob_ewmsd / 10, prob_ewmsd % 10,
mrs->retry_count,
mrs->last_success,
mrs->last_attempts,
@@ -185,6 +187,7 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
static const int bitrates[4] = { 10, 20, 55, 110 };
int idx = i * MCS_GROUP_RATES + j;
+ unsigned int prob_ewmsd;
if (!(mi->supported[i] & BIT(j)))
continue;
@@ -225,13 +228,14 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
+ prob_ewmsd = minstrel_get_ewmsd10(mrs);
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,"
"%u,%llu,%llu,",
tp_max / 10, tp_max % 10,
tp_avg / 10, tp_avg % 10,
eprob / 10, eprob % 10,
- mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
+ prob_ewmsd / 10, prob_ewmsd % 10,
mrs->retry_count,
mrs->last_success,
mrs->last_attempts,
--
2.10.1
^ permalink raw reply related
* [PATCH 04/10] mac80211: check for MCS in ieee80211_duration before fetching chanctx
From: Felix Fietkau @ 2016-12-14 19:46 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, thomas.huehn
In-Reply-To: <20161214194703.33429-1-nbd@nbd.name>
Makes the code a bit more efficient
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/tx.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 058652d..4dea18b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -64,6 +64,10 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
struct ieee80211_chanctx_conf *chanctx_conf;
u32 rate_flags = 0;
+ /* assume HW handles this */
+ if (tx->rate.flags & (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))
+ return 0;
+
rcu_read_lock();
chanctx_conf = rcu_dereference(tx->sdata->vif.chanctx_conf);
if (chanctx_conf) {
@@ -72,10 +76,6 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
}
rcu_read_unlock();
- /* assume HW handles this */
- if (tx->rate.flags & (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))
- return 0;
-
/* uh huh? */
if (WARN_ON_ONCE(tx->rate.idx < 0))
return 0;
--
2.10.1
^ permalink raw reply related
* [PATCH 05/10] mac80211: minstrel: remove cur_prob from debugfs
From: Felix Fietkau @ 2016-12-14 19:46 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, thomas.huehn
In-Reply-To: <20161214194703.33429-1-nbd@nbd.name>
This field is redundant, because it is simply last success divided by
last attempt count. Removing it from the rate stats struct saves about
1.2 KiB per HT station.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/rc80211_minstrel.c | 10 ++++++----
net/mac80211/rc80211_minstrel.h | 2 --
net/mac80211/rc80211_minstrel_debugfs.c | 16 ++++++----------
net/mac80211/rc80211_minstrel_ht_debugfs.c | 16 ++++++----------
4 files changed, 18 insertions(+), 26 deletions(-)
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 14c5ba3..a284ea0 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -159,21 +159,23 @@ minstrel_update_rates(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
void
minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
{
+ unsigned int cur_prob;
+
if (unlikely(mrs->attempts > 0)) {
mrs->sample_skipped = 0;
- mrs->cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
+ cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
if (unlikely(!mrs->att_hist)) {
- mrs->prob_ewma = mrs->cur_prob;
+ mrs->prob_ewma = cur_prob;
} else {
/* update exponential weighted moving variance */
mrs->prob_ewmsd = minstrel_ewmsd(mrs->prob_ewmsd,
- mrs->cur_prob,
+ cur_prob,
mrs->prob_ewma,
EWMA_LEVEL);
/*update exponential weighted moving avarage */
mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
- mrs->cur_prob,
+ cur_prob,
EWMA_LEVEL);
}
mrs->att_hist += mrs->attempts;
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 209961c..94b89b1 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -62,10 +62,8 @@ struct minstrel_rate_stats {
u32 att_hist, succ_hist;
/* statistis of packet delivery probability
- * cur_prob - current prob within last update intervall
* prob_ewma - exponential weighted moving average of prob
* prob_ewmsd - exp. weighted moving standard deviation of prob */
- unsigned int cur_prob;
unsigned int prob_ewma;
u16 prob_ewmsd;
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
index 820b0ab..ca0bafd 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -75,7 +75,7 @@ minstrel_stats_open(struct inode *inode, struct file *file)
{
struct minstrel_sta_info *mi = inode->i_private;
struct minstrel_debugfs_info *ms;
- unsigned int i, tp_max, tp_avg, prob, eprob;
+ unsigned int i, tp_max, tp_avg, eprob;
char *p;
ms = kmalloc(2048, GFP_KERNEL);
@@ -86,9 +86,9 @@ minstrel_stats_open(struct inode *inode, struct file *file)
p = ms->buf;
p += sprintf(p, "\n");
p += sprintf(p,
- "best __________rate_________ ________statistics________ ________last_______ ______sum-of________\n");
+ "best __________rate_________ ________statistics________ ____last_____ ______sum-of________\n");
p += sprintf(p,
- "rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [prob.|retry|suc|att] [#success | #attempts]\n");
+ "rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [retry|suc|att] [#success | #attempts]\n");
for (i = 0; i < mi->n_rates; i++) {
struct minstrel_rate *mr = &mi->r[i];
@@ -107,17 +107,15 @@ minstrel_stats_open(struct inode *inode, struct file *file)
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
- prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u"
- " %3u.%1u %3u %3u %-3u "
+ " %3u %3u %-3u "
"%9llu %-9llu\n",
tp_max / 10, tp_max % 10,
tp_avg / 10, tp_avg % 10,
eprob / 10, eprob % 10,
mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
- prob / 10, prob % 10,
mrs->retry_count,
mrs->last_success,
mrs->last_attempts,
@@ -148,7 +146,7 @@ minstrel_stats_csv_open(struct inode *inode, struct file *file)
{
struct minstrel_sta_info *mi = inode->i_private;
struct minstrel_debugfs_info *ms;
- unsigned int i, tp_max, tp_avg, prob, eprob;
+ unsigned int i, tp_max, tp_avg, eprob;
char *p;
ms = kmalloc(2048, GFP_KERNEL);
@@ -175,16 +173,14 @@ minstrel_stats_csv_open(struct inode *inode, struct file *file)
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
- prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
- p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u,"
+ p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,%u,"
"%llu,%llu,%d,%d\n",
tp_max / 10, tp_max % 10,
tp_avg / 10, tp_avg % 10,
eprob / 10, eprob % 10,
mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
- prob / 10, prob % 10,
mrs->retry_count,
mrs->last_success,
mrs->last_attempts,
diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c
index 1942d4b..0cecd23 100644
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
@@ -19,7 +19,7 @@ static char *
minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
{
const struct mcs_group *mg;
- unsigned int j, tp_max, tp_avg, prob, eprob, tx_time;
+ unsigned int j, tp_max, tp_avg, eprob, tx_time;
char htmode = '2';
char gimode = 'L';
u32 gflags;
@@ -83,17 +83,15 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
- prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u %3u.%1u"
- " %3u.%1u %3u %3u %-3u "
+ " %3u %3u %-3u "
"%9llu %-9llu\n",
tp_max / 10, tp_max % 10,
tp_avg / 10, tp_avg % 10,
eprob / 10, eprob % 10,
mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
- prob / 10, prob % 10,
mrs->retry_count,
mrs->last_success,
mrs->last_attempts,
@@ -130,9 +128,9 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file)
p += sprintf(p, "\n");
p += sprintf(p,
- " best ____________rate__________ ________statistics________ ________last_______ ______sum-of________\n");
+ " best ____________rate__________ ________statistics________ _____last____ ______sum-of________\n");
p += sprintf(p,
- "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [prob.|retry|suc|att] [#success | #attempts]\n");
+ "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [retry|suc|att] [#success | #attempts]\n");
p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p);
for (i = 0; i < MINSTREL_CCK_GROUP; i++)
@@ -165,7 +163,7 @@ static char *
minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
{
const struct mcs_group *mg;
- unsigned int j, tp_max, tp_avg, prob, eprob, tx_time;
+ unsigned int j, tp_max, tp_avg, eprob, tx_time;
char htmode = '2';
char gimode = 'L';
u32 gflags;
@@ -226,16 +224,14 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
- prob = MINSTREL_TRUNC(mrs->cur_prob * 1000);
eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
- p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,"
+ p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u.%u,%u,%u,"
"%u,%llu,%llu,",
tp_max / 10, tp_max % 10,
tp_avg / 10, tp_avg % 10,
eprob / 10, eprob % 10,
mrs->prob_ewmsd / 10, mrs->prob_ewmsd % 10,
- prob / 10, prob % 10,
mrs->retry_count,
mrs->last_success,
mrs->last_attempts,
--
2.10.1
^ permalink raw reply related
* [PATCH 01/10] mac80211: minstrel_ht: move supported bitrate mask out of group data
From: Felix Fietkau @ 2016-12-14 19:46 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, thomas.huehn
Improves dcache footprint by ensuring that fewer cache lines need to be
touched.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/rc80211_minstrel_ht.c | 30 +++++++++++++++---------------
net/mac80211/rc80211_minstrel_ht.h | 6 +++---
net/mac80211/rc80211_minstrel_ht_debugfs.c | 8 ++++----
3 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 30fbabf..ed8a34d 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -301,7 +301,7 @@ minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
break;
/* short preamble */
- if (!(mi->groups[group].supported & BIT(idx)))
+ if (!(mi->supported[group] & BIT(idx)))
idx += 4;
}
return &mi->groups[group].rates[idx];
@@ -486,7 +486,7 @@ minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi)
MCS_GROUP_RATES].streams;
for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
mg = &mi->groups[group];
- if (!mg->supported || group == MINSTREL_CCK_GROUP)
+ if (!mi->supported[group] || group == MINSTREL_CCK_GROUP)
continue;
tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
@@ -540,7 +540,7 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
mg = &mi->groups[group];
- if (!mg->supported)
+ if (!mi->supported[group])
continue;
mi->sample_count++;
@@ -550,7 +550,7 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
tmp_group_tp_rate[j] = group;
for (i = 0; i < MCS_GROUP_RATES; i++) {
- if (!(mg->supported & BIT(i)))
+ if (!(mi->supported[group] & BIT(i)))
continue;
index = MCS_GROUP_RATES * group + i;
@@ -636,7 +636,7 @@ minstrel_set_next_sample_idx(struct minstrel_ht_sta *mi)
mi->sample_group %= ARRAY_SIZE(minstrel_mcs_groups);
mg = &mi->groups[mi->sample_group];
- if (!mg->supported)
+ if (!mi->supported[mi->sample_group])
continue;
if (++mg->index >= MCS_GROUP_RATES) {
@@ -657,7 +657,7 @@ minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
while (group > 0) {
group--;
- if (!mi->groups[group].supported)
+ if (!mi->supported[group])
continue;
if (minstrel_mcs_groups[group].streams >
@@ -994,7 +994,7 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
sample_idx = sample_table[mg->column][mg->index];
minstrel_set_next_sample_idx(mi);
- if (!(mg->supported & BIT(sample_idx)))
+ if (!(mi->supported[sample_group] & BIT(sample_idx)))
return -1;
mrs = &mg->rates[sample_idx];
@@ -1052,7 +1052,7 @@ static void
minstrel_ht_check_cck_shortpreamble(struct minstrel_priv *mp,
struct minstrel_ht_sta *mi, bool val)
{
- u8 supported = mi->groups[MINSTREL_CCK_GROUP].supported;
+ u8 supported = mi->supported[MINSTREL_CCK_GROUP];
if (!supported || !mi->cck_supported_short)
return;
@@ -1061,7 +1061,7 @@ minstrel_ht_check_cck_shortpreamble(struct minstrel_priv *mp,
return;
supported ^= mi->cck_supported_short | (mi->cck_supported_short << 4);
- mi->groups[MINSTREL_CCK_GROUP].supported = supported;
+ mi->supported[MINSTREL_CCK_GROUP] = supported;
}
static void
@@ -1154,7 +1154,7 @@ minstrel_ht_update_cck(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
mi->cck_supported_short |= BIT(i);
}
- mi->groups[MINSTREL_CCK_GROUP].supported = mi->cck_supported;
+ mi->supported[MINSTREL_CCK_GROUP] = mi->cck_supported;
}
static void
@@ -1224,7 +1224,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
u32 gflags = minstrel_mcs_groups[i].flags;
int bw, nss;
- mi->groups[i].supported = 0;
+ mi->supported[i] = 0;
if (i == MINSTREL_CCK_GROUP) {
minstrel_ht_update_cck(mp, mi, sband, sta);
continue;
@@ -1256,8 +1256,8 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
if (use_vht && minstrel_vht_only)
continue;
#endif
- mi->groups[i].supported = mcs->rx_mask[nss - 1];
- if (mi->groups[i].supported)
+ mi->supported[i] = mcs->rx_mask[nss - 1];
+ if (mi->supported[i])
n_supported++;
continue;
}
@@ -1283,10 +1283,10 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
else
bw = BW_20;
- mi->groups[i].supported = minstrel_get_valid_vht_rates(bw, nss,
+ mi->supported[i] = minstrel_get_valid_vht_rates(bw, nss,
vht_cap->vht_mcs.tx_mcs_map);
- if (mi->groups[i].supported)
+ if (mi->supported[i])
n_supported++;
}
diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h
index e8b52a9..de1646c 100644
--- a/net/mac80211/rc80211_minstrel_ht.h
+++ b/net/mac80211/rc80211_minstrel_ht.h
@@ -52,9 +52,6 @@ struct minstrel_mcs_group_data {
u8 index;
u8 column;
- /* bitfield of supported MCS rates of this group */
- u16 supported;
-
/* sorted rate set within a MCS group*/
u16 max_group_tp_rate[MAX_THR_RATES];
u16 max_group_prob_rate;
@@ -101,6 +98,9 @@ struct minstrel_ht_sta {
u8 cck_supported;
u8 cck_supported_short;
+ /* Bitfield of supported MCS rates of all groups */
+ u16 supported[MINSTREL_GROUPS_NB];
+
/* MCS rate group info and statistics */
struct minstrel_mcs_group_data groups[MINSTREL_GROUPS_NB];
};
diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c
index 5320e35..1942d4b 100644
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
@@ -24,7 +24,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
char gimode = 'L';
u32 gflags;
- if (!mi->groups[i].supported)
+ if (!mi->supported[i])
return p;
mg = &minstrel_mcs_groups[i];
@@ -42,7 +42,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
static const int bitrates[4] = { 10, 20, 55, 110 };
int idx = i * MCS_GROUP_RATES + j;
- if (!(mi->groups[i].supported & BIT(j)))
+ if (!(mi->supported[i] & BIT(j)))
continue;
if (gflags & IEEE80211_TX_RC_MCS) {
@@ -170,7 +170,7 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
char gimode = 'L';
u32 gflags;
- if (!mi->groups[i].supported)
+ if (!mi->supported[i])
return p;
mg = &minstrel_mcs_groups[i];
@@ -188,7 +188,7 @@ minstrel_ht_stats_csv_dump(struct minstrel_ht_sta *mi, int i, char *p)
static const int bitrates[4] = { 10, 20, 55, 110 };
int idx = i * MCS_GROUP_RATES + j;
- if (!(mi->groups[i].supported & BIT(j)))
+ if (!(mi->supported[i] & BIT(j)))
continue;
if (gflags & IEEE80211_TX_RC_MCS) {
--
2.10.1
^ permalink raw reply related
* [PATCH 03/10] mac80211: minstrel_ht: make att_hist and succ_hist u32 instead of u64
From: Felix Fietkau @ 2016-12-14 19:46 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, thomas.huehn
In-Reply-To: <20161214194703.33429-1-nbd@nbd.name>
They are only used for debugging purposes and take a very long time to
overflow. Visibly reduces the size of the per-sta rate control data.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/rc80211_minstrel.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index c230bbe..209961c 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -59,7 +59,7 @@ struct minstrel_rate_stats {
u16 success, last_success;
/* total attempts/success counters */
- u64 att_hist, succ_hist;
+ u32 att_hist, succ_hist;
/* statistis of packet delivery probability
* cur_prob - current prob within last update intervall
--
2.10.1
^ permalink raw reply related
* [PATCH 02/10] mac80211: minstrel_ht: move short preamble check out of get_rate
From: Felix Fietkau @ 2016-12-14 19:46 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, thomas.huehn
In-Reply-To: <20161214194703.33429-1-nbd@nbd.name>
Test short preamble support in minstrel_ht_update_caps instead of
looking at the per-packet flag. Makes the code more efficient.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/rc80211_minstrel_ht.c | 22 +++++-----------------
1 file changed, 5 insertions(+), 17 deletions(-)
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index ed8a34d..ae45dcb 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -14,6 +14,7 @@
#include <linux/ieee80211.h>
#include <net/mac80211.h>
#include "rate.h"
+#include "sta_info.h"
#include "rc80211_minstrel.h"
#include "rc80211_minstrel_ht.h"
@@ -1049,22 +1050,6 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
}
static void
-minstrel_ht_check_cck_shortpreamble(struct minstrel_priv *mp,
- struct minstrel_ht_sta *mi, bool val)
-{
- u8 supported = mi->supported[MINSTREL_CCK_GROUP];
-
- if (!supported || !mi->cck_supported_short)
- return;
-
- if (supported & (mi->cck_supported_short << (val * 4)))
- return;
-
- supported ^= mi->cck_supported_short | (mi->cck_supported_short << 4);
- mi->supported[MINSTREL_CCK_GROUP] = supported;
-}
-
-static void
minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
struct ieee80211_tx_rate_control *txrc)
{
@@ -1087,7 +1072,6 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
minstrel_aggr_check(sta, txrc->skb);
info->flags |= mi->tx_flags;
- minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble);
#ifdef CONFIG_MAC80211_DEBUGFS
if (mp->fixed_rate_idx != -1)
@@ -1168,6 +1152,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
u16 sta_cap = sta->ht_cap.cap;
struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
+ struct sta_info *sinfo = container_of(sta, struct sta_info, sta);
int use_vht;
int n_supported = 0;
int ack_dur;
@@ -1293,6 +1278,9 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
if (!n_supported)
goto use_legacy;
+ if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE))
+ mi->cck_supported_short |= mi->cck_supported_short << 4;
+
/* create an initial rate table with the lowest supported rates */
minstrel_ht_update_stats(mp, mi);
minstrel_ht_update_rates(mp, mi);
--
2.10.1
^ permalink raw reply related
* [PATCH v2] mac80211: fix legacy and invalid rx-rate rpt
From: greearb @ 2016-12-14 19:30 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, Ben Greear
From: Ben Greear <greearb@candelatech.com>
This fixes obtaining the rate info via sta_set_sinfo
when the rx rate is invalid (for instance, on IBSS
interface that has received no frames from one of its
peers).
This also fixes a more general issue with rinfo->flags
not being properly initialized for legacy rates.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
Patch is against 4.7
net/mac80211/sta_info.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 01868f9..6d27813e 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2057,6 +2057,7 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u16 rate,
u16 brate;
unsigned int shift;
+ rinfo->flags = 0;
sband = local->hw.wiphy->bands[(rate >> 4) & 0xf];
brate = sband->bitrates[rate & 0xf].bitrate;
if (rinfo->bw == RATE_INFO_BW_5)
@@ -2072,14 +2073,15 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u16 rate,
rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
}
-static void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
+static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
{
u16 rate = ACCESS_ONCE(sta_get_last_rx_stats(sta)->last_rate);
-
- if (rate == STA_STATS_RATE_INVALID)
- rinfo->flags = 0;
- else
+ if (rate == STA_STATS_RATE_INVALID) {
+ return -EINVAL;
+ } else {
sta_stats_decode_rate(sta->local, rate, rinfo);
+ return 0;
+ }
}
static void sta_set_tidstats(struct sta_info *sta,
@@ -2284,8 +2286,8 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
}
if (!(sinfo->filled & BIT(NL80211_STA_INFO_RX_BITRATE))) {
- sta_set_rate_info_rx(sta, &sinfo->rxrate);
- sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
+ if (sta_set_rate_info_rx(sta, &sinfo->rxrate) == 0)
+ sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
}
sinfo->filled |= BIT(NL80211_STA_INFO_TID_STATS);
--
2.4.11
^ permalink raw reply related
* RE: ath10k firmware sends probes on DFS channels without radar detection
From: Jean-Pierre Tosoni @ 2016-12-14 18:14 UTC (permalink / raw)
To: 'Ben Greear', ath10k, linux-wireless
In-Reply-To: <63c731f2-ee21-6450-2ae4-2808e7130eb5@candelatech.com>
On 12/06/15 08:36 PM, Ben Greear wrote:
> On 12/06/2016 09:02 AM, Jean-Pierre Tosoni wrote:
> > This follows on the previous discussion
> > "Client station sends probes on DFS channels"
> >
> > Problem:
> > The combination of QCA988X firmware v10.2.4.70-2 + ath10k +
> > wpa_supplicant do not comply with the norm ETSI/EN 301-893 section
> > 4.7; because they can send probes for 600s when no AP is around.
> >
> > Analysis:
> > The problem seems to lie in the firmware, which regards the presence
> > of *any* beacon as a proof that the channel is radar-clean for 600s.
> >
> > This is a wrong hypothesis, since a rogue AP sending fraudulent
> > beacons should not induce a scrupulous STA in sending illegal probes.
> >
> > Moreover, the norm (table D.1) sets a time limit of 10s to shutdown
> > when no AP positively allows the STA to transmit on the DFS channel.
> >
> > Status:
> > - there is no known plan at QCA to fix the issue.
> > - ath10k firmware is not publicly available for fixes.
> > - there is no obvious fix working in ath10k.
> > - the issue does not show up with other mac80211 devices like ath9k.
> > - wpa_supplicant considers this is a kernel issue [2]
>
> Have you confirmed that there are no probe requests being sent by ath10k
> driver?
I have put a printk in the ath10k_tx function (in the path for management
frames) and it does not show up.
On another hand I cannot find any other function preparing / sending probes.
There is only the wmi command that starts scans.
>
> You could also try disabling the station keep-alive and roaming logic in
> the firmware by tweaking the wmi initial setup logic. I disable that in
> my firmware, for instance, because mac80211 can do a better job and then I
> can save resources in the firmware.
Do you mean the values set in wmi.c:: ath10k_wmi_start_scan_init() ?
Should I replace all the scan offload by a mac80211-controlled scan like
in ath9k? The problem then is to switch channels; channel switching
seems very different from ath9k.
Thanks,
JP
> Finally, if that doesn't work, then I could probably fix that in CT
> firmware in case that is of interest.
>
> Thanks,
> Ben
>
> >
> > Jean-Pierre Tosoni
> >
> >
> >
> >> -----Message d'origine-----
> >> De : ath10k [mailto:ath10k-bounces@lists.infradead.org] De la part de
> >> Jean-Pierre Tosoni Envoyé : mercredi 30 novembre 2016 19:04 À :
> >> ath10k@lists.infradead.org Objet : Client station sends probes on DFS
> >> channels
> >>
> >> Hello list,
> >>
> >> There is a case where I can see probes on a DFS channel, from a non-
> >> associated station using ath10k. (note that the problem does not
> >> arise when using ath9k).
> >>
> >> *The setup*
> >>
> >> I am using Openwrt, wpa_supplicant and compat-wireless 2016-10-08,
> >> Card firmware is ath10k_pci: qca988x hw2.0 (0x4100016c, 0x043202ff)
> >> fw 10.2.4.70-2 api 5 htt-ver 2.1 wmi-op 5 htt-op 2
> >> cal otp max-sta 128 features no-p2p
> >> ath10k_pci: debug 0 debugfs 1 tracing 0 dfs 1 testmode 1
> >>
> >> I am using channel 116, regdom US or FR, where I see no traffic at
> >> all using wireshark+Airpcap.
> >> I set wpa_supplicant to scan this channel only for a specific SSID
> >> "ssid1".
> >>
> >> At initial startup of the client device, no probes are going out,
> >> which is OK.
> >>
> >> Then, on another device, I start a hostapd set to channel 116, with a
> >> different SSID "otherssid" so that the supplicant will not associate.
> >>
> >> Shortly (1-2s) after the beacons appear in the air, the client begins
> >> to Send probe request in the air, which is unexpected, but acceptable
> >> since the client can infer absence of radars from the presence of
> beacons.
> >>
> >> *The problem*
> >>
> >> If I power down the AP, the client continues to send probes for
> >> around
> >> 10 minutes, which is unacceptable since it cannot handle radar
> >> detection, as it is a slave device in the meaning of ETSI/EN 301-
> 893[1].
> >>
> >>
> >> Some tests I made:
> >> - I tried to investigate the "beacon hint" mechanism but it appears
> >> that it is not used on DFS channels.
> >>
> >> - I tried to force the IEEE80211_NO_IR flag when IEEE80211_CHAN_DFS
> >> is set.
> >>
> >> - When I reload the reg. domain using "iw reg set", the probes cease,
> >> but will reappear if I cycle my AP again On then Off.
> >>
> >> - When I let the client associate, then disassociate and stop the AP,
> >> the same problem arises. It disappears if I add a call to
> >> ath10k_regd_update() in mac.c after a disconnection (This is not a
> >> fix, since in my case the client never associates).
> >>
> >> - Since at startup, the client does not send probes, I infer that the
> >> problem is *not* caused by a hidden AP that the card could see but
> >> not airpcap.
> >>
> >> - I tried with channels 52 and 100, with regdom FR or US: same problem.
> >>
> >> Any ideas?
> >>
> >>
> >> [1] http://www.etsi.org/deliver/etsi_en/301800_301899/301893/
> >> 01.08.01_60/en_301893v010801p.pdf
> > [2] http://lists.shmoo.com/pipermail/hostap/2015-January/031906.html
> >>
> >> J.P. Tosoni - ACKSYS
> >>
> >>
> >>
> >>
> >> _______________________________________________
> >> ath10k mailing list
> >> ath10k@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/ath10k
> >
>
>
> --
> Ben Greear <greearb@candelatech.com>
> Candela Technologies Inc http://www.candelatech.com
>
>
> _______________________________________________
> ath10k mailing list
> ath10k@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/ath10k
^ permalink raw reply
* Re: [Patch] NFC: trf7970a:
From: Geoff Lansberry @ 2016-12-14 18:35 UTC (permalink / raw)
To: Mark Greer
Cc: linux-wireless, Lauro Ramos Venancio, Aloisio Almeida Jr,
Samuel Ortiz, Justin Bronder
In-Reply-To: <20161214171010.GA29321@animalcreek.com>
On Wed, Dec 14, 2016 at 12:10 PM, Mark Greer <mgreer@animalcreek.com> wrote:
> On Wed, Dec 14, 2016 at 11:17:33AM -0500, Geoff Lansberry wrote:
>> On Wed, Dec 14, 2016 at 10:57 AM, Mark Greer <mgreer@animalcreek.com> wrote:
>> >
>> > On Tue, Dec 13, 2016 at 08:50:04PM -0500, Geoff Lansberry wrote:
>> > > Hi Mark - Thanks for getting back to me. It's funny that you ask,
>> > > because we are currently chasing a segfault that is happening in neard, but
>> > > may end up back in the trf7970a driver. Have you ever heard on anyone
>> > > having segfault problems related to the trf7970a hardware drivers?
>> >
>> > No. Mind sharing more info on that segfault?
>> >
>> > > I'll get you an update later tonight or tomorrow.
>> >
>> > Okay, thanks.
>> >
>> > Mark
>> > --
>>
>> Mark - The segfault issue is only happening on writing, The work on
>> the segfault is being done by a consultant, but here is his statement
>> on how to recreate it on our build:
>>
>> I am able to reliably force neard to segfault by flooding it with
>> write requests. I have attached a python script called flood.py that
>> can be used to do this. The script uses utilities that ship with
>> neard.
>>
>> The segfault does not appear deterministic. It usually happens within
>> 1000 writes, but the time can varying greatly. The logs output from
>> neard are inconsistent between crashes, which suggests this may be a
>> timing or race condition related issue.
>>
>> I have been running neard manually to obtain the log information and a
>> core file for debugging (attached). I run neard as,
>>
>> $ /usr/lib/neard/nfc/neard -d -n
>>
>> In a separate terminal I run,
>>
>> $ python flood.py
>>
>> And the resulting core file provides the following backtrace,
>>
>> (gdb) bt
>> #0 0xb6caed64 in ?? ()
>> #1 0x0001ed7c in data_recv (resp=0x5bd90 "", length=17, data=0x58348)
>> at plugins/nfctype2.c:156
>> #2 0x00024ecc in execute_recv_cb (user_data=0x5bd88) at src/adapter.c:979
>> #3 0xb6e70d60 in ?? ()
>> Backtrace stopped: previous frame identical to this frame (corrupt stack?)
>> (gdb)
>>
>> The line at nfctype2.c:156 contains a memcpy operation.
>
> Thanks Geoff.
>
> What are the values of the arguments to memcpy()?
>
> I will look at it later today/tomorrow but if you have another NFC device
> to test with, it would help isolate whether it is neard or the trf7970a
> driver. The driver shouldn't be able to make neard crash like this but
> who knows.
>
> You could also try testing older versions of neard to see if they also
> fail and if not, start bisecting from there. Maybe test a different
> tag type too.
>
> Mark
> --
Mark - We can't seem to get gdb to run on our board, so we can't see
the exact arguments. Here is what our consultant has to say about
your question:
The backtrace seems to indicate that the error is occurring in neard,
not the driver.
Since the driver is built as a module, your kernel won't crash if
there is a problem in it, but you should be told that the error is
originating in the module.
It is also possible that the NFC driver does have a non-fatal problem
in it (such as returning unexpected data) that is propagating to neard
and causing the error there.
Of course, it is also worth noting:
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
and the same address appearing twice -- what I would assume to be your
memcpy address, since that is the last call made on a given source
line. If the stack is corrupt, then the error could very well
originate in the driver and not neard.
^ permalink raw reply
* Re: ath10k firmware sends probes on DFS channels without radar detection
From: Ben Greear @ 2016-12-14 18:28 UTC (permalink / raw)
To: Jean-Pierre Tosoni, ath10k, linux-wireless
In-Reply-To: <00e701d25635$e0108480$a0318d80$@acksys.fr>
On 12/14/2016 10:14 AM, Jean-Pierre Tosoni wrote:
> On 12/06/15 08:36 PM, Ben Greear wrote:
>> On 12/06/2016 09:02 AM, Jean-Pierre Tosoni wrote:
>>> This follows on the previous discussion
>>> "Client station sends probes on DFS channels"
>>>
>>> Problem:
>>> The combination of QCA988X firmware v10.2.4.70-2 + ath10k +
>>> wpa_supplicant do not comply with the norm ETSI/EN 301-893 section
>>> 4.7; because they can send probes for 600s when no AP is around.
>>>
>>> Analysis:
>>> The problem seems to lie in the firmware, which regards the presence
>>> of *any* beacon as a proof that the channel is radar-clean for 600s.
>>>
>>> This is a wrong hypothesis, since a rogue AP sending fraudulent
>>> beacons should not induce a scrupulous STA in sending illegal probes.
>>>
>>> Moreover, the norm (table D.1) sets a time limit of 10s to shutdown
>>> when no AP positively allows the STA to transmit on the DFS channel.
>>>
>>> Status:
>>> - there is no known plan at QCA to fix the issue.
>>> - ath10k firmware is not publicly available for fixes.
>>> - there is no obvious fix working in ath10k.
>>> - the issue does not show up with other mac80211 devices like ath9k.
>>> - wpa_supplicant considers this is a kernel issue [2]
>>
>> Have you confirmed that there are no probe requests being sent by ath10k
>> driver?
>
> I have put a printk in the ath10k_tx function (in the path for management
> frames) and it does not show up.
> On another hand I cannot find any other function preparing / sending probes.
> There is only the wmi command that starts scans.
That wmi command causes probes, so make sure it is not being called.
>> You could also try disabling the station keep-alive and roaming logic in
>> the firmware by tweaking the wmi initial setup logic. I disable that in
>> my firmware, for instance, because mac80211 can do a better job and then I
>> can save resources in the firmware.
>
> Do you mean the values set in wmi.c:: ath10k_wmi_start_scan_init() ?
>
> Should I replace all the scan offload by a mac80211-controlled scan like
> in ath9k? The problem then is to switch channels; channel switching
> seems very different from ath9k.
You might try one or more of these settings in the ath10k_wmi_10_1_op_gen_init
method (or 10.2 if that is the FW you are using):
config.roam_offload_max_vdev = 0; /* disable roaming */
config.roam_offload_max_ap_profiles = 0; /* disable roaming */
config.bmiss_offload_max_vdev = 0;
I have only tested this using my CT firmware, and I have some additional
patches in my driver to enable mac80211 keep-alive logic when using my
CT firmware.
Thanks,
Ben
>
> Thanks,
> JP
>
>> Finally, if that doesn't work, then I could probably fix that in CT
>> firmware in case that is of interest.
>>
>> Thanks,
>> Ben
>>
>>>
>>> Jean-Pierre Tosoni
>>>
>>>
>>>
>>>> -----Message d'origine-----
>>>> De : ath10k [mailto:ath10k-bounces@lists.infradead.org] De la part de
>>>> Jean-Pierre Tosoni Envoyé : mercredi 30 novembre 2016 19:04 À :
>>>> ath10k@lists.infradead.org Objet : Client station sends probes on DFS
>>>> channels
>>>>
>>>> Hello list,
>>>>
>>>> There is a case where I can see probes on a DFS channel, from a non-
>>>> associated station using ath10k. (note that the problem does not
>>>> arise when using ath9k).
>>>>
>>>> *The setup*
>>>>
>>>> I am using Openwrt, wpa_supplicant and compat-wireless 2016-10-08,
>>>> Card firmware is ath10k_pci: qca988x hw2.0 (0x4100016c, 0x043202ff)
>>>> fw 10.2.4.70-2 api 5 htt-ver 2.1 wmi-op 5 htt-op 2
>>>> cal otp max-sta 128 features no-p2p
>>>> ath10k_pci: debug 0 debugfs 1 tracing 0 dfs 1 testmode 1
>>>>
>>>> I am using channel 116, regdom US or FR, where I see no traffic at
>>>> all using wireshark+Airpcap.
>>>> I set wpa_supplicant to scan this channel only for a specific SSID
>>>> "ssid1".
>>>>
>>>> At initial startup of the client device, no probes are going out,
>>>> which is OK.
>>>>
>>>> Then, on another device, I start a hostapd set to channel 116, with a
>>>> different SSID "otherssid" so that the supplicant will not associate.
>>>>
>>>> Shortly (1-2s) after the beacons appear in the air, the client begins
>>>> to Send probe request in the air, which is unexpected, but acceptable
>>>> since the client can infer absence of radars from the presence of
>> beacons.
>>>>
>>>> *The problem*
>>>>
>>>> If I power down the AP, the client continues to send probes for
>>>> around
>>>> 10 minutes, which is unacceptable since it cannot handle radar
>>>> detection, as it is a slave device in the meaning of ETSI/EN 301-
>> 893[1].
>>>>
>>>>
>>>> Some tests I made:
>>>> - I tried to investigate the "beacon hint" mechanism but it appears
>>>> that it is not used on DFS channels.
>>>>
>>>> - I tried to force the IEEE80211_NO_IR flag when IEEE80211_CHAN_DFS
>>>> is set.
>>>>
>>>> - When I reload the reg. domain using "iw reg set", the probes cease,
>>>> but will reappear if I cycle my AP again On then Off.
>>>>
>>>> - When I let the client associate, then disassociate and stop the AP,
>>>> the same problem arises. It disappears if I add a call to
>>>> ath10k_regd_update() in mac.c after a disconnection (This is not a
>>>> fix, since in my case the client never associates).
>>>>
>>>> - Since at startup, the client does not send probes, I infer that the
>>>> problem is *not* caused by a hidden AP that the card could see but
>>>> not airpcap.
>>>>
>>>> - I tried with channels 52 and 100, with regdom FR or US: same problem.
>>>>
>>>> Any ideas?
>>>>
>>>>
>>>> [1] http://www.etsi.org/deliver/etsi_en/301800_301899/301893/
>>>> 01.08.01_60/en_301893v010801p.pdf
>>> [2] http://lists.shmoo.com/pipermail/hostap/2015-January/031906.html
>>>>
>>>> J.P. Tosoni - ACKSYS
>>>>
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> ath10k mailing list
>>>> ath10k@lists.infradead.org
>>>> http://lists.infradead.org/mailman/listinfo/ath10k
>>>
>>
>>
>> --
>> Ben Greear <greearb@candelatech.com>
>> Candela Technologies Inc http://www.candelatech.com
>>
>>
>> _______________________________________________
>> ath10k mailing list
>> ath10k@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/ath10k
>
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [Patch] NFC: trf7970a:
From: Mark Greer @ 2016-12-14 17:10 UTC (permalink / raw)
To: Geoff Lansberry
Cc: linux-wireless, Lauro Ramos Venancio, Aloisio Almeida Jr,
Samuel Ortiz, Justin Bronder
In-Reply-To: <CAO7Z3WKqhS5Q6qAaDs8364KP5-7ma=b_ic2B10=njngMmp5noQ@mail.gmail.com>
On Wed, Dec 14, 2016 at 11:17:33AM -0500, Geoff Lansberry wrote:
> On Wed, Dec 14, 2016 at 10:57 AM, Mark Greer <mgreer@animalcreek.com> wrote:
> >
> > On Tue, Dec 13, 2016 at 08:50:04PM -0500, Geoff Lansberry wrote:
> > > Hi Mark - Thanks for getting back to me. It's funny that you ask,
> > > because we are currently chasing a segfault that is happening in neard, but
> > > may end up back in the trf7970a driver. Have you ever heard on anyone
> > > having segfault problems related to the trf7970a hardware drivers?
> >
> > No. Mind sharing more info on that segfault?
> >
> > > I'll get you an update later tonight or tomorrow.
> >
> > Okay, thanks.
> >
> > Mark
> > --
>
> Mark - The segfault issue is only happening on writing, The work on
> the segfault is being done by a consultant, but here is his statement
> on how to recreate it on our build:
>
> I am able to reliably force neard to segfault by flooding it with
> write requests. I have attached a python script called flood.py that
> can be used to do this. The script uses utilities that ship with
> neard.
>
> The segfault does not appear deterministic. It usually happens within
> 1000 writes, but the time can varying greatly. The logs output from
> neard are inconsistent between crashes, which suggests this may be a
> timing or race condition related issue.
>
> I have been running neard manually to obtain the log information and a
> core file for debugging (attached). I run neard as,
>
> $ /usr/lib/neard/nfc/neard -d -n
>
> In a separate terminal I run,
>
> $ python flood.py
>
> And the resulting core file provides the following backtrace,
>
> (gdb) bt
> #0 0xb6caed64 in ?? ()
> #1 0x0001ed7c in data_recv (resp=0x5bd90 "", length=17, data=0x58348)
> at plugins/nfctype2.c:156
> #2 0x00024ecc in execute_recv_cb (user_data=0x5bd88) at src/adapter.c:979
> #3 0xb6e70d60 in ?? ()
> Backtrace stopped: previous frame identical to this frame (corrupt stack?)
> (gdb)
>
> The line at nfctype2.c:156 contains a memcpy operation.
Thanks Geoff.
What are the values of the arguments to memcpy()?
I will look at it later today/tomorrow but if you have another NFC device
to test with, it would help isolate whether it is neard or the trf7970a
driver. The driver shouldn't be able to make neard crash like this but
who knows.
You could also try testing older versions of neard to see if they also
fail and if not, start bisecting from there. Maybe test a different
tag type too.
Mark
--
^ permalink raw reply
* Re: [PATCH 1/2] ath10k: add accounting for the extended peer statistics
From: Christian Lamparter @ 2016-12-14 16:38 UTC (permalink / raw)
To: Mohammed Shafi Shajakhan; +Cc: linux-wireless, ath10k, Kalle Valo
In-Reply-To: <20161214073337.GA4046@atheros-ThinkPad-T61>
On Wednesday, December 14, 2016 1:03:38 PM CET Mohammed Shafi Shajakhan wrote:
> > On Wednesday, December 7, 2016 11:58:24 AM CET Mohammed Shafi Shajakhan wrote:
> > > On Mon, Dec 05, 2016 at 10:52:45PM +0100, Christian Lamparter wrote:
> > > > @@ -409,10 +410,12 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
> > > > goto free;
> > > > }
> > > >
> > > > + if (!list_empty(&stats.peers))
> > >
> > > [shafi] sorry please correct me if i am wrong, for 'extended peer stats' we are checking
> > > for normal 'peer stats' ? Is this the fix intended, i had started a build to
> > > check your change and we will keep you posted, does this fix displaying
> > > 'rx_duration' in ath10k fw_stats.
> > The idea is not to queue any "extended peer stats" when there where no "peer stats" to
> > begin with. Because otherwise, the function is still vulnerable to OOM since the
> > extended peers stats will be queued unchecked (not that this is currently a problem).
>
> [shafi] list_splice_tail_init should still check for non-empty 'peers_extd' list
> and append if required ? please let me know if i am still missing something
Well, you can also count the entries in peers_extd and delete the old entries
if they start to overflow. If you want to do it differently, please go ahead.
Regards,
Christian
^ permalink raw reply
* [PATCH] mac80211: only alloc mem if a station doesnt exist yet
From: Koen Vandeputte @ 2016-12-14 16:28 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Koen Vandeputte
This speeds up the function in case a station already exists by avoiding
calling an expensive kzalloc just to free it again after the next check.
Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
---
net/mac80211/sta_info.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 1711bae..0a42e6e 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -513,23 +513,23 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
{
struct ieee80211_local *local = sta->local;
struct ieee80211_sub_if_data *sdata = sta->sdata;
- struct station_info *sinfo;
+ struct station_info *sinfo = NULL;
int err = 0;
lockdep_assert_held(&local->sta_mtx);
- sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
- if (!sinfo) {
- err = -ENOMEM;
- goto out_err;
- }
-
/* check if STA exists already */
if (sta_info_get_bss(sdata, sta->sta.addr)) {
err = -EEXIST;
goto out_err;
}
+ sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
+ if (!sinfo) {
+ err = -ENOMEM;
+ goto out_err;
+ }
+
local->num_sta++;
local->sta_generation++;
smp_mb();
--
2.7.4
^ permalink raw reply related
* Re: [Patch] NFC: trf7970a:
From: Geoff Lansberry @ 2016-12-14 16:17 UTC (permalink / raw)
To: Mark Greer
Cc: linux-wireless, Lauro Ramos Venancio, Aloisio Almeida Jr,
Samuel Ortiz, Justin Bronder
In-Reply-To: <20161214155743.GA22282@animalcreek.com>
On Wed, Dec 14, 2016 at 10:57 AM, Mark Greer <mgreer@animalcreek.com> wrote:
>
> On Tue, Dec 13, 2016 at 08:50:04PM -0500, Geoff Lansberry wrote:
> > Hi Mark - Thanks for getting back to me. It's funny that you ask,
> > because we are currently chasing a segfault that is happening in neard, but
> > may end up back in the trf7970a driver. Have you ever heard on anyone
> > having segfault problems related to the trf7970a hardware drivers?
>
> No. Mind sharing more info on that segfault?
>
> > I'll get you an update later tonight or tomorrow.
>
> Okay, thanks.
>
> Mark
> --
Mark - The segfault issue is only happening on writing, The work on
the segfault is being done by a consultant, but here is his statement
on how to recreate it on our build:
I am able to reliably force neard to segfault by flooding it with
write requests. I have attached a python script called flood.py that
can be used to do this. The script uses utilities that ship with
neard.
The segfault does not appear deterministic. It usually happens within
1000 writes, but the time can varying greatly. The logs output from
neard are inconsistent between crashes, which suggests this may be a
timing or race condition related issue.
I have been running neard manually to obtain the log information and a
core file for debugging (attached). I run neard as,
$ /usr/lib/neard/nfc/neard -d -n
In a separate terminal I run,
$ python flood.py
And the resulting core file provides the following backtrace,
(gdb) bt
#0 0xb6caed64 in ?? ()
#1 0x0001ed7c in data_recv (resp=0x5bd90 "", length=17, data=0x58348)
at plugins/nfctype2.c:156
#2 0x00024ecc in execute_recv_cb (user_data=0x5bd88) at src/adapter.c:979
#3 0xb6e70d60 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb)
The line at nfctype2.c:156 contains a memcpy operation.
Below is the flood.py script:
#!/usr/bin/python
import neardutils
import dbus
import time
bus = dbus.SystemBus()
DURATION = 0.05
def write():
# Get an adapter interface
objects = neardutils.get_managed_objects()
for path, interfaces in objects.iteritems():
if "org.neard.Adapter" in interfaces:
break
else:
raise Exception("Unable to find adapter")
print("adapter object path: " + path)
adapter = dbus.Interface(bus.get_object("org.neard", path),
"org.freedesktop.DBus.Properties")
# power cycle
try:
adapter.Set("org.neard.Adapter", "Powered", dbus.Boolean(0))
time.sleep(DURATION)
except:
pass
try:
adapter.Set("org.neard.Adapter", "Powered", dbus.Boolean(1))
time.sleep(DURATION)
except:
pass
# Set polling
adapter = dbus.Interface(bus.get_object("org.neard", path),
"org.neard.Adapter")
adapter.StartPollLoop("Initiator")
time.sleep(DURATION)
# write tag
objects = neardutils.get_managed_objects()
for path, interfaces in objects.iteritems():
if "org.neard.Tag" in interfaces:
break
else:
raise Exception("Unable to find tag")
print("tag object path: " + path)
time.sleep(DURATION)
tag = dbus.Interface(bus.get_object("org.neard", path), "org.neard.Tag")
tag.Write(({
"Type": "Text",
"Encoding": "UTF-8",
"Language": "en",
"Representation": "omen_red_2014",
}))
time.sleep(DURATION)
objects = neardutils.get_managed_objects()
for path, interfaces in objects.iteritems():
if "org.neard.Record" in interfaces:
break
else:
raise Exception("Unable to read record")
print("record object path: " + path)
time.sleep(DURATION)
record = dbus.Interface(bus.get_object("org.neard", path),
"org.freedesktop.DBus.Properties")
print("representation: " + record.Get("org.neard.Record", "Representation"))
def main():
for iteration in range(1000):
try:
print("==================================================")
print("iteration: " + str(iteration))
write()
print("SUCCESS")
except Exception,e:
print(str(e))
print("FAILURE")
if __name__ == "__main__":
main()
-----
If we find the source of the problem, we will share it upstream. If
you have any thoughts on where to look, please share.
Geoff Lansberry
^ permalink raw reply
* Re: [Patch] NFC: trf7970a:
From: Mark Greer @ 2016-12-14 15:57 UTC (permalink / raw)
To: Geoff Lansberry
Cc: linux-wireless, Lauro Ramos Venancio, Aloisio Almeida Jr,
Samuel Ortiz, Justin Bronder
In-Reply-To: <CAO7Z3WJwf80mCqubSYTeK=BHN9sd=mzmL9th4Su-E25de6TmAg@mail.gmail.com>
On Tue, Dec 13, 2016 at 08:50:04PM -0500, Geoff Lansberry wrote:
> Hi Mark - Thanks for getting back to me. It's funny that you ask,
> because we are currently chasing a segfault that is happening in neard, but
> may end up back in the trf7970a driver. Have you ever heard on anyone
> having segfault problems related to the trf7970a hardware drivers?
No. Mind sharing more info on that segfault?
> I'll get you an update later tonight or tomorrow.
Okay, thanks.
Mark
--
^ permalink raw reply
* [PATCH 4/5] mwifiex: get rid of __mwifiex_sdio_remove helper
From: Amitkumar Karwar @ 2016-12-14 14:10 UTC (permalink / raw)
To: linux-wireless
Cc: Cathy Luo, Nishant Sarmukadam, rajatja, briannorris,
dmitry.torokhov, Xinming Hu, Amitkumar Karwar
In-Reply-To: <1481724651-30397-1-git-send-email-akarwar@marvell.com>
From: Xinming Hu <huxm@marvell.com>
__mwifiex_sdio_remove helper is not needed after
our enhancements in SDIO card reset.
Signed-off-by: Xinming Hu <huxm@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
drivers/net/wireless/marvell/mwifiex/sdio.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
index b3aca10..0fda87a 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
@@ -370,7 +370,7 @@ static int mwifiex_check_winner_status(struct mwifiex_adapter *adapter)
* This function removes the interface and frees up the card structure.
*/
static void
-__mwifiex_sdio_remove(struct sdio_func *func)
+mwifiex_sdio_remove(struct sdio_func *func)
{
struct sdio_mmc_card *card;
struct mwifiex_adapter *adapter;
@@ -388,6 +388,8 @@ static int mwifiex_check_winner_status(struct mwifiex_adapter *adapter)
if (!adapter || !adapter->priv_num)
return;
+ cancel_work_sync(&sdio_work);
+
mwifiex_dbg(adapter, INFO, "info: SDIO func num=%d\n", func->num);
ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);
@@ -402,13 +404,6 @@ static int mwifiex_check_winner_status(struct mwifiex_adapter *adapter)
mwifiex_remove_card(adapter);
}
-static void
-mwifiex_sdio_remove(struct sdio_func *func)
-{
- cancel_work_sync(&sdio_work);
- __mwifiex_sdio_remove(func);
-}
-
/*
* SDIO suspend.
*
--
1.9.1
^ permalink raw reply related
* [PATCH 2/5] mwifiex: cleanup in PCIe flr code path
From: Amitkumar Karwar @ 2016-12-14 14:10 UTC (permalink / raw)
To: linux-wireless
Cc: Cathy Luo, Nishant Sarmukadam, rajatja, briannorris,
dmitry.torokhov, Xinming Hu, Amitkumar Karwar
In-Reply-To: <1481724651-30397-1-git-send-email-akarwar@marvell.com>
From: Xinming Hu <huxm@marvell.com>
adapter and card variables don't get freed during PCIe function level
reset. "adapter->ext_scan" variable need not be re-initialized.
fw_name and tx_buf_size initialization is moved to pcie specific code
so that mwifiex_reinit_sw() can be used by SDIO.
Signed-off-by: Xinming Hu <huxm@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
drivers/net/wireless/marvell/mwifiex/main.c | 9 ---------
drivers/net/wireless/marvell/mwifiex/pcie.c | 12 +++++++++++-
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index 3fc6221..9d80180 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -1425,9 +1425,6 @@ static void mwifiex_main_work_queue(struct work_struct *work)
int
mwifiex_reinit_sw(struct mwifiex_adapter *adapter)
{
- char fw_name[32];
- struct pcie_service_card *card = adapter->card;
-
mwifiex_init_lock_list(adapter);
if (adapter->if_ops.up_dev)
adapter->if_ops.up_dev(adapter);
@@ -1468,18 +1465,12 @@ static void mwifiex_main_work_queue(struct work_struct *work)
* mwifiex_register_dev()
*/
mwifiex_dbg(adapter, INFO, "%s, mwifiex_init_hw_fw()...\n", __func__);
- strcpy(fw_name, adapter->fw_name);
- strcpy(adapter->fw_name, PCIE8997_DEFAULT_WIFIFW_NAME);
- adapter->tx_buf_size = card->pcie.tx_buf_size;
- adapter->ext_scan = card->pcie.can_ext_scan;
if (mwifiex_init_hw_fw(adapter, false)) {
- strcpy(adapter->fw_name, fw_name);
mwifiex_dbg(adapter, ERROR,
"%s: firmware init failed\n", __func__);
goto err_init_fw;
}
- strcpy(adapter->fw_name, fw_name);
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
complete_all(adapter->fw_done);
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 02f6db0..66226c6 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -3082,6 +3082,17 @@ static void mwifiex_pcie_up_dev(struct mwifiex_adapter *adapter)
struct pci_dev *pdev = card->dev;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
+ /* Bluetooth is not on pcie interface. Download Wifi only firmware
+ * during pcie FLR, so that bluetooth part of firmware which is
+ * already running doesn't get affected.
+ */
+ strcpy(adapter->fw_name, PCIE8997_DEFAULT_WIFIFW_NAME);
+
+ /* tx_buf_size might be changed to 3584 by firmware during
+ * data transfer, we should reset it to default size.
+ */
+ adapter->tx_buf_size = card->pcie.tx_buf_size;
+
card->cmdrsp_buf = NULL;
ret = mwifiex_pcie_create_txbd_ring(adapter);
if (ret) {
@@ -3143,7 +3154,6 @@ static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter)
mwifiex_dbg(adapter, ERROR, "Failed to write driver not-ready signature\n");
adapter->seq_num = 0;
- adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
if (reg->sleep_cookie)
mwifiex_pcie_delete_sleep_cookie_buf(adapter);
--
1.9.1
^ permalink raw reply related
* [PATCH 5/5] mwifiex: get rid of global save_adapter and sdio_work
From: Amitkumar Karwar @ 2016-12-14 14:10 UTC (permalink / raw)
To: linux-wireless
Cc: Cathy Luo, Nishant Sarmukadam, rajatja, briannorris,
dmitry.torokhov, Xinming Hu, Amitkumar Karwar
In-Reply-To: <1481724651-30397-1-git-send-email-akarwar@marvell.com>
From: Xinming Hu <huxm@marvell.com>
This patch moves sdio_work to card structure, in this way we can get
adapter structure in the work, so save_adapter won't be needed.
Signed-off-by: Xinming Hu <huxm@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
drivers/net/wireless/marvell/mwifiex/sdio.c | 39 ++++++++++++++++-------------
drivers/net/wireless/marvell/mwifiex/sdio.h | 3 +++
2 files changed, 24 insertions(+), 18 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
index 0fda87a..a4b356d 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
@@ -32,10 +32,8 @@
#define SDIO_VERSION "1.0"
static void mwifiex_sdio_work(struct work_struct *work);
-static DECLARE_WORK(sdio_work, mwifiex_sdio_work);
static struct mwifiex_if_ops sdio_ops;
-static unsigned long iface_work_flags;
static struct memory_type_mapping generic_mem_type_map[] = {
{"DUMP", NULL, 0, 0xDD},
@@ -123,6 +121,7 @@ static int mwifiex_sdio_probe_of(struct device *dev)
card->fw_dump_enh = data->fw_dump_enh;
card->can_auto_tdls = data->can_auto_tdls;
card->can_ext_scan = data->can_ext_scan;
+ INIT_WORK(&card->work, mwifiex_sdio_work);
}
sdio_claim_host(func);
@@ -388,7 +387,7 @@ static int mwifiex_check_winner_status(struct mwifiex_adapter *adapter)
if (!adapter || !adapter->priv_num)
return;
- cancel_work_sync(&sdio_work);
+ cancel_work_sync(&card->work);
mwifiex_dbg(adapter, INFO, "info: SDIO func num=%d\n", func->num);
@@ -2190,7 +2189,6 @@ static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)
port, card->mp_data_port_mask);
}
-static struct mwifiex_adapter *save_adapter;
static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
{
struct sdio_mmc_card *card = adapter->card;
@@ -2206,8 +2204,8 @@ static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
/* Previous save_adapter won't be valid after this. We will cancel
* pending work requests.
*/
- clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags);
- clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags);
+ clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
+ clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
mwifiex_reinit_sw(adapter);
}
@@ -2513,35 +2511,40 @@ static void mwifiex_sdio_device_dump_work(struct mwifiex_adapter *adapter)
static void mwifiex_sdio_work(struct work_struct *work)
{
+ struct sdio_mmc_card *card =
+ container_of(work, struct sdio_mmc_card, work);
+
if (test_and_clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,
- &iface_work_flags))
- mwifiex_sdio_device_dump_work(save_adapter);
+ &card->work_flags))
+ mwifiex_sdio_device_dump_work(card->adapter);
if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,
- &iface_work_flags))
- mwifiex_sdio_card_reset_work(save_adapter);
+ &card->work_flags))
+ mwifiex_sdio_card_reset_work(card->adapter);
}
/* This function resets the card */
static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter)
{
- save_adapter = adapter;
- if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags))
+ struct sdio_mmc_card *card = adapter->card;
+
+ if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags))
return;
- set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags);
+ set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
- schedule_work(&sdio_work);
+ schedule_work(&card->work);
}
/* This function dumps FW information */
static void mwifiex_sdio_device_dump(struct mwifiex_adapter *adapter)
{
- save_adapter = adapter;
- if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags))
+ struct sdio_mmc_card *card = adapter->card;
+
+ if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags))
return;
- set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags);
- schedule_work(&sdio_work);
+ set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
+ schedule_work(&card->work);
}
/* Function to dump SDIO function registers and SDIO scratch registers in case
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h
index afa10d5..dccf7fd 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.h
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.h
@@ -267,6 +267,9 @@ struct sdio_mmc_card {
struct mwifiex_sdio_mpa_tx mpa_tx;
struct mwifiex_sdio_mpa_rx mpa_rx;
+
+ struct work_struct work;
+ unsigned long work_flags;
};
struct mwifiex_sdio_device {
--
1.9.1
^ permalink raw reply related
* [PATCH 3/5] mwifiex: sdio card reset enhancement
From: Amitkumar Karwar @ 2016-12-14 14:10 UTC (permalink / raw)
To: linux-wireless
Cc: Cathy Luo, Nishant Sarmukadam, rajatja, briannorris,
dmitry.torokhov, Xinming Hu, Amitkumar Karwar
In-Reply-To: <1481724651-30397-1-git-send-email-akarwar@marvell.com>
From: Xinming Hu <huxm@marvell.com>
Commit b4336a282db8 ("mwifiex: sdio: reset adapter using mmc_hw_reset")
introduces a simple sdio card reset solution based on card remove and
re-probe. This solution has proved to be vulnerable, as card and
adapter structures are not protected, concurrent access will result in
kernel panic issues.
Let's reuse PCIe FLR's functions for SDIO reset to avoid freeing and
reallocating adapter and card structures.
Signed-off-by: Xinming Hu <huxm@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
drivers/net/wireless/marvell/mwifiex/sdio.c | 73 +++++++++++++----------------
drivers/net/wireless/marvell/mwifiex/sdio.h | 3 --
2 files changed, 33 insertions(+), 43 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
index 44eb65a..b3aca10 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
@@ -104,7 +104,6 @@ static int mwifiex_sdio_probe_of(struct device *dev)
init_completion(&card->fw_done);
card->func = func;
- card->device_id = id;
func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
@@ -2196,33 +2195,13 @@ static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)
port, card->mp_data_port_mask);
}
-static void mwifiex_recreate_adapter(struct sdio_mmc_card *card)
+static struct mwifiex_adapter *save_adapter;
+static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
{
+ struct sdio_mmc_card *card = adapter->card;
struct sdio_func *func = card->func;
- const struct sdio_device_id *device_id = card->device_id;
-
- /* TODO mmc_hw_reset does not require destroying and re-probing the
- * whole adapter. Hence there was no need to for this rube-goldberg
- * design to reload the fw from an external workqueue. If we don't
- * destroy the adapter we could reload the fw from
- * mwifiex_main_work_queue directly.
- * The real difficulty with fw reset is to restore all the user
- * settings applied through ioctl. By destroying and recreating the
- * adapter, we take the easy way out, since we rely on user space to
- * restore them. We assume that user space will treat the new
- * incarnation of the adapter(interfaces) as if they had been just
- * discovered and initializes them from scratch.
- */
- __mwifiex_sdio_remove(func);
-
- /*
- * Normally, we would let the driver core take care of releasing these.
- * But we're not letting the driver core handle this one. See above
- * TODO.
- */
- sdio_set_drvdata(func, NULL);
- devm_kfree(&func->dev, card);
+ mwifiex_shutdown_sw(adapter);
/* power cycle the adapter */
sdio_claim_host(func);
@@ -2235,21 +2214,7 @@ static void mwifiex_recreate_adapter(struct sdio_mmc_card *card)
clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags);
clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags);
- mwifiex_sdio_probe(func, device_id);
-}
-
-static struct mwifiex_adapter *save_adapter;
-static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
-{
- struct sdio_mmc_card *card = adapter->card;
-
- /* TODO card pointer is unprotected. If the adapter is removed
- * physically, sdio core might trigger mwifiex_sdio_remove, before this
- * workqueue is run, which will destroy the adapter struct. When this
- * workqueue eventually exceutes it will dereference an invalid adapter
- * pointer
- */
- mwifiex_recreate_adapter(card);
+ mwifiex_reinit_sw(adapter);
}
/* This function read/write firmware */
@@ -2677,6 +2642,33 @@ static void mwifiex_sdio_device_dump(struct mwifiex_adapter *adapter)
return p - drv_buf;
}
+/* sdio device/function initialization, code is extracted
+ * from init_if handler and register_dev handler.
+ */
+static void mwifiex_sdio_up_dev(struct mwifiex_adapter *adapter)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ u8 sdio_ireg;
+
+ sdio_claim_host(card->func);
+ sdio_enable_func(card->func);
+ sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE);
+ sdio_release_host(card->func);
+
+ /* tx_buf_size might be changed to 3584 by firmware during
+ * data transfer, we will reset to default size.
+ */
+ adapter->tx_buf_size = card->tx_buf_size;
+
+ /* Read the host_int_status_reg for ACK the first interrupt got
+ * from the bootloader. If we don't do this we get a interrupt
+ * as soon as we register the irq.
+ */
+ mwifiex_read_reg(adapter, card->reg->host_int_status_reg, &sdio_ireg);
+
+ mwifiex_init_sdio_ioport(adapter);
+}
+
static struct mwifiex_if_ops sdio_ops = {
.init_if = mwifiex_init_sdio,
.cleanup_if = mwifiex_cleanup_sdio,
@@ -2702,6 +2694,7 @@ static void mwifiex_sdio_device_dump(struct mwifiex_adapter *adapter)
.reg_dump = mwifiex_sdio_reg_dump,
.device_dump = mwifiex_sdio_device_dump,
.deaggr_pkt = mwifiex_deaggr_sdio_pkt,
+ .up_dev = mwifiex_sdio_up_dev,
};
module_driver(mwifiex_sdio, sdio_register_driver, sdio_unregister_driver);
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h
index cdbf3a3a..afa10d5 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.h
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.h
@@ -267,9 +267,6 @@ struct sdio_mmc_card {
struct mwifiex_sdio_mpa_tx mpa_tx;
struct mwifiex_sdio_mpa_rx mpa_rx;
-
- /* needed for card reset */
- const struct sdio_device_id *device_id;
};
struct mwifiex_sdio_device {
--
1.9.1
^ permalink raw reply related
* [PATCH 1/5] mwifiex: get rid of mwifiex_do_flr wrapper
From: Amitkumar Karwar @ 2016-12-14 14:10 UTC (permalink / raw)
To: linux-wireless
Cc: Cathy Luo, Nishant Sarmukadam, rajatja, briannorris,
dmitry.torokhov, Xinming Hu, Amitkumar Karwar
From: Xinming Hu <huxm@marvell.com>
This patch gets rid of mwifiex_do_flr. We will call
mwifiex_shutdown_sw() and mwifiex_reinit_sw() directly.
These two general purpose functions will be useful for
sdio card reset handler.
Signed-off-by: Xinming Hu <huxm@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
drivers/net/wireless/marvell/mwifiex/main.c | 31 +++++------------------------
drivers/net/wireless/marvell/mwifiex/main.h | 3 ++-
drivers/net/wireless/marvell/mwifiex/pcie.c | 4 ++--
3 files changed, 9 insertions(+), 29 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index c1821aa..3fc6221 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -1348,7 +1348,7 @@ static void mwifiex_main_work_queue(struct work_struct *work)
* This function gets called during PCIe function level reset. Required
* code is extracted from mwifiex_remove_card()
*/
-static int
+int
mwifiex_shutdown_sw(struct mwifiex_adapter *adapter)
{
struct mwifiex_private *priv;
@@ -1417,13 +1417,13 @@ static void mwifiex_main_work_queue(struct work_struct *work)
exit_return:
return 0;
}
+EXPORT_SYMBOL_GPL(mwifiex_shutdown_sw);
/* This function gets called during PCIe function level reset. Required
* code is extracted from mwifiex_add_card()
*/
-static int
-mwifiex_reinit_sw(struct mwifiex_adapter *adapter, struct completion *fw_done,
- struct mwifiex_if_ops *if_ops, u8 iface_type)
+int
+mwifiex_reinit_sw(struct mwifiex_adapter *adapter)
{
char fw_name[32];
struct pcie_service_card *card = adapter->card;
@@ -1432,9 +1432,6 @@ static void mwifiex_main_work_queue(struct work_struct *work)
if (adapter->if_ops.up_dev)
adapter->if_ops.up_dev(adapter);
- adapter->iface_type = iface_type;
- adapter->fw_done = fw_done;
-
adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
adapter->surprise_removed = false;
init_waitqueue_head(&adapter->init_wait_q);
@@ -1507,25 +1504,7 @@ static void mwifiex_main_work_queue(struct work_struct *work)
return -1;
}
-
-/* This function processes pre and post PCIe function level resets.
- * It performs software cleanup without touching PCIe specific code.
- * Also, during initialization PCIe stuff is skipped.
- */
-void mwifiex_do_flr(struct mwifiex_adapter *adapter, bool prepare)
-{
- struct mwifiex_if_ops if_ops;
-
- if (!prepare) {
- mwifiex_reinit_sw(adapter, adapter->fw_done, &if_ops,
- adapter->iface_type);
- } else {
- memcpy(&if_ops, &adapter->if_ops,
- sizeof(struct mwifiex_if_ops));
- mwifiex_shutdown_sw(adapter);
- }
-}
-EXPORT_SYMBOL_GPL(mwifiex_do_flr);
+EXPORT_SYMBOL_GPL(mwifiex_reinit_sw);
static irqreturn_t mwifiex_irq_wakeup_handler(int irq, void *priv)
{
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index d501d03..5f7a010 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -1666,5 +1666,6 @@ void mwifiex_process_multi_chan_event(struct mwifiex_private *priv,
void mwifiex_dev_debugfs_init(struct mwifiex_private *priv);
void mwifiex_dev_debugfs_remove(struct mwifiex_private *priv);
#endif
-void mwifiex_do_flr(struct mwifiex_adapter *adapter, bool prepare);
+int mwifiex_reinit_sw(struct mwifiex_adapter *adapter);
+int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter);
#endif /* !_MWIFIEX_MAIN_H_ */
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 55c79e3..02f6db0 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -375,7 +375,7 @@ static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
* Cleanup all software without cleaning anything related to
* PCIe and HW.
*/
- mwifiex_do_flr(adapter, prepare);
+ mwifiex_shutdown_sw(adapter);
adapter->surprise_removed = true;
} else {
/* Kernel stores and restores PCIe function context before and
@@ -383,7 +383,7 @@ static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
* and firmware including firmware redownload
*/
adapter->surprise_removed = false;
- mwifiex_do_flr(adapter, prepare);
+ mwifiex_reinit_sw(adapter);
}
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
}
--
1.9.1
^ permalink raw reply related
* Re: [RFC v2 05/11] ath10k: htc: refactorization
From: Valo, Kalle @ 2016-12-14 13:49 UTC (permalink / raw)
To: michal.kazior@tieto.com
Cc: Erik Stromdahl, linux-wireless@vger.kernel.org,
ath10k@lists.infradead.org
In-Reply-To: <CA+BoTQmRV59imnmSykjs=ym0qut9akUHzFKfAMioK=MT8my98A@mail.gmail.com>
Michal Kazior <michal.kazior@tieto.com> writes:
>> I have made a few updates since I submitted the original RFC and created
>> a repo on github:
>>
>> https://github.com/erstrom/linux-ath
>>
>> I have a bunch of branches that are all based on the tags on the ath mas=
ter.
>>
>> As of this moment the latest version is:
>>
>> ath-201612131156-ath10k-sdio
>>
>> This branch contains the original RFC patches plus some addons/fixes.
>>
>> In the above mentioned branch there are a few commits related to this
>> race condition. Perhaps you can have a look at them?
>>
>> The commits are:
>> 821672913328cf737c9616786dc28d2e4e8a4a90
>
> I would avoid if(bus=3D=3Dxx) checks.
Very much agreed. For example to enable HTT high latency support you
could add an enum to ath10k_core_create() with values for both high and
low latency. This way sdio.c and pci.c can enable the correct mode
during initialisation.
--=20
Kalle Valo=
^ 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