refresh
This commit is contained in:
parent
4f762a48b9
commit
40cea26d4e
@ -1 +0,0 @@
|
||||
12
|
@ -1 +0,0 @@
|
||||
12
|
@ -1,36 +0,0 @@
|
||||
--- a/net/mac80211/vht.c
|
||||
+++ b/net/mac80211/vht.c
|
||||
@@ -135,7 +135,8 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(stru
|
||||
have_80mhz = false;
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
|
||||
- IEEE80211_CHAN_NO_80MHZ))
|
||||
+ IEEE80211_CHAN_NO_80MHZ) &&
|
||||
+ (sband->band != NL80211_BAND_2GHZ))
|
||||
continue;
|
||||
|
||||
have_80mhz = true;
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -1775,7 +1775,8 @@ static int ieee80211_build_preq_ies_band
|
||||
/* Check if any channel in this sband supports at least 80 MHz */
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
|
||||
- IEEE80211_CHAN_NO_80MHZ))
|
||||
+ IEEE80211_CHAN_NO_80MHZ) &&
|
||||
+ (sband->band != NL80211_BAND_2GHZ))
|
||||
continue;
|
||||
|
||||
have_80mhz = true;
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -4821,7 +4821,8 @@ static int ieee80211_prep_channel(struct
|
||||
have_80mhz = false;
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
|
||||
- IEEE80211_CHAN_NO_80MHZ))
|
||||
+ IEEE80211_CHAN_NO_80MHZ) &&
|
||||
+ (sband->band != NL80211_BAND_2GHZ))
|
||||
continue;
|
||||
|
||||
have_80mhz = true;
|
@ -1,767 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 22 Jan 2021 23:57:50 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: significantly redesign the rate
|
||||
probing strategy
|
||||
|
||||
The biggest flaw in current minstrel_ht is the fact that it needs way too
|
||||
many probing packets to be able to quickly find the best rate.
|
||||
Depending on the wifi hardware and operating mode, this can significantly
|
||||
reduce throughput when not operating at the highest available data rate.
|
||||
|
||||
In order to be able to significantly reduce the amount of rate sampling,
|
||||
we need a much smarter selection of probing rates.
|
||||
|
||||
The new approach introduced by this patch maintains a limited set of
|
||||
available rates to be tested during a statistics window.
|
||||
|
||||
They are split into distinct categories:
|
||||
- MINSTREL_SAMPLE_TYPE_INC - incremental rate upgrade:
|
||||
Pick the next rate group and find the first rate that is faster than
|
||||
the current max. throughput rate
|
||||
- MINSTREL_SAMPLE_TYPE_JUMP - random testing of higher rates:
|
||||
Pick a random rate from the next group that is faster than the current
|
||||
max throughput rate. This allows faster adaptation when the link changes
|
||||
significantly
|
||||
- MINSTREL_SAMPLE_TYPE_SLOW - test a rate between max_prob, max_tp2 and
|
||||
max_tp in order to reduce the gap between them
|
||||
|
||||
In order to prioritize sampling, every 6 attempts are split into 3x INC,
|
||||
2x JUMP, 1x SLOW.
|
||||
|
||||
Available rates are checked and refilled on every stats window update.
|
||||
|
||||
With this approach, we finally get a very small delta in throughput when
|
||||
comparing setting the optimal data rate as a fixed rate vs normal rate
|
||||
control operation.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -266,6 +266,14 @@ const struct mcs_group minstrel_mcs_grou
|
||||
const s16 minstrel_cck_bitrates[4] = { 10, 20, 55, 110 };
|
||||
const s16 minstrel_ofdm_bitrates[8] = { 60, 90, 120, 180, 240, 360, 480, 540 };
|
||||
static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
|
||||
+static const u8 minstrel_sample_seq[] = {
|
||||
+ MINSTREL_SAMPLE_TYPE_INC,
|
||||
+ MINSTREL_SAMPLE_TYPE_JUMP,
|
||||
+ MINSTREL_SAMPLE_TYPE_INC,
|
||||
+ MINSTREL_SAMPLE_TYPE_JUMP,
|
||||
+ MINSTREL_SAMPLE_TYPE_INC,
|
||||
+ MINSTREL_SAMPLE_TYPE_SLOW,
|
||||
+};
|
||||
|
||||
static void
|
||||
minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi);
|
||||
@@ -620,77 +628,31 @@ minstrel_ht_prob_rate_reduce_streams(str
|
||||
}
|
||||
}
|
||||
|
||||
-static bool
|
||||
-minstrel_ht_probe_group(struct minstrel_ht_sta *mi, const struct mcs_group *tp_group,
|
||||
- int tp_idx, const struct mcs_group *group)
|
||||
-{
|
||||
- if (group->bw < tp_group->bw)
|
||||
- return false;
|
||||
-
|
||||
- if (group->streams == tp_group->streams)
|
||||
- return true;
|
||||
-
|
||||
- if (tp_idx < 4 && group->streams == tp_group->streams - 1)
|
||||
- return true;
|
||||
-
|
||||
- return group->streams == tp_group->streams + 1;
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-minstrel_ht_find_probe_rates(struct minstrel_ht_sta *mi, u16 *rates, int *n_rates,
|
||||
- bool faster_rate)
|
||||
+static u16
|
||||
+__minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi,
|
||||
+ enum minstrel_sample_type type)
|
||||
{
|
||||
- const struct mcs_group *group, *tp_group;
|
||||
- int i, g, max_dur;
|
||||
- int tp_idx;
|
||||
-
|
||||
- tp_group = &minstrel_mcs_groups[MI_RATE_GROUP(mi->max_tp_rate[0])];
|
||||
- tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]);
|
||||
-
|
||||
- max_dur = minstrel_get_duration(mi->max_tp_rate[0]);
|
||||
- if (faster_rate)
|
||||
- max_dur -= max_dur / 16;
|
||||
-
|
||||
- for (g = 0; g < MINSTREL_GROUPS_NB; g++) {
|
||||
- u16 supported = mi->supported[g];
|
||||
-
|
||||
- if (!supported)
|
||||
- continue;
|
||||
+ u16 *rates = mi->sample[type].sample_rates;
|
||||
+ u16 cur;
|
||||
+ int i;
|
||||
|
||||
- group = &minstrel_mcs_groups[g];
|
||||
- if (!minstrel_ht_probe_group(mi, tp_group, tp_idx, group))
|
||||
+ for (i = 0; i < MINSTREL_SAMPLE_RATES; i++) {
|
||||
+ if (!rates[i])
|
||||
continue;
|
||||
|
||||
- for (i = 0; supported; supported >>= 1, i++) {
|
||||
- int idx;
|
||||
-
|
||||
- if (!(supported & 1))
|
||||
- continue;
|
||||
-
|
||||
- if ((group->duration[i] << group->shift) > max_dur)
|
||||
- continue;
|
||||
-
|
||||
- idx = MI_RATE(g, i);
|
||||
- if (idx == mi->max_tp_rate[0])
|
||||
- continue;
|
||||
-
|
||||
- rates[(*n_rates)++] = idx;
|
||||
- break;
|
||||
- }
|
||||
+ cur = rates[i];
|
||||
+ rates[i] = 0;
|
||||
+ return cur;
|
||||
}
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
minstrel_ht_rate_sample_switch(struct minstrel_priv *mp,
|
||||
struct minstrel_ht_sta *mi)
|
||||
{
|
||||
- struct minstrel_rate_stats *mrs;
|
||||
- u16 rates[MINSTREL_GROUPS_NB];
|
||||
- int n_rates = 0;
|
||||
- int probe_rate = 0;
|
||||
- bool faster_rate;
|
||||
- int i;
|
||||
- u8 random;
|
||||
+ u16 rate;
|
||||
|
||||
/*
|
||||
* Use rate switching instead of probing packets for devices with
|
||||
@@ -699,43 +661,11 @@ minstrel_ht_rate_sample_switch(struct mi
|
||||
if (mp->hw->max_rates > 1)
|
||||
return;
|
||||
|
||||
- /*
|
||||
- * If the current EWMA prob is >75%, look for a rate that's 6.25%
|
||||
- * faster than the max tp rate.
|
||||
- * If that fails, look again for a rate that is at least as fast
|
||||
- */
|
||||
- mrs = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
|
||||
- faster_rate = mrs->prob_avg > MINSTREL_FRAC(75, 100);
|
||||
- minstrel_ht_find_probe_rates(mi, rates, &n_rates, faster_rate);
|
||||
- if (!n_rates && faster_rate)
|
||||
- minstrel_ht_find_probe_rates(mi, rates, &n_rates, false);
|
||||
-
|
||||
- /* If no suitable rate was found, try to pick the next one in the group */
|
||||
- if (!n_rates) {
|
||||
- int g_idx = MI_RATE_GROUP(mi->max_tp_rate[0]);
|
||||
- u16 supported = mi->supported[g_idx];
|
||||
-
|
||||
- supported >>= MI_RATE_IDX(mi->max_tp_rate[0]);
|
||||
- for (i = 0; supported; supported >>= 1, i++) {
|
||||
- if (!(supported & 1))
|
||||
- continue;
|
||||
-
|
||||
- probe_rate = mi->max_tp_rate[0] + i;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
+ rate = __minstrel_ht_get_sample_rate(mi, MINSTREL_SAMPLE_TYPE_INC);
|
||||
+ if (!rate)
|
||||
return;
|
||||
- }
|
||||
-
|
||||
- i = 0;
|
||||
- if (n_rates > 1) {
|
||||
- random = prandom_u32();
|
||||
- i = random % n_rates;
|
||||
- }
|
||||
- probe_rate = rates[i];
|
||||
|
||||
-out:
|
||||
- mi->sample_rate = probe_rate;
|
||||
+ mi->sample_rate = rate;
|
||||
mi->sample_mode = MINSTREL_SAMPLE_ACTIVE;
|
||||
}
|
||||
|
||||
@@ -804,6 +734,274 @@ minstrel_ht_calc_rate_stats(struct minst
|
||||
mrs->attempts = 0;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+minstrel_ht_find_sample_rate(struct minstrel_ht_sta *mi, int type, int idx)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MINSTREL_SAMPLE_RATES; i++) {
|
||||
+ u16 cur = mi->sample[type].sample_rates[i];
|
||||
+
|
||||
+ if (cur == idx)
|
||||
+ return true;
|
||||
+
|
||||
+ if (!cur)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+minstrel_ht_move_sample_rates(struct minstrel_ht_sta *mi, int type,
|
||||
+ u32 fast_rate_dur, u32 slow_rate_dur)
|
||||
+{
|
||||
+ u16 *rates = mi->sample[type].sample_rates;
|
||||
+ int i, j;
|
||||
+
|
||||
+ for (i = 0, j = 0; i < MINSTREL_SAMPLE_RATES; i++) {
|
||||
+ u32 duration;
|
||||
+ bool valid = false;
|
||||
+ u16 cur;
|
||||
+
|
||||
+ cur = rates[i];
|
||||
+ if (!cur)
|
||||
+ continue;
|
||||
+
|
||||
+ duration = minstrel_get_duration(cur);
|
||||
+ switch (type) {
|
||||
+ case MINSTREL_SAMPLE_TYPE_SLOW:
|
||||
+ valid = duration > fast_rate_dur &&
|
||||
+ duration < slow_rate_dur;
|
||||
+ break;
|
||||
+ case MINSTREL_SAMPLE_TYPE_INC:
|
||||
+ case MINSTREL_SAMPLE_TYPE_JUMP:
|
||||
+ valid = duration < fast_rate_dur;
|
||||
+ break;
|
||||
+ default:
|
||||
+ valid = false;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!valid) {
|
||||
+ rates[i] = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (i == j)
|
||||
+ continue;
|
||||
+
|
||||
+ rates[j++] = cur;
|
||||
+ rates[i] = 0;
|
||||
+ }
|
||||
+
|
||||
+ return j;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+minstrel_ht_group_min_rate_offset(struct minstrel_ht_sta *mi, int group,
|
||||
+ u32 max_duration)
|
||||
+{
|
||||
+ u16 supported = mi->supported[group];
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MCS_GROUP_RATES && supported; i++, supported >>= 1) {
|
||||
+ if (!(supported & BIT(0)))
|
||||
+ continue;
|
||||
+
|
||||
+ if (minstrel_get_duration(MI_RATE(group, i)) >= max_duration)
|
||||
+ continue;
|
||||
+
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Incremental update rates:
|
||||
+ * Flip through groups and pick the first group rate that is faster than the
|
||||
+ * highest currently selected rate
|
||||
+ */
|
||||
+static u16
|
||||
+minstrel_ht_next_inc_rate(struct minstrel_ht_sta *mi, u32 fast_rate_dur)
|
||||
+{
|
||||
+ struct minstrel_mcs_group_data *mg;
|
||||
+ u8 type = MINSTREL_SAMPLE_TYPE_INC;
|
||||
+ int i, index = 0;
|
||||
+ u8 group;
|
||||
+
|
||||
+ group = mi->sample[type].sample_group;
|
||||
+ for (i = 0; i < ARRAY_SIZE(minstrel_mcs_groups); i++) {
|
||||
+ group = (group + 1) % ARRAY_SIZE(minstrel_mcs_groups);
|
||||
+ mg = &mi->groups[group];
|
||||
+
|
||||
+ index = minstrel_ht_group_min_rate_offset(mi, group,
|
||||
+ fast_rate_dur);
|
||||
+ if (index < 0)
|
||||
+ continue;
|
||||
+
|
||||
+ index = MI_RATE(group, index & 0xf);
|
||||
+ if (!minstrel_ht_find_sample_rate(mi, type, index))
|
||||
+ goto out;
|
||||
+ }
|
||||
+ index = 0;
|
||||
+
|
||||
+out:
|
||||
+ mi->sample[type].sample_group = group;
|
||||
+
|
||||
+ return index;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+minstrel_ht_next_group_sample_rate(struct minstrel_ht_sta *mi, int group,
|
||||
+ u16 supported, int offset)
|
||||
+{
|
||||
+ struct minstrel_mcs_group_data *mg = &mi->groups[group];
|
||||
+ u16 idx;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MCS_GROUP_RATES; i++) {
|
||||
+ idx = sample_table[mg->column][mg->index];
|
||||
+ if (++mg->index >= MCS_GROUP_RATES) {
|
||||
+ mg->index = 0;
|
||||
+ if (++mg->column >= ARRAY_SIZE(sample_table))
|
||||
+ mg->column = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (idx < offset)
|
||||
+ continue;
|
||||
+
|
||||
+ if (!(supported & BIT(idx)))
|
||||
+ continue;
|
||||
+
|
||||
+ return MI_RATE(group, idx);
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Jump rates:
|
||||
+ * Sample random rates, use those that are faster than the highest
|
||||
+ * currently selected rate. Rates between the fastest and the slowest
|
||||
+ * get sorted into the slow sample bucket, but only if it has room
|
||||
+ */
|
||||
+static u16
|
||||
+minstrel_ht_next_jump_rate(struct minstrel_ht_sta *mi, u32 fast_rate_dur,
|
||||
+ u32 slow_rate_dur, int *slow_rate_ofs)
|
||||
+{
|
||||
+ struct minstrel_mcs_group_data *mg;
|
||||
+ struct minstrel_rate_stats *mrs;
|
||||
+ u32 max_duration = slow_rate_dur;
|
||||
+ int i, index, offset;
|
||||
+ u16 *slow_rates;
|
||||
+ u16 supported;
|
||||
+ u32 duration;
|
||||
+ u8 group;
|
||||
+
|
||||
+ if (*slow_rate_ofs >= MINSTREL_SAMPLE_RATES)
|
||||
+ max_duration = fast_rate_dur;
|
||||
+
|
||||
+ slow_rates = mi->sample[MINSTREL_SAMPLE_TYPE_SLOW].sample_rates;
|
||||
+ group = mi->sample[MINSTREL_SAMPLE_TYPE_JUMP].sample_group;
|
||||
+ for (i = 0; i < ARRAY_SIZE(minstrel_mcs_groups); i++) {
|
||||
+ u8 type;
|
||||
+
|
||||
+ group = (group + 1) % ARRAY_SIZE(minstrel_mcs_groups);
|
||||
+ mg = &mi->groups[group];
|
||||
+
|
||||
+ supported = mi->supported[group];
|
||||
+ if (!supported)
|
||||
+ continue;
|
||||
+
|
||||
+ offset = minstrel_ht_group_min_rate_offset(mi, group,
|
||||
+ max_duration);
|
||||
+ if (offset < 0)
|
||||
+ continue;
|
||||
+
|
||||
+ index = minstrel_ht_next_group_sample_rate(mi, group, supported,
|
||||
+ offset);
|
||||
+ if (index < 0)
|
||||
+ continue;
|
||||
+
|
||||
+ duration = minstrel_get_duration(index);
|
||||
+ if (duration < fast_rate_dur)
|
||||
+ type = MINSTREL_SAMPLE_TYPE_JUMP;
|
||||
+ else
|
||||
+ type = MINSTREL_SAMPLE_TYPE_SLOW;
|
||||
+
|
||||
+ if (minstrel_ht_find_sample_rate(mi, type, index))
|
||||
+ continue;
|
||||
+
|
||||
+ if (type == MINSTREL_SAMPLE_TYPE_JUMP)
|
||||
+ goto found;
|
||||
+
|
||||
+ if (*slow_rate_ofs >= MINSTREL_SAMPLE_RATES)
|
||||
+ continue;
|
||||
+
|
||||
+ if (duration >= slow_rate_dur)
|
||||
+ continue;
|
||||
+
|
||||
+ /* skip slow rates with high success probability */
|
||||
+ mrs = minstrel_get_ratestats(mi, index);
|
||||
+ if (mrs->prob_avg > MINSTREL_FRAC(95, 100))
|
||||
+ continue;
|
||||
+
|
||||
+ slow_rates[(*slow_rate_ofs)++] = index;
|
||||
+ if (*slow_rate_ofs >= MINSTREL_SAMPLE_RATES)
|
||||
+ max_duration = fast_rate_dur;
|
||||
+ }
|
||||
+ index = 0;
|
||||
+
|
||||
+found:
|
||||
+ mi->sample[MINSTREL_SAMPLE_TYPE_JUMP].sample_group = group;
|
||||
+
|
||||
+ return index;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+minstrel_ht_refill_sample_rates(struct minstrel_ht_sta *mi)
|
||||
+{
|
||||
+ u32 prob_dur = minstrel_get_duration(mi->max_prob_rate);
|
||||
+ u32 tp_dur = minstrel_get_duration(mi->max_tp_rate[0]);
|
||||
+ u32 tp2_dur = minstrel_get_duration(mi->max_tp_rate[1]);
|
||||
+ u32 fast_rate_dur = min(min(tp_dur, tp2_dur), prob_dur);
|
||||
+ u32 slow_rate_dur = max(max(tp_dur, tp2_dur), prob_dur);
|
||||
+ u16 *rates;
|
||||
+ int i, j;
|
||||
+
|
||||
+ rates = mi->sample[MINSTREL_SAMPLE_TYPE_INC].sample_rates;
|
||||
+ i = minstrel_ht_move_sample_rates(mi, MINSTREL_SAMPLE_TYPE_INC,
|
||||
+ fast_rate_dur, slow_rate_dur);
|
||||
+ while (i < MINSTREL_SAMPLE_RATES) {
|
||||
+ rates[i] = minstrel_ht_next_inc_rate(mi, tp_dur);
|
||||
+ if (!rates[i])
|
||||
+ break;
|
||||
+
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ rates = mi->sample[MINSTREL_SAMPLE_TYPE_JUMP].sample_rates;
|
||||
+ i = minstrel_ht_move_sample_rates(mi, MINSTREL_SAMPLE_TYPE_JUMP,
|
||||
+ fast_rate_dur, slow_rate_dur);
|
||||
+ j = minstrel_ht_move_sample_rates(mi, MINSTREL_SAMPLE_TYPE_SLOW,
|
||||
+ fast_rate_dur, slow_rate_dur);
|
||||
+ while (i < MINSTREL_SAMPLE_RATES) {
|
||||
+ rates[i] = minstrel_ht_next_jump_rate(mi, fast_rate_dur,
|
||||
+ slow_rate_dur, &j);
|
||||
+ if (!rates[i])
|
||||
+ break;
|
||||
+
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(mi->sample); i++)
|
||||
+ memcpy(mi->sample[i].cur_sample_rates, mi->sample[i].sample_rates,
|
||||
+ sizeof(mi->sample[i].cur_sample_rates));
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Update rate statistics and select new primary rates
|
||||
*
|
||||
@@ -848,8 +1046,6 @@ minstrel_ht_update_stats(struct minstrel
|
||||
mi->ampdu_packets = 0;
|
||||
}
|
||||
|
||||
- mi->sample_count = 0;
|
||||
-
|
||||
if (mi->supported[MINSTREL_CCK_GROUP])
|
||||
group = MINSTREL_CCK_GROUP;
|
||||
else if (mi->supported[MINSTREL_OFDM_GROUP])
|
||||
@@ -884,8 +1080,6 @@ minstrel_ht_update_stats(struct minstrel
|
||||
if (!mi->supported[group])
|
||||
continue;
|
||||
|
||||
- mi->sample_count++;
|
||||
-
|
||||
/* (re)Initialize group rate indexes */
|
||||
for(j = 0; j < MAX_THR_RATES; j++)
|
||||
tmp_group_tp_rate[j] = MI_RATE(group, 0);
|
||||
@@ -952,9 +1146,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
|
||||
/* Try to increase robustness of max_prob_rate*/
|
||||
minstrel_ht_prob_rate_reduce_streams(mi);
|
||||
-
|
||||
- /* try to sample half of all available rates during each interval */
|
||||
- mi->sample_count *= 4;
|
||||
+ minstrel_ht_refill_sample_rates(mi);
|
||||
|
||||
if (sample)
|
||||
minstrel_ht_rate_sample_switch(mp, mi);
|
||||
@@ -971,6 +1163,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
|
||||
/* Reset update timer */
|
||||
mi->last_stats_update = jiffies;
|
||||
+ mi->sample_time = jiffies;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -1001,28 +1194,6 @@ minstrel_ht_txstat_valid(struct minstrel
|
||||
}
|
||||
|
||||
static void
|
||||
-minstrel_set_next_sample_idx(struct minstrel_ht_sta *mi)
|
||||
-{
|
||||
- struct minstrel_mcs_group_data *mg;
|
||||
-
|
||||
- for (;;) {
|
||||
- mi->sample_group++;
|
||||
- mi->sample_group %= ARRAY_SIZE(minstrel_mcs_groups);
|
||||
- mg = &mi->groups[mi->sample_group];
|
||||
-
|
||||
- if (!mi->supported[mi->sample_group])
|
||||
- continue;
|
||||
-
|
||||
- if (++mg->index >= MCS_GROUP_RATES) {
|
||||
- mg->index = 0;
|
||||
- if (++mg->column >= ARRAY_SIZE(sample_table))
|
||||
- mg->column = 0;
|
||||
- }
|
||||
- break;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
|
||||
{
|
||||
int group, orig_group;
|
||||
@@ -1107,14 +1278,6 @@ minstrel_ht_tx_status(void *priv, struct
|
||||
mi->ampdu_packets++;
|
||||
mi->ampdu_len += info->status.ampdu_len;
|
||||
|
||||
- if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
|
||||
- int avg_ampdu_len = minstrel_ht_avg_ampdu_len(mi);
|
||||
-
|
||||
- mi->sample_wait = 16 + 2 * avg_ampdu_len;
|
||||
- mi->sample_tries = 1;
|
||||
- mi->sample_count--;
|
||||
- }
|
||||
-
|
||||
if (mi->sample_mode != MINSTREL_SAMPLE_IDLE)
|
||||
rate_sample = minstrel_get_ratestats(mi, mi->sample_rate);
|
||||
|
||||
@@ -1386,97 +1549,20 @@ minstrel_ht_update_rates(struct minstrel
|
||||
rate_control_set_rates(mp->hw, mi->sta, rates);
|
||||
}
|
||||
|
||||
-static int
|
||||
-minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||
+static u16
|
||||
+minstrel_ht_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||
{
|
||||
- struct minstrel_rate_stats *mrs;
|
||||
- struct minstrel_mcs_group_data *mg;
|
||||
- unsigned int sample_dur, sample_group, cur_max_tp_streams;
|
||||
- int tp_rate1, tp_rate2;
|
||||
- int sample_idx = 0;
|
||||
-
|
||||
- if (mp->hw->max_rates == 1 && mp->sample_switch &&
|
||||
- (mi->total_packets_cur >= SAMPLE_SWITCH_THR ||
|
||||
- mp->sample_switch == 1))
|
||||
- return -1;
|
||||
-
|
||||
- if (mi->sample_wait > 0) {
|
||||
- mi->sample_wait--;
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- if (!mi->sample_tries)
|
||||
- return -1;
|
||||
-
|
||||
- sample_group = mi->sample_group;
|
||||
- mg = &mi->groups[sample_group];
|
||||
- sample_idx = sample_table[mg->column][mg->index];
|
||||
- minstrel_set_next_sample_idx(mi);
|
||||
-
|
||||
- if (!(mi->supported[sample_group] & BIT(sample_idx)))
|
||||
- return -1;
|
||||
+ u8 seq;
|
||||
|
||||
- mrs = &mg->rates[sample_idx];
|
||||
- sample_idx += MI_RATE(sample_group, 0);
|
||||
-
|
||||
- tp_rate1 = mi->max_tp_rate[0];
|
||||
-
|
||||
- /* Set tp_rate2 to the second highest max_tp_rate */
|
||||
- if (minstrel_get_duration(mi->max_tp_rate[0]) >
|
||||
- minstrel_get_duration(mi->max_tp_rate[1])) {
|
||||
- tp_rate2 = mi->max_tp_rate[0];
|
||||
+ if (mp->hw->max_rates > 1) {
|
||||
+ seq = mi->sample_seq;
|
||||
+ mi->sample_seq = (seq + 1) % ARRAY_SIZE(minstrel_sample_seq);
|
||||
+ seq = minstrel_sample_seq[seq];
|
||||
} else {
|
||||
- tp_rate2 = mi->max_tp_rate[1];
|
||||
+ seq = MINSTREL_SAMPLE_TYPE_INC;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Sampling might add some overhead (RTS, no aggregation)
|
||||
- * to the frame. Hence, don't use sampling for the highest currently
|
||||
- * used highest throughput or probability rate.
|
||||
- */
|
||||
- if (sample_idx == mi->max_tp_rate[0] || sample_idx == mi->max_prob_rate)
|
||||
- return -1;
|
||||
-
|
||||
- /*
|
||||
- * Do not sample if the probability is already higher than 95%,
|
||||
- * or if the rate is 3 times slower than the current max probability
|
||||
- * rate, to avoid wasting airtime.
|
||||
- */
|
||||
- sample_dur = minstrel_get_duration(sample_idx);
|
||||
- if (mrs->prob_avg > MINSTREL_FRAC(95, 100) ||
|
||||
- minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur)
|
||||
- return -1;
|
||||
-
|
||||
-
|
||||
- /*
|
||||
- * For devices with no configurable multi-rate retry, skip sampling
|
||||
- * below the per-group max throughput rate, and only use one sampling
|
||||
- * attempt per rate
|
||||
- */
|
||||
- if (mp->hw->max_rates == 1 &&
|
||||
- (minstrel_get_duration(mg->max_group_tp_rate[0]) < sample_dur ||
|
||||
- mrs->attempts))
|
||||
- return -1;
|
||||
-
|
||||
- /* Skip already sampled slow rates */
|
||||
- if (sample_dur >= minstrel_get_duration(tp_rate1) && mrs->attempts)
|
||||
- return -1;
|
||||
-
|
||||
- /*
|
||||
- * Make sure that lower rates get sampled only occasionally,
|
||||
- * if the link is working perfectly.
|
||||
- */
|
||||
-
|
||||
- cur_max_tp_streams = minstrel_mcs_groups[MI_RATE_GROUP(tp_rate1)].streams;
|
||||
- if (sample_dur >= minstrel_get_duration(tp_rate2) &&
|
||||
- (cur_max_tp_streams - 1 <
|
||||
- minstrel_mcs_groups[sample_group].streams ||
|
||||
- sample_dur >= minstrel_get_duration(mi->max_prob_rate)))
|
||||
- return -1;
|
||||
-
|
||||
- mi->sample_tries--;
|
||||
-
|
||||
- return sample_idx;
|
||||
+ return __minstrel_ht_get_sample_rate(mi, seq);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1488,7 +1574,7 @@ minstrel_ht_get_rate(void *priv, struct
|
||||
struct ieee80211_tx_rate *rate = &info->status.rates[0];
|
||||
struct minstrel_ht_sta *mi = priv_sta;
|
||||
struct minstrel_priv *mp = priv;
|
||||
- int sample_idx;
|
||||
+ u16 sample_idx;
|
||||
|
||||
if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
|
||||
!minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_prob_rate)))
|
||||
@@ -1504,11 +1590,19 @@ minstrel_ht_get_rate(void *priv, struct
|
||||
/* 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))
|
||||
- sample_idx = -1;
|
||||
- else
|
||||
- sample_idx = minstrel_get_sample_rate(mp, mi);
|
||||
+ return;
|
||||
+
|
||||
+ if (mp->hw->max_rates == 1 && mp->sample_switch &&
|
||||
+ (mi->total_packets_cur >= SAMPLE_SWITCH_THR ||
|
||||
+ mp->sample_switch == 1))
|
||||
+ return;
|
||||
+
|
||||
+ if (time_is_before_jiffies(mi->sample_time))
|
||||
+ return;
|
||||
|
||||
- if (sample_idx < 0)
|
||||
+ mi->sample_time = jiffies + MINSTREL_SAMPLE_INTERVAL;
|
||||
+ sample_idx = minstrel_ht_get_sample_rate(mp, mi);
|
||||
+ if (!sample_idx)
|
||||
return;
|
||||
|
||||
sample_group = &minstrel_mcs_groups[MI_RATE_GROUP(sample_idx)];
|
||||
@@ -1629,16 +1723,6 @@ minstrel_ht_update_caps(void *priv, stru
|
||||
|
||||
mi->avg_ampdu_len = MINSTREL_FRAC(1, 1);
|
||||
|
||||
- /* When using MRR, sample more on the first attempt, without delay */
|
||||
- if (mp->has_mrr) {
|
||||
- mi->sample_count = 16;
|
||||
- mi->sample_wait = 0;
|
||||
- } else {
|
||||
- mi->sample_count = 8;
|
||||
- mi->sample_wait = 8;
|
||||
- }
|
||||
- mi->sample_tries = 4;
|
||||
-
|
||||
if (!use_vht) {
|
||||
stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >>
|
||||
IEEE80211_HT_CAP_RX_STBC_SHIFT;
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.h
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
||||
@@ -69,6 +69,8 @@
|
||||
#define MI_RATE_IDX(_rate) FIELD_GET(MI_RATE_IDX_MASK, _rate)
|
||||
#define MI_RATE_GROUP(_rate) FIELD_GET(MI_RATE_GROUP_MASK, _rate)
|
||||
|
||||
+#define MINSTREL_SAMPLE_RATES 5 /* rates per sample type */
|
||||
+#define MINSTREL_SAMPLE_INTERVAL (HZ / 50)
|
||||
|
||||
struct minstrel_priv {
|
||||
struct ieee80211_hw *hw;
|
||||
@@ -126,6 +128,13 @@ struct minstrel_rate_stats {
|
||||
bool retry_updated;
|
||||
};
|
||||
|
||||
+enum minstrel_sample_type {
|
||||
+ MINSTREL_SAMPLE_TYPE_INC,
|
||||
+ MINSTREL_SAMPLE_TYPE_JUMP,
|
||||
+ MINSTREL_SAMPLE_TYPE_SLOW,
|
||||
+ __MINSTREL_SAMPLE_TYPE_MAX
|
||||
+};
|
||||
+
|
||||
struct minstrel_mcs_group_data {
|
||||
u8 index;
|
||||
u8 column;
|
||||
@@ -144,6 +153,12 @@ enum minstrel_sample_mode {
|
||||
MINSTREL_SAMPLE_PENDING,
|
||||
};
|
||||
|
||||
+struct minstrel_sample_category {
|
||||
+ u8 sample_group;
|
||||
+ u16 sample_rates[MINSTREL_SAMPLE_RATES];
|
||||
+ u16 cur_sample_rates[MINSTREL_SAMPLE_RATES];
|
||||
+};
|
||||
+
|
||||
struct minstrel_ht_sta {
|
||||
struct ieee80211_sta *sta;
|
||||
|
||||
@@ -175,16 +190,14 @@ struct minstrel_ht_sta {
|
||||
/* tx flags to add for frames for this sta */
|
||||
u32 tx_flags;
|
||||
|
||||
- u8 sample_wait;
|
||||
- u8 sample_tries;
|
||||
- u8 sample_count;
|
||||
+ unsigned long sample_time;
|
||||
+ struct minstrel_sample_category sample[__MINSTREL_SAMPLE_TYPE_MAX];
|
||||
+
|
||||
+ u8 sample_seq;
|
||||
|
||||
enum minstrel_sample_mode sample_mode;
|
||||
u16 sample_rate;
|
||||
|
||||
- /* current MCS group to be sampled */
|
||||
- u8 sample_group;
|
||||
-
|
||||
u8 band;
|
||||
|
||||
/* Bitfield of supported MCS rates of all groups */
|
@ -1,67 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -8419,6 +8419,56 @@ static void rt2800_init_rfcsr_5592(struc
|
||||
rt2800_led_open_drain_enable(rt2x00dev);
|
||||
}
|
||||
|
||||
+static void rt2800_rf_self_txdc_cal(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ u8 rfb5r1_org, rfb7r1_org, rfvalue;
|
||||
+ u32 mac0518, mac051c, mac0528, mac052c;
|
||||
+ u8 i;
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "RF Tx self calibration start\n");
|
||||
+ mac0518 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
|
||||
+ mac051c = rt2800_register_read(rt2x00dev, RF_BYPASS0);
|
||||
+ mac0528 = rt2800_register_read(rt2x00dev, RF_CONTROL2);
|
||||
+ mac052c = rt2800_register_read(rt2x00dev, RF_BYPASS2);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x0);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS2, 0x0);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0xC);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x3306);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL2, 0x3330);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS2, 0xfffff);
|
||||
+ rfb5r1_org = rt2800_rfcsr_read_bank(rt2x00dev, 5, 1);
|
||||
+ rfb7r1_org = rt2800_rfcsr_read_bank(rt2x00dev, 7, 1);
|
||||
+
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, 0x4);
|
||||
+ for (i = 0; i < 100; i = i + 1) {
|
||||
+ udelay(50);
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 1);
|
||||
+ if((rfvalue & 0x04) != 0x4)
|
||||
+ break;
|
||||
+ }
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, rfb5r1_org);
|
||||
+
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 1, 0x4);
|
||||
+ for (i = 0; i < 100; i = i + 1) {
|
||||
+ udelay(50);
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 1);
|
||||
+ if((rfvalue & 0x04) != 0x4)
|
||||
+ break;
|
||||
+ }
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 1, rfb7r1_org);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x0);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS2, 0x0);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, mac0518);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, mac051c);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL2, mac0528);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS2, mac052c);
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "RF Tx self calibration end\n");
|
||||
+}
|
||||
+
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9026,6 +9076,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
|
||||
|
||||
+ rt2800_rf_self_txdc_cal(rt2x00dev);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, true);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
Date: Mon, 19 Apr 2021 14:59:56 +0800
|
||||
From: Ping-Ke Shih <pkshih@realtek.com>
|
||||
To: <kvalo@codeaurora.org>
|
||||
CC: <linux-wireless@vger.kernel.org>, <mail@maciej.szmigiero.name>,
|
||||
<Larry.Finger@lwfinger.net>
|
||||
Subject: [PATCH] rtlwifi: implement set_tim by update beacon content
|
||||
|
||||
Once beacon content is changed, we update the content to wifi card by
|
||||
send_beacon_frame(). Then, STA with PS can wake up properly to receive its
|
||||
packets.
|
||||
|
||||
Since we update beacon content to PCI wifi devices every beacon interval,
|
||||
the only one usb device, 8192CU, needs to update beacon content when
|
||||
mac80211 calling set_tim.
|
||||
|
||||
Reported-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
|
||||
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Tested-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
|
||||
---
|
||||
drivers/net/wireless/realtek/rtlwifi/core.c | 32 +++++++++++++++++++++
|
||||
drivers/net/wireless/realtek/rtlwifi/core.h | 1 +
|
||||
drivers/net/wireless/realtek/rtlwifi/usb.c | 3 ++
|
||||
drivers/net/wireless/realtek/rtlwifi/wifi.h | 1 +
|
||||
4 files changed, 37 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
|
||||
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
|
||||
@@ -1018,6 +1018,25 @@ static void send_beacon_frame(struct iee
|
||||
}
|
||||
}
|
||||
|
||||
+void rtl_update_beacon_work_callback(struct work_struct *work)
|
||||
+{
|
||||
+ struct rtl_works *rtlworks =
|
||||
+ container_of(work, struct rtl_works, update_beacon_work);
|
||||
+ struct ieee80211_hw *hw = rtlworks->hw;
|
||||
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
+ struct ieee80211_vif *vif = rtlpriv->mac80211.vif;
|
||||
+
|
||||
+ if (!vif) {
|
||||
+ WARN_ONCE(true, "no vif to update beacon\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ mutex_lock(&rtlpriv->locks.conf_mutex);
|
||||
+ send_beacon_frame(hw, vif);
|
||||
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(rtl_update_beacon_work_callback);
|
||||
+
|
||||
static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *bss_conf,
|
||||
@@ -1747,6 +1766,18 @@ static void rtl_op_flush(struct ieee8021
|
||||
rtlpriv->intf_ops->flush(hw, queues, drop);
|
||||
}
|
||||
|
||||
+static int rtl_op_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
|
||||
+ bool set)
|
||||
+{
|
||||
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
+
|
||||
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU)
|
||||
+ schedule_work(&rtlpriv->works.update_beacon_work);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Description:
|
||||
* This routine deals with the Power Configuration CMD
|
||||
* parsing for RTL8723/RTL8188E Series IC.
|
||||
@@ -1903,6 +1934,7 @@ const struct ieee80211_ops rtl_ops = {
|
||||
.sta_add = rtl_op_sta_add,
|
||||
.sta_remove = rtl_op_sta_remove,
|
||||
.flush = rtl_op_flush,
|
||||
+ .set_tim = rtl_op_set_tim,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(rtl_ops);
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtlwifi/core.h
|
||||
+++ b/drivers/net/wireless/realtek/rtlwifi/core.h
|
||||
@@ -60,5 +60,6 @@ void rtl_bb_delay(struct ieee80211_hw *h
|
||||
bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
bool rtl_btc_status_false(void);
|
||||
void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igval);
|
||||
+void rtl_update_beacon_work_callback(struct work_struct *work);
|
||||
|
||||
#endif
|
||||
--- a/drivers/net/wireless/realtek/rtlwifi/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtlwifi/usb.c
|
||||
@@ -807,6 +807,7 @@ static void rtl_usb_stop(struct ieee8021
|
||||
|
||||
tasklet_kill(&rtlusb->rx_work_tasklet);
|
||||
cancel_work_sync(&rtlpriv->works.lps_change_work);
|
||||
+ cancel_work_sync(&rtlpriv->works.update_beacon_work);
|
||||
|
||||
flush_workqueue(rtlpriv->works.rtl_wq);
|
||||
|
||||
@@ -1033,6 +1034,8 @@ int rtl_usb_probe(struct usb_interface *
|
||||
rtl_fill_h2c_cmd_work_callback);
|
||||
INIT_WORK(&rtlpriv->works.lps_change_work,
|
||||
rtl_lps_change_work_callback);
|
||||
+ INIT_WORK(&rtlpriv->works.update_beacon_work,
|
||||
+ rtl_update_beacon_work_callback);
|
||||
|
||||
rtlpriv->usb_data_index = 0;
|
||||
init_completion(&rtlpriv->firmware_loading_complete);
|
||||
--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
|
||||
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
|
||||
@@ -2487,6 +2487,7 @@ struct rtl_works {
|
||||
|
||||
struct work_struct lps_change_work;
|
||||
struct work_struct fill_h2c_cmd;
|
||||
+ struct work_struct update_beacon_work;
|
||||
};
|
||||
|
||||
struct rtl_debug {
|
@ -1,23 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 26 Jan 2021 16:40:52 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: fix regression in the max_prob_rate
|
||||
fix
|
||||
|
||||
Since mi->max_prob_rate is overwritten after the loop that calls
|
||||
minstrel_ht_set_best_prob_rate, the new best rate needs to be written to *dest
|
||||
|
||||
Fixes: a7fca4e4037f ("mac80211: minstrel_ht: fix max probability rate selection")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -545,7 +545,7 @@ minstrel_ht_set_best_prob_rate(struct mi
|
||||
cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx,
|
||||
mrs->prob_avg);
|
||||
if (cur_tp_avg > tmp_tp_avg)
|
||||
- mi->max_prob_rate = index;
|
||||
+ *dest = index;
|
||||
|
||||
max_gpr_tp_avg = minstrel_ht_get_tp_avg(mi, max_gpr_group,
|
||||
max_gpr_idx,
|
@ -1,172 +0,0 @@
|
||||
PKG_DRIVERS += \
|
||||
rt2x00-lib rt2x00-pci rt2x00-usb rt2x00-mmio \
|
||||
rt2400-pci rt2500-pci rt2500-usb \
|
||||
rt2800-lib rt2800-mmio rt2800-pci rt2800-soc rt2800-usb \
|
||||
rt61-pci rt73-usb
|
||||
|
||||
PKG_CONFIG_DEPENDS += \
|
||||
CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS \
|
||||
CONFIG_PACKAGE_RT2X00_DEBUG
|
||||
|
||||
config-$(call config_package,rt2x00-lib) += RT2X00 RT2X00_LIB
|
||||
config-$(call config_package,rt2x00-pci) += RT2X00_LIB_PCI
|
||||
config-$(call config_package,rt2x00-mmio) += RT2X00_LIB_MMIO
|
||||
config-$(call config_package,rt2x00-usb) += RT2X00_LIB_USB
|
||||
config-$(CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS) += RT2X00_LIB_DEBUGFS
|
||||
config-$(CONFIG_PACKAGE_RT2X00_DEBUG) += RT2X00_DEBUG
|
||||
|
||||
config-$(call config_package,rt2400-pci) += RT2400PCI
|
||||
config-$(call config_package,rt2500-pci) += RT2500PCI
|
||||
config-$(call config_package,rt2500-usb) += RT2500USB
|
||||
config-$(call config_package,rt61-pci) += RT61PCI
|
||||
config-$(call config_package,rt73-usb) += RT73USB
|
||||
|
||||
config-$(call config_package,rt2800-lib) += RT2800_LIB
|
||||
|
||||
config-$(call config_package,rt2800-soc) += RT2800SOC
|
||||
config-$(call config_package,rt2800-pci) += RT2800PCI
|
||||
config-y += RT2800PCI_RT33XX RT2800PCI_RT35XX RT2800PCI_RT53XX RT2800PCI_RT3290
|
||||
|
||||
config-$(call config_package,rt2800-usb) += RT2800USB
|
||||
config-y += RT2800USB_RT33XX RT2800USB_RT35XX RT2800USB_RT3573 RT2800USB_RT53XX RT2800USB_RT55XX RT2800USB_UNKNOWN
|
||||
|
||||
define KernelPackage/rt2x00/Default
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Ralink Drivers for RT2x00 cards
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2x00-lib
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-mac80211
|
||||
TITLE+= (LIB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00lib.ko
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2x00-lib/config
|
||||
if PACKAGE_kmod-rt2x00-lib
|
||||
|
||||
config PACKAGE_RT2X00_LIB_DEBUGFS
|
||||
bool "Enable rt2x00 debugfs support"
|
||||
depends on PACKAGE_MAC80211_DEBUGFS
|
||||
help
|
||||
Enable creation of debugfs files for the rt2x00 drivers.
|
||||
These debugfs files support both reading and writing of the
|
||||
most important register types of the rt2x00 hardware.
|
||||
|
||||
config PACKAGE_RT2X00_DEBUG
|
||||
bool "Enable rt2x00 debug output"
|
||||
help
|
||||
Enable debugging output for all rt2x00 modules
|
||||
|
||||
endif
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2x00-mmio
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @(PCI_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib
|
||||
HIDDEN:=1
|
||||
TITLE+= (MMIO)
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2x00-pci
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-mmio +kmod-rt2x00-lib
|
||||
HIDDEN:=1
|
||||
TITLE+= (PCI)
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2x00pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2x00-usb
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-rt2x00-lib +kmod-usb-core
|
||||
HIDDEN:=1
|
||||
TITLE+= (USB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00usb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2x00usb)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2800-lib
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib +kmod-lib-crc-ccitt +@DRIVER_11N_SUPPORT
|
||||
HIDDEN:=1
|
||||
TITLE+= (rt2800 LIB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800lib.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2400-pci
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +kmod-eeprom-93cx6
|
||||
TITLE+= (RT2400 PCI)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2400pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2400pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2500-pci
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +kmod-eeprom-93cx6
|
||||
TITLE+= (RT2500 PCI)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2500pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2500pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2500-usb
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb
|
||||
TITLE+= (RT2500 USB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2500usb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2500usb)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2800-mmio
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
TITLE += (RT28xx/RT3xxx MMIO)
|
||||
DEPENDS += +kmod-rt2800-lib +kmod-rt2x00-mmio
|
||||
HIDDEN:=1
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800mmio.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2800-soc
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS += @(TARGET_ramips_rt288x||TARGET_ramips_rt305x||TARGET_ramips_rt3883||TARGET_ramips_mt7620) +kmod-rt2800-mmio +kmod-rt2800-lib
|
||||
TITLE += (RT28xx/RT3xxx SoC)
|
||||
FILES := \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00soc.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800soc.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2800soc)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2800-pci
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +kmod-rt2800-lib +kmod-rt2800-mmio +kmod-eeprom-93cx6 +rt2800-pci-firmware
|
||||
TITLE+= (RT2860 PCI)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2800pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2800-usb
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb +kmod-rt2800-lib +kmod-lib-crc-ccitt +rt2800-usb-firmware
|
||||
TITLE+= (RT2870 USB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800usb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2800usb)
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/rt61-pci
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +kmod-eeprom-93cx6 +kmod-lib-crc-itu-t +rt61-pci-firmware
|
||||
TITLE+= (RT2x61 PCI)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt61pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt61pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt73-usb
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb +kmod-lib-crc-itu-t +rt73-usb-firmware
|
||||
TITLE+= (RT73 USB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt73usb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt73usb)
|
||||
endef
|
@ -1,28 +0,0 @@
|
||||
--- a/backport-include/linux/kconfig.h
|
||||
+++ b/backport-include/linux/kconfig.h
|
||||
@@ -5,6 +5,8 @@
|
||||
#include_next <linux/kconfig.h>
|
||||
#endif
|
||||
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
|
||||
+
|
||||
#ifndef __ARG_PLACEHOLDER_1
|
||||
#define __ARG_PLACEHOLDER_1 0,
|
||||
#define config_enabled(cfg) _config_enabled(cfg)
|
||||
@@ -16,6 +18,7 @@
|
||||
* 3.1 - 3.3 had a broken version of this, so undef
|
||||
* (they didn't have __ARG_PLACEHOLDER_1)
|
||||
*/
|
||||
+
|
||||
#undef IS_ENABLED
|
||||
#define IS_ENABLED(option) \
|
||||
(config_enabled(option) || config_enabled(option##_MODULE))
|
||||
@@ -31,6 +34,8 @@
|
||||
#undef IS_BUILTIN
|
||||
#define IS_BUILTIN(option) config_enabled(option)
|
||||
|
||||
+#endif
|
||||
+
|
||||
#ifndef IS_REACHABLE
|
||||
/*
|
||||
* IS_REACHABLE(CONFIG_FOO) evaluates to 1 if the currently compiled
|
@ -1,296 +0,0 @@
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -332,6 +332,7 @@ RT2X00_LIB_FIRMWARE=
|
||||
RT2X00_LIB_CRYPTO=
|
||||
RT2X00_LIB_LEDS=
|
||||
RT2X00_LIB_DEBUGFS=
|
||||
+RT2X00_LIB_EEPROM=
|
||||
RT2X00_DEBUG=
|
||||
WLAN_VENDOR_REALTEK=
|
||||
RTL8180=
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/Kconfig
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
|
||||
@@ -70,6 +70,7 @@ config RT2800PCI
|
||||
select RT2X00_LIB_MMIO
|
||||
select RT2X00_LIB_PCI
|
||||
select RT2X00_LIB_FIRMWARE
|
||||
+ select RT2X00_LIB_EEPROM
|
||||
select RT2X00_LIB_CRYPTO
|
||||
depends on CRC_CCITT
|
||||
depends on EEPROM_93CX6
|
||||
@@ -216,6 +217,7 @@ config RT2800SOC
|
||||
select RT2X00_LIB_MMIO
|
||||
select RT2X00_LIB_CRYPTO
|
||||
select RT2X00_LIB_FIRMWARE
|
||||
+ select RT2X00_LIB_EEPROM
|
||||
select RT2800_LIB
|
||||
select RT2800_LIB_MMIO
|
||||
help
|
||||
@@ -266,6 +268,9 @@ config RT2X00_LIB_FIRMWARE
|
||||
config RT2X00_LIB_CRYPTO
|
||||
bool
|
||||
|
||||
+config RT2X00_LIB_EEPROM
|
||||
+ bool
|
||||
+
|
||||
config RT2X00_LIB_LEDS
|
||||
bool
|
||||
default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n)
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/Makefile
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/Makefile
|
||||
@@ -8,6 +8,7 @@ rt2x00lib-$(CPTCFG_RT2X00_LIB_DEBUGFS) +
|
||||
rt2x00lib-$(CPTCFG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o
|
||||
rt2x00lib-$(CPTCFG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
|
||||
rt2x00lib-$(CPTCFG_RT2X00_LIB_LEDS) += rt2x00leds.o
|
||||
+rt2x00lib-$(CPTCFG_RT2X00_LIB_EEPROM) += rt2x00eeprom.o
|
||||
|
||||
obj-$(CPTCFG_RT2X00_LIB) += rt2x00lib.o
|
||||
obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
@@ -37,6 +37,8 @@ struct rt2800_drv_data {
|
||||
struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE];
|
||||
};
|
||||
|
||||
+#include "rt2800.h"
|
||||
+
|
||||
struct rt2800_ops {
|
||||
u32 (*register_read)(struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned int offset);
|
||||
@@ -135,6 +137,15 @@ static inline int rt2800_read_eeprom(str
|
||||
{
|
||||
const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
|
||||
|
||||
+ if (rt2x00dev->eeprom_file) {
|
||||
+ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data,
|
||||
+ EEPROM_SIZE);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!rt2800ops->read_eeprom)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
return rt2800ops->read_eeprom(rt2x00dev);
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
@@ -90,19 +90,6 @@ static int rt2800soc_set_device_state(st
|
||||
return retval;
|
||||
}
|
||||
|
||||
-static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
-{
|
||||
- void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
|
||||
-
|
||||
- if (!base_addr)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
|
||||
-
|
||||
- iounmap(base_addr);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
/* Firmware functions */
|
||||
static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
@@ -167,7 +154,6 @@ static const struct rt2800_ops rt2800soc
|
||||
.register_multiread = rt2x00mmio_register_multiread,
|
||||
.register_multiwrite = rt2x00mmio_register_multiwrite,
|
||||
.regbusy_read = rt2x00mmio_regbusy_read,
|
||||
- .read_eeprom = rt2800soc_read_eeprom,
|
||||
.hwcrypt_disabled = rt2800soc_hwcrypt_disabled,
|
||||
.drv_write_firmware = rt2800soc_write_firmware,
|
||||
.drv_init_registers = rt2800mmio_init_registers,
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
@@ -694,6 +694,7 @@ enum rt2x00_capability_flags {
|
||||
REQUIRE_HT_TX_DESC,
|
||||
REQUIRE_PS_AUTOWAKE,
|
||||
REQUIRE_DELAYED_RFKILL,
|
||||
+ REQUIRE_EEPROM_FILE,
|
||||
|
||||
/*
|
||||
* Capabilities
|
||||
@@ -970,6 +971,11 @@ struct rt2x00_dev {
|
||||
const struct firmware *fw;
|
||||
|
||||
/*
|
||||
+ * EEPROM image.
|
||||
+ */
|
||||
+ const struct firmware *eeprom_file;
|
||||
+
|
||||
+ /*
|
||||
* FIFO for storing tx status reports between isr and tasklet.
|
||||
*/
|
||||
DECLARE_KFIFO_PTR(txstatus_fifo, u32);
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1402,6 +1402,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
|
||||
INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
|
||||
INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
|
||||
|
||||
+ retval = rt2x00lib_load_eeprom_file(rt2x00dev);
|
||||
+ if (retval)
|
||||
+ goto exit;
|
||||
+
|
||||
/*
|
||||
* Let the driver probe the device to detect the capabilities.
|
||||
*/
|
||||
@@ -1545,6 +1549,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
|
||||
* Free the driver data.
|
||||
*/
|
||||
kfree(rt2x00dev->drv_data);
|
||||
+
|
||||
+ /*
|
||||
+ * Free EEPROM image.
|
||||
+ */
|
||||
+ rt2x00lib_free_eeprom_file(rt2x00dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
|
||||
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
|
||||
@@ -0,0 +1,106 @@
|
||||
+/*
|
||||
+ Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
|
||||
+ Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com>
|
||||
+ <http://rt2x00.serialmonkey.com>
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU General Public License as published by
|
||||
+ the Free Software Foundation; either version 2 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program; if not, write to the
|
||||
+ Free Software Foundation, Inc.,
|
||||
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ Module: rt2x00lib
|
||||
+ Abstract: rt2x00 eeprom file loading routines.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+
|
||||
+#include "rt2x00.h"
|
||||
+#include "rt2x00lib.h"
|
||||
+
|
||||
+static const char *
|
||||
+rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data;
|
||||
+
|
||||
+ if (pdata && pdata->eeprom_file_name)
|
||||
+ return pdata->eeprom_file_name;
|
||||
+
|
||||
+ return NULL
|
||||
+}
|
||||
+
|
||||
+static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ const struct firmware *ee;
|
||||
+ const char *ee_name;
|
||||
+ int retval;
|
||||
+
|
||||
+ ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev);
|
||||
+ if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) {
|
||||
+ rt2x00_err(rt2x00dev, "Required EEPROM name is missing.");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (!ee_name)
|
||||
+ return 0;
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "Loading EEPROM data from '%s'.\n", ee_name);
|
||||
+
|
||||
+ retval = request_firmware(&ee, ee_name, rt2x00dev->dev);
|
||||
+ if (retval) {
|
||||
+ rt2x00_err(rt2x00dev, "Failed to request EEPROM.\n");
|
||||
+ return retval;
|
||||
+ }
|
||||
+
|
||||
+ if (!ee || !ee->size || !ee->data) {
|
||||
+ rt2x00_err(rt2x00dev, "Failed to read EEPROM file.\n");
|
||||
+ retval = -ENOENT;
|
||||
+ goto err_exit;
|
||||
+ }
|
||||
+
|
||||
+ if (ee->size != rt2x00dev->ops->eeprom_size) {
|
||||
+ rt2x00_err(rt2x00dev,
|
||||
+ "EEPROM file size is invalid, it should be %d bytes\n",
|
||||
+ rt2x00dev->ops->eeprom_size);
|
||||
+ retval = -EINVAL;
|
||||
+ goto err_release_ee;
|
||||
+ }
|
||||
+
|
||||
+ rt2x00dev->eeprom_file = ee;
|
||||
+ return 0;
|
||||
+
|
||||
+err_release_ee:
|
||||
+ release_firmware(ee);
|
||||
+err_exit:
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ int retval;
|
||||
+
|
||||
+ retval = rt2x00lib_request_eeprom_file(rt2x00dev);
|
||||
+ if (retval)
|
||||
+ return retval;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ if (rt2x00dev->eeprom_file && rt2x00dev->eeprom_file->size)
|
||||
+ release_firmware(rt2x00dev->eeprom_file);
|
||||
+ rt2x00dev->eeprom_file = NULL;
|
||||
+}
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h
|
||||
@@ -286,6 +286,22 @@ static inline void rt2x00lib_free_firmwa
|
||||
#endif /* CPTCFG_RT2X00_LIB_FIRMWARE */
|
||||
|
||||
/*
|
||||
+ * EEPROM file handlers.
|
||||
+ */
|
||||
+#ifdef CPTCFG_RT2X00_LIB_EEPROM
|
||||
+int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev);
|
||||
+void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev);
|
||||
+#else
|
||||
+static inline int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+static inline void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+}
|
||||
+#endif /* CPTCFG_RT2X00_LIB_EEPROM */
|
||||
+
|
||||
+/*
|
||||
* Debugfs handlers.
|
||||
*/
|
||||
#ifdef CPTCFG_RT2X00_LIB_DEBUGFS
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
|
||||
@@ -86,6 +86,7 @@ int rt2x00soc_probe(struct platform_devi
|
||||
if (IS_ERR(rt2x00dev->clk))
|
||||
rt2x00dev->clk = NULL;
|
||||
|
||||
+ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags);
|
||||
rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC);
|
||||
|
||||
retval = rt2x00soc_alloc_reg(rt2x00dev);
|
@ -1,125 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||
@@ -1411,6 +1411,52 @@ static const struct file_operations fops
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
||||
+
|
||||
+static ssize_t read_file_chan_bw(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;
|
||||
+
|
||||
+ len = sprintf(buf, "0x%08x\n", common->chan_bw);
|
||||
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
+}
|
||||
+
|
||||
+static ssize_t write_file_chan_bw(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 chan_bw;
|
||||
+ char buf[32];
|
||||
+ ssize_t len;
|
||||
+
|
||||
+ len = min(count, sizeof(buf) - 1);
|
||||
+ if (copy_from_user(buf, user_buf, len))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ buf[len] = '\0';
|
||||
+ if (kstrtoul(buf, 0, &chan_bw))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ common->chan_bw = chan_bw;
|
||||
+ if (!test_bit(ATH_OP_INVALID, &common->op_flags))
|
||||
+ ath9k_ops.config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL);
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations fops_chanbw = {
|
||||
+ .read = read_file_chan_bw,
|
||||
+ .write = write_file_chan_bw,
|
||||
+ .open = simple_open,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .llseek = default_llseek,
|
||||
+};
|
||||
+
|
||||
+
|
||||
int ath9k_init_debug(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
@@ -1432,6 +1478,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||
|
||||
debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
|
||||
&fops_eeprom);
|
||||
+ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
|
||||
+ sc, &fops_chanbw);
|
||||
debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
|
||||
read_file_dma);
|
||||
debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
|
||||
--- a/drivers/net/wireless/ath/ath.h
|
||||
+++ b/drivers/net/wireless/ath/ath.h
|
||||
@@ -149,6 +149,7 @@ struct ath_common {
|
||||
int debug_mask;
|
||||
enum ath_device_state state;
|
||||
unsigned long op_flags;
|
||||
+ u32 chan_bw;
|
||||
|
||||
struct ath_ani ani;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/common.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/common.c
|
||||
@@ -297,11 +297,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke
|
||||
/*
|
||||
* Update internal channel flags.
|
||||
*/
|
||||
-static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
|
||||
+static void ath9k_cmn_update_ichannel(struct ath_common *common,
|
||||
+ struct ath9k_channel *ichan,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_channel *chan = chandef->chan;
|
||||
u16 flags = 0;
|
||||
+ int width;
|
||||
|
||||
ichan->channel = chan->center_freq;
|
||||
ichan->chan = chan;
|
||||
@@ -309,7 +311,19 @@ static void ath9k_cmn_update_ichannel(st
|
||||
if (chan->band == NL80211_BAND_5GHZ)
|
||||
flags |= CHANNEL_5GHZ;
|
||||
|
||||
- switch (chandef->width) {
|
||||
+ switch (common->chan_bw) {
|
||||
+ case 5:
|
||||
+ width = NL80211_CHAN_WIDTH_5;
|
||||
+ break;
|
||||
+ case 10:
|
||||
+ width = NL80211_CHAN_WIDTH_10;
|
||||
+ break;
|
||||
+ default:
|
||||
+ width = chandef->width;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ switch (width) {
|
||||
case NL80211_CHAN_WIDTH_5:
|
||||
flags |= CHANNEL_QUARTER;
|
||||
break;
|
||||
@@ -342,10 +356,11 @@ struct ath9k_channel *ath9k_cmn_get_chan
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_channel *curchan = chandef->chan;
|
||||
+ struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_channel *channel;
|
||||
|
||||
channel = &ah->channels[curchan->hw_value];
|
||||
- ath9k_cmn_update_ichannel(channel, chandef);
|
||||
+ ath9k_cmn_update_ichannel(common, channel, chandef);
|
||||
|
||||
return channel;
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 23 Jan 2021 00:10:34 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: show sampling rates in debugfs
|
||||
|
||||
This makes it easier to see what rates are going to be tested next
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
|
||||
@@ -32,6 +32,18 @@ minstrel_stats_release(struct inode *ino
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+minstrel_ht_is_sample_rate(struct minstrel_ht_sta *mi, int idx)
|
||||
+{
|
||||
+ int type, i;
|
||||
+
|
||||
+ for (type = 0; type < ARRAY_SIZE(mi->sample); type++)
|
||||
+ for (i = 0; i < MINSTREL_SAMPLE_RATES; i++)
|
||||
+ if (mi->sample[type].cur_sample_rates[i] == idx)
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static char *
|
||||
minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
|
||||
{
|
||||
@@ -84,6 +96,7 @@ minstrel_ht_stats_dump(struct minstrel_h
|
||||
*(p++) = (idx == mi->max_tp_rate[2]) ? 'C' : ' ';
|
||||
*(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' ';
|
||||
*(p++) = (idx == mi->max_prob_rate) ? 'P' : ' ';
|
||||
+ *(p++) = minstrel_ht_is_sample_rate(mi, idx) ? 'S' : ' ';
|
||||
|
||||
if (gflags & IEEE80211_TX_RC_MCS) {
|
||||
p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j);
|
||||
@@ -145,9 +158,9 @@ minstrel_ht_stats_open(struct inode *ino
|
||||
|
||||
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)] [retry|suc|att] [#success | #attempts]\n");
|
||||
+ "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(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++)
|
||||
@@ -228,6 +241,7 @@ minstrel_ht_stats_csv_dump(struct minstr
|
||||
p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[2]) ? "C" : ""));
|
||||
p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[3]) ? "D" : ""));
|
||||
p += sprintf(p, "%s" ,((idx == mi->max_prob_rate) ? "P" : ""));
|
||||
+ p += sprintf(p, "%s", (minstrel_ht_is_sample_rate(mi, idx) ? "S" : ""));
|
||||
|
||||
if (gflags & IEEE80211_TX_RC_MCS) {
|
||||
p += sprintf(p, ",MCS%-2u,", (mg->streams - 1) * 8 + j);
|
@ -1,169 +0,0 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -5,7 +5,7 @@
|
||||
ifeq ($(KERNELRELEASE),)
|
||||
|
||||
MAKEFLAGS += --no-print-directory
|
||||
-SHELL := /bin/bash
|
||||
+SHELL := /usr/bin/env bash
|
||||
BACKPORT_DIR := $(shell pwd)
|
||||
|
||||
KMODDIR ?= updates
|
||||
@@ -19,6 +19,7 @@ KLIB_BUILD ?= $(KLIB)/build/
|
||||
KERNEL_CONFIG := $(KLIB_BUILD)/.config
|
||||
KERNEL_MAKEFILE := $(KLIB_BUILD)/Makefile
|
||||
CONFIG_MD5 := $(shell md5sum $(KERNEL_CONFIG) 2>/dev/null | sed 's/\s.*//')
|
||||
+STAMP_KERNEL_CONFIG := .kernel_config_md5_$(CONFIG_MD5)
|
||||
|
||||
export KLIB KLIB_BUILD BACKPORT_DIR KMODDIR KMODPATH_ARG
|
||||
|
||||
@@ -36,7 +37,8 @@ mrproper:
|
||||
@rm -f .kernel_config_md5 Kconfig.versions Kconfig.kernel
|
||||
@rm -f backport-include/backport/autoconf.h
|
||||
|
||||
-.DEFAULT:
|
||||
+.SILENT: $(STAMP_KERNEL_CONFIG)
|
||||
+$(STAMP_KERNEL_CONFIG):
|
||||
@set -e ; test -f local-symbols || ( \
|
||||
echo "/--------------" ;\
|
||||
echo "| You shouldn't run make in the backports tree, but only in" ;\
|
||||
@@ -60,58 +62,62 @@ mrproper:
|
||||
echo "| (that isn't currently running.)" ;\
|
||||
echo "\\--" ;\
|
||||
false)
|
||||
- @set -e ; if [ "$$(cat .kernel_config_md5 2>/dev/null)" != "$(CONFIG_MD5)" ] ;\
|
||||
- then \
|
||||
- echo -n "Generating local configuration database from kernel ..." ;\
|
||||
- grep -v -f local-symbols $(KERNEL_CONFIG) | grep = | ( \
|
||||
- while read l ; do \
|
||||
- if [ "$${l:0:7}" != "CONFIG_" ] ; then \
|
||||
- continue ;\
|
||||
- fi ;\
|
||||
- l=$${l:7} ;\
|
||||
- n=$${l%%=*} ;\
|
||||
- v=$${l#*=} ;\
|
||||
- if [ "$$v" = "m" ] ; then \
|
||||
- echo config $$n ;\
|
||||
- echo ' tristate' ;\
|
||||
- elif [ "$$v" = "y" ] ; then \
|
||||
- echo config $$n ;\
|
||||
- echo ' bool' ;\
|
||||
- else \
|
||||
- continue ;\
|
||||
- fi ;\
|
||||
- echo " default $$v" ;\
|
||||
- echo "" ;\
|
||||
- done \
|
||||
- ) > Kconfig.kernel ;\
|
||||
- kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \
|
||||
- kernelversion | sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\
|
||||
- test "$$kver" != "" || echo "Kernel version parse failed!" ;\
|
||||
- test "$$kver" != "" ;\
|
||||
- kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\
|
||||
- kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\
|
||||
- kvers="$$kvers $$(seq 0 20 | sed 's/^/4./')" ;\
|
||||
- kvers="$$kvers $$(seq 0 99 | sed 's/^/5./')" ;\
|
||||
- print=0 ;\
|
||||
- for v in $$kvers ; do \
|
||||
- if [ "$$print" = "1" ] ; then \
|
||||
- echo config KERNEL_$$(echo $$v | tr . _) ;\
|
||||
- echo " def_bool y" ;\
|
||||
- fi ;\
|
||||
- if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\
|
||||
- done > Kconfig.versions ;\
|
||||
- # RHEL as well, sadly we need to grep for it ;\
|
||||
- RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \
|
||||
- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
|
||||
- RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \
|
||||
- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
|
||||
- for v in $$(seq 0 $$RHEL_MINOR) ; do \
|
||||
- echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\
|
||||
- echo " def_bool y" ;\
|
||||
- done >> Kconfig.versions ;\
|
||||
- echo " done." ;\
|
||||
- fi ;\
|
||||
- echo "$(CONFIG_MD5)" > .kernel_config_md5
|
||||
+ @rm -f .kernel_config_md5_*
|
||||
+ @touch $@
|
||||
+
|
||||
+Kconfig.kernel: $(STAMP_KERNEL_CONFIG) local-symbols
|
||||
+ @printf "Generating local configuration database from kernel ..."
|
||||
+ @grep -v -f local-symbols $(KERNEL_CONFIG) | grep = | ( \
|
||||
+ while read l ; do \
|
||||
+ if [ "$${l:0:7}" != "CONFIG_" ] ; then \
|
||||
+ continue ;\
|
||||
+ fi ;\
|
||||
+ l=$${l:7} ;\
|
||||
+ n=$${l%%=*} ;\
|
||||
+ v=$${l#*=} ;\
|
||||
+ if [ "$$v" = "m" ] ; then \
|
||||
+ echo config $$n ;\
|
||||
+ echo ' tristate' ;\
|
||||
+ elif [ "$$v" = "y" ] ; then \
|
||||
+ echo config $$n ;\
|
||||
+ echo ' bool' ;\
|
||||
+ else \
|
||||
+ continue ;\
|
||||
+ fi ;\
|
||||
+ echo " default $$v" ;\
|
||||
+ echo "" ;\
|
||||
+ done \
|
||||
+ ) > $@
|
||||
+ @echo " done."
|
||||
+
|
||||
+Kconfig.versions: Kconfig.kernel
|
||||
+ @kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \
|
||||
+ kernelversion | sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\
|
||||
+ test "$$kver" != "" || echo "Kernel version parse failed!" ;\
|
||||
+ test "$$kver" != "" ;\
|
||||
+ kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\
|
||||
+ kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\
|
||||
+ kvers="$$kvers $$(seq 0 20 | sed 's/^/4./')" ;\
|
||||
+ kvers="$$kvers $$(seq 0 99 | sed 's/^/5./')" ;\
|
||||
+ print=0 ;\
|
||||
+ for v in $$kvers ; do \
|
||||
+ if [ "$$print" = "1" ] ; then \
|
||||
+ echo config KERNEL_$$(echo $$v | tr . _) ;\
|
||||
+ echo " def_bool y" ;\
|
||||
+ fi ;\
|
||||
+ if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\
|
||||
+ done > $@
|
||||
+ @RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \
|
||||
+ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
|
||||
+ RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \
|
||||
+ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
|
||||
+ for v in $$(seq 0 $$RHEL_MINOR) ; do \
|
||||
+ echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\
|
||||
+ echo " def_bool y" ;\
|
||||
+ done >> $@
|
||||
+
|
||||
+.DEFAULT:
|
||||
+ @$(MAKE) Kconfig.versions
|
||||
@$(MAKE) -f Makefile.real "$@"
|
||||
|
||||
.PHONY: defconfig-help
|
||||
--- a/Makefile.real
|
||||
+++ b/Makefile.real
|
||||
@@ -59,7 +59,7 @@ defconfig-%::
|
||||
|
||||
backport-include/backport/autoconf.h: .config Kconfig.versions Kconfig.kernel
|
||||
@$(MAKE) oldconfig
|
||||
- @echo -n "Building backport-include/backport/autoconf.h ..."
|
||||
+ @printf "Building backport-include/backport/autoconf.h ..."
|
||||
@grep -f local-symbols .config | ( \
|
||||
echo "#ifndef COMPAT_AUTOCONF_INCLUDED" ;\
|
||||
echo "#define COMPAT_AUTOCONF_INCLUDED" ;\
|
||||
@@ -80,7 +80,12 @@ backport-include/backport/autoconf.h: .c
|
||||
esac ;\
|
||||
done ;\
|
||||
echo "#endif /* COMPAT_AUTOCONF_INCLUDED */" ;\
|
||||
- ) > backport-include/backport/autoconf.h
|
||||
+ ) > $@.new
|
||||
+ @if cmp -s $@ $@.new; then \
|
||||
+ rm -f $@.new; \
|
||||
+ else \
|
||||
+ mv $@.new $@; \
|
||||
+ fi
|
||||
@echo " done."
|
||||
|
||||
.PHONY: modules
|
@ -1,403 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include "ath9k.h"
|
||||
+#include "hsr.h"
|
||||
|
||||
/* Set/change channels. If the channel is really being changed, it's done
|
||||
* by reseting the chip. To accomplish this we must first cleanup any pending
|
||||
@@ -22,6 +23,7 @@
|
||||
*/
|
||||
static int ath_set_channel(struct ath_softc *sc)
|
||||
{
|
||||
+ struct device_node *np = sc->dev->of_node;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ieee80211_hw *hw = sc->hw;
|
||||
@@ -42,6 +44,11 @@ static int ath_set_channel(struct ath_so
|
||||
ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
|
||||
chan->center_freq, chandef->width);
|
||||
|
||||
+ if (of_property_read_bool(np, "ubnt,hsr")) {
|
||||
+ ath9k_hsr_enable(ah, chandef->width, chan->center_freq);
|
||||
+ ath9k_hsr_status(ah);
|
||||
+ }
|
||||
+
|
||||
/* update survey stats for the old channel before switching */
|
||||
spin_lock_irqsave(&common->cc_lock, flags);
|
||||
ath_update_survey_stats(sc);
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hsr.c
|
||||
@@ -0,0 +1,247 @@
|
||||
+/*
|
||||
+ *
|
||||
+ * The MIT License (MIT)
|
||||
+ *
|
||||
+ * Copyright (c) 2015 Kirill Berezin
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
+ * of this software and associated documentation files (the "Software"), to deal
|
||||
+ * in the Software without restriction, including without limitation the rights
|
||||
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
+ * copies of the Software, and to permit persons to whom the Software is
|
||||
+ * furnished to do so, subject to the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be included in
|
||||
+ * all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
+ * SOFTWARE.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/time.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/etherdevice.h>
|
||||
+#include <linux/rtnetlink.h>
|
||||
+#include <asm/unaligned.h>
|
||||
+
|
||||
+#include "hw.h"
|
||||
+#include "ath9k.h"
|
||||
+
|
||||
+#define HSR_GPIO_CSN 8
|
||||
+#define HSR_GPIO_CLK 6
|
||||
+#define HSR_GPIO_DOUT 7
|
||||
+#define HSR_GPIO_DIN 5
|
||||
+
|
||||
+/* delays are in useconds */
|
||||
+#define HSR_DELAY_HALF_TICK 100
|
||||
+#define HSR_DELAY_PRE_WRITE 75
|
||||
+#define HSR_DELAY_FINAL 20000
|
||||
+#define HSR_DELAY_TRAILING 200
|
||||
+
|
||||
+void ath9k_hsr_init(struct ath_hw *ah)
|
||||
+{
|
||||
+ ath9k_hw_gpio_request_in(ah, HSR_GPIO_DIN, NULL);
|
||||
+ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CSN, NULL,
|
||||
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
|
||||
+ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CLK, NULL,
|
||||
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
|
||||
+ ath9k_hw_gpio_request_out(ah, HSR_GPIO_DOUT, NULL,
|
||||
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
|
||||
+
|
||||
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1);
|
||||
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0);
|
||||
+ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, 0);
|
||||
+
|
||||
+ udelay(HSR_DELAY_TRAILING);
|
||||
+}
|
||||
+
|
||||
+static u32 ath9k_hsr_write_byte(struct ath_hw *ah, int delay, u32 value)
|
||||
+{
|
||||
+ struct ath_common *common = ath9k_hw_common(ah);
|
||||
+ int i;
|
||||
+ u32 rval = 0;
|
||||
+
|
||||
+ udelay(delay);
|
||||
+
|
||||
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0);
|
||||
+ udelay(HSR_DELAY_HALF_TICK);
|
||||
+
|
||||
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 0);
|
||||
+ udelay(HSR_DELAY_HALF_TICK);
|
||||
+
|
||||
+ for (i = 0; i < 8; ++i) {
|
||||
+ rval = rval << 1;
|
||||
+
|
||||
+ /* pattern is left to right, that is 7-th bit runs first */
|
||||
+ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, (value >> (7 - i)) & 0x1);
|
||||
+ udelay(HSR_DELAY_HALF_TICK);
|
||||
+
|
||||
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 1);
|
||||
+ udelay(HSR_DELAY_HALF_TICK);
|
||||
+
|
||||
+ rval |= ath9k_hw_gpio_get(ah, HSR_GPIO_DIN);
|
||||
+
|
||||
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0);
|
||||
+ udelay(HSR_DELAY_HALF_TICK);
|
||||
+ }
|
||||
+
|
||||
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1);
|
||||
+ udelay(HSR_DELAY_HALF_TICK);
|
||||
+
|
||||
+ ath_dbg(common, CONFIG, "ath9k_hsr_write_byte: write byte %d return value is %d %c\n",
|
||||
+ value, rval, rval > 32 ? rval : '-');
|
||||
+
|
||||
+ return rval & 0xff;
|
||||
+}
|
||||
+
|
||||
+static int ath9k_hsr_write_a_chain(struct ath_hw *ah, char *chain, int items)
|
||||
+{
|
||||
+ int status = 0;
|
||||
+ int i = 0;
|
||||
+ int err;
|
||||
+
|
||||
+ /* a preamble */
|
||||
+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
|
||||
+ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
|
||||
+
|
||||
+ /* clear HSR's reply buffer */
|
||||
+ if (status) {
|
||||
+ int loop = 0;
|
||||
+
|
||||
+ for (loop = 0; (loop < 42) && status; ++loop)
|
||||
+ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE,
|
||||
+ 0);
|
||||
+
|
||||
+ if (loop >= 42) {
|
||||
+ ATH_DBG_WARN(1,
|
||||
+ "ath9k_hsr_write_a_chain: can't clear an output buffer after a 42 cycles.\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; (i < items) && (chain[i] != 0); ++i)
|
||||
+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, (u32)chain[i]);
|
||||
+
|
||||
+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
|
||||
+ mdelay(HSR_DELAY_FINAL / 1000);
|
||||
+
|
||||
+ /* reply */
|
||||
+ memset(chain, 0, items);
|
||||
+
|
||||
+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
|
||||
+ udelay(HSR_DELAY_TRAILING);
|
||||
+
|
||||
+ for (i = 0; i < (items - 1); ++i) {
|
||||
+ u32 ret;
|
||||
+
|
||||
+ ret = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
|
||||
+ if (ret != 0)
|
||||
+ chain[i] = (char)ret;
|
||||
+ else
|
||||
+ break;
|
||||
+
|
||||
+ udelay(HSR_DELAY_TRAILING);
|
||||
+ }
|
||||
+
|
||||
+ if (i <= 1)
|
||||
+ return 0;
|
||||
+
|
||||
+ err = kstrtoint(chain + 1, 10, &i);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return i;
|
||||
+}
|
||||
+
|
||||
+int ath9k_hsr_disable(struct ath_hw *ah)
|
||||
+{
|
||||
+ char cmd[10] = {'b', '4', '0', 0, 0, 0, 0, 0, 0, 0};
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd));
|
||||
+ if ((ret > 0) && (*cmd == 'B'))
|
||||
+ return 0;
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq)
|
||||
+{
|
||||
+ char cmd[10];
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Bandwidth argument is 0 sometimes. Assume default 802.11bgn
|
||||
+ * 20MHz on invalid values
|
||||
+ */
|
||||
+ if ((bw != 5) && (bw != 10) && (bw != 20) && (bw != 40))
|
||||
+ bw = 20;
|
||||
+
|
||||
+ memset(cmd, 0, sizeof(cmd));
|
||||
+ *cmd = 'b';
|
||||
+ snprintf(cmd + 1, 3, "%02d", bw);
|
||||
+
|
||||
+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd));
|
||||
+ if ((*cmd != 'B') || (ret != bw)) {
|
||||
+ ATH_DBG_WARN(1,
|
||||
+ "ath9k_hsr_enable: failed changing bandwidth -> set (%d,%d) reply (%d, %d)\n",
|
||||
+ 'b', bw, *cmd, ret);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ memset(cmd, 0, sizeof(cmd));
|
||||
+ *cmd = 'x';
|
||||
+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd));
|
||||
+ if (*cmd != 'X') {
|
||||
+ ATH_DBG_WARN(1,
|
||||
+ "ath9k_hsr_enable: failed 'x' command -> reply (%d, %d)\n",
|
||||
+ *cmd, ret);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ memset(cmd, 0, sizeof(cmd));
|
||||
+ *cmd = 'm';
|
||||
+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd));
|
||||
+ if (*cmd != 'M') {
|
||||
+ ATH_DBG_WARN(1,
|
||||
+ "ath9k_hsr_enable: failed 'm' command -> reply (%d, %d)\n",
|
||||
+ *cmd, ret);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ memset(cmd, 0, sizeof(cmd));
|
||||
+ *cmd = 'f';
|
||||
+ snprintf(cmd + 1, 6, "%05d", fq);
|
||||
+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd));
|
||||
+ if ((*cmd != 'F') && (ret != fq)) {
|
||||
+ ATH_DBG_WARN(1,
|
||||
+ "ath9k_hsr_enable: failed set frequency -> reply (%d, %d)\n",
|
||||
+ *cmd, ret);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int ath9k_hsr_status(struct ath_hw *ah)
|
||||
+{
|
||||
+ char cmd[10] = {'s', 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd));
|
||||
+ if (*cmd != 'S') {
|
||||
+ ATH_DBG_WARN(1, "ath9k_hsr_status: returned %d,%d\n", *cmd,
|
||||
+ ret);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hsr.h
|
||||
@@ -0,0 +1,48 @@
|
||||
+/*
|
||||
+ * The MIT License (MIT)
|
||||
+ *
|
||||
+ * Copyright (c) 2015 Kirill Berezin
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
+ * of this software and associated documentation files (the "Software"), to deal
|
||||
+ * in the Software without restriction, including without limitation the rights
|
||||
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
+ * copies of the Software, and to permit persons to whom the Software is
|
||||
+ * furnished to do so, subject to the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be included in
|
||||
+ * all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
+ * SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#ifndef HSR_H
|
||||
+#define HSR_H
|
||||
+
|
||||
+#ifdef CPTCFG_ATH9K_UBNTHSR
|
||||
+
|
||||
+void ath9k_hsr_init(struct ath_hw *ah);
|
||||
+int ath9k_hsr_disable(struct ath_hw *ah);
|
||||
+int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq);
|
||||
+int ath9k_hsr_status(struct ath_hw *ah);
|
||||
+
|
||||
+#else
|
||||
+static inline void ath9k_hsr_init(struct ath_hw *ah) {}
|
||||
+
|
||||
+static inline int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int ath9k_hsr_disable(struct ath_hw *ah) { return 0; }
|
||||
+static inline int ath9k_hsr_status(struct ath_hw *ah) { return 0; }
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#endif /* HSR_H */
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include "ath9k.h"
|
||||
#include "btcoex.h"
|
||||
+#include "hsr.h"
|
||||
|
||||
static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
u32 queues, bool drop);
|
||||
@@ -657,6 +658,7 @@ void ath_reset_work(struct work_struct *
|
||||
static int ath9k_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
+ struct device_node *np = sc->dev->of_node;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan;
|
||||
@@ -735,6 +737,11 @@ static int ath9k_start(struct ieee80211_
|
||||
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
|
||||
}
|
||||
|
||||
+ if (of_property_read_bool(np, "ubnt,hsr")) {
|
||||
+ ath9k_hsr_init(ah);
|
||||
+ ath9k_hsr_disable(ah);
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Reset key cache to sane defaults (all entries cleared) instead of
|
||||
* semi-random values after suspend/resume.
|
||||
--- a/drivers/net/wireless/ath/ath9k/Makefile
|
||||
+++ b/drivers/net/wireless/ath/ath9k/Makefile
|
||||
@@ -17,6 +17,7 @@ ath9k-$(CPTCFG_ATH9K_DFS_CERTIFIED) += d
|
||||
ath9k-$(CPTCFG_ATH9K_TX99) += tx99.o
|
||||
ath9k-$(CPTCFG_ATH9K_WOW) += wow.o
|
||||
ath9k-$(CPTCFG_ATH9K_HWRNG) += rng.o
|
||||
+ath9k-$(CPTCFG_ATH9K_UBNTHSR) += hsr.o
|
||||
|
||||
ath9k-$(CPTCFG_ATH9K_DEBUGFS) += debug.o
|
||||
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -112,6 +112,7 @@ ATH9K_WOW=
|
||||
ATH9K_RFKILL=
|
||||
ATH9K_CHANNEL_CONTEXT=
|
||||
ATH9K_PCOEM=
|
||||
+ATH9K_UBNTHSR=
|
||||
ATH9K_PCI_NO_EEPROM=
|
||||
ATH9K_HTC=
|
||||
ATH9K_HTC_DEBUGFS=
|
||||
--- a/drivers/net/wireless/ath/ath9k/Kconfig
|
||||
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
|
||||
@@ -58,6 +58,19 @@ config ATH9K_AHB
|
||||
Say Y, if you have a SoC with a compatible built-in
|
||||
wireless MAC. Say N if unsure.
|
||||
|
||||
+config ATH9K_UBNTHSR
|
||||
+ bool "Ubiquiti UniFi Outdoor Plus HSR support"
|
||||
+ depends on ATH9K
|
||||
+ ---help---
|
||||
+ This options enables code to control the HSR RF
|
||||
+ filter in the receive path of the Ubiquiti UniFi
|
||||
+ Outdoor Plus access point.
|
||||
+
|
||||
+ Say Y if you want to use the access point. The
|
||||
+ code will only be used if the device is detected,
|
||||
+ so it does not harm other setup other than occupying
|
||||
+ a bit of memory.
|
||||
+
|
||||
config ATH9K_DEBUGFS
|
||||
bool "Atheros ath9k debugging"
|
||||
depends on ATH9K && DEBUG_FS
|
@ -1,11 +0,0 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -2,7 +2,7 @@
|
||||
# Makefile for the output source package
|
||||
#
|
||||
|
||||
-ifeq ($(KERNELRELEASE),)
|
||||
+ifeq ($(KERNELVERSION),)
|
||||
|
||||
MAKEFLAGS += --no-print-directory
|
||||
SHELL := /usr/bin/env bash
|
@ -1,206 +0,0 @@
|
||||
PKG_DRIVERS += \
|
||||
rtl8180 rtl8187 \
|
||||
rtlwifi rtlwifi-pci rtlwifi-btcoexist rtlwifi-usb rtl8192c-common \
|
||||
rtl8192ce rtl8192se rtl8192de rtl8192cu rtl8723bs rtl8821ae \
|
||||
rtl8xxxu rtw88
|
||||
|
||||
config-$(call config_package,rtl8180) += RTL8180
|
||||
config-$(call config_package,rtl8187) += RTL8187
|
||||
|
||||
config-$(call config_package,rtlwifi) += RTL_CARDS RTLWIFI
|
||||
config-$(call config_package,rtlwifi-pci) += RTLWIFI_PCI
|
||||
config-$(call config_package,rtlwifi-btcoexist) += RTLBTCOEXIST
|
||||
config-$(call config_package,rtlwifi-usb) += RTLWIFI_USB
|
||||
config-$(call config_package,rtl8192c-common) += RTL8192C_COMMON
|
||||
config-$(call config_package,rtl8192ce) += RTL8192CE
|
||||
config-$(call config_package,rtl8192se) += RTL8192SE
|
||||
config-$(call config_package,rtl8192de) += RTL8192DE
|
||||
config-$(call config_package,rtl8192cu) += RTL8192CU
|
||||
config-$(call config_package,rtl8821ae) += RTL8821AE
|
||||
config-$(CONFIG_PACKAGE_RTLWIFI_DEBUG) += RTLWIFI_DEBUG
|
||||
|
||||
config-$(call config_package,rtl8xxxu) += RTL8XXXU
|
||||
config-y += RTL8XXXU_UNTESTED
|
||||
|
||||
config-$(call config_package,rtl8723bs) += RTL8723BS
|
||||
config-y += STAGING
|
||||
|
||||
config-$(call config_package,rtw88) += RTW88 RTW88_CORE RTW88_PCI
|
||||
config-y += RTW88_8822BE RTW88_8822CE RTW88_8723DE
|
||||
|
||||
define KernelPackage/rtl818x/Default
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek Drivers for RTL818x devices
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/rtl8187
|
||||
DEPENDS+= +kmod-eeprom-93cx6 +kmod-mac80211
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8180
|
||||
$(call KernelPackage/rtl818x/Default)
|
||||
DEPENDS+= @PCI_SUPPORT
|
||||
TITLE+= (RTL8180 PCI)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl818x_pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl818x_pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8187
|
||||
$(call KernelPackage/rtl818x/Default)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-usb-core
|
||||
TITLE+= (RTL8187 USB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8187.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8187)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtlwifi/config
|
||||
config PACKAGE_RTLWIFI_DEBUG
|
||||
bool "Realtek wireless debugging"
|
||||
depends on PACKAGE_kmod-rtlwifi
|
||||
help
|
||||
Say Y, if you want to debug realtek wireless drivers.
|
||||
|
||||
endef
|
||||
|
||||
define KernelPackage/rtlwifi
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek common driver part
|
||||
DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 +@DRIVER_11N_SUPPORT
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtlwifi.ko
|
||||
HIDDEN:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/rtlwifi-pci
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek common driver part (PCI support)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-rtlwifi
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl_pci)
|
||||
HIDDEN:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/rtlwifi-btcoexist
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek BT coexist support
|
||||
DEPENDS+= +kmod-rtlwifi
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/btcoexist/btcoexist.ko
|
||||
AUTOLOAD:=$(call AutoProbe,btcoexist)
|
||||
HIDDEN:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/rtlwifi-usb
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek common driver part (USB support)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-rtlwifi
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_usb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl_usb)
|
||||
HIDDEN:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8192c-common
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8192CE/RTL8192CU common support module
|
||||
DEPENDS+= +kmod-rtlwifi
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192c/rtl8192c-common.ko
|
||||
HIDDEN:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8192ce
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8192CE/RTL8188CE support
|
||||
DEPENDS+= +kmod-rtlwifi-pci +kmod-rtl8192c-common +rtl8192ce-firmware
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rtl8192ce.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8192ce)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8192se
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8192SE/RTL8191SE support
|
||||
DEPENDS+= +kmod-rtlwifi-pci +rtl8192se-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rtl8192se.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8192se)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8192de
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8192DE/RTL8188DE support
|
||||
DEPENDS+= +kmod-rtlwifi-pci +rtl8192de-firmware
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rtl8192de.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8192de)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8192cu
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8192CU/RTL8188CU support
|
||||
DEPENDS+= +kmod-rtlwifi-usb +kmod-rtl8192c-common +rtl8192cu-firmware
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rtl8192cu.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8192cu)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8821ae
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8821AE support
|
||||
DEPENDS+= +kmod-rtlwifi-btcoexist +kmod-rtlwifi-pci +rtl8821ae-firmware
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rtl8821ae.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8821ae)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8xxxu
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=alternative Realtek RTL8XXXU support
|
||||
DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-mac80211
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8xxxu)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8xxxu/description
|
||||
This is an alternative driver for various Realtek RTL8XXX
|
||||
parts written to utilize the Linux mac80211 stack.
|
||||
The driver is known to work with a number of RTL8723AU,
|
||||
RL8188CU, RTL8188RU, RTL8191CU, and RTL8192CU devices
|
||||
|
||||
This driver is under development and has a limited feature
|
||||
set. In particular it does not yet support 40MHz channels
|
||||
and power management. However it should have a smaller
|
||||
memory footprint than the vendor drivers and benetifs
|
||||
from the in kernel mac80211 stack.
|
||||
|
||||
It can coexist with drivers from drivers/staging/rtl8723au,
|
||||
drivers/staging/rtl8192u, and drivers/net/wireless/rtlwifi,
|
||||
but you will need to control which module you wish to load.
|
||||
|
||||
RTL8XXXU_UNTESTED is enabled
|
||||
This option enables detection of Realtek 8723/8188/8191/8192 WiFi
|
||||
USB devices which have not been tested directly by the driver
|
||||
author or reported to be working by third parties.
|
||||
|
||||
Please report your results!
|
||||
endef
|
||||
|
||||
define KernelPackage/rtw88
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8822BE/RTL8822CE/RTL8723DE
|
||||
DEPENDS+= @(PCI_SUPPORT) +kmod-mac80211 +@DRIVER_11AC_SUPPORT +@DRIVER_11N_SUPPORT
|
||||
FILES:=\
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822be.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822b.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822ce.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822c.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8723de.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8723d.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_core.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtw88_8822be rtw88_8822ce rtw88_8723de)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8723bs
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8723BS SDIO Wireless LAN NIC driver (staging)
|
||||
DEPENDS+=+kmod-mmc +kmod-mac80211
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/staging/rtl8723bs/r8723bs.ko
|
||||
AUTOLOAD:=$(call AutoProbe,r8723bs)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8723bs/description
|
||||
This option enables support for RTL8723BS SDIO drivers, such as the wifi found
|
||||
on the 1st gen Intel Compute Stick, the CHIP and many other Intel Atom and ARM
|
||||
based devices.
|
||||
endef
|
@ -1,107 +0,0 @@
|
||||
From 9782a7f7488443568fa4d6088b73c9aff7eb8510 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 19 Apr 2017 16:14:53 +0200
|
||||
Subject: [PATCH] rt2x00: add support for external PA on MT7620
|
||||
To: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Cc: Helmut Schaa <helmut.schaa@googlemail.com>,
|
||||
linux-wireless@vger.kernel.org,
|
||||
Kalle Valo <kvalo@codeaurora.org>
|
||||
Content-Type: text/plain; charset="UTF-8"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
|
||||
[pozega.tomislav@gmail.com: use chanreg and dccal helpers.]
|
||||
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800.h | 1 +
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 70 +++++++++++++++++++++++++-
|
||||
2 files changed, 70 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
@@ -2739,6 +2739,7 @@ enum rt2800_eeprom_word {
|
||||
#define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f)
|
||||
#define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0)
|
||||
#define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600)
|
||||
+#define EEPROM_NIC_CONF2_EXTERNAL_PA FIELD16(0xc000)
|
||||
|
||||
/*
|
||||
* EEPROM LNA
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -4356,6 +4356,45 @@ static void rt2800_config_channel(struct
|
||||
rt2800_iq_calibrate(rt2x00dev, rf->channel);
|
||||
}
|
||||
|
||||
+ if (rt2x00_rt(rt2x00dev, RT6352)) {
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0,
|
||||
+ &rt2x00dev->cap_flags)) {
|
||||
+ rt2x00_warn(rt2x00dev, "Using incomplete support for " \
|
||||
+ "external PA\n");
|
||||
+ reg = rt2800_register_read(rt2x00dev, RF_CONTROL3);
|
||||
+ reg |= 0x00000101;
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, reg);
|
||||
+
|
||||
+ reg = rt2800_register_read(rt2x00dev, RF_BYPASS3);
|
||||
+ reg |= 0x00000101;
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
|
||||
+
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x73);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x73);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x73);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0xC8);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xA4);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x05);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xC8);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xA4);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x05);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0xC8);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xA4);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x05);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
|
||||
+ 0x36303636);
|
||||
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN,
|
||||
+ 0x6C6C6B6C);
|
||||
+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
|
||||
+ 0x6C6C6B6C);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
bbp = rt2800_bbp_read(rt2x00dev, 4);
|
||||
rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
|
||||
rt2800_bbp_write(rt2x00dev, 4, bbp);
|
||||
@@ -9559,7 +9598,8 @@ static int rt2800_init_eeprom(struct rt2
|
||||
*/
|
||||
eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1);
|
||||
|
||||
- if (rt2x00_rt(rt2x00dev, RT3352)) {
|
||||
+ if (rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
+ rt2x00_rt(rt2x00dev, RT6352)) {
|
||||
if (rt2x00_get_field16(eeprom,
|
||||
EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
|
||||
__set_bit(CAPABILITY_EXTERNAL_PA_TX0,
|
||||
@@ -9570,6 +9610,18 @@ static int rt2800_init_eeprom(struct rt2
|
||||
&rt2x00dev->cap_flags);
|
||||
}
|
||||
|
||||
+ eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF2);
|
||||
+
|
||||
+ if (rt2x00_rt(rt2x00dev, RT6352) && eeprom != 0 && eeprom != 0xffff) {
|
||||
+ if (rt2x00_get_field16(eeprom,
|
||||
+ EEPROM_NIC_CONF2_EXTERNAL_PA)) {
|
||||
+ __set_bit(CAPABILITY_EXTERNAL_PA_TX0,
|
||||
+ &rt2x00dev->cap_flags);
|
||||
+ __set_bit(CAPABILITY_EXTERNAL_PA_TX1,
|
||||
+ &rt2x00dev->cap_flags);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,109 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
BASE=$1; shift
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 NNN <file>..."
|
||||
exit 1
|
||||
}
|
||||
|
||||
check_number() {
|
||||
case "$1" in
|
||||
[0-9][0-9][0-9]) return 0;;
|
||||
esac
|
||||
return 1;
|
||||
}
|
||||
|
||||
patch_header()
|
||||
{
|
||||
awk '
|
||||
/^(---|\*\*\*|Index:)[ \t][^ \t]|^diff -/ \
|
||||
{ exit }
|
||||
{ print }
|
||||
'
|
||||
}
|
||||
|
||||
strip_diffstat()
|
||||
{
|
||||
awk '
|
||||
/#? .* \| / \
|
||||
{ eat = eat $0 "\n"
|
||||
next }
|
||||
/^#? .* files? changed(, .* insertions?\(\+\))?(, .* deletions?\(-\))?/ \
|
||||
{ eat = ""
|
||||
next }
|
||||
{ print eat $0
|
||||
eat = "" }
|
||||
'
|
||||
}
|
||||
|
||||
strip_trailing_whitespace() {
|
||||
sed -e 's:[ '$'\t'']*$::'
|
||||
}
|
||||
|
||||
fixup_header() {
|
||||
awk '
|
||||
/^From / { next }
|
||||
/^Subject: / {
|
||||
sub("Subject: \\[[^\]]*\\]", "Subject: [PATCH]")
|
||||
}
|
||||
{ print }
|
||||
'
|
||||
}
|
||||
|
||||
check_number "$BASE" || usage
|
||||
|
||||
quilt series > /dev/null || {
|
||||
echo "Not in quilt directory"
|
||||
exit 2
|
||||
}
|
||||
|
||||
get_next() {
|
||||
NEW=$BASE
|
||||
quilt series | while read CUR; do
|
||||
[ -n "$CUR" ] || break
|
||||
CUR=${CUR%%-*}
|
||||
check_number "$CUR" || continue
|
||||
[ "$CUR" -lt "$NEW" ] && continue
|
||||
[ "$CUR" -ge "$(($BASE + 100))" ] && continue
|
||||
NEW="$(($CUR + 1))"
|
||||
echo $NEW
|
||||
done | tail -n1
|
||||
}
|
||||
|
||||
CUR=$(get_next)
|
||||
CUR="${CUR:-$BASE}"
|
||||
|
||||
while [ -n "$1" ]; do
|
||||
FILE="$1"; shift
|
||||
NAME="$(basename $FILE)"
|
||||
NAME="${NAME#[0-9]*-}"
|
||||
echo -n "Processing patch $NAME: "
|
||||
|
||||
[ -e "$FILE" ] || {
|
||||
echo "file $FILE not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
grep -qE "$NAME$" patches/series && {
|
||||
echo "already applied"
|
||||
continue
|
||||
}
|
||||
|
||||
quilt new "$CUR-$NAME" || exit 1
|
||||
patch_header < "$FILE" |
|
||||
strip_diffstat |
|
||||
strip_trailing_whitespace |
|
||||
fixup_header > "patches/$CUR-$NAME"
|
||||
|
||||
quilt fold < "$FILE" || {
|
||||
cp "$FILE" ./cur_patch
|
||||
echo "patch $FILE failed to apply, copied to ./cur_patch"
|
||||
exit 1
|
||||
}
|
||||
|
||||
quilt refresh -p ab --no-index --no-timestamps
|
||||
|
||||
CUR="$(($CUR + 1))"
|
||||
done
|
||||
|
||||
exit 0
|
File diff suppressed because it is too large
Load Diff
@ -1,511 +0,0 @@
|
||||
PKG_DRIVERS += \
|
||||
b43 b43legacy brcmsmac brcmfmac brcmutil
|
||||
|
||||
PKG_CONFIG_DEPENDS += \
|
||||
CONFIG_PACKAGE_B43_DEBUG \
|
||||
CONFIG_PACKAGE_B43_PIO \
|
||||
CONFIG_PACKAGE_B43_PHY_G \
|
||||
CONFIG_PACKAGE_B43_PHY_N \
|
||||
CONFIG_PACKAGE_B43_PHY_LP \
|
||||
CONFIG_PACKAGE_B43_PHY_HT \
|
||||
CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB \
|
||||
CONFIG_PACKAGE_B43_BUSES_BCMA \
|
||||
CONFIG_PACKAGE_B43_BUSES_SSB \
|
||||
CONFIG_PACKAGE_BRCM80211_DEBUG
|
||||
|
||||
config-$(call config_package,b43) += B43
|
||||
config-$(CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB) += B43_BUSES_BCMA_AND_SSB
|
||||
config-$(CONFIG_PACKAGE_B43_BUSES_BCMA) += B43_BUSES_BCMA
|
||||
config-$(CONFIG_PACKAGE_B43_BUSES_SSB) += B43_BUSES_SSB
|
||||
config-$(CONFIG_PACKAGE_B43_PHY_G) += B43_PHY_G
|
||||
config-$(CONFIG_PACKAGE_B43_PHY_N) += B43_PHY_N
|
||||
config-$(CONFIG_PACKAGE_B43_PHY_LP) += B43_PHY_LP
|
||||
config-$(CONFIG_PACKAGE_B43_PHY_HT) += B43_PHY_HT
|
||||
config-$(CONFIG_PACKAGE_B43_PIO) += B43_PIO
|
||||
config-$(CONFIG_PACKAGE_B43_DEBUG) += B43_DEBUG
|
||||
|
||||
config-$(call config_package,b43legacy) += B43LEGACY
|
||||
config-y += B43LEGACY_DMA_MODE
|
||||
|
||||
config-$(call config_package,brcmutil) += BRCMUTIL
|
||||
config-$(call config_package,brcmsmac) += BRCMSMAC
|
||||
config-$(call config_package,brcmfmac) += BRCMFMAC
|
||||
config-$(CONFIG_BRCMFMAC_SDIO) += BRCMFMAC_SDIO
|
||||
config-$(CONFIG_BRCMFMAC_USB) += BRCMFMAC_USB
|
||||
config-$(CONFIG_BRCMFMAC_PCIE) += BRCMFMAC_PCIE
|
||||
config-$(CONFIG_PACKAGE_BRCM80211_DEBUG) += BRCMDBG
|
||||
|
||||
config-$(CONFIG_LEDS_TRIGGERS) += B43_LEDS B43LEGACY_LEDS
|
||||
|
||||
#Broadcom firmware
|
||||
ifneq ($(CONFIG_B43_FW_6_30),)
|
||||
PKG_B43_FWV4_NAME:=broadcom-wl
|
||||
PKG_B43_FWV4_VERSION:=6.30.163.46
|
||||
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).wl_apsta.o
|
||||
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
|
||||
PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/
|
||||
PKG_B43_FWV4_HASH:=a07c3b6b277833c7dbe61daa511f908cd66c5e2763eb7a0859abc36cd9335c2d
|
||||
else
|
||||
ifneq ($(CONFIG_B43_FW_5_10),)
|
||||
PKG_B43_FWV4_NAME:=broadcom-wl
|
||||
PKG_B43_FWV4_VERSION:=5.10.56.27.3
|
||||
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta/wl_prebuilt.o
|
||||
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)_mipsel.tar.bz2
|
||||
PKG_B43_FWV4_SOURCE_URL:=@OPENWRT
|
||||
PKG_B43_FWV4_HASH:=26a8c370f48fc129d0731cfd751c36cae1419b0bc8ca35781126744e60eae009
|
||||
else
|
||||
ifneq ($(CONFIG_B43_FW_4_178),)
|
||||
PKG_B43_FWV4_NAME:=broadcom-wl
|
||||
PKG_B43_FWV4_VERSION:=4.178.10.4
|
||||
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o
|
||||
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
|
||||
PKG_B43_FWV4_SOURCE_URL:=@OPENWRT
|
||||
PKG_B43_FWV4_HASH:=32f6ad98facbb9045646fdc8b54bb03086d204153253f9c65d0234a5d90ae53f
|
||||
else
|
||||
ifneq ($(CONFIG_B43_FW_5_100_138),)
|
||||
PKG_B43_FWV4_NAME:=broadcom-wl
|
||||
PKG_B43_FWV4_VERSION:=5.100.138
|
||||
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o
|
||||
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
|
||||
PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/
|
||||
PKG_B43_FWV4_HASH:=f1e7067aac5b62b67b8b6e4c517990277804339ac16065eb13c731ff909ae46f
|
||||
else
|
||||
PKG_B43_FWV4_NAME:=broadcom-wl
|
||||
PKG_B43_FWV4_VERSION:=4.150.10.5
|
||||
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta_mimo.o
|
||||
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
|
||||
PKG_B43_FWV4_SOURCE_URL:=@OPENWRT
|
||||
PKG_B43_FWV4_HASH:=a9f4e276a4d8d3a1cd0f2eb87080ae89b77f0a7140f06d4e9e2135fc44fdd533
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifneq ($(CONFIG_B43_OPENFIRMWARE),)
|
||||
PKG_B43_FWV4_NAME:=broadcom-wl
|
||||
PKG_B43_FWV4_VERSION:=5.2
|
||||
PKG_B43_FWV4_OBJECT:=openfwwf-$(PKG_B43_FWV4_VERSION)
|
||||
PKG_B43_FWV4_SOURCE:=openfwwf-$(PKG_B43_FWV4_VERSION).tar.gz
|
||||
PKG_B43_FWV4_SOURCE_URL:=http://netweb.ing.unibs.it/~openfwwf/firmware
|
||||
PKG_B43_FWV4_HASH:=9de03320083201080b2e94b81637ac07a159cf4e6f3481383e1a217e627bc0dc
|
||||
endif
|
||||
|
||||
|
||||
define Download/b43
|
||||
FILE:=$(PKG_B43_FWV4_SOURCE)
|
||||
URL:=$(PKG_B43_FWV4_SOURCE_URL)
|
||||
HASH:=$(PKG_B43_FWV4_HASH)
|
||||
endef
|
||||
$(eval $(call Download,b43))
|
||||
|
||||
define KernelPackage/b43
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Broadcom 43xx wireless support
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/b43
|
||||
KCONFIG:= \
|
||||
CONFIG_HW_RANDOM=y
|
||||
# Depend on PCI_SUPPORT to make sure we can select kmod-bcma or kmod-ssb
|
||||
DEPENDS += \
|
||||
@PCI_SUPPORT +kmod-mac80211 +kmod-lib-cordic \
|
||||
$(if $(CONFIG_PACKAGE_B43_USE_SSB),+kmod-ssb) \
|
||||
$(if $(CONFIG_PACKAGE_B43_USE_BCMA),+kmod-bcma)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/b43/b43.ko
|
||||
AUTOLOAD:=$(call AutoProbe,b43)
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/b43/config
|
||||
|
||||
config PACKAGE_B43_USE_SSB
|
||||
select PACKAGE_kmod-ssb
|
||||
tristate
|
||||
depends on !TARGET_bcm47xx && !TARGET_bcm63xx
|
||||
default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB
|
||||
default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_SSB
|
||||
|
||||
config PACKAGE_B43_USE_BCMA
|
||||
select PACKAGE_kmod-bcma
|
||||
tristate
|
||||
depends on !TARGET_bcm47xx && !TARGET_bcm53xx
|
||||
default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB
|
||||
default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA
|
||||
|
||||
if PACKAGE_kmod-b43
|
||||
|
||||
choice
|
||||
prompt "b43 firmware version"
|
||||
default B43_FW_5_100_138
|
||||
help
|
||||
This option allows you to select the version of the b43 firmware.
|
||||
|
||||
config B43_FW_4_150
|
||||
bool "Firmware 410.2160 from driver 4.150.10.5 (old stable)"
|
||||
help
|
||||
Old stable firmware for BCM43xx devices.
|
||||
|
||||
If unsure, select this.
|
||||
|
||||
config B43_FW_4_178
|
||||
bool "Firmware 478.104 from driver 4.178.10.4"
|
||||
help
|
||||
Older firmware for BCM43xx devices.
|
||||
|
||||
If unsure, select the "stable" firmware.
|
||||
|
||||
config B43_FW_5_10
|
||||
bool "Firmware 508.1084 from driver 5.10.56.27"
|
||||
help
|
||||
Older firmware for BCM43xx devices.
|
||||
|
||||
If unsure, select the "stable" firmware.
|
||||
|
||||
config B43_FW_5_100_138
|
||||
bool "Firmware 666.2 from driver 5.100.138 (stable)"
|
||||
help
|
||||
The currently default firmware for BCM43xx devices.
|
||||
|
||||
This firmware currently gets most of the testing and is needed for some N-PHY devices.
|
||||
|
||||
If unsure, select the this firmware.
|
||||
|
||||
config B43_FW_6_30
|
||||
bool "Firmware 784.2 from driver 6.30.163.46 (experimental)"
|
||||
help
|
||||
Newer experimental firmware for BCM43xx devices.
|
||||
|
||||
This firmware is mostly untested.
|
||||
|
||||
If unsure, select the "stable" firmware.
|
||||
|
||||
config B43_OPENFIRMWARE
|
||||
bool "Open FirmWare for WiFi networks"
|
||||
help
|
||||
Opensource firmware for BCM43xx devices.
|
||||
|
||||
Do _not_ select this, unless you know what you are doing.
|
||||
The Opensource firmware is not suitable for embedded devices, yet.
|
||||
It does not support QoS, which is bad for AccessPoints.
|
||||
It does not support hardware crypto acceleration, which is a showstopper
|
||||
for embedded devices with low CPU resources.
|
||||
|
||||
If unsure, select the "stable" firmware.
|
||||
|
||||
endchoice
|
||||
|
||||
config B43_FW_SQUASH
|
||||
bool "Remove unnecessary firmware files"
|
||||
depends on !B43_OPENFIRMWARE
|
||||
default y
|
||||
help
|
||||
This options allows you to remove unnecessary b43 firmware files
|
||||
from the final rootfs image. This can reduce the rootfs size by
|
||||
up to 200k.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config B43_FW_SQUASH_COREREVS
|
||||
string "Core revisions to include"
|
||||
depends on B43_FW_SQUASH
|
||||
default "5,6,7,8,9,10,11,13,15" if TARGET_bcm47xx_legacy
|
||||
default "16,28,29,30" if TARGET_bcm47xx_mips74k
|
||||
default "5,6,7,8,9,10,11,13,15,16,28,29,30"
|
||||
help
|
||||
This is a comma separated list of core revision numbers.
|
||||
|
||||
Example (keep files for rev5 only):
|
||||
5
|
||||
|
||||
Example (keep files for rev5 and rev11):
|
||||
5,11
|
||||
|
||||
config B43_FW_SQUASH_PHYTYPES
|
||||
string "PHY types to include"
|
||||
depends on B43_FW_SQUASH
|
||||
default "G,N,LP" if TARGET_bcm47xx_legacy
|
||||
default "N,HT" if TARGET_bcm47xx_mips74k
|
||||
default "G,N,LP,HT"
|
||||
help
|
||||
This is a comma separated list of PHY types:
|
||||
A => A-PHY
|
||||
AG => Dual A-PHY G-PHY
|
||||
G => G-PHY
|
||||
LP => LP-PHY
|
||||
N => N-PHY
|
||||
HT => HT-PHY
|
||||
LCN => LCN-PHY
|
||||
LCN40 => LCN40-PHY
|
||||
AC => AC-PHY
|
||||
|
||||
Example (keep files for G-PHY only):
|
||||
G
|
||||
|
||||
Example (keep files for G-PHY and N-PHY):
|
||||
G,N
|
||||
|
||||
choice
|
||||
prompt "Supported buses"
|
||||
default PACKAGE_B43_BUSES_BCMA_AND_SSB
|
||||
help
|
||||
This allows choosing buses that b43 should support.
|
||||
|
||||
config PACKAGE_B43_BUSES_BCMA_AND_SSB
|
||||
depends on !TARGET_bcm47xx_legacy && !TARGET_bcm47xx_mips74k && !TARGET_bcm53xx
|
||||
bool "BCMA and SSB"
|
||||
|
||||
config PACKAGE_B43_BUSES_BCMA
|
||||
depends on !TARGET_bcm47xx_legacy
|
||||
bool "BCMA only"
|
||||
|
||||
config PACKAGE_B43_BUSES_SSB
|
||||
depends on !TARGET_bcm47xx_mips74k && !TARGET_bcm53xx
|
||||
bool "SSB only"
|
||||
|
||||
endchoice
|
||||
|
||||
config PACKAGE_B43_DEBUG
|
||||
bool "Enable debug output and debugfs for b43"
|
||||
default n
|
||||
help
|
||||
Enable additional debug output and runtime sanity checks for b43
|
||||
and enables the debugfs interface.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PACKAGE_B43_PIO
|
||||
bool "Enable support for PIO transfer mode"
|
||||
default n
|
||||
help
|
||||
Enable support for using PIO instead of DMA. Unless you have DMA
|
||||
transfer problems you don't need this.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PACKAGE_B43_PHY_G
|
||||
bool "Enable support for G-PHYs"
|
||||
default n if TARGET_bcm47xx_mips74k
|
||||
default y
|
||||
help
|
||||
Enable support for G-PHY. This includes support for the following devices:
|
||||
PCI: BCM4306, BCM4311, BCM4318
|
||||
SoC: BCM5352E, BCM4712
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config PACKAGE_B43_PHY_N
|
||||
bool "Enable support for N-PHYs"
|
||||
default y
|
||||
help
|
||||
Enable support for N-PHY. This includes support for the following devices:
|
||||
PCI: BCM4321, BCM4322, BCM43222, BCM43224, BCM43225
|
||||
SoC: BCM4716, BCM4717, BCM4718
|
||||
|
||||
Currently only 11g speed is available.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config PACKAGE_B43_PHY_LP
|
||||
bool "Enable support for LP-PHYs"
|
||||
default n if TARGET_bcm47xx_mips74k
|
||||
default y
|
||||
help
|
||||
Enable support for LP-PHY. This includes support for the following devices:
|
||||
PCI: BCM4312
|
||||
SoC: BCM5354
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config PACKAGE_B43_PHY_HT
|
||||
bool "Enable support for HT-PHYs"
|
||||
default n if TARGET_bcm47xx_legacy
|
||||
default y
|
||||
help
|
||||
Enable support for HT-PHY. This includes support for the following devices:
|
||||
PCI: BCM4331
|
||||
|
||||
Currently only 11g speed is available.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config PACKAGE_B43_PHY_LCN
|
||||
bool "Enable support for LCN-PHYs"
|
||||
depends on BROKEN
|
||||
default n
|
||||
help
|
||||
Currently broken.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
endif
|
||||
endef
|
||||
|
||||
define KernelPackage/b43/description
|
||||
Kernel module for Broadcom 43xx wireless support (mac80211 stack) new
|
||||
endef
|
||||
|
||||
define KernelPackage/b43legacy
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Broadcom 43xx-legacy wireless support
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/b43
|
||||
KCONFIG:= \
|
||||
CONFIG_HW_RANDOM=y
|
||||
DEPENDS+= +kmod-mac80211 +!(TARGET_bcm47xx||TARGET_bcm63xx):kmod-ssb @!TARGET_bcm47xx_mips74k +b43legacy-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/b43legacy/b43legacy.ko
|
||||
AUTOLOAD:=$(call AutoProbe,b43legacy)
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/b43legacy/description
|
||||
Kernel module for Broadcom 43xx-legacy wireless support (mac80211 stack) new
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/brcmutil
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Broadcom IEEE802.11n common driver parts
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211
|
||||
DEPENDS+=@PCI_SUPPORT||USB_SUPPORT
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmutil/brcmutil.ko
|
||||
AUTOLOAD:=$(call AutoProbe,brcmutil)
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmutil/description
|
||||
This module contains some common parts needed by Broadcom Wireless drivers brcmsmac and brcmfmac.
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmutil/config
|
||||
if PACKAGE_kmod-brcmutil
|
||||
|
||||
config PACKAGE_BRCM80211_DEBUG
|
||||
bool "Broadcom wireless driver debugging"
|
||||
help
|
||||
Say Y, if you want to debug brcmsmac and brcmfmac wireless driver.
|
||||
|
||||
endif
|
||||
endef
|
||||
|
||||
PKG_BRCMSMAC_FW_NAME:=broadcom-wl
|
||||
PKG_BRCMSMAC_FW_VERSION:=5.100.138
|
||||
PKG_BRCMSMAC_FW_OBJECT:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION)/linux/wl_apsta.o
|
||||
PKG_BRCMSMAC_FW_SOURCE:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION).tar.bz2
|
||||
PKG_BRCMSMAC_FW_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/
|
||||
PKG_BRCMSMAC_FW_HASH:=f1e7067aac5b62b67b8b6e4c517990277804339ac16065eb13c731ff909ae46f
|
||||
|
||||
define Download/brcmsmac
|
||||
FILE:=$(PKG_BRCMSMAC_FW_SOURCE)
|
||||
URL:=$(PKG_BRCMSMAC_FW_SOURCE_URL)
|
||||
HASH:=$(PKG_BRCMSMAC_FW_HASH)
|
||||
endef
|
||||
$(eval $(call Download,brcmsmac))
|
||||
|
||||
define KernelPackage/brcmsmac
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Broadcom IEEE802.11n PCIe SoftMAC WLAN driver
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211
|
||||
DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT +!TARGET_bcm47xx:kmod-bcma +kmod-lib-cordic +kmod-lib-crc8 +kmod-brcmutil +!BRCMSMAC_USE_FW_FROM_WL:brcmsmac-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcmsmac.ko
|
||||
AUTOLOAD:=$(call AutoProbe,brcmsmac)
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmsmac/description
|
||||
Kernel module for Broadcom IEEE802.11n PCIe Wireless cards
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmsmac/config
|
||||
if PACKAGE_kmod-brcmsmac
|
||||
|
||||
config BRCMSMAC_USE_FW_FROM_WL
|
||||
bool "Use firmware extracted from broadcom proprietary driver"
|
||||
default y
|
||||
help
|
||||
Instead of using the official brcmsmac firmware a firmware
|
||||
version 666.2 extracted from the proprietary Broadcom driver
|
||||
is used. This is needed to get core rev 17 used in bcm4716
|
||||
to work.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
endif
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/brcmfmac
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Broadcom IEEE802.11n USB FullMAC WLAN driver
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211
|
||||
DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT \
|
||||
+kmod-brcmutil +BRCMFMAC_SDIO:kmod-mmc @!TARGET_uml \
|
||||
+BRCMFMAC_USB:kmod-usb-core +BRCMFMAC_USB:brcmfmac-firmware-usb
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko
|
||||
AUTOLOAD:=$(call AutoProbe,brcmfmac)
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmfmac/description
|
||||
Kernel module for Broadcom IEEE802.11n USB Wireless cards
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmfmac/config
|
||||
if PACKAGE_kmod-brcmfmac
|
||||
|
||||
config BRCMFMAC_SDIO
|
||||
bool "Enable SDIO bus interface support"
|
||||
default y if TARGET_bcm27xx
|
||||
default y if TARGET_rockchip
|
||||
default y if TARGET_sunxi
|
||||
default n
|
||||
help
|
||||
Enable support for cards attached to an SDIO bus.
|
||||
Select this option only if you are sure that your
|
||||
board has a Broadcom wireless chip atacched to
|
||||
that bus.
|
||||
|
||||
config BRCMFMAC_USB
|
||||
bool "Enable USB bus interface support"
|
||||
depends on USB_SUPPORT
|
||||
default y
|
||||
help
|
||||
Supported USB connected chipsets:
|
||||
BCM43235, BCM43236, BCM43238 (all in revision 3 only)
|
||||
BCM43143, BCM43242, BCM43566, BCM43569
|
||||
|
||||
config BRCMFMAC_PCIE
|
||||
bool "Enable PCIE bus interface support"
|
||||
depends on PCI_SUPPORT
|
||||
default y
|
||||
help
|
||||
Supported PCIe connected chipsets:
|
||||
BCM4354, BCM4356, BCM43567, BCM43570, BCM43602
|
||||
|
||||
endif
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/b43/install
|
||||
rm -rf $(1)/lib/firmware/
|
||||
ifeq ($(CONFIG_B43_OPENFIRMWARE),y)
|
||||
tar xzf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)"
|
||||
else
|
||||
tar xjf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)"
|
||||
endif
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/
|
||||
ifeq ($(CONFIG_B43_OPENFIRMWARE),y)
|
||||
$(MAKE) -C "$(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/"
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/b43-open/
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/ucode5.fw $(1)/lib/firmware/b43-open/ucode5.fw
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0bsinitvals5.fw $(1)/lib/firmware/b43-open/b0g0bsinitvals5.fw
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0initvals5.fw $(1)/lib/firmware/b43-open/b0g0initvals5.fw
|
||||
else
|
||||
b43-fwcutter -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)
|
||||
endif
|
||||
ifneq ($(CONFIG_B43_FW_SQUASH),)
|
||||
b43-fwsquash.py "$(CONFIG_B43_FW_SQUASH_PHYTYPES)" "$(CONFIG_B43_FW_SQUASH_COREREVS)" "$(1)/lib/firmware/b43"
|
||||
endif
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmsmac/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/brcm
|
||||
ifeq ($(CONFIG_BRCMSMAC_USE_FW_FROM_WL),y)
|
||||
tar xjf "$(DL_DIR)/$(PKG_BRCMSMAC_FW_SOURCE)" -C "$(PKG_BUILD_DIR)"
|
||||
b43-fwcutter --brcmsmac -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_BRCMSMAC_FW_OBJECT)
|
||||
endif
|
||||
endef
|
@ -1,74 +0,0 @@
|
||||
From: Rohan Dutta <drohan@codeaurora.org>
|
||||
Date: Tue, 27 Oct 2020 12:09:10 +0200
|
||||
Subject: [PATCH] cfg80211: Add support to configure SAE PWE value to drivers
|
||||
|
||||
Add support to configure SAE PWE preference from userspace to drivers in
|
||||
both AP and STA modes. This is needed for cases where the driver takes
|
||||
care of Authentication frame processing (SME in the driver) so that
|
||||
correct enforcement of the acceptable PWE derivation mechanism can be
|
||||
performed.
|
||||
|
||||
The userspace applications can pass the sae_pwe value using the
|
||||
NL80211_ATTR_SAE_PWE attribute in the NL80211_CMD_CONNECT and
|
||||
NL80211_CMD_START_AP commands to the driver. This allows selection
|
||||
between the hunting-and-pecking loop and hash-to-element options for PWE
|
||||
derivation. For backwards compatibility, this new attribute is optional
|
||||
and if not included, the driver is notified of the value being
|
||||
unspecified.
|
||||
|
||||
Signed-off-by: Rohan Dutta <drohan@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20201027100910.22283-1-jouni@codeaurora.org
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -1009,6 +1009,14 @@ struct survey_info {
|
||||
* @sae_pwd: password for SAE authentication (for devices supporting SAE
|
||||
* offload)
|
||||
* @sae_pwd_len: length of SAE password (for devices supporting SAE offload)
|
||||
+ * @sae_pwe: The mechanisms allowed for SAE PWE derivation
|
||||
+ * NL80211_SAE_PWE_UNSPECIFIED: Not-specified, used to indicate userspace
|
||||
+ * did not specify any preference. The driver should follow its
|
||||
+ * internal policy in such a scenario.
|
||||
+ * NL80211_SAE_PWE_HUNT_AND_PECK: Allow hunting-and-pecking loop only
|
||||
+ * NL80211_SAE_PWE_HASH_TO_ELEMENT: Allow hash-to-element only
|
||||
+ * NL80211_SAE_PWE_BOTH: Allow either hunting-and-pecking loop
|
||||
+ * or hash-to-element
|
||||
*/
|
||||
struct cfg80211_crypto_settings {
|
||||
u32 wpa_versions;
|
||||
@@ -1027,6 +1035,7 @@ struct cfg80211_crypto_settings {
|
||||
const u8 *psk;
|
||||
const u8 *sae_pwd;
|
||||
u8 sae_pwd_len;
|
||||
+ enum nl80211_sae_pwe_mechanism sae_pwe;
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -736,6 +736,9 @@ static const struct nla_policy nl80211_p
|
||||
NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
|
||||
[NL80211_ATTR_S1G_CAPABILITY_MASK] =
|
||||
NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
|
||||
+ [NL80211_ATTR_SAE_PWE] =
|
||||
+ NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
|
||||
+ NL80211_SAE_PWE_BOTH),
|
||||
[NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
|
||||
};
|
||||
|
||||
@@ -9763,6 +9766,12 @@ static int nl80211_crypto_settings(struc
|
||||
nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
|
||||
}
|
||||
|
||||
+ if (info->attrs[NL80211_ATTR_SAE_PWE])
|
||||
+ settings->sae_pwe =
|
||||
+ nla_get_u8(info->attrs[NL80211_ATTR_SAE_PWE]);
|
||||
+ else
|
||||
+ settings->sae_pwe = NL80211_SAE_PWE_UNSPECIFIED;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ "${ACTION}" = "add" ] && {
|
||||
/sbin/wifi config
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath10k/Kconfig
|
||||
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
|
||||
@@ -86,6 +86,12 @@ config ATH10K_TRACING
|
||||
help
|
||||
Select this to ath10k use tracing infrastructure.
|
||||
|
||||
+config ATH10K_THERMAL
|
||||
+ bool "Atheros ath10k thermal monitoring support"
|
||||
+ depends on THERMAL
|
||||
+ ---help---
|
||||
+ Select this to ath10k use hwmon for thermal measurement.
|
||||
+
|
||||
config ATH10K_DFS_CERTIFIED
|
||||
bool "Atheros DFS support for certified platforms"
|
||||
depends on ATH10K && CFG80211_CERTIFICATION_ONUS
|
||||
--- a/drivers/net/wireless/ath/ath10k/Makefile
|
||||
+++ b/drivers/net/wireless/ath/ath10k/Makefile
|
||||
@@ -18,7 +18,7 @@ ath10k_core-y += mac.o \
|
||||
ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o
|
||||
ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o
|
||||
ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o
|
||||
-ath10k_core-$(CONFIG_THERMAL) += thermal.o
|
||||
+ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o
|
||||
ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o
|
||||
ath10k_core-$(CONFIG_PM) += wow.o
|
||||
ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o
|
||||
--- a/drivers/net/wireless/ath/ath10k/thermal.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/thermal.h
|
||||
@@ -25,7 +25,7 @@ struct ath10k_thermal {
|
||||
int temperature;
|
||||
};
|
||||
|
||||
-#if IS_REACHABLE(CONFIG_THERMAL)
|
||||
+#if IS_REACHABLE(CPTCFG_ATH10K_THERMAL)
|
||||
int ath10k_thermal_register(struct ath10k *ar);
|
||||
void ath10k_thermal_unregister(struct ath10k *ar);
|
||||
void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature);
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -144,6 +144,7 @@ ATH10K_SNOC=
|
||||
ATH10K_DEBUG=
|
||||
ATH10K_DEBUGFS=
|
||||
ATH10K_SPECTRAL=
|
||||
+ATH10K_THERMAL=
|
||||
ATH10K_TRACING=
|
||||
ATH10K_DFS_CERTIFIED=
|
||||
WCN36XX=
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/net/wireless/marvell/mwl8k.c
|
||||
+++ b/drivers/net/wireless/marvell/mwl8k.c
|
||||
@@ -5695,6 +5695,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
|
||||
MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
|
||||
|
||||
static const struct pci_device_id mwl8k_pci_id_table[] = {
|
||||
+ { PCI_VDEVICE(MARVELL, 0x2a02), .driver_data = MWL8363, },
|
||||
{ PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
|
||||
{ PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
|
||||
{ PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
|
@ -1,196 +0,0 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Fri, 9 Apr 2021 12:40:17 +0300
|
||||
Subject: [PATCH] wireless: align some HE capabilities with the spec
|
||||
|
||||
Some names were changed, align that with the spec as of
|
||||
802.11ax-D6.1.
|
||||
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20210409123755.b1e5fbab0d8c.I3eb6076cb0714ec6aec6b8f9dee613ce4a05d825@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -3627,7 +3627,7 @@ ath11k_mac_filter_he_cap_mesh(struct iee
|
||||
IEEE80211_HE_MAC_CAP4_BQR;
|
||||
he_cap_elem->mac_cap_info[4] &= ~m;
|
||||
|
||||
- m = IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_TRANSMISSION |
|
||||
+ m = IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION |
|
||||
IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU |
|
||||
IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING |
|
||||
IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX;
|
||||
@@ -3637,7 +3637,7 @@ ath11k_mac_filter_he_cap_mesh(struct iee
|
||||
IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;
|
||||
he_cap_elem->phy_cap_info[2] &= ~m;
|
||||
|
||||
- m = IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA |
|
||||
+ m = IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK;
|
||||
he_cap_elem->phy_cap_info[3] &= ~m;
|
||||
@@ -3649,13 +3649,13 @@ ath11k_mac_filter_he_cap_mesh(struct iee
|
||||
he_cap_elem->phy_cap_info[5] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
|
||||
- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
|
||||
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
|
||||
IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO;
|
||||
he_cap_elem->phy_cap_info[6] &= ~m;
|
||||
|
||||
- m = IEEE80211_HE_PHY_CAP7_SRP_BASED_SR |
|
||||
- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
|
||||
+ m = IEEE80211_HE_PHY_CAP7_PSR_BASED_SR |
|
||||
+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP |
|
||||
IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ |
|
||||
IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ;
|
||||
he_cap_elem->phy_cap_info[7] &= ~m;
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
@@ -307,8 +307,8 @@ mt7915_set_stream_he_txbf_caps(struct ie
|
||||
IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK;
|
||||
elem->phy_cap_info[5] &= ~c;
|
||||
|
||||
- c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
|
||||
- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB;
|
||||
+ c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
|
||||
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;
|
||||
elem->phy_cap_info[6] &= ~c;
|
||||
|
||||
elem->phy_cap_info[7] &= ~IEEE80211_HE_PHY_CAP7_MAX_NC_MASK;
|
||||
@@ -348,8 +348,8 @@ mt7915_set_stream_he_txbf_caps(struct ie
|
||||
c = (nss - 1) | (max_t(int, mcs->tx_mcs_160, 1) << 3);
|
||||
elem->phy_cap_info[5] |= c;
|
||||
|
||||
- c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
|
||||
- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB;
|
||||
+ c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
|
||||
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;
|
||||
elem->phy_cap_info[6] |= c;
|
||||
}
|
||||
|
||||
@@ -484,7 +484,7 @@ mt7915_init_he_caps(struct mt7915_phy *p
|
||||
IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
|
||||
he_cap_elem->phy_cap_info[7] |=
|
||||
- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
|
||||
+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP |
|
||||
IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI;
|
||||
he_cap_elem->phy_cap_info[8] |=
|
||||
IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
|
||||
--- a/include/linux/ieee80211.h
|
||||
+++ b/include/linux/ieee80211.h
|
||||
@@ -2065,7 +2065,7 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
#define IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG 0x01
|
||||
#define IEEE80211_HE_MAC_CAP4_QTP 0x02
|
||||
#define IEEE80211_HE_MAC_CAP4_BQR 0x04
|
||||
-#define IEEE80211_HE_MAC_CAP4_SRP_RESP 0x08
|
||||
+#define IEEE80211_HE_MAC_CAP4_PSR_RESP 0x08
|
||||
#define IEEE80211_HE_MAC_CAP4_NDP_FB_REP 0x10
|
||||
#define IEEE80211_HE_MAC_CAP4_OPS 0x20
|
||||
#define IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU 0x40
|
||||
@@ -2076,7 +2076,7 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
|
||||
#define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40 0x01
|
||||
#define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B41 0x02
|
||||
-#define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_TRANSMISSION 0x04
|
||||
+#define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION 0x04
|
||||
#define IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU 0x08
|
||||
#define IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX 0x10
|
||||
#define IEEE80211_HE_MAC_CAP5_HE_DYNAMIC_SM_PS 0x20
|
||||
@@ -2134,7 +2134,7 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK 0x18
|
||||
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 0x00
|
||||
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_2 0x20
|
||||
-#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40
|
||||
+#define IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU 0x40
|
||||
#define IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER 0x80
|
||||
|
||||
#define IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE 0x01
|
||||
@@ -2181,15 +2181,15 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
|
||||
#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU 0x01
|
||||
#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU 0x02
|
||||
-#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB 0x04
|
||||
-#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB 0x08
|
||||
+#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB 0x04
|
||||
+#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB 0x08
|
||||
#define IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB 0x10
|
||||
#define IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE 0x20
|
||||
#define IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO 0x40
|
||||
#define IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT 0x80
|
||||
|
||||
-#define IEEE80211_HE_PHY_CAP7_SRP_BASED_SR 0x01
|
||||
-#define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR 0x02
|
||||
+#define IEEE80211_HE_PHY_CAP7_PSR_BASED_SR 0x01
|
||||
+#define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP 0x02
|
||||
#define IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI 0x04
|
||||
#define IEEE80211_HE_PHY_CAP7_MAX_NC_1 0x08
|
||||
#define IEEE80211_HE_PHY_CAP7_MAX_NC_2 0x10
|
||||
--- a/net/mac80211/debugfs_sta.c
|
||||
+++ b/net/mac80211/debugfs_sta.c
|
||||
@@ -732,15 +732,15 @@ static ssize_t sta_he_capa_read(struct f
|
||||
PFLAG(MAC, 4, BSRP_BQRP_A_MPDU_AGG, "BSRP-BQRP-A-MPDU-AGG");
|
||||
PFLAG(MAC, 4, QTP, "QTP");
|
||||
PFLAG(MAC, 4, BQR, "BQR");
|
||||
- PFLAG(MAC, 4, SRP_RESP, "SRP-RESP");
|
||||
+ PFLAG(MAC, 4, PSR_RESP, "PSR-RESP");
|
||||
PFLAG(MAC, 4, NDP_FB_REP, "NDP-FB-REP");
|
||||
PFLAG(MAC, 4, OPS, "OPS");
|
||||
PFLAG(MAC, 4, AMDSU_IN_AMPDU, "AMSDU-IN-AMPDU");
|
||||
|
||||
PRINT("MULTI-TID-AGG-TX-QOS-%d", ((cap[5] << 1) | (cap[4] >> 7)) & 0x7);
|
||||
|
||||
- PFLAG(MAC, 5, SUBCHAN_SELECVITE_TRANSMISSION,
|
||||
- "SUBCHAN-SELECVITE-TRANSMISSION");
|
||||
+ PFLAG(MAC, 5, SUBCHAN_SELECTIVE_TRANSMISSION,
|
||||
+ "SUBCHAN-SELECTIVE-TRANSMISSION");
|
||||
PFLAG(MAC, 5, UL_2x996_TONE_RU, "UL-2x996-TONE-RU");
|
||||
PFLAG(MAC, 5, OM_CTRL_UL_MU_DATA_DIS_RX, "OM-CTRL-UL-MU-DATA-DIS-RX");
|
||||
PFLAG(MAC, 5, HE_DYNAMIC_SM_PS, "HE-DYNAMIC-SM-PS");
|
||||
@@ -832,8 +832,8 @@ static ssize_t sta_he_capa_read(struct f
|
||||
|
||||
PFLAG(PHY, 3, DCM_MAX_RX_NSS_1, "DCM-MAX-RX-NSS-1");
|
||||
PFLAG(PHY, 3, DCM_MAX_RX_NSS_2, "DCM-MAX-RX-NSS-2");
|
||||
- PFLAG(PHY, 3, RX_HE_MU_PPDU_FROM_NON_AP_STA,
|
||||
- "RX-HE-MU-PPDU-FROM-NON-AP-STA");
|
||||
+ PFLAG(PHY, 3, RX_PARTIAL_BW_SU_IN_20MHZ_MU,
|
||||
+ "RX-PARTIAL-BW-SU-IN-20MHZ-MU");
|
||||
PFLAG(PHY, 3, SU_BEAMFORMER, "SU-BEAMFORMER");
|
||||
|
||||
PFLAG(PHY, 4, SU_BEAMFORMEE, "SU-BEAMFORMEE");
|
||||
@@ -853,16 +853,17 @@ static ssize_t sta_he_capa_read(struct f
|
||||
|
||||
PFLAG(PHY, 6, CODEBOOK_SIZE_42_SU, "CODEBOOK-SIZE-42-SU");
|
||||
PFLAG(PHY, 6, CODEBOOK_SIZE_75_MU, "CODEBOOK-SIZE-75-MU");
|
||||
- PFLAG(PHY, 6, TRIG_SU_BEAMFORMER_FB, "TRIG-SU-BEAMFORMER-FB");
|
||||
- PFLAG(PHY, 6, TRIG_MU_BEAMFORMER_FB, "TRIG-MU-BEAMFORMER-FB");
|
||||
+ PFLAG(PHY, 6, TRIG_SU_BEAMFORMING_FB, "TRIG-SU-BEAMFORMING-FB");
|
||||
+ PFLAG(PHY, 6, TRIG_MU_BEAMFORMING_PARTIAL_BW_FB,
|
||||
+ "MU-BEAMFORMING-PARTIAL-BW-FB");
|
||||
PFLAG(PHY, 6, TRIG_CQI_FB, "TRIG-CQI-FB");
|
||||
PFLAG(PHY, 6, PARTIAL_BW_EXT_RANGE, "PARTIAL-BW-EXT-RANGE");
|
||||
PFLAG(PHY, 6, PARTIAL_BANDWIDTH_DL_MUMIMO,
|
||||
"PARTIAL-BANDWIDTH-DL-MUMIMO");
|
||||
PFLAG(PHY, 6, PPE_THRESHOLD_PRESENT, "PPE-THRESHOLD-PRESENT");
|
||||
|
||||
- PFLAG(PHY, 7, SRP_BASED_SR, "SRP-BASED-SR");
|
||||
- PFLAG(PHY, 7, POWER_BOOST_FACTOR_AR, "POWER-BOOST-FACTOR-AR");
|
||||
+ PFLAG(PHY, 7, PSR_BASED_SR, "PSR-BASED-SR");
|
||||
+ PFLAG(PHY, 7, POWER_BOOST_FACTOR_SUPP, "POWER-BOOST-FACTOR-SUPP");
|
||||
PFLAG(PHY, 7, HE_SU_MU_PPDU_4XLTF_AND_08_US_GI,
|
||||
"HE-SU-MU-PPDU-4XLTF-AND-08-US-GI");
|
||||
PFLAG_RANGE(PHY, 7, MAX_NC, 0, 1, 1, "MAX-NC-%d");
|
||||
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
@@ -631,7 +631,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
.phy_cap_info[6] =
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
|
||||
.phy_cap_info[7] =
|
||||
- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
|
||||
+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP |
|
||||
IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI |
|
||||
IEEE80211_HE_PHY_CAP7_MAX_NC_1,
|
||||
.phy_cap_info[8] =
|
@ -1,139 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
@@ -78,6 +78,9 @@ struct rt2800_ops {
|
||||
int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
|
||||
__le32 *(*drv_get_txwi)(struct queue_entry *entry);
|
||||
unsigned int (*drv_get_dma_done)(struct data_queue *queue);
|
||||
+ int (*hw_get_chippkg)(void);
|
||||
+ int (*hw_get_chipver)(void);
|
||||
+ int (*hw_get_chipeco)(void);
|
||||
};
|
||||
|
||||
static inline u32 rt2800_register_read(struct rt2x00_dev *rt2x00dev,
|
||||
@@ -195,6 +198,27 @@ static inline unsigned int rt2800_drv_ge
|
||||
return rt2800ops->drv_get_dma_done(queue);
|
||||
}
|
||||
|
||||
+static inline int rt2800_hw_get_chippkg(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
|
||||
+
|
||||
+ return rt2800ops->hw_get_chippkg();
|
||||
+}
|
||||
+
|
||||
+static inline int rt2800_hw_get_chipver(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
|
||||
+
|
||||
+ return rt2800ops->hw_get_chipver();
|
||||
+}
|
||||
+
|
||||
+static inline int rt2800_hw_get_chipeco(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
|
||||
+
|
||||
+ return rt2800ops->hw_get_chipeco();
|
||||
+}
|
||||
+
|
||||
void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
|
||||
const u8 command, const u8 token,
|
||||
const u8 arg0, const u8 arg1);
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
|
||||
@@ -286,6 +286,10 @@ static int rt2800pci_read_eeprom(struct
|
||||
return retval;
|
||||
}
|
||||
|
||||
+static int rt2800pci_get_chippkg(void) { return 0; }
|
||||
+static int rt2800pci_get_chipver(void) { return 0; }
|
||||
+static int rt2800pci_get_chipeco(void) { return 0; }
|
||||
+
|
||||
static const struct ieee80211_ops rt2800pci_mac80211_ops = {
|
||||
.tx = rt2x00mac_tx,
|
||||
.start = rt2x00mac_start,
|
||||
@@ -328,6 +332,9 @@ static const struct rt2800_ops rt2800pci
|
||||
.drv_init_registers = rt2800mmio_init_registers,
|
||||
.drv_get_txwi = rt2800mmio_get_txwi,
|
||||
.drv_get_dma_done = rt2800mmio_get_dma_done,
|
||||
+ .hw_get_chippkg = rt2800pci_get_chippkg,
|
||||
+ .hw_get_chipver = rt2800pci_get_chipver,
|
||||
+ .hw_get_chipeco = rt2800pci_get_chipeco,
|
||||
};
|
||||
|
||||
static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
@@ -27,6 +27,12 @@
|
||||
#include "rt2800lib.h"
|
||||
#include "rt2800mmio.h"
|
||||
|
||||
+/* Needed to probe CHIP_VER register on MT7620 */
|
||||
+#ifdef CONFIG_SOC_MT7620
|
||||
+#include <asm/mach-ralink/ralink_regs.h>
|
||||
+#include <asm/mach-ralink/mt7620.h>
|
||||
+#endif
|
||||
+
|
||||
/* Allow hardware encryption to be disabled. */
|
||||
static bool modparam_nohwcrypt;
|
||||
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444);
|
||||
@@ -118,6 +124,27 @@ static int rt2800soc_write_firmware(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SOC_MT7620
|
||||
+static int rt2800soc_get_chippkg(void)
|
||||
+{
|
||||
+ return mt7620_get_pkg();
|
||||
+}
|
||||
+
|
||||
+static int rt2800soc_get_chipver(void)
|
||||
+{
|
||||
+ return mt7620_get_chipver();
|
||||
+}
|
||||
+
|
||||
+static int rt2800soc_get_chipeco(void)
|
||||
+{
|
||||
+ return mt7620_get_eco();
|
||||
+}
|
||||
+#else
|
||||
+static int rt2800soc_get_chippkg(void) { return 0; }
|
||||
+static int rt2800soc_get_chipver(void) { return 0; }
|
||||
+static int rt2800soc_get_chipeco(void) { return 0; }
|
||||
+#endif
|
||||
+
|
||||
static const struct ieee80211_ops rt2800soc_mac80211_ops = {
|
||||
.tx = rt2x00mac_tx,
|
||||
.start = rt2x00mac_start,
|
||||
@@ -159,6 +186,9 @@ static const struct rt2800_ops rt2800soc
|
||||
.drv_init_registers = rt2800mmio_init_registers,
|
||||
.drv_get_txwi = rt2800mmio_get_txwi,
|
||||
.drv_get_dma_done = rt2800mmio_get_dma_done,
|
||||
+ .hw_get_chippkg = rt2800soc_get_chippkg,
|
||||
+ .hw_get_chipver = rt2800soc_get_chipver,
|
||||
+ .hw_get_chipeco = rt2800soc_get_chipeco,
|
||||
};
|
||||
|
||||
static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
|
||||
@@ -628,6 +628,10 @@ static int rt2800usb_probe_hw(struct rt2
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int rt2800usb_get_chippkg(void) { return 0; }
|
||||
+static int rt2800usb_get_chipver(void) { return 0; }
|
||||
+static int rt2800usb_get_chipeco(void) { return 0; }
|
||||
+
|
||||
static const struct ieee80211_ops rt2800usb_mac80211_ops = {
|
||||
.tx = rt2x00mac_tx,
|
||||
.start = rt2x00mac_start,
|
||||
@@ -671,6 +675,9 @@ static const struct rt2800_ops rt2800usb
|
||||
.drv_init_registers = rt2800usb_init_registers,
|
||||
.drv_get_txwi = rt2800usb_get_txwi,
|
||||
.drv_get_dma_done = rt2800usb_get_dma_done,
|
||||
+ .hw_get_chippkg = rt2800usb_get_chippkg,
|
||||
+ .hw_get_chipver = rt2800usb_get_chipver,
|
||||
+ .hw_get_chipeco = rt2800usb_get_chipeco,
|
||||
};
|
||||
|
||||
static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
|
@ -1,53 +0,0 @@
|
||||
From 79c9d7aabae1d1da9eea97d83b61e1517a8a2221 Mon Sep 17 00:00:00 2001
|
||||
From: Mathias Kresin <dev@kresin.me>
|
||||
Date: Fri, 22 Jun 2018 18:59:44 +0200
|
||||
Subject: [PATCH] ath10k: use tpt LED trigger by default
|
||||
|
||||
Use the tpt LED trigger for each created phy led. Ths way LEDs attached
|
||||
to the ath10k GPIO pins are indicating the phy status and blink on
|
||||
traffic.
|
||||
|
||||
Signed-off-by: Mathias Kresin <dev@kresin.me>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/core.h | 4 ++++
|
||||
drivers/net/wireless/ath/ath10k/leds.c | 4 +---
|
||||
drivers/net/wireless/ath/ath10k/mac.c | 2 +-
|
||||
3 files changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.h
|
||||
@@ -1290,6 +1290,10 @@ struct ath10k {
|
||||
bool coex_support;
|
||||
int coex_gpio_pin;
|
||||
|
||||
+#ifdef CPTCFG_MAC80211_LEDS
|
||||
+ const char *led_default_trigger;
|
||||
+#endif
|
||||
+
|
||||
/* must be last */
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
--- a/drivers/net/wireless/ath/ath10k/leds.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/leds.c
|
||||
@@ -81,9 +81,7 @@ int ath10k_leds_register(struct ath10k *
|
||||
|
||||
ar->leds.cdev.name = ar->leds.label;
|
||||
ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking;
|
||||
-
|
||||
- /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */
|
||||
- ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger;
|
||||
+ ar->leds.cdev.default_trigger = ar->led_default_trigger;
|
||||
|
||||
ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev);
|
||||
if (ret)
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -10075,7 +10075,7 @@ int ath10k_mac_register(struct ath10k *a
|
||||
ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
|
||||
|
||||
#ifdef CPTCFG_MAC80211_LEDS
|
||||
- ieee80211_create_tpt_led_trigger(ar->hw,
|
||||
+ ar->led_default_trigger = ieee80211_create_tpt_led_trigger(ar->hw,
|
||||
IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink,
|
||||
ARRAY_SIZE(ath10k_tpt_blink));
|
||||
#endif
|
@ -1,111 +0,0 @@
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Sat, 9 Jan 2021 18:57:51 +0100
|
||||
Subject: [PATCH] mac80211: introduce aql_enable node in debugfs
|
||||
|
||||
Introduce aql_enable node in debugfs in order to enable/disable aql.
|
||||
This is useful for debugging purpose.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://lore.kernel.org/r/e7a934d5d84e4796c4f97ea5de4e66c824296b07.1610214851.git.lorenzo@kernel.org
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/debugfs.c
|
||||
+++ b/net/mac80211/debugfs.c
|
||||
@@ -281,6 +281,56 @@ static const struct file_operations aql_
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
+static ssize_t aql_enable_read(struct file *file, char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ char buf[3];
|
||||
+ int len;
|
||||
+
|
||||
+ len = scnprintf(buf, sizeof(buf), "%d\n",
|
||||
+ !static_key_false(&aql_disable.key));
|
||||
+
|
||||
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
+}
|
||||
+
|
||||
+static ssize_t aql_enable_write(struct file *file, const char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ bool aql_disabled = static_key_false(&aql_disable.key);
|
||||
+ char buf[3];
|
||||
+ size_t len;
|
||||
+
|
||||
+ if (count > sizeof(buf))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (copy_from_user(buf, user_buf, count))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ buf[sizeof(buf) - 1] = '\0';
|
||||
+ len = strlen(buf);
|
||||
+ if (len > 0 && buf[len - 1] == '\n')
|
||||
+ buf[len - 1] = 0;
|
||||
+
|
||||
+ if (buf[0] == '0' && buf[1] == '\0') {
|
||||
+ if (!aql_disabled)
|
||||
+ static_branch_inc(&aql_disable);
|
||||
+ } else if (buf[0] == '1' && buf[1] == '\0') {
|
||||
+ if (aql_disabled)
|
||||
+ static_branch_dec(&aql_disable);
|
||||
+ } else {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations aql_enable_ops = {
|
||||
+ .write = aql_enable_write,
|
||||
+ .read = aql_enable_read,
|
||||
+ .open = simple_open,
|
||||
+ .llseek = default_llseek,
|
||||
+};
|
||||
+
|
||||
static ssize_t force_tx_status_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count,
|
||||
@@ -569,6 +619,7 @@ void debugfs_hw_add(struct ieee80211_loc
|
||||
DEBUGFS_ADD(power);
|
||||
DEBUGFS_ADD(hw_conf);
|
||||
DEBUGFS_ADD_MODE(force_tx_status, 0600);
|
||||
+ DEBUGFS_ADD_MODE(aql_enable, 0600);
|
||||
|
||||
if (local->ops->wake_tx_queue)
|
||||
DEBUGFS_ADD_MODE(aqm, 0600);
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1140,6 +1140,8 @@ enum mac80211_scan_state {
|
||||
SCAN_ABORT,
|
||||
};
|
||||
|
||||
+DECLARE_STATIC_KEY_FALSE(aql_disable);
|
||||
+
|
||||
struct ieee80211_local {
|
||||
/* embed the driver visible part.
|
||||
* don't cast (use the static inlines below), but we keep
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3909,6 +3909,8 @@ void __ieee80211_schedule_txq(struct iee
|
||||
}
|
||||
EXPORT_SYMBOL(__ieee80211_schedule_txq);
|
||||
|
||||
+DEFINE_STATIC_KEY_FALSE(aql_disable);
|
||||
+
|
||||
bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
|
||||
struct ieee80211_txq *txq)
|
||||
{
|
||||
@@ -3918,6 +3920,9 @@ bool ieee80211_txq_airtime_check(struct
|
||||
if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
|
||||
return true;
|
||||
|
||||
+ if (static_branch_unlikely(&aql_disable))
|
||||
+ return true;
|
||||
+
|
||||
if (!txq->sta)
|
||||
return true;
|
||||
|
@ -1,126 +0,0 @@
|
||||
From: Ryder Lee <ryder.lee@mediatek.com>
|
||||
Date: Fri, 28 May 2021 14:05:43 +0800
|
||||
Subject: [PATCH] mac80211: add rate control support for encap offload
|
||||
|
||||
The software rate control cannot deal with encap offload, so fix it.
|
||||
|
||||
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rate.c
|
||||
+++ b/net/mac80211/rate.c
|
||||
@@ -297,15 +297,11 @@ void ieee80211_check_rate_mask(struct ie
|
||||
static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc)
|
||||
{
|
||||
struct sk_buff *skb = txrc->skb;
|
||||
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
- __le16 fc;
|
||||
-
|
||||
- fc = hdr->frame_control;
|
||||
|
||||
return (info->flags & (IEEE80211_TX_CTL_NO_ACK |
|
||||
IEEE80211_TX_CTL_USE_MINRATE)) ||
|
||||
- !ieee80211_is_data(fc);
|
||||
+ !ieee80211_is_tx_data(skb);
|
||||
}
|
||||
|
||||
static void rc_send_low_basicrate(struct ieee80211_tx_rate *rate,
|
||||
@@ -870,7 +866,6 @@ void ieee80211_get_tx_rates(struct ieee8
|
||||
int max_rates)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_supported_band *sband;
|
||||
|
||||
@@ -882,7 +877,7 @@ void ieee80211_get_tx_rates(struct ieee8
|
||||
sdata = vif_to_sdata(vif);
|
||||
sband = sdata->local->hw.wiphy->bands[info->band];
|
||||
|
||||
- if (ieee80211_is_data(hdr->frame_control))
|
||||
+ if (ieee80211_is_tx_data(skb))
|
||||
rate_control_apply_mask(sdata, sta, sband, dest, max_rates);
|
||||
|
||||
if (dest[0].idx < 0)
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -679,6 +679,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
|
||||
u32 len;
|
||||
struct ieee80211_tx_rate_control txrc;
|
||||
struct ieee80211_sta_rates *ratetbl = NULL;
|
||||
+ bool encap = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
|
||||
bool assoc = false;
|
||||
|
||||
memset(&txrc, 0, sizeof(txrc));
|
||||
@@ -720,7 +721,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
|
||||
* just wants a probe response.
|
||||
*/
|
||||
if (tx->sdata->vif.bss_conf.use_short_preamble &&
|
||||
- (ieee80211_is_data(hdr->frame_control) ||
|
||||
+ (ieee80211_is_tx_data(tx->skb) ||
|
||||
(tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
|
||||
txrc.short_preamble = true;
|
||||
|
||||
@@ -742,7 +743,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
|
||||
"%s: Dropped data frame as no usable bitrate found while "
|
||||
"scanning and associated. Target station: "
|
||||
"%pM on %d GHz band\n",
|
||||
- tx->sdata->name, hdr->addr1,
|
||||
+ tx->sdata->name,
|
||||
+ encap ? ((struct ethhdr *)hdr)->h_dest : hdr->addr1,
|
||||
info->band ? 5 : 2))
|
||||
return TX_DROP;
|
||||
|
||||
@@ -776,7 +778,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
|
||||
|
||||
if (txrc.reported_rate.idx < 0) {
|
||||
txrc.reported_rate = tx->rate;
|
||||
- if (tx->sta && ieee80211_is_data(hdr->frame_control))
|
||||
+ if (tx->sta && ieee80211_is_tx_data(tx->skb))
|
||||
tx->sta->tx_stats.last_rate = txrc.reported_rate;
|
||||
} else if (tx->sta)
|
||||
tx->sta->tx_stats.last_rate = txrc.reported_rate;
|
||||
@@ -3682,8 +3684,16 @@ begin:
|
||||
else
|
||||
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
|
||||
|
||||
- if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
|
||||
+ if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
|
||||
+ if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) {
|
||||
+ r = ieee80211_tx_h_rate_ctrl(&tx);
|
||||
+ if (r != TX_CONTINUE) {
|
||||
+ ieee80211_free_txskb(&local->hw, skb);
|
||||
+ goto begin;
|
||||
+ }
|
||||
+ }
|
||||
goto encap_out;
|
||||
+ }
|
||||
|
||||
if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) {
|
||||
struct sta_info *sta = container_of(txq->sta, struct sta_info,
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -6733,4 +6733,22 @@ struct sk_buff *ieee80211_get_fils_disco
|
||||
struct sk_buff *
|
||||
ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif);
|
||||
+
|
||||
+/**
|
||||
+ * ieee80211_is_tx_data - check if frame is a data frame
|
||||
+ *
|
||||
+ * The function is used to check if a frame is a data frame. Frames with
|
||||
+ * hardware encapsulation enabled are data frames.
|
||||
+ *
|
||||
+ * @skb: the frame to be transmitted.
|
||||
+ */
|
||||
+static inline bool ieee80211_is_tx_data(struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
+ struct ieee80211_hdr *hdr = (void *) skb->data;
|
||||
+
|
||||
+ return info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP ||
|
||||
+ ieee80211_is_data(hdr->frame_control);
|
||||
+}
|
||||
+
|
||||
#endif /* MAC80211_H */
|
@ -1,20 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 26 Dec 2020 19:14:58 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: increase stats update interval
|
||||
|
||||
The shorter interval was leading to too many frames being used for probing
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -1865,7 +1865,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h
|
||||
mp->has_mrr = true;
|
||||
|
||||
mp->hw = hw;
|
||||
- mp->update_interval = HZ / 20;
|
||||
+ mp->update_interval = HZ / 10;
|
||||
|
||||
minstrel_ht_init_cck_rates(mp);
|
||||
for (i = 0; i < ARRAY_SIZE(mp->hw->wiphy->bands); i++)
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1341,7 +1341,7 @@ static inline void rt2x00lib_set_if_comb
|
||||
*/
|
||||
if_limit = &rt2x00dev->if_limits_ap;
|
||||
if_limit->max = rt2x00dev->ops->max_ap_intf;
|
||||
- if_limit->types = BIT(NL80211_IFTYPE_AP);
|
||||
+ if_limit->types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_STATION);
|
||||
#ifdef CPTCFG_MAC80211_MESH
|
||||
if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT);
|
||||
#endif
|
@ -1,408 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
@@ -1042,6 +1042,11 @@
|
||||
#define MIMO_PS_CFG_RX_STBY_POL FIELD32(0x00000010)
|
||||
#define MIMO_PS_CFG_RX_RX_STBY0 FIELD32(0x00000020)
|
||||
|
||||
+#define BB_PA_MODE_CFG0 0x1214
|
||||
+#define BB_PA_MODE_CFG1 0x1218
|
||||
+#define RF_PA_MODE_CFG0 0x121C
|
||||
+#define RF_PA_MODE_CFG1 0x1220
|
||||
+
|
||||
/*
|
||||
* EDCA_AC0_CFG:
|
||||
*/
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -3685,14 +3685,16 @@ static void rt2800_config_channel_rf7620
|
||||
rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4);
|
||||
rt2800_rfcsr_write(rt2x00dev, 19, rfcsr);
|
||||
|
||||
- /* Default: XO=20MHz , SDM mode */
|
||||
- rfcsr = rt2800_rfcsr_read(rt2x00dev, 16);
|
||||
- rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
|
||||
-
|
||||
- rfcsr = rt2800_rfcsr_read(rt2x00dev, 21);
|
||||
- rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
|
||||
+ /* Default: XO=20MHz , SDM mode */
|
||||
+ rfcsr = rt2800_rfcsr_read(rt2x00dev, 16);
|
||||
+ rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
|
||||
+
|
||||
+ rfcsr = rt2800_rfcsr_read(rt2x00dev, 21);
|
||||
+ rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
|
||||
+ }
|
||||
|
||||
rfcsr = rt2800_rfcsr_read(rt2x00dev, 1);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620,
|
||||
@@ -3726,18 +3728,23 @@ static void rt2800_config_channel_rf7620
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20);
|
||||
}
|
||||
|
||||
- if (conf_is_ht40(conf)) {
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08);
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08);
|
||||
- } else {
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28);
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
|
||||
+ if (conf_is_ht40(conf)) {
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08);
|
||||
+ } else {
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28);
|
||||
+ }
|
||||
}
|
||||
|
||||
- rfcsr = rt2800_rfcsr_read(rt2x00dev, 28);
|
||||
- rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40,
|
||||
- conf_is_ht40(conf) && (rf->channel == 11));
|
||||
- rt2800_rfcsr_write(rt2x00dev, 28, rfcsr);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
|
||||
+ rt2800_hw_get_chipeco(rt2x00dev) == 2) {
|
||||
+ rfcsr = rt2800_rfcsr_read(rt2x00dev, 28);
|
||||
+ rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40,
|
||||
+ conf_is_ht40(conf) && (rf->channel == 11));
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 28, rfcsr);
|
||||
+ }
|
||||
|
||||
if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) {
|
||||
if (conf_is_ht40(conf)) {
|
||||
@@ -3837,25 +3844,29 @@ static void rt2800_config_alc(struct rt2
|
||||
if (i == 10000)
|
||||
rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n");
|
||||
|
||||
- if (chan->center_freq > 2457) {
|
||||
- bbp = rt2800_bbp_read(rt2x00dev, 30);
|
||||
- bbp = 0x40;
|
||||
- rt2800_bbp_write(rt2x00dev, 30, bbp);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 39, 0);
|
||||
- if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
|
||||
- rt2800_rfcsr_write(rt2x00dev, 42, 0xfb);
|
||||
- else
|
||||
- rt2800_rfcsr_write(rt2x00dev, 42, 0x7b);
|
||||
- } else {
|
||||
- bbp = rt2800_bbp_read(rt2x00dev, 30);
|
||||
- bbp = 0x1f;
|
||||
- rt2800_bbp_write(rt2x00dev, 30, bbp);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
|
||||
- if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
|
||||
- rt2800_rfcsr_write(rt2x00dev, 42, 0xdb);
|
||||
- else
|
||||
- rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
|
||||
+ rt2800_hw_get_chipeco(rt2x00dev) >= 2) {
|
||||
+ if (chan->center_freq > 2457) {
|
||||
+ bbp = rt2800_bbp_read(rt2x00dev, 30);
|
||||
+ bbp = 0x40;
|
||||
+ rt2800_bbp_write(rt2x00dev, 30, bbp);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 39, 0);
|
||||
+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 42, 0xfb);
|
||||
+ else
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 42, 0x7b);
|
||||
+ } else {
|
||||
+ bbp = rt2800_bbp_read(rt2x00dev, 30);
|
||||
+ bbp = 0x1f;
|
||||
+ rt2800_bbp_write(rt2x00dev, 30, bbp);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
|
||||
+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 42, 0xdb);
|
||||
+ else
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
|
||||
+ }
|
||||
}
|
||||
+
|
||||
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl);
|
||||
|
||||
rt2800_vco_calibration(rt2x00dev);
|
||||
@@ -5887,18 +5898,33 @@ static int rt2800_init_registers(struct
|
||||
} else if (rt2x00_rt(rt2x00dev, RT5350)) {
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT6352)) {
|
||||
- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
|
||||
- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
|
||||
- rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
|
||||
- rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000);
|
||||
- rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
|
||||
- rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0);
|
||||
- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C);
|
||||
- rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C666C);
|
||||
- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
|
||||
- 0x3630363A);
|
||||
- rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT,
|
||||
- 0x3630363A);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) <= 1) {
|
||||
+ rt2800_register_write(rt2x00dev, TX_ALC_VGA3,
|
||||
+ 0x00000000);
|
||||
+ rt2800_register_write(rt2x00dev, BB_PA_MODE_CFG0,
|
||||
+ 0x000055FF);
|
||||
+ rt2800_register_write(rt2x00dev, BB_PA_MODE_CFG1,
|
||||
+ 0x00550055);
|
||||
+ rt2800_register_write(rt2x00dev, RF_PA_MODE_CFG0,
|
||||
+ 0x000055FF);
|
||||
+ rt2800_register_write(rt2x00dev, RF_PA_MODE_CFG1,
|
||||
+ 0x00550055);
|
||||
+ } else {
|
||||
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
|
||||
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
|
||||
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
|
||||
+ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000);
|
||||
+ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
|
||||
+ rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0);
|
||||
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN,
|
||||
+ 0x6C6C666C);
|
||||
+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
|
||||
+ 0x6C6C666C);
|
||||
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
|
||||
+ 0x3630363A);
|
||||
+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT,
|
||||
+ 0x3630363A);
|
||||
+ }
|
||||
reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_1);
|
||||
rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0);
|
||||
rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg);
|
||||
@@ -7042,14 +7068,16 @@ static void rt2800_init_bbp_6352(struct
|
||||
rt2800_bbp_write(rt2x00dev, 188, 0x00);
|
||||
rt2800_bbp_write(rt2x00dev, 189, 0x00);
|
||||
|
||||
- rt2800_bbp_write(rt2x00dev, 91, 0x06);
|
||||
- rt2800_bbp_write(rt2x00dev, 92, 0x04);
|
||||
- rt2800_bbp_write(rt2x00dev, 93, 0x54);
|
||||
- rt2800_bbp_write(rt2x00dev, 99, 0x50);
|
||||
- rt2800_bbp_write(rt2x00dev, 148, 0x84);
|
||||
- rt2800_bbp_write(rt2x00dev, 167, 0x80);
|
||||
- rt2800_bbp_write(rt2x00dev, 178, 0xFF);
|
||||
- rt2800_bbp_write(rt2x00dev, 106, 0x13);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 91, 0x06);
|
||||
+ rt2800_bbp_write(rt2x00dev, 92, 0x04);
|
||||
+ rt2800_bbp_write(rt2x00dev, 93, 0x54);
|
||||
+ rt2800_bbp_write(rt2x00dev, 99, 0x50);
|
||||
+ rt2800_bbp_write(rt2x00dev, 148, 0x84);
|
||||
+ rt2800_bbp_write(rt2x00dev, 167, 0x80);
|
||||
+ rt2800_bbp_write(rt2x00dev, 178, 0xFF);
|
||||
+ rt2800_bbp_write(rt2x00dev, 106, 0x13);
|
||||
+ }
|
||||
|
||||
/* BBP for G band GLRT function (BBP_128 ~ BBP_221) */
|
||||
rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00);
|
||||
@@ -10388,31 +10416,36 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rfcsr_write(rt2x00dev, 42, 0x5B);
|
||||
rt2800_rfcsr_write(rt2x00dev, 43, 0x00);
|
||||
|
||||
- rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
|
||||
- if (rt2800_clk_is_20mhz(rt2x00dev))
|
||||
- rt2800_rfcsr_write(rt2x00dev, 13, 0x03);
|
||||
- else
|
||||
- rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 14, 0x7C);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 16, 0x80);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 17, 0x99);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 18, 0x99);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 19, 0x09);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 20, 0x50);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 21, 0xB0);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 23, 0x06);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 26, 0x5D);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 28, 0x61);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 29, 0xB5);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 43, 0x02);
|
||||
-
|
||||
- rt2800_rfcsr_write(rt2x00dev, 28, 0x62);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 29, 0xAD);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
|
||||
+ if (rt2800_clk_is_20mhz(rt2x00dev))
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 13, 0x03);
|
||||
+ else
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 14, 0x7C);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 16, 0x80);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 17, 0x99);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 18, 0x99);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 19, 0x09);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 20, 0x50);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 21, 0xB0);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 23, 0x06);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 26, 0x5D);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 28, 0x61);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 29, 0xB5);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 43, 0x02);
|
||||
+ }
|
||||
+
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
|
||||
+ rt2800_hw_get_chipeco(rt2x00dev) >= 2) {
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 28, 0x62);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 29, 0xAD);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
|
||||
+ }
|
||||
|
||||
/* Initialize RF channel register to default value */
|
||||
rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03);
|
||||
@@ -10478,63 +10511,71 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
|
||||
rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5);
|
||||
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
|
||||
- rt2800_rfcsr_write_bank(rt2x00dev, 4, 47, 0x67);
|
||||
- rt2800_rfcsr_write_bank(rt2x00dev, 6, 47, 0x69);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF);
|
||||
- rt2800_rfcsr_write_bank(rt2x00dev, 4, 54, 0x27);
|
||||
- rt2800_rfcsr_write_bank(rt2x00dev, 6, 54, 0x20);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09);
|
||||
-
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
|
||||
-
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
|
||||
-
|
||||
- /* Initialize RF channel register for DRQFN */
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 47, 0x67);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 47, 0x69);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 54, 0x27);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 54, 0x20);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09);
|
||||
+ }
|
||||
+
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
|
||||
+ rt2800_hw_get_chipeco(rt2x00dev) >= 2) {
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
|
||||
+
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
|
||||
+ }
|
||||
+
|
||||
+ if (rt2800_hw_get_chippkg(rt2x00dev) == 0 &&
|
||||
+ rt2800_hw_get_chipver(rt2x00dev) == 1) {
|
||||
+ /* Initialize RF channel register for DRQFN */
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7);
|
||||
+ }
|
||||
|
||||
/* Initialize RF DC calibration register to default value */
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47);
|
||||
@@ -10597,12 +10638,17 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00);
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00);
|
||||
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08);
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04);
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20);
|
||||
+ }
|
||||
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
|
||||
+ rt2800_hw_get_chipeco(rt2x00dev) >= 2) {
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
|
||||
+ }
|
||||
|
||||
rt2800_r_calibration(rt2x00dev);
|
||||
rt2800_rf_self_txdc_cal(rt2x00dev);
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/Kconfig
|
||||
+++ b/drivers/net/wireless/ath/Kconfig
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: ISC
|
||||
config ATH_COMMON
|
||||
- tristate
|
||||
+ tristate "ath.ko"
|
||||
depends on m
|
||||
|
||||
config WLAN_VENDOR_ATH
|
@ -1,113 +0,0 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Fri, 9 Apr 2021 12:40:24 +0300
|
||||
Subject: [PATCH] wireless: fix spelling of A-MSDU in HE capabilities
|
||||
|
||||
In the HE capabilities, spell A-MSDU correctly, not "A-MDSU".
|
||||
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20210409123755.9e6ff1af1181.If6868bc6902ccd9a95c74c78f716c4b41473ef14@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
@@ -598,7 +598,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
.mac_cap_info[4] =
|
||||
- IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU |
|
||||
+ IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU |
|
||||
IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39,
|
||||
.mac_cap_info[5] =
|
||||
IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40 |
|
||||
@@ -682,7 +682,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
.mac_cap_info[4] =
|
||||
- IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
|
||||
+ IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.mac_cap_info[5] =
|
||||
IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU,
|
||||
.phy_cap_info[0] =
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
@@ -427,7 +427,7 @@ mt7915_init_he_caps(struct mt7915_phy *p
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED;
|
||||
he_cap_elem->mac_cap_info[4] =
|
||||
- IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU;
|
||||
+ IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU;
|
||||
|
||||
if (band == NL80211_BAND_2GHZ)
|
||||
he_cap_elem->phy_cap_info[0] =
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
|
||||
@@ -1353,7 +1353,7 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *sk
|
||||
if (elem->mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL)
|
||||
cap |= STA_REC_HE_CAP_OM;
|
||||
|
||||
- if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU)
|
||||
+ if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU)
|
||||
cap |= STA_REC_HE_CAP_AMSDU_IN_AMPDU;
|
||||
|
||||
if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR)
|
||||
--- a/include/linux/ieee80211.h
|
||||
+++ b/include/linux/ieee80211.h
|
||||
@@ -2068,7 +2068,7 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
#define IEEE80211_HE_MAC_CAP4_PSR_RESP 0x08
|
||||
#define IEEE80211_HE_MAC_CAP4_NDP_FB_REP 0x10
|
||||
#define IEEE80211_HE_MAC_CAP4_OPS 0x20
|
||||
-#define IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU 0x40
|
||||
+#define IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU 0x40
|
||||
/* Multi TID agg TX is split between byte #4 and #5
|
||||
* The value is a combination of B39,B40,B41
|
||||
*/
|
||||
--- a/net/mac80211/debugfs_sta.c
|
||||
+++ b/net/mac80211/debugfs_sta.c
|
||||
@@ -735,7 +735,7 @@ static ssize_t sta_he_capa_read(struct f
|
||||
PFLAG(MAC, 4, PSR_RESP, "PSR-RESP");
|
||||
PFLAG(MAC, 4, NDP_FB_REP, "NDP-FB-REP");
|
||||
PFLAG(MAC, 4, OPS, "OPS");
|
||||
- PFLAG(MAC, 4, AMDSU_IN_AMPDU, "AMSDU-IN-AMPDU");
|
||||
+ PFLAG(MAC, 4, AMSDU_IN_AMPDU, "AMSDU-IN-AMPDU");
|
||||
|
||||
PRINT("MULTI-TID-AGG-TX-QOS-%d", ((cap[5] << 1) | (cap[4] >> 7)) & 0x7);
|
||||
|
||||
--- a/drivers/net/wireless/mac80211_hwsim.c
|
||||
+++ b/drivers/net/wireless/mac80211_hwsim.c
|
||||
@@ -2818,7 +2818,7 @@ static const struct ieee80211_sband_ifty
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
|
||||
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
|
||||
IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
|
||||
@@ -2862,7 +2862,7 @@ static const struct ieee80211_sband_ifty
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
|
||||
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
|
||||
IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
|
||||
@@ -2908,7 +2908,7 @@ static const struct ieee80211_sband_ifty
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
|
||||
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
|
||||
@@ -2956,7 +2956,7 @@ static const struct ieee80211_sband_ifty
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
|
||||
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
|
@ -1,279 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 23 Jan 2021 07:18:26 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: remove sample rate switching code for
|
||||
constrained devices
|
||||
|
||||
This was added to mitigate the effects of too much sampling on devices that
|
||||
use a static global fallback table instead of configurable multi-rate retry.
|
||||
Now that the sampling algorithm is improved, this code path no longer performs
|
||||
any better than the standard probing on affected devices.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -648,27 +648,6 @@ __minstrel_ht_get_sample_rate(struct min
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void
|
||||
-minstrel_ht_rate_sample_switch(struct minstrel_priv *mp,
|
||||
- struct minstrel_ht_sta *mi)
|
||||
-{
|
||||
- u16 rate;
|
||||
-
|
||||
- /*
|
||||
- * Use rate switching instead of probing packets for devices with
|
||||
- * little control over retry fallback behavior
|
||||
- */
|
||||
- if (mp->hw->max_rates > 1)
|
||||
- return;
|
||||
-
|
||||
- rate = __minstrel_ht_get_sample_rate(mi, MINSTREL_SAMPLE_TYPE_INC);
|
||||
- if (!rate)
|
||||
- return;
|
||||
-
|
||||
- mi->sample_rate = rate;
|
||||
- mi->sample_mode = MINSTREL_SAMPLE_ACTIVE;
|
||||
-}
|
||||
-
|
||||
static inline int
|
||||
minstrel_ewma(int old, int new, int weight)
|
||||
{
|
||||
@@ -1012,8 +991,7 @@ minstrel_ht_refill_sample_rates(struct m
|
||||
* higher throughput rates, even if the probablity is a bit lower
|
||||
*/
|
||||
static void
|
||||
-minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
|
||||
- bool sample)
|
||||
+minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||
{
|
||||
struct minstrel_mcs_group_data *mg;
|
||||
struct minstrel_rate_stats *mrs;
|
||||
@@ -1023,18 +1001,6 @@ minstrel_ht_update_stats(struct minstrel
|
||||
u16 index;
|
||||
bool ht_supported = mi->sta->ht_cap.ht_supported;
|
||||
|
||||
- mi->sample_mode = MINSTREL_SAMPLE_IDLE;
|
||||
-
|
||||
- if (sample) {
|
||||
- mi->total_packets_cur = mi->total_packets -
|
||||
- mi->total_packets_last;
|
||||
- mi->total_packets_last = mi->total_packets;
|
||||
- }
|
||||
- if (!mp->sample_switch)
|
||||
- sample = false;
|
||||
- if (mi->total_packets_cur < SAMPLE_SWITCH_THR && mp->sample_switch != 1)
|
||||
- sample = false;
|
||||
-
|
||||
if (mi->ampdu_packets > 0) {
|
||||
if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN))
|
||||
mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len,
|
||||
@@ -1148,16 +1114,12 @@ minstrel_ht_update_stats(struct minstrel
|
||||
minstrel_ht_prob_rate_reduce_streams(mi);
|
||||
minstrel_ht_refill_sample_rates(mi);
|
||||
|
||||
- if (sample)
|
||||
- minstrel_ht_rate_sample_switch(mp, mi);
|
||||
-
|
||||
#ifdef CPTCFG_MAC80211_DEBUGFS
|
||||
/* use fixed index if set */
|
||||
if (mp->fixed_rate_idx != -1) {
|
||||
for (i = 0; i < 4; i++)
|
||||
mi->max_tp_rate[i] = mp->fixed_rate_idx;
|
||||
mi->max_prob_rate = mp->fixed_rate_idx;
|
||||
- mi->sample_mode = MINSTREL_SAMPLE_IDLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1247,11 +1209,10 @@ minstrel_ht_tx_status(void *priv, struct
|
||||
struct ieee80211_tx_info *info = st->info;
|
||||
struct minstrel_ht_sta *mi = priv_sta;
|
||||
struct ieee80211_tx_rate *ar = info->status.rates;
|
||||
- struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL;
|
||||
+ struct minstrel_rate_stats *rate, *rate2;
|
||||
struct minstrel_priv *mp = priv;
|
||||
u32 update_interval = mp->update_interval;
|
||||
bool last, update = false;
|
||||
- bool sample_status = false;
|
||||
int i;
|
||||
|
||||
/* This packet was aggregated but doesn't carry status info */
|
||||
@@ -1278,49 +1239,18 @@ minstrel_ht_tx_status(void *priv, struct
|
||||
mi->ampdu_packets++;
|
||||
mi->ampdu_len += info->status.ampdu_len;
|
||||
|
||||
- if (mi->sample_mode != MINSTREL_SAMPLE_IDLE)
|
||||
- rate_sample = minstrel_get_ratestats(mi, mi->sample_rate);
|
||||
-
|
||||
last = !minstrel_ht_txstat_valid(mp, mi, &ar[0]);
|
||||
for (i = 0; !last; i++) {
|
||||
last = (i == IEEE80211_TX_MAX_RATES - 1) ||
|
||||
!minstrel_ht_txstat_valid(mp, mi, &ar[i + 1]);
|
||||
|
||||
rate = minstrel_ht_get_stats(mp, mi, &ar[i]);
|
||||
- if (rate == rate_sample)
|
||||
- sample_status = true;
|
||||
-
|
||||
if (last)
|
||||
rate->success += info->status.ampdu_ack_len;
|
||||
|
||||
rate->attempts += ar[i].count * info->status.ampdu_len;
|
||||
}
|
||||
|
||||
- switch (mi->sample_mode) {
|
||||
- case MINSTREL_SAMPLE_IDLE:
|
||||
- if (mp->hw->max_rates > 1 ||
|
||||
- mi->total_packets_cur < SAMPLE_SWITCH_THR)
|
||||
- update_interval /= 2;
|
||||
- break;
|
||||
-
|
||||
- case MINSTREL_SAMPLE_ACTIVE:
|
||||
- if (!sample_status)
|
||||
- break;
|
||||
-
|
||||
- mi->sample_mode = MINSTREL_SAMPLE_PENDING;
|
||||
- update = true;
|
||||
- break;
|
||||
-
|
||||
- case MINSTREL_SAMPLE_PENDING:
|
||||
- if (sample_status)
|
||||
- break;
|
||||
-
|
||||
- update = true;
|
||||
- minstrel_ht_update_stats(mp, mi, false);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
-
|
||||
if (mp->hw->max_rates > 1) {
|
||||
/*
|
||||
* check for sudden death of spatial multiplexing,
|
||||
@@ -1343,7 +1273,7 @@ minstrel_ht_tx_status(void *priv, struct
|
||||
|
||||
if (time_after(jiffies, mi->last_stats_update + update_interval)) {
|
||||
update = true;
|
||||
- minstrel_ht_update_stats(mp, mi, true);
|
||||
+ minstrel_ht_update_stats(mp, mi);
|
||||
}
|
||||
|
||||
if (update)
|
||||
@@ -1522,18 +1452,14 @@ static void
|
||||
minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||
{
|
||||
struct ieee80211_sta_rates *rates;
|
||||
- u16 first_rate = mi->max_tp_rate[0];
|
||||
int i = 0;
|
||||
|
||||
- if (mi->sample_mode == MINSTREL_SAMPLE_ACTIVE)
|
||||
- first_rate = mi->sample_rate;
|
||||
-
|
||||
rates = kzalloc(sizeof(*rates), GFP_ATOMIC);
|
||||
if (!rates)
|
||||
return;
|
||||
|
||||
/* Start with max_tp_rate[0] */
|
||||
- minstrel_ht_set_rate(mp, mi, rates, i++, first_rate);
|
||||
+ minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]);
|
||||
|
||||
if (mp->hw->max_rates >= 3) {
|
||||
/* At least 3 tx rates supported, use max_tp_rate[1] next */
|
||||
@@ -1592,11 +1518,6 @@ minstrel_ht_get_rate(void *priv, struct
|
||||
(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO))
|
||||
return;
|
||||
|
||||
- if (mp->hw->max_rates == 1 && mp->sample_switch &&
|
||||
- (mi->total_packets_cur >= SAMPLE_SWITCH_THR ||
|
||||
- mp->sample_switch == 1))
|
||||
- return;
|
||||
-
|
||||
if (time_is_before_jiffies(mi->sample_time))
|
||||
return;
|
||||
|
||||
@@ -1810,7 +1731,7 @@ minstrel_ht_update_caps(void *priv, stru
|
||||
minstrel_ht_update_ofdm(mp, mi, sband, sta);
|
||||
|
||||
/* create an initial rate table with the lowest supported rates */
|
||||
- minstrel_ht_update_stats(mp, mi, true);
|
||||
+ minstrel_ht_update_stats(mp, mi);
|
||||
minstrel_ht_update_rates(mp, mi);
|
||||
}
|
||||
|
||||
@@ -1926,8 +1847,6 @@ minstrel_ht_alloc(struct ieee80211_hw *h
|
||||
if (!mp)
|
||||
return NULL;
|
||||
|
||||
- mp->sample_switch = -1;
|
||||
-
|
||||
/* contention window settings
|
||||
* Just an approximation. Using the per-queue values would complicate
|
||||
* the calculations and is probably unnecessary */
|
||||
@@ -1947,7 +1866,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h
|
||||
mp->has_mrr = true;
|
||||
|
||||
mp->hw = hw;
|
||||
- mp->update_interval = HZ / 10;
|
||||
+ mp->update_interval = HZ / 20;
|
||||
|
||||
minstrel_ht_init_cck_rates(mp);
|
||||
for (i = 0; i < ARRAY_SIZE(mp->hw->wiphy->bands); i++)
|
||||
@@ -1965,8 +1884,6 @@ static void minstrel_ht_add_debugfs(stru
|
||||
mp->fixed_rate_idx = (u32) -1;
|
||||
debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir,
|
||||
&mp->fixed_rate_idx);
|
||||
- debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir,
|
||||
- &mp->sample_switch);
|
||||
}
|
||||
#endif
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.h
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
||||
@@ -75,7 +75,6 @@
|
||||
struct minstrel_priv {
|
||||
struct ieee80211_hw *hw;
|
||||
bool has_mrr;
|
||||
- u32 sample_switch;
|
||||
unsigned int cw_min;
|
||||
unsigned int cw_max;
|
||||
unsigned int max_retry;
|
||||
@@ -147,12 +146,6 @@ struct minstrel_mcs_group_data {
|
||||
struct minstrel_rate_stats rates[MCS_GROUP_RATES];
|
||||
};
|
||||
|
||||
-enum minstrel_sample_mode {
|
||||
- MINSTREL_SAMPLE_IDLE,
|
||||
- MINSTREL_SAMPLE_ACTIVE,
|
||||
- MINSTREL_SAMPLE_PENDING,
|
||||
-};
|
||||
-
|
||||
struct minstrel_sample_category {
|
||||
u8 sample_group;
|
||||
u16 sample_rates[MINSTREL_SAMPLE_RATES];
|
||||
@@ -182,23 +175,19 @@ struct minstrel_ht_sta {
|
||||
unsigned int overhead_legacy;
|
||||
unsigned int overhead_legacy_rtscts;
|
||||
|
||||
- unsigned int total_packets_last;
|
||||
- unsigned int total_packets_cur;
|
||||
unsigned int total_packets;
|
||||
unsigned int sample_packets;
|
||||
|
||||
/* tx flags to add for frames for this sta */
|
||||
u32 tx_flags;
|
||||
|
||||
- unsigned long sample_time;
|
||||
- struct minstrel_sample_category sample[__MINSTREL_SAMPLE_TYPE_MAX];
|
||||
+ u8 band;
|
||||
|
||||
u8 sample_seq;
|
||||
-
|
||||
- enum minstrel_sample_mode sample_mode;
|
||||
u16 sample_rate;
|
||||
|
||||
- u8 band;
|
||||
+ unsigned long sample_time;
|
||||
+ struct minstrel_sample_category sample[__MINSTREL_SAMPLE_TYPE_MAX];
|
||||
|
||||
/* Bitfield of supported MCS rates of all groups */
|
||||
u16 supported[MINSTREL_GROUPS_NB];
|
@ -1,60 +0,0 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Subject: [PATCH] brcmfmac: add in-driver tables with country codes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This adds early support for changing region. Ideally this data should
|
||||
be stored in DT as all these mappings are devices specific.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
@@ -12,6 +12,36 @@
|
||||
#include "common.h"
|
||||
#include "of.h"
|
||||
|
||||
+/* TODO: FIXME: Use DT */
|
||||
+static void brcmf_of_probe_cc(struct device *dev,
|
||||
+ struct brcmf_mp_device *settings)
|
||||
+{
|
||||
+ static struct brcmfmac_pd_cc_entry netgear_r8000_cc_ent[] = {
|
||||
+ { "JP", "JP", 78 },
|
||||
+ { "US", "Q2", 86 },
|
||||
+ };
|
||||
+ struct brcmfmac_pd_cc_entry *cc_ent = NULL;
|
||||
+ int table_size = 0;
|
||||
+
|
||||
+ if (of_machine_is_compatible("netgear,r8000")) {
|
||||
+ cc_ent = netgear_r8000_cc_ent;
|
||||
+ table_size = ARRAY_SIZE(netgear_r8000_cc_ent);
|
||||
+ }
|
||||
+
|
||||
+ if (cc_ent && table_size) {
|
||||
+ struct brcmfmac_pd_cc *cc;
|
||||
+ size_t memsize;
|
||||
+
|
||||
+ memsize = table_size * sizeof(struct brcmfmac_pd_cc_entry);
|
||||
+ cc = devm_kzalloc(dev, sizeof(*cc) + memsize, GFP_KERNEL);
|
||||
+ if (!cc)
|
||||
+ return;
|
||||
+ cc->table_size = table_size;
|
||||
+ memcpy(cc->table, cc_ent, memsize);
|
||||
+ settings->country_codes = cc;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
|
||||
struct brcmf_mp_device *settings)
|
||||
{
|
||||
@@ -43,6 +73,8 @@ void brcmf_of_probe(struct device *dev,
|
||||
of_node_put(root);
|
||||
}
|
||||
|
||||
+ brcmf_of_probe_cc(dev, settings);
|
||||
+
|
||||
if (!np || bus_type != BRCMF_BUSTYPE_SDIO ||
|
||||
!of_device_is_compatible(np, "brcm,bcm4329-fmac"))
|
||||
return;
|
@ -1,271 +0,0 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Sun, 6 Dec 2020 14:54:43 +0200
|
||||
Subject: [PATCH] mac80211: support driver-based disconnect with reconnect hint
|
||||
|
||||
Support the driver indicating that a disconnection needs
|
||||
to be performed, and pass through the reconnect hint in
|
||||
this case.
|
||||
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20201206145305.5c8dab7a22a0.I58459fdf6968b16c90cab9c574f0f04ca22b0c79@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -5885,6 +5885,17 @@ void ieee80211_beacon_loss(struct ieee80
|
||||
void ieee80211_connection_loss(struct ieee80211_vif *vif);
|
||||
|
||||
/**
|
||||
+ * ieee80211_disconnect - request disconnection
|
||||
+ *
|
||||
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||
+ * @reconnect: immediate reconnect is desired
|
||||
+ *
|
||||
+ * Request disconnection from the current network and, if enabled, send a
|
||||
+ * hint to the higher layers that immediate reconnect is desired.
|
||||
+ */
|
||||
+void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect);
|
||||
+
|
||||
+/**
|
||||
* ieee80211_resume_disconnect - disconnect from AP after resume
|
||||
*
|
||||
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -450,7 +450,9 @@ struct ieee80211_if_managed {
|
||||
unsigned long probe_timeout;
|
||||
int probe_send_count;
|
||||
bool nullfunc_failed;
|
||||
- bool connection_loss;
|
||||
+ u8 connection_loss:1,
|
||||
+ driver_disconnect:1,
|
||||
+ reconnect:1;
|
||||
|
||||
struct cfg80211_bss *associated;
|
||||
struct ieee80211_mgd_auth_data *auth_data;
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -2716,7 +2716,7 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get)
|
||||
|
||||
static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata,
|
||||
const u8 *buf, size_t len, bool tx,
|
||||
- u16 reason)
|
||||
+ u16 reason, bool reconnect)
|
||||
{
|
||||
struct ieee80211_event event = {
|
||||
.type = MLME_EVENT,
|
||||
@@ -2725,7 +2725,7 @@ static void ieee80211_report_disconnect(
|
||||
};
|
||||
|
||||
if (tx)
|
||||
- cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, false);
|
||||
+ cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, reconnect);
|
||||
else
|
||||
cfg80211_rx_mlme_mgmt(sdata->dev, buf, len);
|
||||
|
||||
@@ -2747,13 +2747,18 @@ static void __ieee80211_disconnect(struc
|
||||
|
||||
tx = !sdata->csa_block_tx;
|
||||
|
||||
- /* AP is probably out of range (or not reachable for another reason) so
|
||||
- * remove the bss struct for that AP.
|
||||
- */
|
||||
- cfg80211_unlink_bss(local->hw.wiphy, ifmgd->associated);
|
||||
+ if (!ifmgd->driver_disconnect) {
|
||||
+ /*
|
||||
+ * AP is probably out of range (or not reachable for another
|
||||
+ * reason) so remove the bss struct for that AP.
|
||||
+ */
|
||||
+ cfg80211_unlink_bss(local->hw.wiphy, ifmgd->associated);
|
||||
+ }
|
||||
|
||||
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
|
||||
- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
|
||||
+ ifmgd->driver_disconnect ?
|
||||
+ WLAN_REASON_DEAUTH_LEAVING :
|
||||
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
|
||||
tx, frame_buf);
|
||||
mutex_lock(&local->mtx);
|
||||
sdata->vif.csa_active = false;
|
||||
@@ -2766,7 +2771,9 @@ static void __ieee80211_disconnect(struc
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx,
|
||||
- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
|
||||
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
|
||||
+ ifmgd->reconnect);
|
||||
+ ifmgd->reconnect = false;
|
||||
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
@@ -2785,6 +2792,13 @@ static void ieee80211_beacon_connection_
|
||||
sdata_info(sdata, "Connection to AP %pM lost\n",
|
||||
ifmgd->bssid);
|
||||
__ieee80211_disconnect(sdata);
|
||||
+ ifmgd->connection_loss = false;
|
||||
+ } else if (ifmgd->driver_disconnect) {
|
||||
+ sdata_info(sdata,
|
||||
+ "Driver requested disconnection from AP %pM\n",
|
||||
+ ifmgd->bssid);
|
||||
+ __ieee80211_disconnect(sdata);
|
||||
+ ifmgd->driver_disconnect = false;
|
||||
} else {
|
||||
ieee80211_mgd_probe_ap(sdata, true);
|
||||
}
|
||||
@@ -2823,6 +2837,21 @@ void ieee80211_connection_loss(struct ie
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_connection_loss);
|
||||
|
||||
+void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect)
|
||||
+{
|
||||
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
+ struct ieee80211_hw *hw = &sdata->local->hw;
|
||||
+
|
||||
+ trace_api_disconnect(sdata, reconnect);
|
||||
+
|
||||
+ if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
|
||||
+ return;
|
||||
+
|
||||
+ sdata->u.mgd.driver_disconnect = true;
|
||||
+ sdata->u.mgd.reconnect = reconnect;
|
||||
+ ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_disconnect);
|
||||
|
||||
static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
|
||||
bool assoc)
|
||||
@@ -3126,7 +3155,7 @@ static void ieee80211_rx_mgmt_deauth(str
|
||||
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
||||
|
||||
ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false,
|
||||
- reason_code);
|
||||
+ reason_code, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3175,7 +3204,8 @@ static void ieee80211_rx_mgmt_disassoc(s
|
||||
|
||||
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
||||
|
||||
- ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code);
|
||||
+ ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code,
|
||||
+ false);
|
||||
}
|
||||
|
||||
static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
|
||||
@@ -4199,7 +4229,8 @@ static void ieee80211_rx_mgmt_beacon(str
|
||||
true, deauth_buf);
|
||||
ieee80211_report_disconnect(sdata, deauth_buf,
|
||||
sizeof(deauth_buf), true,
|
||||
- WLAN_REASON_DEAUTH_LEAVING);
|
||||
+ WLAN_REASON_DEAUTH_LEAVING,
|
||||
+ false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4344,7 +4375,7 @@ static void ieee80211_sta_connection_los
|
||||
tx, frame_buf);
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
|
||||
- reason);
|
||||
+ reason, false);
|
||||
}
|
||||
|
||||
static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
|
||||
@@ -5434,7 +5465,8 @@ int ieee80211_mgd_auth(struct ieee80211_
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
- WLAN_REASON_UNSPECIFIED);
|
||||
+ WLAN_REASON_UNSPECIFIED,
|
||||
+ false);
|
||||
}
|
||||
|
||||
sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
|
||||
@@ -5506,7 +5538,8 @@ int ieee80211_mgd_assoc(struct ieee80211
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
- WLAN_REASON_UNSPECIFIED);
|
||||
+ WLAN_REASON_UNSPECIFIED,
|
||||
+ false);
|
||||
}
|
||||
|
||||
if (ifmgd->auth_data && !ifmgd->auth_data->done) {
|
||||
@@ -5809,7 +5842,7 @@ int ieee80211_mgd_deauth(struct ieee8021
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
- req->reason_code);
|
||||
+ req->reason_code, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -5829,7 +5862,7 @@ int ieee80211_mgd_deauth(struct ieee8021
|
||||
ieee80211_destroy_assoc_data(sdata, false, true);
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
- req->reason_code);
|
||||
+ req->reason_code, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5844,7 +5877,7 @@ int ieee80211_mgd_deauth(struct ieee8021
|
||||
req->reason_code, tx, frame_buf);
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
- req->reason_code);
|
||||
+ req->reason_code, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5877,7 +5910,7 @@ int ieee80211_mgd_disassoc(struct ieee80
|
||||
frame_buf);
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
|
||||
- req->reason_code);
|
||||
+ req->reason_code, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/net/mac80211/trace.h
|
||||
+++ b/net/mac80211/trace.h
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Portions of this file
|
||||
* Copyright(c) 2016-2017 Intel Deutschland GmbH
|
||||
-* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
+* Copyright (C) 2018 - 2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
|
||||
@@ -2086,6 +2086,27 @@ TRACE_EVENT(api_connection_loss,
|
||||
)
|
||||
);
|
||||
|
||||
+TRACE_EVENT(api_disconnect,
|
||||
+ TP_PROTO(struct ieee80211_sub_if_data *sdata, bool reconnect),
|
||||
+
|
||||
+ TP_ARGS(sdata, reconnect),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ VIF_ENTRY
|
||||
+ __field(int, reconnect)
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ VIF_ASSIGN;
|
||||
+ __entry->reconnect = reconnect;
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ VIF_PR_FMT " reconnect:%d",
|
||||
+ VIF_PR_ARG, __entry->reconnect
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
TRACE_EVENT(api_cqm_rssi_notify,
|
||||
TP_PROTO(struct ieee80211_sub_if_data *sdata,
|
||||
enum nl80211_cqm_rssi_threshold_event rssi_event,
|
@ -1,335 +0,0 @@
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -437,43 +437,6 @@ USB_SIERRA_NET=
|
||||
USB_VL600=
|
||||
USB_NET_CH9200=
|
||||
USB_NET_AQC111=
|
||||
-SSB_POSSIBLE=
|
||||
-SSB=
|
||||
-SSB_SPROM=
|
||||
-SSB_BLOCKIO=
|
||||
-SSB_PCIHOST_POSSIBLE=
|
||||
-SSB_PCIHOST=
|
||||
-SSB_B43_PCI_BRIDGE=
|
||||
-SSB_PCMCIAHOST_POSSIBLE=
|
||||
-SSB_PCMCIAHOST=
|
||||
-SSB_SDIOHOST_POSSIBLE=
|
||||
-SSB_SDIOHOST=
|
||||
-SSB_HOST_SOC=
|
||||
-SSB_SERIAL=
|
||||
-SSB_DRIVER_PCICORE_POSSIBLE=
|
||||
-SSB_DRIVER_PCICORE=
|
||||
-SSB_PCICORE_HOSTMODE=
|
||||
-SSB_DRIVER_MIPS=
|
||||
-SSB_SFLASH=
|
||||
-SSB_EMBEDDED=
|
||||
-SSB_DRIVER_EXTIF=
|
||||
-SSB_DRIVER_GIGE=
|
||||
-SSB_DRIVER_GPIO=
|
||||
-BCMA_POSSIBLE=
|
||||
-BCMA=
|
||||
-BCMA_BLOCKIO=
|
||||
-BCMA_HOST_PCI_POSSIBLE=
|
||||
-BCMA_HOST_PCI=
|
||||
-BCMA_HOST_SOC=
|
||||
-BCMA_DRIVER_PCI=
|
||||
-BCMA_DRIVER_PCI_HOSTMODE=
|
||||
-BCMA_DRIVER_MIPS=
|
||||
-BCMA_PFLASH=
|
||||
-BCMA_SFLASH=
|
||||
-BCMA_NFLASH=
|
||||
-BCMA_DRIVER_GMAC_CMN=
|
||||
-BCMA_DRIVER_GPIO=
|
||||
-BCMA_DEBUG=
|
||||
USB_ACM=
|
||||
USB_PRINTER=
|
||||
USB_WDM=
|
||||
--- a/drivers/net/wireless/broadcom/b43/Kconfig
|
||||
+++ b/drivers/net/wireless/broadcom/b43/Kconfig
|
||||
@@ -63,21 +63,21 @@ endchoice
|
||||
config B43_PCI_AUTOSELECT
|
||||
bool
|
||||
depends on B43 && SSB_PCIHOST_POSSIBLE
|
||||
- select SSB_PCIHOST
|
||||
- select SSB_B43_PCI_BRIDGE
|
||||
+ depends on SSB_PCIHOST
|
||||
+ depends on SSB_B43_PCI_BRIDGE
|
||||
default y
|
||||
|
||||
# Auto-select SSB PCICORE driver, if possible
|
||||
config B43_PCICORE_AUTOSELECT
|
||||
bool
|
||||
depends on B43 && SSB_DRIVER_PCICORE_POSSIBLE
|
||||
- select SSB_DRIVER_PCICORE
|
||||
+ depends on SSB_DRIVER_PCICORE
|
||||
default y
|
||||
|
||||
config B43_SDIO
|
||||
bool "Broadcom 43xx SDIO device support"
|
||||
depends on B43 && B43_SSB && SSB_SDIOHOST_POSSIBLE
|
||||
- select SSB_SDIOHOST
|
||||
+ depends on SSB_SDIOHOST
|
||||
help
|
||||
Broadcom 43xx device support for Soft-MAC SDIO devices.
|
||||
|
||||
@@ -96,13 +96,13 @@ config B43_SDIO
|
||||
config B43_BCMA_PIO
|
||||
bool
|
||||
depends on B43 && B43_BCMA
|
||||
- select BCMA_BLOCKIO
|
||||
+ depends on BCMA_BLOCKIO
|
||||
default y
|
||||
|
||||
config B43_PIO
|
||||
bool
|
||||
depends on B43 && B43_SSB
|
||||
- select SSB_BLOCKIO
|
||||
+ depends on SSB_BLOCKIO
|
||||
default y
|
||||
|
||||
config B43_PHY_G
|
||||
--- a/drivers/net/wireless/broadcom/b43/main.c
|
||||
+++ b/drivers/net/wireless/broadcom/b43/main.c
|
||||
@@ -2853,7 +2853,7 @@ static struct ssb_device *b43_ssb_gpio_d
|
||||
{
|
||||
struct ssb_bus *bus = dev->dev->sdev->bus;
|
||||
|
||||
-#ifdef CPTCFG_SSB_DRIVER_PCICORE
|
||||
+#ifdef CONFIG_SSB_DRIVER_PCICORE
|
||||
return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
|
||||
#else
|
||||
return bus->chipco.dev;
|
||||
@@ -4870,7 +4870,7 @@ static int b43_wireless_core_init(struct
|
||||
}
|
||||
if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
|
||||
hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
|
||||
-#if defined(CPTCFG_B43_SSB) && defined(CPTCFG_SSB_DRIVER_PCICORE)
|
||||
+#if defined(CPTCFG_B43_SSB) && defined(CONFIG_SSB_DRIVER_PCICORE)
|
||||
if (dev->dev->bus_type == B43_BUS_SSB &&
|
||||
dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
|
||||
dev->dev->sdev->bus->pcicore.dev->id.revision <= 10)
|
||||
--- a/drivers/net/wireless/broadcom/b43legacy/Kconfig
|
||||
+++ b/drivers/net/wireless/broadcom/b43legacy/Kconfig
|
||||
@@ -3,7 +3,7 @@ config B43LEGACY
|
||||
tristate "Broadcom 43xx-legacy wireless support (mac80211 stack)"
|
||||
depends on m
|
||||
depends on SSB_POSSIBLE && MAC80211 && HAS_DMA
|
||||
- select SSB
|
||||
+ depends on SSB
|
||||
depends on FW_LOADER
|
||||
help
|
||||
b43legacy is a driver for 802.11b devices from Broadcom (BCM4301 and
|
||||
@@ -25,15 +25,15 @@ config B43LEGACY
|
||||
config B43LEGACY_PCI_AUTOSELECT
|
||||
bool
|
||||
depends on B43LEGACY && SSB_PCIHOST_POSSIBLE
|
||||
- select SSB_PCIHOST
|
||||
- select SSB_B43_PCI_BRIDGE
|
||||
+ depends on SSB_PCIHOST
|
||||
+ depends on SSB_B43_PCI_BRIDGE
|
||||
default y
|
||||
|
||||
# Auto-select SSB PCICORE driver, if possible
|
||||
config B43LEGACY_PCICORE_AUTOSELECT
|
||||
bool
|
||||
depends on B43LEGACY && SSB_DRIVER_PCICORE_POSSIBLE
|
||||
- select SSB_DRIVER_PCICORE
|
||||
+ depends on SSB_DRIVER_PCICORE
|
||||
default y
|
||||
|
||||
# LED support
|
||||
--- a/drivers/net/wireless/broadcom/b43legacy/main.c
|
||||
+++ b/drivers/net/wireless/broadcom/b43legacy/main.c
|
||||
@@ -1907,7 +1907,7 @@ static int b43legacy_gpio_init(struct b4
|
||||
if (dev->dev->id.revision >= 2)
|
||||
mask |= 0x0010; /* FIXME: This is redundant. */
|
||||
|
||||
-#ifdef CPTCFG_SSB_DRIVER_PCICORE
|
||||
+#ifdef CONFIG_SSB_DRIVER_PCICORE
|
||||
pcidev = bus->pcicore.dev;
|
||||
#endif
|
||||
gpiodev = bus->chipco.dev ? : pcidev;
|
||||
@@ -1926,7 +1926,7 @@ static void b43legacy_gpio_cleanup(struc
|
||||
struct ssb_bus *bus = dev->dev->bus;
|
||||
struct ssb_device *gpiodev, *pcidev = NULL;
|
||||
|
||||
-#ifdef CPTCFG_SSB_DRIVER_PCICORE
|
||||
+#ifdef CONFIG_SSB_DRIVER_PCICORE
|
||||
pcidev = bus->pcicore.dev;
|
||||
#endif
|
||||
gpiodev = bus->chipco.dev ? : pcidev;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h
|
||||
@@ -24,7 +24,7 @@ struct brcms_led {
|
||||
struct gpio_desc *gpiod;
|
||||
};
|
||||
|
||||
-#ifdef CPTCFG_BCMA_DRIVER_GPIO
|
||||
+#ifdef CONFIG_BCMA_DRIVER_GPIO
|
||||
void brcms_led_unregister(struct brcms_info *wl);
|
||||
int brcms_led_register(struct brcms_info *wl);
|
||||
#else
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile
|
||||
@@ -42,6 +42,6 @@ brcmsmac-y := \
|
||||
brcms_trace_events.o \
|
||||
debug.o
|
||||
|
||||
-brcmsmac-$(CPTCFG_BCMA_DRIVER_GPIO) += led.o
|
||||
+brcmsmac-$(CONFIG_BCMA_DRIVER_GPIO) += led.o
|
||||
|
||||
obj-$(CPTCFG_BRCMSMAC) += brcmsmac.o
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
|
||||
@@ -8,7 +8,7 @@ config BRCMSMAC
|
||||
depends on m
|
||||
depends on MAC80211
|
||||
depends on BCMA_POSSIBLE
|
||||
- select BCMA
|
||||
+ depends on BCMA
|
||||
select NEW_LEDS if BCMA_DRIVER_GPIO
|
||||
select LEDS_CLASS if BCMA_DRIVER_GPIO
|
||||
select BRCMUTIL
|
||||
--- a/Kconfig.local
|
||||
+++ b/Kconfig.local
|
||||
@@ -1315,117 +1315,6 @@ config BACKPORTED_USB_NET_CH9200
|
||||
config BACKPORTED_USB_NET_AQC111
|
||||
tristate
|
||||
default USB_NET_AQC111
|
||||
-config BACKPORTED_SSB_POSSIBLE
|
||||
- tristate
|
||||
- default SSB_POSSIBLE
|
||||
-config BACKPORTED_SSB
|
||||
- tristate
|
||||
- default SSB
|
||||
-config BACKPORTED_SSB_SPROM
|
||||
- tristate
|
||||
- default SSB_SPROM
|
||||
-config BACKPORTED_SSB_BLOCKIO
|
||||
- tristate
|
||||
- default SSB_BLOCKIO
|
||||
-config BACKPORTED_SSB_PCIHOST_POSSIBLE
|
||||
- tristate
|
||||
- default SSB_PCIHOST_POSSIBLE
|
||||
-config BACKPORTED_SSB_PCIHOST
|
||||
- tristate
|
||||
- default SSB_PCIHOST
|
||||
-config BACKPORTED_SSB_B43_PCI_BRIDGE
|
||||
- tristate
|
||||
- default SSB_B43_PCI_BRIDGE
|
||||
-config BACKPORTED_SSB_PCMCIAHOST_POSSIBLE
|
||||
- tristate
|
||||
- default SSB_PCMCIAHOST_POSSIBLE
|
||||
-config BACKPORTED_SSB_PCMCIAHOST
|
||||
- tristate
|
||||
- default SSB_PCMCIAHOST
|
||||
-config BACKPORTED_SSB_SDIOHOST_POSSIBLE
|
||||
- tristate
|
||||
- default SSB_SDIOHOST_POSSIBLE
|
||||
-config BACKPORTED_SSB_SDIOHOST
|
||||
- tristate
|
||||
- default SSB_SDIOHOST
|
||||
-config BACKPORTED_SSB_HOST_SOC
|
||||
- tristate
|
||||
- default SSB_HOST_SOC
|
||||
-config BACKPORTED_SSB_SERIAL
|
||||
- tristate
|
||||
- default SSB_SERIAL
|
||||
-config BACKPORTED_SSB_DRIVER_PCICORE_POSSIBLE
|
||||
- tristate
|
||||
- default SSB_DRIVER_PCICORE_POSSIBLE
|
||||
-config BACKPORTED_SSB_DRIVER_PCICORE
|
||||
- tristate
|
||||
- default SSB_DRIVER_PCICORE
|
||||
-config BACKPORTED_SSB_PCICORE_HOSTMODE
|
||||
- tristate
|
||||
- default SSB_PCICORE_HOSTMODE
|
||||
-config BACKPORTED_SSB_DRIVER_MIPS
|
||||
- tristate
|
||||
- default SSB_DRIVER_MIPS
|
||||
-config BACKPORTED_SSB_SFLASH
|
||||
- tristate
|
||||
- default SSB_SFLASH
|
||||
-config BACKPORTED_SSB_EMBEDDED
|
||||
- tristate
|
||||
- default SSB_EMBEDDED
|
||||
-config BACKPORTED_SSB_DRIVER_EXTIF
|
||||
- tristate
|
||||
- default SSB_DRIVER_EXTIF
|
||||
-config BACKPORTED_SSB_DRIVER_GIGE
|
||||
- tristate
|
||||
- default SSB_DRIVER_GIGE
|
||||
-config BACKPORTED_SSB_DRIVER_GPIO
|
||||
- tristate
|
||||
- default SSB_DRIVER_GPIO
|
||||
-config BACKPORTED_BCMA_POSSIBLE
|
||||
- tristate
|
||||
- default BCMA_POSSIBLE
|
||||
-config BACKPORTED_BCMA
|
||||
- tristate
|
||||
- default BCMA
|
||||
-config BACKPORTED_BCMA_BLOCKIO
|
||||
- tristate
|
||||
- default BCMA_BLOCKIO
|
||||
-config BACKPORTED_BCMA_HOST_PCI_POSSIBLE
|
||||
- tristate
|
||||
- default BCMA_HOST_PCI_POSSIBLE
|
||||
-config BACKPORTED_BCMA_HOST_PCI
|
||||
- tristate
|
||||
- default BCMA_HOST_PCI
|
||||
-config BACKPORTED_BCMA_HOST_SOC
|
||||
- tristate
|
||||
- default BCMA_HOST_SOC
|
||||
-config BACKPORTED_BCMA_DRIVER_PCI
|
||||
- tristate
|
||||
- default BCMA_DRIVER_PCI
|
||||
-config BACKPORTED_BCMA_DRIVER_PCI_HOSTMODE
|
||||
- tristate
|
||||
- default BCMA_DRIVER_PCI_HOSTMODE
|
||||
-config BACKPORTED_BCMA_DRIVER_MIPS
|
||||
- tristate
|
||||
- default BCMA_DRIVER_MIPS
|
||||
-config BACKPORTED_BCMA_PFLASH
|
||||
- tristate
|
||||
- default BCMA_PFLASH
|
||||
-config BACKPORTED_BCMA_SFLASH
|
||||
- tristate
|
||||
- default BCMA_SFLASH
|
||||
-config BACKPORTED_BCMA_NFLASH
|
||||
- tristate
|
||||
- default BCMA_NFLASH
|
||||
-config BACKPORTED_BCMA_DRIVER_GMAC_CMN
|
||||
- tristate
|
||||
- default BCMA_DRIVER_GMAC_CMN
|
||||
-config BACKPORTED_BCMA_DRIVER_GPIO
|
||||
- tristate
|
||||
- default BCMA_DRIVER_GPIO
|
||||
-config BACKPORTED_BCMA_DEBUG
|
||||
- tristate
|
||||
- default BCMA_DEBUG
|
||||
config BACKPORTED_USB_ACM
|
||||
tristate
|
||||
default USB_ACM
|
||||
--- a/Kconfig.sources
|
||||
+++ b/Kconfig.sources
|
||||
@@ -7,9 +7,6 @@ source "$BACKPORT_DIR/net/mac80211/Kconf
|
||||
source "$BACKPORT_DIR/drivers/net/wireless/Kconfig"
|
||||
source "$BACKPORT_DIR/drivers/net/usb/Kconfig"
|
||||
|
||||
-source "$BACKPORT_DIR/drivers/ssb/Kconfig"
|
||||
-source "$BACKPORT_DIR/drivers/bcma/Kconfig"
|
||||
-
|
||||
source "$BACKPORT_DIR/drivers/usb/class/Kconfig"
|
||||
|
||||
source "$BACKPORT_DIR/drivers/staging/Kconfig"
|
||||
--- a/Makefile.kernel
|
||||
+++ b/Makefile.kernel
|
||||
@@ -40,8 +40,6 @@ obj-y += compat/
|
||||
obj-$(CPTCFG_CFG80211) += net/wireless/
|
||||
obj-$(CPTCFG_MAC80211) += net/mac80211/
|
||||
obj-$(CPTCFG_WLAN) += drivers/net/wireless/
|
||||
-obj-$(CPTCFG_SSB) += drivers/ssb/
|
||||
-obj-$(CPTCFG_BCMA) += drivers/bcma/
|
||||
obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/
|
||||
|
||||
obj-$(CPTCFG_USB_WDM) += drivers/usb/class/
|
@ -1,564 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2007-2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=mac80211
|
||||
|
||||
PKG_VERSION:=5.10.68-1
|
||||
PKG_RELEASE:=1
|
||||
PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.10.68/
|
||||
PKG_HASH:=bba161b0084590c677a84b80993709e388a3c478f29ed0c475d4fce1b9162968
|
||||
|
||||
PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
PKG_DRIVERS = \
|
||||
adm8211 \
|
||||
airo \
|
||||
hermes hermes-pci hermes-pcmcia hermes-plx\
|
||||
lib80211 \
|
||||
mac80211-hwsim \
|
||||
mt7601u \
|
||||
p54-common p54-pci p54-usb \
|
||||
rsi91x rsi91x-usb rsi91x-sdio\
|
||||
wlcore wl12xx wl18xx \
|
||||
zd1211rw
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_PACKAGE_kmod-mac80211 \
|
||||
CONFIG_PACKAGE_CFG80211_TESTMODE \
|
||||
CONFIG_PACKAGE_MAC80211_DEBUGFS \
|
||||
CONFIG_PACKAGE_MAC80211_MESH \
|
||||
CONFIG_PACKAGE_MAC80211_TRACING \
|
||||
CONFIG_PACKAGE_IWLWIFI_DEBUG \
|
||||
CONFIG_PACKAGE_IWLWIFI_DEBUGFS \
|
||||
CONFIG_PACKAGE_RTLWIFI_DEBUG \
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
WMENU:=Wireless Drivers
|
||||
|
||||
define KernelPackage/mac80211/Default
|
||||
SUBMENU:=$(WMENU)
|
||||
URL:=https://wireless.wiki.kernel.org/
|
||||
MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
endef
|
||||
|
||||
config_package=$(if $(CONFIG_PACKAGE_kmod-$(1)),m)
|
||||
|
||||
config-y:= \
|
||||
WLAN \
|
||||
CFG80211_WEXT \
|
||||
CFG80211_CERTIFICATION_ONUS \
|
||||
MAC80211_RC_MINSTREL \
|
||||
MAC80211_RC_MINSTREL_HT \
|
||||
MAC80211_RC_MINSTREL_VHT \
|
||||
MAC80211_RC_DEFAULT_MINSTREL \
|
||||
WLAN_VENDOR_ADMTEK \
|
||||
WLAN_VENDOR_ATH \
|
||||
WLAN_VENDOR_ATMEL \
|
||||
WLAN_VENDOR_BROADCOM \
|
||||
WLAN_VENDOR_CISCO \
|
||||
WLAN_VENDOR_INTEL \
|
||||
WLAN_VENDOR_INTERSIL \
|
||||
WLAN_VENDOR_MARVELL \
|
||||
WLAN_VENDOR_MEDIATEK \
|
||||
WLAN_VENDOR_RALINK \
|
||||
WLAN_VENDOR_REALTEK \
|
||||
WLAN_VENDOR_RSI \
|
||||
WLAN_VENDOR_ST \
|
||||
WLAN_VENDOR_TI \
|
||||
WLAN_VENDOR_ZYDAS \
|
||||
|
||||
config-$(call config_package,cfg80211) += CFG80211
|
||||
config-$(CONFIG_PACKAGE_CFG80211_TESTMODE) += NL80211_TESTMODE
|
||||
|
||||
config-$(call config_package,mac80211) += MAC80211
|
||||
config-$(CONFIG_PACKAGE_MAC80211_MESH) += MAC80211_MESH
|
||||
|
||||
include ath.mk
|
||||
include broadcom.mk
|
||||
include intel.mk
|
||||
include marvell.mk
|
||||
include ralink.mk
|
||||
include realtek.mk
|
||||
|
||||
PKG_CONFIG_DEPENDS += \
|
||||
$(patsubst %,CONFIG_PACKAGE_kmod-%,$(PKG_DRIVERS))
|
||||
|
||||
define KernelPackage/cfg80211
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=cfg80211 - wireless configuration API
|
||||
DEPENDS+= +iw +iwinfo +wireless-regdb
|
||||
ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE)
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/compat/compat.ko \
|
||||
$(PKG_BUILD_DIR)/net/wireless/cfg80211.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/cfg80211/description
|
||||
cfg80211 is the Linux wireless LAN (802.11) configuration API.
|
||||
endef
|
||||
|
||||
define KernelPackage/cfg80211/config
|
||||
if PACKAGE_kmod-cfg80211
|
||||
|
||||
config PACKAGE_CFG80211_TESTMODE
|
||||
bool "Enable testmode command support"
|
||||
default n
|
||||
help
|
||||
This is typically used for tests and calibration during
|
||||
manufacturing, or vendor specific debugging features
|
||||
|
||||
endif
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/mac80211
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Linux 802.11 Wireless Networking Stack
|
||||
# +kmod-crypto-cmac is a runtime only dependency of net/mac80211/aes_cmac.c
|
||||
DEPENDS+= +kmod-cfg80211 +kmod-crypto-cmac +kmod-crypto-ccm +kmod-crypto-gcm +hostapd-common
|
||||
KCONFIG:=\
|
||||
CONFIG_AVERAGE=y
|
||||
FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko
|
||||
ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE)
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/mac80211/config
|
||||
if PACKAGE_kmod-mac80211
|
||||
|
||||
config PACKAGE_MAC80211_DEBUGFS
|
||||
bool "Export mac80211 internals in DebugFS"
|
||||
select KERNEL_DEBUG_FS
|
||||
default y
|
||||
help
|
||||
Select this to see extensive information about
|
||||
the internal state of mac80211 in debugfs.
|
||||
|
||||
config PACKAGE_MAC80211_TRACING
|
||||
bool "Enable tracing (mac80211 and supported drivers)"
|
||||
select KERNEL_FTRACE
|
||||
select KERNEL_ENABLE_DEFAULT_TRACERS
|
||||
default n
|
||||
help
|
||||
Select this to enable tracing of mac80211 and
|
||||
related wifi drivers (using trace-cmd).
|
||||
|
||||
config PACKAGE_MAC80211_MESH
|
||||
bool "Enable 802.11s mesh support"
|
||||
default y
|
||||
|
||||
endif
|
||||
endef
|
||||
|
||||
define KernelPackage/mac80211/description
|
||||
Generic IEEE 802.11 Networking Stack (mac80211)
|
||||
endef
|
||||
|
||||
define KernelPackage/adm8211
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=ADMTek 8211 support
|
||||
DEPENDS+=@PCI_SUPPORT +kmod-mac80211 +kmod-eeprom-93cx6
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/admtek/adm8211.ko
|
||||
AUTOLOAD:=$(call AutoProbe,adm8211)
|
||||
endef
|
||||
|
||||
define KernelPackage/airo
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Cisco Aironet driver
|
||||
DEPENDS+=@PCI_SUPPORT +@DRIVER_WEXT_SUPPORT +kmod-cfg80211 @TARGET_x86 @BROKEN
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/cisco/airo.ko
|
||||
AUTOLOAD:=$(call AutoProbe,airo)
|
||||
endef
|
||||
|
||||
define KernelPackage/airo/description
|
||||
Kernel support for Cisco Aironet cards
|
||||
endef
|
||||
|
||||
define KernelPackage/hermes
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Hermes 802.11b chipset support
|
||||
DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT +kmod-crypto-michael-mic
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco.ko
|
||||
AUTOLOAD:=$(call AutoProbe,orinoco)
|
||||
endef
|
||||
|
||||
define KernelPackage/hermes/description
|
||||
Kernel support for Hermes 802.11b chipsets
|
||||
endef
|
||||
|
||||
define KernelPackage/hermes-pci
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Intersil Prism 2.5 PCI support
|
||||
DEPENDS:=@PCI_SUPPORT +kmod-hermes
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco_pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,orinoco_pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/hermes-pci/description
|
||||
Kernel modules for Intersil Prism 2.5 PCI support
|
||||
endef
|
||||
|
||||
define KernelPackage/hermes-plx
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=PLX9052 based PCI adaptor
|
||||
DEPENDS:=@PCI_SUPPORT +kmod-hermes
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco_plx.ko
|
||||
AUTOLOAD:=$(call AutoProbe,orinoco_plx)
|
||||
endef
|
||||
|
||||
define KernelPackage/hermes-plx/description
|
||||
Kernel modules for Hermes in PLX9052 based PCI adaptors
|
||||
endef
|
||||
|
||||
define KernelPackage/hermes-pcmcia
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Hermes based PCMCIA adaptors
|
||||
DEPENDS:=@PCMCIA_SUPPORT +kmod-hermes +kmod-pcmcia-core
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco_cs.ko
|
||||
AUTOLOAD:=$(call AutoProbe,orinoco_cs)
|
||||
endef
|
||||
|
||||
define KernelPackage/hermes-pcmcia/description
|
||||
Kernel modules for Hermes based PCMCIA adaptors
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/lib80211
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=802.11 Networking stack
|
||||
DEPENDS:=+kmod-cfg80211 +kmod-crypto-hash +kmod-crypto-ccm
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/net/wireless/lib80211.ko \
|
||||
$(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_wep.ko \
|
||||
$(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_ccmp.ko \
|
||||
$(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_tkip.ko
|
||||
AUTOLOAD:=$(call AutoProbe, \
|
||||
lib80211 \
|
||||
lib80211_crypt_wep \
|
||||
lib80211_crypt_ccmp \
|
||||
lib80211_crypt_tkip \
|
||||
)
|
||||
endef
|
||||
|
||||
define KernelPackage/lib80211/description
|
||||
Kernel modules for 802.11 Networking stack
|
||||
Includes:
|
||||
- lib80211
|
||||
- lib80211_crypt_wep
|
||||
- lib80211_crypt_tkip
|
||||
- lib80211_crytp_ccmp
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/mac80211-hwsim
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=mac80211 HW simulation device
|
||||
DEPENDS+= +kmod-mac80211 +@DRIVER_11AC_SUPPORT +@DRIVER_11N_SUPPORT
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mac80211_hwsim.ko
|
||||
AUTOLOAD:=$(call AutoProbe,mac80211_hwsim)
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/mt7601u
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=MT7601U-based USB dongles Wireless Driver
|
||||
DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT @USB_SUPPORT +kmod-usb-core +mt7601u-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mediatek/mt7601u/mt7601u.ko
|
||||
AUTOLOAD:=$(call AutoProbe,mt7601u)
|
||||
endef
|
||||
|
||||
define KernelPackage/p54/Default
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Prism54 Drivers
|
||||
endef
|
||||
|
||||
define KernelPackage/p54/description
|
||||
Kernel module for Prism54 chipsets (mac80211)
|
||||
endef
|
||||
|
||||
define KernelPackage/p54-common
|
||||
$(call KernelPackage/p54/Default)
|
||||
DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 +kmod-lib-crc-ccitt
|
||||
TITLE+= (COMMON)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54common.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/p54-pci
|
||||
$(call KernelPackage/p54/Default)
|
||||
TITLE+= (PCI)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-p54-common +p54-pci-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,p54pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/p54-usb
|
||||
$(call KernelPackage/p54/Default)
|
||||
TITLE+= (USB)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-p54-common +p54-usb-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54usb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,p54usb)
|
||||
endef
|
||||
|
||||
define KernelPackage/rsi91x
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Redpine Signals Inc 91x WLAN driver support
|
||||
DEPENDS+= +kmod-mac80211 +rs9113-firmware +@DRIVER_11N_SUPPORT
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_91x.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/rsi91x-usb
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Redpine Signals USB bus support
|
||||
DEPENDS+=@USB_SUPPORT +kmod-usb-core +kmod-mac80211 +kmod-rsi91x +rs9113-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_usb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rsi_usb)
|
||||
endef
|
||||
|
||||
define KernelPackage/rsi91x-sdio
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Redpine Signals SDIO bus support
|
||||
DEPENDS+= +kmod-mac80211 +kmod-mmc +kmod-rsi91x +rs9113-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_sdio.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rsi_sdio)
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/wlcore
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=TI common driver part
|
||||
DEPENDS+= +kmod-mmc +kmod-mac80211 +@DRIVER_11N_SUPPORT
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore_sdio.ko
|
||||
AUTOLOAD:=$(call AutoProbe,wlcore wlcore_sdio)
|
||||
endef
|
||||
|
||||
define KernelPackage/wlcore/description
|
||||
This module contains some common parts needed by TI Wireless drivers.
|
||||
endef
|
||||
|
||||
define KernelPackage/wl12xx
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Driver for TI WL12xx
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/wl12xx
|
||||
DEPENDS+= +kmod-wlcore +wl12xx-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl12xx/wl12xx.ko
|
||||
AUTOLOAD:=$(call AutoProbe,wl12xx)
|
||||
endef
|
||||
|
||||
define KernelPackage/wl12xx/description
|
||||
Kernel modules for TI WL12xx
|
||||
endef
|
||||
|
||||
define KernelPackage/wl18xx
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Driver for TI WL18xx
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/wl18xx
|
||||
DEPENDS+= +kmod-wlcore +wl18xx-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl18xx/wl18xx.ko
|
||||
AUTOLOAD:=$(call AutoProbe,wl18xx)
|
||||
endef
|
||||
|
||||
define KernelPackage/wl18xx/description
|
||||
Kernel modules for TI WL18xx
|
||||
endef
|
||||
|
||||
|
||||
ZD1211FW_NAME:=zd1211-firmware
|
||||
ZD1211FW_VERSION:=1.4
|
||||
define Download/zd1211rw
|
||||
FILE:=$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2
|
||||
URL:=@SF/zd1211/
|
||||
HASH:=866308f6f59f7075f075d4959dff2ede47735c751251fecd1496df1ba4d338e1
|
||||
endef
|
||||
$(eval $(call Download,zd1211rw))
|
||||
|
||||
define KernelPackage/zd1211rw
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Zydas ZD1211 support
|
||||
DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-mac80211
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/zydas/zd1211rw/zd1211rw.ko
|
||||
AUTOLOAD:=$(call AutoProbe,zd1211rw)
|
||||
endef
|
||||
|
||||
ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS
|
||||
config-y += \
|
||||
CFG80211_DEBUGFS \
|
||||
MAC80211_DEBUGFS
|
||||
endif
|
||||
|
||||
ifdef CONFIG_PACKAGE_MAC80211_TRACING
|
||||
config-y += \
|
||||
IWLWIFI_DEVICE_TRACING
|
||||
endif
|
||||
|
||||
config-$(call config_package,lib80211) += LIB80211 LIB80211_CRYPT_WEP LIB80211_CRYPT_CCMP LIB80211_CRYPT_TKIP
|
||||
|
||||
config-$(call config_package,airo) += AIRO
|
||||
|
||||
config-$(call config_package,mac80211-hwsim) += MAC80211_HWSIM
|
||||
config-$(call config_package,mt7601u) += MT7601U
|
||||
config-y += WL_MEDIATEK
|
||||
|
||||
config-$(call config_package,p54-common) += P54_COMMON
|
||||
config-$(call config_package,p54-pci) += P54_PCI
|
||||
config-$(call config_package,p54-usb) += P54_USB
|
||||
|
||||
config-$(call config_package,hermes) += HERMES
|
||||
config-$(call config_package,hermes-pci) += PCI_HERMES
|
||||
config-$(call config_package,hermes-plx) += PLX_HERMES
|
||||
config-$(call config_package,hermes-pcmcia) += PCMCIA_HERMES
|
||||
config-y += HERMES_PRISM
|
||||
|
||||
config-$(call config_package,adm8211) += ADM8211
|
||||
config-$(call config_package,wlcore) += WLCORE WLCORE_SDIO
|
||||
config-$(call config_package,wl12xx) += WL12XX
|
||||
config-$(call config_package,wl18xx) += WL18XX
|
||||
config-y += WL_TI WILINK_PLATFORM_DATA
|
||||
config-$(call config_package,zd1211rw) += ZD1211RW
|
||||
config-$(call config_package,rsi91x) += RSI_91X
|
||||
config-$(call config_package,rsi91x-usb) += RSI_USB
|
||||
config-$(call config_package,rsi91x-sdio) += RSI_SDIO
|
||||
|
||||
config-$(CONFIG_LEDS_TRIGGERS) += MAC80211_LEDS
|
||||
|
||||
MAKE_OPTS:= -C "$(PKG_BUILD_DIR)" \
|
||||
$(KERNEL_MAKE_FLAGS) \
|
||||
EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS)" \
|
||||
KLIB_BUILD="$(LINUX_DIR)" \
|
||||
MODPROBE=true \
|
||||
KLIB=$(TARGET_MODULES_DIR) \
|
||||
KERNEL_SUBLEVEL=$(lastword $(subst ., ,$(KERNEL_PATCHVER))) \
|
||||
KBUILD_LDFLAGS_MODULE_PREREQ=
|
||||
|
||||
define ConfigVars
|
||||
$(subst $(space),,$(foreach opt,$(config-$(1)),CPTCFG_$(opt)=$(1)
|
||||
))
|
||||
endef
|
||||
|
||||
define mac80211_config
|
||||
$(call ConfigVars,m)$(call ConfigVars,y)
|
||||
endef
|
||||
$(eval $(call shexport,mac80211_config))
|
||||
|
||||
define Build/Prepare
|
||||
rm -rf $(PKG_BUILD_DIR)
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
$(PKG_UNPACK)
|
||||
$(Build/Patch)
|
||||
$(TAR) -C $(PKG_BUILD_DIR) -xzf $(DL_DIR)/$(IPW2100_NAME)-$(IPW2100_VERSION).tgz
|
||||
$(TAR) -C $(PKG_BUILD_DIR) -xzf $(DL_DIR)/$(IPW2200_NAME)-$(IPW2200_VERSION).tgz
|
||||
$(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2
|
||||
rm -rf \
|
||||
$(PKG_BUILD_DIR)/include/linux/ssb \
|
||||
$(PKG_BUILD_DIR)/include/linux/bcma \
|
||||
$(PKG_BUILD_DIR)/include/net/bluetooth
|
||||
|
||||
rm -f \
|
||||
$(PKG_BUILD_DIR)/include/linux/cordic.h \
|
||||
$(PKG_BUILD_DIR)/include/linux/crc8.h \
|
||||
$(PKG_BUILD_DIR)/include/linux/eeprom_93cx6.h \
|
||||
$(PKG_BUILD_DIR)/include/linux/wl12xx.h \
|
||||
$(PKG_BUILD_DIR)/include/linux/spi/libertas_spi.h \
|
||||
$(PKG_BUILD_DIR)/include/net/ieee80211.h \
|
||||
$(PKG_BUILD_DIR)/backport-include/linux/bcm47xx_nvram.h
|
||||
|
||||
echo 'compat-wireless-$(PKG_VERSION)-$(PKG_RELEASE)-$(REVISION)' > $(PKG_BUILD_DIR)/compat_version
|
||||
endef
|
||||
|
||||
ifneq ($(CONFIG_PACKAGE_kmod-cfg80211)$(CONFIG_PACKAGE_kmod-lib80211),)
|
||||
define Build/Compile/kmod
|
||||
rm -rf $(PKG_BUILD_DIR)/modules
|
||||
+$(MAKE) $(PKG_JOBS) $(MAKE_OPTS) modules
|
||||
endef
|
||||
endif
|
||||
|
||||
#do not Build/Configure for EXTERNAL KERNEL
|
||||
ifeq ($(strip $(CONFIG_EXTERNAL_KERNEL_TREE)),"")
|
||||
ifeq ($(strip $(CONFIG_KERNEL_GIT_CLONE_URI)),"")
|
||||
define Build/Configure
|
||||
cmp $(PKG_BUILD_DIR)/include/linux/ath9k_platform.h $(LINUX_DIR)/include/linux/ath9k_platform.h
|
||||
cmp $(PKG_BUILD_DIR)/include/linux/ath5k_platform.h $(LINUX_DIR)/include/linux/ath5k_platform.h
|
||||
cmp $(PKG_BUILD_DIR)/include/linux/rt2x00_platform.h $(LINUX_DIR)/include/linux/rt2x00_platform.h
|
||||
endef
|
||||
endif
|
||||
endif
|
||||
|
||||
define Build/Patch
|
||||
$(if $(QUILT),rm -rf $(PKG_BUILD_DIR)/patches; mkdir -p $(PKG_BUILD_DIR)/patches)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath5k,ath5k/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/)
|
||||
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rtl,rtl/)
|
||||
$(if $(QUILT),touch $(PKG_BUILD_DIR)/.quilt_used)
|
||||
endef
|
||||
|
||||
define Quilt/Refresh/Package
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath5k,ath5k/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/)
|
||||
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rtl,rtl/)
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(SH_FUNC) var2file "$(call shvar,mac80211_config)" $(PKG_BUILD_DIR)/.config
|
||||
$(MAKE) $(MAKE_OPTS) allnoconfig
|
||||
$(call Build/Compile/kmod)
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
mkdir -p \
|
||||
$(1)/usr/include/mac80211 \
|
||||
$(1)/usr/include/mac80211-backport \
|
||||
$(1)/usr/include/mac80211/ath \
|
||||
$(1)/usr/include/net/mac80211
|
||||
$(CP) $(PKG_BUILD_DIR)/net/mac80211/*.h $(PKG_BUILD_DIR)/include/* $(1)/usr/include/mac80211/
|
||||
$(CP) $(PKG_BUILD_DIR)/backport-include/* $(1)/usr/include/mac80211-backport/
|
||||
$(CP) $(PKG_BUILD_DIR)/net/mac80211/rate.h $(1)/usr/include/net/mac80211/
|
||||
$(CP) $(PKG_BUILD_DIR)/drivers/net/wireless/ath/*.h $(1)/usr/include/mac80211/ath/
|
||||
rm -f $(1)/usr/include/mac80211-backport/linux/module.h
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/cfg80211/install
|
||||
$(INSTALL_DIR) $(1)/lib/wifi $(1)/lib/netifd/wireless
|
||||
$(INSTALL_DATA) ./files/lib/wifi/mac80211.sh $(1)/lib/wifi
|
||||
$(INSTALL_BIN) ./files/lib/netifd/wireless/mac80211.sh $(1)/lib/netifd/wireless
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211
|
||||
$(INSTALL_DATA) ./files/mac80211.hotplug $(1)/etc/hotplug.d/ieee80211/10-wifi-detect
|
||||
endef
|
||||
|
||||
define KernelPackage/zd1211rw/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/zd1211
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(ZD1211FW_NAME)/zd1211* $(1)/lib/firmware/zd1211
|
||||
endef
|
||||
|
||||
$(eval $(foreach drv,$(PKG_DRIVERS),$(call KernelPackage,$(drv))))
|
||||
$(eval $(call KernelPackage,cfg80211))
|
||||
$(eval $(call KernelPackage,mac80211))
|
@ -1,576 +0,0 @@
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Mon, 23 Aug 2021 20:02:39 +0200
|
||||
Subject: [PATCH] mac80211: introduce individual TWT support in AP mode
|
||||
|
||||
Introduce TWT action frames parsing support to mac80211.
|
||||
Currently just individual TWT agreement are support in AP mode.
|
||||
Whenever the AP receives a TWT action frame from an associated client,
|
||||
after performing sanity checks, it will notify the underlay driver with
|
||||
requested parameters in order to check if they are supported and if there
|
||||
is enough room for a new agreement. The driver is expected to set the
|
||||
agreement result and report it to mac80211.
|
||||
|
||||
Drivers supporting this have two new callbacks:
|
||||
- add_twt_setup (mandatory)
|
||||
- twt_teardown_request (optional)
|
||||
|
||||
mac80211 will send an action frame reply according to the result
|
||||
reported by the driver.
|
||||
|
||||
Tested-by: Peter Chiu <chui-hao.chiu@mediatek.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://lore.kernel.org/r/257512f2e22ba42b9f2624942a128dd8f141de4b.1629741512.git.lorenzo@kernel.org
|
||||
[use le16p_replace_bits(), minor cleanups, use (void *) casts,
|
||||
fix to use ieee80211_get_he_iftype_cap() correctly]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -4219,6 +4219,11 @@ struct ieee80211_ops {
|
||||
void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enabled);
|
||||
+ void (*add_twt_setup)(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ struct ieee80211_twt_setup *twt);
|
||||
+ void (*twt_teardown_request)(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_sta *sta, u8 flowid);
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/net/mac80211/driver-ops.h
|
||||
+++ b/net/mac80211/driver-ops.h
|
||||
@@ -1429,4 +1429,40 @@ static inline void drv_sta_set_decap_off
|
||||
trace_drv_return_void(local);
|
||||
}
|
||||
|
||||
+static inline void drv_add_twt_setup(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sub_if_data *sdata,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ struct ieee80211_twt_setup *twt)
|
||||
+{
|
||||
+ struct ieee80211_twt_params *twt_agrt;
|
||||
+
|
||||
+ might_sleep();
|
||||
+
|
||||
+ if (!check_sdata_in_driver(sdata))
|
||||
+ return;
|
||||
+
|
||||
+ twt_agrt = (void *)twt->params;
|
||||
+
|
||||
+ trace_drv_add_twt_setup(local, sta, twt, twt_agrt);
|
||||
+ local->ops->add_twt_setup(&local->hw, sta, twt);
|
||||
+ trace_drv_return_void(local);
|
||||
+}
|
||||
+
|
||||
+static inline void drv_twt_teardown_request(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sub_if_data *sdata,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ u8 flowid)
|
||||
+{
|
||||
+ might_sleep();
|
||||
+ if (!check_sdata_in_driver(sdata))
|
||||
+ return;
|
||||
+
|
||||
+ if (!local->ops->twt_teardown_request)
|
||||
+ return;
|
||||
+
|
||||
+ trace_drv_twt_teardown_request(local, sta, flowid);
|
||||
+ local->ops->twt_teardown_request(&local->hw, sta, flowid);
|
||||
+ trace_drv_return_void(local);
|
||||
+}
|
||||
+
|
||||
#endif /* __MAC80211_DRIVER_OPS */
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -954,6 +954,7 @@ struct ieee80211_sub_if_data {
|
||||
|
||||
struct work_struct work;
|
||||
struct sk_buff_head skb_queue;
|
||||
+ struct sk_buff_head status_queue;
|
||||
|
||||
u8 needed_rx_chains;
|
||||
enum ieee80211_smps_mode smps_mode;
|
||||
@@ -2093,6 +2094,11 @@ ieee80211_he_op_ie_to_bss_conf(struct ie
|
||||
|
||||
/* S1G */
|
||||
void ieee80211_s1g_sta_rate_init(struct sta_info *sta);
|
||||
+bool ieee80211_s1g_is_twt_setup(struct sk_buff *skb);
|
||||
+void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb);
|
||||
+void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb);
|
||||
|
||||
/* Spectrum management */
|
||||
void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -563,6 +563,7 @@ static void ieee80211_do_stop(struct iee
|
||||
*/
|
||||
ieee80211_free_keys(sdata, true);
|
||||
skb_queue_purge(&sdata->skb_queue);
|
||||
+ skb_queue_purge(&sdata->status_queue);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
||||
@@ -1070,6 +1071,7 @@ int ieee80211_add_virtual_monitor(struct
|
||||
}
|
||||
|
||||
skb_queue_head_init(&sdata->skb_queue);
|
||||
+ skb_queue_head_init(&sdata->status_queue);
|
||||
INIT_WORK(&sdata->work, ieee80211_iface_work);
|
||||
|
||||
return 0;
|
||||
@@ -1442,6 +1444,24 @@ static void ieee80211_if_setup_no_queue(
|
||||
#endif
|
||||
}
|
||||
|
||||
+static void ieee80211_iface_process_status(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
|
||||
+
|
||||
+ if (ieee80211_is_action(mgmt->frame_control) &&
|
||||
+ mgmt->u.action.category == WLAN_CATEGORY_S1G) {
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ ieee80211_s1g_status_twt_action(sdata, skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void ieee80211_iface_work(struct work_struct *work)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata =
|
||||
@@ -1519,6 +1539,16 @@ static void ieee80211_iface_work(struct
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
+ } else if (ieee80211_is_action(mgmt->frame_control) &&
|
||||
+ mgmt->u.action.category == WLAN_CATEGORY_S1G) {
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ ieee80211_s1g_rx_twt_action(sdata, skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
} else if (ieee80211_is_ext(mgmt->frame_control)) {
|
||||
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||
ieee80211_sta_rx_queued_ext(sdata, skb);
|
||||
@@ -1574,6 +1604,12 @@ static void ieee80211_iface_work(struct
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
+ /* process status queue */
|
||||
+ while ((skb = skb_dequeue(&sdata->status_queue))) {
|
||||
+ ieee80211_iface_process_status(sdata, skb);
|
||||
+ kfree_skb(skb);
|
||||
+ }
|
||||
+
|
||||
/* then other type-dependent work */
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
@@ -1637,6 +1677,7 @@ static void ieee80211_setup_sdata(struct
|
||||
}
|
||||
|
||||
skb_queue_head_init(&sdata->skb_queue);
|
||||
+ skb_queue_head_init(&sdata->status_queue);
|
||||
INIT_WORK(&sdata->work, ieee80211_iface_work);
|
||||
INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
|
||||
INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -3208,6 +3208,68 @@ ieee80211_rx_h_mgmt_check(struct ieee802
|
||||
return RX_CONTINUE;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+ieee80211_process_rx_twt_action(struct ieee80211_rx_data *rx)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)rx->skb->data;
|
||||
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
||||
+ struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
+ const struct ieee80211_sta_he_cap *hecap;
|
||||
+ struct ieee80211_supported_band *sband;
|
||||
+
|
||||
+ /* TWT actions are only supported in AP for the moment */
|
||||
+ if (sdata->vif.type != NL80211_IFTYPE_AP)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!rx->local->ops->add_twt_setup)
|
||||
+ return false;
|
||||
+
|
||||
+ sband = rx->local->hw.wiphy->bands[status->band];
|
||||
+ hecap = ieee80211_get_he_iftype_cap(sband,
|
||||
+ ieee80211_vif_type_p2p(&sdata->vif));
|
||||
+ if (!hecap)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!(hecap->he_cap_elem.mac_cap_info[0] &
|
||||
+ IEEE80211_HE_MAC_CAP0_TWT_RES))
|
||||
+ return false;
|
||||
+
|
||||
+ if (!rx->sta)
|
||||
+ return false;
|
||||
+
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_SETUP: {
|
||||
+ struct ieee80211_twt_setup *twt;
|
||||
+
|
||||
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE +
|
||||
+ 1 + /* action code */
|
||||
+ sizeof(struct ieee80211_twt_setup) +
|
||||
+ 2 /* TWT req_type agrt */)
|
||||
+ break;
|
||||
+
|
||||
+ twt = (void *)mgmt->u.action.u.s1g.variable;
|
||||
+ if (twt->element_id != WLAN_EID_S1G_TWT)
|
||||
+ break;
|
||||
+
|
||||
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE +
|
||||
+ 4 + /* action code + token + tlv */
|
||||
+ twt->length)
|
||||
+ break;
|
||||
+
|
||||
+ return true; /* queue the frame */
|
||||
+ }
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE + 2)
|
||||
+ break;
|
||||
+
|
||||
+ return true; /* queue the frame */
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static ieee80211_rx_result debug_noinline
|
||||
ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
||||
{
|
||||
@@ -3487,6 +3549,17 @@ ieee80211_rx_h_action(struct ieee80211_r
|
||||
!mesh_path_sel_is_hwmp(sdata))
|
||||
break;
|
||||
goto queue;
|
||||
+ case WLAN_CATEGORY_S1G:
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ if (ieee80211_process_rx_twt_action(rx))
|
||||
+ goto queue;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
}
|
||||
|
||||
return RX_CONTINUE;
|
||||
--- a/net/mac80211/s1g.c
|
||||
+++ b/net/mac80211/s1g.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <linux/ieee80211.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "ieee80211_i.h"
|
||||
+#include "driver-ops.h"
|
||||
|
||||
void ieee80211_s1g_sta_rate_init(struct sta_info *sta)
|
||||
{
|
||||
@@ -14,3 +15,182 @@ void ieee80211_s1g_sta_rate_init(struct
|
||||
sta->rx_stats.last_rate =
|
||||
STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_S1G);
|
||||
}
|
||||
+
|
||||
+bool ieee80211_s1g_is_twt_setup(struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+
|
||||
+ if (likely(!ieee80211_is_action(mgmt->frame_control)))
|
||||
+ return false;
|
||||
+
|
||||
+ if (likely(mgmt->u.action.category != WLAN_CATEGORY_S1G))
|
||||
+ return false;
|
||||
+
|
||||
+ return mgmt->u.action.u.s1g.action_code == WLAN_S1G_TWT_SETUP;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_send_twt_setup(struct ieee80211_sub_if_data *sdata, const u8 *da,
|
||||
+ const u8 *bssid, struct ieee80211_twt_setup *twt)
|
||||
+{
|
||||
+ int len = IEEE80211_MIN_ACTION_SIZE + 4 + twt->length;
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct ieee80211_mgmt *mgmt;
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
|
||||
+ if (!skb)
|
||||
+ return;
|
||||
+
|
||||
+ skb_reserve(skb, local->hw.extra_tx_headroom);
|
||||
+ mgmt = skb_put_zero(skb, len);
|
||||
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||
+ IEEE80211_STYPE_ACTION);
|
||||
+ memcpy(mgmt->da, da, ETH_ALEN);
|
||||
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
|
||||
+ memcpy(mgmt->bssid, bssid, ETH_ALEN);
|
||||
+
|
||||
+ mgmt->u.action.category = WLAN_CATEGORY_S1G;
|
||||
+ mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_SETUP;
|
||||
+ memcpy(mgmt->u.action.u.s1g.variable, twt, 3 + twt->length);
|
||||
+
|
||||
+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
|
||||
+ IEEE80211_TX_INTFL_MLME_CONN_TX |
|
||||
+ IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
+ ieee80211_tx_skb(sdata, skb);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_send_twt_teardown(struct ieee80211_sub_if_data *sdata,
|
||||
+ const u8 *da, const u8 *bssid, u8 flowid)
|
||||
+{
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct ieee80211_mgmt *mgmt;
|
||||
+ struct sk_buff *skb;
|
||||
+ u8 *id;
|
||||
+
|
||||
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom +
|
||||
+ IEEE80211_MIN_ACTION_SIZE + 2);
|
||||
+ if (!skb)
|
||||
+ return;
|
||||
+
|
||||
+ skb_reserve(skb, local->hw.extra_tx_headroom);
|
||||
+ mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE + 2);
|
||||
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||
+ IEEE80211_STYPE_ACTION);
|
||||
+ memcpy(mgmt->da, da, ETH_ALEN);
|
||||
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
|
||||
+ memcpy(mgmt->bssid, bssid, ETH_ALEN);
|
||||
+
|
||||
+ mgmt->u.action.category = WLAN_CATEGORY_S1G;
|
||||
+ mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_TEARDOWN;
|
||||
+ id = (u8 *)mgmt->u.action.u.s1g.variable;
|
||||
+ *id = flowid;
|
||||
+
|
||||
+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
|
||||
+ IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
+ ieee80211_tx_skb(sdata, skb);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_rx_twt_setup(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sta_info *sta, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
|
||||
+ struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable;
|
||||
+ struct ieee80211_twt_params *twt_agrt = (void *)twt->params;
|
||||
+
|
||||
+ twt_agrt->req_type &= cpu_to_le16(~IEEE80211_TWT_REQTYPE_REQUEST);
|
||||
+
|
||||
+ /* broadcast TWT not supported yet */
|
||||
+ if (twt->control & IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST) {
|
||||
+ le16p_replace_bits(&twt_agrt->req_type,
|
||||
+ TWT_SETUP_CMD_REJECT,
|
||||
+ IEEE80211_TWT_REQTYPE_SETUP_CMD);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ drv_add_twt_setup(sdata->local, sdata, &sta->sta, twt);
|
||||
+out:
|
||||
+ ieee80211_s1g_send_twt_setup(sdata, mgmt->sa, sdata->vif.addr, twt);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_rx_twt_teardown(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sta_info *sta, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+
|
||||
+ drv_twt_teardown_request(sdata->local, sdata, &sta->sta,
|
||||
+ mgmt->u.action.u.s1g.variable[0]);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_tx_twt_setup_fail(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sta_info *sta, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+ struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable;
|
||||
+ struct ieee80211_twt_params *twt_agrt = (void *)twt->params;
|
||||
+ u8 flowid = le16_get_bits(twt_agrt->req_type,
|
||||
+ IEEE80211_TWT_REQTYPE_FLOWID);
|
||||
+
|
||||
+ drv_twt_teardown_request(sdata->local, sdata, &sta->sta, flowid);
|
||||
+
|
||||
+ ieee80211_s1g_send_twt_teardown(sdata, mgmt->sa, sdata->vif.addr,
|
||||
+ flowid);
|
||||
+}
|
||||
+
|
||||
+void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct sta_info *sta;
|
||||
+
|
||||
+ mutex_lock(&local->sta_mtx);
|
||||
+
|
||||
+ sta = sta_info_get_bss(sdata, mgmt->sa);
|
||||
+ if (!sta)
|
||||
+ goto out;
|
||||
+
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ ieee80211_s1g_rx_twt_setup(sdata, sta, skb);
|
||||
+ break;
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ ieee80211_s1g_rx_twt_teardown(sdata, sta, skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&local->sta_mtx);
|
||||
+}
|
||||
+
|
||||
+void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct sta_info *sta;
|
||||
+
|
||||
+ mutex_lock(&local->sta_mtx);
|
||||
+
|
||||
+ sta = sta_info_get_bss(sdata, mgmt->da);
|
||||
+ if (!sta)
|
||||
+ goto out;
|
||||
+
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ /* process failed twt setup frames */
|
||||
+ ieee80211_s1g_tx_twt_setup_fail(sdata, sta, skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&local->sta_mtx);
|
||||
+}
|
||||
--- a/net/mac80211/status.c
|
||||
+++ b/net/mac80211/status.c
|
||||
@@ -705,13 +705,26 @@ static void ieee80211_report_used_skb(st
|
||||
/* Check to see if packet is a TDLS teardown packet */
|
||||
if (ieee80211_is_data(hdr->frame_control) &&
|
||||
(ieee80211_get_tdls_action(skb, hdr_size) ==
|
||||
- WLAN_TDLS_TEARDOWN))
|
||||
+ WLAN_TDLS_TEARDOWN)) {
|
||||
ieee80211_tdls_td_tx_handle(local, sdata, skb,
|
||||
info->flags);
|
||||
- else
|
||||
+ } else if (ieee80211_s1g_is_twt_setup(skb)) {
|
||||
+ if (!acked) {
|
||||
+ struct sk_buff *qskb;
|
||||
+
|
||||
+ qskb = skb_clone(skb, GFP_ATOMIC);
|
||||
+ if (qskb) {
|
||||
+ skb_queue_tail(&sdata->status_queue,
|
||||
+ qskb);
|
||||
+ ieee80211_queue_work(&local->hw,
|
||||
+ &sdata->work);
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
ieee80211_mgd_conn_tx_status(sdata,
|
||||
hdr->frame_control,
|
||||
acked);
|
||||
+ }
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
--- a/net/mac80211/trace.h
|
||||
+++ b/net/mac80211/trace.h
|
||||
@@ -2804,6 +2804,73 @@ DEFINE_EVENT(sta_flag_evt, drv_sta_set_d
|
||||
TP_ARGS(local, sdata, sta, enabled)
|
||||
);
|
||||
|
||||
+TRACE_EVENT(drv_add_twt_setup,
|
||||
+ TP_PROTO(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ struct ieee80211_twt_setup *twt,
|
||||
+ struct ieee80211_twt_params *twt_agrt),
|
||||
+
|
||||
+ TP_ARGS(local, sta, twt, twt_agrt),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ LOCAL_ENTRY
|
||||
+ STA_ENTRY
|
||||
+ __field(u8, dialog_token)
|
||||
+ __field(u8, control)
|
||||
+ __field(__le16, req_type)
|
||||
+ __field(__le64, twt)
|
||||
+ __field(u8, duration)
|
||||
+ __field(__le16, mantissa)
|
||||
+ __field(u8, channel)
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ LOCAL_ASSIGN;
|
||||
+ STA_ASSIGN;
|
||||
+ __entry->dialog_token = twt->dialog_token;
|
||||
+ __entry->control = twt->control;
|
||||
+ __entry->req_type = twt_agrt->req_type;
|
||||
+ __entry->twt = twt_agrt->twt;
|
||||
+ __entry->duration = twt_agrt->min_twt_dur;
|
||||
+ __entry->mantissa = twt_agrt->mantissa;
|
||||
+ __entry->channel = twt_agrt->channel;
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ LOCAL_PR_FMT STA_PR_FMT
|
||||
+ " token:%d control:0x%02x req_type:0x%04x"
|
||||
+ " twt:%llu duration:%d mantissa:%d channel:%d",
|
||||
+ LOCAL_PR_ARG, STA_PR_ARG, __entry->dialog_token,
|
||||
+ __entry->control, le16_to_cpu(__entry->req_type),
|
||||
+ le64_to_cpu(__entry->twt), __entry->duration,
|
||||
+ le16_to_cpu(__entry->mantissa), __entry->channel
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
+TRACE_EVENT(drv_twt_teardown_request,
|
||||
+ TP_PROTO(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sta *sta, u8 flowid),
|
||||
+
|
||||
+ TP_ARGS(local, sta, flowid),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ LOCAL_ENTRY
|
||||
+ STA_ENTRY
|
||||
+ __field(u8, flowid)
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ LOCAL_ASSIGN;
|
||||
+ STA_ASSIGN;
|
||||
+ __entry->flowid = flowid;
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ LOCAL_PR_FMT STA_PR_FMT " flowid:%d",
|
||||
+ LOCAL_PR_ARG, STA_PR_ARG, __entry->flowid
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
@ -1,81 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -8618,6 +8618,70 @@ static void rt2800_r_calibration(struct
|
||||
rt2800_register_write(rt2x00dev, PWR_PIN_CFG, MAC_PWR_PIN_CFG);
|
||||
}
|
||||
|
||||
+static void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ u8 bbpreg = 0;
|
||||
+ u32 macvalue = 0, macvalue1 = 0;
|
||||
+ u8 saverfb0r2, saverfb5r4, saverfb7r4, rfvalue;
|
||||
+ int i;
|
||||
+
|
||||
+ saverfb0r2 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
|
||||
+ rfvalue = saverfb0r2;
|
||||
+ rfvalue |= 0x03;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfvalue);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 141);
|
||||
+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbpreg |= 0x10;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x8);
|
||||
+
|
||||
+ for (i = 0; i < 10000; i++) {
|
||||
+ macvalue1 = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
|
||||
+ if (macvalue1 & 0x1)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 0);
|
||||
+ saverfb7r4 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
|
||||
+ saverfb5r4 = saverfb5r4 & (~0x40);
|
||||
+ saverfb7r4 = saverfb7r4 & (~0x40);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x64);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, saverfb5r4);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, saverfb7r4);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 141);
|
||||
+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbpreg = bbpreg & (~0x40);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
|
||||
+ bbpreg |= 0x48;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
|
||||
+
|
||||
+ for (i = 0; i < 10000; i++) {
|
||||
+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ if ((bbpreg & 0x40)==0)
|
||||
+ break;
|
||||
+ udelay(50);
|
||||
+ }
|
||||
+
|
||||
+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbpreg = bbpreg & (~0x40);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 141);
|
||||
+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbpreg &= (~0x10);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
|
||||
+
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, saverfb0r2);
|
||||
+}
|
||||
+
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9227,6 +9291,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
|
||||
rt2800_r_calibration(rt2x00dev);
|
||||
rt2800_rf_self_txdc_cal(rt2x00dev);
|
||||
+ rt2800_rxdcoc_calibration(rt2x00dev);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, true);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
From: David Bauer <mail@david-bauer.net>
|
||||
Date: Mon, 16 Dec 2019 20:47:06 +0100
|
||||
Subject: [PATCH] rt2x00: add throughput LED trigger
|
||||
|
||||
This adds a (currently missing) throughput LED trigger for the rt2x00
|
||||
driver. Previously, LED triggers had to be assigned to the netdev, which
|
||||
was limited to a single VAP.
|
||||
|
||||
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
Tested-by: Christoph Krapp <achterin@googlemail.com>
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1126,6 +1126,19 @@ static void rt2x00lib_remove_hw(struct r
|
||||
kfree(rt2x00dev->spec.channels_info);
|
||||
}
|
||||
|
||||
+static const struct ieee80211_tpt_blink rt2x00_tpt_blink[] = {
|
||||
+ { .throughput = 0 * 1024, .blink_time = 334 },
|
||||
+ { .throughput = 1 * 1024, .blink_time = 260 },
|
||||
+ { .throughput = 2 * 1024, .blink_time = 220 },
|
||||
+ { .throughput = 5 * 1024, .blink_time = 190 },
|
||||
+ { .throughput = 10 * 1024, .blink_time = 170 },
|
||||
+ { .throughput = 25 * 1024, .blink_time = 150 },
|
||||
+ { .throughput = 54 * 1024, .blink_time = 130 },
|
||||
+ { .throughput = 120 * 1024, .blink_time = 110 },
|
||||
+ { .throughput = 265 * 1024, .blink_time = 80 },
|
||||
+ { .throughput = 586 * 1024, .blink_time = 50 },
|
||||
+};
|
||||
+
|
||||
static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct hw_mode_spec *spec = &rt2x00dev->spec;
|
||||
@@ -1207,6 +1220,10 @@ static int rt2x00lib_probe_hw(struct rt2
|
||||
|
||||
#undef RT2X00_TASKLET_INIT
|
||||
|
||||
+ ieee80211_create_tpt_led_trigger(rt2x00dev->hw,
|
||||
+ IEEE80211_TPT_LEDTRIG_FL_RADIO, rt2x00_tpt_blink,
|
||||
+ ARRAY_SIZE(rt2x00_tpt_blink));
|
||||
+
|
||||
/*
|
||||
* Register HW.
|
||||
*/
|
@ -1,102 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 22 Jan 2021 19:24:59 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: reduce the need to sample slower
|
||||
rates
|
||||
|
||||
In order to more gracefully be able to fall back to lower rates without too
|
||||
much throughput fluctuations, initialize all untested rates below tested ones
|
||||
to the maximum probabilty of higher rates.
|
||||
Usually this leads to untested lower rates getting initialized with a
|
||||
probability value of 100%, making them better candidates for fallback without
|
||||
having to rely on random probing
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -791,14 +791,11 @@ minstrel_ht_calc_rate_stats(struct minst
|
||||
unsigned int cur_prob;
|
||||
|
||||
if (unlikely(mrs->attempts > 0)) {
|
||||
- mrs->sample_skipped = 0;
|
||||
cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
|
||||
minstrel_filter_avg_add(&mrs->prob_avg,
|
||||
&mrs->prob_avg_1, cur_prob);
|
||||
mrs->att_hist += mrs->attempts;
|
||||
mrs->succ_hist += mrs->success;
|
||||
- } else {
|
||||
- mrs->sample_skipped++;
|
||||
}
|
||||
|
||||
mrs->last_success = mrs->success;
|
||||
@@ -851,7 +848,6 @@ minstrel_ht_update_stats(struct minstrel
|
||||
mi->ampdu_packets = 0;
|
||||
}
|
||||
|
||||
- mi->sample_slow = 0;
|
||||
mi->sample_count = 0;
|
||||
|
||||
if (mi->supported[MINSTREL_CCK_GROUP])
|
||||
@@ -882,6 +878,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
/* Find best rate sets within all MCS groups*/
|
||||
for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
|
||||
u16 *tp_rate = tmp_mcs_tp_rate;
|
||||
+ u16 last_prob = 0;
|
||||
|
||||
mg = &mi->groups[group];
|
||||
if (!mi->supported[group])
|
||||
@@ -896,7 +893,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
if (group == MINSTREL_CCK_GROUP && ht_supported)
|
||||
tp_rate = tmp_legacy_tp_rate;
|
||||
|
||||
- for (i = 0; i < MCS_GROUP_RATES; i++) {
|
||||
+ for (i = MCS_GROUP_RATES - 1; i >= 0; i--) {
|
||||
if (!(mi->supported[group] & BIT(i)))
|
||||
continue;
|
||||
|
||||
@@ -905,6 +902,11 @@ minstrel_ht_update_stats(struct minstrel
|
||||
mrs = &mg->rates[i];
|
||||
mrs->retry_updated = false;
|
||||
minstrel_ht_calc_rate_stats(mp, mrs);
|
||||
+
|
||||
+ if (mrs->att_hist)
|
||||
+ last_prob = max(last_prob, mrs->prob_avg);
|
||||
+ else
|
||||
+ mrs->prob_avg = max(last_prob, mrs->prob_avg);
|
||||
cur_prob = mrs->prob_avg;
|
||||
|
||||
if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0)
|
||||
@@ -1469,13 +1471,9 @@ minstrel_get_sample_rate(struct minstrel
|
||||
if (sample_dur >= minstrel_get_duration(tp_rate2) &&
|
||||
(cur_max_tp_streams - 1 <
|
||||
minstrel_mcs_groups[sample_group].streams ||
|
||||
- sample_dur >= minstrel_get_duration(mi->max_prob_rate))) {
|
||||
- if (mrs->sample_skipped < 20)
|
||||
+ sample_dur >= minstrel_get_duration(mi->max_prob_rate)))
|
||||
return -1;
|
||||
|
||||
- if (mi->sample_slow++ > 2)
|
||||
- return -1;
|
||||
- }
|
||||
mi->sample_tries--;
|
||||
|
||||
return sample_idx;
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.h
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
||||
@@ -123,7 +123,6 @@ struct minstrel_rate_stats {
|
||||
u8 retry_count;
|
||||
u8 retry_count_rtscts;
|
||||
|
||||
- u8 sample_skipped;
|
||||
bool retry_updated;
|
||||
};
|
||||
|
||||
@@ -179,7 +178,6 @@ struct minstrel_ht_sta {
|
||||
u8 sample_wait;
|
||||
u8 sample_tries;
|
||||
u8 sample_count;
|
||||
- u8 sample_slow;
|
||||
|
||||
enum minstrel_sample_mode sample_mode;
|
||||
u16 sample_rate;
|
@ -1,101 +0,0 @@
|
||||
From: Sven Eckelmann <seckelmann@datto.com>
|
||||
Date: Wed, 28 Nov 2018 16:16:27 +0100
|
||||
Subject: ath10k: adjust tx power reduction for US regulatory domain
|
||||
|
||||
FCC allows maximum antenna gain of 6 dBi. 15.247(b)(4):
|
||||
|
||||
> (4) The conducted output power limit
|
||||
> specified in paragraph (b) of this section
|
||||
> is based on the use of antennas
|
||||
> with directional gains that do not exceed
|
||||
> 6 dBi. Except as shown in paragraph
|
||||
> (c) of this section, if transmitting
|
||||
> antennas of directional gain greater
|
||||
> than 6 dBi are used, the conducted
|
||||
> output power from the intentional radiator
|
||||
> shall be reduced below the stated
|
||||
> values in paragraphs (b)(1), (b)(2),
|
||||
> and (b)(3) of this section, as appropriate,
|
||||
> by the amount in dB that the
|
||||
> directional gain of the antenna exceeds
|
||||
> 6 dBi.
|
||||
|
||||
https://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol1/pdf/CFR-2013-title47-vol1-sec15-247.pdf
|
||||
|
||||
Signed-off-by: Sven Eckelmann <seckelmann@datto.com>
|
||||
|
||||
Forwarded: no
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -1006,6 +1006,40 @@ static inline int ath10k_vdev_setup_sync
|
||||
return ar->last_wmi_vdev_start_status;
|
||||
}
|
||||
|
||||
+static u32 ath10k_get_max_antenna_gain(struct ath10k *ar,
|
||||
+ u32 ch_max_antenna_gain)
|
||||
+{
|
||||
+ u32 max_antenna_gain;
|
||||
+
|
||||
+ if (ar->dfs_detector && ar->dfs_detector->region == NL80211_DFS_FCC) {
|
||||
+ /* FCC allows maximum antenna gain of 6 dBi. 15.247(b)(4):
|
||||
+ *
|
||||
+ * > (4) The conducted output power limit
|
||||
+ * > specified in paragraph (b) of this section
|
||||
+ * > is based on the use of antennas
|
||||
+ * > with directional gains that do not exceed
|
||||
+ * > 6 dBi. Except as shown in paragraph
|
||||
+ * > (c) of this section, if transmitting
|
||||
+ * > antennas of directional gain greater
|
||||
+ * > than 6 dBi are used, the conducted
|
||||
+ * > output power from the intentional radiator
|
||||
+ * > shall be reduced below the stated
|
||||
+ * > values in paragraphs (b)(1), (b)(2),
|
||||
+ * > and (b)(3) of this section, as appropriate,
|
||||
+ * > by the amount in dB that the
|
||||
+ * > directional gain of the antenna exceeds
|
||||
+ * > 6 dBi.
|
||||
+ *
|
||||
+ * https://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol1/pdf/CFR-2013-title47-vol1-sec15-247.pdf
|
||||
+ */
|
||||
+ max_antenna_gain = 6;
|
||||
+ } else {
|
||||
+ max_antenna_gain = 0;
|
||||
+ }
|
||||
+
|
||||
+ return max(ch_max_antenna_gain, max_antenna_gain);
|
||||
+}
|
||||
+
|
||||
static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
|
||||
{
|
||||
struct cfg80211_chan_def *chandef = NULL;
|
||||
@@ -1038,7 +1072,8 @@ static int ath10k_monitor_vdev_start(str
|
||||
arg.channel.min_power = 0;
|
||||
arg.channel.max_power = channel->max_power * 2;
|
||||
arg.channel.max_reg_power = channel->max_reg_power * 2;
|
||||
- arg.channel.max_antenna_gain = channel->max_antenna_gain;
|
||||
+ arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar,
|
||||
+ channel->max_antenna_gain);
|
||||
|
||||
reinit_completion(&ar->vdev_setup_done);
|
||||
reinit_completion(&ar->vdev_delete_done);
|
||||
@@ -1484,7 +1519,8 @@ static int ath10k_vdev_start_restart(str
|
||||
arg.channel.min_power = 0;
|
||||
arg.channel.max_power = chandef->chan->max_power * 2;
|
||||
arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
|
||||
- arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain;
|
||||
+ arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar,
|
||||
+ chandef->chan->max_antenna_gain);
|
||||
|
||||
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
|
||||
arg.ssid = arvif->u.ap.ssid;
|
||||
@@ -3255,7 +3291,8 @@ static int ath10k_update_channel_list(st
|
||||
ch->min_power = 0;
|
||||
ch->max_power = channel->max_power * 2;
|
||||
ch->max_reg_power = channel->max_reg_power * 2;
|
||||
- ch->max_antenna_gain = channel->max_antenna_gain;
|
||||
+ ch->max_antenna_gain = ath10k_get_max_antenna_gain(ar,
|
||||
+ channel->max_antenna_gain);
|
||||
ch->reg_class_id = 0; /* FIXME */
|
||||
|
||||
/* FIXME: why use only legacy modes, why not any
|
@ -1,183 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -1238,6 +1238,8 @@ void rt2800_watchdog(struct rt2x00_dev *
|
||||
if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags))
|
||||
return;
|
||||
|
||||
+ rt2800_update_survey(rt2x00dev);
|
||||
+
|
||||
queue_for_each(rt2x00dev, queue) {
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
@@ -1274,6 +1276,18 @@ void rt2800_watchdog(struct rt2x00_dev *
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_watchdog);
|
||||
|
||||
+void rt2800_update_survey(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ struct ieee80211_channel *chan = rt2x00dev->hw->conf.chandef.chan;
|
||||
+ struct rt2x00_chan_survey *chan_survey =
|
||||
+ &rt2x00dev->chan_survey[chan->hw_value];
|
||||
+
|
||||
+ chan_survey->time_idle += rt2800_register_read(rt2x00dev, CH_IDLE_STA);
|
||||
+ chan_survey->time_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA);
|
||||
+ chan_survey->time_ext_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(rt2800_update_survey);
|
||||
+
|
||||
static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
|
||||
unsigned int index)
|
||||
{
|
||||
@@ -12199,26 +12213,30 @@ int rt2800_get_survey(struct ieee80211_h
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
- u32 idle, busy, busy_ext;
|
||||
+ struct rt2x00_chan_survey *chan_survey =
|
||||
+ &rt2x00dev->chan_survey[idx];
|
||||
+ enum nl80211_band band = NL80211_BAND_2GHZ;
|
||||
|
||||
- if (idx != 0)
|
||||
+ if (idx >= rt2x00dev->bands[band].n_channels) {
|
||||
+ idx -= rt2x00dev->bands[band].n_channels;
|
||||
+ band = NL80211_BAND_5GHZ;
|
||||
+ }
|
||||
+
|
||||
+ if (idx >= rt2x00dev->bands[band].n_channels)
|
||||
return -ENOENT;
|
||||
|
||||
- survey->channel = conf->chandef.chan;
|
||||
+ if (idx == 0)
|
||||
+ rt2800_update_survey(rt2x00dev);
|
||||
|
||||
- idle = rt2800_register_read(rt2x00dev, CH_IDLE_STA);
|
||||
- busy = rt2800_register_read(rt2x00dev, CH_BUSY_STA);
|
||||
- busy_ext = rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC);
|
||||
-
|
||||
- if (idle || busy) {
|
||||
- survey->filled = SURVEY_INFO_TIME |
|
||||
- SURVEY_INFO_TIME_BUSY |
|
||||
- SURVEY_INFO_TIME_EXT_BUSY;
|
||||
-
|
||||
- survey->time = (idle + busy) / 1000;
|
||||
- survey->time_busy = busy / 1000;
|
||||
- survey->time_ext_busy = busy_ext / 1000;
|
||||
- }
|
||||
+ survey->channel = &rt2x00dev->bands[band].channels[idx];
|
||||
+
|
||||
+ survey->filled = SURVEY_INFO_TIME |
|
||||
+ SURVEY_INFO_TIME_BUSY |
|
||||
+ SURVEY_INFO_TIME_EXT_BUSY;
|
||||
+
|
||||
+ survey->time = div_u64(chan_survey->time_idle + chan_survey->time_busy, 1000);
|
||||
+ survey->time_busy = div_u64(chan_survey->time_busy, 1000);
|
||||
+ survey->time_ext_busy = div_u64(chan_survey->time_ext_busy, 1000);
|
||||
|
||||
if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
|
||||
survey->filled |= SURVEY_INFO_IN_USE;
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
@@ -243,6 +243,7 @@ bool rt2800_txstatus_timeout(struct rt2x
|
||||
bool rt2800_txstatus_pending(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
void rt2800_watchdog(struct rt2x00_dev *rt2x00dev);
|
||||
+void rt2800_update_survey(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
|
||||
void rt2800_clear_beacon(struct queue_entry *entry);
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
|
||||
@@ -360,6 +360,7 @@ static const struct rt2x00lib_ops rt2800
|
||||
.gain_calibration = rt2800_gain_calibration,
|
||||
.vco_calibration = rt2800_vco_calibration,
|
||||
.watchdog = rt2800_watchdog,
|
||||
+ .update_survey = rt2800_update_survey,
|
||||
.start_queue = rt2800mmio_start_queue,
|
||||
.kick_queue = rt2800mmio_kick_queue,
|
||||
.stop_queue = rt2800mmio_stop_queue,
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
@@ -214,6 +214,7 @@ static const struct rt2x00lib_ops rt2800
|
||||
.gain_calibration = rt2800_gain_calibration,
|
||||
.vco_calibration = rt2800_vco_calibration,
|
||||
.watchdog = rt2800_watchdog,
|
||||
+ .update_survey = rt2800_update_survey,
|
||||
.start_queue = rt2800mmio_start_queue,
|
||||
.kick_queue = rt2800mmio_kick_queue,
|
||||
.stop_queue = rt2800mmio_stop_queue,
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
@@ -183,6 +183,15 @@ struct rf_channel {
|
||||
};
|
||||
|
||||
/*
|
||||
+ * Information structure for channel survey.
|
||||
+ */
|
||||
+struct rt2x00_chan_survey {
|
||||
+ u64 time_idle;
|
||||
+ u64 time_busy;
|
||||
+ u64 time_ext_busy;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
* Channel information structure
|
||||
*/
|
||||
struct channel_info {
|
||||
@@ -567,6 +576,7 @@ struct rt2x00lib_ops {
|
||||
* Data queue handlers.
|
||||
*/
|
||||
void (*watchdog) (struct rt2x00_dev *rt2x00dev);
|
||||
+ void (*update_survey) (struct rt2x00_dev *rt2x00dev);
|
||||
void (*start_queue) (struct data_queue *queue);
|
||||
void (*kick_queue) (struct data_queue *queue);
|
||||
void (*stop_queue) (struct data_queue *queue);
|
||||
@@ -755,6 +765,7 @@ struct rt2x00_dev {
|
||||
*/
|
||||
struct ieee80211_hw *hw;
|
||||
struct ieee80211_supported_band bands[NUM_NL80211_BANDS];
|
||||
+ struct rt2x00_chan_survey *chan_survey;
|
||||
enum nl80211_band curr_band;
|
||||
int curr_freq;
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1054,6 +1054,12 @@ static int rt2x00lib_probe_hw_modes(stru
|
||||
if (!rates)
|
||||
goto exit_free_channels;
|
||||
|
||||
+ rt2x00dev->chan_survey =
|
||||
+ kcalloc(spec->num_channels, sizeof(struct rt2x00_chan_survey),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!rt2x00dev->chan_survey)
|
||||
+ goto exit_free_rates;
|
||||
+
|
||||
/*
|
||||
* Initialize Rate list.
|
||||
*/
|
||||
@@ -1105,6 +1111,8 @@ static int rt2x00lib_probe_hw_modes(stru
|
||||
|
||||
return 0;
|
||||
|
||||
+ exit_free_rates:
|
||||
+ kfree(rates);
|
||||
exit_free_channels:
|
||||
kfree(channels);
|
||||
rt2x00_err(rt2x00dev, "Allocation ieee80211 modes failed\n");
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
|
||||
@@ -317,6 +317,15 @@ int rt2x00mac_config(struct ieee80211_hw
|
||||
return 0;
|
||||
|
||||
/*
|
||||
+ * To provide correct survey data for survey-based ACS algorithm
|
||||
+ * we have to save survey data for current channel before switching.
|
||||
+ */
|
||||
+ if (rt2x00dev->ops->lib->update_survey &&
|
||||
+ (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
|
||||
+ rt2x00dev->ops->lib->update_survey(rt2x00dev);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* Some configuration parameters (e.g. channel and antenna values) can
|
||||
* only be set when the radio is enabled, but do require the RX to
|
||||
* be off. During this period we should keep link tuning enabled,
|
@ -1,123 +0,0 @@
|
||||
From: Ramon Fontes <ramonreisfontes@gmail.com>
|
||||
Date: Sun, 27 Dec 2020 00:11:55 -0300
|
||||
Subject: [PATCH] mac80211_hwsim: add 6GHz channels
|
||||
|
||||
Advertise 6GHz channels to mac80211.
|
||||
|
||||
Signed-off-by: Ramon Fontes <ramonreisfontes@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20201227031155.81161-1-ramonreisfontes@gmail.com
|
||||
[reword commit message]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/mac80211_hwsim.c
|
||||
+++ b/drivers/net/wireless/mac80211_hwsim.c
|
||||
@@ -311,6 +311,12 @@ static struct net_device *hwsim_mon; /*
|
||||
.hw_value = (_freq), \
|
||||
}
|
||||
|
||||
+#define CHAN6G(_freq) { \
|
||||
+ .band = NL80211_BAND_6GHZ, \
|
||||
+ .center_freq = (_freq), \
|
||||
+ .hw_value = (_freq), \
|
||||
+}
|
||||
+
|
||||
static const struct ieee80211_channel hwsim_channels_2ghz[] = {
|
||||
CHAN2G(2412), /* Channel 1 */
|
||||
CHAN2G(2417), /* Channel 2 */
|
||||
@@ -377,6 +383,68 @@ static const struct ieee80211_channel hw
|
||||
CHAN5G(5925), /* Channel 185 */
|
||||
};
|
||||
|
||||
+static const struct ieee80211_channel hwsim_channels_6ghz[] = {
|
||||
+ CHAN6G(5955), /* Channel 1 */
|
||||
+ CHAN6G(5975), /* Channel 5 */
|
||||
+ CHAN6G(5995), /* Channel 9 */
|
||||
+ CHAN6G(6015), /* Channel 13 */
|
||||
+ CHAN6G(6035), /* Channel 17 */
|
||||
+ CHAN6G(6055), /* Channel 21 */
|
||||
+ CHAN6G(6075), /* Channel 25 */
|
||||
+ CHAN6G(6095), /* Channel 29 */
|
||||
+ CHAN6G(6115), /* Channel 33 */
|
||||
+ CHAN6G(6135), /* Channel 37 */
|
||||
+ CHAN6G(6155), /* Channel 41 */
|
||||
+ CHAN6G(6175), /* Channel 45 */
|
||||
+ CHAN6G(6195), /* Channel 49 */
|
||||
+ CHAN6G(6215), /* Channel 53 */
|
||||
+ CHAN6G(6235), /* Channel 57 */
|
||||
+ CHAN6G(6255), /* Channel 61 */
|
||||
+ CHAN6G(6275), /* Channel 65 */
|
||||
+ CHAN6G(6295), /* Channel 69 */
|
||||
+ CHAN6G(6315), /* Channel 73 */
|
||||
+ CHAN6G(6335), /* Channel 77 */
|
||||
+ CHAN6G(6355), /* Channel 81 */
|
||||
+ CHAN6G(6375), /* Channel 85 */
|
||||
+ CHAN6G(6395), /* Channel 89 */
|
||||
+ CHAN6G(6415), /* Channel 93 */
|
||||
+ CHAN6G(6435), /* Channel 97 */
|
||||
+ CHAN6G(6455), /* Channel 181 */
|
||||
+ CHAN6G(6475), /* Channel 105 */
|
||||
+ CHAN6G(6495), /* Channel 109 */
|
||||
+ CHAN6G(6515), /* Channel 113 */
|
||||
+ CHAN6G(6535), /* Channel 117 */
|
||||
+ CHAN6G(6555), /* Channel 121 */
|
||||
+ CHAN6G(6575), /* Channel 125 */
|
||||
+ CHAN6G(6595), /* Channel 129 */
|
||||
+ CHAN6G(6615), /* Channel 133 */
|
||||
+ CHAN6G(6635), /* Channel 137 */
|
||||
+ CHAN6G(6655), /* Channel 141 */
|
||||
+ CHAN6G(6675), /* Channel 145 */
|
||||
+ CHAN6G(6695), /* Channel 149 */
|
||||
+ CHAN6G(6715), /* Channel 153 */
|
||||
+ CHAN6G(6735), /* Channel 157 */
|
||||
+ CHAN6G(6755), /* Channel 161 */
|
||||
+ CHAN6G(6775), /* Channel 165 */
|
||||
+ CHAN6G(6795), /* Channel 169 */
|
||||
+ CHAN6G(6815), /* Channel 173 */
|
||||
+ CHAN6G(6835), /* Channel 177 */
|
||||
+ CHAN6G(6855), /* Channel 181 */
|
||||
+ CHAN6G(6875), /* Channel 185 */
|
||||
+ CHAN6G(6895), /* Channel 189 */
|
||||
+ CHAN6G(6915), /* Channel 193 */
|
||||
+ CHAN6G(6935), /* Channel 197 */
|
||||
+ CHAN6G(6955), /* Channel 201 */
|
||||
+ CHAN6G(6975), /* Channel 205 */
|
||||
+ CHAN6G(6995), /* Channel 209 */
|
||||
+ CHAN6G(7015), /* Channel 213 */
|
||||
+ CHAN6G(7035), /* Channel 217 */
|
||||
+ CHAN6G(7055), /* Channel 221 */
|
||||
+ CHAN6G(7075), /* Channel 225 */
|
||||
+ CHAN6G(7095), /* Channel 229 */
|
||||
+ CHAN6G(7115), /* Channel 233 */
|
||||
+};
|
||||
+
|
||||
#define NUM_S1G_CHANS_US 51
|
||||
static struct ieee80211_channel hwsim_channels_s1g[NUM_S1G_CHANS_US];
|
||||
|
||||
@@ -548,6 +616,7 @@ struct mac80211_hwsim_data {
|
||||
struct ieee80211_supported_band bands[NUM_NL80211_BANDS];
|
||||
struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)];
|
||||
struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
|
||||
+ struct ieee80211_channel channels_6ghz[ARRAY_SIZE(hwsim_channels_6ghz)];
|
||||
struct ieee80211_channel channels_s1g[ARRAY_SIZE(hwsim_channels_s1g)];
|
||||
struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
|
||||
struct ieee80211_iface_combination if_combination;
|
||||
@@ -579,7 +648,8 @@ struct mac80211_hwsim_data {
|
||||
struct ieee80211_channel *channel;
|
||||
unsigned long next_start, start, end;
|
||||
} survey_data[ARRAY_SIZE(hwsim_channels_2ghz) +
|
||||
- ARRAY_SIZE(hwsim_channels_5ghz)];
|
||||
+ ARRAY_SIZE(hwsim_channels_5ghz) +
|
||||
+ ARRAY_SIZE(hwsim_channels_6ghz)];
|
||||
|
||||
struct ieee80211_channel *channel;
|
||||
u64 beacon_int /* beacon interval in us */;
|
||||
@@ -3172,6 +3242,8 @@ static int mac80211_hwsim_new_radio(stru
|
||||
sizeof(hwsim_channels_2ghz));
|
||||
memcpy(data->channels_5ghz, hwsim_channels_5ghz,
|
||||
sizeof(hwsim_channels_5ghz));
|
||||
+ memcpy(data->channels_6ghz, hwsim_channels_6ghz,
|
||||
+ sizeof(hwsim_channels_6ghz));
|
||||
memcpy(data->channels_s1g, hwsim_channels_s1g,
|
||||
sizeof(hwsim_channels_s1g));
|
||||
memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
|
@ -1,17 +0,0 @@
|
||||
--- a/drivers/net/wireless/broadcom/b43/main.c
|
||||
+++ b/drivers/net/wireless/broadcom/b43/main.c
|
||||
@@ -2886,6 +2886,14 @@ static int b43_gpio_init(struct b43_wlde
|
||||
} else if (dev->dev->chip_id == 0x5354) {
|
||||
/* Don't allow overtaking buttons GPIOs */
|
||||
set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */
|
||||
+ } else if (dev->dev->chip_id == BCMA_CHIP_ID_BCM4716 ||
|
||||
+ dev->dev->chip_id == BCMA_CHIP_ID_BCM47162 ||
|
||||
+ dev->dev->chip_id == BCMA_CHIP_ID_BCM5356 ||
|
||||
+ dev->dev->chip_id == BCMA_CHIP_ID_BCM5357 ||
|
||||
+ dev->dev->chip_id == BCMA_CHIP_ID_BCM53572) {
|
||||
+ /* just use gpio 0 and 1 for 2.4 GHz wifi led */
|
||||
+ set &= 0x3;
|
||||
+ mask &= 0x3;
|
||||
}
|
||||
|
||||
if (0 /* FIXME: conditional unknown */ ) {
|
@ -1,34 +0,0 @@
|
||||
--- a/compat/main.c
|
||||
+++ b/compat/main.c
|
||||
@@ -20,31 +20,6 @@ MODULE_LICENSE("GPL");
|
||||
#error "You need a CPTCFG_VERSION"
|
||||
#endif
|
||||
|
||||
-static char *backported_kernel_name = CPTCFG_KERNEL_NAME;
|
||||
-
|
||||
-module_param(backported_kernel_name, charp, 0400);
|
||||
-MODULE_PARM_DESC(backported_kernel_name,
|
||||
- "The kernel tree name that was used for this backport (" CPTCFG_KERNEL_NAME ")");
|
||||
-
|
||||
-#ifdef BACKPORTS_GIT_TRACKED
|
||||
-static char *backports_tracker_id = BACKPORTS_GIT_TRACKED;
|
||||
-module_param(backports_tracker_id, charp, 0400);
|
||||
-MODULE_PARM_DESC(backports_tracker_id,
|
||||
- "The version of the tree containing this backport (" BACKPORTS_GIT_TRACKED ")");
|
||||
-#else
|
||||
-static char *backported_kernel_version = CPTCFG_KERNEL_VERSION;
|
||||
-static char *backports_version = CPTCFG_VERSION;
|
||||
-
|
||||
-module_param(backported_kernel_version, charp, 0400);
|
||||
-MODULE_PARM_DESC(backported_kernel_version,
|
||||
- "The kernel version that was used for this backport (" CPTCFG_KERNEL_VERSION ")");
|
||||
-
|
||||
-module_param(backports_version, charp, 0400);
|
||||
-MODULE_PARM_DESC(backports_version,
|
||||
- "The git version of the backports tree used to generate this backport (" CPTCFG_VERSION ")");
|
||||
-
|
||||
-#endif
|
||||
-
|
||||
void backport_dependency_symbol(void)
|
||||
{
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/net/wireless/broadcom/b43/main.c
|
||||
+++ b/drivers/net/wireless/broadcom/b43/main.c
|
||||
@@ -114,7 +114,7 @@ static int b43_modparam_pio = 0;
|
||||
module_param_named(pio, b43_modparam_pio, int, 0644);
|
||||
MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
|
||||
|
||||
-static int modparam_allhwsupport = !IS_ENABLED(CPTCFG_BRCMSMAC);
|
||||
+static int modparam_allhwsupport = 1;
|
||||
module_param_named(allhwsupport, modparam_allhwsupport, int, 0444);
|
||||
MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)");
|
||||
|
@ -1,148 +0,0 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Fri, 9 Apr 2021 12:40:20 +0300
|
||||
Subject: [PATCH] wireless: align HE capabilities A-MPDU Length Exponent
|
||||
Extension
|
||||
|
||||
The A-MPDU length exponent extension is defined differently in
|
||||
802.11ax D6.1, align with that.
|
||||
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20210409123755.c2a257d3e2df.I3455245d388c52c61dace7e7958dbed7e807cfb6@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -1290,9 +1290,8 @@ static void ath11k_peer_assoc_h_he(struc
|
||||
* request, then use MAX_AMPDU_LEN_FACTOR as 16 to calculate max_ampdu
|
||||
* length.
|
||||
*/
|
||||
- ampdu_factor = (he_cap->he_cap_elem.mac_cap_info[3] &
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) >>
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_SHIFT;
|
||||
+ ampdu_factor = u8_get_bits(he_cap->he_cap_elem.mac_cap_info[3],
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK);
|
||||
|
||||
if (ampdu_factor) {
|
||||
if (sta->vht_cap.vht_supported)
|
||||
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
@@ -596,7 +596,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2,
|
||||
.mac_cap_info[4] =
|
||||
IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU |
|
||||
IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39,
|
||||
@@ -680,7 +680,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
IEEE80211_HE_MAC_CAP2_BSR,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2,
|
||||
.mac_cap_info[4] =
|
||||
IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.mac_cap_info[5] =
|
||||
--- a/drivers/net/wireless/mac80211_hwsim.c
|
||||
+++ b/drivers/net/wireless/mac80211_hwsim.c
|
||||
@@ -2817,7 +2817,7 @@ static const struct ieee80211_sband_ifty
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
|
||||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
|
||||
@@ -2861,7 +2861,7 @@ static const struct ieee80211_sband_ifty
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
|
||||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
|
||||
@@ -2907,7 +2907,7 @@ static const struct ieee80211_sband_ifty
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
|
||||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
@@ -2955,7 +2955,7 @@ static const struct ieee80211_sband_ifty
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
|
||||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
@@ -425,7 +425,7 @@ mt7915_init_he_caps(struct mt7915_phy *p
|
||||
IEEE80211_HE_MAC_CAP0_HTC_HE;
|
||||
he_cap_elem->mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED;
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3;
|
||||
he_cap_elem->mac_cap_info[4] =
|
||||
IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU;
|
||||
|
||||
--- a/include/linux/ieee80211.h
|
||||
+++ b/include/linux/ieee80211.h
|
||||
@@ -2051,17 +2051,15 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
* A-MDPU Length Exponent field in the HT capabilities, VHT capabilities and the
|
||||
* same field in the HE capabilities.
|
||||
*/
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_USE_VHT 0x00
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_1 0x08
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2 0x10
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED 0x18
|
||||
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_0 0x00
|
||||
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1 0x08
|
||||
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2 0x10
|
||||
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3 0x18
|
||||
#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK 0x18
|
||||
#define IEEE80211_HE_MAC_CAP3_AMSDU_FRAG 0x20
|
||||
#define IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED 0x40
|
||||
#define IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS 0x80
|
||||
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_SHIFT 3
|
||||
-
|
||||
#define IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG 0x01
|
||||
#define IEEE80211_HE_MAC_CAP4_QTP 0x02
|
||||
#define IEEE80211_HE_MAC_CAP4_BQR 0x04
|
||||
--- a/net/mac80211/debugfs_sta.c
|
||||
+++ b/net/mac80211/debugfs_sta.c
|
||||
@@ -711,17 +711,17 @@ static ssize_t sta_he_capa_read(struct f
|
||||
PFLAG(MAC, 3, OFDMA_RA, "OFDMA-RA");
|
||||
|
||||
switch (cap[3] & IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) {
|
||||
- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_USE_VHT:
|
||||
- PRINT("MAX-AMPDU-LEN-EXP-USE-VHT");
|
||||
+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_0:
|
||||
+ PRINT("MAX-AMPDU-LEN-EXP-USE-EXT-0");
|
||||
break;
|
||||
- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_1:
|
||||
- PRINT("MAX-AMPDU-LEN-EXP-VHT-1");
|
||||
+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1:
|
||||
+ PRINT("MAX-AMPDU-LEN-EXP-VHT-EXT-1");
|
||||
break;
|
||||
- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2:
|
||||
- PRINT("MAX-AMPDU-LEN-EXP-VHT-2");
|
||||
+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2:
|
||||
+ PRINT("MAX-AMPDU-LEN-EXP-VHT-EXT-2");
|
||||
break;
|
||||
- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED:
|
||||
- PRINT("MAX-AMPDU-LEN-EXP-RESERVED");
|
||||
+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3:
|
||||
+ PRINT("MAX-AMPDU-LEN-EXP-VHT-EXT-3");
|
||||
break;
|
||||
}
|
||||
|
@ -1,186 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.h
|
||||
@@ -723,6 +723,7 @@ struct ath_spec_scan {
|
||||
* @config_pci_powersave:
|
||||
* @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
|
||||
*
|
||||
+ * @get_adc_entropy: get entropy from the raw ADC I/Q output
|
||||
* @spectral_scan_config: set parameters for spectral scan and enable/disable it
|
||||
* @spectral_scan_trigger: trigger a spectral scan run
|
||||
* @spectral_scan_wait: wait for a spectral scan run to finish
|
||||
@@ -745,6 +746,7 @@ struct ath_hw_ops {
|
||||
struct ath_hw_antcomb_conf *antconf);
|
||||
void (*antdiv_comb_conf_set)(struct ath_hw *ah,
|
||||
struct ath_hw_antcomb_conf *antconf);
|
||||
+ void (*get_adc_entropy)(struct ath_hw *ah, u8 *buf, size_t len);
|
||||
void (*spectral_scan_config)(struct ath_hw *ah,
|
||||
struct ath_spec_scan *param);
|
||||
void (*spectral_scan_trigger)(struct ath_hw *ah);
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
@@ -1927,6 +1927,26 @@ void ar9003_hw_init_rate_txpower(struct
|
||||
}
|
||||
}
|
||||
|
||||
+static void ar9003_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len)
|
||||
+{
|
||||
+ int i, j;
|
||||
+
|
||||
+ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1);
|
||||
+ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5);
|
||||
+ REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0);
|
||||
+
|
||||
+ memset(buf, 0, len);
|
||||
+ for (i = 0; i < len; i++) {
|
||||
+ for (j = 0; j < 4; j++) {
|
||||
+ u32 regval = REG_READ(ah, AR_PHY_TST_ADC);
|
||||
+
|
||||
+ buf[i] <<= 2;
|
||||
+ buf[i] |= (regval & 1) | ((regval & BIT(10)) >> 9);
|
||||
+ udelay(1);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
@@ -1963,6 +1983,7 @@ void ar9003_hw_attach_phy_ops(struct ath
|
||||
priv_ops->set_radar_params = ar9003_hw_set_radar_params;
|
||||
priv_ops->fast_chan_change = ar9003_hw_fast_chan_change;
|
||||
|
||||
+ ops->get_adc_entropy = ar9003_hw_get_adc_entropy;
|
||||
ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
|
||||
ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
|
||||
ops->spectral_scan_config = ar9003_hw_spectral_scan_config;
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -815,7 +815,8 @@ static void ath9k_init_txpower_limits(st
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
|
||||
ath9k_init_band_txpower(sc, NL80211_BAND_5GHZ);
|
||||
|
||||
- ah->curchan = curchan;
|
||||
+ if (curchan)
|
||||
+ ah->curchan = curchan;
|
||||
}
|
||||
|
||||
static const struct ieee80211_iface_limit if_limits[] = {
|
||||
@@ -1012,6 +1013,18 @@ static void ath9k_set_hw_capab(struct at
|
||||
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
|
||||
}
|
||||
|
||||
+static void ath_get_initial_entropy(struct ath_softc *sc)
|
||||
+{
|
||||
+ struct ath_hw *ah = sc->sc_ah;
|
||||
+ char buf[256];
|
||||
+
|
||||
+ /* reuse last channel initialized by the tx power test */
|
||||
+ ath9k_hw_reset(ah, ah->curchan, NULL, false);
|
||||
+
|
||||
+ ath9k_hw_get_adc_entropy(ah, buf, sizeof(buf));
|
||||
+ add_device_randomness(buf, sizeof(buf));
|
||||
+}
|
||||
+
|
||||
int ath9k_init_device(u16 devid, struct ath_softc *sc,
|
||||
const struct ath_bus_ops *bus_ops)
|
||||
{
|
||||
@@ -1057,6 +1070,8 @@ int ath9k_init_device(u16 devid, struct
|
||||
ARRAY_SIZE(ath9k_tpt_blink));
|
||||
#endif
|
||||
|
||||
+ ath_get_initial_entropy(sc);
|
||||
+
|
||||
/* Register with mac80211 */
|
||||
error = ieee80211_register_hw(hw);
|
||||
if (error)
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
|
||||
@@ -100,6 +100,12 @@ static inline void ath9k_hw_tx99_set_txp
|
||||
ath9k_hw_ops(ah)->tx99_set_txpower(ah, power);
|
||||
}
|
||||
|
||||
+static inline void ath9k_hw_get_adc_entropy(struct ath_hw *ah,
|
||||
+ u8 *buf, size_t len)
|
||||
+{
|
||||
+ ath9k_hw_ops(ah)->get_adc_entropy(ah, buf, len);
|
||||
+}
|
||||
+
|
||||
#ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT
|
||||
|
||||
static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
|
||||
@@ -1349,9 +1349,30 @@ void ar5008_hw_init_rate_txpower(struct
|
||||
}
|
||||
}
|
||||
|
||||
+static void ar5008_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len)
|
||||
+{
|
||||
+ int i, j;
|
||||
+
|
||||
+ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1);
|
||||
+ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5);
|
||||
+ REG_RMW_FIELD(ah, AR_PHY_TEST2, AR_PHY_TEST2_RX_OBS_SEL, 0);
|
||||
+
|
||||
+ memset(buf, 0, len);
|
||||
+ for (i = 0; i < len; i++) {
|
||||
+ for (j = 0; j < 4; j++) {
|
||||
+ u32 regval = REG_READ(ah, AR_PHY_TST_ADC);
|
||||
+
|
||||
+ buf[i] <<= 2;
|
||||
+ buf[i] |= (regval & 1) | ((regval & BIT(9)) >> 8);
|
||||
+ udelay(1);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int ar5008_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
+ struct ath_hw_ops *ops = ath9k_hw_ops(ah);
|
||||
static const u32 ar5416_cca_regs[6] = {
|
||||
AR_PHY_CCA,
|
||||
AR_PHY_CH1_CCA,
|
||||
@@ -1366,6 +1387,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ ops->get_adc_entropy = ar5008_hw_get_adc_entropy;
|
||||
+
|
||||
priv_ops->rf_set_freq = ar5008_hw_set_channel;
|
||||
priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
|
||||
@@ -20,6 +20,12 @@
|
||||
#define PHY_AGC_CLR 0x10000000
|
||||
#define RFSILENT_BB 0x00002000
|
||||
|
||||
+#define AR_PHY_TEST_BBB_OBS_SEL 0x780000
|
||||
+#define AR_PHY_TEST_BBB_OBS_SEL_S 19
|
||||
+
|
||||
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23
|
||||
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5 (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S)
|
||||
+
|
||||
#define AR_PHY_TURBO 0x9804
|
||||
#define AR_PHY_FC_TURBO_MODE 0x00000001
|
||||
#define AR_PHY_FC_TURBO_SHORT 0x00000002
|
||||
@@ -36,6 +42,9 @@
|
||||
|
||||
#define AR_PHY_TEST2 0x9808
|
||||
|
||||
+#define AR_PHY_TEST2_RX_OBS_SEL 0x3C00
|
||||
+#define AR_PHY_TEST2_RX_OBS_SEL_S 10
|
||||
+
|
||||
#define AR_PHY_TIMING2 0x9810
|
||||
#define AR_PHY_TIMING3 0x9814
|
||||
#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
|
||||
@@ -393,6 +402,8 @@
|
||||
#define AR_PHY_RFBUS_GRANT 0x9C20
|
||||
#define AR_PHY_RFBUS_GRANT_EN 0x00000001
|
||||
|
||||
+#define AR_PHY_TST_ADC 0x9C24
|
||||
+
|
||||
#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4
|
||||
#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
|
||||
|
@ -1,12 +0,0 @@
|
||||
Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1307,7 +1307,6 @@ static int ieee80211_stop_ap(struct wiph
|
||||
sdata->vif.bss_conf.ftmr_params = NULL;
|
||||
|
||||
__sta_info_flush(sdata, true);
|
||||
- ieee80211_free_keys(sdata, true);
|
||||
|
||||
sdata->vif.bss_conf.enable_beacon = false;
|
||||
sdata->beacon_rate_set = false;
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/net/wireless/broadcom/b43/dma.h
|
||||
+++ b/drivers/net/wireless/broadcom/b43/dma.h
|
||||
@@ -170,7 +170,7 @@ struct b43_dmadesc_generic {
|
||||
|
||||
/* DMA engine tuning knobs */
|
||||
#define B43_TXRING_SLOTS 256
|
||||
-#define B43_RXRING_SLOTS 256
|
||||
+#define B43_RXRING_SLOTS 32
|
||||
#define B43_DMA0_RX_FW598_BUFSIZE (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN)
|
||||
#define B43_DMA0_RX_FW351_BUFSIZE (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN)
|
||||
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -827,6 +827,7 @@ static const struct ieee80211_iface_limi
|
||||
BIT(NL80211_IFTYPE_AP) },
|
||||
{ .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO) },
|
||||
+ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
|
||||
};
|
||||
|
||||
#ifdef CPTCFG_WIRELESS_WDS
|
@ -1,19 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1013,6 +1013,16 @@ static int rt2x00lib_probe_hw_modes(stru
|
||||
struct ieee80211_rate *rates;
|
||||
unsigned int num_rates;
|
||||
unsigned int i;
|
||||
+#ifdef CONFIG_OF
|
||||
+ struct device_node *np = rt2x00dev->dev->of_node;
|
||||
+ unsigned int enabled;
|
||||
+ if (!of_property_read_u32(np, "ralink,2ghz",
|
||||
+ &enabled) && !enabled)
|
||||
+ spec->supported_bands &= ~SUPPORT_BAND_2GHZ;
|
||||
+ if (!of_property_read_u32(np, "ralink,5ghz",
|
||||
+ &enabled) && !enabled)
|
||||
+ spec->supported_bands &= ~SUPPORT_BAND_5GHZ;
|
||||
+#endif /* CONFIG_OF */
|
||||
|
||||
if (rt2x00dev->dev->platform_data) {
|
||||
struct rt2x00_platform_data *pdata;
|
@ -1,67 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 26 Dec 2020 19:08:19 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: improve ampdu length estimation
|
||||
|
||||
If the driver does not report A-MPDU length, estimate it based on the rate.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -382,13 +382,37 @@ minstrel_get_ratestats(struct minstrel_h
|
||||
return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES];
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+minstrel_get_duration(int index)
|
||||
+{
|
||||
+ const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
|
||||
+ unsigned int duration = group->duration[index % MCS_GROUP_RATES];
|
||||
+ return duration << group->shift;
|
||||
+}
|
||||
+
|
||||
static unsigned int
|
||||
minstrel_ht_avg_ampdu_len(struct minstrel_ht_sta *mi)
|
||||
{
|
||||
- if (!mi->avg_ampdu_len)
|
||||
- return AVG_AMPDU_SIZE;
|
||||
+ int duration;
|
||||
+
|
||||
+ if (mi->avg_ampdu_len)
|
||||
+ return MINSTREL_TRUNC(mi->avg_ampdu_len);
|
||||
+
|
||||
+ if (minstrel_ht_is_legacy_group(mi->max_tp_rate[0] / MCS_GROUP_RATES))
|
||||
+ return 1;
|
||||
+
|
||||
+ duration = minstrel_get_duration(mi->max_tp_rate[0]);
|
||||
|
||||
- return MINSTREL_TRUNC(mi->avg_ampdu_len);
|
||||
+ if (duration > 400 * 1000)
|
||||
+ return 2;
|
||||
+
|
||||
+ if (duration > 250 * 1000)
|
||||
+ return 4;
|
||||
+
|
||||
+ if (duration > 150 * 1000)
|
||||
+ return 8;
|
||||
+
|
||||
+ return 16;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -588,14 +612,6 @@ minstrel_ht_prob_rate_reduce_streams(str
|
||||
}
|
||||
}
|
||||
|
||||
-static inline int
|
||||
-minstrel_get_duration(int index)
|
||||
-{
|
||||
- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
|
||||
- unsigned int duration = group->duration[index % MCS_GROUP_RATES];
|
||||
- return duration << group->shift;
|
||||
-}
|
||||
-
|
||||
static bool
|
||||
minstrel_ht_probe_group(struct minstrel_ht_sta *mi, const struct mcs_group *tp_group,
|
||||
int tp_idx, const struct mcs_group *group)
|
@ -1,279 +0,0 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Sun, 6 Dec 2020 14:54:42 +0200
|
||||
Subject: [PATCH] cfg80211: support immediate reconnect request hint
|
||||
|
||||
There are cases where it's necessary to disconnect, but an
|
||||
immediate reconnection is desired. Support a hint to userspace
|
||||
that this is the case, by including a new attribute in the
|
||||
deauth or disassoc event.
|
||||
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20201206145305.58d33941fb9d.I0e7168c205c7949529c8e3b86f3c9b12c01a7017@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -6410,13 +6410,15 @@ void cfg80211_abandon_assoc(struct net_d
|
||||
* @dev: network device
|
||||
* @buf: 802.11 frame (header + body)
|
||||
* @len: length of the frame data
|
||||
+ * @reconnect: immediate reconnect is desired (include the nl80211 attribute)
|
||||
*
|
||||
* This function is called whenever deauthentication has been processed in
|
||||
* station mode. This includes both received deauthentication frames and
|
||||
* locally generated ones. This function may sleep. The caller must hold the
|
||||
* corresponding wdev's mutex.
|
||||
*/
|
||||
-void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len);
|
||||
+void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len,
|
||||
+ bool reconnect);
|
||||
|
||||
/**
|
||||
* cfg80211_rx_unprot_mlme_mgmt - notification of unprotected mlme mgmt frame
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -2725,7 +2725,7 @@ static void ieee80211_report_disconnect(
|
||||
};
|
||||
|
||||
if (tx)
|
||||
- cfg80211_tx_mlme_mgmt(sdata->dev, buf, len);
|
||||
+ cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, false);
|
||||
else
|
||||
cfg80211_rx_mlme_mgmt(sdata->dev, buf, len);
|
||||
|
||||
@@ -4719,7 +4719,8 @@ void ieee80211_mgd_quiesce(struct ieee80
|
||||
if (ifmgd->auth_data)
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
|
||||
- IEEE80211_DEAUTH_FRAME_LEN);
|
||||
+ IEEE80211_DEAUTH_FRAME_LEN,
|
||||
+ false);
|
||||
}
|
||||
|
||||
/* This is a bit of a hack - we should find a better and more generic
|
||||
--- a/net/wireless/mlme.c
|
||||
+++ b/net/wireless/mlme.c
|
||||
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2015 Intel Deutschland GmbH
|
||||
- * Copyright (C) 2019 Intel Corporation
|
||||
+ * Copyright (C) 2019-2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -81,7 +81,8 @@ static void cfg80211_process_auth(struct
|
||||
}
|
||||
|
||||
static void cfg80211_process_deauth(struct wireless_dev *wdev,
|
||||
- const u8 *buf, size_t len)
|
||||
+ const u8 *buf, size_t len,
|
||||
+ bool reconnect)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
|
||||
@@ -89,7 +90,7 @@ static void cfg80211_process_deauth(stru
|
||||
u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
|
||||
bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
|
||||
|
||||
- nl80211_send_deauth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
|
||||
+ nl80211_send_deauth(rdev, wdev->netdev, buf, len, reconnect, GFP_KERNEL);
|
||||
|
||||
if (!wdev->current_bss ||
|
||||
!ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
|
||||
@@ -100,7 +101,8 @@ static void cfg80211_process_deauth(stru
|
||||
}
|
||||
|
||||
static void cfg80211_process_disassoc(struct wireless_dev *wdev,
|
||||
- const u8 *buf, size_t len)
|
||||
+ const u8 *buf, size_t len,
|
||||
+ bool reconnect)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
|
||||
@@ -108,7 +110,8 @@ static void cfg80211_process_disassoc(st
|
||||
u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
|
||||
bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
|
||||
|
||||
- nl80211_send_disassoc(rdev, wdev->netdev, buf, len, GFP_KERNEL);
|
||||
+ nl80211_send_disassoc(rdev, wdev->netdev, buf, len, reconnect,
|
||||
+ GFP_KERNEL);
|
||||
|
||||
if (WARN_ON(!wdev->current_bss ||
|
||||
!ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
|
||||
@@ -133,9 +136,9 @@ void cfg80211_rx_mlme_mgmt(struct net_de
|
||||
if (ieee80211_is_auth(mgmt->frame_control))
|
||||
cfg80211_process_auth(wdev, buf, len);
|
||||
else if (ieee80211_is_deauth(mgmt->frame_control))
|
||||
- cfg80211_process_deauth(wdev, buf, len);
|
||||
+ cfg80211_process_deauth(wdev, buf, len, false);
|
||||
else if (ieee80211_is_disassoc(mgmt->frame_control))
|
||||
- cfg80211_process_disassoc(wdev, buf, len);
|
||||
+ cfg80211_process_disassoc(wdev, buf, len, false);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt);
|
||||
|
||||
@@ -180,22 +183,23 @@ void cfg80211_abandon_assoc(struct net_d
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_abandon_assoc);
|
||||
|
||||
-void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
|
||||
+void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len,
|
||||
+ bool reconnect)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct ieee80211_mgmt *mgmt = (void *)buf;
|
||||
|
||||
ASSERT_WDEV_LOCK(wdev);
|
||||
|
||||
- trace_cfg80211_tx_mlme_mgmt(dev, buf, len);
|
||||
+ trace_cfg80211_tx_mlme_mgmt(dev, buf, len, reconnect);
|
||||
|
||||
if (WARN_ON(len < 2))
|
||||
return;
|
||||
|
||||
if (ieee80211_is_deauth(mgmt->frame_control))
|
||||
- cfg80211_process_deauth(wdev, buf, len);
|
||||
+ cfg80211_process_deauth(wdev, buf, len, reconnect);
|
||||
else
|
||||
- cfg80211_process_disassoc(wdev, buf, len);
|
||||
+ cfg80211_process_disassoc(wdev, buf, len, reconnect);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt);
|
||||
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -736,6 +736,7 @@ static const struct nla_policy nl80211_p
|
||||
NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
|
||||
[NL80211_ATTR_S1G_CAPABILITY_MASK] =
|
||||
NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
|
||||
+ [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@@ -15902,7 +15903,7 @@ static void nl80211_send_mlme_event(stru
|
||||
const u8 *buf, size_t len,
|
||||
enum nl80211_commands cmd, gfp_t gfp,
|
||||
int uapsd_queues, const u8 *req_ies,
|
||||
- size_t req_ies_len)
|
||||
+ size_t req_ies_len, bool reconnect)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
@@ -15924,6 +15925,9 @@ static void nl80211_send_mlme_event(stru
|
||||
nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies)))
|
||||
goto nla_put_failure;
|
||||
|
||||
+ if (reconnect && nla_put_flag(msg, NL80211_ATTR_RECONNECT_REQUESTED))
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
if (uapsd_queues >= 0) {
|
||||
struct nlattr *nla_wmm =
|
||||
nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME);
|
||||
@@ -15952,7 +15956,8 @@ void nl80211_send_rx_auth(struct cfg8021
|
||||
size_t len, gfp_t gfp)
|
||||
{
|
||||
nl80211_send_mlme_event(rdev, netdev, buf, len,
|
||||
- NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0);
|
||||
+ NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0,
|
||||
+ false);
|
||||
}
|
||||
|
||||
void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
|
||||
@@ -15962,23 +15967,25 @@ void nl80211_send_rx_assoc(struct cfg802
|
||||
{
|
||||
nl80211_send_mlme_event(rdev, netdev, buf, len,
|
||||
NL80211_CMD_ASSOCIATE, gfp, uapsd_queues,
|
||||
- req_ies, req_ies_len);
|
||||
+ req_ies, req_ies_len, false);
|
||||
}
|
||||
|
||||
void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, const u8 *buf,
|
||||
- size_t len, gfp_t gfp)
|
||||
+ size_t len, bool reconnect, gfp_t gfp)
|
||||
{
|
||||
nl80211_send_mlme_event(rdev, netdev, buf, len,
|
||||
- NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0);
|
||||
+ NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0,
|
||||
+ reconnect);
|
||||
}
|
||||
|
||||
void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, const u8 *buf,
|
||||
- size_t len, gfp_t gfp)
|
||||
+ size_t len, bool reconnect, gfp_t gfp)
|
||||
{
|
||||
nl80211_send_mlme_event(rdev, netdev, buf, len,
|
||||
- NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0);
|
||||
+ NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0,
|
||||
+ reconnect);
|
||||
}
|
||||
|
||||
void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
|
||||
@@ -16009,7 +16016,7 @@ void cfg80211_rx_unprot_mlme_mgmt(struct
|
||||
|
||||
trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
|
||||
nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
|
||||
- NULL, 0);
|
||||
+ NULL, 0, false);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
|
||||
|
||||
--- a/net/wireless/nl80211.h
|
||||
+++ b/net/wireless/nl80211.h
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Portions of this file
|
||||
- * Copyright (C) 2018 Intel Corporation
|
||||
+ * Copyright (C) 2018, 2020 Intel Corporation
|
||||
*/
|
||||
#ifndef __NET_WIRELESS_NL80211_H
|
||||
#define __NET_WIRELESS_NL80211_H
|
||||
@@ -69,10 +69,12 @@ void nl80211_send_rx_assoc(struct cfg802
|
||||
const u8 *req_ies, size_t req_ies_len);
|
||||
void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev,
|
||||
- const u8 *buf, size_t len, gfp_t gfp);
|
||||
+ const u8 *buf, size_t len,
|
||||
+ bool reconnect, gfp_t gfp);
|
||||
void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev,
|
||||
- const u8 *buf, size_t len, gfp_t gfp);
|
||||
+ const u8 *buf, size_t len,
|
||||
+ bool reconnect, gfp_t gfp);
|
||||
void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev,
|
||||
const u8 *addr, gfp_t gfp);
|
||||
--- a/net/wireless/trace.h
|
||||
+++ b/net/wireless/trace.h
|
||||
@@ -2684,19 +2684,23 @@ DEFINE_EVENT(netdev_frame_event, cfg8021
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_tx_mlme_mgmt,
|
||||
- TP_PROTO(struct net_device *netdev, const u8 *buf, int len),
|
||||
- TP_ARGS(netdev, buf, len),
|
||||
+ TP_PROTO(struct net_device *netdev, const u8 *buf, int len,
|
||||
+ bool reconnect),
|
||||
+ TP_ARGS(netdev, buf, len, reconnect),
|
||||
TP_STRUCT__entry(
|
||||
NETDEV_ENTRY
|
||||
__dynamic_array(u8, frame, len)
|
||||
+ __field(int, reconnect)
|
||||
),
|
||||
TP_fast_assign(
|
||||
NETDEV_ASSIGN;
|
||||
memcpy(__get_dynamic_array(frame), buf, len);
|
||||
+ __entry->reconnect = reconnect;
|
||||
),
|
||||
- TP_printk(NETDEV_PR_FMT ", ftype:0x%.2x",
|
||||
+ TP_printk(NETDEV_PR_FMT ", ftype:0x%.2x reconnect:%d",
|
||||
NETDEV_PR_ARG,
|
||||
- le16_to_cpup((__le16 *)__get_dynamic_array(frame)))
|
||||
+ le16_to_cpup((__le16 *)__get_dynamic_array(frame)),
|
||||
+ __entry->reconnect)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(netdev_mac_evt,
|
@ -1,33 +0,0 @@
|
||||
--- /dev/null
|
||||
+++ b/include/linux/ath5k_platform.h
|
||||
@@ -0,0 +1,30 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2008 Atheros Communications Inc.
|
||||
+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
|
||||
+ * Copyright (c) 2010 Daniel Golle <daniel.golle@gmail.com>
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and/or distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LINUX_ATH5K_PLATFORM_H
|
||||
+#define _LINUX_ATH5K_PLATFORM_H
|
||||
+
|
||||
+#define ATH5K_PLAT_EEP_MAX_WORDS 2048
|
||||
+
|
||||
+struct ath5k_platform_data {
|
||||
+ u16 *eeprom_data;
|
||||
+ u8 *macaddr;
|
||||
+};
|
||||
+
|
||||
+#endif /* _LINUX_ATH5K_PLATFORM_H */
|
@ -1,114 +0,0 @@
|
||||
From: Ryder Lee <ryder.lee@mediatek.com>
|
||||
Date: Fri, 28 May 2021 14:05:41 +0800
|
||||
Subject: [PATCH] mac80211: call ieee80211_tx_h_rate_ctrl() when dequeue
|
||||
|
||||
Make ieee80211_tx_h_rate_ctrl() get called on dequeue to improve
|
||||
performance since it reduces the turnaround time for rate control.
|
||||
|
||||
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -1778,8 +1778,6 @@ static int invoke_tx_handlers_early(stru
|
||||
CALL_TXH(ieee80211_tx_h_ps_buf);
|
||||
CALL_TXH(ieee80211_tx_h_check_control_port_protocol);
|
||||
CALL_TXH(ieee80211_tx_h_select_key);
|
||||
- if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
|
||||
- CALL_TXH(ieee80211_tx_h_rate_ctrl);
|
||||
|
||||
txh_done:
|
||||
if (unlikely(res == TX_DROP)) {
|
||||
@@ -1812,6 +1810,9 @@ static int invoke_tx_handlers_late(struc
|
||||
goto txh_done;
|
||||
}
|
||||
|
||||
+ if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
|
||||
+ CALL_TXH(ieee80211_tx_h_rate_ctrl);
|
||||
+
|
||||
CALL_TXH(ieee80211_tx_h_michael_mic_add);
|
||||
CALL_TXH(ieee80211_tx_h_sequence);
|
||||
CALL_TXH(ieee80211_tx_h_fragment);
|
||||
@@ -3404,15 +3405,21 @@ out:
|
||||
* Can be called while the sta lock is held. Anything that can cause packets to
|
||||
* be generated will cause deadlock!
|
||||
*/
|
||||
-static void ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata,
|
||||
- struct sta_info *sta, u8 pn_offs,
|
||||
- struct ieee80211_key *key,
|
||||
- struct sk_buff *skb)
|
||||
+static ieee80211_tx_result
|
||||
+ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sta_info *sta, u8 pn_offs,
|
||||
+ struct ieee80211_key *key,
|
||||
+ struct ieee80211_tx_data *tx)
|
||||
{
|
||||
+ struct sk_buff *skb = tx->skb;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
u8 tid = IEEE80211_NUM_TIDS;
|
||||
|
||||
+ if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL) &&
|
||||
+ ieee80211_tx_h_rate_ctrl(tx) != TX_CONTINUE)
|
||||
+ return TX_DROP;
|
||||
+
|
||||
if (key)
|
||||
info->control.hw_key = &key->conf;
|
||||
|
||||
@@ -3461,6 +3468,8 @@ static void ieee80211_xmit_fast_finish(s
|
||||
break;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ return TX_CONTINUE;
|
||||
}
|
||||
|
||||
static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
||||
@@ -3564,24 +3573,17 @@ static bool ieee80211_xmit_fast(struct i
|
||||
tx.sta = sta;
|
||||
tx.key = fast_tx->key;
|
||||
|
||||
- if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) {
|
||||
- tx.skb = skb;
|
||||
- r = ieee80211_tx_h_rate_ctrl(&tx);
|
||||
- skb = tx.skb;
|
||||
- tx.skb = NULL;
|
||||
-
|
||||
- if (r != TX_CONTINUE) {
|
||||
- if (r != TX_QUEUED)
|
||||
- kfree_skb(skb);
|
||||
- return true;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
if (ieee80211_queue_skb(local, sdata, sta, skb))
|
||||
return true;
|
||||
|
||||
- ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs,
|
||||
- fast_tx->key, skb);
|
||||
+ tx.skb = skb;
|
||||
+ r = ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs,
|
||||
+ fast_tx->key, &tx);
|
||||
+ tx.skb = NULL;
|
||||
+ if (r == TX_DROP) {
|
||||
+ kfree_skb(skb);
|
||||
+ return true;
|
||||
+ }
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
sdata = container_of(sdata->bss,
|
||||
@@ -3692,8 +3694,12 @@ begin:
|
||||
(tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
|
||||
pn_offs = ieee80211_hdrlen(hdr->frame_control);
|
||||
|
||||
- ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs,
|
||||
- tx.key, skb);
|
||||
+ r = ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs,
|
||||
+ tx.key, &tx);
|
||||
+ if (r != TX_CONTINUE) {
|
||||
+ ieee80211_free_txskb(&local->hw, skb);
|
||||
+ goto begin;
|
||||
+ }
|
||||
} else {
|
||||
if (invoke_tx_handlers_late(&tx))
|
||||
goto begin;
|
@ -1,86 +0,0 @@
|
||||
--- a/drivers/net/wireless/broadcom/b43/Makefile
|
||||
+++ b/drivers/net/wireless/broadcom/b43/Makefile
|
||||
@@ -18,7 +18,7 @@ b43-$(CPTCFG_B43_PHY_AC) += phy_ac.o
|
||||
b43-y += sysfs.o
|
||||
b43-y += xmit.o
|
||||
b43-y += dma.o
|
||||
-b43-y += pio.o
|
||||
+b43-$(CPTCFG_B43_PIO) += pio.o
|
||||
b43-y += rfkill.o
|
||||
b43-y += ppr.o
|
||||
b43-$(CPTCFG_B43_LEDS) += leds.o
|
||||
--- a/drivers/net/wireless/broadcom/b43/main.c
|
||||
+++ b/drivers/net/wireless/broadcom/b43/main.c
|
||||
@@ -2001,10 +2001,12 @@ static void b43_do_interrupt_thread(stru
|
||||
dma_reason[0], dma_reason[1],
|
||||
dma_reason[2], dma_reason[3],
|
||||
dma_reason[4], dma_reason[5]);
|
||||
+#ifdef CPTCFG_B43_PIO
|
||||
b43err(dev->wl, "This device does not support DMA "
|
||||
"on your system. It will now be switched to PIO.\n");
|
||||
/* Fall back to PIO transfers if we get fatal DMA errors! */
|
||||
dev->use_pio = true;
|
||||
+#endif
|
||||
b43_controller_restart(dev, "DMA error");
|
||||
return;
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/b43/pio.h
|
||||
+++ b/drivers/net/wireless/broadcom/b43/pio.h
|
||||
@@ -151,7 +151,7 @@ static inline void b43_piorx_write32(str
|
||||
b43_write32(q->dev, q->mmio_base + offset, value);
|
||||
}
|
||||
|
||||
-
|
||||
+#ifdef CPTCFG_B43_PIO
|
||||
int b43_pio_init(struct b43_wldev *dev);
|
||||
void b43_pio_free(struct b43_wldev *dev);
|
||||
|
||||
@@ -162,5 +162,37 @@ void b43_pio_rx(struct b43_pio_rxqueue *
|
||||
|
||||
void b43_pio_tx_suspend(struct b43_wldev *dev);
|
||||
void b43_pio_tx_resume(struct b43_wldev *dev);
|
||||
+#else
|
||||
+static inline int b43_pio_init(struct b43_wldev *dev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void b43_pio_free(struct b43_wldev *dev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void b43_pio_handle_txstatus(struct b43_wldev *dev,
|
||||
+ const struct b43_txstatus *status)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void b43_pio_rx(struct b43_pio_rxqueue *q)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void b43_pio_tx_suspend(struct b43_wldev *dev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void b43_pio_tx_resume(struct b43_wldev *dev)
|
||||
+{
|
||||
+}
|
||||
+#endif /* CPTCFG_B43_PIO */
|
||||
|
||||
#endif /* B43_PIO_H_ */
|
||||
--- a/drivers/net/wireless/broadcom/b43/Kconfig
|
||||
+++ b/drivers/net/wireless/broadcom/b43/Kconfig
|
||||
@@ -100,7 +100,7 @@ config B43_BCMA_PIO
|
||||
default y
|
||||
|
||||
config B43_PIO
|
||||
- bool
|
||||
+ bool "Broadcom 43xx PIO support"
|
||||
depends on B43 && B43_SSB
|
||||
depends on SSB_BLOCKIO
|
||||
default y
|
File diff suppressed because it is too large
Load Diff
@ -1,90 +0,0 @@
|
||||
PKG_DRIVERS += \
|
||||
libertas-sdio libertas-usb libertas-spi \
|
||||
mwl8k mwifiex-pcie mwifiex-sdio
|
||||
|
||||
config-$(call config_package,libertas-sdio) += LIBERTAS LIBERTAS_SDIO
|
||||
config-$(call config_package,libertas-usb) += LIBERTAS LIBERTAS_USB
|
||||
config-$(call config_package,libertas-spi) += LIBERTAS LIBERTAS_SPI
|
||||
config-$(call config_package,mwl8k) += MWL8K
|
||||
config-$(call config_package,mwifiex-pcie) += MWIFIEX MWIFIEX_PCIE
|
||||
config-$(call config_package,mwifiex-sdio) += MWIFIEX MWIFIEX_SDIO
|
||||
|
||||
define KernelPackage/libertas-usb
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +kmod-usb-core +kmod-lib80211 +@DRIVER_WEXT_SUPPORT +libertas-usb-firmware
|
||||
TITLE:=Marvell 88W8015 Wireless Driver
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/usb8xxx.ko
|
||||
AUTOLOAD:=$(call AutoProbe,libertas usb8xxx)
|
||||
endef
|
||||
|
||||
define KernelPackage/libertas-sdio
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +kmod-mmc +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-sdio-firmware
|
||||
TITLE:=Marvell 88W8686 Wireless Driver
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas_sdio.ko
|
||||
AUTOLOAD:=$(call AutoProbe,libertas libertas_sdio)
|
||||
endef
|
||||
|
||||
define KernelPackage/libertas-spi
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
SUBMENU:=Wireless Drivers
|
||||
DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-spi-firmware
|
||||
KCONFIG := \
|
||||
CONFIG_SPI=y \
|
||||
CONFIG_SPI_MASTER=y
|
||||
TITLE:=Marvell 88W8686 SPI Wireless Driver
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas_spi.ko
|
||||
AUTOLOAD:=$(call AutoProbe,libertas libertas_spi)
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/mwl8k
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Driver for Marvell TOPDOG 802.11 Wireless cards
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwl8k
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +@DRIVER_11N_SUPPORT +mwl8k-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwl8k.ko
|
||||
AUTOLOAD:=$(call AutoProbe,mwl8k)
|
||||
endef
|
||||
|
||||
define KernelPackage/mwl8k/description
|
||||
Kernel modules for Marvell TOPDOG 802.11 Wireless cards
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/mwifiex-pcie
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Driver for Marvell 802.11n/802.11ac PCIe Wireless cards
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwifiex
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +mwifiex-pcie-firmware
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex_pcie.ko
|
||||
AUTOLOAD:=$(call AutoProbe,mwifiex_pcie)
|
||||
endef
|
||||
|
||||
define KernelPackage/mwifiex-pcie/description
|
||||
Kernel modules for Marvell 802.11n/802.11ac PCIe Wireless cards
|
||||
endef
|
||||
|
||||
define KernelPackage/mwifiex-sdio
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Driver for Marvell 802.11n/802.11ac SDIO Wireless cards
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwifiex
|
||||
DEPENDS+= +kmod-mmc +kmod-mac80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +mwifiex-sdio-firmware
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex_sdio.ko
|
||||
AUTOLOAD:=$(call AutoProbe,mwifiex_sdio)
|
||||
endef
|
||||
|
||||
define KernelPackage/mwifiex-sdio/description
|
||||
Kernel modules for Marvell 802.11n/802.11ac SDIO Wireless cards
|
||||
endef
|
||||
|
@ -1,398 +0,0 @@
|
||||
From: Carl Huang <cjhuang@codeaurora.org>
|
||||
Date: Thu, 3 Dec 2020 05:37:26 -0500
|
||||
Subject: [PATCH] nl80211: add common API to configure SAR power limitations
|
||||
|
||||
NL80211_CMD_SET_SAR_SPECS is added to configure SAR from
|
||||
user space. NL80211_ATTR_SAR_SPEC is used to pass the SAR
|
||||
power specification when used with NL80211_CMD_SET_SAR_SPECS.
|
||||
|
||||
Wireless driver needs to register SAR type, supported frequency
|
||||
ranges to wiphy, so user space can query it. The index in
|
||||
frequency range is used to specify which sub band the power
|
||||
limitation applies to. The SAR type is for compatibility, so later
|
||||
other SAR mechanism can be implemented without breaking the user
|
||||
space SAR applications.
|
||||
|
||||
Normal process is user space queries the SAR capability, and
|
||||
gets the index of supported frequency ranges and associates the
|
||||
power limitation with this index and sends to kernel.
|
||||
|
||||
Here is an example of message send to kernel:
|
||||
8c 00 00 00 08 00 01 00 00 00 00 00 38 00 2b 81
|
||||
08 00 01 00 00 00 00 00 2c 00 02 80 14 00 00 80
|
||||
08 00 02 00 00 00 00 00 08 00 01 00 38 00 00 00
|
||||
14 00 01 80 08 00 02 00 01 00 00 00 08 00 01 00
|
||||
48 00 00 00
|
||||
|
||||
NL80211_CMD_SET_SAR_SPECS: 0x8c
|
||||
NL80211_ATTR_WIPHY: 0x01(phy idx is 0)
|
||||
NL80211_ATTR_SAR_SPEC: 0x812b (NLA_NESTED)
|
||||
NL80211_SAR_ATTR_TYPE: 0x00 (NL80211_SAR_TYPE_POWER)
|
||||
NL80211_SAR_ATTR_SPECS: 0x8002 (NLA_NESTED)
|
||||
freq range 0 power: 0x38 in 0.25dbm unit (14dbm)
|
||||
freq range 1 power: 0x48 in 0.25dbm unit (18dbm)
|
||||
|
||||
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
||||
Reviewed-by: Brian Norris <briannorris@chromium.org>
|
||||
Reviewed-by: Abhishek Kumar <kuabhs@chromium.org>
|
||||
Link: https://lore.kernel.org/r/20201203103728.3034-2-cjhuang@codeaurora.org
|
||||
[minor edits, NLA parse cleanups]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -1737,6 +1737,54 @@ struct station_info {
|
||||
u8 connected_to_as;
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * struct cfg80211_sar_sub_specs - sub specs limit
|
||||
+ * @power: power limitation in 0.25dbm
|
||||
+ * @freq_range_index: index the power limitation applies to
|
||||
+ */
|
||||
+struct cfg80211_sar_sub_specs {
|
||||
+ s32 power;
|
||||
+ u32 freq_range_index;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct cfg80211_sar_specs - sar limit specs
|
||||
+ * @type: it's set with power in 0.25dbm or other types
|
||||
+ * @num_sub_specs: number of sar sub specs
|
||||
+ * @sub_specs: memory to hold the sar sub specs
|
||||
+ */
|
||||
+struct cfg80211_sar_specs {
|
||||
+ enum nl80211_sar_type type;
|
||||
+ u32 num_sub_specs;
|
||||
+ struct cfg80211_sar_sub_specs sub_specs[];
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * @struct cfg80211_sar_chan_ranges - sar frequency ranges
|
||||
+ * @start_freq: start range edge frequency
|
||||
+ * @end_freq: end range edge frequency
|
||||
+ */
|
||||
+struct cfg80211_sar_freq_ranges {
|
||||
+ u32 start_freq;
|
||||
+ u32 end_freq;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct cfg80211_sar_capa - sar limit capability
|
||||
+ * @type: it's set via power in 0.25dbm or other types
|
||||
+ * @num_freq_ranges: number of frequency ranges
|
||||
+ * @freq_ranges: memory to hold the freq ranges.
|
||||
+ *
|
||||
+ * Note: WLAN driver may append new ranges or split an existing
|
||||
+ * range to small ones and then append them.
|
||||
+ */
|
||||
+struct cfg80211_sar_capa {
|
||||
+ enum nl80211_sar_type type;
|
||||
+ u32 num_freq_ranges;
|
||||
+ const struct cfg80211_sar_freq_ranges *freq_ranges;
|
||||
+};
|
||||
+
|
||||
#if IS_ENABLED(CPTCFG_CFG80211)
|
||||
/**
|
||||
* cfg80211_get_station - retrieve information about a given station
|
||||
@@ -4259,6 +4307,8 @@ struct cfg80211_ops {
|
||||
struct cfg80211_tid_config *tid_conf);
|
||||
int (*reset_tid_config)(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *peer, u8 tids);
|
||||
+ int (*set_sar_specs)(struct wiphy *wiphy,
|
||||
+ struct cfg80211_sar_specs *sar);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -5030,6 +5080,8 @@ struct wiphy {
|
||||
|
||||
u8 max_data_retry_count;
|
||||
|
||||
+ const struct cfg80211_sar_capa *sar_capa;
|
||||
+
|
||||
char priv[] __aligned(NETDEV_ALIGN);
|
||||
};
|
||||
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -405,6 +405,18 @@ nl80211_unsol_bcast_probe_resp_policy[NL
|
||||
.len = IEEE80211_MAX_DATA_LEN }
|
||||
};
|
||||
|
||||
+static const struct nla_policy
|
||||
+sar_specs_policy[NL80211_SAR_ATTR_SPECS_MAX + 1] = {
|
||||
+ [NL80211_SAR_ATTR_SPECS_POWER] = { .type = NLA_S32 },
|
||||
+ [NL80211_SAR_ATTR_SPECS_RANGE_INDEX] = {.type = NLA_U32 },
|
||||
+};
|
||||
+
|
||||
+static const struct nla_policy
|
||||
+sar_policy[NL80211_SAR_ATTR_MAX + 1] = {
|
||||
+ [NL80211_SAR_ATTR_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_SAR_TYPE),
|
||||
+ [NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy),
|
||||
+};
|
||||
+
|
||||
static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||
[0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
|
||||
[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
|
||||
@@ -739,6 +751,7 @@ static const struct nla_policy nl80211_p
|
||||
[NL80211_ATTR_SAE_PWE] =
|
||||
NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
|
||||
NL80211_SAE_PWE_BOTH),
|
||||
+ [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
|
||||
[NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
|
||||
};
|
||||
|
||||
@@ -2117,6 +2130,56 @@ fail:
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
+static int
|
||||
+nl80211_put_sar_specs(struct cfg80211_registered_device *rdev,
|
||||
+ struct sk_buff *msg)
|
||||
+{
|
||||
+ struct nlattr *sar_capa, *specs, *sub_freq_range;
|
||||
+ u8 num_freq_ranges;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!rdev->wiphy.sar_capa)
|
||||
+ return 0;
|
||||
+
|
||||
+ num_freq_ranges = rdev->wiphy.sar_capa->num_freq_ranges;
|
||||
+
|
||||
+ sar_capa = nla_nest_start(msg, NL80211_ATTR_SAR_SPEC);
|
||||
+ if (!sar_capa)
|
||||
+ return -ENOSPC;
|
||||
+
|
||||
+ if (nla_put_u32(msg, NL80211_SAR_ATTR_TYPE, rdev->wiphy.sar_capa->type))
|
||||
+ goto fail;
|
||||
+
|
||||
+ specs = nla_nest_start(msg, NL80211_SAR_ATTR_SPECS);
|
||||
+ if (!specs)
|
||||
+ goto fail;
|
||||
+
|
||||
+ /* report supported freq_ranges */
|
||||
+ for (i = 0; i < num_freq_ranges; i++) {
|
||||
+ sub_freq_range = nla_nest_start(msg, i + 1);
|
||||
+ if (!sub_freq_range)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_START_FREQ,
|
||||
+ rdev->wiphy.sar_capa->freq_ranges[i].start_freq))
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_END_FREQ,
|
||||
+ rdev->wiphy.sar_capa->freq_ranges[i].end_freq))
|
||||
+ goto fail;
|
||||
+
|
||||
+ nla_nest_end(msg, sub_freq_range);
|
||||
+ }
|
||||
+
|
||||
+ nla_nest_end(msg, specs);
|
||||
+ nla_nest_end(msg, sar_capa);
|
||||
+
|
||||
+ return 0;
|
||||
+fail:
|
||||
+ nla_nest_cancel(msg, sar_capa);
|
||||
+ return -ENOBUFS;
|
||||
+}
|
||||
+
|
||||
struct nl80211_dump_wiphy_state {
|
||||
s64 filter_wiphy;
|
||||
long start;
|
||||
@@ -2366,6 +2429,8 @@ static int nl80211_send_wiphy(struct cfg
|
||||
CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
|
||||
CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
|
||||
CMD(update_ft_ies, UPDATE_FT_IES);
|
||||
+ if (rdev->wiphy.sar_capa)
|
||||
+ CMD(set_sar_specs, SET_SAR_SPECS);
|
||||
}
|
||||
#undef CMD
|
||||
|
||||
@@ -2691,6 +2756,11 @@ static int nl80211_send_wiphy(struct cfg
|
||||
|
||||
if (nl80211_put_tid_config_support(rdev, msg))
|
||||
goto nla_put_failure;
|
||||
+ state->split_start++;
|
||||
+ break;
|
||||
+ case 16:
|
||||
+ if (nl80211_put_sar_specs(rdev, msg))
|
||||
+ goto nla_put_failure;
|
||||
|
||||
/* done */
|
||||
state->split_start = 0;
|
||||
@@ -14712,6 +14782,111 @@ static void nl80211_post_doit(__genl_con
|
||||
}
|
||||
}
|
||||
|
||||
+static int nl80211_set_sar_sub_specs(struct cfg80211_registered_device *rdev,
|
||||
+ struct cfg80211_sar_specs *sar_specs,
|
||||
+ struct nlattr *spec[], int index)
|
||||
+{
|
||||
+ u32 range_index, i;
|
||||
+
|
||||
+ if (!sar_specs || !spec)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!spec[NL80211_SAR_ATTR_SPECS_POWER] ||
|
||||
+ !spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ range_index = nla_get_u32(spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]);
|
||||
+
|
||||
+ /* check if range_index exceeds num_freq_ranges */
|
||||
+ if (range_index >= rdev->wiphy.sar_capa->num_freq_ranges)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* check if range_index duplicates */
|
||||
+ for (i = 0; i < index; i++) {
|
||||
+ if (sar_specs->sub_specs[i].freq_range_index == range_index)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ sar_specs->sub_specs[index].power =
|
||||
+ nla_get_s32(spec[NL80211_SAR_ATTR_SPECS_POWER]);
|
||||
+
|
||||
+ sar_specs->sub_specs[index].freq_range_index = range_index;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info)
|
||||
+{
|
||||
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
+ struct nlattr *spec[NL80211_SAR_ATTR_SPECS_MAX + 1];
|
||||
+ struct nlattr *tb[NL80211_SAR_ATTR_MAX + 1];
|
||||
+ struct cfg80211_sar_specs *sar_spec;
|
||||
+ enum nl80211_sar_type type;
|
||||
+ struct nlattr *spec_list;
|
||||
+ u32 specs;
|
||||
+ int rem, err;
|
||||
+
|
||||
+ if (!rdev->wiphy.sar_capa || !rdev->ops->set_sar_specs)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ if (!info->attrs[NL80211_ATTR_SAR_SPEC])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ nla_parse_nested(tb, NL80211_SAR_ATTR_MAX,
|
||||
+ info->attrs[NL80211_ATTR_SAR_SPEC],
|
||||
+ NULL, NULL);
|
||||
+
|
||||
+ if (!tb[NL80211_SAR_ATTR_TYPE] || !tb[NL80211_SAR_ATTR_SPECS])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ type = nla_get_u32(tb[NL80211_SAR_ATTR_TYPE]);
|
||||
+ if (type != rdev->wiphy.sar_capa->type)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ specs = 0;
|
||||
+ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem)
|
||||
+ specs++;
|
||||
+
|
||||
+ if (specs > rdev->wiphy.sar_capa->num_freq_ranges)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ sar_spec = kzalloc(sizeof(*sar_spec) +
|
||||
+ specs * sizeof(struct cfg80211_sar_sub_specs),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!sar_spec)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ sar_spec->type = type;
|
||||
+ specs = 0;
|
||||
+ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) {
|
||||
+ nla_parse_nested(spec, NL80211_SAR_ATTR_SPECS_MAX,
|
||||
+ spec_list, NULL, NULL);
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case NL80211_SAR_TYPE_POWER:
|
||||
+ if (nl80211_set_sar_sub_specs(rdev, sar_spec,
|
||||
+ spec, specs)) {
|
||||
+ err = -EINVAL;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ err = -EINVAL;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ specs++;
|
||||
+ }
|
||||
+
|
||||
+ sar_spec->num_sub_specs = specs;
|
||||
+
|
||||
+ rdev->cur_cmd_info = info;
|
||||
+ err = rdev_set_sar_specs(rdev, sar_spec);
|
||||
+ rdev->cur_cmd_info = NULL;
|
||||
+error:
|
||||
+ kfree(sar_spec);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static __genl_const struct genl_ops nl80211_ops[] = {
|
||||
{
|
||||
.cmd = NL80211_CMD_GET_WIPHY,
|
||||
@@ -15575,6 +15750,14 @@ static const struct genl_small_ops nl802
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
+ {
|
||||
+ .cmd = NL80211_CMD_SET_SAR_SPECS,
|
||||
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
+ .doit = nl80211_set_sar_specs,
|
||||
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||
+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
|
||||
+ NL80211_FLAG_NEED_RTNL,
|
||||
+ },
|
||||
};
|
||||
|
||||
static struct genl_family nl80211_fam __genl_ro_after_init = {
|
||||
--- a/net/wireless/rdev-ops.h
|
||||
+++ b/net/wireless/rdev-ops.h
|
||||
@@ -1356,4 +1356,16 @@ static inline int rdev_reset_tid_config(
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static inline int rdev_set_sar_specs(struct cfg80211_registered_device *rdev,
|
||||
+ struct cfg80211_sar_specs *sar)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ trace_rdev_set_sar_specs(&rdev->wiphy, sar);
|
||||
+ ret = rdev->ops->set_sar_specs(&rdev->wiphy, sar);
|
||||
+ trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
#endif /* __CFG80211_RDEV_OPS */
|
||||
--- a/net/wireless/trace.h
|
||||
+++ b/net/wireless/trace.h
|
||||
@@ -3551,6 +3551,25 @@ TRACE_EVENT(rdev_reset_tid_config,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", tids: 0x%x",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->tids)
|
||||
);
|
||||
+
|
||||
+TRACE_EVENT(rdev_set_sar_specs,
|
||||
+ TP_PROTO(struct wiphy *wiphy, struct cfg80211_sar_specs *sar),
|
||||
+ TP_ARGS(wiphy, sar),
|
||||
+ TP_STRUCT__entry(
|
||||
+ WIPHY_ENTRY
|
||||
+ __field(u16, type)
|
||||
+ __field(u16, num)
|
||||
+ ),
|
||||
+ TP_fast_assign(
|
||||
+ WIPHY_ASSIGN;
|
||||
+ __entry->type = sar->type;
|
||||
+ __entry->num = sar->num_sub_specs;
|
||||
+
|
||||
+ ),
|
||||
+ TP_printk(WIPHY_PR_FMT ", Set type:%d, num_specs:%d",
|
||||
+ WIPHY_PR_ARG, __entry->type, __entry->num)
|
||||
+);
|
||||
+
|
||||
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
@ -1,395 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -8682,6 +8682,384 @@ static void rt2800_rxdcoc_calibration(st
|
||||
rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, saverfb0r2);
|
||||
}
|
||||
|
||||
+static u32 rt2800_do_sqrt_accumulation(u32 si) {
|
||||
+ u32 root, root_pre, bit;
|
||||
+ char i;
|
||||
+ bit = 1 << 15;
|
||||
+ root = 0;
|
||||
+ for (i = 15; i >= 0; i = i - 1) {
|
||||
+ root_pre = root + bit;
|
||||
+ if ((root_pre*root_pre) <= si)
|
||||
+ root = root_pre;
|
||||
+ bit = bit >> 1;
|
||||
+ }
|
||||
+
|
||||
+ return root;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev) {
|
||||
+ u8 rfb0r1, rfb0r2, rfb0r42;
|
||||
+ u8 rfb4r0, rfb4r19;
|
||||
+ u8 rfb5r3, rfb5r4, rfb5r17, rfb5r18, rfb5r19, rfb5r20;
|
||||
+ u8 rfb6r0, rfb6r19;
|
||||
+ u8 rfb7r3, rfb7r4, rfb7r17, rfb7r18, rfb7r19, rfb7r20;
|
||||
+
|
||||
+ u8 bbp1, bbp4;
|
||||
+ u8 bbpr241, bbpr242;
|
||||
+ u32 i;
|
||||
+ u8 ch_idx;
|
||||
+ u8 bbpval;
|
||||
+ u8 rfval, vga_idx = 0;
|
||||
+ int mi = 0, mq = 0, si = 0, sq = 0, riq = 0;
|
||||
+ int sigma_i, sigma_q, r_iq, g_rx;
|
||||
+ int g_imb;
|
||||
+ int ph_rx;
|
||||
+ u32 savemacsysctrl = 0;
|
||||
+ u32 orig_RF_CONTROL0 = 0;
|
||||
+ u32 orig_RF_BYPASS0 = 0;
|
||||
+ u32 orig_RF_CONTROL1 = 0;
|
||||
+ u32 orig_RF_BYPASS1 = 0;
|
||||
+ u32 orig_RF_CONTROL3 = 0;
|
||||
+ u32 orig_RF_BYPASS3 = 0;
|
||||
+ u32 macstatus, bbpval1 = 0;
|
||||
+ u8 rf_vga_table[] = {0x20, 0x21, 0x22, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f};
|
||||
+
|
||||
+ savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ orig_RF_CONTROL0 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
|
||||
+ orig_RF_BYPASS0 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
|
||||
+ orig_RF_CONTROL1 = rt2800_register_read(rt2x00dev, RF_CONTROL1);
|
||||
+ orig_RF_BYPASS1 = rt2800_register_read(rt2x00dev, RF_BYPASS1);
|
||||
+ orig_RF_CONTROL3 = rt2800_register_read(rt2x00dev, RF_CONTROL3);
|
||||
+ orig_RF_BYPASS3 = rt2800_register_read(rt2x00dev, RF_BYPASS3);
|
||||
+
|
||||
+ bbp1 = rt2800_bbp_read(rt2x00dev, 1);
|
||||
+ bbp4 = rt2800_bbp_read(rt2x00dev, 4);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x0);
|
||||
+
|
||||
+ for (i = 0; i < 10000; i++) {
|
||||
+ macstatus = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
|
||||
+ if (macstatus & 0x3)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (i == 10000)
|
||||
+ rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n");
|
||||
+
|
||||
+ bbpval = bbp4 & (~0x18);
|
||||
+ bbpval = bbp4 | 0x00;
|
||||
+ rt2800_bbp_write(rt2x00dev, 4, bbpval);
|
||||
+
|
||||
+ bbpval = rt2800_bbp_read(rt2x00dev, 21);
|
||||
+ bbpval = bbpval | 1;
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, bbpval);
|
||||
+ bbpval = bbpval & 0xfe;
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, bbpval);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL1, 0x00000202);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS1, 0x00000303);
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags))
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x0101);
|
||||
+ else
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x0000);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, 0xf1f1);
|
||||
+
|
||||
+ rfb0r1 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
|
||||
+ rfb0r2 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
|
||||
+ rfb0r42 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
|
||||
+ rfb4r0 = rt2800_rfcsr_read_bank(rt2x00dev, 4, 0);
|
||||
+ rfb4r19 = rt2800_rfcsr_read_bank(rt2x00dev, 4, 19);
|
||||
+ rfb5r3 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 3);
|
||||
+ rfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);
|
||||
+ rfb5r17 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 17);
|
||||
+ rfb5r18 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 18);
|
||||
+ rfb5r19 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 19);
|
||||
+ rfb5r20 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 20);
|
||||
+
|
||||
+ rfb6r0 = rt2800_rfcsr_read_bank(rt2x00dev, 6, 0);
|
||||
+ rfb6r19 = rt2800_rfcsr_read_bank(rt2x00dev, 6, 19);
|
||||
+ rfb7r3 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 3);
|
||||
+ rfb7r4 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
|
||||
+ rfb7r17 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 17);
|
||||
+ rfb7r18 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 18);
|
||||
+ rfb7r19 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 19);
|
||||
+ rfb7r20 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 20);
|
||||
+
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x87);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0x27);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x38);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x38);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x80);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 18, 0xC1);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 19, 0x60);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 20, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x0);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x0);
|
||||
+
|
||||
+ rt2800_bbp_dcoc_write(rt2x00dev, 5, 0x0);
|
||||
+
|
||||
+ bbpr241 = rt2800_bbp_read(rt2x00dev, 241);
|
||||
+ bbpr242 = rt2800_bbp_read(rt2x00dev, 242);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 241, 0x10);
|
||||
+ rt2800_bbp_write(rt2x00dev, 242, 0x84);
|
||||
+ rt2800_bbp_write(rt2x00dev, 244, 0x31);
|
||||
+
|
||||
+ bbpval = rt2800_bbp_dcoc_read(rt2x00dev, 3);
|
||||
+ bbpval = bbpval & (~0x7);
|
||||
+ rt2800_bbp_dcoc_write(rt2x00dev, 3, bbpval);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
|
||||
+ udelay(1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000006);
|
||||
+ usleep_range(1, 200);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00003376);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001006);
|
||||
+ udelay(1);
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x06);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x06);
|
||||
+ } else {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x02);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x02);
|
||||
+ }
|
||||
+
|
||||
+ for (ch_idx = 0; ch_idx < 2; ch_idx = ch_idx + 1) {
|
||||
+ if (ch_idx == 0) {
|
||||
+ rfval = rfb0r1 & (~0x3);
|
||||
+ rfval = rfb0r1 | 0x1;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfval);
|
||||
+ rfval = rfb0r2 & (~0x33);
|
||||
+ rfval = rfb0r2 | 0x11;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfval);
|
||||
+ rfval = rfb0r42 & (~0x50);
|
||||
+ rfval = rfb0r42 | 0x10;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfval);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001006);
|
||||
+ udelay(1);
|
||||
+
|
||||
+ bbpval = bbp1 & (~ 0x18);
|
||||
+ bbpval = bbpval | 0x00;
|
||||
+ rt2800_bbp_write(rt2x00dev, 1, bbpval);
|
||||
+
|
||||
+ rt2800_bbp_dcoc_write(rt2x00dev, 1, 0x00);
|
||||
+ } else {
|
||||
+ rfval = rfb0r1 & (~0x3);
|
||||
+ rfval = rfb0r1 | 0x2;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfval);
|
||||
+ rfval = rfb0r2 & (~0x33);
|
||||
+ rfval = rfb0r2 | 0x22;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfval);
|
||||
+ rfval = rfb0r42 & (~0x50);
|
||||
+ rfval = rfb0r42 | 0x40;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfval);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002006);
|
||||
+ udelay(1);
|
||||
+
|
||||
+ bbpval = bbp1 & (~ 0x18);
|
||||
+ bbpval = bbpval | 0x08;
|
||||
+ rt2800_bbp_write(rt2x00dev, 1, bbpval);
|
||||
+
|
||||
+ rt2800_bbp_dcoc_write(rt2x00dev, 1, 0x01);
|
||||
+ }
|
||||
+ udelay(500);
|
||||
+
|
||||
+ vga_idx = 0;
|
||||
+ while (vga_idx < 11) {
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, rf_vga_table[vga_idx]);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, rf_vga_table[vga_idx]);
|
||||
+
|
||||
+ rt2800_bbp_dcoc_write(rt2x00dev, 0, 0x93);
|
||||
+
|
||||
+ for (i = 0; i < 10000; i++) {
|
||||
+ bbpval = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ if ((bbpval & 0xff) == 0x93)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if ((bbpval & 0xff) == 0x93) {
|
||||
+ rt2x00_warn(rt2x00dev, "Fatal Error: Calibration doesn't finish");
|
||||
+ goto restore_value;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 5; i++) {
|
||||
+ u32 bbptemp = 0;
|
||||
+ u8 value = 0;
|
||||
+ int result = 0;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x1e);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, i);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x22);
|
||||
+ value = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbptemp = bbptemp + (value << 24);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x21);
|
||||
+ value = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbptemp = bbptemp + (value << 16);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x20);
|
||||
+ value = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbptemp = bbptemp + (value << 8);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x1f);
|
||||
+ value = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbptemp = bbptemp + value;
|
||||
+
|
||||
+ if ((i < 2) && (bbptemp & 0x800000))
|
||||
+ result = (bbptemp & 0xffffff) - 0x1000000;
|
||||
+ else if (i == 4)
|
||||
+ result = bbptemp;
|
||||
+ else
|
||||
+ result = bbptemp;
|
||||
+
|
||||
+ if (i == 0)
|
||||
+ mi = result/4096;
|
||||
+ else if (i == 1)
|
||||
+ mq = result/4096;
|
||||
+ else if (i == 2)
|
||||
+ si = bbptemp/4096;
|
||||
+ else if (i == 3)
|
||||
+ sq = bbptemp/4096;
|
||||
+ else
|
||||
+ riq = result/4096;
|
||||
+ }
|
||||
+
|
||||
+ bbpval1 = si - mi*mi;
|
||||
+ rt2x00_dbg(rt2x00dev, "RXIQ si=%d, sq=%d, riq=%d, bbpval %d, vga_idx %d", si, sq, riq, bbpval1, vga_idx);
|
||||
+
|
||||
+ if (bbpval1 >= (100*100))
|
||||
+ break;
|
||||
+
|
||||
+ if (bbpval1 <= 100)
|
||||
+ vga_idx = vga_idx + 9;
|
||||
+ else if (bbpval1 <= 158)
|
||||
+ vga_idx = vga_idx + 8;
|
||||
+ else if (bbpval1 <= 251)
|
||||
+ vga_idx = vga_idx + 7;
|
||||
+ else if (bbpval1 <= 398)
|
||||
+ vga_idx = vga_idx + 6;
|
||||
+ else if (bbpval1 <= 630)
|
||||
+ vga_idx = vga_idx + 5;
|
||||
+ else if (bbpval1 <= 1000)
|
||||
+ vga_idx = vga_idx + 4;
|
||||
+ else if (bbpval1 <= 1584)
|
||||
+ vga_idx = vga_idx + 3;
|
||||
+ else if (bbpval1 <= 2511)
|
||||
+ vga_idx = vga_idx + 2;
|
||||
+ else
|
||||
+ vga_idx = vga_idx + 1;
|
||||
+ }
|
||||
+
|
||||
+ sigma_i = rt2800_do_sqrt_accumulation(100*(si - mi*mi));
|
||||
+ sigma_q = rt2800_do_sqrt_accumulation(100*(sq - mq*mq));
|
||||
+ r_iq = 10*(riq-(mi*mq));
|
||||
+
|
||||
+ rt2x00_dbg(rt2x00dev, "Sigma_i=%d, Sigma_q=%d, R_iq=%d", sigma_i, sigma_q, r_iq);
|
||||
+
|
||||
+ if (((sigma_i <= 1400 ) && (sigma_i >= 1000))
|
||||
+ && ((sigma_i - sigma_q) <= 112)
|
||||
+ && ((sigma_i - sigma_q) >= -112)
|
||||
+ && ((mi <= 32) && (mi >= -32))
|
||||
+ && ((mq <= 32) && (mq >= -32))) {
|
||||
+ r_iq = 10*(riq-(mi*mq));
|
||||
+ rt2x00_dbg(rt2x00dev, "RXIQ Sigma_i=%d, Sigma_q=%d, R_iq=%d\n", sigma_i, sigma_q, r_iq);
|
||||
+
|
||||
+ g_rx = (1000 * sigma_q) / sigma_i;
|
||||
+ g_imb = ((-2) * 128 * (1000 - g_rx)) / (1000 + g_rx);
|
||||
+ ph_rx = (r_iq * 2292) / (sigma_i * sigma_q);
|
||||
+ rt2x00_info(rt2x00dev, "RXIQ G_imb=%d, Ph_rx=%d\n", g_imb, ph_rx);
|
||||
+
|
||||
+ if ((ph_rx > 20) || (ph_rx < -20)) {
|
||||
+ ph_rx = 0;
|
||||
+ rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
|
||||
+ }
|
||||
+
|
||||
+ if ((g_imb > 12) || (g_imb < -12)) {
|
||||
+ g_imb = 0;
|
||||
+ rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
|
||||
+ }
|
||||
+ }
|
||||
+ else {
|
||||
+ g_imb = 0;
|
||||
+ ph_rx = 0;
|
||||
+ rt2x00_dbg(rt2x00dev, "RXIQ Sigma_i=%d, Sigma_q=%d, R_iq=%d\n", sigma_i, sigma_q, r_iq);
|
||||
+ rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
|
||||
+ }
|
||||
+
|
||||
+ if (ch_idx == 0) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x37);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, g_imb & 0x3f);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x35);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, ph_rx & 0x3f);
|
||||
+ } else {
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x55);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, g_imb & 0x3f);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x53);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, ph_rx & 0x3f);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+restore_value:
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x3);
|
||||
+ bbpval = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, (bbpval | 0x07));
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 1, bbp1);
|
||||
+ rt2800_bbp_write(rt2x00dev, 4, bbp4);
|
||||
+ rt2800_bbp_write(rt2x00dev, 241, bbpr241);
|
||||
+ rt2800_bbp_write(rt2x00dev, 242, bbpr242);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 244, 0x00);
|
||||
+ bbpval = rt2800_bbp_read(rt2x00dev, 21);
|
||||
+ bbpval |= 0x1;
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, bbpval);
|
||||
+ usleep_range(10, 200);
|
||||
+ bbpval &= 0xfe;
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, bbpval);
|
||||
+
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfb0r1);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfb0r2);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfb0r42);
|
||||
+
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 0, rfb4r0);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 19, rfb4r19);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, rfb5r3);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, rfb5r4);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, rfb5r17);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, rfb5r18);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, rfb5r19);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, rfb5r20);
|
||||
+
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 0, rfb6r0);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 19, rfb6r19);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 3, rfb7r3);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, rfb7r4);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 17, rfb7r17);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 18, rfb7r18);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 19, rfb7r19);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 20, rfb7r20);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000006);
|
||||
+ udelay(1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
|
||||
+ udelay(1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, orig_RF_CONTROL0);
|
||||
+ udelay(1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, orig_RF_BYPASS0);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL1, orig_RF_CONTROL1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS1, orig_RF_BYPASS1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, orig_RF_CONTROL3);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, orig_RF_BYPASS3);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
|
||||
+}
|
||||
+
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9294,6 +9672,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rxdcoc_calibration(rt2x00dev);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, true);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
+ rt2800_rxiq_calibration(rt2x00dev);
|
||||
}
|
||||
|
||||
static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
@ -1,67 +0,0 @@
|
||||
--- a/net/mac80211/main.c
|
||||
+++ b/net/mac80211/main.c
|
||||
@@ -321,7 +321,7 @@ void ieee80211_restart_hw(struct ieee802
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_restart_hw);
|
||||
|
||||
-#ifdef CONFIG_INET
|
||||
+#ifdef __disabled__CONFIG_INET
|
||||
static int ieee80211_ifa_changed(struct notifier_block *nb,
|
||||
unsigned long data, void *arg)
|
||||
{
|
||||
@@ -380,7 +380,7 @@ static int ieee80211_ifa_changed(struct
|
||||
}
|
||||
#endif
|
||||
|
||||
-#if IS_ENABLED(CONFIG_IPV6)
|
||||
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
|
||||
static int ieee80211_ifa6_changed(struct notifier_block *nb,
|
||||
unsigned long data, void *arg)
|
||||
{
|
||||
@@ -1315,14 +1315,14 @@ int ieee80211_register_hw(struct ieee802
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
-#ifdef CONFIG_INET
|
||||
+#ifdef __disabled__CONFIG_INET
|
||||
local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
|
||||
result = register_inetaddr_notifier(&local->ifa_notifier);
|
||||
if (result)
|
||||
goto fail_ifa;
|
||||
#endif
|
||||
|
||||
-#if IS_ENABLED(CONFIG_IPV6)
|
||||
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
|
||||
local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
|
||||
result = register_inet6addr_notifier(&local->ifa6_notifier);
|
||||
if (result)
|
||||
@@ -1331,13 +1331,13 @@ int ieee80211_register_hw(struct ieee802
|
||||
|
||||
return 0;
|
||||
|
||||
-#if IS_ENABLED(CONFIG_IPV6)
|
||||
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
|
||||
fail_ifa6:
|
||||
-#ifdef CONFIG_INET
|
||||
+#ifdef __disabled__CONFIG_INET
|
||||
unregister_inetaddr_notifier(&local->ifa_notifier);
|
||||
#endif
|
||||
#endif
|
||||
-#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
|
||||
+#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6)
|
||||
fail_ifa:
|
||||
#endif
|
||||
wiphy_unregister(local->hw.wiphy);
|
||||
@@ -1365,10 +1365,10 @@ void ieee80211_unregister_hw(struct ieee
|
||||
tasklet_kill(&local->tx_pending_tasklet);
|
||||
tasklet_kill(&local->tasklet);
|
||||
|
||||
-#ifdef CONFIG_INET
|
||||
+#ifdef __disabled__CONFIG_INET
|
||||
unregister_inetaddr_notifier(&local->ifa_notifier);
|
||||
#endif
|
||||
-#if IS_ENABLED(CONFIG_IPV6)
|
||||
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
|
||||
unregister_inet6addr_notifier(&local->ifa6_notifier);
|
||||
#endif
|
||||
|
@ -1,18 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -403,13 +403,8 @@ static void ath9k_hw_init_config(struct
|
||||
|
||||
ah->config.rx_intr_mitigation = true;
|
||||
|
||||
- if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
- ah->config.rimt_last = 500;
|
||||
- ah->config.rimt_first = 2000;
|
||||
- } else {
|
||||
- ah->config.rimt_last = 250;
|
||||
- ah->config.rimt_first = 700;
|
||||
- }
|
||||
+ ah->config.rimt_last = 250;
|
||||
+ ah->config.rimt_first = 500;
|
||||
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
|
||||
ah->config.pll_pwrsave = 7;
|
@ -1,973 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -9060,6 +9060,943 @@ restore_value:
|
||||
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
|
||||
}
|
||||
|
||||
+static void rt2800_rf_configstore(struct rt2x00_dev *rt2x00dev, rf_reg_pair rf_reg_record[][13], u8 chain)
|
||||
+{
|
||||
+ u8 rfvalue = 0;
|
||||
+
|
||||
+ if (chain == CHAIN_0) {
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
|
||||
+ rf_reg_record[CHAIN_0][0].bank = 0;
|
||||
+ rf_reg_record[CHAIN_0][0].reg = 1;
|
||||
+ rf_reg_record[CHAIN_0][0].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
|
||||
+ rf_reg_record[CHAIN_0][1].bank = 0;
|
||||
+ rf_reg_record[CHAIN_0][1].reg = 2;
|
||||
+ rf_reg_record[CHAIN_0][1].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 35);
|
||||
+ rf_reg_record[CHAIN_0][2].bank = 0;
|
||||
+ rf_reg_record[CHAIN_0][2].reg = 35;
|
||||
+ rf_reg_record[CHAIN_0][2].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
|
||||
+ rf_reg_record[CHAIN_0][3].bank = 0;
|
||||
+ rf_reg_record[CHAIN_0][3].reg = 42;
|
||||
+ rf_reg_record[CHAIN_0][3].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 4, 0);
|
||||
+ rf_reg_record[CHAIN_0][4].bank = 4;
|
||||
+ rf_reg_record[CHAIN_0][4].reg = 0;
|
||||
+ rf_reg_record[CHAIN_0][4].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 4, 2);
|
||||
+ rf_reg_record[CHAIN_0][5].bank = 4;
|
||||
+ rf_reg_record[CHAIN_0][5].reg = 2;
|
||||
+ rf_reg_record[CHAIN_0][5].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 4, 34);
|
||||
+ rf_reg_record[CHAIN_0][6].bank = 4;
|
||||
+ rf_reg_record[CHAIN_0][6].reg = 34;
|
||||
+ rf_reg_record[CHAIN_0][6].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 3);
|
||||
+ rf_reg_record[CHAIN_0][7].bank = 5;
|
||||
+ rf_reg_record[CHAIN_0][7].reg = 3;
|
||||
+ rf_reg_record[CHAIN_0][7].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);
|
||||
+ rf_reg_record[CHAIN_0][8].bank = 5;
|
||||
+ rf_reg_record[CHAIN_0][8].reg = 4;
|
||||
+ rf_reg_record[CHAIN_0][8].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 17);
|
||||
+ rf_reg_record[CHAIN_0][9].bank = 5;
|
||||
+ rf_reg_record[CHAIN_0][9].reg = 17;
|
||||
+ rf_reg_record[CHAIN_0][9].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 18);
|
||||
+ rf_reg_record[CHAIN_0][10].bank = 5;
|
||||
+ rf_reg_record[CHAIN_0][10].reg = 18;
|
||||
+ rf_reg_record[CHAIN_0][10].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 19);
|
||||
+ rf_reg_record[CHAIN_0][11].bank = 5;
|
||||
+ rf_reg_record[CHAIN_0][11].reg = 19;
|
||||
+ rf_reg_record[CHAIN_0][11].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 20);
|
||||
+ rf_reg_record[CHAIN_0][12].bank = 5;
|
||||
+ rf_reg_record[CHAIN_0][12].reg = 20;
|
||||
+ rf_reg_record[CHAIN_0][12].value = rfvalue;
|
||||
+ } else if (chain == CHAIN_1) {
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
|
||||
+ rf_reg_record[CHAIN_1][0].bank = 0;
|
||||
+ rf_reg_record[CHAIN_1][0].reg = 1;
|
||||
+ rf_reg_record[CHAIN_1][0].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
|
||||
+ rf_reg_record[CHAIN_1][1].bank = 0;
|
||||
+ rf_reg_record[CHAIN_1][1].reg = 2;
|
||||
+ rf_reg_record[CHAIN_1][1].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 35);
|
||||
+ rf_reg_record[CHAIN_1][2].bank = 0;
|
||||
+ rf_reg_record[CHAIN_1][2].reg = 35;
|
||||
+ rf_reg_record[CHAIN_1][2].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
|
||||
+ rf_reg_record[CHAIN_1][3].bank = 0;
|
||||
+ rf_reg_record[CHAIN_1][3].reg = 42;
|
||||
+ rf_reg_record[CHAIN_1][3].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 6, 0);
|
||||
+ rf_reg_record[CHAIN_1][4].bank = 6;
|
||||
+ rf_reg_record[CHAIN_1][4].reg = 0;
|
||||
+ rf_reg_record[CHAIN_1][4].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 6, 2);
|
||||
+ rf_reg_record[CHAIN_1][5].bank = 6;
|
||||
+ rf_reg_record[CHAIN_1][5].reg = 2;
|
||||
+ rf_reg_record[CHAIN_1][5].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 6, 34);
|
||||
+ rf_reg_record[CHAIN_1][6].bank = 6;
|
||||
+ rf_reg_record[CHAIN_1][6].reg = 34;
|
||||
+ rf_reg_record[CHAIN_1][6].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 3);
|
||||
+ rf_reg_record[CHAIN_1][7].bank = 7;
|
||||
+ rf_reg_record[CHAIN_1][7].reg = 3;
|
||||
+ rf_reg_record[CHAIN_1][7].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
|
||||
+ rf_reg_record[CHAIN_1][8].bank = 7;
|
||||
+ rf_reg_record[CHAIN_1][8].reg = 4;
|
||||
+ rf_reg_record[CHAIN_1][8].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 17);
|
||||
+ rf_reg_record[CHAIN_1][9].bank = 7;
|
||||
+ rf_reg_record[CHAIN_1][9].reg = 17;
|
||||
+ rf_reg_record[CHAIN_1][9].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 18);
|
||||
+ rf_reg_record[CHAIN_1][10].bank = 7;
|
||||
+ rf_reg_record[CHAIN_1][10].reg = 18;
|
||||
+ rf_reg_record[CHAIN_1][10].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 19);
|
||||
+ rf_reg_record[CHAIN_1][11].bank = 7;
|
||||
+ rf_reg_record[CHAIN_1][11].reg = 19;
|
||||
+ rf_reg_record[CHAIN_1][11].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 20);
|
||||
+ rf_reg_record[CHAIN_1][12].bank = 7;
|
||||
+ rf_reg_record[CHAIN_1][12].reg = 20;
|
||||
+ rf_reg_record[CHAIN_1][12].value = rfvalue;
|
||||
+ } else {
|
||||
+ rt2x00_warn(rt2x00dev, "Unknown chain = %u\n", chain);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_rf_configrecover(struct rt2x00_dev *rt2x00dev, rf_reg_pair rf_record[][13])
|
||||
+{
|
||||
+ u8 chain_index = 0, record_index = 0;
|
||||
+ u8 bank = 0, rf_register = 0, value = 0;
|
||||
+
|
||||
+ for (chain_index = 0; chain_index < 2; chain_index++) {
|
||||
+ for (record_index = 0; record_index < 13; record_index++) {
|
||||
+ bank = rf_record[chain_index][record_index].bank;
|
||||
+ rf_register = rf_record[chain_index][record_index].reg;
|
||||
+ value = rf_record[chain_index][record_index].value;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, bank, rf_register, value);
|
||||
+ rt2x00_dbg(rt2x00dev, "bank: %d, rf_register: %d, value: %x\n", bank, rf_register, value);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_setbbptonegenerator(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xAA);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xAB);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x0A);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xAC);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x3F);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xAD);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x3F);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 244, 0x40);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static u32 rt2800_do_fft_accumulation(struct rt2x00_dev *rt2x00dev, u8 tidx, u8 read_neg)
|
||||
+{
|
||||
+ u32 macvalue = 0;
|
||||
+ int fftout_i = 0, fftout_q = 0;
|
||||
+ u32 ptmp=0, pint = 0;
|
||||
+ u8 bbp = 0;
|
||||
+ u8 tidxi;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x9b);
|
||||
+
|
||||
+ bbp = 0x9b;
|
||||
+
|
||||
+ while (bbp == 0x9b) {
|
||||
+ udelay(10);
|
||||
+ bbp = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbp = bbp & 0xff;
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xba);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidx);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidx);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidx);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, 0x057C);
|
||||
+
|
||||
+ fftout_i = (macvalue >> 16);
|
||||
+ fftout_i = (fftout_i & 0x8000) ? (fftout_i - 0x10000) : fftout_i;
|
||||
+ fftout_q = (macvalue & 0xffff);
|
||||
+ fftout_q = (fftout_q & 0x8000) ? (fftout_q - 0x10000) : fftout_q;
|
||||
+ ptmp = (fftout_i * fftout_i);
|
||||
+ ptmp = ptmp + (fftout_q * fftout_q);
|
||||
+ pint = ptmp;
|
||||
+ rt2x00_dbg(rt2x00dev, "I = %d, Q = %d, power = %x\n", fftout_i, fftout_q, pint);
|
||||
+ if (read_neg) {
|
||||
+ pint = pint >> 1;
|
||||
+ tidxi = 0x40 - tidx;
|
||||
+ tidxi = tidxi & 0x3f;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xba);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidxi);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidxi);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidxi);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, 0x057C);
|
||||
+
|
||||
+ fftout_i = (macvalue >> 16);
|
||||
+ fftout_i = (fftout_i & 0x8000) ? (fftout_i - 0x10000) : fftout_i;
|
||||
+ fftout_q = (macvalue & 0xffff);
|
||||
+ fftout_q = (fftout_q & 0x8000) ? (fftout_q - 0x10000) : fftout_q;
|
||||
+ ptmp = (fftout_i * fftout_i);
|
||||
+ ptmp = ptmp + (fftout_q * fftout_q);
|
||||
+ ptmp = ptmp >> 1;
|
||||
+ pint = pint + ptmp;
|
||||
+ }
|
||||
+
|
||||
+ return pint;
|
||||
+}
|
||||
+
|
||||
+static u32 rt2800_read_fft_accumulation(struct rt2x00_dev *rt2x00dev, u8 tidx) {
|
||||
+ u32 macvalue = 0;
|
||||
+ int fftout_i = 0, fftout_q = 0;
|
||||
+ u32 ptmp=0, pint = 0;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xBA);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidx);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidx);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidx);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, 0x057C);
|
||||
+
|
||||
+ fftout_i = (macvalue >> 16);
|
||||
+ fftout_i = (fftout_i & 0x8000) ? (fftout_i - 0x10000) : fftout_i;
|
||||
+ fftout_q = (macvalue & 0xffff);
|
||||
+ fftout_q = (fftout_q & 0x8000) ? (fftout_q - 0x10000) : fftout_q;
|
||||
+ ptmp = (fftout_i * fftout_i);
|
||||
+ ptmp = ptmp + (fftout_q * fftout_q);
|
||||
+ pint = ptmp;
|
||||
+ rt2x00_info(rt2x00dev, "I = %d, Q = %d, power = %x\n", fftout_i, fftout_q, pint);
|
||||
+
|
||||
+ return pint;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_write_dc(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 alc, u8 iorq, u8 dc)
|
||||
+{
|
||||
+ u8 bbp = 0;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xb0);
|
||||
+ bbp = alc | 0x80;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+
|
||||
+ if (ch_idx == 0)
|
||||
+ bbp = (iorq == 0) ? 0xb1: 0xb2;
|
||||
+ else
|
||||
+ bbp = (iorq == 0) ? 0xb8: 0xb9;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ bbp = dc;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_loft_search(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 alc_idx, u8 dc_result[][RF_ALC_NUM][2])
|
||||
+{
|
||||
+ u32 p0 = 0, p1 = 0, pf = 0;
|
||||
+ char idx0 = 0, idx1 = 0;
|
||||
+ u8 idxf[] = {0x00, 0x00};
|
||||
+ u8 ibit = 0x20;
|
||||
+ u8 iorq;
|
||||
+ char bidx;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xb0);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x80);
|
||||
+
|
||||
+ for (bidx = 5; bidx >= 0; bidx--) {
|
||||
+ for (iorq = 0; iorq <= 1; iorq++) {
|
||||
+ rt2x00_dbg(rt2x00dev, "\n========================================================\n");
|
||||
+
|
||||
+ if (idxf[iorq] == 0x20) {
|
||||
+ idx0 = 0x20;
|
||||
+ p0 = pf;
|
||||
+ } else {
|
||||
+ idx0 = idxf[iorq] - ibit;
|
||||
+ idx0 = idx0 & 0x3F;
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idx0);
|
||||
+ p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
|
||||
+ }
|
||||
+
|
||||
+ idx1 = idxf[iorq] + ((bidx == 5) ? 0 : ibit);
|
||||
+ idx1 = idx1 & 0x3F;
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idx1);
|
||||
+ p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
|
||||
+
|
||||
+ rt2x00_dbg(rt2x00dev, "alc=%u, IorQ=%u, idx_final=%2x\n", alc_idx, iorq, idxf[iorq]);
|
||||
+ rt2x00_dbg(rt2x00dev, "p0=%x, p1=%x, pf=%x, idx_0=%x, idx_1=%x, ibit=%x !\n", p0, p1, pf, idx0, idx1, ibit);
|
||||
+
|
||||
+ if ((bidx != 5) && (pf <= p0) && (pf < p1)) {
|
||||
+ pf = pf;
|
||||
+ idxf[iorq] = idxf[iorq];
|
||||
+ } else if (p0 < p1) {
|
||||
+ pf = p0;
|
||||
+ idxf[iorq] = idx0 & 0x3F;
|
||||
+ } else {
|
||||
+ pf = p1;
|
||||
+ idxf[iorq] = idx1 & 0x3F;
|
||||
+ }
|
||||
+ rt2x00_dbg(rt2x00dev, "IorQ=%u, idx_final[%u]:%x, pf:%8x\n", iorq, iorq, idxf[iorq], pf);
|
||||
+
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idxf[iorq]);
|
||||
+
|
||||
+ }
|
||||
+ ibit = ibit >> 1;
|
||||
+ }
|
||||
+ dc_result[ch_idx][alc_idx][0] = idxf[0];
|
||||
+ dc_result[ch_idx][alc_idx][1] = idxf[1];
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_iq_search(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 *ges, u8 *pes)
|
||||
+{
|
||||
+ u32 p0 = 0, p1 = 0, pf = 0;
|
||||
+ char perr = 0, gerr = 0, iq_err = 0;
|
||||
+ char pef = 0, gef = 0;
|
||||
+ char psta, pend;
|
||||
+ char gsta, gend;
|
||||
+
|
||||
+ u8 ibit = 0x20;
|
||||
+ u8 first_search = 0x00, touch_neg_max = 0x00;
|
||||
+ char idx0 = 0, idx1 = 0;
|
||||
+ u8 gop;
|
||||
+ u8 bbp = 0;
|
||||
+ char bidx;
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "IQCalibration Start!\n");
|
||||
+ for (bidx = 5; bidx >= 1; bidx--) {
|
||||
+ for (gop = 0; gop < 2; gop++) {
|
||||
+ rt2x00_dbg(rt2x00dev, "\n========================================================\n");
|
||||
+
|
||||
+ if ((gop == 1) || (bidx < 4)) {
|
||||
+ if (gop == 0)
|
||||
+ iq_err = gerr;
|
||||
+ else
|
||||
+ iq_err = perr;
|
||||
+
|
||||
+ first_search = (gop == 0) ? (bidx == 3) : (bidx == 5);
|
||||
+ touch_neg_max = (gop) ? ((iq_err & 0x0F) == 0x08) : ((iq_err & 0x3F) == 0x20);
|
||||
+
|
||||
+ if (touch_neg_max) {
|
||||
+ p0 = pf;
|
||||
+ idx0 = iq_err;
|
||||
+ } else {
|
||||
+ idx0 = iq_err - ibit;
|
||||
+ bbp = (ch_idx == 0) ? ((gop == 0) ? 0x28 : 0x29): ((gop == 0) ? 0x46 : 0x47);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, idx0);
|
||||
+
|
||||
+ p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1);
|
||||
+ }
|
||||
+
|
||||
+ idx1 = iq_err + (first_search ? 0 : ibit);
|
||||
+ idx1 = (gop == 0) ? (idx1 & 0x0F) : (idx1 & 0x3F);
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? (gop == 0) ? 0x28 : 0x29 : (gop == 0) ? 0x46 : 0x47;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, idx1);
|
||||
+
|
||||
+ p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1);
|
||||
+
|
||||
+ rt2x00_dbg(rt2x00dev, "p0=%x, p1=%x, pwer_final=%x, idx0=%x, idx1=%x, iq_err=%x, gop=%d, ibit=%x !\n", p0, p1, pf, idx0, idx1, iq_err, gop, ibit);
|
||||
+
|
||||
+ if ((!first_search) && (pf <= p0) && (pf < p1)) {
|
||||
+ pf = pf;
|
||||
+ } else if (p0 < p1) {
|
||||
+ pf = p0;
|
||||
+ iq_err = idx0;
|
||||
+ } else {
|
||||
+ pf = p1;
|
||||
+ iq_err = idx1;
|
||||
+ }
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? (gop == 0) ? 0x28 : 0x29 : (gop == 0) ? 0x46 : 0x47;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, iq_err);
|
||||
+
|
||||
+ if (gop == 0)
|
||||
+ gerr = iq_err;
|
||||
+ else
|
||||
+ perr = iq_err;
|
||||
+
|
||||
+ rt2x00_dbg(rt2x00dev, "IQCalibration pf=%8x (%2x, %2x) !\n", pf, gerr & 0x0F, perr & 0x3F);
|
||||
+
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (bidx > 0)
|
||||
+ ibit = (ibit >> 1);
|
||||
+ }
|
||||
+ gerr = (gerr & 0x08) ? (gerr & 0x0F) - 0x10 : (gerr & 0x0F);
|
||||
+ perr = (perr & 0x20) ? (perr & 0x3F) - 0x40 : (perr & 0x3F);
|
||||
+
|
||||
+ gerr = (gerr < -0x07) ? -0x07 : (gerr > 0x05) ? 0x05 : gerr;
|
||||
+ gsta = gerr - 1;
|
||||
+ gend = gerr + 2;
|
||||
+
|
||||
+ perr = (perr < -0x1f) ? -0x1f : (perr > 0x1d) ? 0x1d : perr;
|
||||
+ psta = perr - 1;
|
||||
+ pend = perr + 2;
|
||||
+
|
||||
+ for (gef = gsta; gef <= gend; gef = gef + 1)
|
||||
+ for (pef = psta; pef <= pend; pef = pef + 1) {
|
||||
+ bbp = (ch_idx == 0) ? 0x28 : 0x46;
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, gef & 0x0F);
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? 0x29 : 0x47;
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, pef & 0x3F);
|
||||
+
|
||||
+ p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1);
|
||||
+ if ((gef == gsta) && (pef == psta)) {
|
||||
+ pf = p1;
|
||||
+ gerr = gef;
|
||||
+ perr = pef;
|
||||
+ }
|
||||
+ else if (pf > p1){
|
||||
+ pf = p1;
|
||||
+ gerr = gef;
|
||||
+ perr = pef;
|
||||
+ }
|
||||
+ rt2x00_dbg(rt2x00dev, "Fine IQCalibration p1=%8x pf=%8x (%2x, %2x) !\n", p1, pf, gef & 0x0F, pef & 0x3F);
|
||||
+ }
|
||||
+
|
||||
+ ges[ch_idx] = gerr & 0x0F;
|
||||
+ pes[ch_idx] = perr & 0x3F;
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "IQCalibration Done! CH = %u, (gain=%2x, phase=%2x)\n", ch_idx, gerr & 0x0F, perr & 0x3F);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_rf_aux_tx0_loopback(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, 0x21);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, 0x10);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x00);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, 0x1b);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 0, 0x81);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 2, 0x81);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 34, 0xee);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, 0x2d);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, 0x2d);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, 0x80);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, 0xd7);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, 0xa2);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, 0x20);
|
||||
+}
|
||||
+
|
||||
+static void rt2800_rf_aux_tx1_loopback(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, 0x22);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, 0x20);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x00);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, 0x4b);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 0, 0x81);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 2, 0x81);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 34, 0xee);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 3, 0x2d);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, 0x2d);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 17, 0x80);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 18, 0xd7);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 19, 0xa2);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 20, 0x20);
|
||||
+}
|
||||
+
|
||||
+void rt2800_loft_iq_calibration(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ rf_reg_pair rf_store[CHAIN_NUM][13];
|
||||
+ u32 macorg1 = 0;
|
||||
+ u32 macorg2 = 0;
|
||||
+ u32 macorg3 = 0;
|
||||
+ u32 macorg4 = 0;
|
||||
+ u32 macorg5 = 0;
|
||||
+ u32 orig528 = 0;
|
||||
+ u32 orig52c = 0;
|
||||
+
|
||||
+ u32 savemacsysctrl = 0, mtxcycle = 0;
|
||||
+ u32 macvalue = 0;
|
||||
+ u32 mac13b8 = 0;
|
||||
+ u32 p0 = 0, p1 = 0;
|
||||
+ u32 p0_idx10 = 0, p1_idx10 = 0;
|
||||
+
|
||||
+ u8 rfvalue;
|
||||
+ u8 loft_dc_search_result[CHAIN_NUM][RF_ALC_NUM][2];
|
||||
+ u8 ger[CHAIN_NUM], per[CHAIN_NUM];
|
||||
+ u8 rf_gain[] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x0c};
|
||||
+ u8 rfvga_gain_table[] = {0x24, 0x25, 0x26, 0x27, 0x28, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3F};
|
||||
+
|
||||
+ u8 vga_gain[] = {14, 14};
|
||||
+ u8 bbp_2324gain[] = {0x16, 0x14, 0x12, 0x10, 0x0c, 0x08};
|
||||
+ u8 bbp = 0, ch_idx = 0, rf_alc_idx = 0, idx = 0;
|
||||
+ u8 bbpr30, rfb0r39, rfb0r42;
|
||||
+ u8 bbpr1;
|
||||
+ u8 bbpr4;
|
||||
+ u8 bbpr241, bbpr242;
|
||||
+ u8 count_step;
|
||||
+
|
||||
+ savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ macorg1 = rt2800_register_read(rt2x00dev, TX_PIN_CFG);
|
||||
+ macorg2 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
|
||||
+ macorg3 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
|
||||
+ macorg4 = rt2800_register_read(rt2x00dev, RF_CONTROL3);
|
||||
+ macorg5 = rt2800_register_read(rt2x00dev, RF_BYPASS3);
|
||||
+ mac13b8 = rt2800_register_read(rt2x00dev, 0x13b8);
|
||||
+ orig528 = rt2800_register_read(rt2x00dev, RF_CONTROL2);
|
||||
+ orig52c = rt2800_register_read(rt2x00dev, RF_BYPASS2);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ macvalue &= (~0x04);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
|
||||
+
|
||||
+ for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
|
||||
+ if (macvalue & 0x01)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ macvalue &= (~0x08);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
|
||||
+
|
||||
+ for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
|
||||
+ if (macvalue & 0x02)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ for (ch_idx = 0; ch_idx < 2; ch_idx++) {
|
||||
+ rt2800_rf_configstore(rt2x00dev, rf_store, ch_idx);
|
||||
+ }
|
||||
+
|
||||
+ bbpr30 = rt2800_bbp_read(rt2x00dev, 30);
|
||||
+ rfb0r39 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 39);
|
||||
+ rfb0r42 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 30, 0x1F);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 39, 0x80);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, 0x5B);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x00);
|
||||
+
|
||||
+ rt2800_setbbptonegenerator(rt2x00dev);
|
||||
+
|
||||
+ for (ch_idx = 0; ch_idx < 2; ch_idx ++) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x0000000F);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00003306);
|
||||
+ rt2800_register_write(rt2x00dev, 0x13b8, 0x10);
|
||||
+ udelay(1);
|
||||
+
|
||||
+ if (ch_idx == 0) {
|
||||
+ rt2800_rf_aux_tx0_loopback(rt2x00dev);
|
||||
+ } else {
|
||||
+ rt2800_rf_aux_tx1_loopback(rt2x00dev);
|
||||
+ }
|
||||
+ udelay(1);
|
||||
+
|
||||
+ if (ch_idx == 0) {
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001004);
|
||||
+ } else {
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002004);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x05);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x01);
|
||||
+ if (ch_idx == 0)
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+ else
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x01);
|
||||
+
|
||||
+ vga_gain[ch_idx] = 18;
|
||||
+ for (rf_alc_idx = 0; rf_alc_idx < 3; rf_alc_idx++) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, bbp_2324gain[rf_alc_idx]);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, bbp_2324gain[rf_alc_idx]);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, RF_CONTROL3);
|
||||
+ macvalue &= (~0x0000F1F1);
|
||||
+ macvalue |= (rf_gain[rf_alc_idx] << 4);
|
||||
+ macvalue |= (rf_gain[rf_alc_idx] << 12);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, macvalue);
|
||||
+ macvalue = (0x0000F1F1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, macvalue);
|
||||
+
|
||||
+ if (rf_alc_idx == 0) {
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x21);
|
||||
+ for (;vga_gain[ch_idx] > 0;vga_gain[ch_idx] = vga_gain[ch_idx] - 2) {
|
||||
+ rfvalue = rfvga_gain_table[vga_gain[ch_idx]];
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue);
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x00);
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x00);
|
||||
+ p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x21);
|
||||
+ p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
|
||||
+ rt2x00_dbg(rt2x00dev, "LOFT AGC %d %d\n", p0, p1);
|
||||
+ if ((p0 < 7000*7000) && (p1 < (7000*7000))) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x00);
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x00);
|
||||
+
|
||||
+ rt2x00_dbg(rt2x00dev, "Used VGA %d %x\n",vga_gain[ch_idx], rfvga_gain_table[vga_gain[ch_idx]]);
|
||||
+
|
||||
+ if (vga_gain[ch_idx] < 0)
|
||||
+ vga_gain[ch_idx] = 0;
|
||||
+ }
|
||||
+
|
||||
+ rfvalue = rfvga_gain_table[vga_gain[ch_idx]];
|
||||
+
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue);
|
||||
+
|
||||
+ rt2800_loft_search(rt2x00dev, ch_idx, rf_alc_idx, loft_dc_search_result);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (rf_alc_idx = 0; rf_alc_idx < 3; rf_alc_idx++) {
|
||||
+ for (idx = 0; idx < 4; idx++) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xB0);
|
||||
+ bbp = (idx<<2) + rf_alc_idx;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+ rt2x00_dbg(rt2x00dev, " ALC %2x,", bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xb1);
|
||||
+ bbp = loft_dc_search_result[CHAIN_0][rf_alc_idx][0x00];
|
||||
+ bbp = bbp & 0x3F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+ rt2x00_dbg(rt2x00dev, " I0 %2x,", bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xb2);
|
||||
+ bbp = loft_dc_search_result[CHAIN_0][rf_alc_idx][0x01];
|
||||
+ bbp = bbp & 0x3F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+ rt2x00_dbg(rt2x00dev, " Q0 %2x,", bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xb8);
|
||||
+ bbp = loft_dc_search_result[CHAIN_1][rf_alc_idx][0x00];
|
||||
+ bbp = bbp & 0x3F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+ rt2x00_dbg(rt2x00dev, " I1 %2x,", bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xb9);
|
||||
+ bbp = loft_dc_search_result[CHAIN_1][rf_alc_idx][0x01];
|
||||
+ bbp = bbp & 0x3F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+ rt2x00_dbg(rt2x00dev, " Q1 %2x\n", bbp);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x00);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+
|
||||
+ bbp = 0x00;
|
||||
+ rt2800_bbp_write(rt2x00dev, 244, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, 0x01);
|
||||
+ udelay(1);
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, 0x00);
|
||||
+
|
||||
+ rt2800_rf_configrecover(rt2x00dev, rf_store);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, macorg1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, macorg2);
|
||||
+ udelay(1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, macorg3);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, macorg4);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, macorg5);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL2, orig528);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS2, orig52c);
|
||||
+ rt2800_register_write(rt2x00dev, 0x13b8, mac13b8);
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "LOFT Calibration Done!\n");
|
||||
+
|
||||
+ savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ macorg1 = rt2800_register_read(rt2x00dev, TX_PIN_CFG);
|
||||
+ macorg2 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
|
||||
+ macorg3 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
|
||||
+ macorg4 = rt2800_register_read(rt2x00dev, RF_CONTROL3);
|
||||
+ macorg5 = rt2800_register_read(rt2x00dev, RF_BYPASS3);
|
||||
+
|
||||
+ bbpr1 = rt2800_bbp_read(rt2x00dev, 1);
|
||||
+ bbpr4 = rt2800_bbp_read(rt2x00dev, 4);
|
||||
+ bbpr241 = rt2800_bbp_read(rt2x00dev, 241);
|
||||
+ bbpr242 = rt2800_bbp_read(rt2x00dev, 242);
|
||||
+ mac13b8 = rt2800_register_read(rt2x00dev, 0x13b8);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ macvalue &= (~0x04);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
|
||||
+ for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
|
||||
+ if (macvalue & 0x01)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ macvalue &= (~0x08);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
|
||||
+ for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
|
||||
+ if (macvalue & 0x02)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x00000101);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0000F1F1);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x00);
|
||||
+
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 4, bbpr4 & (~0x18));
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, 0x01);
|
||||
+ udelay(1);
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 241, 0x14);
|
||||
+ rt2800_bbp_write(rt2x00dev, 242, 0x80);
|
||||
+ rt2800_bbp_write(rt2x00dev, 244, 0x31);
|
||||
+ } else {
|
||||
+ rt2800_setbbptonegenerator(rt2x00dev);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00003306);
|
||||
+ udelay(1);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x0000000F);
|
||||
+
|
||||
+ if (!test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x00000000);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0000F1F1);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, 0x13b8, 0x00000010);
|
||||
+
|
||||
+ for (ch_idx = 0; ch_idx < 2; ch_idx++) {
|
||||
+ rt2800_rf_configstore(rt2x00dev, rf_store, ch_idx);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x3B);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x3B);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x03);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x60);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xB0);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x80);
|
||||
+
|
||||
+ for (ch_idx = 0; ch_idx < 2; ch_idx ++) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x00);
|
||||
+
|
||||
+ if (ch_idx == 0) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x01);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ bbp = bbpr1 & (~0x18);
|
||||
+ bbp = bbp | 0x00;
|
||||
+ rt2800_bbp_write(rt2x00dev, 1, bbp);
|
||||
+ }
|
||||
+ rt2800_rf_aux_tx0_loopback(rt2x00dev);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001004);
|
||||
+ } else {
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x01);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x01);
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX1, &rt2x00dev->cap_flags)) {
|
||||
+ bbp = bbpr1 & (~0x18);
|
||||
+ bbp = bbp | 0x08;
|
||||
+ rt2800_bbp_write(rt2x00dev, 1, bbp);
|
||||
+ }
|
||||
+ rt2800_rf_aux_tx1_loopback(rt2x00dev);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002004);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x05);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x04);
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? 0x28 : 0x46;
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x06);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x06);
|
||||
+ count_step = 1;
|
||||
+ } else {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x1F);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x1F);
|
||||
+ count_step = 2;
|
||||
+ }
|
||||
+
|
||||
+ for (;vga_gain[ch_idx] < 19; vga_gain[ch_idx]=(vga_gain[ch_idx] + count_step)) {
|
||||
+ rfvalue = rfvga_gain_table[vga_gain[ch_idx]];
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue);
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? 0x29 : 0x47;
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+ p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 0);
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ p0_idx10 = rt2800_read_fft_accumulation(rt2x00dev, 0x0A);
|
||||
+ }
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? 0x29 : 0x47;
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x21);
|
||||
+ p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 0);
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX1, &rt2x00dev->cap_flags)) {
|
||||
+ p1_idx10 = rt2800_read_fft_accumulation(rt2x00dev, 0x0A);
|
||||
+ }
|
||||
+
|
||||
+ rt2x00_dbg(rt2x00dev, "IQ AGC %d %d\n", p0, p1);
|
||||
+
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2x00_dbg(rt2x00dev, "IQ AGC IDX 10 %d %d\n", p0_idx10, p1_idx10);
|
||||
+ if ((p0_idx10 > 7000*7000) || (p1_idx10 > 7000*7000)) {
|
||||
+ if (vga_gain[ch_idx]!=0)
|
||||
+ vga_gain[ch_idx] = vga_gain[ch_idx]-1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((p0 > 2500*2500) || (p1 > 2500*2500)) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (vga_gain[ch_idx] > 18)
|
||||
+ vga_gain[ch_idx] = 18;
|
||||
+ rt2x00_dbg(rt2x00dev, "Used VGA %d %x\n",vga_gain[ch_idx], rfvga_gain_table[vga_gain[ch_idx]]);
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? 0x29 : 0x47;
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+
|
||||
+ rt2800_iq_search(rt2x00dev, ch_idx, ger, per);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x28);
|
||||
+ bbp = ger[CHAIN_0] & 0x0F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x29);
|
||||
+ bbp = per[CHAIN_0] & 0x3F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x46);
|
||||
+ bbp = ger[CHAIN_1] & 0x0F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x47);
|
||||
+ bbp = per[CHAIN_1] & 0x3F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 1, bbpr1);
|
||||
+ rt2800_bbp_write(rt2x00dev, 241, bbpr241);
|
||||
+ rt2800_bbp_write(rt2x00dev, 242, bbpr242);
|
||||
+ }
|
||||
+ rt2800_bbp_write(rt2x00dev, 244, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xB0);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 30, bbpr30);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 39, rfb0r39);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfb0r42);
|
||||
+
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 4, bbpr4);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, 0x01);
|
||||
+ udelay(1);
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, 0x00);
|
||||
+
|
||||
+ rt2800_rf_configrecover(rt2x00dev, rf_store);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, macorg1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, macorg2);
|
||||
+ udelay(1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, macorg3);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, macorg4);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, macorg5);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
|
||||
+ rt2800_register_write(rt2x00dev, 0x13b8, mac13b8);
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "TX IQ Calibration Done!\n");
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9672,6 +10609,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rxdcoc_calibration(rt2x00dev);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, true);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
+ rt2800_loft_iq_calibration(rt2x00dev);
|
||||
rt2800_rxiq_calibration(rt2x00dev);
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
@@ -17,6 +17,16 @@
|
||||
#define WCID_START 33
|
||||
#define WCID_END 222
|
||||
#define STA_IDS_SIZE (WCID_END - WCID_START + 2)
|
||||
+#define CHAIN_0 0x0
|
||||
+#define CHAIN_1 0x1
|
||||
+#define RF_ALC_NUM 6
|
||||
+#define CHAIN_NUM 2
|
||||
+
|
||||
+typedef struct rf_reg_pair {
|
||||
+ u8 bank;
|
||||
+ u8 reg;
|
||||
+ u8 value;
|
||||
+} rf_reg_pair;
|
||||
|
||||
/* RT2800 driver data structure */
|
||||
struct rt2800_drv_data {
|
@ -1,267 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -844,6 +844,9 @@ static inline int ath9k_dump_btcoex(stru
|
||||
#ifdef CPTCFG_MAC80211_LEDS
|
||||
void ath_init_leds(struct ath_softc *sc);
|
||||
void ath_deinit_leds(struct ath_softc *sc);
|
||||
+int ath_create_gpio_led(struct ath_softc *sc, int gpio, const char *name,
|
||||
+ const char *trigger, bool active_low);
|
||||
+
|
||||
#else
|
||||
static inline void ath_init_leds(struct ath_softc *sc)
|
||||
{
|
||||
@@ -980,6 +983,13 @@ void ath_ant_comb_scan(struct ath_softc
|
||||
|
||||
#define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */
|
||||
|
||||
+struct ath_led {
|
||||
+ struct list_head list;
|
||||
+ struct ath_softc *sc;
|
||||
+ const struct gpio_led *gpio;
|
||||
+ struct led_classdev cdev;
|
||||
+};
|
||||
+
|
||||
struct ath_softc {
|
||||
struct ieee80211_hw *hw;
|
||||
struct device *dev;
|
||||
@@ -1033,9 +1043,8 @@ struct ath_softc {
|
||||
spinlock_t chan_lock;
|
||||
|
||||
#ifdef CPTCFG_MAC80211_LEDS
|
||||
- bool led_registered;
|
||||
- char led_name[32];
|
||||
- struct led_classdev led_cdev;
|
||||
+ const char *led_default_trigger;
|
||||
+ struct list_head leds;
|
||||
#endif
|
||||
|
||||
#ifdef CPTCFG_ATH9K_DEBUGFS
|
||||
--- a/drivers/net/wireless/ath/ath9k/gpio.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
|
||||
@@ -39,61 +39,111 @@ static void ath_fill_led_pin(struct ath_
|
||||
else
|
||||
ah->led_pin = ATH_LED_PIN_DEF;
|
||||
}
|
||||
+}
|
||||
+
|
||||
+static void ath_led_brightness(struct led_classdev *led_cdev,
|
||||
+ enum led_brightness brightness)
|
||||
+{
|
||||
+ struct ath_led *led = container_of(led_cdev, struct ath_led, cdev);
|
||||
+ struct ath_softc *sc = led->sc;
|
||||
+
|
||||
+ ath9k_ps_wakeup(sc);
|
||||
+ ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio,
|
||||
+ (brightness != LED_OFF) ^ led->gpio->active_low);
|
||||
+ ath9k_ps_restore(sc);
|
||||
+}
|
||||
+
|
||||
+static int ath_add_led(struct ath_softc *sc, struct ath_led *led)
|
||||
+{
|
||||
+ const struct gpio_led *gpio = led->gpio;
|
||||
+ int ret;
|
||||
+
|
||||
+ led->cdev.name = gpio->name;
|
||||
+ led->cdev.default_trigger = gpio->default_trigger;
|
||||
+ led->cdev.brightness_set = ath_led_brightness;
|
||||
+
|
||||
+ ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->cdev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ led->sc = sc;
|
||||
+ list_add(&led->list, &sc->leds);
|
||||
|
||||
/* Configure gpio for output */
|
||||
- ath9k_hw_gpio_request_out(ah, ah->led_pin, "ath9k-led",
|
||||
+ ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name,
|
||||
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
|
||||
|
||||
- /* LED off, active low */
|
||||
- ath9k_hw_set_gpio(ah, ah->led_pin, ah->config.led_active_high ? 0 : 1);
|
||||
+ /* LED off */
|
||||
+ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
-static void ath_led_brightness(struct led_classdev *led_cdev,
|
||||
- enum led_brightness brightness)
|
||||
+int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name,
|
||||
+ const char *trigger, bool active_low)
|
||||
{
|
||||
- struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev);
|
||||
- u32 val = (brightness == LED_OFF);
|
||||
+ struct ath_led *led;
|
||||
+ struct gpio_led *gpio;
|
||||
+ char *_name;
|
||||
+ int ret;
|
||||
|
||||
- if (sc->sc_ah->config.led_active_high)
|
||||
- val = !val;
|
||||
+ led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!led)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ led->gpio = gpio = (struct gpio_led *) (led + 1);
|
||||
+ _name = (char *) (led->gpio + 1);
|
||||
+
|
||||
+ strcpy(_name, name);
|
||||
+ gpio->name = _name;
|
||||
+ gpio->gpio = gpio_num;
|
||||
+ gpio->active_low = active_low;
|
||||
+ gpio->default_trigger = trigger;
|
||||
+
|
||||
+ ret = ath_add_led(sc, led);
|
||||
+ if (unlikely(ret < 0))
|
||||
+ kfree(led);
|
||||
|
||||
- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
void ath_deinit_leds(struct ath_softc *sc)
|
||||
{
|
||||
- if (!sc->led_registered)
|
||||
- return;
|
||||
+ struct ath_led *led;
|
||||
|
||||
- ath_led_brightness(&sc->led_cdev, LED_OFF);
|
||||
- led_classdev_unregister(&sc->led_cdev);
|
||||
-
|
||||
- ath9k_hw_gpio_free(sc->sc_ah, sc->sc_ah->led_pin);
|
||||
+ while (!list_empty(&sc->leds)) {
|
||||
+ led = list_first_entry(&sc->leds, struct ath_led, list);
|
||||
+ list_del(&led->list);
|
||||
+ ath_led_brightness(&led->cdev, LED_OFF);
|
||||
+ led_classdev_unregister(&led->cdev);
|
||||
+ ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio);
|
||||
+ kfree(led);
|
||||
+ }
|
||||
}
|
||||
|
||||
void ath_init_leds(struct ath_softc *sc)
|
||||
{
|
||||
- int ret;
|
||||
+ char led_name[32];
|
||||
+ const char *trigger;
|
||||
+
|
||||
+ INIT_LIST_HEAD(&sc->leds);
|
||||
|
||||
if (AR_SREV_9100(sc->sc_ah))
|
||||
return;
|
||||
|
||||
ath_fill_led_pin(sc);
|
||||
|
||||
- if (!ath9k_led_blink)
|
||||
- sc->led_cdev.default_trigger =
|
||||
- ieee80211_get_radio_led_name(sc->hw);
|
||||
-
|
||||
- snprintf(sc->led_name, sizeof(sc->led_name),
|
||||
- "ath9k-%s", wiphy_name(sc->hw->wiphy));
|
||||
- sc->led_cdev.name = sc->led_name;
|
||||
- sc->led_cdev.brightness_set = ath_led_brightness;
|
||||
+ snprintf(led_name, sizeof(led_name), "ath9k-%s",
|
||||
+ wiphy_name(sc->hw->wiphy));
|
||||
|
||||
- ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
|
||||
- if (ret < 0)
|
||||
- return;
|
||||
+ if (ath9k_led_blink)
|
||||
+ trigger = sc->led_default_trigger;
|
||||
+ else
|
||||
+ trigger = ieee80211_get_radio_led_name(sc->hw);
|
||||
|
||||
- sc->led_registered = true;
|
||||
+ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger,
|
||||
+ !sc->sc_ah->config.led_active_high);
|
||||
}
|
||||
#endif
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -1052,7 +1052,7 @@ int ath9k_init_device(u16 devid, struct
|
||||
|
||||
#ifdef CPTCFG_MAC80211_LEDS
|
||||
/* must be initialized before ieee80211_register_hw */
|
||||
- sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
|
||||
+ sc->led_default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
|
||||
IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
|
||||
ARRAY_SIZE(ath9k_tpt_blink));
|
||||
#endif
|
||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||
@@ -1456,6 +1456,61 @@ static const struct file_operations fops
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
+#ifdef CONFIG_MAC80211_LEDS
|
||||
+
|
||||
+static ssize_t write_file_gpio_led(struct file *file, const char __user *ubuf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ath_softc *sc = file->private_data;
|
||||
+ char buf[32], *str, *name, *c;
|
||||
+ ssize_t len;
|
||||
+ unsigned int gpio;
|
||||
+ bool active_low = false;
|
||||
+
|
||||
+ len = min(count, sizeof(buf) - 1);
|
||||
+ if (copy_from_user(buf, ubuf, len))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ buf[len] = '\0';
|
||||
+ name = strchr(buf, ',');
|
||||
+ if (!name)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ *(name++) = 0;
|
||||
+ if (!*name)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ c = strchr(name, '\n');
|
||||
+ if (c)
|
||||
+ *c = 0;
|
||||
+
|
||||
+ str = buf;
|
||||
+ if (*str == '!') {
|
||||
+ str++;
|
||||
+ active_low = true;
|
||||
+ }
|
||||
+
|
||||
+ if (kstrtouint(str, 0, &gpio) < 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (gpio >= sc->sc_ah->caps.num_gpio_pins)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (ath_create_gpio_led(sc, gpio, name, NULL, active_low) < 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations fops_gpio_led = {
|
||||
+ .write = write_file_gpio_led,
|
||||
+ .open = simple_open,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .llseek = default_llseek,
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
|
||||
int ath9k_init_debug(struct ath_hw *ah)
|
||||
{
|
||||
@@ -1480,6 +1535,10 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||
&fops_eeprom);
|
||||
debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
|
||||
sc, &fops_chanbw);
|
||||
+#ifdef CONFIG_MAC80211_LEDS
|
||||
+ debugfs_create_file("gpio_led", S_IWUSR,
|
||||
+ sc->debug.debugfs_phy, sc, &fops_gpio_led);
|
||||
+#endif
|
||||
debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
|
||||
read_file_dma);
|
||||
debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
|
@ -1,27 +0,0 @@
|
||||
From 66ae1b1750720a33e29792a177b1e696f4f005fb Mon Sep 17 00:00:00 2001
|
||||
From: Phil Elwell <phil@raspberrypi.org>
|
||||
Date: Wed, 9 Mar 2016 17:25:59 +0000
|
||||
Subject: [PATCH] brcmfmac: Disable power management
|
||||
|
||||
Disable wireless power saving in the brcmfmac WLAN driver. This is a
|
||||
temporary measure until the connectivity loss resulting from power
|
||||
saving is resolved.
|
||||
|
||||
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
||||
---
|
||||
drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -2961,6 +2961,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
|
||||
* preference in cfg struct to apply this to
|
||||
* FW later while initializing the dongle
|
||||
*/
|
||||
+#if defined(CONFIG_ARCH_BCM2835)
|
||||
+ brcmf_dbg(INFO, "power management disabled\n");
|
||||
+ enabled = false;
|
||||
+#endif
|
||||
cfg->pwr_save = enabled;
|
||||
if (!check_vif_up(ifp->vif)) {
|
||||
|
@ -1,14 +0,0 @@
|
||||
--- a/kconf/Makefile
|
||||
+++ b/kconf/Makefile
|
||||
@@ -1,9 +1,9 @@
|
||||
-CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
|
||||
+CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -DKBUILD_NO_NLS
|
||||
|
||||
LXDIALOG := lxdialog/checklist.o lxdialog/inputbox.o lxdialog/menubox.o lxdialog/textbox.o lxdialog/util.o lxdialog/yesno.o
|
||||
|
||||
conf: conf.o zconf.tab.o
|
||||
-mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags) -DLOCALE
|
||||
+mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags)
|
||||
mconf_LDFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
|
||||
mconf: CFLAGS += $(mconf_CFLAGS)
|
||||
|
@ -1,32 +0,0 @@
|
||||
--- /dev/null
|
||||
+++ b/include/linux/rt2x00_platform.h
|
||||
@@ -0,0 +1,19 @@
|
||||
+/*
|
||||
+ * Platform data definition for the rt2x00 driver
|
||||
+ *
|
||||
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef _RT2X00_PLATFORM_H
|
||||
+#define _RT2X00_PLATFORM_H
|
||||
+
|
||||
+struct rt2x00_platform_data {
|
||||
+ char *eeprom_file_name;
|
||||
+};
|
||||
+
|
||||
+#endif /* _RT2X00_PLATFORM_H */
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/average.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/clk.h>
|
||||
+#include <linux/rt2x00_platform.h>
|
||||
|
||||
#include <net/mac80211.h>
|
||||
|
@ -1,34 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -1140,25 +1140,25 @@ static int __init ath9k_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
- error = ath_pci_init();
|
||||
+ error = ath_ahb_init();
|
||||
if (error < 0) {
|
||||
- pr_err("No PCI devices found, driver not installed\n");
|
||||
error = -ENODEV;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
- error = ath_ahb_init();
|
||||
+ error = ath_pci_init();
|
||||
if (error < 0) {
|
||||
+ pr_err("No PCI devices found, driver not installed\n");
|
||||
error = -ENODEV;
|
||||
- goto err_pci_exit;
|
||||
+ goto err_ahb_exit;
|
||||
}
|
||||
|
||||
dmi_check_system(ath9k_quirks);
|
||||
|
||||
return 0;
|
||||
|
||||
- err_pci_exit:
|
||||
- ath_pci_exit();
|
||||
+ err_ahb_exit:
|
||||
+ ath_ahb_exit();
|
||||
err_out:
|
||||
return error;
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
--- a/kconf/conf.c
|
||||
+++ b/kconf/conf.c
|
||||
@@ -598,40 +598,12 @@ int main(int ac, char **av)
|
||||
case oldconfig:
|
||||
case listnewconfig:
|
||||
case olddefconfig:
|
||||
- conf_read(NULL);
|
||||
- break;
|
||||
case allnoconfig:
|
||||
case allyesconfig:
|
||||
case allmodconfig:
|
||||
case alldefconfig:
|
||||
case randconfig:
|
||||
- name = getenv("KCONFIG_ALLCONFIG");
|
||||
- if (!name)
|
||||
- break;
|
||||
- if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
|
||||
- if (conf_read_simple(name, S_DEF_USER)) {
|
||||
- fprintf(stderr,
|
||||
- _("*** Can't read seed configuration \"%s\"!\n"),
|
||||
- name);
|
||||
- exit(1);
|
||||
- }
|
||||
- break;
|
||||
- }
|
||||
- switch (input_mode) {
|
||||
- case allnoconfig: name = "allno.config"; break;
|
||||
- case allyesconfig: name = "allyes.config"; break;
|
||||
- case allmodconfig: name = "allmod.config"; break;
|
||||
- case alldefconfig: name = "alldef.config"; break;
|
||||
- case randconfig: name = "allrandom.config"; break;
|
||||
- default: break;
|
||||
- }
|
||||
- if (conf_read_simple(name, S_DEF_USER) &&
|
||||
- conf_read_simple("all.config", S_DEF_USER)) {
|
||||
- fprintf(stderr,
|
||||
- _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"),
|
||||
- name);
|
||||
- exit(1);
|
||||
- }
|
||||
+ conf_read(NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
--- a/kconf/confdata.c
|
||||
+++ b/kconf/confdata.c
|
||||
@@ -1170,6 +1170,8 @@ bool conf_set_all_new_symbols(enum conf_
|
||||
}
|
||||
bool has_changed = false;
|
||||
|
||||
+ sym_clear_all_valid();
|
||||
+
|
||||
for_all_symbols(i, sym) {
|
||||
if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
|
||||
continue;
|
||||
@@ -1213,8 +1215,6 @@ bool conf_set_all_new_symbols(enum conf_
|
||||
|
||||
}
|
||||
|
||||
- sym_clear_all_valid();
|
||||
-
|
||||
/*
|
||||
* We have different type of choice blocks.
|
||||
* If curr.tri equals to mod then we can select several
|
@ -1,51 +0,0 @@
|
||||
From: Carl Huang <cjhuang@codeaurora.org>
|
||||
Date: Thu, 3 Dec 2020 05:37:27 -0500
|
||||
Subject: [PATCH] mac80211: add ieee80211_set_sar_specs
|
||||
|
||||
This change registers ieee80211_set_sar_specs to
|
||||
mac80211_config_ops, so cfg80211 can call it.
|
||||
|
||||
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
||||
Reviewed-by: Brian Norris <briannorris@chromium.org>
|
||||
Reviewed-by: Abhishek Kumar <kuabhs@chromium.org>
|
||||
Link: https://lore.kernel.org/r/20201203103728.3034-3-cjhuang@codeaurora.org
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -4207,6 +4207,8 @@ struct ieee80211_ops {
|
||||
struct ieee80211_vif *vif);
|
||||
void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enabled);
|
||||
+ int (*set_sar_specs)(struct ieee80211_hw *hw,
|
||||
+ const struct cfg80211_sar_specs *sar);
|
||||
void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enabled);
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -4136,6 +4136,17 @@ static int ieee80211_reset_tid_config(st
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int ieee80211_set_sar_specs(struct wiphy *wiphy,
|
||||
+ struct cfg80211_sar_specs *sar)
|
||||
+{
|
||||
+ struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
+
|
||||
+ if (!local->ops->set_sar_specs)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return local->ops->set_sar_specs(&local->hw, sar);
|
||||
+}
|
||||
+
|
||||
const struct cfg80211_ops mac80211_config_ops = {
|
||||
.add_virtual_intf = ieee80211_add_iface,
|
||||
.del_virtual_intf = ieee80211_del_iface,
|
||||
@@ -4239,4 +4250,5 @@ const struct cfg80211_ops mac80211_confi
|
||||
.probe_mesh_link = ieee80211_probe_mesh_link,
|
||||
.set_tid_config = ieee80211_set_tid_config,
|
||||
.reset_tid_config = ieee80211_reset_tid_config,
|
||||
+ .set_sar_specs = ieee80211_set_sar_specs,
|
||||
};
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/net/wireless/marvell/libertas/cfg.c
|
||||
+++ b/drivers/net/wireless/marvell/libertas/cfg.c
|
||||
@@ -2129,6 +2129,8 @@ int lbs_cfg_register(struct lbs_private
|
||||
wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
|
||||
wdev->wiphy->reg_notifier = lbs_reg_notifier;
|
||||
|
||||
+ memcpy(wdev->wiphy->perm_addr, priv->current_addr, ETH_ALEN);
|
||||
+
|
||||
ret = wiphy_register(wdev->wiphy);
|
||||
if (ret < 0)
|
||||
pr_err("cannot register wiphy device\n");
|
@ -1,25 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -990,6 +990,12 @@ static void rt2x00lib_rate(struct ieee80
|
||||
|
||||
void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
|
||||
{
|
||||
+ struct rt2x00_platform_data *pdata;
|
||||
+
|
||||
+ pdata = rt2x00dev->dev->platform_data;
|
||||
+ if (pdata && pdata->mac_address)
|
||||
+ ether_addr_copy(eeprom_mac_addr, pdata->mac_address);
|
||||
+
|
||||
of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr);
|
||||
|
||||
if (!is_valid_ether_addr(eeprom_mac_addr)) {
|
||||
--- a/include/linux/rt2x00_platform.h
|
||||
+++ b/include/linux/rt2x00_platform.h
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
struct rt2x00_platform_data {
|
||||
char *eeprom_file_name;
|
||||
+ const u8 *mac_address;
|
||||
|
||||
int disable_2ghz;
|
||||
int disable_5ghz;
|
@ -1,116 +0,0 @@
|
||||
From: Markus Theil <markus.theil@tu-ilmenau.de>
|
||||
Date: Sat, 6 Feb 2021 12:51:12 +0100
|
||||
Subject: [PATCH] mac80211: enable QoS support for nl80211 ctrl port
|
||||
|
||||
This patch unifies sending control port frames
|
||||
over nl80211 and AF_PACKET sockets a little more.
|
||||
|
||||
Before this patch, EAPOL frames got QoS prioritization
|
||||
only when using AF_PACKET sockets.
|
||||
|
||||
__ieee80211_select_queue only selects a QoS-enabled queue
|
||||
for control port frames, when the control port protocol
|
||||
is set correctly on the skb. For the AF_PACKET path this
|
||||
works, but the nl80211 path used ETH_P_802_3.
|
||||
|
||||
Another check for injected frames in wme.c then prevented
|
||||
the QoS TID to be copied in the frame.
|
||||
|
||||
In order to fix this, get rid of the frame injection marking
|
||||
for nl80211 ctrl port and set the correct ethernet protocol.
|
||||
|
||||
Please note:
|
||||
An erlier version of this path tried to prevent
|
||||
frame aggregation for control port frames in order to speed up
|
||||
the initial connection setup a little. This seemed to cause
|
||||
issues on my older Intel dvm-based hardware, and was therefore
|
||||
removed again. Future commits which try to reintroduce this
|
||||
have to check carefully how hw behaves with aggregated and
|
||||
non-aggregated traffic for the same TID.
|
||||
My NIC: Intel(R) Centrino(R) Ultimate-N 6300 AGN, REV=0x74
|
||||
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
|
||||
Link: https://lore.kernel.org/r/20210206115112.567881-1-markus.theil@tu-ilmenau.de
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/status.c
|
||||
+++ b/net/mac80211/status.c
|
||||
@@ -628,16 +628,12 @@ static void ieee80211_report_ack_skb(str
|
||||
u64 cookie = IEEE80211_SKB_CB(skb)->ack.cookie;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
- __be16 ethertype = 0;
|
||||
-
|
||||
- if (skb->len >= ETH_HLEN && skb->protocol == cpu_to_be16(ETH_P_802_3))
|
||||
- skb_copy_bits(skb, 2 * ETH_ALEN, ðertype, ETH_TLEN);
|
||||
|
||||
rcu_read_lock();
|
||||
sdata = ieee80211_sdata_from_skb(local, skb);
|
||||
if (sdata) {
|
||||
- if (ethertype == sdata->control_port_protocol ||
|
||||
- ethertype == cpu_to_be16(ETH_P_PREAUTH))
|
||||
+ if (skb->protocol == sdata->control_port_protocol ||
|
||||
+ skb->protocol == cpu_to_be16(ETH_P_PREAUTH))
|
||||
cfg80211_control_port_tx_status(&sdata->wdev,
|
||||
cookie,
|
||||
skb->data,
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -1195,9 +1195,7 @@ ieee80211_tx_prepare(struct ieee80211_su
|
||||
tx->sta = rcu_dereference(sdata->u.vlan.sta);
|
||||
if (!tx->sta && sdata->wdev.use_4addr)
|
||||
return TX_DROP;
|
||||
- } else if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX |
|
||||
- IEEE80211_TX_CTL_INJECTED) ||
|
||||
- tx->sdata->control_port_protocol == tx->skb->protocol) {
|
||||
+ } else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
|
||||
tx->sta = sta_info_get_bss(sdata, hdr->addr1);
|
||||
}
|
||||
if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
|
||||
@@ -5443,6 +5441,7 @@ int ieee80211_tx_control_port(struct wip
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
+ struct sta_info *sta;
|
||||
struct sk_buff *skb;
|
||||
struct ethhdr *ehdr;
|
||||
u32 ctrl_flags = 0;
|
||||
@@ -5465,8 +5464,7 @@ int ieee80211_tx_control_port(struct wip
|
||||
if (cookie)
|
||||
ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
|
||||
- flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX |
|
||||
- IEEE80211_TX_CTL_INJECTED;
|
||||
+ flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX;
|
||||
|
||||
skb = dev_alloc_skb(local->hw.extra_tx_headroom +
|
||||
sizeof(struct ethhdr) + len);
|
||||
@@ -5483,10 +5481,25 @@ int ieee80211_tx_control_port(struct wip
|
||||
ehdr->h_proto = proto;
|
||||
|
||||
skb->dev = dev;
|
||||
- skb->protocol = htons(ETH_P_802_3);
|
||||
+ skb->protocol = proto;
|
||||
skb_reset_network_header(skb);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
+ /* update QoS header to prioritize control port frames if possible,
|
||||
+ * priorization also happens for control port frames send over
|
||||
+ * AF_PACKET
|
||||
+ */
|
||||
+ rcu_read_lock();
|
||||
+
|
||||
+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta) == 0 && !IS_ERR(sta)) {
|
||||
+ u16 queue = __ieee80211_select_queue(sdata, sta, skb);
|
||||
+
|
||||
+ skb_set_queue_mapping(skb, queue);
|
||||
+ skb_get_hash(skb);
|
||||
+ }
|
||||
+
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
/* mutex lock is only needed for incrementing the cookie counter */
|
||||
mutex_lock(&local->mtx);
|
||||
|
@ -1,15 +0,0 @@
|
||||
--- a/backport-include/linux/rfkill.h
|
||||
+++ b/backport-include/linux/rfkill.h
|
||||
@@ -2,6 +2,12 @@
|
||||
#define __COMPAT_RFKILL_H
|
||||
#include <linux/version.h>
|
||||
|
||||
+#undef CONFIG_RFKILL
|
||||
+#undef CONFIG_RFKILL_FULL
|
||||
+#undef CONFIG_RFKILL_LEDS
|
||||
+#undef CONFIG_RFKILL_MODULE
|
||||
+#undef CONFIG_RFKILL_FULL_MODULE
|
||||
+
|
||||
#if LINUX_VERSION_IS_GEQ(3,10,0)
|
||||
#include_next <linux/rfkill.h>
|
||||
#else
|
@ -1,21 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 28 Apr 2021 21:03:13 +0200
|
||||
Subject: [PATCH] mac80211: minstrel_ht: fix MINSTREL_FRAC macro
|
||||
|
||||
Add missing braces to avoid issues with e.g. using additions in the
|
||||
div expression
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.h
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
/* scaled fraction values */
|
||||
#define MINSTREL_SCALE 12
|
||||
-#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
|
||||
+#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / (div))
|
||||
#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
|
||||
|
||||
#define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */
|
@ -1,11 +0,0 @@
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -2463,7 +2463,7 @@ static int ieee80211_scan(struct wiphy *
|
||||
* the frames sent while scanning on other channel will be
|
||||
* lost)
|
||||
*/
|
||||
- if (sdata->u.ap.beacon &&
|
||||
+ if (0 && sdata->u.ap.beacon &&
|
||||
(!(wiphy->features & NL80211_FEATURE_AP_SCAN) ||
|
||||
!(req->flags & NL80211_SCAN_FLAG_AP)))
|
||||
return -EOPNOTSUPP;
|
@ -1,139 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||
@@ -1512,6 +1512,50 @@ static const struct file_operations fops
|
||||
#endif
|
||||
|
||||
|
||||
+static ssize_t read_file_diag(struct file *file, char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ath_softc *sc = file->private_data;
|
||||
+ struct ath_hw *ah = sc->sc_ah;
|
||||
+ char buf[32];
|
||||
+ unsigned int len;
|
||||
+
|
||||
+ len = sprintf(buf, "0x%08lx\n", ah->diag);
|
||||
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
+}
|
||||
+
|
||||
+static ssize_t write_file_diag(struct file *file, const char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ath_softc *sc = file->private_data;
|
||||
+ struct ath_hw *ah = sc->sc_ah;
|
||||
+ unsigned long diag;
|
||||
+ char buf[32];
|
||||
+ ssize_t len;
|
||||
+
|
||||
+ len = min(count, sizeof(buf) - 1);
|
||||
+ if (copy_from_user(buf, user_buf, len))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ buf[len] = '\0';
|
||||
+ if (kstrtoul(buf, 0, &diag))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ah->diag = diag;
|
||||
+ ath9k_hw_update_diag(ah);
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations fops_diag = {
|
||||
+ .read = read_file_diag,
|
||||
+ .write = write_file_diag,
|
||||
+ .open = simple_open,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .llseek = default_llseek,
|
||||
+};
|
||||
+
|
||||
+
|
||||
int ath9k_init_debug(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
@@ -1539,6 +1583,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||
debugfs_create_file("gpio_led", S_IWUSR,
|
||||
sc->debug.debugfs_phy, sc, &fops_gpio_led);
|
||||
#endif
|
||||
+ debugfs_create_file("diag", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
|
||||
+ sc, &fops_diag);
|
||||
debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
|
||||
read_file_dma);
|
||||
debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.h
|
||||
@@ -522,6 +522,12 @@ enum {
|
||||
ATH9K_RESET_COLD,
|
||||
};
|
||||
|
||||
+enum {
|
||||
+ ATH_DIAG_DISABLE_RX,
|
||||
+ ATH_DIAG_DISABLE_TX,
|
||||
+ ATH_DIAG_TRIGGER_ERROR,
|
||||
+};
|
||||
+
|
||||
struct ath9k_hw_version {
|
||||
u32 magic;
|
||||
u16 devid;
|
||||
@@ -810,6 +816,8 @@ struct ath_hw {
|
||||
u32 ah_flags;
|
||||
s16 nf_override;
|
||||
|
||||
+ unsigned long diag;
|
||||
+
|
||||
bool reset_power_on;
|
||||
bool htc_reset_init;
|
||||
|
||||
@@ -1077,6 +1085,7 @@ void ath9k_hw_check_nav(struct ath_hw *a
|
||||
bool ath9k_hw_check_alive(struct ath_hw *ah);
|
||||
|
||||
bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
|
||||
+void ath9k_hw_update_diag(struct ath_hw *ah);
|
||||
|
||||
/* Generic hw timer primitives */
|
||||
struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -1882,6 +1882,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_get_tsf_offset);
|
||||
|
||||
+void ath9k_hw_update_diag(struct ath_hw *ah)
|
||||
+{
|
||||
+ if (test_bit(ATH_DIAG_DISABLE_RX, &ah->diag))
|
||||
+ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
|
||||
+ else
|
||||
+ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
|
||||
+
|
||||
+ if (test_bit(ATH_DIAG_DISABLE_TX, &ah->diag))
|
||||
+ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK);
|
||||
+ else
|
||||
+ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK);
|
||||
+}
|
||||
+EXPORT_SYMBOL(ath9k_hw_update_diag);
|
||||
+
|
||||
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
struct ath9k_hw_cal_data *caldata, bool fastcc)
|
||||
{
|
||||
@@ -2090,6 +2104,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
||||
ar9003_hw_disable_phy_restart(ah);
|
||||
|
||||
ath9k_hw_apply_gpio_override(ah);
|
||||
+ ath9k_hw_update_diag(ah);
|
||||
|
||||
if (AR_SREV_9565(ah) && common->bt_ant_diversity)
|
||||
REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -536,6 +536,11 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
|
||||
return IRQ_HANDLED;
|
||||
|
||||
+ if (test_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag)) {
|
||||
+ status |= ATH9K_INT_FATAL;
|
||||
+ clear_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag);
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* If there are no status bits set, then this interrupt was not
|
||||
* for me (should have been caught above).
|
@ -1,251 +0,0 @@
|
||||
From: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
|
||||
Date: Sun, 31 Jan 2016 21:01:31 +0100
|
||||
Subject: [PATCH v4 4/8] mac80211: ath9k: enable access to GPIO
|
||||
|
||||
Enable access to GPIO chip and its pins for Atheros AR92xx
|
||||
wireless devices. For now AR9285 and AR9287 are supported.
|
||||
|
||||
Signed-off-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <linux/completion.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/hw_random.h>
|
||||
+#include <linux/gpio/driver.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "debug.h"
|
||||
@@ -990,6 +991,14 @@ struct ath_led {
|
||||
struct led_classdev cdev;
|
||||
};
|
||||
|
||||
+#ifdef CONFIG_GPIOLIB
|
||||
+struct ath9k_gpio_chip {
|
||||
+ struct ath_softc *sc;
|
||||
+ char label[32];
|
||||
+ struct gpio_chip gchip;
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
struct ath_softc {
|
||||
struct ieee80211_hw *hw;
|
||||
struct device *dev;
|
||||
@@ -1045,6 +1054,9 @@ struct ath_softc {
|
||||
#ifdef CPTCFG_MAC80211_LEDS
|
||||
const char *led_default_trigger;
|
||||
struct list_head leds;
|
||||
+#ifdef CONFIG_GPIOLIB
|
||||
+ struct ath9k_gpio_chip *gpiochip;
|
||||
+#endif
|
||||
#endif
|
||||
|
||||
#ifdef CPTCFG_ATH9K_DEBUGFS
|
||||
--- a/drivers/net/wireless/ath/ath9k/gpio.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
|
||||
@@ -16,13 +16,139 @@
|
||||
|
||||
#include "ath9k.h"
|
||||
#include <linux/ath9k_platform.h>
|
||||
+#include <linux/gpio.h>
|
||||
+
|
||||
+#ifdef CPTCFG_MAC80211_LEDS
|
||||
+
|
||||
+#ifdef CONFIG_GPIOLIB
|
||||
+
|
||||
+/***************/
|
||||
+/* GPIO Chip */
|
||||
+/***************/
|
||||
+
|
||||
+/* gpio_chip handler : set GPIO to input */
|
||||
+static int ath9k_gpio_pin_cfg_input(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
|
||||
+ gchip);
|
||||
+
|
||||
+ ath9k_hw_gpio_request_in(gc->sc->sc_ah, offset, "ath9k-gpio");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* gpio_chip handler : set GPIO to output */
|
||||
+static int ath9k_gpio_pin_cfg_output(struct gpio_chip *chip, unsigned offset,
|
||||
+ int value)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
|
||||
+ gchip);
|
||||
+
|
||||
+ ath9k_hw_gpio_request_out(gc->sc->sc_ah, offset, "ath9k-gpio",
|
||||
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
|
||||
+ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* gpio_chip handler : query GPIO direction (0=out, 1=in) */
|
||||
+static int ath9k_gpio_pin_get_dir(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
|
||||
+ gchip);
|
||||
+ struct ath_hw *ah = gc->sc->sc_ah;
|
||||
+
|
||||
+ return !((REG_READ(ah, AR_GPIO_OE_OUT) >> (offset * 2)) & 3);
|
||||
+}
|
||||
+
|
||||
+/* gpio_chip handler : get GPIO pin value */
|
||||
+static int ath9k_gpio_pin_get(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
|
||||
+ gchip);
|
||||
+
|
||||
+ return ath9k_hw_gpio_get(gc->sc->sc_ah, offset);
|
||||
+}
|
||||
+
|
||||
+/* gpio_chip handler : set GPIO pin to value */
|
||||
+static void ath9k_gpio_pin_set(struct gpio_chip *chip, unsigned offset,
|
||||
+ int value)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
|
||||
+ gchip);
|
||||
+
|
||||
+ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value);
|
||||
+}
|
||||
+
|
||||
+/* register GPIO chip */
|
||||
+static void ath9k_register_gpio_chip(struct ath_softc *sc)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc;
|
||||
+ struct ath_hw *ah = sc->sc_ah;
|
||||
+
|
||||
+ gc = kzalloc(sizeof(struct ath9k_gpio_chip), GFP_KERNEL);
|
||||
+ if (!gc)
|
||||
+ return;
|
||||
+
|
||||
+ gc->sc = sc;
|
||||
+ snprintf(gc->label, sizeof(gc->label), "ath9k-%s",
|
||||
+ wiphy_name(sc->hw->wiphy));
|
||||
+#ifdef CONFIG_OF
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)
|
||||
+ gc->gchip.parent = sc->dev;
|
||||
+#else
|
||||
+ gc->gchip.dev = sc->dev;
|
||||
+#endif
|
||||
+#endif
|
||||
+ gc->gchip.label = gc->label;
|
||||
+ gc->gchip.base = -1; /* determine base automatically */
|
||||
+ gc->gchip.ngpio = ah->caps.num_gpio_pins;
|
||||
+ gc->gchip.direction_input = ath9k_gpio_pin_cfg_input;
|
||||
+ gc->gchip.direction_output = ath9k_gpio_pin_cfg_output;
|
||||
+ gc->gchip.get_direction = ath9k_gpio_pin_get_dir;
|
||||
+ gc->gchip.get = ath9k_gpio_pin_get;
|
||||
+ gc->gchip.set = ath9k_gpio_pin_set;
|
||||
+
|
||||
+ if (gpiochip_add(&gc->gchip)) {
|
||||
+ kfree(gc);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+#ifdef CONFIG_OF
|
||||
+ gc->gchip.owner = NULL;
|
||||
+#endif
|
||||
+ sc->gpiochip = gc;
|
||||
+}
|
||||
+
|
||||
+/* remove GPIO chip */
|
||||
+static void ath9k_unregister_gpio_chip(struct ath_softc *sc)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc = sc->gpiochip;
|
||||
+
|
||||
+ if (!gc)
|
||||
+ return;
|
||||
+
|
||||
+ gpiochip_remove(&gc->gchip);
|
||||
+ kfree(gc);
|
||||
+ sc->gpiochip = NULL;
|
||||
+}
|
||||
+
|
||||
+#else /* CONFIG_GPIOLIB */
|
||||
+
|
||||
+static inline void ath9k_register_gpio_chip(struct ath_softc *sc)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void ath9k_unregister_gpio_chip(struct ath_softc *sc)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+#endif /* CONFIG_GPIOLIB */
|
||||
|
||||
/********************************/
|
||||
/* LED functions */
|
||||
/********************************/
|
||||
|
||||
-#ifdef CPTCFG_MAC80211_LEDS
|
||||
-
|
||||
static void ath_fill_led_pin(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@@ -80,6 +206,12 @@ static int ath_add_led(struct ath_softc
|
||||
else
|
||||
ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low);
|
||||
|
||||
+#ifdef CONFIG_GPIOLIB
|
||||
+ /* If there is GPIO chip configured, reserve LED pin */
|
||||
+ if (sc->gpiochip)
|
||||
+ gpio_request(sc->gpiochip->gchip.base + gpio->gpio, gpio->name);
|
||||
+#endif
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -136,17 +268,24 @@ void ath_deinit_leds(struct ath_softc *s
|
||||
|
||||
while (!list_empty(&sc->leds)) {
|
||||
led = list_first_entry(&sc->leds, struct ath_led, list);
|
||||
+#ifdef CONFIG_GPIOLIB
|
||||
+ /* If there is GPIO chip configured, free LED pin */
|
||||
+ if (sc->gpiochip)
|
||||
+ gpio_free(sc->gpiochip->gchip.base + led->gpio->gpio);
|
||||
+#endif
|
||||
list_del(&led->list);
|
||||
ath_led_brightness(&led->cdev, LED_OFF);
|
||||
led_classdev_unregister(&led->cdev);
|
||||
ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio);
|
||||
kfree(led);
|
||||
}
|
||||
+ ath9k_unregister_gpio_chip(sc);
|
||||
}
|
||||
|
||||
void ath_init_leds(struct ath_softc *sc)
|
||||
{
|
||||
struct ath9k_platform_data *pdata = sc->dev->platform_data;
|
||||
+ struct device_node *np = sc->dev->of_node;
|
||||
char led_name[32];
|
||||
const char *trigger;
|
||||
int i;
|
||||
@@ -156,6 +295,15 @@ void ath_init_leds(struct ath_softc *sc)
|
||||
if (AR_SREV_9100(sc->sc_ah))
|
||||
return;
|
||||
|
||||
+ if (!np)
|
||||
+ ath9k_register_gpio_chip(sc);
|
||||
+
|
||||
+ /* setup gpio controller only if requested and skip the led_pin setup */
|
||||
+ if (of_property_read_bool(np, "gpio-controller")) {
|
||||
+ ath9k_register_gpio_chip(sc);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
ath_fill_led_pin(sc);
|
||||
|
||||
if (pdata && pdata->leds && pdata->num_leds)
|
||||
@@ -180,6 +328,7 @@ void ath_init_leds(struct ath_softc *sc)
|
||||
ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger,
|
||||
!sc->sc_ah->config.led_active_high);
|
||||
}
|
||||
+
|
||||
#endif
|
||||
|
||||
/*******************/
|
@ -1,317 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 25 Nov 2020 18:10:34 +0100
|
||||
Subject: [PATCH] net/fq_impl: do not maintain a backlog-sorted list of
|
||||
flows
|
||||
|
||||
A sorted flow list is only needed to drop packets in the biggest flow when
|
||||
hitting the overmemory condition.
|
||||
By scanning flows only when needed, we can avoid paying the cost of
|
||||
maintaining the list under normal conditions
|
||||
In order to avoid scanning lots of empty flows and touching too many cold
|
||||
cache lines, a bitmap of flows with backlog is maintained
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/include/net/fq.h
|
||||
+++ b/include/net/fq.h
|
||||
@@ -19,8 +19,6 @@ struct fq_tin;
|
||||
* @flowchain: can be linked to fq_tin's new_flows or old_flows. Used for DRR++
|
||||
* (deficit round robin) based round robin queuing similar to the one
|
||||
* found in net/sched/sch_fq_codel.c
|
||||
- * @backlogchain: can be linked to other fq_flow and fq. Used to keep track of
|
||||
- * fat flows and efficient head-dropping if packet limit is reached
|
||||
* @queue: sk_buff queue to hold packets
|
||||
* @backlog: number of bytes pending in the queue. The number of packets can be
|
||||
* found in @queue.qlen
|
||||
@@ -29,7 +27,6 @@ struct fq_tin;
|
||||
struct fq_flow {
|
||||
struct fq_tin *tin;
|
||||
struct list_head flowchain;
|
||||
- struct list_head backlogchain;
|
||||
struct sk_buff_head queue;
|
||||
u32 backlog;
|
||||
int deficit;
|
||||
@@ -47,6 +44,7 @@ struct fq_flow {
|
||||
struct fq_tin {
|
||||
struct list_head new_flows;
|
||||
struct list_head old_flows;
|
||||
+ struct list_head tin_list;
|
||||
struct fq_flow default_flow;
|
||||
u32 backlog_bytes;
|
||||
u32 backlog_packets;
|
||||
@@ -60,14 +58,14 @@ struct fq_tin {
|
||||
/**
|
||||
* struct fq - main container for fair queuing purposes
|
||||
*
|
||||
- * @backlogs: linked to fq_flows. Used to maintain fat flows for efficient
|
||||
- * head-dropping when @backlog reaches @limit
|
||||
* @limit: max number of packets that can be queued across all flows
|
||||
* @backlog: number of packets queued across all flows
|
||||
*/
|
||||
struct fq {
|
||||
struct fq_flow *flows;
|
||||
- struct list_head backlogs;
|
||||
+ unsigned long *flows_bitmap;
|
||||
+
|
||||
+ struct list_head tin_backlog;
|
||||
spinlock_t lock;
|
||||
u32 flows_cnt;
|
||||
u32 limit;
|
||||
--- a/include/net/fq_impl.h
|
||||
+++ b/include/net/fq_impl.h
|
||||
@@ -17,12 +17,24 @@ __fq_adjust_removal(struct fq *fq, struc
|
||||
unsigned int bytes, unsigned int truesize)
|
||||
{
|
||||
struct fq_tin *tin = flow->tin;
|
||||
+ int idx;
|
||||
|
||||
tin->backlog_bytes -= bytes;
|
||||
tin->backlog_packets -= packets;
|
||||
flow->backlog -= bytes;
|
||||
fq->backlog -= packets;
|
||||
fq->memory_usage -= truesize;
|
||||
+
|
||||
+ if (flow->backlog)
|
||||
+ return;
|
||||
+
|
||||
+ if (flow == &tin->default_flow) {
|
||||
+ list_del_init(&tin->tin_list);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ idx = flow - fq->flows;
|
||||
+ __clear_bit(idx, fq->flows_bitmap);
|
||||
}
|
||||
|
||||
static void fq_adjust_removal(struct fq *fq,
|
||||
@@ -32,24 +44,6 @@ static void fq_adjust_removal(struct fq
|
||||
__fq_adjust_removal(fq, flow, 1, skb->len, skb->truesize);
|
||||
}
|
||||
|
||||
-static void fq_rejigger_backlog(struct fq *fq, struct fq_flow *flow)
|
||||
-{
|
||||
- struct fq_flow *i;
|
||||
-
|
||||
- if (flow->backlog == 0) {
|
||||
- list_del_init(&flow->backlogchain);
|
||||
- } else {
|
||||
- i = flow;
|
||||
-
|
||||
- list_for_each_entry_continue(i, &fq->backlogs, backlogchain)
|
||||
- if (i->backlog < flow->backlog)
|
||||
- break;
|
||||
-
|
||||
- list_move_tail(&flow->backlogchain,
|
||||
- &i->backlogchain);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
static struct sk_buff *fq_flow_dequeue(struct fq *fq,
|
||||
struct fq_flow *flow)
|
||||
{
|
||||
@@ -62,7 +56,6 @@ static struct sk_buff *fq_flow_dequeue(s
|
||||
return NULL;
|
||||
|
||||
fq_adjust_removal(fq, flow, skb);
|
||||
- fq_rejigger_backlog(fq, flow);
|
||||
|
||||
return skb;
|
||||
}
|
||||
@@ -90,7 +83,6 @@ static int fq_flow_drop(struct fq *fq, s
|
||||
} while (packets < pending);
|
||||
|
||||
__fq_adjust_removal(fq, flow, packets, bytes, truesize);
|
||||
- fq_rejigger_backlog(fq, flow);
|
||||
|
||||
return packets;
|
||||
}
|
||||
@@ -170,22 +162,36 @@ static struct fq_flow *fq_flow_classify(
|
||||
return flow;
|
||||
}
|
||||
|
||||
-static void fq_recalc_backlog(struct fq *fq,
|
||||
- struct fq_tin *tin,
|
||||
- struct fq_flow *flow)
|
||||
-{
|
||||
- struct fq_flow *i;
|
||||
-
|
||||
- if (list_empty(&flow->backlogchain))
|
||||
- list_add_tail(&flow->backlogchain, &fq->backlogs);
|
||||
-
|
||||
- i = flow;
|
||||
- list_for_each_entry_continue_reverse(i, &fq->backlogs,
|
||||
- backlogchain)
|
||||
- if (i->backlog > flow->backlog)
|
||||
- break;
|
||||
+static struct fq_flow *fq_find_fattest_flow(struct fq *fq)
|
||||
+{
|
||||
+ struct fq_tin *tin;
|
||||
+ struct fq_flow *flow = NULL;
|
||||
+ u32 len = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ for_each_set_bit(i, fq->flows_bitmap, fq->flows_cnt) {
|
||||
+ struct fq_flow *cur = &fq->flows[i];
|
||||
+ unsigned int cur_len;
|
||||
+
|
||||
+ cur_len = cur->backlog;
|
||||
+ if (cur_len <= len)
|
||||
+ continue;
|
||||
+
|
||||
+ flow = cur;
|
||||
+ len = cur_len;
|
||||
+ }
|
||||
|
||||
- list_move(&flow->backlogchain, &i->backlogchain);
|
||||
+ list_for_each_entry(tin, &fq->tin_backlog, tin_list) {
|
||||
+ unsigned int cur_len = tin->default_flow.backlog;
|
||||
+
|
||||
+ if (cur_len <= len)
|
||||
+ continue;
|
||||
+
|
||||
+ flow = &tin->default_flow;
|
||||
+ len = cur_len;
|
||||
+ }
|
||||
+
|
||||
+ return flow;
|
||||
}
|
||||
|
||||
static void fq_tin_enqueue(struct fq *fq,
|
||||
@@ -200,6 +206,13 @@ static void fq_tin_enqueue(struct fq *fq
|
||||
|
||||
flow = fq_flow_classify(fq, tin, idx, skb);
|
||||
|
||||
+ if (!flow->backlog) {
|
||||
+ if (flow != &tin->default_flow)
|
||||
+ __set_bit(idx, fq->flows_bitmap);
|
||||
+ else if (list_empty(&tin->tin_list))
|
||||
+ list_add(&tin->tin_list, &fq->tin_backlog);
|
||||
+ }
|
||||
+
|
||||
flow->tin = tin;
|
||||
flow->backlog += skb->len;
|
||||
tin->backlog_bytes += skb->len;
|
||||
@@ -207,8 +220,6 @@ static void fq_tin_enqueue(struct fq *fq
|
||||
fq->memory_usage += skb->truesize;
|
||||
fq->backlog++;
|
||||
|
||||
- fq_recalc_backlog(fq, tin, flow);
|
||||
-
|
||||
if (list_empty(&flow->flowchain)) {
|
||||
flow->deficit = fq->quantum;
|
||||
list_add_tail(&flow->flowchain,
|
||||
@@ -218,9 +229,7 @@ static void fq_tin_enqueue(struct fq *fq
|
||||
__skb_queue_tail(&flow->queue, skb);
|
||||
oom = (fq->memory_usage > fq->memory_limit);
|
||||
while (fq->backlog > fq->limit || oom) {
|
||||
- flow = list_first_entry_or_null(&fq->backlogs,
|
||||
- struct fq_flow,
|
||||
- backlogchain);
|
||||
+ flow = fq_find_fattest_flow(fq);
|
||||
if (!flow)
|
||||
return;
|
||||
|
||||
@@ -255,8 +264,6 @@ static void fq_flow_filter(struct fq *fq
|
||||
fq_adjust_removal(fq, flow, skb);
|
||||
free_func(fq, tin, flow, skb);
|
||||
}
|
||||
-
|
||||
- fq_rejigger_backlog(fq, flow);
|
||||
}
|
||||
|
||||
static void fq_tin_filter(struct fq *fq,
|
||||
@@ -279,16 +286,18 @@ static void fq_flow_reset(struct fq *fq,
|
||||
struct fq_flow *flow,
|
||||
fq_skb_free_t free_func)
|
||||
{
|
||||
+ struct fq_tin *tin = flow->tin;
|
||||
struct sk_buff *skb;
|
||||
|
||||
while ((skb = fq_flow_dequeue(fq, flow)))
|
||||
- free_func(fq, flow->tin, flow, skb);
|
||||
+ free_func(fq, tin, flow, skb);
|
||||
|
||||
- if (!list_empty(&flow->flowchain))
|
||||
+ if (!list_empty(&flow->flowchain)) {
|
||||
list_del_init(&flow->flowchain);
|
||||
-
|
||||
- if (!list_empty(&flow->backlogchain))
|
||||
- list_del_init(&flow->backlogchain);
|
||||
+ if (list_empty(&tin->new_flows) &&
|
||||
+ list_empty(&tin->old_flows))
|
||||
+ list_del_init(&tin->tin_list);
|
||||
+ }
|
||||
|
||||
flow->tin = NULL;
|
||||
|
||||
@@ -314,6 +323,7 @@ static void fq_tin_reset(struct fq *fq,
|
||||
fq_flow_reset(fq, flow, free_func);
|
||||
}
|
||||
|
||||
+ WARN_ON_ONCE(!list_empty(&tin->tin_list));
|
||||
WARN_ON_ONCE(tin->backlog_bytes);
|
||||
WARN_ON_ONCE(tin->backlog_packets);
|
||||
}
|
||||
@@ -321,7 +331,6 @@ static void fq_tin_reset(struct fq *fq,
|
||||
static void fq_flow_init(struct fq_flow *flow)
|
||||
{
|
||||
INIT_LIST_HEAD(&flow->flowchain);
|
||||
- INIT_LIST_HEAD(&flow->backlogchain);
|
||||
__skb_queue_head_init(&flow->queue);
|
||||
}
|
||||
|
||||
@@ -329,6 +338,7 @@ static void fq_tin_init(struct fq_tin *t
|
||||
{
|
||||
INIT_LIST_HEAD(&tin->new_flows);
|
||||
INIT_LIST_HEAD(&tin->old_flows);
|
||||
+ INIT_LIST_HEAD(&tin->tin_list);
|
||||
fq_flow_init(&tin->default_flow);
|
||||
}
|
||||
|
||||
@@ -337,8 +347,8 @@ static int fq_init(struct fq *fq, int fl
|
||||
int i;
|
||||
|
||||
memset(fq, 0, sizeof(fq[0]));
|
||||
- INIT_LIST_HEAD(&fq->backlogs);
|
||||
spin_lock_init(&fq->lock);
|
||||
+ INIT_LIST_HEAD(&fq->tin_backlog);
|
||||
fq->flows_cnt = max_t(u32, flows_cnt, 1);
|
||||
fq->quantum = 300;
|
||||
fq->limit = 8192;
|
||||
@@ -348,6 +358,14 @@ static int fq_init(struct fq *fq, int fl
|
||||
if (!fq->flows)
|
||||
return -ENOMEM;
|
||||
|
||||
+ fq->flows_bitmap = kcalloc(BITS_TO_LONGS(fq->flows_cnt), sizeof(long),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!fq->flows_bitmap) {
|
||||
+ kvfree(fq->flows);
|
||||
+ fq->flows = NULL;
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < fq->flows_cnt; i++)
|
||||
fq_flow_init(&fq->flows[i]);
|
||||
|
||||
@@ -364,6 +382,9 @@ static void fq_reset(struct fq *fq,
|
||||
|
||||
kvfree(fq->flows);
|
||||
fq->flows = NULL;
|
||||
+
|
||||
+ kfree(fq->flows_bitmap);
|
||||
+ fq->flows_bitmap = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3386,8 +3386,6 @@ out_recalc:
|
||||
if (head->len != orig_len) {
|
||||
flow->backlog += head->len - orig_len;
|
||||
tin->backlog_bytes += head->len - orig_len;
|
||||
-
|
||||
- fq_recalc_backlog(fq, tin, flow);
|
||||
}
|
||||
out:
|
||||
spin_unlock_bh(&fq->lock);
|
@ -1,155 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
|
||||
@@ -978,55 +978,6 @@ static bool ar5008_hw_ani_control_new(st
|
||||
* on == 0 means more noise imm
|
||||
*/
|
||||
u32 on = param ? 1 : 0;
|
||||
- /*
|
||||
- * make register setting for default
|
||||
- * (weak sig detect ON) come from INI file
|
||||
- */
|
||||
- int m1ThreshLow = on ?
|
||||
- aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
|
||||
- int m2ThreshLow = on ?
|
||||
- aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
|
||||
- int m1Thresh = on ?
|
||||
- aniState->iniDef.m1Thresh : m1Thresh_off;
|
||||
- int m2Thresh = on ?
|
||||
- aniState->iniDef.m2Thresh : m2Thresh_off;
|
||||
- int m2CountThr = on ?
|
||||
- aniState->iniDef.m2CountThr : m2CountThr_off;
|
||||
- int m2CountThrLow = on ?
|
||||
- aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
|
||||
- int m1ThreshLowExt = on ?
|
||||
- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
|
||||
- int m2ThreshLowExt = on ?
|
||||
- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
|
||||
- int m1ThreshExt = on ?
|
||||
- aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
|
||||
- int m2ThreshExt = on ?
|
||||
- aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
|
||||
-
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
- AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
|
||||
- m1ThreshLow);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
- AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
|
||||
- m2ThreshLow);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
- AR_PHY_SFCORR_M1_THRESH, m1Thresh);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
- AR_PHY_SFCORR_M2_THRESH, m2Thresh);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
- AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
|
||||
- m2CountThrLow);
|
||||
-
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
|
||||
|
||||
if (on)
|
||||
REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
@@ -42,20 +42,6 @@ static const int cycpwrThr1_table[] =
|
||||
/* level: 0 1 2 3 4 5 6 7 8 */
|
||||
{ -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */
|
||||
|
||||
-/*
|
||||
- * register values to turn OFDM weak signal detection OFF
|
||||
- */
|
||||
-static const int m1ThreshLow_off = 127;
|
||||
-static const int m2ThreshLow_off = 127;
|
||||
-static const int m1Thresh_off = 127;
|
||||
-static const int m2Thresh_off = 127;
|
||||
-static const int m2CountThr_off = 31;
|
||||
-static const int m2CountThrLow_off = 63;
|
||||
-static const int m1ThreshLowExt_off = 127;
|
||||
-static const int m2ThreshLowExt_off = 127;
|
||||
-static const int m1ThreshExt_off = 127;
|
||||
-static const int m2ThreshExt_off = 127;
|
||||
-
|
||||
static const u8 ofdm2pwr[] = {
|
||||
ALL_TARGET_LEGACY_6_24,
|
||||
ALL_TARGET_LEGACY_6_24,
|
||||
@@ -1077,11 +1063,6 @@ static bool ar9003_hw_ani_control(struct
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ar5416AniState *aniState = &ah->ani;
|
||||
- int m1ThreshLow, m2ThreshLow;
|
||||
- int m1Thresh, m2Thresh;
|
||||
- int m2CountThr, m2CountThrLow;
|
||||
- int m1ThreshLowExt, m2ThreshLowExt;
|
||||
- int m1ThreshExt, m2ThreshExt;
|
||||
s32 value, value2;
|
||||
|
||||
switch (cmd & ah->ani_function) {
|
||||
@@ -1095,61 +1076,6 @@ static bool ar9003_hw_ani_control(struct
|
||||
*/
|
||||
u32 on = param ? 1 : 0;
|
||||
|
||||
- if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
|
||||
- goto skip_ws_det;
|
||||
-
|
||||
- m1ThreshLow = on ?
|
||||
- aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
|
||||
- m2ThreshLow = on ?
|
||||
- aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
|
||||
- m1Thresh = on ?
|
||||
- aniState->iniDef.m1Thresh : m1Thresh_off;
|
||||
- m2Thresh = on ?
|
||||
- aniState->iniDef.m2Thresh : m2Thresh_off;
|
||||
- m2CountThr = on ?
|
||||
- aniState->iniDef.m2CountThr : m2CountThr_off;
|
||||
- m2CountThrLow = on ?
|
||||
- aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
|
||||
- m1ThreshLowExt = on ?
|
||||
- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
|
||||
- m2ThreshLowExt = on ?
|
||||
- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
|
||||
- m1ThreshExt = on ?
|
||||
- aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
|
||||
- m2ThreshExt = on ?
|
||||
- aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
|
||||
-
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
- AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
|
||||
- m1ThreshLow);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
- AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
|
||||
- m2ThreshLow);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
- AR_PHY_SFCORR_M1_THRESH,
|
||||
- m1Thresh);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
- AR_PHY_SFCORR_M2_THRESH,
|
||||
- m2Thresh);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
- AR_PHY_SFCORR_M2COUNT_THR,
|
||||
- m2CountThr);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
|
||||
- m2CountThrLow);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
|
||||
- m1ThreshLowExt);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
|
||||
- m2ThreshLowExt);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M1_THRESH,
|
||||
- m1ThreshExt);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M2_THRESH,
|
||||
- m2ThreshExt);
|
||||
-skip_ws_det:
|
||||
if (on)
|
||||
REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
@ -1,47 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/Kconfig
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
|
||||
@@ -226,36 +226,37 @@ config RT2800SOC
|
||||
|
||||
|
||||
config RT2800_LIB
|
||||
- tristate
|
||||
+ tristate "RT2800 USB/PCI support"
|
||||
depends on m
|
||||
|
||||
config RT2800_LIB_MMIO
|
||||
- tristate
|
||||
+ tristate "RT2800 MMIO support"
|
||||
depends on m
|
||||
select RT2X00_LIB_MMIO
|
||||
select RT2800_LIB
|
||||
|
||||
config RT2X00_LIB_MMIO
|
||||
- tristate
|
||||
+ tristate "RT2x00 MMIO support"
|
||||
depends on m
|
||||
|
||||
config RT2X00_LIB_PCI
|
||||
- tristate
|
||||
+ tristate "RT2x00 PCI support"
|
||||
depends on m
|
||||
select RT2X00_LIB
|
||||
|
||||
config RT2X00_LIB_SOC
|
||||
- tristate
|
||||
+ tristate "RT2x00 SoC support"
|
||||
+ depends on SOC_RT288X || SOC_RT305X || SOC_MT7620
|
||||
depends on m
|
||||
select RT2X00_LIB
|
||||
|
||||
config RT2X00_LIB_USB
|
||||
- tristate
|
||||
+ tristate "RT2x00 USB support"
|
||||
depends on m
|
||||
select RT2X00_LIB
|
||||
|
||||
config RT2X00_LIB
|
||||
- tristate
|
||||
+ tristate "RT2x00 support"
|
||||
depends on m
|
||||
|
||||
config RT2X00_LIB_FIRMWARE
|
@ -1,142 +0,0 @@
|
||||
This adds a bwmode debugfs file which can be used to set alternate
|
||||
channel operating bandwidths. Only tested with AR5413 and only at
|
||||
5 and 20 mhz channels.
|
||||
|
||||
Signed-off-by: Pat Erley <pat-lkml at erley.org>
|
||||
---
|
||||
Other devices will need to be added to the switch in write_file_bwmode
|
||||
|
||||
drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++
|
||||
1 files changed, 86 insertions(+), 0 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath5k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath5k/debug.c
|
||||
@@ -803,6 +803,97 @@ static const struct file_operations fops
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
+/* debugfs: bwmode */
|
||||
+
|
||||
+static ssize_t read_file_bwmode(struct file *file, char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ath5k_hw *ah = file->private_data;
|
||||
+ char buf[15];
|
||||
+ unsigned int len = 0;
|
||||
+
|
||||
+ int cur_ah_bwmode = ah->ah_bwmode_debug;
|
||||
+
|
||||
+#define print_selected(MODE, LABEL) \
|
||||
+ if (cur_ah_bwmode == MODE) \
|
||||
+ len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \
|
||||
+ else \
|
||||
+ len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \
|
||||
+ len += snprintf(buf+len, sizeof(buf)-len, " ");
|
||||
+
|
||||
+ print_selected(AR5K_BWMODE_5MHZ, "5");
|
||||
+ print_selected(AR5K_BWMODE_10MHZ, "10");
|
||||
+ print_selected(AR5K_BWMODE_DEFAULT, "20");
|
||||
+ print_selected(AR5K_BWMODE_40MHZ, "40");
|
||||
+#undef print_selected
|
||||
+
|
||||
+ len += snprintf(buf+len, sizeof(buf)-len, "\n");
|
||||
+
|
||||
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
+}
|
||||
+
|
||||
+static ssize_t write_file_bwmode(struct file *file,
|
||||
+ const char __user *userbuf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ath5k_hw *ah = file->private_data;
|
||||
+ char buf[3];
|
||||
+ int bw = 20;
|
||||
+ int tobwmode = AR5K_BWMODE_DEFAULT;
|
||||
+
|
||||
+ if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ /* TODO: Add check for active interface */
|
||||
+
|
||||
+ if(strncmp(buf, "5", 1) == 0 ) {
|
||||
+ tobwmode = AR5K_BWMODE_5MHZ;
|
||||
+ bw = 5;
|
||||
+ } else if ( strncmp(buf, "10", 2) == 0 ) {
|
||||
+ tobwmode = AR5K_BWMODE_10MHZ;
|
||||
+ bw = 10;
|
||||
+ } else if ( strncmp(buf, "20", 2) == 0 ) {
|
||||
+ tobwmode = AR5K_BWMODE_DEFAULT;
|
||||
+ bw = 20;
|
||||
+ } else if ( strncmp(buf, "40", 2) == 0 ) {
|
||||
+ tobwmode = AR5K_BWMODE_40MHZ;
|
||||
+ bw = 40;
|
||||
+ } else
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n",
|
||||
+ bw, tobwmode);
|
||||
+
|
||||
+ switch (ah->ah_radio) {
|
||||
+ /* TODO: only define radios that actually support 5/10mhz channels */
|
||||
+ case AR5K_RF5413:
|
||||
+ case AR5K_RF5110:
|
||||
+ case AR5K_RF5111:
|
||||
+ case AR5K_RF5112:
|
||||
+ case AR5K_RF2413:
|
||||
+ case AR5K_RF2316:
|
||||
+ case AR5K_RF2317:
|
||||
+ case AR5K_RF2425:
|
||||
+ if(ah->ah_bwmode_debug != tobwmode) {
|
||||
+ mutex_lock(&ah->lock);
|
||||
+ ah->ah_bwmode = tobwmode;
|
||||
+ ah->ah_bwmode_debug = tobwmode;
|
||||
+ mutex_unlock(&ah->lock);
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations fops_bwmode = {
|
||||
+ .read = read_file_bwmode,
|
||||
+ .write = write_file_bwmode,
|
||||
+ .open = simple_open,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .llseek = default_llseek,
|
||||
+};
|
||||
|
||||
/* debugfs: queues etc */
|
||||
|
||||
@@ -997,6 +1088,8 @@ ath5k_debug_init_device(struct ath5k_hw
|
||||
debugfs_create_file("queue", 0600, phydir, ah, &fops_queue);
|
||||
debugfs_create_bool("32khz_clock", 0600, phydir,
|
||||
&ah->ah_use_32khz_clock);
|
||||
+ debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah,
|
||||
+ &fops_bwmode);
|
||||
}
|
||||
|
||||
/* functions used in other places */
|
||||
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
|
||||
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
|
||||
@@ -1372,6 +1372,7 @@ struct ath5k_hw {
|
||||
u8 ah_coverage_class;
|
||||
bool ah_ack_bitrate_high;
|
||||
u8 ah_bwmode;
|
||||
+ u8 ah_bwmode_debug;
|
||||
bool ah_short_slot;
|
||||
|
||||
/* Antenna Control */
|
||||
--- a/drivers/net/wireless/ath/ath5k/base.c
|
||||
+++ b/drivers/net/wireless/ath/ath5k/base.c
|
||||
@@ -466,6 +466,9 @@ ath5k_chan_set(struct ath5k_hw *ah, stru
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if (ah->ah_bwmode_debug != AR5K_BWMODE_DEFAULT)
|
||||
+ ah->ah_bwmode = ah->ah_bwmode_debug;
|
||||
+
|
||||
/*
|
||||
* To switch channels clear any pending DMA operations;
|
||||
* wait long enough for the RX fifo to drain, reset the
|
@ -1,46 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
|
||||
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
|
||||
@@ -86,13 +86,8 @@ ath5k_add_interface(struct ieee80211_hw
|
||||
goto end;
|
||||
}
|
||||
|
||||
- /* Don't allow other interfaces if one ad-hoc is configured.
|
||||
- * TODO: Fix the problems with ad-hoc and multiple other interfaces.
|
||||
- * We would need to operate the HW in ad-hoc mode to allow TSF updates
|
||||
- * for the IBSS, but this breaks with additional AP or STA interfaces
|
||||
- * at the moment. */
|
||||
- if (ah->num_adhoc_vifs ||
|
||||
- (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
|
||||
+ /* Don't allow more than one ad-hoc interface */
|
||||
+ if (ah->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) {
|
||||
ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n");
|
||||
ret = -ELNRNG;
|
||||
goto end;
|
||||
--- a/drivers/net/wireless/ath/ath5k/base.c
|
||||
+++ b/drivers/net/wireless/ath/ath5k/base.c
|
||||
@@ -1964,7 +1964,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
|
||||
}
|
||||
|
||||
if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +
|
||||
- ah->num_mesh_vifs > 1) ||
|
||||
+ ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) ||
|
||||
ah->opmode == NL80211_IFTYPE_MESH_POINT) {
|
||||
u64 tsf = ath5k_hw_get_tsf64(ah);
|
||||
u32 tsftu = TSF_TO_TU(tsf);
|
||||
@@ -2050,7 +2050,7 @@ ath5k_beacon_update_timers(struct ath5k_
|
||||
|
||||
intval = ah->bintval & AR5K_BEACON_PERIOD;
|
||||
if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
|
||||
- + ah->num_mesh_vifs > 1) {
|
||||
+ + ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) {
|
||||
intval /= ATH_BCBUF; /* staggered multi-bss beacons */
|
||||
if (intval < 15)
|
||||
ATH5K_WARN(ah, "intval %u is too low, min 15\n",
|
||||
@@ -2516,6 +2516,7 @@ static const struct ieee80211_iface_limi
|
||||
BIT(NL80211_IFTYPE_MESH_POINT) |
|
||||
#endif
|
||||
BIT(NL80211_IFTYPE_AP) },
|
||||
+ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_combination if_comb = {
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/ani.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ani.h
|
||||
@@ -42,7 +42,7 @@
|
||||
#define ATH9K_ANI_PERIOD 300
|
||||
|
||||
/* in ms */
|
||||
-#define ATH9K_ANI_POLLINTERVAL 1000
|
||||
+#define ATH9K_ANI_POLLINTERVAL 300
|
||||
|
||||
#define ATH9K_SIG_FIRSTEP_SETTING_MIN 0
|
||||
#define ATH9K_SIG_FIRSTEP_SETTING_MAX 20
|
@ -1,129 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 9 Jul 2016 15:26:44 +0200
|
||||
Subject: [PATCH] ath9k_hw: issue external reset for QCA955x
|
||||
|
||||
The RTC interface on the SoC needs to be reset along with the rest of
|
||||
the WMAC.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -1312,39 +1312,56 @@ void ath9k_hw_get_delta_slope_vals(struc
|
||||
*coef_exponent = coef_exp - 16;
|
||||
}
|
||||
|
||||
-/* AR9330 WAR:
|
||||
- * call external reset function to reset WMAC if:
|
||||
- * - doing a cold reset
|
||||
- * - we have pending frames in the TX queues.
|
||||
- */
|
||||
-static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type)
|
||||
+static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type)
|
||||
{
|
||||
- int i, npend = 0;
|
||||
+ int i;
|
||||
|
||||
- for (i = 0; i < AR_NUM_QCU; i++) {
|
||||
- npend = ath9k_hw_numtxpending(ah, i);
|
||||
- if (npend)
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if (ah->external_reset &&
|
||||
- (npend || type == ATH9K_RESET_COLD)) {
|
||||
- int reset_err = 0;
|
||||
-
|
||||
- ath_dbg(ath9k_hw_common(ah), RESET,
|
||||
- "reset MAC via external reset\n");
|
||||
-
|
||||
- reset_err = ah->external_reset();
|
||||
- if (reset_err) {
|
||||
- ath_err(ath9k_hw_common(ah),
|
||||
- "External reset failed, err=%d\n",
|
||||
- reset_err);
|
||||
- return false;
|
||||
+ if (type == ATH9K_RESET_COLD)
|
||||
+ return true;
|
||||
+
|
||||
+ if (AR_SREV_9550(ah))
|
||||
+ return true;
|
||||
+
|
||||
+ /* AR9330 WAR:
|
||||
+ * call external reset function to reset WMAC if:
|
||||
+ * - doing a cold reset
|
||||
+ * - we have pending frames in the TX queues.
|
||||
+ */
|
||||
+ if (AR_SREV_9330(ah)) {
|
||||
+ for (i = 0; i < AR_NUM_QCU; i++) {
|
||||
+ if (ath9k_hw_numtxpending(ah, i))
|
||||
+ return true;
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static bool ath9k_hw_external_reset(struct ath_hw *ah, int type)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type))
|
||||
+ return true;
|
||||
+
|
||||
+ ath_dbg(ath9k_hw_common(ah), RESET,
|
||||
+ "reset MAC via external reset\n");
|
||||
|
||||
- REG_WRITE(ah, AR_RTC_RESET, 1);
|
||||
+ err = ah->external_reset();
|
||||
+ if (err) {
|
||||
+ ath_err(ath9k_hw_common(ah),
|
||||
+ "External reset failed, err=%d\n", err);
|
||||
+ return false;
|
||||
}
|
||||
|
||||
+ if (AR_SREV_9550(ah)) {
|
||||
+ REG_WRITE(ah, AR_RTC_RESET, 0);
|
||||
+ udelay(10);
|
||||
+ }
|
||||
+
|
||||
+ REG_WRITE(ah, AR_RTC_RESET, 1);
|
||||
+ udelay(10);
|
||||
+
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1397,24 +1414,24 @@ static bool ath9k_hw_set_reset(struct at
|
||||
rst_flags |= AR_RTC_RC_MAC_COLD;
|
||||
}
|
||||
|
||||
- if (AR_SREV_9330(ah)) {
|
||||
- if (!ath9k_hw_ar9330_reset_war(ah, type))
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
if (ath9k_hw_mci_is_enabled(ah))
|
||||
ar9003_mci_check_gpm_offset(ah);
|
||||
|
||||
/* DMA HALT added to resolve ar9300 and ar9580 bus error during
|
||||
- * RTC_RC reg read
|
||||
+ * RTC_RC reg read. Also needed for AR9550 external reset
|
||||
*/
|
||||
- if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) {
|
||||
+ if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) {
|
||||
REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
|
||||
ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK,
|
||||
20 * AH_WAIT_TIMEOUT);
|
||||
- REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
|
||||
}
|
||||
|
||||
+ if (!AR_SREV_9100(ah))
|
||||
+ ath9k_hw_external_reset(ah, type);
|
||||
+
|
||||
+ if (AR_SREV_9300(ah) || AR_SREV_9580(ah))
|
||||
+ REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
|
||||
+
|
||||
REG_WRITE(ah, AR_RTC_RC, rst_flags);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
@ -1,191 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
append DRIVERS "mac80211"
|
||||
|
||||
lookup_phy() {
|
||||
[ -n "$phy" ] && {
|
||||
[ -d /sys/class/ieee80211/$phy ] && return
|
||||
}
|
||||
|
||||
local devpath
|
||||
config_get devpath "$device" path
|
||||
[ -n "$devpath" ] && {
|
||||
phy="$(iwinfo nl80211 phyname "path=$devpath")"
|
||||
[ -n "$phy" ] && return
|
||||
}
|
||||
|
||||
local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
|
||||
[ -n "$macaddr" ] && {
|
||||
for _phy in /sys/class/ieee80211/*; do
|
||||
[ -e "$_phy" ] || continue
|
||||
|
||||
[ "$macaddr" = "$(cat ${_phy}/macaddress)" ] || continue
|
||||
phy="${_phy##*/}"
|
||||
return
|
||||
done
|
||||
}
|
||||
phy=
|
||||
return
|
||||
}
|
||||
|
||||
find_mac80211_phy() {
|
||||
local device="$1"
|
||||
|
||||
config_get phy "$device" phy
|
||||
lookup_phy
|
||||
[ -n "$phy" -a -d "/sys/class/ieee80211/$phy" ] || {
|
||||
echo "PHY for wifi device $1 not found"
|
||||
return 1
|
||||
}
|
||||
config_set "$device" phy "$phy"
|
||||
|
||||
config_get macaddr "$device" macaddr
|
||||
[ -z "$macaddr" ] && {
|
||||
config_set "$device" macaddr "$(cat /sys/class/ieee80211/${phy}/macaddress)"
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
check_mac80211_device() {
|
||||
config_get phy "$1" phy
|
||||
[ -z "$phy" ] && {
|
||||
find_mac80211_phy "$1" >/dev/null || return 0
|
||||
config_get phy "$1" phy
|
||||
}
|
||||
[ "$phy" = "$dev" ] && found=1
|
||||
}
|
||||
|
||||
|
||||
__get_band_defaults() {
|
||||
local phy="$1"
|
||||
|
||||
( iw phy "$phy" info; echo ) | awk '
|
||||
BEGIN {
|
||||
bands = ""
|
||||
}
|
||||
|
||||
($1 == "Band" || $1 == "") && band {
|
||||
if (channel) {
|
||||
mode="NOHT"
|
||||
if (ht) mode="HT20"
|
||||
if (vht && band != "1:") mode="VHT80"
|
||||
if (he) mode="HE80"
|
||||
if (he && band == "1:") mode="HE20"
|
||||
sub("\\[", "", channel)
|
||||
sub("\\]", "", channel)
|
||||
bands = bands band channel ":" mode " "
|
||||
}
|
||||
band=""
|
||||
}
|
||||
|
||||
$1 == "Band" {
|
||||
band = $2
|
||||
channel = ""
|
||||
vht = ""
|
||||
ht = ""
|
||||
he = ""
|
||||
}
|
||||
|
||||
$0 ~ "Capabilities:" {
|
||||
ht=1
|
||||
}
|
||||
|
||||
$0 ~ "VHT Capabilities" {
|
||||
vht=1
|
||||
}
|
||||
|
||||
$0 ~ "HE Iftypes" {
|
||||
he=1
|
||||
}
|
||||
|
||||
$1 == "*" && $3 == "MHz" && $0 !~ /disabled/ && band && !channel {
|
||||
channel = $4
|
||||
}
|
||||
|
||||
END {
|
||||
print bands
|
||||
}'
|
||||
}
|
||||
|
||||
get_band_defaults() {
|
||||
local phy="$1"
|
||||
|
||||
for c in $(__get_band_defaults "$phy"); do
|
||||
local band="${c%%:*}"
|
||||
c="${c#*:}"
|
||||
local chan="${c%%:*}"
|
||||
c="${c#*:}"
|
||||
local mode="${c%%:*}"
|
||||
|
||||
case "$band" in
|
||||
1) band=2g;;
|
||||
2) band=5g;;
|
||||
3) band=60g;;
|
||||
4) band=6g;;
|
||||
*) band="";;
|
||||
esac
|
||||
|
||||
[ -n "$band" ] || continue
|
||||
[ -n "$mode_band" -a "$band" = "6g" ] && return
|
||||
|
||||
mode_band="$band"
|
||||
channel="$chan"
|
||||
htmode="$mode"
|
||||
done
|
||||
}
|
||||
|
||||
detect_mac80211() {
|
||||
devidx=0
|
||||
config_load wireless
|
||||
while :; do
|
||||
config_get type "radio$devidx" type
|
||||
[ -n "$type" ] || break
|
||||
devidx=$(($devidx + 1))
|
||||
done
|
||||
|
||||
for _dev in /sys/class/ieee80211/*; do
|
||||
[ -e "$_dev" ] || continue
|
||||
|
||||
dev="${_dev##*/}"
|
||||
|
||||
found=0
|
||||
config_foreach check_mac80211_device wifi-device
|
||||
[ "$found" -gt 0 ] && continue
|
||||
|
||||
mode_band=""
|
||||
channel=""
|
||||
htmode=""
|
||||
ht_capab=""
|
||||
|
||||
get_band_defaults "$dev"
|
||||
|
||||
path="$(iwinfo nl80211 path "$dev")"
|
||||
if [ -n "$path" ]; then
|
||||
dev_id="set wireless.radio${devidx}.path='$path'"
|
||||
else
|
||||
dev_id="set wireless.radio${devidx}.macaddr=$(cat /sys/class/ieee80211/${dev}/macaddress)"
|
||||
fi
|
||||
|
||||
uci -q batch <<-EOF
|
||||
set wireless.radio${devidx}=wifi-device
|
||||
set wireless.radio${devidx}.type=mac80211
|
||||
${dev_id}
|
||||
set wireless.radio${devidx}.channel=${channel}
|
||||
set wireless.radio${devidx}.band=${mode_band}
|
||||
set wireless.radio${devidx}.htmode=$htmode
|
||||
set wireless.radio${devidx}.country=US
|
||||
set wireless.radio${devidx}.disabled=0
|
||||
|
||||
set wireless.default_radio${devidx}=wifi-iface
|
||||
set wireless.default_radio${devidx}.device=radio${devidx}
|
||||
set wireless.default_radio${devidx}.network=lan
|
||||
set wireless.default_radio${devidx}.mode=ap
|
||||
set wireless.default_radio${devidx}.ssid=OpenWrt
|
||||
set wireless.default_radio${devidx}.encryption=none
|
||||
EOF
|
||||
uci -q commit wireless
|
||||
|
||||
devidx=$(($devidx + 1))
|
||||
done
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
From: Ryder Lee <ryder.lee@mediatek.com>
|
||||
Date: Fri, 18 Jun 2021 04:38:59 +0800
|
||||
Subject: [PATCH] mac80211: check per vif offload_flags in Tx path
|
||||
|
||||
offload_flags has been introduced to indicate encap status of each interface.
|
||||
An interface can encap offload at runtime, or if it has some extra limitations
|
||||
it can simply override the flags, so it's more flexible to check offload_flags
|
||||
in Tx path.
|
||||
|
||||
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
||||
Link: https://lore.kernel.org/r/177785418cf407808bf3a44760302d0647076990.1623961575.git.ryder.lee@mediatek.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3331,6 +3331,9 @@ static bool ieee80211_amsdu_aggregate(st
|
||||
if (!ieee80211_hw_check(&local->hw, TX_AMSDU))
|
||||
return false;
|
||||
|
||||
+ if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
|
||||
+ return false;
|
||||
+
|
||||
if (skb_is_gso(skb))
|
||||
return false;
|
||||
|
@ -1,51 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/regd.c
|
||||
+++ b/drivers/net/wireless/ath/regd.c
|
||||
@@ -115,6 +115,16 @@ static const struct ieee80211_regdomain
|
||||
)
|
||||
};
|
||||
|
||||
+static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
|
||||
+{
|
||||
+ return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
|
||||
+}
|
||||
+
|
||||
+static bool is_default_regd(struct ath_regulatory *reg)
|
||||
+{
|
||||
+ return ath_regd_get_eepromRD(reg) == CTRY_DEFAULT;
|
||||
+}
|
||||
+
|
||||
static bool dynamic_country_user_possible(struct ath_regulatory *reg)
|
||||
{
|
||||
if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
|
||||
@@ -123,6 +133,9 @@ static bool dynamic_country_user_possibl
|
||||
if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
|
||||
return true;
|
||||
|
||||
+ if (is_default_regd(reg))
|
||||
+ return true;
|
||||
+
|
||||
switch (reg->country_code) {
|
||||
case CTRY_UNITED_STATES:
|
||||
case CTRY_JAPAN1:
|
||||
@@ -208,11 +221,6 @@ static inline bool is_wwr_sku(u16 regd)
|
||||
(regd == WORLD));
|
||||
}
|
||||
|
||||
-static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
|
||||
-{
|
||||
- return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
|
||||
-}
|
||||
-
|
||||
bool ath_is_world_regd(struct ath_regulatory *reg)
|
||||
{
|
||||
return is_wwr_sku(ath_regd_get_eepromRD(reg));
|
||||
@@ -658,6 +666,9 @@ ath_regd_init_wiphy(struct ath_regulator
|
||||
if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
|
||||
return 0;
|
||||
|
||||
+ if (is_default_regd(reg))
|
||||
+ return 0;
|
||||
+
|
||||
wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
|
||||
REGULATORY_CUSTOM_REG;
|
||||
|
@ -1,609 +0,0 @@
|
||||
From: Sebastian Gottschall <s.gottschall@newmedia-net.de>
|
||||
|
||||
Adds LED and GPIO Control support for 988x, 9887, 9888, 99x0, 9984 based
|
||||
chipsets with on chipset connected led's using WMI Firmware API. The LED
|
||||
device will get available named as "ath10k-phyX" at sysfs and can be controlled
|
||||
with various triggers. adds also debugfs interface for gpio control.
|
||||
|
||||
This patch is specific for OpenWRt base, as is use old backported package
|
||||
with old wireless source. Support for QCA9984 is removed and a simbol
|
||||
is added to local-simbol file to export the actually compile the code
|
||||
with the ATH10K_LEDS simbol.
|
||||
|
||||
|
||||
Signed-off-by: Sebastian Gottschall <s.gottschall@dd-wrt.com>
|
||||
Reviewed-by: Steve deRosier <derosier@cal-sierra.com>
|
||||
[kvalo: major reorg and cleanup]
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||
---
|
||||
|
||||
v13:
|
||||
|
||||
* only compile tested!
|
||||
|
||||
* fix all checkpatch warnings
|
||||
|
||||
* fix commit log
|
||||
|
||||
* sizeof(struct ath10k_gpiocontrol) -> sizeof(*gpio)
|
||||
|
||||
* unsigned -> unsigned int
|
||||
|
||||
* remove GPIOLIB code, that should be added in a separate patch
|
||||
|
||||
* rename gpio.c to leds.c
|
||||
|
||||
* add leds.h
|
||||
|
||||
* rename some functions:
|
||||
|
||||
ath10k_attach_led() -> ath10k_leds_register()
|
||||
ath10k_unregister_led() -> ath10k_leds_unregister()
|
||||
ath10k_reset_led_pin() -> ath10k_leds_start()
|
||||
|
||||
* call ath10k_leds_unregister() before ath10k_thermal_unregister() to preserve ordering
|
||||
|
||||
* call ath10k_leds_start() only from ath10k_core_start() and not from mac.c
|
||||
|
||||
* rename struct ath10k_gpiocontrol as anonymous function under struct
|
||||
ath10k::leds, no need for memory allocation
|
||||
|
||||
* merge ath10k_add_led() to ath10k_attach_led(), which is it's only caller
|
||||
|
||||
* remove #if IS_ENABLED() checks from most of places, memory savings from those were not worth it
|
||||
|
||||
* Kconfig help text improvement and move it lower in the menu, also don't enable it by default
|
||||
|
||||
* switch to set_brightness_blocking() so that the callback can sleep,
|
||||
then no need to use ath10k_wmi_cmd_send_nowait() and can take mutex
|
||||
to access ar->state
|
||||
|
||||
* don't touch ath10k_wmi_pdev_get_temperature()
|
||||
|
||||
* as QCA6174/QCA9377 are not (yet) supported don't add the command to WMI-TLV interface
|
||||
|
||||
* remove debugfs interface, that should be added in another patch
|
||||
|
||||
* cleanup includes
|
||||
|
||||
|
||||
drivers/net/wireless/ath/ath10k/Kconfig | 10 +++
|
||||
drivers/net/wireless/ath/ath10k/Makefile | 1 +
|
||||
drivers/net/wireless/ath/ath10k/core.c | 22 +++++++
|
||||
drivers/net/wireless/ath/ath10k/core.h | 9 ++-
|
||||
drivers/net/wireless/ath/ath10k/hw.h | 1 +
|
||||
drivers/net/wireless/ath/ath10k/leds.c | 103 ++++++++++++++++++++++++++++++
|
||||
drivers/net/wireless/ath/ath10k/leds.h | 45 +++++++++++++
|
||||
drivers/net/wireless/ath/ath10k/mac.c | 1 +
|
||||
drivers/net/wireless/ath/ath10k/wmi-ops.h | 32 ++++++++++
|
||||
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 +
|
||||
drivers/net/wireless/ath/ath10k/wmi.c | 54 ++++++++++++++++
|
||||
drivers/net/wireless/ath/ath10k/wmi.h | 35 ++++++++++
|
||||
12 files changed, 314 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/wireless/ath/ath10k/leds.c
|
||||
create mode 100644 drivers/net/wireless/ath/ath10k/leds.h
|
||||
--- a/drivers/net/wireless/ath/ath10k/Kconfig
|
||||
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
|
||||
@@ -70,6 +70,16 @@ config ATH10K_DEBUGFS
|
||||
|
||||
If unsure, say Y to make it easier to debug problems.
|
||||
|
||||
+config ATH10K_LEDS
|
||||
+ bool "Atheros ath10k LED support"
|
||||
+ depends on ATH10K
|
||||
+ select MAC80211_LEDS
|
||||
+ select LEDS_CLASS
|
||||
+ select NEW_LEDS
|
||||
+ default y
|
||||
+ ---help---
|
||||
+ This option is necessary, if you want LED support for chipset connected led pins. If unsure, say N.
|
||||
+
|
||||
config ATH10K_SPECTRAL
|
||||
bool "Atheros ath10k spectral scan support"
|
||||
depends on ATH10K_DEBUGFS
|
||||
--- a/drivers/net/wireless/ath/ath10k/Makefile
|
||||
+++ b/drivers/net/wireless/ath/ath10k/Makefile
|
||||
@@ -19,6 +19,7 @@ ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) +=
|
||||
ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o
|
||||
ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o
|
||||
ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o
|
||||
+ath10k_core-$(CPTCFG_ATH10K_LEDS) += leds.o
|
||||
ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o
|
||||
ath10k_core-$(CONFIG_PM) += wow.o
|
||||
ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -145,6 +145,7 @@ ATH10K_DEBUG=
|
||||
ATH10K_DEBUGFS=
|
||||
ATH10K_SPECTRAL=
|
||||
ATH10K_THERMAL=
|
||||
+ATH10K_LEDS=
|
||||
ATH10K_TRACING=
|
||||
ATH10K_DFS_CERTIFIED=
|
||||
WCN36XX=
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "testmode.h"
|
||||
#include "wmi-ops.h"
|
||||
#include "coredump.h"
|
||||
+#include "leds.h"
|
||||
|
||||
unsigned int ath10k_debug_mask;
|
||||
EXPORT_SYMBOL(ath10k_debug_mask);
|
||||
@@ -61,6 +62,7 @@ static const struct ath10k_hw_params ath
|
||||
.dev_id = QCA988X_2_0_DEVICE_ID,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.name = "qca988x hw2.0",
|
||||
+ .led_pin = 1,
|
||||
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
||||
@@ -130,6 +132,7 @@ static const struct ath10k_hw_params ath
|
||||
.dev_id = QCA9887_1_0_DEVICE_ID,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.name = "qca9887 hw1.0",
|
||||
+ .led_pin = 1,
|
||||
.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
||||
@@ -335,6 +338,7 @@ static const struct ath10k_hw_params ath
|
||||
.dev_id = QCA99X0_2_0_DEVICE_ID,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.name = "qca99x0 hw2.0",
|
||||
+ .led_pin = 17,
|
||||
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.otp_exe_param = 0x00000700,
|
||||
@@ -375,6 +379,7 @@ static const struct ath10k_hw_params ath
|
||||
.dev_id = QCA9984_1_0_DEVICE_ID,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.name = "qca9984/qca9994 hw1.0",
|
||||
+ .led_pin = 17,
|
||||
.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
||||
@@ -422,6 +427,7 @@ static const struct ath10k_hw_params ath
|
||||
.dev_id = QCA9888_2_0_DEVICE_ID,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.name = "qca9888 hw2.0",
|
||||
+ .led_pin = 17,
|
||||
.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
||||
@@ -2904,6 +2910,10 @@ int ath10k_core_start(struct ath10k *ar,
|
||||
goto err_hif_stop;
|
||||
}
|
||||
|
||||
+ status = ath10k_leds_start(ar);
|
||||
+ if (status)
|
||||
+ goto err_hif_stop;
|
||||
+
|
||||
return 0;
|
||||
|
||||
err_hif_stop:
|
||||
@@ -3162,9 +3172,18 @@ static void ath10k_core_register_work(st
|
||||
goto err_spectral_destroy;
|
||||
}
|
||||
|
||||
+ status = ath10k_leds_register(ar);
|
||||
+ if (status) {
|
||||
+ ath10k_err(ar, "could not register leds: %d\n",
|
||||
+ status);
|
||||
+ goto err_thermal_unregister;
|
||||
+ }
|
||||
+
|
||||
set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
|
||||
return;
|
||||
|
||||
+err_thermal_unregister:
|
||||
+ ath10k_thermal_unregister(ar);
|
||||
err_spectral_destroy:
|
||||
ath10k_spectral_destroy(ar);
|
||||
err_debug_destroy:
|
||||
@@ -3210,6 +3229,8 @@ void ath10k_core_unregister(struct ath10
|
||||
if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
|
||||
return;
|
||||
|
||||
+ ath10k_leds_unregister(ar);
|
||||
+
|
||||
ath10k_thermal_unregister(ar);
|
||||
/* Stop spectral before unregistering from mac80211 to remove the
|
||||
* relayfs debugfs file cleanly. Otherwise the parent debugfs tree
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.h
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/uuid.h>
|
||||
#include <linux/time.h>
|
||||
+#include <linux/leds.h>
|
||||
|
||||
#include "htt.h"
|
||||
#include "htc.h"
|
||||
@@ -1237,6 +1238,13 @@ struct ath10k {
|
||||
} testmode;
|
||||
|
||||
struct {
|
||||
+ struct gpio_led wifi_led;
|
||||
+ struct led_classdev cdev;
|
||||
+ char label[48];
|
||||
+ u32 gpio_state_pin;
|
||||
+ } leds;
|
||||
+
|
||||
+ struct {
|
||||
/* protected by data_lock */
|
||||
u32 rx_crc_err_drop;
|
||||
u32 fw_crash_counter;
|
||||
--- a/drivers/net/wireless/ath/ath10k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/hw.h
|
||||
@@ -517,6 +517,7 @@ struct ath10k_hw_params {
|
||||
const char *name;
|
||||
u32 patch_load_addr;
|
||||
int uart_pin;
|
||||
+ int led_pin;
|
||||
u32 otp_exe_param;
|
||||
|
||||
/* Type of hw cycle counter wraparound logic, for more info
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/wireless/ath/ath10k/leds.c
|
||||
@@ -0,0 +1,103 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
+ * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
||||
+ * Copyright (c) 2018 Sebastian Gottschall <s.gottschall@dd-wrt.com>
|
||||
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and/or distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/leds.h>
|
||||
+
|
||||
+#include "core.h"
|
||||
+#include "wmi.h"
|
||||
+#include "wmi-ops.h"
|
||||
+
|
||||
+#include "leds.h"
|
||||
+
|
||||
+static int ath10k_leds_set_brightness_blocking(struct led_classdev *led_cdev,
|
||||
+ enum led_brightness brightness)
|
||||
+{
|
||||
+ struct ath10k *ar = container_of(led_cdev, struct ath10k,
|
||||
+ leds.cdev);
|
||||
+ struct gpio_led *led = &ar->leds.wifi_led;
|
||||
+
|
||||
+ mutex_lock(&ar->conf_mutex);
|
||||
+
|
||||
+ if (ar->state != ATH10K_STATE_ON)
|
||||
+ goto out;
|
||||
+
|
||||
+ ar->leds.gpio_state_pin = (brightness != LED_OFF) ^ led->active_low;
|
||||
+ ath10k_wmi_gpio_output(ar, led->gpio, ar->leds.gpio_state_pin);
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&ar->conf_mutex);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int ath10k_leds_start(struct ath10k *ar)
|
||||
+{
|
||||
+ if (ar->hw_params.led_pin == 0)
|
||||
+ /* leds not supported */
|
||||
+ return 0;
|
||||
+
|
||||
+ /* under some circumstances, the gpio pin gets reconfigured
|
||||
+ * to default state by the firmware, so we need to
|
||||
+ * reconfigure it this behaviour has only ben seen on
|
||||
+ * QCA9984 and QCA99XX devices so far
|
||||
+ */
|
||||
+ ath10k_wmi_gpio_config(ar, ar->hw_params.led_pin, 0,
|
||||
+ WMI_GPIO_PULL_NONE, WMI_GPIO_INTTYPE_DISABLE);
|
||||
+ ath10k_wmi_gpio_output(ar, ar->hw_params.led_pin, 1);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int ath10k_leds_register(struct ath10k *ar)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (ar->hw_params.led_pin == 0)
|
||||
+ /* leds not supported */
|
||||
+ return 0;
|
||||
+
|
||||
+ snprintf(ar->leds.label, sizeof(ar->leds.label), "ath10k-%s",
|
||||
+ wiphy_name(ar->hw->wiphy));
|
||||
+ ar->leds.wifi_led.active_low = 1;
|
||||
+ ar->leds.wifi_led.gpio = ar->hw_params.led_pin;
|
||||
+ ar->leds.wifi_led.name = ar->leds.label;
|
||||
+ ar->leds.wifi_led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
|
||||
+
|
||||
+ ar->leds.cdev.name = ar->leds.label;
|
||||
+ ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking;
|
||||
+
|
||||
+ /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */
|
||||
+ ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger;
|
||||
+
|
||||
+ ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void ath10k_leds_unregister(struct ath10k *ar)
|
||||
+{
|
||||
+ if (ar->hw_params.led_pin == 0)
|
||||
+ /* leds not supported */
|
||||
+ return;
|
||||
+
|
||||
+ led_classdev_unregister(&ar->leds.cdev);
|
||||
+}
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/wireless/ath/ath10k/leds.h
|
||||
@@ -0,0 +1,41 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and/or distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+#ifndef _LEDS_H_
|
||||
+#define _LEDS_H_
|
||||
+
|
||||
+#include "core.h"
|
||||
+
|
||||
+#ifdef CPTCFG_ATH10K_LEDS
|
||||
+void ath10k_leds_unregister(struct ath10k *ar);
|
||||
+int ath10k_leds_start(struct ath10k *ar);
|
||||
+int ath10k_leds_register(struct ath10k *ar);
|
||||
+#else
|
||||
+static inline void ath10k_leds_unregister(struct ath10k *ar)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline int ath10k_leds_start(struct ath10k *ar)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int ath10k_leds_register(struct ath10k *ar)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+#endif /* _LEDS_H_ */
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "wmi-tlv.h"
|
||||
#include "wmi-ops.h"
|
||||
#include "wow.h"
|
||||
+#include "leds.h"
|
||||
|
||||
/*********/
|
||||
/* Rates */
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
|
||||
@@ -226,7 +226,10 @@ struct wmi_ops {
|
||||
const struct wmi_bb_timing_cfg_arg *arg);
|
||||
struct sk_buff *(*gen_per_peer_per_tid_cfg)(struct ath10k *ar,
|
||||
const struct wmi_per_peer_per_tid_cfg_arg *arg);
|
||||
+ struct sk_buff *(*gen_gpio_config)(struct ath10k *ar, u32 gpio_num,
|
||||
+ u32 input, u32 pull_type, u32 intr_mode);
|
||||
|
||||
+ struct sk_buff *(*gen_gpio_output)(struct ath10k *ar, u32 gpio_num, u32 set);
|
||||
};
|
||||
|
||||
int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
|
||||
@@ -1122,6 +1125,35 @@ ath10k_wmi_force_fw_hang(struct ath10k *
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);
|
||||
}
|
||||
|
||||
+static inline int ath10k_wmi_gpio_config(struct ath10k *ar, u32 gpio_num,
|
||||
+ u32 input, u32 pull_type, u32 intr_mode)
|
||||
+{
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ if (!ar->wmi.ops->gen_gpio_config)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ skb = ar->wmi.ops->gen_gpio_config(ar, gpio_num, input, pull_type, intr_mode);
|
||||
+ if (IS_ERR(skb))
|
||||
+ return PTR_ERR(skb);
|
||||
+
|
||||
+ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_config_cmdid);
|
||||
+}
|
||||
+
|
||||
+static inline int ath10k_wmi_gpio_output(struct ath10k *ar, u32 gpio_num, u32 set)
|
||||
+{
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ if (!ar->wmi.ops->gen_gpio_config)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ skb = ar->wmi.ops->gen_gpio_output(ar, gpio_num, set);
|
||||
+ if (IS_ERR(skb))
|
||||
+ return PTR_ERR(skb);
|
||||
+
|
||||
+ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_output_cmdid);
|
||||
+}
|
||||
+
|
||||
static inline int
|
||||
ath10k_wmi_dbglog_cfg(struct ath10k *ar, u64 module_enable, u32 log_level)
|
||||
{
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
|
||||
@@ -4594,6 +4594,8 @@ static const struct wmi_ops wmi_tlv_ops
|
||||
.gen_echo = ath10k_wmi_tlv_op_gen_echo,
|
||||
.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
|
||||
.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
|
||||
+ /* .gen_gpio_config not implemented */
|
||||
+ /* .gen_gpio_output not implemented */
|
||||
};
|
||||
|
||||
static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -7468,6 +7468,49 @@ ath10k_wmi_op_gen_peer_set_param(struct
|
||||
return skb;
|
||||
}
|
||||
|
||||
+static struct sk_buff *ath10k_wmi_op_gen_gpio_config(struct ath10k *ar,
|
||||
+ u32 gpio_num, u32 input,
|
||||
+ u32 pull_type, u32 intr_mode)
|
||||
+{
|
||||
+ struct wmi_gpio_config_cmd *cmd;
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
|
||||
+ if (!skb)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ cmd = (struct wmi_gpio_config_cmd *)skb->data;
|
||||
+ cmd->pull_type = __cpu_to_le32(pull_type);
|
||||
+ cmd->gpio_num = __cpu_to_le32(gpio_num);
|
||||
+ cmd->input = __cpu_to_le32(input);
|
||||
+ cmd->intr_mode = __cpu_to_le32(intr_mode);
|
||||
+
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_config gpio_num 0x%08x input 0x%08x pull_type 0x%08x intr_mode 0x%08x\n",
|
||||
+ gpio_num, input, pull_type, intr_mode);
|
||||
+
|
||||
+ return skb;
|
||||
+}
|
||||
+
|
||||
+static struct sk_buff *ath10k_wmi_op_gen_gpio_output(struct ath10k *ar,
|
||||
+ u32 gpio_num, u32 set)
|
||||
+{
|
||||
+ struct wmi_gpio_output_cmd *cmd;
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
|
||||
+ if (!skb)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ cmd = (struct wmi_gpio_output_cmd *)skb->data;
|
||||
+ cmd->gpio_num = __cpu_to_le32(gpio_num);
|
||||
+ cmd->set = __cpu_to_le32(set);
|
||||
+
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_output gpio_num 0x%08x set 0x%08x\n",
|
||||
+ gpio_num, set);
|
||||
+
|
||||
+ return skb;
|
||||
+}
|
||||
+
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_sta_ps_mode psmode)
|
||||
@@ -9156,6 +9199,9 @@ static const struct wmi_ops wmi_ops = {
|
||||
.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
.gen_echo = ath10k_wmi_op_gen_echo,
|
||||
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
||||
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
||||
+
|
||||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
@@ -9226,6 +9272,8 @@ static const struct wmi_ops wmi_10_1_ops
|
||||
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
.gen_echo = ath10k_wmi_op_gen_echo,
|
||||
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
||||
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
||||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
@@ -9298,6 +9346,8 @@ static const struct wmi_ops wmi_10_2_ops
|
||||
.gen_delba_send = ath10k_wmi_op_gen_delba_send,
|
||||
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
||||
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
||||
/* .gen_pdev_enable_adaptive_cca not implemented */
|
||||
};
|
||||
|
||||
@@ -9369,6 +9419,8 @@ static const struct wmi_ops wmi_10_2_4_o
|
||||
ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
|
||||
.get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype,
|
||||
.gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing,
|
||||
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
||||
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
||||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
@@ -9450,6 +9502,8 @@ static const struct wmi_ops wmi_10_4_ops
|
||||
.gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info,
|
||||
.gen_echo = ath10k_wmi_op_gen_echo,
|
||||
.gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
|
||||
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
||||
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
||||
};
|
||||
|
||||
int ath10k_wmi_attach(struct ath10k *ar)
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
@@ -3027,6 +3027,41 @@ enum wmi_10_4_feature_mask {
|
||||
|
||||
};
|
||||
|
||||
+/* WMI_GPIO_CONFIG_CMDID */
|
||||
+enum {
|
||||
+ WMI_GPIO_PULL_NONE,
|
||||
+ WMI_GPIO_PULL_UP,
|
||||
+ WMI_GPIO_PULL_DOWN,
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ WMI_GPIO_INTTYPE_DISABLE,
|
||||
+ WMI_GPIO_INTTYPE_RISING_EDGE,
|
||||
+ WMI_GPIO_INTTYPE_FALLING_EDGE,
|
||||
+ WMI_GPIO_INTTYPE_BOTH_EDGE,
|
||||
+ WMI_GPIO_INTTYPE_LEVEL_LOW,
|
||||
+ WMI_GPIO_INTTYPE_LEVEL_HIGH
|
||||
+};
|
||||
+
|
||||
+/* WMI_GPIO_CONFIG_CMDID */
|
||||
+struct wmi_gpio_config_cmd {
|
||||
+ __le32 gpio_num; /* GPIO number to be setup */
|
||||
+ __le32 input; /* 0 - Output/ 1 - Input */
|
||||
+ __le32 pull_type; /* Pull type defined above */
|
||||
+ __le32 intr_mode; /* Interrupt mode defined above (Input) */
|
||||
+} __packed;
|
||||
+
|
||||
+/* WMI_GPIO_OUTPUT_CMDID */
|
||||
+struct wmi_gpio_output_cmd {
|
||||
+ __le32 gpio_num; /* GPIO number to be setup */
|
||||
+ __le32 set; /* Set the GPIO pin*/
|
||||
+} __packed;
|
||||
+
|
||||
+/* WMI_GPIO_INPUT_EVENTID */
|
||||
+struct wmi_gpio_input_event {
|
||||
+ __le32 gpio_num; /* GPIO number which changed state */
|
||||
+} __packed;
|
||||
+
|
||||
struct wmi_ext_resource_config_10_4_cmd {
|
||||
/* contains enum wmi_host_platform_type */
|
||||
__le32 host_platform_config;
|
@ -1,43 +0,0 @@
|
||||
--- a/net/wireless/sysfs.c
|
||||
+++ b/net/wireless/sysfs.c
|
||||
@@ -23,18 +23,35 @@ static inline struct cfg80211_registered
|
||||
return container_of(dev, struct cfg80211_registered_device, wiphy.dev);
|
||||
}
|
||||
|
||||
-#define SHOW_FMT(name, fmt, member) \
|
||||
+#define SHOW_FMT(name, fmt, member, mode) \
|
||||
static ssize_t name ## _show(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *buf) \
|
||||
{ \
|
||||
return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \
|
||||
} \
|
||||
-static DEVICE_ATTR_RO(name)
|
||||
+static DEVICE_ATTR_##mode(name)
|
||||
|
||||
-SHOW_FMT(index, "%d", wiphy_idx);
|
||||
-SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
|
||||
-SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
|
||||
+static ssize_t macaddress_store(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ const char *buf, size_t len)
|
||||
+{
|
||||
+ u8 mac[ETH_ALEN];
|
||||
+
|
||||
+ if (!mac_pton(buf, mac))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ memcpy(dev_to_rdev(dev)->wiphy.perm_addr, mac, ETH_ALEN);
|
||||
+
|
||||
+ return strnlen(buf, len);
|
||||
+}
|
||||
+
|
||||
+SHOW_FMT(index, "%d", wiphy_idx, RO);
|
||||
+SHOW_FMT(macaddress, "%pM", wiphy.perm_addr, RW);
|
||||
+SHOW_FMT(address_mask, "%pM", wiphy.addr_mask, RO);
|
||||
|
||||
static ssize_t name_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
@ -1,23 +0,0 @@
|
||||
brcmfmac: do not use internal roaming engine by default
|
||||
|
||||
Some evidence of curing disconnects with this disabled, so make it a default.
|
||||
Can be overridden with module parameter roamoff=0
|
||||
See: http://projectable.me/optimize-my-pi-wi-fi/
|
||||
|
||||
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -59,7 +59,11 @@ static int brcmf_fcmode;
|
||||
module_param_named(fcmode, brcmf_fcmode, int, 0);
|
||||
MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
|
||||
|
||||
+#if defined(CONFIG_ARCH_BCM2835)
|
||||
+static int brcmf_roamoff = 1;
|
||||
+#else
|
||||
static int brcmf_roamoff;
|
||||
+#endif
|
||||
module_param_named(roamoff, brcmf_roamoff, int, 0400);
|
||||
MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
|
||||
|
@ -1,49 +0,0 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Thu, 9 Jul 2015 00:07:59 +0200
|
||||
Subject: [PATCH] brcmfmac: workaround bug with some inconsistent BSSes state
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -715,8 +715,36 @@ static struct wireless_dev *brcmf_cfg802
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct brcmf_pub *drvr = cfg->pub;
|
||||
struct wireless_dev *wdev;
|
||||
+ struct net_device *dev;
|
||||
int err;
|
||||
|
||||
+ /*
|
||||
+ * There is a bug with in-firmware BSS management. When adding virtual
|
||||
+ * interface brcmfmac first tells firmware to create new BSS and then
|
||||
+ * it creates new struct net_device.
|
||||
+ *
|
||||
+ * If creating/registering netdev(ice) fails, BSS remains in some bugged
|
||||
+ * state. It conflicts with existing BSSes by overtaking their auth
|
||||
+ * requests.
|
||||
+ *
|
||||
+ * It results in one BSS (addresss X) sending beacons and another BSS
|
||||
+ * (address Y) replying to authentication requests. This makes interface
|
||||
+ * unusable as AP.
|
||||
+ *
|
||||
+ * To workaround this bug we may try to guess if register_netdev(ice)
|
||||
+ * will fail. The most obvious case is using interface name that already
|
||||
+ * exists. This is actually quite likely with brcmfmac & some user space
|
||||
+ * scripts as brcmfmac doesn't allow deleting virtual interfaces.
|
||||
+ * So this bug can be triggered even by something trivial like:
|
||||
+ * iw dev wlan0 delete
|
||||
+ * iw phy phy0 interface add wlan0 type __ap
|
||||
+ */
|
||||
+ dev = dev_get_by_name(&init_net, name);
|
||||
+ if (dev) {
|
||||
+ dev_put(dev);
|
||||
+ return ERR_PTR(-ENFILE);
|
||||
+ }
|
||||
+
|
||||
brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
|
||||
err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
|
||||
if (err) {
|
@ -1,30 +0,0 @@
|
||||
From 91094ed065f7794886b4a5490fd6de942f036bb4 Mon Sep 17 00:00:00 2001
|
||||
From: Gabor Juhos <juhosg@openwrt.org>
|
||||
Date: Sun, 24 Mar 2013 19:26:26 +0100
|
||||
Subject: [PATCH] rt2x00: allow to build rt2800soc module for RT3883
|
||||
|
||||
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/Kconfig
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
|
||||
@@ -211,7 +211,7 @@ endif
|
||||
config RT2800SOC
|
||||
tristate "Ralink WiSoC support"
|
||||
depends on m
|
||||
- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620
|
||||
+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620
|
||||
select RT2X00_LIB_SOC
|
||||
select RT2X00_LIB_MMIO
|
||||
select RT2X00_LIB_CRYPTO
|
||||
@@ -246,7 +246,7 @@ config RT2X00_LIB_PCI
|
||||
|
||||
config RT2X00_LIB_SOC
|
||||
tristate "RT2x00 SoC support"
|
||||
- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620
|
||||
+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620
|
||||
depends on m
|
||||
select RT2X00_LIB
|
||||
|
@ -1,37 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -9709,6 +9709,21 @@ static int ath10k_mac_init_rd(struct ath
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef CPTCFG_MAC80211_LEDS
|
||||
+static const struct ieee80211_tpt_blink ath10k_tpt_blink[] = {
|
||||
+ { .throughput = 0 * 1024, .blink_time = 334 },
|
||||
+ { .throughput = 1 * 1024, .blink_time = 260 },
|
||||
+ { .throughput = 2 * 1024, .blink_time = 220 },
|
||||
+ { .throughput = 5 * 1024, .blink_time = 190 },
|
||||
+ { .throughput = 10 * 1024, .blink_time = 170 },
|
||||
+ { .throughput = 25 * 1024, .blink_time = 150 },
|
||||
+ { .throughput = 54 * 1024, .blink_time = 130 },
|
||||
+ { .throughput = 120 * 1024, .blink_time = 110 },
|
||||
+ { .throughput = 265 * 1024, .blink_time = 80 },
|
||||
+ { .throughput = 586 * 1024, .blink_time = 50 },
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
int ath10k_mac_register(struct ath10k *ar)
|
||||
{
|
||||
static const u32 cipher_suites[] = {
|
||||
@@ -10058,6 +10073,12 @@ int ath10k_mac_register(struct ath10k *a
|
||||
|
||||
ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
|
||||
|
||||
+#ifdef CPTCFG_MAC80211_LEDS
|
||||
+ ieee80211_create_tpt_led_trigger(ar->hw,
|
||||
+ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink,
|
||||
+ ARRAY_SIZE(ath10k_tpt_blink));
|
||||
+#endif
|
||||
+
|
||||
ret = ieee80211_register_hw(ar->hw);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
|
@ -1,412 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Thu, 21 Jan 2021 18:29:30 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: use bitfields to encode rate
|
||||
indexes
|
||||
|
||||
Get rid of a lot of divisions and modulo operations
|
||||
Reduces code size and improves performance
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -379,14 +379,14 @@ out:
|
||||
static inline struct minstrel_rate_stats *
|
||||
minstrel_get_ratestats(struct minstrel_ht_sta *mi, int index)
|
||||
{
|
||||
- return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES];
|
||||
+ return &mi->groups[MI_RATE_GROUP(index)].rates[MI_RATE_IDX(index)];
|
||||
}
|
||||
|
||||
-static inline int
|
||||
-minstrel_get_duration(int index)
|
||||
+static inline int minstrel_get_duration(int index)
|
||||
{
|
||||
- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
|
||||
- unsigned int duration = group->duration[index % MCS_GROUP_RATES];
|
||||
+ const struct mcs_group *group = &minstrel_mcs_groups[MI_RATE_GROUP(index)];
|
||||
+ unsigned int duration = group->duration[MI_RATE_IDX(index)];
|
||||
+
|
||||
return duration << group->shift;
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ minstrel_ht_avg_ampdu_len(struct minstre
|
||||
if (mi->avg_ampdu_len)
|
||||
return MINSTREL_TRUNC(mi->avg_ampdu_len);
|
||||
|
||||
- if (minstrel_ht_is_legacy_group(mi->max_tp_rate[0] / MCS_GROUP_RATES))
|
||||
+ if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_tp_rate[0])))
|
||||
return 1;
|
||||
|
||||
duration = minstrel_get_duration(mi->max_tp_rate[0]);
|
||||
@@ -465,14 +465,14 @@ minstrel_ht_sort_best_tp_rates(struct mi
|
||||
int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob;
|
||||
int j = MAX_THR_RATES;
|
||||
|
||||
- cur_group = index / MCS_GROUP_RATES;
|
||||
- cur_idx = index % MCS_GROUP_RATES;
|
||||
+ cur_group = MI_RATE_GROUP(index);
|
||||
+ cur_idx = MI_RATE_IDX(index);
|
||||
cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg;
|
||||
cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, cur_prob);
|
||||
|
||||
do {
|
||||
- tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
|
||||
- tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
|
||||
+ tmp_group = MI_RATE_GROUP(tp_list[j - 1]);
|
||||
+ tmp_idx = MI_RATE_IDX(tp_list[j - 1]);
|
||||
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx,
|
||||
tmp_prob);
|
||||
@@ -504,23 +504,23 @@ minstrel_ht_set_best_prob_rate(struct mi
|
||||
int max_gpr_group, max_gpr_idx;
|
||||
int max_gpr_tp_avg, max_gpr_prob;
|
||||
|
||||
- cur_group = index / MCS_GROUP_RATES;
|
||||
- cur_idx = index % MCS_GROUP_RATES;
|
||||
- mg = &mi->groups[index / MCS_GROUP_RATES];
|
||||
- mrs = &mg->rates[index % MCS_GROUP_RATES];
|
||||
+ cur_group = MI_RATE_GROUP(index);
|
||||
+ cur_idx = MI_RATE_IDX(index);
|
||||
+ mg = &mi->groups[cur_group];
|
||||
+ mrs = &mg->rates[cur_idx];
|
||||
|
||||
- tmp_group = *dest / MCS_GROUP_RATES;
|
||||
- tmp_idx = *dest % MCS_GROUP_RATES;
|
||||
+ tmp_group = MI_RATE_GROUP(*dest);
|
||||
+ tmp_idx = MI_RATE_IDX(*dest);
|
||||
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
|
||||
|
||||
/* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from
|
||||
* MCS_GROUP as well as CCK_GROUP rates do not allow aggregation */
|
||||
- max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES;
|
||||
- max_tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ max_tp_group = MI_RATE_GROUP(mi->max_tp_rate[0]);
|
||||
+ max_tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]);
|
||||
max_tp_prob = mi->groups[max_tp_group].rates[max_tp_idx].prob_avg;
|
||||
|
||||
- if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES) &&
|
||||
+ if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(index)) &&
|
||||
!minstrel_ht_is_legacy_group(max_tp_group))
|
||||
return;
|
||||
|
||||
@@ -529,8 +529,8 @@ minstrel_ht_set_best_prob_rate(struct mi
|
||||
mrs->prob_avg < max_tp_prob)
|
||||
return;
|
||||
|
||||
- max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES;
|
||||
- max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
|
||||
+ max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate);
|
||||
+ max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate);
|
||||
max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
|
||||
|
||||
if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) {
|
||||
@@ -567,13 +567,13 @@ minstrel_ht_assign_best_tp_rates(struct
|
||||
unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp, tmp_prob;
|
||||
int i;
|
||||
|
||||
- tmp_group = tmp_legacy_tp_rate[0] / MCS_GROUP_RATES;
|
||||
- tmp_idx = tmp_legacy_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ tmp_group = MI_RATE_GROUP(tmp_legacy_tp_rate[0]);
|
||||
+ tmp_idx = MI_RATE_IDX(tmp_legacy_tp_rate[0]);
|
||||
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
|
||||
|
||||
- tmp_group = tmp_mcs_tp_rate[0] / MCS_GROUP_RATES;
|
||||
- tmp_idx = tmp_mcs_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ tmp_group = MI_RATE_GROUP(tmp_mcs_tp_rate[0]);
|
||||
+ tmp_idx = MI_RATE_IDX(tmp_mcs_tp_rate[0]);
|
||||
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
|
||||
|
||||
@@ -600,14 +600,14 @@ minstrel_ht_prob_rate_reduce_streams(str
|
||||
if (!mi->sta->ht_cap.ht_supported)
|
||||
return;
|
||||
|
||||
- tmp_max_streams = minstrel_mcs_groups[mi->max_tp_rate[0] /
|
||||
- MCS_GROUP_RATES].streams;
|
||||
+ group = MI_RATE_GROUP(mi->max_tp_rate[0]);
|
||||
+ tmp_max_streams = minstrel_mcs_groups[group].streams;
|
||||
for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
|
||||
mg = &mi->groups[group];
|
||||
if (!mi->supported[group] || group == MINSTREL_CCK_GROUP)
|
||||
continue;
|
||||
|
||||
- tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
|
||||
+ tmp_idx = MI_RATE_IDX(mg->max_group_prob_rate);
|
||||
tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg;
|
||||
|
||||
if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) &&
|
||||
@@ -644,8 +644,8 @@ minstrel_ht_find_probe_rates(struct mins
|
||||
int i, g, max_dur;
|
||||
int tp_idx;
|
||||
|
||||
- tp_group = &minstrel_mcs_groups[mi->max_tp_rate[0] / MCS_GROUP_RATES];
|
||||
- tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ tp_group = &minstrel_mcs_groups[MI_RATE_GROUP(mi->max_tp_rate[0])];
|
||||
+ tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]);
|
||||
|
||||
max_dur = minstrel_get_duration(mi->max_tp_rate[0]);
|
||||
if (faster_rate)
|
||||
@@ -670,7 +670,7 @@ minstrel_ht_find_probe_rates(struct mins
|
||||
if ((group->duration[i] << group->shift) > max_dur)
|
||||
continue;
|
||||
|
||||
- idx = g * MCS_GROUP_RATES + i;
|
||||
+ idx = MI_RATE(g, i);
|
||||
if (idx == mi->max_tp_rate[0])
|
||||
continue;
|
||||
|
||||
@@ -712,10 +712,10 @@ minstrel_ht_rate_sample_switch(struct mi
|
||||
|
||||
/* If no suitable rate was found, try to pick the next one in the group */
|
||||
if (!n_rates) {
|
||||
- int g_idx = mi->max_tp_rate[0] / MCS_GROUP_RATES;
|
||||
+ int g_idx = MI_RATE_GROUP(mi->max_tp_rate[0]);
|
||||
u16 supported = mi->supported[g_idx];
|
||||
|
||||
- supported >>= mi->max_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ supported >>= MI_RATE_IDX(mi->max_tp_rate[0]);
|
||||
for (i = 0; supported; supported >>= 1, i++) {
|
||||
if (!(supported & 1))
|
||||
continue;
|
||||
@@ -854,24 +854,27 @@ minstrel_ht_update_stats(struct minstrel
|
||||
mi->sample_slow = 0;
|
||||
mi->sample_count = 0;
|
||||
|
||||
- memset(tmp_mcs_tp_rate, 0, sizeof(tmp_mcs_tp_rate));
|
||||
- memset(tmp_legacy_tp_rate, 0, sizeof(tmp_legacy_tp_rate));
|
||||
if (mi->supported[MINSTREL_CCK_GROUP])
|
||||
- for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++)
|
||||
- tmp_legacy_tp_rate[j] = MINSTREL_CCK_GROUP * MCS_GROUP_RATES;
|
||||
+ group = MINSTREL_CCK_GROUP;
|
||||
else if (mi->supported[MINSTREL_OFDM_GROUP])
|
||||
- for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++)
|
||||
- tmp_legacy_tp_rate[j] = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES;
|
||||
+ group = MINSTREL_OFDM_GROUP;
|
||||
+ else
|
||||
+ group = 0;
|
||||
+
|
||||
+ index = MI_RATE(group, 0);
|
||||
+ for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++)
|
||||
+ tmp_legacy_tp_rate[j] = index;
|
||||
|
||||
if (mi->supported[MINSTREL_VHT_GROUP_0])
|
||||
- index = MINSTREL_VHT_GROUP_0 * MCS_GROUP_RATES;
|
||||
+ group = MINSTREL_VHT_GROUP_0;
|
||||
else if (ht_supported)
|
||||
- index = MINSTREL_HT_GROUP_0 * MCS_GROUP_RATES;
|
||||
+ group = MINSTREL_HT_GROUP_0;
|
||||
else if (mi->supported[MINSTREL_CCK_GROUP])
|
||||
- index = MINSTREL_CCK_GROUP * MCS_GROUP_RATES;
|
||||
+ group = MINSTREL_CCK_GROUP;
|
||||
else
|
||||
- index = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES;
|
||||
+ group = MINSTREL_OFDM_GROUP;
|
||||
|
||||
+ index = MI_RATE(group, 0);
|
||||
tmp_max_prob_rate = index;
|
||||
for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++)
|
||||
tmp_mcs_tp_rate[j] = index;
|
||||
@@ -888,7 +891,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
|
||||
/* (re)Initialize group rate indexes */
|
||||
for(j = 0; j < MAX_THR_RATES; j++)
|
||||
- tmp_group_tp_rate[j] = MCS_GROUP_RATES * group;
|
||||
+ tmp_group_tp_rate[j] = MI_RATE(group, 0);
|
||||
|
||||
if (group == MINSTREL_CCK_GROUP && ht_supported)
|
||||
tp_rate = tmp_legacy_tp_rate;
|
||||
@@ -897,7 +900,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
if (!(mi->supported[group] & BIT(i)))
|
||||
continue;
|
||||
|
||||
- index = MCS_GROUP_RATES * group + i;
|
||||
+ index = MI_RATE(group, i);
|
||||
|
||||
mrs = &mg->rates[i];
|
||||
mrs->retry_updated = false;
|
||||
@@ -929,13 +932,13 @@ minstrel_ht_update_stats(struct minstrel
|
||||
continue;
|
||||
|
||||
mg = &mi->groups[group];
|
||||
- mg->max_group_prob_rate = MCS_GROUP_RATES * group;
|
||||
+ mg->max_group_prob_rate = MI_RATE(group, 0);
|
||||
|
||||
for (i = 0; i < MCS_GROUP_RATES; i++) {
|
||||
if (!(mi->supported[group] & BIT(i)))
|
||||
continue;
|
||||
|
||||
- index = MCS_GROUP_RATES * group + i;
|
||||
+ index = MI_RATE(group, i);
|
||||
|
||||
/* Find max probability rate per group and global */
|
||||
minstrel_ht_set_best_prob_rate(mi, &tmp_max_prob_rate,
|
||||
@@ -1022,7 +1025,7 @@ minstrel_downgrade_rate(struct minstrel_
|
||||
{
|
||||
int group, orig_group;
|
||||
|
||||
- orig_group = group = *idx / MCS_GROUP_RATES;
|
||||
+ orig_group = group = MI_RATE_GROUP(*idx);
|
||||
while (group > 0) {
|
||||
group--;
|
||||
|
||||
@@ -1206,7 +1209,7 @@ minstrel_calc_retransmit(struct minstrel
|
||||
ctime += (t_slot * cw) >> 1;
|
||||
cw = min((cw << 1) | 1, mp->cw_max);
|
||||
|
||||
- if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES)) {
|
||||
+ if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(index))) {
|
||||
overhead = mi->overhead_legacy;
|
||||
overhead_rtscts = mi->overhead_legacy_rtscts;
|
||||
} else {
|
||||
@@ -1239,7 +1242,7 @@ static void
|
||||
minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
|
||||
struct ieee80211_sta_rates *ratetbl, int offset, int index)
|
||||
{
|
||||
- int group_idx = index / MCS_GROUP_RATES;
|
||||
+ int group_idx = MI_RATE_GROUP(index);
|
||||
const struct mcs_group *group = &minstrel_mcs_groups[group_idx];
|
||||
struct minstrel_rate_stats *mrs;
|
||||
u8 idx;
|
||||
@@ -1259,7 +1262,7 @@ minstrel_ht_set_rate(struct minstrel_pri
|
||||
ratetbl->rate[offset].count_rts = mrs->retry_count_rtscts;
|
||||
}
|
||||
|
||||
- index %= MCS_GROUP_RATES;
|
||||
+ index = MI_RATE_IDX(index);
|
||||
if (group_idx == MINSTREL_CCK_GROUP)
|
||||
idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)];
|
||||
else if (group_idx == MINSTREL_OFDM_GROUP)
|
||||
@@ -1289,17 +1292,17 @@ minstrel_ht_set_rate(struct minstrel_pri
|
||||
static inline int
|
||||
minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate)
|
||||
{
|
||||
- int group = rate / MCS_GROUP_RATES;
|
||||
- rate %= MCS_GROUP_RATES;
|
||||
+ int group = MI_RATE_GROUP(rate);
|
||||
+ rate = MI_RATE_IDX(rate);
|
||||
return mi->groups[group].rates[rate].prob_avg;
|
||||
}
|
||||
|
||||
static int
|
||||
minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi)
|
||||
{
|
||||
- int group = mi->max_prob_rate / MCS_GROUP_RATES;
|
||||
+ int group = MI_RATE_GROUP(mi->max_prob_rate);
|
||||
const struct mcs_group *g = &minstrel_mcs_groups[group];
|
||||
- int rate = mi->max_prob_rate % MCS_GROUP_RATES;
|
||||
+ int rate = MI_RATE_IDX(mi->max_prob_rate);
|
||||
unsigned int duration;
|
||||
|
||||
/* Disable A-MSDU if max_prob_rate is bad */
|
||||
@@ -1405,7 +1408,7 @@ minstrel_get_sample_rate(struct minstrel
|
||||
return -1;
|
||||
|
||||
mrs = &mg->rates[sample_idx];
|
||||
- sample_idx += sample_group * MCS_GROUP_RATES;
|
||||
+ sample_idx += MI_RATE(sample_group, 0);
|
||||
|
||||
tp_rate1 = mi->max_tp_rate[0];
|
||||
|
||||
@@ -1455,8 +1458,7 @@ minstrel_get_sample_rate(struct minstrel
|
||||
* if the link is working perfectly.
|
||||
*/
|
||||
|
||||
- cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 /
|
||||
- MCS_GROUP_RATES].streams;
|
||||
+ cur_max_tp_streams = minstrel_mcs_groups[MI_RATE_GROUP(tp_rate1)].streams;
|
||||
if (sample_dur >= minstrel_get_duration(tp_rate2) &&
|
||||
(cur_max_tp_streams - 1 <
|
||||
minstrel_mcs_groups[sample_group].streams ||
|
||||
@@ -1484,7 +1486,7 @@ minstrel_ht_get_rate(void *priv, struct
|
||||
int sample_idx;
|
||||
|
||||
if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
|
||||
- !minstrel_ht_is_legacy_group(mi->max_prob_rate / MCS_GROUP_RATES))
|
||||
+ !minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_prob_rate)))
|
||||
minstrel_aggr_check(sta, txrc->skb);
|
||||
|
||||
info->flags |= mi->tx_flags;
|
||||
@@ -1512,8 +1514,8 @@ minstrel_ht_get_rate(void *priv, struct
|
||||
if (sample_idx < 0)
|
||||
return;
|
||||
|
||||
- sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES];
|
||||
- sample_idx %= MCS_GROUP_RATES;
|
||||
+ sample_group = &minstrel_mcs_groups[MI_RATE_GROUP(sample_idx)];
|
||||
+ sample_idx = MI_RATE_IDX(sample_idx);
|
||||
|
||||
if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP] &&
|
||||
(sample_idx >= 4) != txrc->short_preamble)
|
||||
@@ -1529,7 +1531,7 @@ minstrel_ht_get_rate(void *priv, struct
|
||||
int idx = sample_idx % ARRAY_SIZE(mp->ofdm_rates[0]);
|
||||
rate->idx = mp->ofdm_rates[mi->band][idx];
|
||||
} else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) {
|
||||
- ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES,
|
||||
+ ieee80211_rate_set_vht(rate, MI_RATE_IDX(sample_idx),
|
||||
sample_group->streams);
|
||||
} else {
|
||||
rate->idx = sample_idx + (sample_group->streams - 1) * 8;
|
||||
@@ -1898,8 +1900,8 @@ static u32 minstrel_ht_get_expected_thro
|
||||
struct minstrel_ht_sta *mi = priv_sta;
|
||||
int i, j, prob, tp_avg;
|
||||
|
||||
- i = mi->max_tp_rate[0] / MCS_GROUP_RATES;
|
||||
- j = mi->max_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ i = MI_RATE_GROUP(mi->max_tp_rate[0]);
|
||||
+ j = MI_RATE_IDX(mi->max_tp_rate[0]);
|
||||
prob = mi->groups[i].rates[j].prob_avg;
|
||||
|
||||
/* convert tp_avg from pkt per second in kbps */
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.h
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
||||
@@ -6,6 +6,8 @@
|
||||
#ifndef __RC_MINSTREL_HT_H
|
||||
#define __RC_MINSTREL_HT_H
|
||||
|
||||
+#include <linux/bitfield.h>
|
||||
+
|
||||
/* number of highest throughput rates to consider*/
|
||||
#define MAX_THR_RATES 4
|
||||
#define SAMPLE_COLUMNS 10 /* number of columns in sample table */
|
||||
@@ -57,6 +59,17 @@
|
||||
|
||||
#define MCS_GROUP_RATES 10
|
||||
|
||||
+#define MI_RATE_IDX_MASK GENMASK(3, 0)
|
||||
+#define MI_RATE_GROUP_MASK GENMASK(15, 4)
|
||||
+
|
||||
+#define MI_RATE(_group, _idx) \
|
||||
+ (FIELD_PREP(MI_RATE_GROUP_MASK, _group) | \
|
||||
+ FIELD_PREP(MI_RATE_IDX_MASK, _idx))
|
||||
+
|
||||
+#define MI_RATE_IDX(_rate) FIELD_GET(MI_RATE_IDX_MASK, _rate)
|
||||
+#define MI_RATE_GROUP(_rate) FIELD_GET(MI_RATE_GROUP_MASK, _rate)
|
||||
+
|
||||
+
|
||||
struct minstrel_priv {
|
||||
struct ieee80211_hw *hw;
|
||||
bool has_mrr;
|
||||
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
|
||||
@@ -56,7 +56,7 @@ minstrel_ht_stats_dump(struct minstrel_h
|
||||
|
||||
for (j = 0; j < MCS_GROUP_RATES; j++) {
|
||||
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
|
||||
- int idx = i * MCS_GROUP_RATES + j;
|
||||
+ int idx = MI_RATE(i, j);
|
||||
unsigned int duration;
|
||||
|
||||
if (!(mi->supported[i] & BIT(j)))
|
||||
@@ -201,7 +201,7 @@ minstrel_ht_stats_csv_dump(struct minstr
|
||||
|
||||
for (j = 0; j < MCS_GROUP_RATES; j++) {
|
||||
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
|
||||
- int idx = i * MCS_GROUP_RATES + j;
|
||||
+ int idx = MI_RATE(i, j);
|
||||
unsigned int duration;
|
||||
|
||||
if (!(mi->supported[i] & BIT(j)))
|
@ -1,124 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 26 Dec 2020 19:09:08 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: fix max probability rate selection
|
||||
|
||||
- do not select rates faster than the max throughput rate if probability is lower
|
||||
- reset previous rate before sorting again
|
||||
|
||||
This ensures that the max prob rate gets set to a more reliable rate
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -495,12 +495,13 @@ minstrel_ht_sort_best_tp_rates(struct mi
|
||||
* Find and set the topmost probability rate per sta and per group
|
||||
*/
|
||||
static void
|
||||
-minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index)
|
||||
+minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index)
|
||||
{
|
||||
struct minstrel_mcs_group_data *mg;
|
||||
struct minstrel_rate_stats *mrs;
|
||||
int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob;
|
||||
- int max_tp_group, cur_tp_avg, cur_group, cur_idx;
|
||||
+ int max_tp_group, max_tp_idx, max_tp_prob;
|
||||
+ int cur_tp_avg, cur_group, cur_idx;
|
||||
int max_gpr_group, max_gpr_idx;
|
||||
int max_gpr_tp_avg, max_gpr_prob;
|
||||
|
||||
@@ -509,18 +510,26 @@ minstrel_ht_set_best_prob_rate(struct mi
|
||||
mg = &mi->groups[index / MCS_GROUP_RATES];
|
||||
mrs = &mg->rates[index % MCS_GROUP_RATES];
|
||||
|
||||
- tmp_group = mi->max_prob_rate / MCS_GROUP_RATES;
|
||||
- tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES;
|
||||
+ tmp_group = *dest / MCS_GROUP_RATES;
|
||||
+ tmp_idx = *dest % MCS_GROUP_RATES;
|
||||
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
|
||||
|
||||
/* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from
|
||||
* MCS_GROUP as well as CCK_GROUP rates do not allow aggregation */
|
||||
max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES;
|
||||
+ max_tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ max_tp_prob = mi->groups[max_tp_group].rates[max_tp_idx].prob_avg;
|
||||
+
|
||||
if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES) &&
|
||||
!minstrel_ht_is_legacy_group(max_tp_group))
|
||||
return;
|
||||
|
||||
+ /* skip rates faster than max tp rate with lower prob */
|
||||
+ if (minstrel_get_duration(mi->max_tp_rate[0]) > minstrel_get_duration(index) &&
|
||||
+ mrs->prob_avg < max_tp_prob)
|
||||
+ return;
|
||||
+
|
||||
max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES;
|
||||
max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
|
||||
max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
|
||||
@@ -538,7 +547,7 @@ minstrel_ht_set_best_prob_rate(struct mi
|
||||
mg->max_group_prob_rate = index;
|
||||
} else {
|
||||
if (mrs->prob_avg > tmp_prob)
|
||||
- mi->max_prob_rate = index;
|
||||
+ *dest = index;
|
||||
if (mrs->prob_avg > max_gpr_prob)
|
||||
mg->max_group_prob_rate = index;
|
||||
}
|
||||
@@ -816,7 +825,8 @@ minstrel_ht_update_stats(struct minstrel
|
||||
struct minstrel_rate_stats *mrs;
|
||||
int group, i, j, cur_prob;
|
||||
u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES];
|
||||
- u16 tmp_legacy_tp_rate[MAX_THR_RATES], index;
|
||||
+ u16 tmp_legacy_tp_rate[MAX_THR_RATES], tmp_max_prob_rate;
|
||||
+ u16 index;
|
||||
bool ht_supported = mi->sta->ht_cap.ht_supported;
|
||||
|
||||
mi->sample_mode = MINSTREL_SAMPLE_IDLE;
|
||||
@@ -863,6 +873,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
else
|
||||
index = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES;
|
||||
|
||||
+ tmp_max_prob_rate = index;
|
||||
for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++)
|
||||
tmp_mcs_tp_rate[j] = index;
|
||||
|
||||
@@ -903,9 +914,6 @@ minstrel_ht_update_stats(struct minstrel
|
||||
/* Find max throughput rate set within a group */
|
||||
minstrel_ht_sort_best_tp_rates(mi, index,
|
||||
tmp_group_tp_rate);
|
||||
-
|
||||
- /* Find max probability rate per group and global */
|
||||
- minstrel_ht_set_best_prob_rate(mi, index);
|
||||
}
|
||||
|
||||
memcpy(mg->max_group_tp_rate, tmp_group_tp_rate,
|
||||
@@ -917,6 +925,27 @@ minstrel_ht_update_stats(struct minstrel
|
||||
tmp_legacy_tp_rate);
|
||||
memcpy(mi->max_tp_rate, tmp_mcs_tp_rate, sizeof(mi->max_tp_rate));
|
||||
|
||||
+ for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
|
||||
+ if (!mi->supported[group])
|
||||
+ continue;
|
||||
+
|
||||
+ mg = &mi->groups[group];
|
||||
+ mg->max_group_prob_rate = MCS_GROUP_RATES * group;
|
||||
+
|
||||
+ for (i = 0; i < MCS_GROUP_RATES; i++) {
|
||||
+ if (!(mi->supported[group] & BIT(i)))
|
||||
+ continue;
|
||||
+
|
||||
+ index = MCS_GROUP_RATES * group + i;
|
||||
+
|
||||
+ /* Find max probability rate per group and global */
|
||||
+ minstrel_ht_set_best_prob_rate(mi, &tmp_max_prob_rate,
|
||||
+ index);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ mi->max_prob_rate = tmp_max_prob_rate;
|
||||
+
|
||||
/* Try to increase robustness of max_prob_rate*/
|
||||
minstrel_ht_prob_rate_reduce_streams(mi);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user