From 55e23f2c02ae95e84613ed7d1cbf8aba557b8682 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 2 Jan 2021 14:36:03 +0100 Subject: [PATCH 01/25] wolfssl: enable HAVE_SECRET_CALLBACK Fixes wpad-wolfssl build Signed-off-by: Felix Fietkau --- .../wolfssl/patches/120-enable-secret-callback.patch | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 package/libs/wolfssl/patches/120-enable-secret-callback.patch diff --git a/package/libs/wolfssl/patches/120-enable-secret-callback.patch b/package/libs/wolfssl/patches/120-enable-secret-callback.patch new file mode 100644 index 0000000000..9c9b361d01 --- /dev/null +++ b/package/libs/wolfssl/patches/120-enable-secret-callback.patch @@ -0,0 +1,10 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -943,6 +943,7 @@ then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALWAYS_KEEP_SNI" + AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA" + AM_CFLAGS="$AM_CFLAGS -DHAVE_EXT_CACHE" ++ AM_CFLAGS="$AM_CFLAGS -DHAVE_SECRET_CALLBACK" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_EITHER_SIDE" + AM_CFLAGS="$AM_CFLAGS -DOPENSSL_EXTRA_X509_SMALL" + From 3a12c6679eb184ca2a9a2b1266cc2d41f3f00bad Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 29 Dec 2020 18:23:29 +0100 Subject: [PATCH 02/25] mac80211: replace legacy minstrel with minstrel_ht, improve rate selection Legacy minstrel is essentially unmaintained and was showing poor performance Replace it with minstrel_ht and improve rate selection and sampling behavior Signed-off-by: Felix Fietkau --- ...c80211-minstrel_ht-clean-up-CCK-code.patch | 166 +++ ...l_ht-add-support-for-OFDM-rates-on-n.patch | 762 ++++++++++ ...-remove-legacy-minstrel-rate-control.patch | 1328 +++++++++++++++++ ...l_ht-remove-old-ewma-based-rate-aver.patch | 96 ++ ...l_ht-improve-ampdu-length-estimation.patch | 67 + ...rel_ht-improve-sample-rate-selection.patch | 31 + ...l_ht-fix-max-probability-rate-select.patch | 116 ++ ...el_ht-increase-stats-update-interval.patch | 20 + 8 files changed, 2586 insertions(+) create mode 100644 package/kernel/mac80211/patches/subsys/337-mac80211-minstrel_ht-clean-up-CCK-code.patch create mode 100644 package/kernel/mac80211/patches/subsys/338-mac80211-minstrel_ht-add-support-for-OFDM-rates-on-n.patch create mode 100644 package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch create mode 100644 package/kernel/mac80211/patches/subsys/340-mac80211-minstrel_ht-remove-old-ewma-based-rate-aver.patch create mode 100644 package/kernel/mac80211/patches/subsys/341-mac80211-minstrel_ht-improve-ampdu-length-estimation.patch create mode 100644 package/kernel/mac80211/patches/subsys/342-mac80211-minstrel_ht-improve-sample-rate-selection.patch create mode 100644 package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch create mode 100644 package/kernel/mac80211/patches/subsys/344-mac80211-minstrel_ht-increase-stats-update-interval.patch diff --git a/package/kernel/mac80211/patches/subsys/337-mac80211-minstrel_ht-clean-up-CCK-code.patch b/package/kernel/mac80211/patches/subsys/337-mac80211-minstrel_ht-clean-up-CCK-code.patch new file mode 100644 index 0000000000..f667d2c94e --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/337-mac80211-minstrel_ht-clean-up-CCK-code.patch @@ -0,0 +1,166 @@ +From: Felix Fietkau +Date: Fri, 25 Dec 2020 16:22:52 +0100 +Subject: [PATCH] mac80211: minstrel_ht: clean up CCK code + +- move ack overhead out of rate duration table +- remove cck_supported, cck_supported_short + +Preparation for adding OFDM legacy rates support + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -136,20 +136,16 @@ + __VHT_GROUP(_streams, _sgi, _bw, \ + VHT_GROUP_SHIFT(_streams, _sgi, _bw)) + +-#define CCK_DURATION(_bitrate, _short, _len) \ ++#define CCK_DURATION(_bitrate, _short) \ + (1000 * (10 /* SIFS */ + \ + (_short ? 72 + 24 : 144 + 48) + \ +- (8 * (_len + 4) * 10) / (_bitrate))) +- +-#define CCK_ACK_DURATION(_bitrate, _short) \ +- (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \ +- CCK_DURATION(_bitrate, _short, AVG_PKT_SIZE)) ++ (8 * (AVG_PKT_SIZE + 4) * 10) / (_bitrate))) + + #define CCK_DURATION_LIST(_short, _s) \ +- CCK_ACK_DURATION(10, _short) >> _s, \ +- CCK_ACK_DURATION(20, _short) >> _s, \ +- CCK_ACK_DURATION(55, _short) >> _s, \ +- CCK_ACK_DURATION(110, _short) >> _s ++ CCK_DURATION(10, _short) >> _s, \ ++ CCK_DURATION(20, _short) >> _s, \ ++ CCK_DURATION(55, _short) >> _s, \ ++ CCK_DURATION(110, _short) >> _s + + #define __CCK_GROUP(_s) \ + [MINSTREL_CCK_GROUP] = { \ +@@ -163,7 +159,7 @@ + } + + #define CCK_GROUP_SHIFT \ +- GROUP_SHIFT(CCK_ACK_DURATION(10, false)) ++ GROUP_SHIFT(CCK_DURATION(10, false)) + + #define CCK_GROUP __CCK_GROUP(CCK_GROUP_SHIFT) + +@@ -349,15 +345,19 @@ int + minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate, + int prob_avg) + { +- unsigned int nsecs = 0; ++ unsigned int nsecs = 0, overhead = mi->overhead; ++ unsigned int ampdu_len = 1; + + /* do not account throughput if sucess prob is below 10% */ + if (prob_avg < MINSTREL_FRAC(10, 100)) + return 0; + +- if (group != MINSTREL_CCK_GROUP) +- nsecs = 1000 * mi->overhead / minstrel_ht_avg_ampdu_len(mi); ++ if (group == MINSTREL_CCK_GROUP) ++ overhead = mi->overhead_legacy; ++ else ++ ampdu_len = minstrel_ht_avg_ampdu_len(mi); + ++ nsecs = 1000 * overhead / ampdu_len; + nsecs += minstrel_mcs_groups[group].duration[rate] << + minstrel_mcs_groups[group].shift; + +@@ -1031,7 +1031,10 @@ minstrel_calc_retransmit(struct minstrel + ctime += (t_slot * cw) >> 1; + cw = min((cw << 1) | 1, mp->cw_max); + +- if (index / MCS_GROUP_RATES != MINSTREL_CCK_GROUP) { ++ if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { ++ overhead = mi->overhead_legacy; ++ overhead_rtscts = mi->overhead_legacy_rtscts; ++ } else { + overhead = mi->overhead; + overhead_rtscts = mi->overhead_rtscts; + } +@@ -1369,18 +1372,14 @@ minstrel_ht_update_cck(struct minstrel_p + if (!ieee80211_hw_check(mp->hw, SUPPORTS_HT_CCK_RATES)) + return; + +- mi->cck_supported = 0; +- mi->cck_supported_short = 0; + for (i = 0; i < 4; i++) { + if (!rate_supported(sta, sband->band, mp->cck_rates[i])) + continue; + +- mi->cck_supported |= BIT(i); ++ mi->supported[MINSTREL_CCK_GROUP] |= BIT(i); + if (sband->bitrates[i].flags & IEEE80211_RATE_SHORT_PREAMBLE) +- mi->cck_supported_short |= BIT(i); ++ mi->supported[MINSTREL_CCK_GROUP] |= BIT(i + 4); + } +- +- mi->supported[MINSTREL_CCK_GROUP] = mi->cck_supported; + } + + static void +@@ -1394,12 +1393,13 @@ minstrel_ht_update_caps(void *priv, stru + struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; + u16 ht_cap = sta->ht_cap.cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; ++ const struct ieee80211_rate *ctl_rate; ++ bool ldpc, erp; + int use_vht; + int n_supported = 0; + int ack_dur; + int stbc; + int i; +- bool ldpc; + + /* fall back to the old minstrel for legacy stations */ + if (!sta->ht_cap.ht_supported) +@@ -1423,6 +1423,14 @@ minstrel_ht_update_caps(void *priv, stru + mi->overhead += ack_dur; + mi->overhead_rtscts = mi->overhead + 2 * ack_dur; + ++ ctl_rate = &sband->bitrates[rate_lowest_index(sband, sta)]; ++ erp = ctl_rate->flags & IEEE80211_RATE_ERP_G; ++ ack_dur = ieee80211_frame_duration(sband->band, 10, ++ ctl_rate->bitrate, erp, 1, ++ ieee80211_chandef_get_shift(chandef)); ++ mi->overhead_legacy = ack_dur; ++ mi->overhead_legacy_rtscts = mi->overhead_legacy + 2 * ack_dur; ++ + mi->avg_ampdu_len = MINSTREL_FRAC(1, 1); + + /* When using MRR, sample more on the first attempt, without delay */ +@@ -1523,8 +1531,6 @@ minstrel_ht_update_caps(void *priv, stru + if (!n_supported) + goto use_legacy; + +- mi->supported[MINSTREL_CCK_GROUP] |= mi->cck_supported_short << 4; +- + /* create an initial rate table with the lowest supported rates */ + minstrel_ht_update_stats(mp, mi, true); + minstrel_ht_update_rates(mp, mi); +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -77,6 +77,8 @@ struct minstrel_ht_sta { + /* overhead time in usec for each frame */ + unsigned int overhead; + unsigned int overhead_rtscts; ++ unsigned int overhead_legacy; ++ unsigned int overhead_legacy_rtscts; + + unsigned int total_packets_last; + unsigned int total_packets_cur; +@@ -97,9 +99,6 @@ struct minstrel_ht_sta { + /* current MCS group to be sampled */ + u8 sample_group; + +- u8 cck_supported; +- u8 cck_supported_short; +- + /* Bitfield of supported MCS rates of all groups */ + u16 supported[MINSTREL_GROUPS_NB]; + diff --git a/package/kernel/mac80211/patches/subsys/338-mac80211-minstrel_ht-add-support-for-OFDM-rates-on-n.patch b/package/kernel/mac80211/patches/subsys/338-mac80211-minstrel_ht-add-support-for-OFDM-rates-on-n.patch new file mode 100644 index 0000000000..abefde7109 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/338-mac80211-minstrel_ht-add-support-for-OFDM-rates-on-n.patch @@ -0,0 +1,762 @@ +From: Felix Fietkau +Date: Sat, 26 Dec 2020 13:56:42 +0100 +Subject: [PATCH] mac80211: minstrel_ht: add support for OFDM rates on + non-HT clients + +The legacy minstrel code is essentially unmaintained and receives only very +little testing. In order to bring the significant algorithm improvements from +minstrel_ht to legacy clients, this patch adds support for OFDM rates to +minstrel_ht and removes the fallback to the legacy codepath. +This also makes it work much better on hardware with rate selection constraints, +e.g. mt76. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel.h ++++ b/net/mac80211/rc80211_minstrel.h +@@ -152,6 +152,7 @@ struct minstrel_priv { + unsigned int lookaround_rate_mrr; + + u8 cck_rates[4]; ++ u8 ofdm_rates[NUM_NL80211_BANDS][8]; + + #ifdef CPTCFG_MAC80211_DEBUGFS + /* +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -163,6 +163,38 @@ + + #define CCK_GROUP __CCK_GROUP(CCK_GROUP_SHIFT) + ++#define OFDM_DURATION(_bitrate) \ ++ (1000 * (16 /* SIFS + signal ext */ + \ ++ 16 /* T_PREAMBLE */ + \ ++ 4 /* T_SIGNAL */ + \ ++ 4 * (((16 + 80 * (AVG_PKT_SIZE + 4) + 6) / \ ++ ((_bitrate) * 4))))) ++ ++#define OFDM_DURATION_LIST(_s) \ ++ OFDM_DURATION(60) >> _s, \ ++ OFDM_DURATION(90) >> _s, \ ++ OFDM_DURATION(120) >> _s, \ ++ OFDM_DURATION(180) >> _s, \ ++ OFDM_DURATION(240) >> _s, \ ++ OFDM_DURATION(360) >> _s, \ ++ OFDM_DURATION(480) >> _s, \ ++ OFDM_DURATION(540) >> _s ++ ++#define __OFDM_GROUP(_s) \ ++ [MINSTREL_OFDM_GROUP] = { \ ++ .streams = 1, \ ++ .flags = 0, \ ++ .shift = _s, \ ++ .duration = { \ ++ OFDM_DURATION_LIST(_s), \ ++ } \ ++ } ++ ++#define OFDM_GROUP_SHIFT \ ++ GROUP_SHIFT(OFDM_DURATION(60)) ++ ++#define OFDM_GROUP __OFDM_GROUP(OFDM_GROUP_SHIFT) ++ + + static bool minstrel_vht_only = true; + module_param(minstrel_vht_only, bool, 0644); +@@ -199,6 +231,7 @@ const struct mcs_group minstrel_mcs_grou + MCS_GROUP(4, 1, BW_40), + + CCK_GROUP, ++ OFDM_GROUP, + + VHT_GROUP(1, 0, BW_20), + VHT_GROUP(2, 0, BW_20), +@@ -231,6 +264,8 @@ const struct mcs_group minstrel_mcs_grou + VHT_GROUP(4, 1, BW_80), + }; + ++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 void +@@ -275,6 +310,13 @@ minstrel_get_valid_vht_rates(int bw, int + return 0x3ff & ~mask; + } + ++static bool ++minstrel_ht_is_legacy_group(int group) ++{ ++ return group == MINSTREL_CCK_GROUP || ++ group == MINSTREL_OFDM_GROUP; ++} ++ + /* + * Look up an MCS group index based on mac80211 rate information + */ +@@ -304,21 +346,34 @@ minstrel_ht_get_stats(struct minstrel_pr + if (rate->flags & IEEE80211_TX_RC_MCS) { + group = minstrel_ht_get_group_idx(rate); + idx = rate->idx % 8; +- } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { ++ goto out; ++ } ++ ++ if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { + group = minstrel_vht_get_group_idx(rate); + idx = ieee80211_rate_get_vht_mcs(rate); +- } else { +- group = MINSTREL_CCK_GROUP; ++ goto out; ++ } + +- for (idx = 0; idx < ARRAY_SIZE(mp->cck_rates); idx++) +- if (rate->idx == mp->cck_rates[idx]) +- break; ++ group = MINSTREL_CCK_GROUP; ++ for (idx = 0; idx < ARRAY_SIZE(mp->cck_rates); idx++) { ++ if (rate->idx != mp->cck_rates[idx]) ++ continue; + + /* short preamble */ + if ((mi->supported[group] & BIT(idx + 4)) && + (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) +- idx += 4; ++ idx += 4; ++ goto out; + } ++ ++ group = MINSTREL_OFDM_GROUP; ++ for (idx = 0; idx < ARRAY_SIZE(mp->ofdm_rates[0]); idx++) ++ if (rate->idx == mp->ofdm_rates[mi->band][idx]) ++ goto out; ++ ++ idx = 0; ++out: + return &mi->groups[group].rates[idx]; + } + +@@ -352,7 +407,7 @@ minstrel_ht_get_tp_avg(struct minstrel_h + if (prob_avg < MINSTREL_FRAC(10, 100)) + return 0; + +- if (group == MINSTREL_CCK_GROUP) ++ if (minstrel_ht_is_legacy_group(group)) + overhead = mi->overhead_legacy; + else + ampdu_len = minstrel_ht_avg_ampdu_len(mi); +@@ -439,8 +494,8 @@ minstrel_ht_set_best_prob_rate(struct mi + /* 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; +- if((index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) && +- (max_tp_group != MINSTREL_CCK_GROUP)) ++ if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES) && ++ !minstrel_ht_is_legacy_group(max_tp_group)) + return; + + max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES; +@@ -476,13 +531,13 @@ minstrel_ht_set_best_prob_rate(struct mi + static void + minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi, + u16 tmp_mcs_tp_rate[MAX_THR_RATES], +- u16 tmp_cck_tp_rate[MAX_THR_RATES]) ++ u16 tmp_legacy_tp_rate[MAX_THR_RATES]) + { + unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp, tmp_prob; + int i; + +- tmp_group = tmp_cck_tp_rate[0] / MCS_GROUP_RATES; +- tmp_idx = tmp_cck_tp_rate[0] % MCS_GROUP_RATES; ++ tmp_group = tmp_legacy_tp_rate[0] / MCS_GROUP_RATES; ++ tmp_idx = tmp_legacy_tp_rate[0] % MCS_GROUP_RATES; + 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); + +@@ -493,7 +548,7 @@ minstrel_ht_assign_best_tp_rates(struct + + if (tmp_cck_tp > tmp_mcs_tp) { + for(i = 0; i < MAX_THR_RATES; i++) { +- minstrel_ht_sort_best_tp_rates(mi, tmp_cck_tp_rate[i], ++ minstrel_ht_sort_best_tp_rates(mi, tmp_legacy_tp_rate[i], + tmp_mcs_tp_rate); + } + } +@@ -511,6 +566,9 @@ minstrel_ht_prob_rate_reduce_streams(str + int tmp_max_streams, group, tmp_idx, tmp_prob; + int tmp_tp = 0; + ++ if (!mi->sta->ht_cap.ht_supported) ++ return; ++ + tmp_max_streams = minstrel_mcs_groups[mi->max_tp_rate[0] / + MCS_GROUP_RATES].streams; + for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { +@@ -675,7 +733,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_cck_tp_rate[MAX_THR_RATES], index; ++ u16 tmp_legacy_tp_rate[MAX_THR_RATES], index; ++ bool ht_supported = mi->sta->ht_cap.ht_supported; + + mi->sample_mode = MINSTREL_SAMPLE_IDLE; + +@@ -704,21 +763,29 @@ minstrel_ht_update_stats(struct minstrel + mi->sample_count = 0; + + memset(tmp_mcs_tp_rate, 0, sizeof(tmp_mcs_tp_rate)); +- memset(tmp_cck_tp_rate, 0, sizeof(tmp_cck_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_cck_tp_rate); j++) +- tmp_cck_tp_rate[j] = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; ++ for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++) ++ tmp_legacy_tp_rate[j] = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; ++ 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; + + if (mi->supported[MINSTREL_VHT_GROUP_0]) + index = MINSTREL_VHT_GROUP_0 * MCS_GROUP_RATES; +- else ++ else if (ht_supported) + index = MINSTREL_HT_GROUP_0 * MCS_GROUP_RATES; ++ else if (mi->supported[MINSTREL_CCK_GROUP]) ++ index = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; ++ else ++ index = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES; + + for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++) + tmp_mcs_tp_rate[j] = index; + + /* 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; + + mg = &mi->groups[group]; + if (!mi->supported[group]) +@@ -730,6 +797,9 @@ minstrel_ht_update_stats(struct minstrel + for(j = 0; j < MAX_THR_RATES; j++) + tmp_group_tp_rate[j] = MCS_GROUP_RATES * group; + ++ if (group == MINSTREL_CCK_GROUP && ht_supported) ++ tp_rate = tmp_legacy_tp_rate; ++ + for (i = 0; i < MCS_GROUP_RATES; i++) { + if (!(mi->supported[group] & BIT(i))) + continue; +@@ -745,13 +815,7 @@ minstrel_ht_update_stats(struct minstrel + continue; + + /* Find max throughput rate set */ +- if (group != MINSTREL_CCK_GROUP) { +- minstrel_ht_sort_best_tp_rates(mi, index, +- tmp_mcs_tp_rate); +- } else if (group == MINSTREL_CCK_GROUP) { +- minstrel_ht_sort_best_tp_rates(mi, index, +- tmp_cck_tp_rate); +- } ++ minstrel_ht_sort_best_tp_rates(mi, index, tp_rate); + + /* Find max throughput rate set within a group */ + minstrel_ht_sort_best_tp_rates(mi, index, +@@ -766,7 +830,8 @@ minstrel_ht_update_stats(struct minstrel + } + + /* Assign new rate set per sta */ +- minstrel_ht_assign_best_tp_rates(mi, tmp_mcs_tp_rate, tmp_cck_tp_rate); ++ minstrel_ht_assign_best_tp_rates(mi, tmp_mcs_tp_rate, ++ tmp_legacy_tp_rate); + memcpy(mi->max_tp_rate, tmp_mcs_tp_rate, sizeof(mi->max_tp_rate)); + + /* Try to increase robustness of max_prob_rate*/ +@@ -795,8 +860,11 @@ minstrel_ht_update_stats(struct minstrel + } + + static bool +-minstrel_ht_txstat_valid(struct minstrel_priv *mp, struct ieee80211_tx_rate *rate) ++minstrel_ht_txstat_valid(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ++ struct ieee80211_tx_rate *rate) + { ++ int i; ++ + if (rate->idx < 0) + return false; + +@@ -807,10 +875,15 @@ minstrel_ht_txstat_valid(struct minstrel + rate->flags & IEEE80211_TX_RC_VHT_MCS) + return true; + +- return rate->idx == mp->cck_rates[0] || +- rate->idx == mp->cck_rates[1] || +- rate->idx == mp->cck_rates[2] || +- rate->idx == mp->cck_rates[3]; ++ for (i = 0; i < ARRAY_SIZE(mp->cck_rates); i++) ++ if (rate->idx == mp->cck_rates[i]) ++ return true; ++ ++ for (i = 0; i < ARRAY_SIZE(mp->ofdm_rates[0]); i++) ++ if (rate->idx == mp->ofdm_rates[mi->band][i]) ++ return true; ++ ++ return false; + } + + static void +@@ -897,11 +970,6 @@ minstrel_ht_tx_status(void *priv, struct + bool sample_status = false; + int i; + +- if (!msp->is_ht) +- return mac80211_minstrel.tx_status_ext(priv, sband, +- &msp->legacy, st); +- +- + /* This packet was aggregated but doesn't carry status info */ + if ((info->flags & IEEE80211_TX_CTL_AMPDU) && + !(info->flags & IEEE80211_TX_STAT_AMPDU)) +@@ -930,10 +998,10 @@ minstrel_ht_tx_status(void *priv, struct + if (mi->sample_mode != MINSTREL_SAMPLE_IDLE) + rate_sample = minstrel_get_ratestats(mi, mi->sample_rate); + +- last = !minstrel_ht_txstat_valid(mp, &ar[0]); ++ 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, &ar[i + 1]); ++ !minstrel_ht_txstat_valid(mp, mi, &ar[i + 1]); + + rate = minstrel_ht_get_stats(mp, mi, &ar[i]); + if (rate == rate_sample) +@@ -1031,7 +1099,7 @@ minstrel_calc_retransmit(struct minstrel + ctime += (t_slot * cw) >> 1; + cw = min((cw << 1) | 1, mp->cw_max); + +- if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { ++ if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES)) { + overhead = mi->overhead_legacy; + overhead_rtscts = mi->overhead_legacy_rtscts; + } else { +@@ -1064,7 +1132,8 @@ static void + minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, + struct ieee80211_sta_rates *ratetbl, int offset, int index) + { +- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; ++ int group_idx = index / MCS_GROUP_RATES; ++ const struct mcs_group *group = &minstrel_mcs_groups[group_idx]; + struct minstrel_rate_stats *mrs; + u8 idx; + u16 flags = group->flags; +@@ -1083,13 +1152,17 @@ minstrel_ht_set_rate(struct minstrel_pri + ratetbl->rate[offset].count_rts = mrs->retry_count_rtscts; + } + +- if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) ++ index %= MCS_GROUP_RATES; ++ if (group_idx == MINSTREL_CCK_GROUP) + idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; ++ else if (group_idx == MINSTREL_OFDM_GROUP) ++ idx = mp->ofdm_rates[mi->band][index % ++ ARRAY_SIZE(mp->ofdm_rates[0])]; + else if (flags & IEEE80211_TX_RC_VHT_MCS) + idx = ((group->streams - 1) << 4) | +- ((index % MCS_GROUP_RATES) & 0xF); ++ (index & 0xF); + else +- idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; ++ idx = index + (group->streams - 1) * 8; + + /* enable RTS/CTS if needed: + * - if station is in dynamic SMPS (and streams > 1) +@@ -1304,11 +1377,8 @@ minstrel_ht_get_rate(void *priv, struct + struct minstrel_priv *mp = priv; + int sample_idx; + +- if (!msp->is_ht) +- return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc); +- + if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && +- mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP) ++ !minstrel_ht_is_legacy_group(mi->max_prob_rate / MCS_GROUP_RATES)) + minstrel_aggr_check(sta, txrc->skb); + + info->flags |= mi->tx_flags; +@@ -1349,6 +1419,9 @@ minstrel_ht_get_rate(void *priv, struct + if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP]) { + int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); + rate->idx = mp->cck_rates[idx]; ++ } else if (sample_group == &minstrel_mcs_groups[MINSTREL_OFDM_GROUP]) { ++ 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, + sample_group->streams); +@@ -1369,11 +1442,13 @@ minstrel_ht_update_cck(struct minstrel_p + if (sband->band != NL80211_BAND_2GHZ) + return; + +- if (!ieee80211_hw_check(mp->hw, SUPPORTS_HT_CCK_RATES)) ++ if (sta->ht_cap.ht_supported && ++ !ieee80211_hw_check(mp->hw, SUPPORTS_HT_CCK_RATES)) + return; + + for (i = 0; i < 4; i++) { +- if (!rate_supported(sta, sband->band, mp->cck_rates[i])) ++ if (mp->cck_rates[i] == 0xff || ++ !rate_supported(sta, sband->band, mp->cck_rates[i])) + continue; + + mi->supported[MINSTREL_CCK_GROUP] |= BIT(i); +@@ -1383,9 +1458,30 @@ minstrel_ht_update_cck(struct minstrel_p + } + + static void ++minstrel_ht_update_ofdm(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, ++ struct ieee80211_supported_band *sband, ++ struct ieee80211_sta *sta) ++{ ++ const u8 *rates; ++ int i; ++ ++ if (sta->ht_cap.ht_supported) ++ return; ++ ++ rates = mp->ofdm_rates[sband->band]; ++ for (i = 0; i < ARRAY_SIZE(mp->ofdm_rates[0]); i++) { ++ if (rates[i] == 0xff || ++ !rate_supported(sta, sband->band, rates[i])) ++ continue; ++ ++ mi->supported[MINSTREL_OFDM_GROUP] |= BIT(i); ++ } ++} ++ ++static void + minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, + struct cfg80211_chan_def *chandef, +- struct ieee80211_sta *sta, void *priv_sta) ++ struct ieee80211_sta *sta, void *priv_sta) + { + struct minstrel_priv *mp = priv; + struct minstrel_ht_sta_priv *msp = priv_sta; +@@ -1401,10 +1497,6 @@ minstrel_ht_update_caps(void *priv, stru + int stbc; + int i; + +- /* fall back to the old minstrel for legacy stations */ +- if (!sta->ht_cap.ht_supported) +- goto use_legacy; +- + BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB); + + if (vht_cap->vht_supported) +@@ -1412,10 +1504,10 @@ minstrel_ht_update_caps(void *priv, stru + else + use_vht = 0; + +- msp->is_ht = true; + memset(mi, 0, sizeof(*mi)); + + mi->sta = sta; ++ mi->band = sband->band; + mi->last_stats_update = jiffies; + + ack_dur = ieee80211_frame_duration(sband->band, 10, 60, 1, 1, 0); +@@ -1464,10 +1556,8 @@ minstrel_ht_update_caps(void *priv, stru + int bw, nss; + + mi->supported[i] = 0; +- if (i == MINSTREL_CCK_GROUP) { +- minstrel_ht_update_cck(mp, mi, sband, sta); ++ if (minstrel_ht_is_legacy_group(i)) + continue; +- } + + if (gflags & IEEE80211_TX_RC_SHORT_GI) { + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) { +@@ -1528,22 +1618,12 @@ minstrel_ht_update_caps(void *priv, stru + n_supported++; + } + +- if (!n_supported) +- goto use_legacy; ++ minstrel_ht_update_cck(mp, mi, sband, sta); ++ 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_rates(mp, mi); +- +- return; +- +-use_legacy: +- msp->is_ht = false; +- memset(&msp->legacy, 0, sizeof(msp->legacy)); +- msp->legacy.r = msp->ratelist; +- msp->legacy.sample_table = msp->sample_table; +- return mac80211_minstrel.rate_init(priv, sband, chandef, sta, +- &msp->legacy); + } + + static void +@@ -1611,40 +1691,70 @@ minstrel_ht_free_sta(void *priv, struct + } + + static void +-minstrel_ht_init_cck_rates(struct minstrel_priv *mp) ++minstrel_ht_fill_rate_array(u8 *dest, struct ieee80211_supported_band *sband, ++ const s16 *bitrates, int n_rates, u32 rate_flags) + { +- static const int bitrates[4] = { 10, 20, 55, 110 }; +- struct ieee80211_supported_band *sband; +- u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); + int i, j; + +- sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ]; +- if (!sband) +- return; +- + for (i = 0; i < sband->n_bitrates; i++) { + struct ieee80211_rate *rate = &sband->bitrates[i]; + +- if (rate->flags & IEEE80211_RATE_ERP_G) +- continue; +- + if ((rate_flags & sband->bitrates[i].flags) != rate_flags) + continue; + +- for (j = 0; j < ARRAY_SIZE(bitrates); j++) { ++ for (j = 0; j < n_rates; j++) { + if (rate->bitrate != bitrates[j]) + continue; + +- mp->cck_rates[j] = i; ++ dest[j] = i; + break; + } + } + } + ++static void ++minstrel_ht_init_cck_rates(struct minstrel_priv *mp) ++{ ++ static const s16 bitrates[4] = { 10, 20, 55, 110 }; ++ struct ieee80211_supported_band *sband; ++ u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); ++ ++ memset(mp->cck_rates, 0xff, sizeof(mp->cck_rates)); ++ sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ]; ++ if (!sband) ++ return; ++ ++ BUILD_BUG_ON(ARRAY_SIZE(mp->cck_rates) != ARRAY_SIZE(bitrates)); ++ minstrel_ht_fill_rate_array(mp->cck_rates, sband, ++ minstrel_cck_bitrates, ++ ARRAY_SIZE(minstrel_cck_bitrates), ++ rate_flags); ++} ++ ++static void ++minstrel_ht_init_ofdm_rates(struct minstrel_priv *mp, enum nl80211_band band) ++{ ++ static const s16 bitrates[8] = { 60, 90, 120, 180, 240, 360, 480, 540 }; ++ struct ieee80211_supported_band *sband; ++ u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); ++ ++ memset(mp->ofdm_rates[band], 0xff, sizeof(mp->ofdm_rates[band])); ++ sband = mp->hw->wiphy->bands[band]; ++ if (!sband) ++ return; ++ ++ BUILD_BUG_ON(ARRAY_SIZE(mp->ofdm_rates[band]) != ARRAY_SIZE(bitrates)); ++ minstrel_ht_fill_rate_array(mp->ofdm_rates[band], sband, ++ minstrel_ofdm_bitrates, ++ ARRAY_SIZE(minstrel_ofdm_bitrates), ++ rate_flags); ++} ++ + static void * + minstrel_ht_alloc(struct ieee80211_hw *hw) + { + struct minstrel_priv *mp; ++ int i; + + mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC); + if (!mp) +@@ -1681,6 +1791,8 @@ minstrel_ht_alloc(struct ieee80211_hw *h + mp->new_avg = true; + + minstrel_ht_init_cck_rates(mp); ++ for (i = 0; i < ARRAY_SIZE(mp->hw->wiphy->bands); i++) ++ minstrel_ht_init_ofdm_rates(mp, i); + + return mp; + } +@@ -1713,9 +1825,6 @@ static u32 minstrel_ht_get_expected_thro + struct minstrel_ht_sta *mi = &msp->ht; + int i, j, prob, tp_avg; + +- if (!msp->is_ht) +- return mac80211_minstrel.get_expected_throughput(priv_sta); +- + i = mi->max_tp_rate[0] / MCS_GROUP_RATES; + j = mi->max_tp_rate[0] % MCS_GROUP_RATES; + prob = mi->groups[i].rates[j].prob_avg; +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -18,14 +18,15 @@ + MINSTREL_HT_STREAM_GROUPS) + #define MINSTREL_VHT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ + MINSTREL_VHT_STREAM_GROUPS) +-#define MINSTREL_CCK_GROUPS_NB 1 ++#define MINSTREL_LEGACY_GROUPS_NB 2 + #define MINSTREL_GROUPS_NB (MINSTREL_HT_GROUPS_NB + \ + MINSTREL_VHT_GROUPS_NB + \ +- MINSTREL_CCK_GROUPS_NB) ++ MINSTREL_LEGACY_GROUPS_NB) + + #define MINSTREL_HT_GROUP_0 0 + #define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB) +-#define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1) ++#define MINSTREL_OFDM_GROUP (MINSTREL_CCK_GROUP + 1) ++#define MINSTREL_VHT_GROUP_0 (MINSTREL_OFDM_GROUP + 1) + + #define MCS_GROUP_RATES 10 + +@@ -37,6 +38,8 @@ struct mcs_group { + u16 duration[MCS_GROUP_RATES]; + }; + ++extern const s16 minstrel_cck_bitrates[4]; ++extern const s16 minstrel_ofdm_bitrates[8]; + extern const struct mcs_group minstrel_mcs_groups[]; + + struct minstrel_mcs_group_data { +@@ -99,6 +102,8 @@ struct minstrel_ht_sta { + /* current MCS group to be sampled */ + u8 sample_group; + ++ u8 band; ++ + /* Bitfield of supported MCS rates of all groups */ + u16 supported[MINSTREL_GROUPS_NB]; + +@@ -107,13 +112,9 @@ struct minstrel_ht_sta { + }; + + struct minstrel_ht_sta_priv { +- union { +- struct minstrel_ht_sta ht; +- struct minstrel_sta_info legacy; +- }; ++ struct minstrel_ht_sta ht; + void *ratelist; + void *sample_table; +- bool is_ht; + }; + + void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -52,7 +52,6 @@ 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]; +- static const int bitrates[4] = { 10, 20, 55, 110 }; + int idx = i * MCS_GROUP_RATES + j; + unsigned int duration; + +@@ -67,6 +66,9 @@ minstrel_ht_stats_dump(struct minstrel_h + p += sprintf(p, "VHT%c0 ", htmode); + p += sprintf(p, "%cGI ", gimode); + p += sprintf(p, "%d ", mg->streams); ++ } else if (i == MINSTREL_OFDM_GROUP) { ++ p += sprintf(p, "OFDM "); ++ p += sprintf(p, "1 "); + } else { + p += sprintf(p, "CCK "); + p += sprintf(p, "%cP ", j < 4 ? 'L' : 'S'); +@@ -84,7 +86,12 @@ minstrel_ht_stats_dump(struct minstrel_h + } else if (gflags & IEEE80211_TX_RC_VHT_MCS) { + p += sprintf(p, " MCS%-1u/%1u", j, mg->streams); + } else { +- int r = bitrates[j % 4]; ++ int r; ++ ++ if (i == MINSTREL_OFDM_GROUP) ++ r = minstrel_ofdm_bitrates[j % 8]; ++ else ++ r = minstrel_cck_bitrates[j % 4]; + + p += sprintf(p, " %2u.%1uM", r / 10, r % 10); + } +@@ -124,16 +131,8 @@ minstrel_ht_stats_open(struct inode *ino + struct minstrel_ht_sta *mi = &msp->ht; + struct minstrel_debugfs_info *ms; + unsigned int i; +- int ret; + char *p; + +- if (!msp->is_ht) { +- inode->i_private = &msp->legacy; +- ret = minstrel_stats_open(inode, file); +- inode->i_private = msp; +- return ret; +- } +- + ms = kmalloc(32768, GFP_KERNEL); + if (!ms) + return -ENOMEM; +@@ -199,7 +198,6 @@ 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]; +- static const int bitrates[4] = { 10, 20, 55, 110 }; + int idx = i * MCS_GROUP_RATES + j; + unsigned int duration; + +@@ -214,6 +212,8 @@ minstrel_ht_stats_csv_dump(struct minstr + p += sprintf(p, "VHT%c0,", htmode); + p += sprintf(p, "%cGI,", gimode); + p += sprintf(p, "%d,", mg->streams); ++ } else if (i == MINSTREL_OFDM_GROUP) { ++ p += sprintf(p, "OFDM,,1,"); + } else { + p += sprintf(p, "CCK,"); + p += sprintf(p, "%cP,", j < 4 ? 'L' : 'S'); +@@ -231,7 +231,13 @@ minstrel_ht_stats_csv_dump(struct minstr + } else if (gflags & IEEE80211_TX_RC_VHT_MCS) { + p += sprintf(p, ",MCS%-1u/%1u,", j, mg->streams); + } else { +- int r = bitrates[j % 4]; ++ int r; ++ ++ if (i == MINSTREL_OFDM_GROUP) ++ r = minstrel_ofdm_bitrates[j % 8]; ++ else ++ r = minstrel_cck_bitrates[j % 4]; ++ + p += sprintf(p, ",%2u.%1uM,", r / 10, r % 10); + } + +@@ -274,18 +280,9 @@ minstrel_ht_stats_csv_open(struct inode + struct minstrel_ht_sta *mi = &msp->ht; + struct minstrel_debugfs_info *ms; + unsigned int i; +- int ret; + char *p; + +- if (!msp->is_ht) { +- inode->i_private = &msp->legacy; +- ret = minstrel_stats_csv_open(inode, file); +- inode->i_private = msp; +- return ret; +- } +- + ms = kmalloc(32768, GFP_KERNEL); +- + if (!ms) + return -ENOMEM; + diff --git a/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch b/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch new file mode 100644 index 0000000000..8fd93247af --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch @@ -0,0 +1,1328 @@ +From: Felix Fietkau +Date: Sat, 26 Dec 2020 14:23:47 +0100 +Subject: [PATCH] mac80211: remove legacy minstrel rate control + +Now that minstrel_ht supports legacy rates, it is no longer needed + +Signed-off-by: Felix Fietkau +--- + delete mode 100644 net/mac80211/rc80211_minstrel.c + delete mode 100644 net/mac80211/rc80211_minstrel.h + delete mode 100644 net/mac80211/rc80211_minstrel_debugfs.c + +--- a/net/mac80211/Makefile ++++ b/net/mac80211/Makefile +@@ -54,11 +54,9 @@ mac80211-$(CONFIG_PM) += pm.o + CFLAGS_trace.o := -I$(src) + + rc80211_minstrel-y := \ +- rc80211_minstrel.o \ + rc80211_minstrel_ht.o + + rc80211_minstrel-$(CPTCFG_MAC80211_DEBUGFS) += \ +- rc80211_minstrel_debugfs.o \ + rc80211_minstrel_ht_debugfs.o + + mac80211-$(CPTCFG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) +--- a/net/mac80211/rc80211_minstrel.c ++++ /dev/null +@@ -1,574 +0,0 @@ +-/* +- * Copyright (C) 2008 Felix Fietkau +- * +- * 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. +- * +- * Based on minstrel.c: +- * Copyright (C) 2005-2007 Derek Smithies +- * Sponsored by Indranet Technologies Ltd +- * +- * Based on sample.c: +- * Copyright (c) 2005 John Bicket +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer, +- * without modification. +- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +- * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any +- * redistribution must be conditioned upon including a substantially +- * similar Disclaimer requirement for further binary redistribution. +- * 3. Neither the names of the above-listed copyright holders nor the names +- * of any contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * Alternatively, this software may be distributed under the terms of the +- * GNU General Public License ("GPL") version 2 as published by the Free +- * Software Foundation. +- * +- * NO WARRANTY +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY +- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, +- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +- * THE POSSIBILITY OF SUCH DAMAGES. +- */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "rate.h" +-#include "rc80211_minstrel.h" +- +-#define SAMPLE_TBL(_mi, _idx, _col) \ +- _mi->sample_table[(_idx * SAMPLE_COLUMNS) + _col] +- +-/* convert mac80211 rate index to local array index */ +-static inline int +-rix_to_ndx(struct minstrel_sta_info *mi, int rix) +-{ +- int i = rix; +- for (i = rix; i >= 0; i--) +- if (mi->r[i].rix == rix) +- break; +- return i; +-} +- +-/* return current EMWA throughput */ +-int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg) +-{ +- int usecs; +- +- usecs = mr->perfect_tx_time; +- if (!usecs) +- usecs = 1000000; +- +- /* reset thr. below 10% success */ +- if (mr->stats.prob_avg < MINSTREL_FRAC(10, 100)) +- return 0; +- +- if (prob_avg > MINSTREL_FRAC(90, 100)) +- return MINSTREL_TRUNC(100000 * (MINSTREL_FRAC(90, 100) / usecs)); +- else +- return MINSTREL_TRUNC(100000 * (prob_avg / usecs)); +-} +- +-/* find & sort topmost throughput rates */ +-static inline void +-minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list) +-{ +- int j; +- struct minstrel_rate_stats *tmp_mrs; +- struct minstrel_rate_stats *cur_mrs = &mi->r[i].stats; +- +- for (j = MAX_THR_RATES; j > 0; --j) { +- tmp_mrs = &mi->r[tp_list[j - 1]].stats; +- if (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_avg) <= +- minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_avg)) +- break; +- } +- +- if (j < MAX_THR_RATES - 1) +- memmove(&tp_list[j + 1], &tp_list[j], MAX_THR_RATES - (j + 1)); +- if (j < MAX_THR_RATES) +- tp_list[j] = i; +-} +- +-static void +-minstrel_set_rate(struct minstrel_sta_info *mi, struct ieee80211_sta_rates *ratetbl, +- int offset, int idx) +-{ +- struct minstrel_rate *r = &mi->r[idx]; +- +- ratetbl->rate[offset].idx = r->rix; +- ratetbl->rate[offset].count = r->adjusted_retry_count; +- ratetbl->rate[offset].count_cts = r->retry_count_cts; +- ratetbl->rate[offset].count_rts = r->stats.retry_count_rtscts; +-} +- +-static void +-minstrel_update_rates(struct minstrel_priv *mp, struct minstrel_sta_info *mi) +-{ +- struct ieee80211_sta_rates *ratetbl; +- int i = 0; +- +- ratetbl = kzalloc(sizeof(*ratetbl), GFP_ATOMIC); +- if (!ratetbl) +- return; +- +- /* Start with max_tp_rate */ +- minstrel_set_rate(mi, ratetbl, i++, mi->max_tp_rate[0]); +- +- if (mp->hw->max_rates >= 3) { +- /* At least 3 tx rates supported, use max_tp_rate2 next */ +- minstrel_set_rate(mi, ratetbl, i++, mi->max_tp_rate[1]); +- } +- +- if (mp->hw->max_rates >= 2) { +- /* At least 2 tx rates supported, use max_prob_rate next */ +- minstrel_set_rate(mi, ratetbl, i++, mi->max_prob_rate); +- } +- +- /* Use lowest rate last */ +- ratetbl->rate[i].idx = mi->lowest_rix; +- ratetbl->rate[i].count = mp->max_retry; +- ratetbl->rate[i].count_cts = mp->max_retry; +- ratetbl->rate[i].count_rts = mp->max_retry; +- +- rate_control_set_rates(mp->hw, mi->sta, ratetbl); +-} +- +-/* +-* Recalculate statistics and counters of a given rate +-*/ +-void +-minstrel_calc_rate_stats(struct minstrel_priv *mp, +- struct minstrel_rate_stats *mrs) +-{ +- unsigned int cur_prob; +- +- if (unlikely(mrs->attempts > 0)) { +- mrs->sample_skipped = 0; +- cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); +- if (mp->new_avg) { +- minstrel_filter_avg_add(&mrs->prob_avg, +- &mrs->prob_avg_1, cur_prob); +- } else if (unlikely(!mrs->att_hist)) { +- mrs->prob_avg = cur_prob; +- } else { +- /*update exponential weighted moving avarage */ +- mrs->prob_avg = minstrel_ewma(mrs->prob_avg, +- cur_prob, +- EWMA_LEVEL); +- } +- mrs->att_hist += mrs->attempts; +- mrs->succ_hist += mrs->success; +- } else { +- mrs->sample_skipped++; +- } +- +- mrs->last_success = mrs->success; +- mrs->last_attempts = mrs->attempts; +- mrs->success = 0; +- mrs->attempts = 0; +-} +- +-static void +-minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) +-{ +- u8 tmp_tp_rate[MAX_THR_RATES]; +- u8 tmp_prob_rate = 0; +- int i, tmp_cur_tp, tmp_prob_tp; +- +- for (i = 0; i < MAX_THR_RATES; i++) +- tmp_tp_rate[i] = 0; +- +- for (i = 0; i < mi->n_rates; i++) { +- struct minstrel_rate *mr = &mi->r[i]; +- struct minstrel_rate_stats *mrs = &mi->r[i].stats; +- struct minstrel_rate_stats *tmp_mrs = &mi->r[tmp_prob_rate].stats; +- +- /* Update statistics of success probability per rate */ +- minstrel_calc_rate_stats(mp, mrs); +- +- /* Sample less often below the 10% chance of success. +- * Sample less often above the 95% chance of success. */ +- if (mrs->prob_avg > MINSTREL_FRAC(95, 100) || +- mrs->prob_avg < MINSTREL_FRAC(10, 100)) { +- mr->adjusted_retry_count = mrs->retry_count >> 1; +- if (mr->adjusted_retry_count > 2) +- mr->adjusted_retry_count = 2; +- mr->sample_limit = 4; +- } else { +- mr->sample_limit = -1; +- mr->adjusted_retry_count = mrs->retry_count; +- } +- if (!mr->adjusted_retry_count) +- mr->adjusted_retry_count = 2; +- +- minstrel_sort_best_tp_rates(mi, i, tmp_tp_rate); +- +- /* To determine the most robust rate (max_prob_rate) used at +- * 3rd mmr stage we distinct between two cases: +- * (1) if any success probabilitiy >= 95%, out of those rates +- * choose the maximum throughput rate as max_prob_rate +- * (2) if all success probabilities < 95%, the rate with +- * highest success probability is chosen as max_prob_rate */ +- if (mrs->prob_avg >= MINSTREL_FRAC(95, 100)) { +- tmp_cur_tp = minstrel_get_tp_avg(mr, mrs->prob_avg); +- tmp_prob_tp = minstrel_get_tp_avg(&mi->r[tmp_prob_rate], +- tmp_mrs->prob_avg); +- if (tmp_cur_tp >= tmp_prob_tp) +- tmp_prob_rate = i; +- } else { +- if (mrs->prob_avg >= tmp_mrs->prob_avg) +- tmp_prob_rate = i; +- } +- } +- +- /* Assign the new rate set */ +- memcpy(mi->max_tp_rate, tmp_tp_rate, sizeof(mi->max_tp_rate)); +- mi->max_prob_rate = tmp_prob_rate; +- +-#ifdef CPTCFG_MAC80211_DEBUGFS +- /* use fixed index if set */ +- if (mp->fixed_rate_idx != -1) { +- mi->max_tp_rate[0] = mp->fixed_rate_idx; +- mi->max_tp_rate[1] = mp->fixed_rate_idx; +- mi->max_prob_rate = mp->fixed_rate_idx; +- } +-#endif +- +- /* Reset update timer */ +- mi->last_stats_update = jiffies; +- +- minstrel_update_rates(mp, mi); +-} +- +-static void +-minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband, +- void *priv_sta, struct ieee80211_tx_status *st) +-{ +- struct ieee80211_tx_info *info = st->info; +- struct minstrel_priv *mp = priv; +- struct minstrel_sta_info *mi = priv_sta; +- struct ieee80211_tx_rate *ar = info->status.rates; +- int i, ndx; +- int success; +- +- success = !!(info->flags & IEEE80211_TX_STAT_ACK); +- +- for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { +- if (ar[i].idx < 0 || !ar[i].count) +- break; +- +- ndx = rix_to_ndx(mi, ar[i].idx); +- if (ndx < 0) +- continue; +- +- mi->r[ndx].stats.attempts += ar[i].count; +- +- if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) +- mi->r[ndx].stats.success += success; +- } +- +- if (time_after(jiffies, mi->last_stats_update + +- mp->update_interval / (mp->new_avg ? 2 : 1))) +- minstrel_update_stats(mp, mi); +-} +- +- +-static inline unsigned int +-minstrel_get_retry_count(struct minstrel_rate *mr, +- struct ieee80211_tx_info *info) +-{ +- u8 retry = mr->adjusted_retry_count; +- +- if (info->control.use_rts) +- retry = max_t(u8, 2, min(mr->stats.retry_count_rtscts, retry)); +- else if (info->control.use_cts_prot) +- retry = max_t(u8, 2, min(mr->retry_count_cts, retry)); +- return retry; +-} +- +- +-static int +-minstrel_get_next_sample(struct minstrel_sta_info *mi) +-{ +- unsigned int sample_ndx; +- sample_ndx = SAMPLE_TBL(mi, mi->sample_row, mi->sample_column); +- mi->sample_row++; +- if ((int) mi->sample_row >= mi->n_rates) { +- mi->sample_row = 0; +- mi->sample_column++; +- if (mi->sample_column >= SAMPLE_COLUMNS) +- mi->sample_column = 0; +- } +- return sample_ndx; +-} +- +-static void +-minstrel_get_rate(void *priv, struct ieee80211_sta *sta, +- void *priv_sta, struct ieee80211_tx_rate_control *txrc) +-{ +- struct sk_buff *skb = txrc->skb; +- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +- struct minstrel_sta_info *mi = priv_sta; +- struct minstrel_priv *mp = priv; +- struct ieee80211_tx_rate *rate = &info->control.rates[0]; +- struct minstrel_rate *msr, *mr; +- unsigned int ndx; +- bool mrr_capable; +- bool prev_sample; +- int delta; +- int sampling_ratio; +- +- /* check multi-rate-retry capabilities & adjust lookaround_rate */ +- mrr_capable = mp->has_mrr && +- !txrc->rts && +- !txrc->bss_conf->use_cts_prot; +- if (mrr_capable) +- sampling_ratio = mp->lookaround_rate_mrr; +- else +- sampling_ratio = mp->lookaround_rate; +- +- /* increase sum packet counter */ +- mi->total_packets++; +- +-#ifdef CPTCFG_MAC80211_DEBUGFS +- if (mp->fixed_rate_idx != -1) +- return; +-#endif +- +- /* Don't use EAPOL frames for sampling on non-mrr hw */ +- if (mp->hw->max_rates == 1 && +- (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) +- return; +- +- delta = (mi->total_packets * sampling_ratio / 100) - +- mi->sample_packets; +- +- /* delta < 0: no sampling required */ +- prev_sample = mi->prev_sample; +- mi->prev_sample = false; +- if (delta < 0 || (!mrr_capable && prev_sample)) +- return; +- +- if (mi->total_packets >= 10000) { +- mi->sample_packets = 0; +- mi->total_packets = 0; +- } else if (delta > mi->n_rates * 2) { +- /* With multi-rate retry, not every planned sample +- * attempt actually gets used, due to the way the retry +- * chain is set up - [max_tp,sample,prob,lowest] for +- * sample_rate < max_tp. +- * +- * If there's too much sampling backlog and the link +- * starts getting worse, minstrel would start bursting +- * out lots of sampling frames, which would result +- * in a large throughput loss. */ +- mi->sample_packets += (delta - mi->n_rates * 2); +- } +- +- /* get next random rate sample */ +- ndx = minstrel_get_next_sample(mi); +- msr = &mi->r[ndx]; +- mr = &mi->r[mi->max_tp_rate[0]]; +- +- /* Decide if direct ( 1st mrr stage) or indirect (2nd mrr stage) +- * rate sampling method should be used. +- * Respect such rates that are not sampled for 20 interations. +- */ +- if (msr->perfect_tx_time < mr->perfect_tx_time || +- msr->stats.sample_skipped >= 20) { +- if (!msr->sample_limit) +- return; +- +- mi->sample_packets++; +- if (msr->sample_limit > 0) +- msr->sample_limit--; +- } +- +- /* If we're not using MRR and the sampling rate already +- * has a probability of >95%, we shouldn't be attempting +- * to use it, as this only wastes precious airtime */ +- if (!mrr_capable && +- (mi->r[ndx].stats.prob_avg > MINSTREL_FRAC(95, 100))) +- return; +- +- mi->prev_sample = true; +- +- rate->idx = mi->r[ndx].rix; +- rate->count = minstrel_get_retry_count(&mi->r[ndx], info); +- info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; +-} +- +- +-static void +-calc_rate_durations(enum nl80211_band band, +- struct minstrel_rate *d, +- struct ieee80211_rate *rate, +- struct cfg80211_chan_def *chandef) +-{ +- int erp = !!(rate->flags & IEEE80211_RATE_ERP_G); +- int shift = ieee80211_chandef_get_shift(chandef); +- +- d->perfect_tx_time = ieee80211_frame_duration(band, 1200, +- DIV_ROUND_UP(rate->bitrate, 1 << shift), erp, 1, +- shift); +- d->ack_time = ieee80211_frame_duration(band, 10, +- DIV_ROUND_UP(rate->bitrate, 1 << shift), erp, 1, +- shift); +-} +- +-static void +-init_sample_table(struct minstrel_sta_info *mi) +-{ +- unsigned int i, col, new_idx; +- u8 rnd[8]; +- +- mi->sample_column = 0; +- mi->sample_row = 0; +- memset(mi->sample_table, 0xff, SAMPLE_COLUMNS * mi->n_rates); +- +- for (col = 0; col < SAMPLE_COLUMNS; col++) { +- prandom_bytes(rnd, sizeof(rnd)); +- for (i = 0; i < mi->n_rates; i++) { +- new_idx = (i + rnd[i & 7]) % mi->n_rates; +- while (SAMPLE_TBL(mi, new_idx, col) != 0xff) +- new_idx = (new_idx + 1) % mi->n_rates; +- +- SAMPLE_TBL(mi, new_idx, col) = i; +- } +- } +-} +- +-static void +-minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, +- struct cfg80211_chan_def *chandef, +- struct ieee80211_sta *sta, void *priv_sta) +-{ +- struct minstrel_sta_info *mi = priv_sta; +- struct minstrel_priv *mp = priv; +- struct ieee80211_rate *ctl_rate; +- unsigned int i, n = 0; +- unsigned int t_slot = 9; /* FIXME: get real slot time */ +- u32 rate_flags; +- +- mi->sta = sta; +- mi->lowest_rix = rate_lowest_index(sband, sta); +- ctl_rate = &sband->bitrates[mi->lowest_rix]; +- mi->sp_ack_dur = ieee80211_frame_duration(sband->band, 10, +- ctl_rate->bitrate, +- !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1, +- ieee80211_chandef_get_shift(chandef)); +- +- rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); +- memset(mi->max_tp_rate, 0, sizeof(mi->max_tp_rate)); +- mi->max_prob_rate = 0; +- +- for (i = 0; i < sband->n_bitrates; i++) { +- struct minstrel_rate *mr = &mi->r[n]; +- struct minstrel_rate_stats *mrs = &mi->r[n].stats; +- unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0; +- unsigned int tx_time_single; +- unsigned int cw = mp->cw_min; +- int shift; +- +- if (!rate_supported(sta, sband->band, i)) +- continue; +- if ((rate_flags & sband->bitrates[i].flags) != rate_flags) +- continue; +- +- n++; +- memset(mr, 0, sizeof(*mr)); +- memset(mrs, 0, sizeof(*mrs)); +- +- mr->rix = i; +- shift = ieee80211_chandef_get_shift(chandef); +- mr->bitrate = DIV_ROUND_UP(sband->bitrates[i].bitrate, +- (1 << shift) * 5); +- calc_rate_durations(sband->band, mr, &sband->bitrates[i], +- chandef); +- +- /* calculate maximum number of retransmissions before +- * fallback (based on maximum segment size) */ +- mr->sample_limit = -1; +- mrs->retry_count = 1; +- mr->retry_count_cts = 1; +- mrs->retry_count_rtscts = 1; +- tx_time = mr->perfect_tx_time + mi->sp_ack_dur; +- do { +- /* add one retransmission */ +- tx_time_single = mr->ack_time + mr->perfect_tx_time; +- +- /* contention window */ +- tx_time_single += (t_slot * cw) >> 1; +- cw = min((cw << 1) | 1, mp->cw_max); +- +- tx_time += tx_time_single; +- tx_time_cts += tx_time_single + mi->sp_ack_dur; +- tx_time_rtscts += tx_time_single + 2 * mi->sp_ack_dur; +- if ((tx_time_cts < mp->segment_size) && +- (mr->retry_count_cts < mp->max_retry)) +- mr->retry_count_cts++; +- if ((tx_time_rtscts < mp->segment_size) && +- (mrs->retry_count_rtscts < mp->max_retry)) +- mrs->retry_count_rtscts++; +- } while ((tx_time < mp->segment_size) && +- (++mr->stats.retry_count < mp->max_retry)); +- mr->adjusted_retry_count = mrs->retry_count; +- if (!(sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)) +- mr->retry_count_cts = mrs->retry_count; +- } +- +- for (i = n; i < sband->n_bitrates; i++) { +- struct minstrel_rate *mr = &mi->r[i]; +- mr->rix = -1; +- } +- +- mi->n_rates = n; +- mi->last_stats_update = jiffies; +- +- init_sample_table(mi); +- minstrel_update_rates(mp, mi); +-} +- +-static u32 minstrel_get_expected_throughput(void *priv_sta) +-{ +- struct minstrel_sta_info *mi = priv_sta; +- struct minstrel_rate_stats *tmp_mrs; +- int idx = mi->max_tp_rate[0]; +- int tmp_cur_tp; +- +- /* convert pkt per sec in kbps (1200 is the average pkt size used for +- * computing cur_tp +- */ +- tmp_mrs = &mi->r[idx].stats; +- tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_avg) * 10; +- tmp_cur_tp = tmp_cur_tp * 1200 * 8 / 1024; +- +- return tmp_cur_tp; +-} +- +-const struct rate_control_ops mac80211_minstrel = { +- .tx_status_ext = minstrel_tx_status, +- .get_rate = minstrel_get_rate, +- .rate_init = minstrel_rate_init, +- .get_expected_throughput = minstrel_get_expected_throughput, +-}; +--- a/net/mac80211/rc80211_minstrel.h ++++ /dev/null +@@ -1,185 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-only */ +-/* +- * Copyright (C) 2008 Felix Fietkau +- */ +- +-#ifndef __RC_MINSTREL_H +-#define __RC_MINSTREL_H +- +-#define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */ +-#define EWMA_DIV 128 +-#define SAMPLE_COLUMNS 10 /* number of columns in sample table */ +- +-/* scaled fraction values */ +-#define MINSTREL_SCALE 12 +-#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div) +-#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE) +- +-/* number of highest throughput rates to consider*/ +-#define MAX_THR_RATES 4 +- +-/* +- * Coefficients for moving average with noise filter (period=16), +- * scaled by 10 bits +- * +- * a1 = exp(-pi * sqrt(2) / period) +- * coeff2 = 2 * a1 * cos(sqrt(2) * 2 * pi / period) +- * coeff3 = -sqr(a1) +- * coeff1 = 1 - coeff2 - coeff3 +- */ +-#define MINSTREL_AVG_COEFF1 (MINSTREL_FRAC(1, 1) - \ +- MINSTREL_AVG_COEFF2 - \ +- MINSTREL_AVG_COEFF3) +-#define MINSTREL_AVG_COEFF2 0x00001499 +-#define MINSTREL_AVG_COEFF3 -0x0000092e +- +-/* +- * Perform EWMA (Exponentially Weighted Moving Average) calculation +- */ +-static inline int +-minstrel_ewma(int old, int new, int weight) +-{ +- int diff, incr; +- +- diff = new - old; +- incr = (EWMA_DIV - weight) * diff / EWMA_DIV; +- +- return old + incr; +-} +- +-static inline int minstrel_filter_avg_add(u16 *prev_1, u16 *prev_2, s32 in) +-{ +- s32 out_1 = *prev_1; +- s32 out_2 = *prev_2; +- s32 val; +- +- if (!in) +- in += 1; +- +- if (!out_1) { +- val = out_1 = in; +- goto out; +- } +- +- val = MINSTREL_AVG_COEFF1 * in; +- val += MINSTREL_AVG_COEFF2 * out_1; +- val += MINSTREL_AVG_COEFF3 * out_2; +- val >>= MINSTREL_SCALE; +- +- if (val > 1 << MINSTREL_SCALE) +- val = 1 << MINSTREL_SCALE; +- if (val < 0) +- val = 1; +- +-out: +- *prev_2 = out_1; +- *prev_1 = val; +- +- return val; +-} +- +-struct minstrel_rate_stats { +- /* current / last sampling period attempts/success counters */ +- u16 attempts, last_attempts; +- u16 success, last_success; +- +- /* total attempts/success counters */ +- u32 att_hist, succ_hist; +- +- /* prob_avg - moving average of prob */ +- u16 prob_avg; +- u16 prob_avg_1; +- +- /* maximum retry counts */ +- u8 retry_count; +- u8 retry_count_rtscts; +- +- u8 sample_skipped; +- bool retry_updated; +-}; +- +-struct minstrel_rate { +- int bitrate; +- +- s8 rix; +- u8 retry_count_cts; +- u8 adjusted_retry_count; +- +- unsigned int perfect_tx_time; +- unsigned int ack_time; +- +- int sample_limit; +- +- struct minstrel_rate_stats stats; +-}; +- +-struct minstrel_sta_info { +- struct ieee80211_sta *sta; +- +- unsigned long last_stats_update; +- unsigned int sp_ack_dur; +- unsigned int rate_avg; +- +- unsigned int lowest_rix; +- +- u8 max_tp_rate[MAX_THR_RATES]; +- u8 max_prob_rate; +- unsigned int total_packets; +- unsigned int sample_packets; +- +- unsigned int sample_row; +- unsigned int sample_column; +- +- int n_rates; +- struct minstrel_rate *r; +- bool prev_sample; +- +- /* sampling table */ +- u8 *sample_table; +-}; +- +-struct minstrel_priv { +- struct ieee80211_hw *hw; +- bool has_mrr; +- bool new_avg; +- u32 sample_switch; +- unsigned int cw_min; +- unsigned int cw_max; +- unsigned int max_retry; +- unsigned int segment_size; +- unsigned int update_interval; +- unsigned int lookaround_rate; +- unsigned int lookaround_rate_mrr; +- +- u8 cck_rates[4]; +- u8 ofdm_rates[NUM_NL80211_BANDS][8]; +- +-#ifdef CPTCFG_MAC80211_DEBUGFS +- /* +- * enable fixed rate processing per RC +- * - write static index to debugfs:ieee80211/phyX/rc/fixed_rate_idx +- * - write -1 to enable RC processing again +- * - setting will be applied on next update +- */ +- u32 fixed_rate_idx; +-#endif +-}; +- +-struct minstrel_debugfs_info { +- size_t len; +- char buf[]; +-}; +- +-extern const struct rate_control_ops mac80211_minstrel; +-void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); +- +-/* Recalculate success probabilities and counters for a given rate using EWMA */ +-void minstrel_calc_rate_stats(struct minstrel_priv *mp, +- struct minstrel_rate_stats *mrs); +-int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg); +- +-/* debugfs */ +-int minstrel_stats_open(struct inode *inode, struct file *file); +-int minstrel_stats_csv_open(struct inode *inode, struct file *file); +- +-#endif +--- a/net/mac80211/rc80211_minstrel_debugfs.c ++++ /dev/null +@@ -1,172 +0,0 @@ +-/* +- * Copyright (C) 2008 Felix Fietkau +- * +- * 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. +- * +- * Based on minstrel.c: +- * Copyright (C) 2005-2007 Derek Smithies +- * Sponsored by Indranet Technologies Ltd +- * +- * Based on sample.c: +- * Copyright (c) 2005 John Bicket +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer, +- * without modification. +- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +- * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any +- * redistribution must be conditioned upon including a substantially +- * similar Disclaimer requirement for further binary redistribution. +- * 3. Neither the names of the above-listed copyright holders nor the names +- * of any contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * Alternatively, this software may be distributed under the terms of the +- * GNU General Public License ("GPL") version 2 as published by the Free +- * Software Foundation. +- * +- * NO WARRANTY +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY +- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, +- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +- * THE POSSIBILITY OF SUCH DAMAGES. +- */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "rc80211_minstrel.h" +- +-int +-minstrel_stats_open(struct inode *inode, struct file *file) +-{ +- struct minstrel_sta_info *mi = inode->i_private; +- struct minstrel_debugfs_info *ms; +- unsigned int i, tp_max, tp_avg, eprob; +- char *p; +- +- ms = kmalloc(2048, GFP_KERNEL); +- if (!ms) +- return -ENOMEM; +- +- file->private_data = ms; +- p = ms->buf; +- p += sprintf(p, "\n"); +- p += sprintf(p, +- "best __________rate_________ ____statistics___ ____last_____ ______sum-of________\n"); +- p += sprintf(p, +- "rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]\n"); +- +- for (i = 0; i < mi->n_rates; i++) { +- struct minstrel_rate *mr = &mi->r[i]; +- struct minstrel_rate_stats *mrs = &mi->r[i].stats; +- +- *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' '; +- *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' '; +- *(p++) = (i == mi->max_tp_rate[2]) ? 'C' : ' '; +- *(p++) = (i == mi->max_tp_rate[3]) ? 'D' : ' '; +- *(p++) = (i == mi->max_prob_rate) ? 'P' : ' '; +- +- p += sprintf(p, " %3u%s ", mr->bitrate / 2, +- (mr->bitrate & 1 ? ".5" : " ")); +- p += sprintf(p, "%3u ", i); +- p += sprintf(p, "%6u ", mr->perfect_tx_time); +- +- tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); +- tp_avg = minstrel_get_tp_avg(mr, mrs->prob_avg); +- eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000); +- +- p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u" +- " %3u %3u %-3u " +- "%9llu %-9llu\n", +- tp_max / 10, tp_max % 10, +- tp_avg / 10, tp_avg % 10, +- eprob / 10, eprob % 10, +- mrs->retry_count, +- mrs->last_success, +- mrs->last_attempts, +- (unsigned long long)mrs->succ_hist, +- (unsigned long long)mrs->att_hist); +- } +- p += sprintf(p, "\nTotal packet count:: ideal %d " +- "lookaround %d\n\n", +- mi->total_packets - mi->sample_packets, +- mi->sample_packets); +- ms->len = p - ms->buf; +- +- WARN_ON(ms->len + sizeof(*ms) > 2048); +- +- return 0; +-} +- +-int +-minstrel_stats_csv_open(struct inode *inode, struct file *file) +-{ +- struct minstrel_sta_info *mi = inode->i_private; +- struct minstrel_debugfs_info *ms; +- unsigned int i, tp_max, tp_avg, eprob; +- char *p; +- +- ms = kmalloc(2048, GFP_KERNEL); +- if (!ms) +- return -ENOMEM; +- +- file->private_data = ms; +- p = ms->buf; +- +- for (i = 0; i < mi->n_rates; i++) { +- struct minstrel_rate *mr = &mi->r[i]; +- struct minstrel_rate_stats *mrs = &mi->r[i].stats; +- +- p += sprintf(p, "%s" ,((i == mi->max_tp_rate[0]) ? "A" : "")); +- p += sprintf(p, "%s" ,((i == mi->max_tp_rate[1]) ? "B" : "")); +- p += sprintf(p, "%s" ,((i == mi->max_tp_rate[2]) ? "C" : "")); +- p += sprintf(p, "%s" ,((i == mi->max_tp_rate[3]) ? "D" : "")); +- p += sprintf(p, "%s" ,((i == mi->max_prob_rate) ? "P" : "")); +- +- p += sprintf(p, ",%u%s", mr->bitrate / 2, +- (mr->bitrate & 1 ? ".5," : ",")); +- p += sprintf(p, "%u,", i); +- p += sprintf(p, "%u,",mr->perfect_tx_time); +- +- tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); +- tp_avg = minstrel_get_tp_avg(mr, mrs->prob_avg); +- eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000); +- +- p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u,%u," +- "%llu,%llu,%d,%d\n", +- tp_max / 10, tp_max % 10, +- tp_avg / 10, tp_avg % 10, +- eprob / 10, eprob % 10, +- mrs->retry_count, +- mrs->last_success, +- mrs->last_attempts, +- (unsigned long long)mrs->succ_hist, +- (unsigned long long)mrs->att_hist, +- mi->total_packets - mi->sample_packets, +- mi->sample_packets); +- +- } +- ms->len = p - ms->buf; +- +- WARN_ON(ms->len + sizeof(*ms) > 2048); +- +- return 0; +-} +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -13,7 +13,6 @@ + #include + #include "rate.h" + #include "sta_info.h" +-#include "rc80211_minstrel.h" + #include "rc80211_minstrel_ht.h" + + #define AVG_AMPDU_SIZE 16 +@@ -716,6 +715,83 @@ out: + mi->sample_mode = MINSTREL_SAMPLE_ACTIVE; + } + ++static inline int ++minstrel_ewma(int old, int new, int weight) ++{ ++ int diff, incr; ++ ++ diff = new - old; ++ incr = (EWMA_DIV - weight) * diff / EWMA_DIV; ++ ++ return old + incr; ++} ++ ++static inline int minstrel_filter_avg_add(u16 *prev_1, u16 *prev_2, s32 in) ++{ ++ s32 out_1 = *prev_1; ++ s32 out_2 = *prev_2; ++ s32 val; ++ ++ if (!in) ++ in += 1; ++ ++ if (!out_1) { ++ val = out_1 = in; ++ goto out; ++ } ++ ++ val = MINSTREL_AVG_COEFF1 * in; ++ val += MINSTREL_AVG_COEFF2 * out_1; ++ val += MINSTREL_AVG_COEFF3 * out_2; ++ val >>= MINSTREL_SCALE; ++ ++ if (val > 1 << MINSTREL_SCALE) ++ val = 1 << MINSTREL_SCALE; ++ if (val < 0) ++ val = 1; ++ ++out: ++ *prev_2 = out_1; ++ *prev_1 = val; ++ ++ return val; ++} ++ ++/* ++* Recalculate statistics and counters of a given rate ++*/ ++static void ++minstrel_ht_calc_rate_stats(struct minstrel_priv *mp, ++ struct minstrel_rate_stats *mrs) ++{ ++ unsigned int cur_prob; ++ ++ if (unlikely(mrs->attempts > 0)) { ++ mrs->sample_skipped = 0; ++ cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); ++ if (mp->new_avg) { ++ minstrel_filter_avg_add(&mrs->prob_avg, ++ &mrs->prob_avg_1, cur_prob); ++ } else if (unlikely(!mrs->att_hist)) { ++ mrs->prob_avg = cur_prob; ++ } else { ++ /*update exponential weighted moving avarage */ ++ mrs->prob_avg = minstrel_ewma(mrs->prob_avg, ++ cur_prob, ++ EWMA_LEVEL); ++ } ++ mrs->att_hist += mrs->attempts; ++ mrs->succ_hist += mrs->success; ++ } else { ++ mrs->sample_skipped++; ++ } ++ ++ mrs->last_success = mrs->success; ++ mrs->last_attempts = mrs->attempts; ++ mrs->success = 0; ++ mrs->attempts = 0; ++} ++ + /* + * Update rate statistics and select new primary rates + * +@@ -808,7 +884,7 @@ minstrel_ht_update_stats(struct minstrel + + mrs = &mg->rates[i]; + mrs->retry_updated = false; +- minstrel_calc_rate_stats(mp, mrs); ++ minstrel_ht_calc_rate_stats(mp, mrs); + cur_prob = mrs->prob_avg; + + if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0) +@@ -960,8 +1036,7 @@ minstrel_ht_tx_status(void *priv, struct + void *priv_sta, struct ieee80211_tx_status *st) + { + struct ieee80211_tx_info *info = st->info; +- struct minstrel_ht_sta_priv *msp = priv_sta; +- struct minstrel_ht_sta *mi = &msp->ht; ++ 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_priv *mp = priv; +@@ -1372,8 +1447,7 @@ minstrel_ht_get_rate(void *priv, struct + const struct mcs_group *sample_group; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); + struct ieee80211_tx_rate *rate = &info->status.rates[0]; +- struct minstrel_ht_sta_priv *msp = priv_sta; +- struct minstrel_ht_sta *mi = &msp->ht; ++ struct minstrel_ht_sta *mi = priv_sta; + struct minstrel_priv *mp = priv; + int sample_idx; + +@@ -1484,8 +1558,7 @@ minstrel_ht_update_caps(void *priv, stru + struct ieee80211_sta *sta, void *priv_sta) + { + struct minstrel_priv *mp = priv; +- struct minstrel_ht_sta_priv *msp = priv_sta; +- struct minstrel_ht_sta *mi = &msp->ht; ++ struct minstrel_ht_sta *mi = priv_sta; + struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; + u16 ht_cap = sta->ht_cap.cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; +@@ -1647,7 +1720,7 @@ static void * + minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) + { + struct ieee80211_supported_band *sband; +- struct minstrel_ht_sta_priv *msp; ++ struct minstrel_ht_sta *mi; + struct minstrel_priv *mp = priv; + struct ieee80211_hw *hw = mp->hw; + int max_rates = 0; +@@ -1659,35 +1732,13 @@ minstrel_ht_alloc_sta(void *priv, struct + max_rates = sband->n_bitrates; + } + +- msp = kzalloc(sizeof(*msp), gfp); +- if (!msp) +- return NULL; +- +- msp->ratelist = kcalloc(max_rates, sizeof(struct minstrel_rate), gfp); +- if (!msp->ratelist) +- goto error; +- +- msp->sample_table = kmalloc_array(max_rates, SAMPLE_COLUMNS, gfp); +- if (!msp->sample_table) +- goto error1; +- +- return msp; +- +-error1: +- kfree(msp->ratelist); +-error: +- kfree(msp); +- return NULL; ++ return kzalloc(sizeof(*mi), gfp); + } + + static void + minstrel_ht_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta) + { +- struct minstrel_ht_sta_priv *msp = priv_sta; +- +- kfree(msp->sample_table); +- kfree(msp->ratelist); +- kfree(msp); ++ kfree(priv_sta); + } + + static void +@@ -1768,12 +1819,6 @@ minstrel_ht_alloc(struct ieee80211_hw *h + mp->cw_min = 15; + mp->cw_max = 1023; + +- /* number of packets (in %) to use for sampling other rates +- * sample less often for non-mrr packets, because the overhead +- * is much higher than with mrr */ +- mp->lookaround_rate = 5; +- mp->lookaround_rate_mrr = 10; +- + /* maximum time that the hw is allowed to stay in one MRR segment */ + mp->segment_size = 6000; + +@@ -1821,8 +1866,7 @@ minstrel_ht_free(void *priv) + + static u32 minstrel_ht_get_expected_throughput(void *priv_sta) + { +- struct minstrel_ht_sta_priv *msp = priv_sta; +- struct minstrel_ht_sta *mi = &msp->ht; ++ struct minstrel_ht_sta *mi = priv_sta; + int i, j, prob, tp_avg; + + i = mi->max_tp_rate[0] / MCS_GROUP_RATES; +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -6,6 +6,33 @@ + #ifndef __RC_MINSTREL_HT_H + #define __RC_MINSTREL_HT_H + ++/* number of highest throughput rates to consider*/ ++#define MAX_THR_RATES 4 ++#define SAMPLE_COLUMNS 10 /* number of columns in sample table */ ++ ++/* scaled fraction values */ ++#define MINSTREL_SCALE 12 ++#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] */ ++#define EWMA_DIV 128 ++ ++/* ++ * Coefficients for moving average with noise filter (period=16), ++ * scaled by 10 bits ++ * ++ * a1 = exp(-pi * sqrt(2) / period) ++ * coeff2 = 2 * a1 * cos(sqrt(2) * 2 * pi / period) ++ * coeff3 = -sqr(a1) ++ * coeff1 = 1 - coeff2 - coeff3 ++ */ ++#define MINSTREL_AVG_COEFF1 (MINSTREL_FRAC(1, 1) - \ ++ MINSTREL_AVG_COEFF2 - \ ++ MINSTREL_AVG_COEFF3) ++#define MINSTREL_AVG_COEFF2 0x00001499 ++#define MINSTREL_AVG_COEFF3 -0x0000092e ++ + /* + * The number of streams can be changed to 2 to reduce code + * size and memory footprint. +@@ -30,6 +57,32 @@ + + #define MCS_GROUP_RATES 10 + ++struct minstrel_priv { ++ struct ieee80211_hw *hw; ++ bool has_mrr; ++ bool new_avg; ++ u32 sample_switch; ++ unsigned int cw_min; ++ unsigned int cw_max; ++ unsigned int max_retry; ++ unsigned int segment_size; ++ unsigned int update_interval; ++ ++ u8 cck_rates[4]; ++ u8 ofdm_rates[NUM_NL80211_BANDS][8]; ++ ++#ifdef CPTCFG_MAC80211_DEBUGFS ++ /* ++ * enable fixed rate processing per RC ++ * - write static index to debugfs:ieee80211/phyX/rc/fixed_rate_idx ++ * - write -1 to enable RC processing again ++ * - setting will be applied on next update ++ */ ++ u32 fixed_rate_idx; ++#endif ++}; ++ ++ + struct mcs_group { + u16 flags; + u8 streams; +@@ -42,6 +95,26 @@ extern const s16 minstrel_cck_bitrates[4 + extern const s16 minstrel_ofdm_bitrates[8]; + extern const struct mcs_group minstrel_mcs_groups[]; + ++struct minstrel_rate_stats { ++ /* current / last sampling period attempts/success counters */ ++ u16 attempts, last_attempts; ++ u16 success, last_success; ++ ++ /* total attempts/success counters */ ++ u32 att_hist, succ_hist; ++ ++ /* prob_avg - moving average of prob */ ++ u16 prob_avg; ++ u16 prob_avg_1; ++ ++ /* maximum retry counts */ ++ u8 retry_count; ++ u8 retry_count_rtscts; ++ ++ u8 sample_skipped; ++ bool retry_updated; ++}; ++ + struct minstrel_mcs_group_data { + u8 index; + u8 column; +@@ -111,12 +184,6 @@ struct minstrel_ht_sta { + struct minstrel_mcs_group_data groups[MINSTREL_GROUPS_NB]; + }; + +-struct minstrel_ht_sta_priv { +- struct minstrel_ht_sta ht; +- void *ratelist; +- void *sample_table; +-}; +- + void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); + int minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate, + int prob_avg); +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -9,9 +9,13 @@ + #include + #include + #include +-#include "rc80211_minstrel.h" + #include "rc80211_minstrel_ht.h" + ++struct minstrel_debugfs_info { ++ size_t len; ++ char buf[]; ++}; ++ + static ssize_t + minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) + { +@@ -127,8 +131,7 @@ minstrel_ht_stats_dump(struct minstrel_h + static int + minstrel_ht_stats_open(struct inode *inode, struct file *file) + { +- struct minstrel_ht_sta_priv *msp = inode->i_private; +- struct minstrel_ht_sta *mi = &msp->ht; ++ struct minstrel_ht_sta *mi = inode->i_private; + struct minstrel_debugfs_info *ms; + unsigned int i; + char *p; +@@ -276,8 +279,7 @@ minstrel_ht_stats_csv_dump(struct minstr + static int + minstrel_ht_stats_csv_open(struct inode *inode, struct file *file) + { +- struct minstrel_ht_sta_priv *msp = inode->i_private; +- struct minstrel_ht_sta *mi = &msp->ht; ++ struct minstrel_ht_sta *mi = inode->i_private; + struct minstrel_debugfs_info *ms; + unsigned int i; + char *p; +@@ -313,10 +315,8 @@ static const struct file_operations mins + void + minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir) + { +- struct minstrel_ht_sta_priv *msp = priv_sta; +- +- debugfs_create_file("rc_stats", 0444, dir, msp, ++ debugfs_create_file("rc_stats", 0444, dir, priv_sta, + &minstrel_ht_stat_fops); +- debugfs_create_file("rc_stats_csv", 0444, dir, msp, ++ debugfs_create_file("rc_stats_csv", 0444, dir, priv_sta, + &minstrel_ht_stat_csv_fops); + } diff --git a/package/kernel/mac80211/patches/subsys/340-mac80211-minstrel_ht-remove-old-ewma-based-rate-aver.patch b/package/kernel/mac80211/patches/subsys/340-mac80211-minstrel_ht-remove-old-ewma-based-rate-aver.patch new file mode 100644 index 0000000000..9b6a614aa8 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/340-mac80211-minstrel_ht-remove-old-ewma-based-rate-aver.patch @@ -0,0 +1,96 @@ +From: Felix Fietkau +Date: Sat, 26 Dec 2020 14:34:30 +0100 +Subject: [PATCH] mac80211: minstrel_ht: remove old ewma based rate average + code + +The new noise filter has been the default for a while now with no reported +downside and significant improvement compared to the old code. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -769,17 +769,8 @@ minstrel_ht_calc_rate_stats(struct minst + if (unlikely(mrs->attempts > 0)) { + mrs->sample_skipped = 0; + cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); +- if (mp->new_avg) { +- minstrel_filter_avg_add(&mrs->prob_avg, +- &mrs->prob_avg_1, cur_prob); +- } else if (unlikely(!mrs->att_hist)) { +- mrs->prob_avg = cur_prob; +- } else { +- /*update exponential weighted moving avarage */ +- mrs->prob_avg = minstrel_ewma(mrs->prob_avg, +- cur_prob, +- EWMA_LEVEL); +- } ++ minstrel_filter_avg_add(&mrs->prob_avg, ++ &mrs->prob_avg_1, cur_prob); + mrs->att_hist += mrs->attempts; + mrs->succ_hist += mrs->success; + } else { +@@ -913,10 +904,8 @@ minstrel_ht_update_stats(struct minstrel + /* Try to increase robustness of max_prob_rate*/ + minstrel_ht_prob_rate_reduce_streams(mi); + +- /* try to sample all available rates during each interval */ +- mi->sample_count *= 8; +- if (mp->new_avg) +- mi->sample_count /= 2; ++ /* try to sample half of all available rates during each interval */ ++ mi->sample_count *= 4; + + if (sample) + minstrel_ht_rate_sample_switch(mp, mi); +@@ -1040,7 +1029,7 @@ minstrel_ht_tx_status(void *priv, struct + struct ieee80211_tx_rate *ar = info->status.rates; + struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL; + struct minstrel_priv *mp = priv; +- u32 update_interval = mp->update_interval / 2; ++ u32 update_interval = mp->update_interval; + bool last, update = false; + bool sample_status = false; + int i; +@@ -1090,9 +1079,8 @@ minstrel_ht_tx_status(void *priv, struct + + switch (mi->sample_mode) { + case MINSTREL_SAMPLE_IDLE: +- if (mp->new_avg && +- (mp->hw->max_rates > 1 || +- mi->total_packets_cur < SAMPLE_SWITCH_THR)) ++ if (mp->hw->max_rates > 1 || ++ mi->total_packets_cur < SAMPLE_SWITCH_THR) + update_interval /= 2; + break; + +@@ -1832,8 +1820,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h + mp->has_mrr = true; + + mp->hw = hw; +- mp->update_interval = HZ / 10; +- mp->new_avg = true; ++ mp->update_interval = HZ / 20; + + minstrel_ht_init_cck_rates(mp); + for (i = 0; i < ARRAY_SIZE(mp->hw->wiphy->bands); i++) +@@ -1853,8 +1840,6 @@ static void minstrel_ht_add_debugfs(stru + &mp->fixed_rate_idx); + debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir, + &mp->sample_switch); +- debugfs_create_bool("new_avg", S_IRUGO | S_IWUSR, debugfsdir, +- &mp->new_avg); + } + #endif + +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -60,7 +60,6 @@ + struct minstrel_priv { + struct ieee80211_hw *hw; + bool has_mrr; +- bool new_avg; + u32 sample_switch; + unsigned int cw_min; + unsigned int cw_max; diff --git a/package/kernel/mac80211/patches/subsys/341-mac80211-minstrel_ht-improve-ampdu-length-estimation.patch b/package/kernel/mac80211/patches/subsys/341-mac80211-minstrel_ht-improve-ampdu-length-estimation.patch new file mode 100644 index 0000000000..f450ca9ca9 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/341-mac80211-minstrel_ht-improve-ampdu-length-estimation.patch @@ -0,0 +1,67 @@ +From: Felix Fietkau +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 +--- + +--- 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; + +- return MINSTREL_TRUNC(mi->avg_ampdu_len); ++ 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]); ++ ++ 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) diff --git a/package/kernel/mac80211/patches/subsys/342-mac80211-minstrel_ht-improve-sample-rate-selection.patch b/package/kernel/mac80211/patches/subsys/342-mac80211-minstrel_ht-improve-sample-rate-selection.patch new file mode 100644 index 0000000000..e084525235 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/342-mac80211-minstrel_ht-improve-sample-rate-selection.patch @@ -0,0 +1,31 @@ +From: Felix Fietkau +Date: Sat, 26 Dec 2020 19:12:22 +0100 +Subject: [PATCH] mac80211: minstrel_ht: improve sample rate selection + +Always allow sampling of rates faster than the primary max throughput rate. +When the second max_tp_rate is higher than the first one, sample attempts were +previously skipped, potentially causing rate control to get stuck at a slightly +lower rate + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1379,13 +1379,13 @@ minstrel_get_sample_rate(struct minstrel + mrs = &mg->rates[sample_idx]; + sample_idx += sample_group * MCS_GROUP_RATES; + +- /* Set tp_rate1, tp_rate2 to the highest / second highest max_tp_rate */ ++ 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_rate1 = mi->max_tp_rate[1]; + tp_rate2 = mi->max_tp_rate[0]; + } else { +- tp_rate1 = mi->max_tp_rate[0]; + tp_rate2 = mi->max_tp_rate[1]; + } + diff --git a/package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch b/package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch new file mode 100644 index 0000000000..a0b918c9a1 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch @@ -0,0 +1,116 @@ +From: Felix Fietkau +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 +--- + +--- 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; +@@ -903,9 +913,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 +924,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); + diff --git a/package/kernel/mac80211/patches/subsys/344-mac80211-minstrel_ht-increase-stats-update-interval.patch b/package/kernel/mac80211/patches/subsys/344-mac80211-minstrel_ht-increase-stats-update-interval.patch new file mode 100644 index 0000000000..5c7785f892 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/344-mac80211-minstrel_ht-increase-stats-update-interval.patch @@ -0,0 +1,20 @@ +From: Felix Fietkau +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 +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1864,7 +1864,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++) From 9aeaea471ee6367cc91c07b338f5766ea601b1d5 Mon Sep 17 00:00:00 2001 From: Adrian Schmutzler Date: Sun, 3 Jan 2021 13:55:50 +0100 Subject: [PATCH 03/25] ath79: fix ethernet-phy label for dlink,dap-2660-a1 The phy label/node name should correspond to the reg property. While at it, use more common decimal notation for reg property itself. Signed-off-by: Adrian Schmutzler --- target/linux/ath79/dts/qca9557_dlink_dap-2660-a1.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/linux/ath79/dts/qca9557_dlink_dap-2660-a1.dts b/target/linux/ath79/dts/qca9557_dlink_dap-2660-a1.dts index 1a2974a688..8ef07e42e8 100644 --- a/target/linux/ath79/dts/qca9557_dlink_dap-2660-a1.dts +++ b/target/linux/ath79/dts/qca9557_dlink_dap-2660-a1.dts @@ -63,8 +63,8 @@ &mdio0 { status = "okay"; - phy0: ethernet-phy@4 { - reg = <0x4>; + phy4: ethernet-phy@4 { + reg = <4>; }; }; @@ -73,7 +73,7 @@ pll-data = <0x82000000 0x80000101 0x80001313>; - phy-handle = <&phy0>; + phy-handle = <&phy4>; phy-mode = "rgmii-id"; gmac-config { From aad3d9c710387fb1d9f2f75e6511fe5d6134aa45 Mon Sep 17 00:00:00 2001 From: Sungbo Eo Date: Sun, 3 Jan 2021 22:59:43 +0900 Subject: [PATCH 04/25] ipq40xx: remove unnecessary execute permission bit DTS files do not need to be executable. 644 is enough. Fixes: 0fbdb51f7643 ("ipq40xx: add Edgecore OAP-100 support") Signed-off-by: Sungbo Eo [split by targets] Signed-off-by: Adrian Schmutzler --- .../linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-oap100.dts | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-oap100.dts diff --git a/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-oap100.dts b/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-oap100.dts old mode 100755 new mode 100644 From 2eb336b79d88a506098e1f8cffaefc3696a7757d Mon Sep 17 00:00:00 2001 From: Sungbo Eo Date: Sun, 3 Jan 2021 22:59:43 +0900 Subject: [PATCH 05/25] mediatek: remove unnecessary execute permission bit Kernel config does not need to be executable. 644 is enough. Fixes: 25d9df670b85 ("mediatek: add v5.4 support") Signed-off-by: Sungbo Eo [split by targets] Signed-off-by: Adrian Schmutzler --- target/linux/mediatek/mt7622/config-5.4 | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 target/linux/mediatek/mt7622/config-5.4 diff --git a/target/linux/mediatek/mt7622/config-5.4 b/target/linux/mediatek/mt7622/config-5.4 old mode 100755 new mode 100644 From cbccc2560c0240c2c9528e82d745b7f45ce88bbd Mon Sep 17 00:00:00 2001 From: Sungbo Eo Date: Sun, 3 Jan 2021 23:34:31 +0900 Subject: [PATCH 06/25] ipq806x: consolidate DTS files directory Commit 29ca10e537ee ("ipq806x: remove support for kernel 4.19") moved DTS files to "files" directory, but after that a new DTS file was added to the former "files-5.4" directory. Move it to the new directory. Fixes: 98b86296e67d ("ipq806x: add support for ASRock G10") Signed-off-by: Sungbo Eo --- .../{files-5.4 => files}/arch/arm/boot/dts/qcom-ipq8064-g10.dts | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename target/linux/ipq806x/{files-5.4 => files}/arch/arm/boot/dts/qcom-ipq8064-g10.dts (100%) diff --git a/target/linux/ipq806x/files-5.4/arch/arm/boot/dts/qcom-ipq8064-g10.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-g10.dts similarity index 100% rename from target/linux/ipq806x/files-5.4/arch/arm/boot/dts/qcom-ipq8064-g10.dts rename to target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-g10.dts From 22e568d0fe5d44246874d3300e7e714f7594c320 Mon Sep 17 00:00:00 2001 From: Florian Beverborg Date: Sat, 7 Nov 2020 15:44:05 +0100 Subject: [PATCH 07/25] hostapd: add support for custom per-BSS options This adds an option "hostapd_bss_options" that does the same as "hostapd_options" but on a per-BSS level, instead of a per-device level. This can be used, for example, to configure different per-devce sae_passwords per BSS or to augment some of the existing per-BSS options. Signed-off-by: Florian Beverborg [remove whitespace errors, bump release] Signed-off-by: Paul Spooren --- package/network/services/hostapd/Makefile | 2 +- package/network/services/hostapd/files/hostapd.sh | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile index deb1d565bb..f746f5455a 100644 --- a/package/network/services/hostapd/Makefile +++ b/package/network/services/hostapd/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=hostapd -PKG_RELEASE:=20 +PKG_RELEASE:=21 PKG_SOURCE_URL:=http://w1.fi/hostap.git PKG_SOURCE_PROTO:=git diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh index fc78e2fb90..80e1f7cedf 100644 --- a/package/network/services/hostapd/files/hostapd.sh +++ b/package/network/services/hostapd/files/hostapd.sh @@ -330,6 +330,8 @@ hostapd_common_add_bss_config() { config_add_array airtime_sta_weight config_add_int airtime_bss_weight airtime_bss_limit + + config_add_array hostapd_bss_options } hostapd_set_vlan_file() { @@ -940,6 +942,11 @@ hostapd_set_bss_options() { json_for_each_item append_operator_icon operator_icon fi + json_get_values opts hostapd_bss_options + for val in $opts; do + append bss_conf "$val" "$N" + done + bss_md5sum=$(echo $bss_conf | md5sum | cut -d" " -f1) append bss_conf "config_id=$bss_md5sum" "$N" From 6cda95431984312d15032f6466b3b7238936185b Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Wed, 30 Dec 2020 18:35:30 -1000 Subject: [PATCH 08/25] usbreset: remove redundant package The package `usbutils` already offers an USB reset function, this package is therefore not really required standalone. CC: Jo-Philipp Wich Signed-off-by: Paul Spooren --- package/utils/usbreset/Makefile | 39 ----- package/utils/usbreset/src/usbreset.c | 236 -------------------------- 2 files changed, 275 deletions(-) delete mode 100644 package/utils/usbreset/Makefile delete mode 100644 package/utils/usbreset/src/usbreset.c diff --git a/package/utils/usbreset/Makefile b/package/utils/usbreset/Makefile deleted file mode 100644 index bf3160cb1a..0000000000 --- a/package/utils/usbreset/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright (C) 2011-2014 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=usbreset -PKG_RELEASE:=5 - -include $(INCLUDE_DIR)/package.mk - -define Package/usbreset - SECTION:=utils - CATEGORY:=Utilities - TITLE:=Utility to send a USB port reset to a USB device - MAINTAINER:=Jo-Philipp Wich -endef - -define Package/usbreset/description - This package contains the small usbreset utility which - can be used to send a USB port reset to a USB device - - useful for debugging or to force re-detection of particular - devices. -endef - -define Build/Compile - $(TARGET_CC) $(TARGET_CFLAGS) -Wall \ - -o $(PKG_BUILD_DIR)/usbreset $(PKG_BUILD_DIR)/usbreset.c -endef - -define Package/usbreset/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/usbreset $(1)/usr/bin/ -endef - -$(eval $(call BuildPackage,usbreset)) diff --git a/package/utils/usbreset/src/usbreset.c b/package/utils/usbreset/src/usbreset.c deleted file mode 100644 index dc2df3cb3b..0000000000 --- a/package/utils/usbreset/src/usbreset.c +++ /dev/null @@ -1,236 +0,0 @@ -/* usbreset -- send a USB port reset to a USB device */ - -/* - -http://marc.info/?l=linux-usb-users&m=116827193506484&w=2 - -and needs mounted usbfs filesystem - - sudo mount -t usbfs none /proc/bus/usb - -There is a way to suspend a USB device. In order to use it, -you must have a kernel with CONFIG_PM_SYSFS_DEPRECATED turned on. To -suspend a device, do (as root): - - echo -n 2 >/sys/bus/usb/devices/.../power/state - -where the "..." is the ID for your device. To unsuspend, do the same -thing but with a "0" instead of the "2" above. - -Note that this mechanism is slated to be removed from the kernel within -the next year. Hopefully some other mechanism will take its place. - -> To reset a -> device? - -Here's a program to do it. You invoke it as either - - usbreset /proc/bus/usb/BBB/DDD -or - usbreset /dev/usbB.D - -depending on how your system is set up, where BBB and DDD are the bus and -device address numbers. - -Alan Stern - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -static char *usbfs = NULL; - -struct usbentry { - int bus_num; - int dev_num; - int vendor_id; - int product_id; - char vendor_name[128]; - char product_name[128]; -}; - - -static char *sysfs_attr(const char *dev, const char *attr) -{ - int fd, len = 0; - char path[PATH_MAX]; - static char buf[129]; - - memset(buf, 0, sizeof(buf)); - snprintf(path, sizeof(path) - 1, "/sys/bus/usb/devices/%s/%s", dev, attr); - - if ((fd = open(path, O_RDONLY)) >= 0) - { - len = read(fd, buf, sizeof(buf) - 1); - close(fd); - } - - while (--len > 0 && isspace(buf[len])) - buf[len] = 0; - - return (len >= 0) ? buf : NULL; -} - -static struct usbentry * parse_devlist(DIR *d) -{ - char *attr; - struct dirent *e; - static struct usbentry dev; - - do { - e = readdir(d); - - if (!e) - return NULL; - } - while(!isdigit(e->d_name[0]) || strchr(e->d_name, ':')); - - memset(&dev, 0, sizeof(dev)); - - if ((attr = sysfs_attr(e->d_name, "busnum")) != NULL) - dev.bus_num = strtoul(attr, NULL, 10); - - if ((attr = sysfs_attr(e->d_name, "devnum")) != NULL) - dev.dev_num = strtoul(attr, NULL, 10); - - if ((attr = sysfs_attr(e->d_name, "idVendor")) != NULL) - dev.vendor_id = strtoul(attr, NULL, 16); - - if ((attr = sysfs_attr(e->d_name, "idProduct")) != NULL) - dev.product_id = strtoul(attr, NULL, 16); - - if ((attr = sysfs_attr(e->d_name, "manufacturer")) != NULL) - strcpy(dev.vendor_name, attr); - - if ((attr = sysfs_attr(e->d_name, "product")) != NULL) - strcpy(dev.product_name, attr); - - if (dev.bus_num && dev.dev_num && dev.vendor_id && dev.product_id) - return &dev; - - return NULL; -} - -static void list_devices(void) -{ - DIR *devs = opendir("/sys/bus/usb/devices"); - struct usbentry *dev; - - if (!devs) - return; - - while ((dev = parse_devlist(devs)) != NULL) - { - printf(" Number %03d/%03d ID %04x:%04x %s\n", - dev->bus_num, dev->dev_num, - dev->vendor_id, dev->product_id, - dev->product_name); - } - - closedir(devs); -} - -struct usbentry * find_device(int *bus, int *dev, - int *vid, int *pid, - const char *product) -{ - DIR *devs = opendir("/sys/bus/usb/devices"); - - struct usbentry *e, *match = NULL; - - if (!devs) - return NULL; - - while ((e = parse_devlist(devs)) != NULL) - { - if ((bus && (e->bus_num == *bus) && (e->dev_num == *dev)) || - (vid && (e->vendor_id == *vid) && (e->product_id == *pid)) || - (product && !strcasecmp(e->product_name, product))) - { - match = e; - break; - } - } - - closedir(devs); - - return match; -} - -static void reset_device(struct usbentry *dev) -{ - int fd; - char path[PATH_MAX]; - - snprintf(path, sizeof(path) - 1, "/dev/bus/usb/%03d/%03d", - dev->bus_num, dev->dev_num); - - printf("Resetting %s ... ", dev->product_name); - - if ((fd = open(path, O_WRONLY)) > -1) - { - if (ioctl(fd, USBDEVFS_RESET, 0) < 0) - printf("failed [%s]\n", strerror(errno)); - else - printf("ok\n"); - - close(fd); - } - else - { - printf("can't open [%s]\n", strerror(errno)); - } -} - - -int main(int argc, char **argv) -{ - int id1, id2; - struct usbentry *dev; - - if ((argc == 2) && (sscanf(argv[1], "%3d/%3d", &id1, &id2) == 2)) - { - dev = find_device(&id1, &id2, NULL, NULL, NULL); - } - else if ((argc == 2) && (sscanf(argv[1], "%4x:%4x", &id1, &id2) == 2)) - { - dev = find_device(NULL, NULL, &id1, &id2, NULL); - } - else if ((argc == 2) && strlen(argv[1]) < 128) - { - dev = find_device(NULL, NULL, NULL, NULL, argv[1]); - } - else - { - printf("Usage:\n" - " usbreset PPPP:VVVV - reset by product and vendor id\n" - " usbreset BBB/DDD - reset by bus and device number\n" - " usbreset \"Product\" - reset by product name\n\n" - "Devices:\n"); - list_devices(); - return 1; - } - - if (!dev) - { - fprintf(stderr, "No such device found\n"); - return 1; - } - - reset_device(dev); - return 0; -} From 7937c1f7d7f21309f54ba74de744b7b7db5ce9e8 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Tue, 29 Dec 2020 19:35:11 -0800 Subject: [PATCH 09/25] usbutils: remove This package is not needed in base. It will be imported in the packages feed. Signed-off-by: Rosen Penev Acked-by: Paul Spooren --- package/utils/usbutils/Makefile | 60 --------------------------------- 1 file changed, 60 deletions(-) delete mode 100644 package/utils/usbutils/Makefile diff --git a/package/utils/usbutils/Makefile b/package/utils/usbutils/Makefile deleted file mode 100644 index 4e32e27a06..0000000000 --- a/package/utils/usbutils/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright (C) 2007-2016 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=usbutils -PKG_VERSION:=007 -PKG_RELEASE:=11 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz -PKG_SOURCE_URL:=@KERNEL/linux/utils/usb/usbutils -PKG_HASH:=7593a01724bbc0fd9fe48e62bc721ceb61c76654f1d7b231b3c65f6dfbbaefa4 -PKG_LICENSE:=GPL-2.0 -PKG_LICENSE_FILES:=COPYING - -PKG_BUILD_PARALLEL:=1 -PKG_INSTALL:=1 - -PKG_MAINTAINER:=Felix Fietkau - -include $(INCLUDE_DIR)/package.mk - -define Package/usbutils - SECTION:=utils - CATEGORY:=Utilities - DEPENDS:=+libusb-1.0 +librt +libpthread - TITLE:=USB devices listing utilities - URL:=http://www.linux-usb.org/ -endef - -USB_IDS_VER:=0.339 -USB_IDS_FILE:=usb.ids.$(USB_IDS_VER) -define Download/usb_ids - FILE:=$(USB_IDS_FILE) - URL_FILE:=usb.ids - URL:=@GITHUB/vcrhonek/hwdata/v$(USB_IDS_VER) - HASH:=5ab6b663d3119217aa4117e95063c9b82646107344f2ae1d22248c6c29389fd7 -endef -$(eval $(call Download,usb_ids)) - -define Build/Prepare - $(Build/Prepare/Default) - $(CP) $(DL_DIR)/$(USB_IDS_FILE) $(PKG_BUILD_DIR)/usb.ids -endef - -CONFIGURE_ARGS += \ - --disable-zlib - -define Package/usbutils/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/lsusb $(1)/usr/bin/ - $(INSTALL_DIR) $(1)/usr/share - $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/usb.ids $(1)/usr/share/ -endef - -$(eval $(call BuildPackage,usbutils)) From 927b9df938803d409d6b3a47d6834a6c10f68c3d Mon Sep 17 00:00:00 2001 From: Kagurazaka Kotori Date: Tue, 8 Sep 2020 16:00:02 +0800 Subject: [PATCH 10/25] x86/efi: add FAT32 esp mounting support Adds a new function get_magic_fat32() in base-files to read FAT32 magic. Now FAT32 EFI system partition can be handled in the same way as FAT12/FAT16. Signed-off-by: Kagurazaka Kotori [replace '-o' with '] || [' to satisfy shellsheck] Signed-off-by: Paul Spooren --- package/base-files/files/lib/upgrade/common.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh index b44a5998f4..e8a28f4138 100644 --- a/package/base-files/files/lib/upgrade/common.sh +++ b/package/base-files/files/lib/upgrade/common.sh @@ -133,6 +133,10 @@ get_magic_vfat() { (get_image "$@" | dd bs=1 count=3 skip=54) 2>/dev/null } +get_magic_fat32() { + (get_image "$@" | dd bs=1 count=5 skip=82) 2>/dev/null +} + part_magic_efi() { local magic=$(get_magic_gpt "$@") [ "$magic" = "EFI PART" ] @@ -140,7 +144,8 @@ part_magic_efi() { part_magic_fat() { local magic=$(get_magic_vfat "$@") - [ "$magic" = "FAT" ] + local magic_fat32=$(get_magic_fat32 "$@") + [ "$magic" = "FAT" ] || [ "$magic_fat32" = "FAT32" ] } export_bootdevice() { From b077accb9c79f215d4da5f44474e72aec07e16dc Mon Sep 17 00:00:00 2001 From: Sebastian Schaper Date: Wed, 17 Jun 2020 00:11:37 +0200 Subject: [PATCH 11/25] ath79: add support for D-Link DAP-2230 A1 Specifications: * QCA9533, 16 MiB Flash, 64 MiB RAM, 802.11n 2T2R * 10/100 Ethernet Port, 802.11af PoE Installation: * Factory Web UI is at 192.168.0.50 login with 'admin' and blank password, flash factory.bin * Recovery Web UI is at 192.168.0.50 connect network cable, hold reset button during power-on and keep it pressed until uploading has started (only required when checksum is ok, e.g. for reverting back to oem firmware), flash factory.bin After flashing factory.bin, additional free space can be reclaimed by flashing sysupgrade.bin, since the factory image requires some padding to be accepted for upgrading via OEM Web UI. Signed-off-by: Sebastian Schaper --- .../ath79/dts/qca9533_dlink_dap-2230-a1.dts | 56 +++++++++++++++++++ .../generic/base-files/etc/board.d/02_network | 2 + .../etc/hotplug.d/ieee80211/10_fix_wifi_mac | 3 + .../etc/uci-defaults/09_fix-checksum | 1 + target/linux/ath79/image/generic.mk | 11 ++++ 5 files changed, 73 insertions(+) create mode 100644 target/linux/ath79/dts/qca9533_dlink_dap-2230-a1.dts diff --git a/target/linux/ath79/dts/qca9533_dlink_dap-2230-a1.dts b/target/linux/ath79/dts/qca9533_dlink_dap-2230-a1.dts new file mode 100644 index 0000000000..61b6453842 --- /dev/null +++ b/target/linux/ath79/dts/qca9533_dlink_dap-2230-a1.dts @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca953x.dtsi" +#include "qca95xx_dlink_dap-2xxx.dtsi" + +/ { + compatible = "dlink,dap-2230-a1", "qca,qca9533"; + model = "D-Link DAP-2230 A1"; + + aliases { + led-boot = &led_power_green; + led-failsafe = &led_power_green; + led-running = &led_power_green; + led-upgrade = &led_power_green; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&gpio 17 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_power_green: power_green { + label = "green:power"; + gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + }; +}; + +&partitions { + partition@70000 { + label = "firmware"; + reg = <0x70000 0xee0000>; + compatible = "wrg"; + }; + + partition@f50000 { + label = "dlink"; + reg = <0xf50000 0xa0000>; + read-only; + }; + + art: partition@ff0000 { + label = "art"; + reg = <0xff0000 0x10000>; + read-only; + }; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index f78fdeea9c..86c9a0b8d6 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -27,6 +27,7 @@ ath79_setup_interfaces() devolo,dvl1750x|\ dlink,dap-1330-a1|\ dlink,dap-1365-a1|\ + dlink,dap-2230-a1|\ dlink,dir-505|\ engenius,eap300-v2|\ engenius,eap350-v1|\ @@ -481,6 +482,7 @@ ath79_setup_macs() lan_mac=$(mtd_get_mac_text "mp" 0x1) label_mac=$lan_mac ;; + dlink,dap-2230-a1|\ dlink,dap-2660-a1) lan_mac=$(mtd_get_mac_ascii bdcfg "lanmac") label_mac=$lan_mac diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac index f382e255f1..c3dc2a8b5b 100644 --- a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac +++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac @@ -22,6 +22,9 @@ case "$board" in dlink,dch-g020-a1) mtd_get_mac_text "mp" 0x13 > /sys${DEVPATH}/macaddress ;; + dlink,dap-2230-a1) + mtd_get_mac_ascii bdcfg "wlanmac" > /sys${DEVPATH}/macaddress + ;; dlink,dap-2660-a1) [ "$PHYNBR" -eq 1 ] && \ mtd_get_mac_ascii bdcfg "wlanmac" > /sys${DEVPATH}/macaddress diff --git a/target/linux/ath79/generic/base-files/etc/uci-defaults/09_fix-checksum b/target/linux/ath79/generic/base-files/etc/uci-defaults/09_fix-checksum index 9a2cca79a1..9b98213022 100644 --- a/target/linux/ath79/generic/base-files/etc/uci-defaults/09_fix-checksum +++ b/target/linux/ath79/generic/base-files/etc/uci-defaults/09_fix-checksum @@ -13,6 +13,7 @@ fixwrgg() { board=$(board_name) case "$board" in +dlink,dap-2230-a1|\ dlink,dap-2660-a1|\ dlink,dap-2695-a1) fixwrgg diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index ded8e29c2c..080c6a1603 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -749,6 +749,17 @@ define Device/dlink_dap-2xxx KERNEL_INITRAMFS := $$(KERNEL) | mkwrggimg endef +define Device/dlink_dap-2230-a1 + $(Device/dlink_dap-2xxx) + SOC := qca9533 + DEVICE_VENDOR := D-Link + DEVICE_MODEL := DAP-2230 + DEVICE_VARIANT := A1 + IMAGE_SIZE := 15232k + DAP_SIGNATURE := wapn31_dkbs_dap2230 +endef +TARGET_DEVICES += dlink_dap-2230-a1 + define Device/dlink_dap-2660-a1 $(Device/dlink_dap-2xxx) SOC := qca9557 From 5b58710fad2137eedad874f0fe8fe22082d1edc6 Mon Sep 17 00:00:00 2001 From: Sebastian Schaper Date: Wed, 2 Dec 2020 21:31:19 +0100 Subject: [PATCH 12/25] ath79: add support for D-Link DAP-2680 A1 Specifications: * QCA9558, 16 MiB Flash, 256 MiB RAM, 802.11n 3T3R * QCA9984, 802.11ac Wave 2 3T3R * Gigabit LAN Port (AR8035), 802.11at PoE Installation: * Factory Web UI is at 192.168.0.50 login with 'admin' and blank password, flash factory.bin * Recovery Web UI is at 192.168.0.50 connect network cable, hold reset button during power-on and keep it pressed until uploading has started (only required when checksum is ok, e.g. for reverting back to oem firmware), flash factory.bin After flashing factory.bin, additional free space can be reclaimed by flashing sysupgrade.bin, since the factory image requires some padding to be accepted for upgrading via OEM Web UI. Signed-off-by: Sebastian Schaper --- .../ath79/dts/qca9558_dlink_dap-2680-a1.dts | 89 +++++++++++++++++++ .../generic/base-files/etc/board.d/02_network | 4 +- .../etc/hotplug.d/firmware/11-ath10k-caldata | 6 ++ .../etc/hotplug.d/ieee80211/10_fix_wifi_mac | 3 +- .../etc/uci-defaults/09_fix-checksum | 1 + target/linux/ath79/image/generic.mk | 12 +++ 6 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 target/linux/ath79/dts/qca9558_dlink_dap-2680-a1.dts diff --git a/target/linux/ath79/dts/qca9558_dlink_dap-2680-a1.dts b/target/linux/ath79/dts/qca9558_dlink_dap-2680-a1.dts new file mode 100644 index 0000000000..c3c82937a8 --- /dev/null +++ b/target/linux/ath79/dts/qca9558_dlink_dap-2680-a1.dts @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca955x.dtsi" +#include "qca95xx_dlink_dap-2xxx.dtsi" + +/ { + compatible = "dlink,dap-2680-a1", "qca,qca9558"; + model = "D-Link DAP-2680 A1"; + + aliases { + led-boot = &led_power_green; + led-failsafe = &led_power_red; + led-running = &led_power_green; + led-upgrade = &led_power_red; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_power_red: power_red { + label = "red:power"; + gpios = <&gpio 20 GPIO_ACTIVE_LOW>; + }; + + led_power_green: power_green { + label = "green:power"; + gpios = <&gpio 19 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + }; +}; + +&partitions { + partition@70000 { + label = "firmware"; + reg = <0x70000 0xee0000>; + compatible = "wrg"; + }; + + partition@f50000 { + label = "dlink"; + reg = <0xf50000 0xa0000>; + read-only; + }; + + art: partition@ff0000 { + label = "art"; + reg = <0xff0000 0x10000>; + read-only; + }; +}; + +&mdio0 { + status = "okay"; + + phy4: ethernet-phy@4 { + reg = <4>; + }; +}; + +ð0 { + status = "okay"; + + pll-data = <0x82000000 0x80000101 0x80001313>; + + phy-handle = <&phy4>; + phy-mode = "rgmii-id"; + + gmac-config { + device = <&gmac>; + rgmii-enabled = <1>; + rxd-delay = <3>; + rxdv-delay = <3>; + }; +}; + +&pcie0 { + status = "okay"; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index 86c9a0b8d6..23b824d7e3 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -28,6 +28,7 @@ ath79_setup_interfaces() dlink,dap-1330-a1|\ dlink,dap-1365-a1|\ dlink,dap-2230-a1|\ + dlink,dap-2680-a1|\ dlink,dir-505|\ engenius,eap300-v2|\ engenius,eap350-v1|\ @@ -483,7 +484,8 @@ ath79_setup_macs() label_mac=$lan_mac ;; dlink,dap-2230-a1|\ - dlink,dap-2660-a1) + dlink,dap-2660-a1|\ + dlink,dap-2680-a1) lan_mac=$(mtd_get_mac_ascii bdcfg "lanmac") label_mac=$lan_mac ;; diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/11-ath10k-caldata index 3ab01afcf3..295bc1b180 100644 --- a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/11-ath10k-caldata +++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/11-ath10k-caldata @@ -174,6 +174,12 @@ case "$FIRMWARE" in /lib/firmware/ath10k/QCA9888/hw2.0/board.bin rm /lib/firmware/ath10k/QCA9888/hw2.0/board-2.bin ;; + dlink,dap-2680-a1) + caldata_extract "art" 0x5000 0x2f20 + ath10k_patch_mac $(mtd_get_mac_ascii bdcfg wlanmac_a) + ln -sf /lib/firmware/ath10k/pre-cal-pci-0000\:00\:00.0.bin \ + /lib/firmware/ath10k/QCA9888/hw2.0/board.bin + ;; dlink,dir-842-c1|\ dlink,dir-842-c2|\ dlink,dir-842-c3) diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac index c3dc2a8b5b..8923a2cb11 100644 --- a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac +++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac @@ -25,7 +25,8 @@ case "$board" in dlink,dap-2230-a1) mtd_get_mac_ascii bdcfg "wlanmac" > /sys${DEVPATH}/macaddress ;; - dlink,dap-2660-a1) + dlink,dap-2660-a1|\ + dlink,dap-2680-a1) [ "$PHYNBR" -eq 1 ] && \ mtd_get_mac_ascii bdcfg "wlanmac" > /sys${DEVPATH}/macaddress ;; diff --git a/target/linux/ath79/generic/base-files/etc/uci-defaults/09_fix-checksum b/target/linux/ath79/generic/base-files/etc/uci-defaults/09_fix-checksum index 9b98213022..0bbe321788 100644 --- a/target/linux/ath79/generic/base-files/etc/uci-defaults/09_fix-checksum +++ b/target/linux/ath79/generic/base-files/etc/uci-defaults/09_fix-checksum @@ -15,6 +15,7 @@ board=$(board_name) case "$board" in dlink,dap-2230-a1|\ dlink,dap-2660-a1|\ +dlink,dap-2680-a1|\ dlink,dap-2695-a1) fixwrgg ;; diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index 080c6a1603..26ab0fcb34 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -772,6 +772,18 @@ define Device/dlink_dap-2660-a1 endef TARGET_DEVICES += dlink_dap-2660-a1 +define Device/dlink_dap-2680-a1 + $(Device/dlink_dap-2xxx) + SOC := qca9558 + DEVICE_VENDOR := D-Link + DEVICE_MODEL := DAP-2680 + DEVICE_VARIANT := A1 + DEVICE_PACKAGES := ath10k-firmware-qca99x0-ct kmod-ath10k-ct + IMAGE_SIZE := 15232k + DAP_SIGNATURE := wapac36_dkbs_dap2680 +endef +TARGET_DEVICES += dlink_dap-2680-a1 + define Device/dlink_dap-2695-a1 SOC := qca9558 DEVICE_PACKAGES := ath10k-firmware-qca988x-ct kmod-ath10k-ct From 8ae2ee99c60382f9f5130009397fd36e40900447 Mon Sep 17 00:00:00 2001 From: Sebastian Schaper Date: Mon, 30 Nov 2020 20:09:29 +0100 Subject: [PATCH 13/25] ath79: add support for D-Link DAP-3320 A1 Specifications: * QCA9533, 16 MiB Flash, 64 MiB RAM, 802.11n 2T2R * 10/100 Ethernet Port, 802.11af PoE * IP55 pole-mountable outdoor case Installation: * Factory Web UI is at 192.168.0.50 login with 'admin' and blank password, flash factory.bin * Recovery Web UI is at 192.168.0.50 connect network cable, hold reset button during power-on and keep it pressed until uploading has started (only required when checksum is ok, e.g. for reverting back to oem firmware), flash factory.bin After flashing factory.bin, additional free space can be reclaimed by flashing sysupgrade.bin, since the factory image requires some padding to be accepted for upgrading via OEM Web UI. Signed-off-by: Sebastian Schaper --- .../ath79/dts/qca9533_dlink_dap-3320-a1.dts | 56 +++++++++++++++++++ .../generic/base-files/etc/board.d/02_network | 4 +- .../etc/hotplug.d/ieee80211/10_fix_wifi_mac | 3 +- .../etc/uci-defaults/09_fix-checksum | 3 +- target/linux/ath79/image/generic.mk | 11 ++++ 5 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 target/linux/ath79/dts/qca9533_dlink_dap-3320-a1.dts diff --git a/target/linux/ath79/dts/qca9533_dlink_dap-3320-a1.dts b/target/linux/ath79/dts/qca9533_dlink_dap-3320-a1.dts new file mode 100644 index 0000000000..97f2f62b4a --- /dev/null +++ b/target/linux/ath79/dts/qca9533_dlink_dap-3320-a1.dts @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca953x.dtsi" +#include "qca95xx_dlink_dap-2xxx.dtsi" + +/ { + compatible = "dlink,dap-3320-a1", "qca,qca9533"; + model = "D-Link DAP-3320 A1"; + + aliases { + led-boot = &led_power_green; + led-failsafe = &led_power_green; + led-running = &led_power_green; + led-upgrade = &led_power_green; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&gpio 12 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_power_green: power_green { + label = "green:power"; + gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + }; +}; + +&partitions { + partition@70000 { + label = "firmware"; + reg = <0x70000 0xef0000>; + compatible = "wrg"; + }; + + partition@f60000 { + label = "dlink"; + reg = <0xf60000 0x90000>; + read-only; + }; + + art: partition@ff0000 { + label = "art"; + reg = <0xff0000 0x10000>; + read-only; + }; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index 23b824d7e3..20cf561add 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -29,6 +29,7 @@ ath79_setup_interfaces() dlink,dap-1365-a1|\ dlink,dap-2230-a1|\ dlink,dap-2680-a1|\ + dlink,dap-3320-a1|\ dlink,dir-505|\ engenius,eap300-v2|\ engenius,eap350-v1|\ @@ -485,7 +486,8 @@ ath79_setup_macs() ;; dlink,dap-2230-a1|\ dlink,dap-2660-a1|\ - dlink,dap-2680-a1) + dlink,dap-2680-a1|\ + dlink,dap-3320-a1) lan_mac=$(mtd_get_mac_ascii bdcfg "lanmac") label_mac=$lan_mac ;; diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac index 8923a2cb11..5edc2e4a86 100644 --- a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac +++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac @@ -22,7 +22,8 @@ case "$board" in dlink,dch-g020-a1) mtd_get_mac_text "mp" 0x13 > /sys${DEVPATH}/macaddress ;; - dlink,dap-2230-a1) + dlink,dap-2230-a1|\ + dlink,dap-3320-a1) mtd_get_mac_ascii bdcfg "wlanmac" > /sys${DEVPATH}/macaddress ;; dlink,dap-2660-a1|\ diff --git a/target/linux/ath79/generic/base-files/etc/uci-defaults/09_fix-checksum b/target/linux/ath79/generic/base-files/etc/uci-defaults/09_fix-checksum index 0bbe321788..b522563f17 100644 --- a/target/linux/ath79/generic/base-files/etc/uci-defaults/09_fix-checksum +++ b/target/linux/ath79/generic/base-files/etc/uci-defaults/09_fix-checksum @@ -16,7 +16,8 @@ case "$board" in dlink,dap-2230-a1|\ dlink,dap-2660-a1|\ dlink,dap-2680-a1|\ -dlink,dap-2695-a1) +dlink,dap-2695-a1|\ +dlink,dap-3320-a1) fixwrgg ;; qihoo,c301) diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index 26ab0fcb34..190f477b7e 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -804,6 +804,17 @@ define Device/dlink_dap-2695-a1 endef TARGET_DEVICES += dlink_dap-2695-a1 +define Device/dlink_dap-3320-a1 + $(Device/dlink_dap-2xxx) + SOC := qca9533 + DEVICE_VENDOR := D-Link + DEVICE_MODEL := DAP-3320 + DEVICE_VARIANT := A1 + IMAGE_SIZE := 15296k + DAP_SIGNATURE := wapn29_dkbs_dap3320 +endef +TARGET_DEVICES += dlink_dap-3320-a1 + define Device/dlink_dch-g020-a1 SOC := qca9531 DEVICE_VENDOR := D-Link From d7d87cedcf93cbd64b0edb4712669bfaaec03c1d Mon Sep 17 00:00:00 2001 From: Sebastian Schaper Date: Sun, 3 Jan 2021 21:39:10 +0100 Subject: [PATCH 14/25] ath79: Fix 02_network setup for D-Link DAP-2660 A1 The device is a one-port, but was set up as two-port by the default case in 02_network. Fix it. Signed-off-by: Sebastian Schaper [commit title/message facelift] Signed-off-by: Adrian Schmutzler --- target/linux/ath79/generic/base-files/etc/board.d/02_network | 1 + 1 file changed, 1 insertion(+) diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index 20cf561add..c79286d45d 100755 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -28,6 +28,7 @@ ath79_setup_interfaces() dlink,dap-1330-a1|\ dlink,dap-1365-a1|\ dlink,dap-2230-a1|\ + dlink,dap-2660-a1|\ dlink,dap-2680-a1|\ dlink,dap-3320-a1|\ dlink,dir-505|\ From acdf07cd3eb3d4aff09e0908c492859127524ab5 Mon Sep 17 00:00:00 2001 From: Adrian Schmutzler Date: Mon, 4 Jan 2021 00:56:57 +0100 Subject: [PATCH 15/25] ath79: keep DTSI files for D-Link SoC-specific It is good practice to define device tree files based on specific SoCs. Thus, let's not start to create files that are used across different architectures. Duplicate the DTSI file for D-Link DAP-2xxx in order to have one for qca953x and one for qca955x, respectively. Signed-off-by: Adrian Schmutzler --- .../ath79/dts/qca9533_dlink_dap-2230-a1.dts | 3 +- .../ath79/dts/qca9533_dlink_dap-3320-a1.dts | 3 +- ...-2xxx.dtsi => qca953x_dlink_dap-2xxx.dtsi} | 2 + .../ath79/dts/qca9557_dlink_dap-2660-a1.dts | 3 +- .../ath79/dts/qca9558_dlink_dap-2680-a1.dts | 3 +- .../ath79/dts/qca955x_dlink_dap-2xxx.dtsi | 56 +++++++++++++++++++ 6 files changed, 62 insertions(+), 8 deletions(-) rename target/linux/ath79/dts/{qca95xx_dlink_dap-2xxx.dtsi => qca953x_dlink_dap-2xxx.dtsi} (97%) create mode 100644 target/linux/ath79/dts/qca955x_dlink_dap-2xxx.dtsi diff --git a/target/linux/ath79/dts/qca9533_dlink_dap-2230-a1.dts b/target/linux/ath79/dts/qca9533_dlink_dap-2230-a1.dts index 61b6453842..3717a35ae3 100644 --- a/target/linux/ath79/dts/qca9533_dlink_dap-2230-a1.dts +++ b/target/linux/ath79/dts/qca9533_dlink_dap-2230-a1.dts @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT -#include "qca953x.dtsi" -#include "qca95xx_dlink_dap-2xxx.dtsi" +#include "qca953x_dlink_dap-2xxx.dtsi" / { compatible = "dlink,dap-2230-a1", "qca,qca9533"; diff --git a/target/linux/ath79/dts/qca9533_dlink_dap-3320-a1.dts b/target/linux/ath79/dts/qca9533_dlink_dap-3320-a1.dts index 97f2f62b4a..c186a7ee44 100644 --- a/target/linux/ath79/dts/qca9533_dlink_dap-3320-a1.dts +++ b/target/linux/ath79/dts/qca9533_dlink_dap-3320-a1.dts @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT -#include "qca953x.dtsi" -#include "qca95xx_dlink_dap-2xxx.dtsi" +#include "qca953x_dlink_dap-2xxx.dtsi" / { compatible = "dlink,dap-3320-a1", "qca,qca9533"; diff --git a/target/linux/ath79/dts/qca95xx_dlink_dap-2xxx.dtsi b/target/linux/ath79/dts/qca953x_dlink_dap-2xxx.dtsi similarity index 97% rename from target/linux/ath79/dts/qca95xx_dlink_dap-2xxx.dtsi rename to target/linux/ath79/dts/qca953x_dlink_dap-2xxx.dtsi index 82d50b85e8..aff6eb2871 100644 --- a/target/linux/ath79/dts/qca95xx_dlink_dap-2xxx.dtsi +++ b/target/linux/ath79/dts/qca953x_dlink_dap-2xxx.dtsi @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT +#include "qca953x.dtsi" + #include #include diff --git a/target/linux/ath79/dts/qca9557_dlink_dap-2660-a1.dts b/target/linux/ath79/dts/qca9557_dlink_dap-2660-a1.dts index 8ef07e42e8..622f4410b3 100644 --- a/target/linux/ath79/dts/qca9557_dlink_dap-2660-a1.dts +++ b/target/linux/ath79/dts/qca9557_dlink_dap-2660-a1.dts @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT -#include "qca955x.dtsi" -#include "qca95xx_dlink_dap-2xxx.dtsi" +#include "qca955x_dlink_dap-2xxx.dtsi" / { compatible = "dlink,dap-2660-a1", "qca,qca9557"; diff --git a/target/linux/ath79/dts/qca9558_dlink_dap-2680-a1.dts b/target/linux/ath79/dts/qca9558_dlink_dap-2680-a1.dts index c3c82937a8..7549c0a697 100644 --- a/target/linux/ath79/dts/qca9558_dlink_dap-2680-a1.dts +++ b/target/linux/ath79/dts/qca9558_dlink_dap-2680-a1.dts @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT -#include "qca955x.dtsi" -#include "qca95xx_dlink_dap-2xxx.dtsi" +#include "qca955x_dlink_dap-2xxx.dtsi" / { compatible = "dlink,dap-2680-a1", "qca,qca9558"; diff --git a/target/linux/ath79/dts/qca955x_dlink_dap-2xxx.dtsi b/target/linux/ath79/dts/qca955x_dlink_dap-2xxx.dtsi new file mode 100644 index 0000000000..ac7a0c85f0 --- /dev/null +++ b/target/linux/ath79/dts/qca955x_dlink_dap-2xxx.dtsi @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca955x.dtsi" + +#include +#include + +&spi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + + partitions: partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x40000>; + read-only; + }; + + partition@40000 { + label = "bdcfg"; + reg = <0x40000 0x10000>; + read-only; + }; + + partition@50000 { + label = "rgdb"; + reg = <0x50000 0x10000>; + read-only; + }; + + partition@60000 { + label = "unused"; + reg = <0x60000 0x10000>; + read-only; + }; + }; + }; +}; + +&uart { + status = "okay"; +}; + +&wmac { + status = "okay"; + + mtd-cal-data = <&art 0x1000>; +}; From 6773bee10753ae181257b544371101646822e80e Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Sun, 3 Jan 2021 22:26:05 +0100 Subject: [PATCH 16/25] odhcpd: bump to latest version 3bda900 odhcpd: add option for setting preferred lifetime Signed-off-by: Nick Hainke --- package/network/services/odhcpd/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/network/services/odhcpd/Makefile b/package/network/services/odhcpd/Makefile index 66263ba51d..584029e6fe 100644 --- a/package/network/services/odhcpd/Makefile +++ b/package/network/services/odhcpd/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/odhcpd.git -PKG_SOURCE_DATE:=2020-12-24 -PKG_SOURCE_VERSION:=b75bcad7bd5fd03f64011a532b9960d78e4aac22 -PKG_MIRROR_HASH:=f795e0268b6fe09eaf15b5701a236c3a74c11deb8436af6b6ab0a59d251fc3fd +PKG_SOURCE_DATE:=2021-01-03 +PKG_SOURCE_VERSION:=3bda90079ec5574ef469e2a7804808302f17769d +PKG_MIRROR_HASH:=61ce5cb49e911f7a279d4825002858a39e3f6dc0e22670c240d1992741f7b56f PKG_MAINTAINER:=Hans Dedecker PKG_LICENSE:=GPL-2.0 From c7aec47e5e3a3ff7b5fdaa11cd1e62cae6746acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0tetiar?= Date: Tue, 22 Dec 2020 10:33:02 +0100 Subject: [PATCH 17/25] build: replace which with Bash command built-in MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `which` utility is not shipped by default for example on recent Arch Linux and then any steps relying on its presence fails, like for example following Python3 prereq build check: $ python3 --version Python 3.9.1 $ make /bin/sh: line 1: which: command not found /bin/sh: line 1: which: command not found /bin/sh: line 1: which: command not found ... Checking 'python3'... failed. ... Fix this by switching to Bash builtin `command` which should provide same functionality. Fixes: FS#3525 Signed-off-by: Petr Štetiar --- Makefile | 2 +- include/cmake.mk | 2 +- include/prereq.mk | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 4ccbc20b85..f1577ad4d1 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ $(if $(findstring $(space),$(TOPDIR)),$(error ERROR: The path to the OpenWrt dir world: -DISTRO_PKG_CONFIG:=$(shell which -a pkg-config | grep -E '\/usr' | head -n 1) +DISTRO_PKG_CONFIG:=$(shell command -pv pkg-config | grep -E '\/usr' | head -n 1) export PATH:=$(TOPDIR)/staging_dir/host/bin:$(PATH) ifneq ($(OPENWRT_BUILD),1) diff --git a/include/cmake.mk b/include/cmake.mk index 96c4d7df34..de8022ca57 100644 --- a/include/cmake.mk +++ b/include/cmake.mk @@ -15,7 +15,7 @@ MAKE_PATH = $(firstword $(CMAKE_BINARY_SUBDIR) .) ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),) cmake_tool=$(TOOLCHAIN_DIR)/bin/$(1) else - cmake_tool=$(shell which $(1)) + cmake_tool=$(shell command -v $(1)) endif ifeq ($(CONFIG_CCACHE),) diff --git a/include/prereq.mk b/include/prereq.mk index 83ac21242c..6d14140792 100644 --- a/include/prereq.mk +++ b/include/prereq.mk @@ -52,7 +52,7 @@ endef define RequireCommand define Require/$(1) - which $(1) + command -pv $(1) endef $$(eval $$(call Require,$(1),$(2))) @@ -106,7 +106,7 @@ define SetupHostCommand $(call QuoteHostCommand,$(11)) $(call QuoteHostCommand,$(12)); do \ if [ -n "$$$$$$$$cmd" ]; then \ bin="$$$$$$$$(PATH="$(subst $(space),:,$(filter-out $(STAGING_DIR_HOST)/%,$(subst :,$(space),$(PATH))))" \ - which "$$$$$$$${cmd%% *}")"; \ + command -pv "$$$$$$$${cmd%% *}")"; \ if [ -x "$$$$$$$$bin" ] && eval "$$$$$$$$cmd" >/dev/null 2>/dev/null; then \ mkdir -p "$(STAGING_DIR_HOST)/bin"; \ ln -sf "$$$$$$$$bin" "$(STAGING_DIR_HOST)/bin/$(strip $(1))"; \ From 498fb1b8aa5f314206af78ca0e6d118f9f51c937 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Mon, 4 Jan 2021 21:01:05 +0000 Subject: [PATCH 18/25] fstools: fix 'firstboot' on unmounted UBIFS overlay The usual OpenWrt-way of writing the JFFS2-marker in order to have a filesystem erased at the next boot fails on UBIFS volumes due to UBI being a different beast when it comes to writing. As truncating a UBIFS volume only takes a few milliseconds and has the desired effect of wiping-out all content of that volume, just do that instead. Signed-off-by: Daniel Golle --- package/system/fstools/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/system/fstools/Makefile b/package/system/fstools/Makefile index bd4825b9f9..2da508d541 100644 --- a/package/system/fstools/Makefile +++ b/package/system/fstools/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/fstools.git -PKG_MIRROR_HASH:=22670e033b5623348de37c1d1e69caf799752b38205be8b25bc7020ef9e69884 -PKG_SOURCE_DATE:=2020-12-12 -PKG_SOURCE_VERSION:=f415323b7c87d66ab11d89325937d5dae5eb65c9 +PKG_MIRROR_HASH:=a485792d90c71cd4fb396ce97f42a57ee4d2a3d78e5f3fd0748270ffb14209e6 +PKG_SOURCE_DATE:=2021-01-04 +PKG_SOURCE_VERSION:=c53b18820756f6f32ad0782d3bf489422b7c4ad3 CMAKE_INSTALL:=1 PKG_LICENSE:=GPL-2.0 From b31ca88de9fed0ad5470b65a13b779ca51463ba3 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Tue, 5 Jan 2021 02:15:33 +0000 Subject: [PATCH 19/25] netifd: update to git HEAD 0c83439 netifd: wireless: default to GCMP WPA cipher on 802.11ad Signed-off-by: Daniel Golle --- package/network/config/netifd/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/network/config/netifd/Makefile b/package/network/config/netifd/Makefile index 0bac5840a4..f34896b7ec 100644 --- a/package/network/config/netifd/Makefile +++ b/package/network/config/netifd/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git -PKG_SOURCE_DATE:=2020-12-28 -PKG_SOURCE_VERSION:=39fb8c3edc74a7e419d95e2946a0b5a1206edc25 -PKG_MIRROR_HASH:=53d71140a7eeedb86929d0868b6816aa5b24123ba2aa7fc072cb79c2e9258fee +PKG_SOURCE_DATE:=2021-01-05 +PKG_SOURCE_VERSION:=0c8343968108f960b4eaafe4713453c5453bc6a0 +PKG_MIRROR_HASH:=613c432bbec93e067432646161ab1ba6a433ab7e4e8d3992cf3696128717ae36 PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=GPL-2.0 From 9c845a5ad1f20bc19fcc0af1e7d160c3b3f635aa Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Mon, 4 Jan 2021 18:53:40 +0000 Subject: [PATCH 20/25] base-files: wifi: add support for 802.11ad Signed-off-by: Daniel Golle --- package/base-files/Makefile | 2 +- package/base-files/files/sbin/wifi | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/package/base-files/Makefile b/package/base-files/Makefile index da3976424f..8d40eb0e49 100644 --- a/package/base-files/Makefile +++ b/package/base-files/Makefile @@ -12,7 +12,7 @@ include $(INCLUDE_DIR)/version.mk include $(INCLUDE_DIR)/feeds.mk PKG_NAME:=base-files -PKG_RELEASE:=244 +PKG_RELEASE:=245 PKG_FLAGS:=nonshared PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/ diff --git a/package/base-files/files/sbin/wifi b/package/base-files/files/sbin/wifi index a8b4451c60..75759b94f3 100755 --- a/package/base-files/files/sbin/wifi +++ b/package/base-files/files/sbin/wifi @@ -79,6 +79,7 @@ wifi_fixup_hwmode() { case "$hwmode" in 11bg) hwmode=bg;; 11a) hwmode=a;; + 11ad) hwmode=ad;; 11b) hwmode=b;; 11g) hwmode=g;; 11n*) From f246dfde3386ed4447afe080265ec75440ed5485 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Sun, 17 Mar 2019 21:01:17 +0100 Subject: [PATCH 21/25] hostapd: wpa_supplicant: Enable proper GCMP cipher support This patch enables hostapd.sh to properly configure wpa_supplicant for when GCMP is used as cipher in station mode. Without this wpa_supplicant will be unable to connect to AP. This is needed for wil6210 as it does not support CCMP. Signed-off-by: Robert Marko --- package/network/services/hostapd/Makefile | 2 +- package/network/services/hostapd/files/hostapd.sh | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile index f746f5455a..8e9605fe68 100644 --- a/package/network/services/hostapd/Makefile +++ b/package/network/services/hostapd/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=hostapd -PKG_RELEASE:=21 +PKG_RELEASE:=22 PKG_SOURCE_URL:=http://w1.fi/hostap.git PKG_SOURCE_PROTO:=git diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh index 80e1f7cedf..0f6741336b 100644 --- a/package/network/services/hostapd/files/hostapd.sh +++ b/package/network/services/hostapd/files/hostapd.sh @@ -1312,6 +1312,11 @@ wpa_supplicant_add_network() { ;; esac + [ "$wpa_cipher" = GCMP ] && { + append network_data "pairwise=GCMP" "$N$T" + append network_data "group=GCMP" "$N$T" + } + [ "$mode" = mesh ] || { case "$wpa" in 1) From d140d18990ca3c45c558a3e158ad7c4e90b32a52 Mon Sep 17 00:00:00 2001 From: Gary Cooper Date: Mon, 4 Jan 2021 20:27:49 +0300 Subject: [PATCH 22/25] mac80211: add 802.11ad-support This adds logic to properly populate defaults in /etc/config/wireless. Signed-off-by: Gary Cooper --- package/kernel/mac80211/Makefile | 2 +- package/kernel/mac80211/files/lib/wifi/mac80211.sh | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index e2e5b59825..35a7651d1d 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 PKG_VERSION:=5.8.18-1 -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.8.18/ PKG_HASH:=f04a8172423c6a945fc7d9844b04f33fda9ae574e552f8f18ee3bdfcfb494563 diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh index c0fbfbe5a8..3e99f06693 100644 --- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh +++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh @@ -88,6 +88,12 @@ detect_mac80211() { iw phy "$dev" info | grep -q 'VHT Capabilities' && htmode="VHT80" } + iw phy "$dev" info | grep -q '\* 5.... MHz \[' && { + mode_band="ad" + channel=$(iw phy "$dev" info | grep '\* 5.... MHz \[' | grep '(disabled)' -v -m 1 | sed 's/[^[]*\[\|\|\].*//g') + iw phy "$dev" info | grep -q 'Capabilities:' && htmode="HT20" + } + [ -n "$htmode" ] && ht_capab="set wireless.radio${devidx}.htmode=$htmode" path="$(mac80211_phy_to_path "$dev")" From 246fd27e522b10c173db24a8648cd57690f3435e Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 18 Sep 2019 19:54:56 +0200 Subject: [PATCH 23/25] linux-firmware: Add wil6210 firmware This patch adds wil6210 firmware and board files. Firmware version is not up to date but is only freely redistributable one I found. Board file is a generic one so most devices and especially those for long distance PtP links will require so in a ipq-wifi like way. Signed-off-by: Robert Marko --- package/firmware/linux-firmware/qca.mk | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/package/firmware/linux-firmware/qca.mk b/package/firmware/linux-firmware/qca.mk index 23fcc0905a..71b484d5c7 100644 --- a/package/firmware/linux-firmware/qca.mk +++ b/package/firmware/linux-firmware/qca.mk @@ -37,3 +37,11 @@ define Package/carl9170-firmware/install $(INSTALL_DATA) $(PKG_BUILD_DIR)/carl9170-1.fw $(1)/lib/firmware endef $(eval $(call BuildPackage,carl9170-firmware)) + +Package/wil6210-firmware = $(call Package/firmware-default,wil6210 firmware) +define Package/wil6210-firmware/install + $(INSTALL_DIR) $(1)/lib/firmware + $(INSTALL_DATA) $(PKG_BUILD_DIR)/wil6210.fw $(1)/lib/firmware + $(INSTALL_DATA) $(PKG_BUILD_DIR)/wil6210.brd $(1)/lib/firmware +endef +$(eval $(call BuildPackage,wil6210-firmware)) From 6442b8cbc2e4c53ffa4a6b7c30c2571dac87902d Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 18 Sep 2019 19:58:49 +0200 Subject: [PATCH 24/25] mac80211: Add wil6210 driver This patch adds wil6210 driver for Wilocity/QCA based 802.11ad PCI cards. Driver uses cfg80211 and nl80211 but not mac80211. Integration for UCI and LuCI will come in other patches. Signed-off-by: Robert Marko --- package/kernel/mac80211/ath.mk | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index 957c9da939..24abb910ff 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -1,6 +1,6 @@ PKG_DRIVERS += \ ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc ath10k \ - carl9170 owl-loader ar5523 + carl9170 owl-loader ar5523 wil6210 PKG_CONFIG_DEPENDS += \ CONFIG_PACKAGE_ATH_DEBUG \ @@ -21,7 +21,8 @@ ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS ATH10K_DEBUGFS \ CARL9170_DEBUGFS \ ATH5K_DEBUG \ - ATH6KL_DEBUG + ATH6KL_DEBUG \ + WIL6210_DEBUGFS endif ifdef CONFIG_PACKAGE_MAC80211_TRACING @@ -29,7 +30,8 @@ ifdef CONFIG_PACKAGE_MAC80211_TRACING ATH10K_TRACING \ ATH6KL_TRACING \ ATH_TRACEPOINTS \ - ATH5K_TRACER + ATH5K_TRACER \ + WIL6210_TRACING endif config-$(call config_package,ath) += ATH_CARDS ATH_COMMON ATH_REG_DYNAMIC_USER_REG_HINTS @@ -68,6 +70,8 @@ config-$(call config_package,ath6kl-usb) += ATH6KL_USB config-$(call config_package,carl9170) += CARL9170 config-$(call config_package,ar5523) += AR5523 +config-$(call config_package,wil6210) += WIL6210 + define KernelPackage/ath/config if PACKAGE_kmod-ath config ATH_USER_REGD @@ -309,3 +313,11 @@ define KernelPackage/ar5523 FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ar5523/ar5523.ko AUTOLOAD:=$(call AutoProbe,ar5523) endef + +define KernelPackage/wil6210 + $(call KernelPackage/mac80211/Default) + TITLE:=QCA/Wilocity 60g WiFi card wil6210 support + DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +wil6210-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/wil6210/wil6210.ko + AUTOLOAD:=$(call AutoProbe,wil6210) +endef From 1a775a4fd0339b485f48a864e2cf9e8794bfe4cb Mon Sep 17 00:00:00 2001 From: Gary Cooper Date: Mon, 4 Jan 2021 20:27:50 +0300 Subject: [PATCH 25/25] ipq806x: add support for TP-Link Talon AD7200 Device hardware: https://deviwiki.com/wiki/TP-LINK_AD7200_(Talon) The Talon AD7200 is basically an Archer C2600 with a third PCIe lane and an 802.11ad radio. It looks like the Archers C2600/5400 but the housing is slightly larger. Specifications -------------- - IPQ8064 dual-core 1400MHz - QCA9988 2.4GHz WiFi - QCA9990 5GHz WiFi - QCA9500 60GHz WiFi - 32MB SPI Flash - 512MiB RAM - 5 GBit Ports (QCA8337) Installation ------------ Installation is possible from the OEM web interface. Sysupgrade is possible. TFTP recovery is possible. - Image: AD7200_1.0_tp_recovery.bin Notes - This will be the first 802.11ad device supported by mainline. Signed-off-by: Gary Cooper --- .../ipq806x/base-files/etc/board.d/01_leds | 9 + .../ipq806x/base-files/etc/board.d/02_network | 1 + .../etc/hotplug.d/firmware/11-ath10k-caldata | 2 + .../base-files/lib/upgrade/platform.sh | 1 + .../arch/arm/boot/dts/qcom-ipq8064-ad7200.dts | 440 ++++++++++++++++++ target/linux/ipq806x/image/Makefile | 15 + tools/firmware-utils/src/tplink-safeloader.c | 44 ++ 7 files changed, 512 insertions(+) create mode 100644 target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-ad7200.dts diff --git a/target/linux/ipq806x/base-files/etc/board.d/01_leds b/target/linux/ipq806x/base-files/etc/board.d/01_leds index fed821663a..a03a056d83 100755 --- a/target/linux/ipq806x/base-files/etc/board.d/01_leds +++ b/target/linux/ipq806x/base-files/etc/board.d/01_leds @@ -39,6 +39,15 @@ netgear,r7800) ucidef_set_led_switch "wan" "WAN" "white:wan" "switch0" "0x20" ucidef_set_led_ide "esata" "eSATA" "white:esata" ;; +tplink,ad7200) + ucidef_set_led_usbport "usb1" "USB 1" "blue:usb_1" "usb1-port1" "usb2-port1" + ucidef_set_led_usbport "usb2" "USB 2" "blue:usb_3" "usb3-port1" "usb4-port1" + ucidef_set_led_switch "wan" "wan" "blue:wan" "switch0" "0x02" + ucidef_set_led_switch "lan" "lan" "blue:lan" "switch0" "0x3c" + ucidef_set_led_wlan "wlan2g" "wlan2g" "blue:wlan2g" "phy2tpt" + ucidef_set_led_wlan "wlan5g" "wlan5g" "blue:wlan5g" "phy1tpt" + ucidef_set_led_netdev "wlan60g" "wlan60g" "blue:wlan60g" "wlan0" + ;; tplink,c2600) ucidef_set_led_usbport "usb1" "USB 1" "white:usb_2" "usb1-port1" "usb2-port1" ucidef_set_led_usbport "usb2" "USB 2" "white:usb_4" "usb3-port1" "usb4-port1" diff --git a/target/linux/ipq806x/base-files/etc/board.d/02_network b/target/linux/ipq806x/base-files/etc/board.d/02_network index 10b2ec0148..fbf56c5e0c 100755 --- a/target/linux/ipq806x/base-files/etc/board.d/02_network +++ b/target/linux/ipq806x/base-files/etc/board.d/02_network @@ -51,6 +51,7 @@ nec,wg2600hp3) "2:lan" "3:lan" "4:lan" "5:lan" "0@eth1" "1:wan" "6@eth0" ;; netgear,r7800 |\ +tplink,ad7200 |\ tplink,c2600) ucidef_add_switch "switch0" \ "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "6@eth1" "5:wan" "0@eth0" diff --git a/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata index 8788fc92f6..3befc40630 100644 --- a/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata +++ b/target/linux/ipq806x/base-files/etc/hotplug.d/firmware/11-ath10k-caldata @@ -35,6 +35,7 @@ case "$FIRMWARE" in caldata_extract "art" 0x1000 0x2f20 ath10k_patch_mac $(macaddr_add $(mtd_get_mac_binary art 0x6) +1) ;; + tplink,ad7200 |\ tplink,c2600) caldata_extract "radio" 0x1000 0x2f20 ath10k_patch_mac $(macaddr_add $(mtd_get_mac_binary default-mac 0x8) -1) @@ -74,6 +75,7 @@ case "$FIRMWARE" in caldata_extract "art" 0x5000 0x2f20 ath10k_patch_mac $(macaddr_add $(mtd_get_mac_binary art 0x6) +2) ;; + tplink,ad7200 |\ tplink,c2600) caldata_extract "radio" 0x5000 0x2f20 ath10k_patch_mac $(mtd_get_mac_binary default-mac 0x8) diff --git a/target/linux/ipq806x/base-files/lib/upgrade/platform.sh b/target/linux/ipq806x/base-files/lib/upgrade/platform.sh index f5d6c5d55d..4dc612492c 100644 --- a/target/linux/ipq806x/base-files/lib/upgrade/platform.sh +++ b/target/linux/ipq806x/base-files/lib/upgrade/platform.sh @@ -43,6 +43,7 @@ platform_do_upgrade() { linksys,ea8500) platform_do_upgrade_linksys "$1" ;; + tplink,ad7200 |\ tplink,c2600) PART_NAME="os-image:rootfs" MTD_CONFIG_ARGS="-s 0x200000" diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-ad7200.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-ad7200.dts new file mode 100644 index 0000000000..e5bdc32114 --- /dev/null +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-ad7200.dts @@ -0,0 +1,440 @@ +//SPDX-License-Identifier: GPL-2.0-or-later OR MIT +#include "qcom-ipq8064-v2.0.dtsi" + +#include + +/ { + model = "TP-Link Talon AD7200"; + compatible = "tplink,ad7200", "qcom,ipq8064"; + + memory@0 { + reg = <0x42000000 0x1e000000>; + device_type = "memory"; + }; + + aliases { + mdio-gpio0 = &mdio0; + + led-boot = &power; + led-failsafe = &power; + led-running = &power; + led-upgrade = &power; + label-mac-device = &gmac2; + }; + + keys { + compatible = "gpio-keys"; + pinctrl-0 = <&button_pins>; + pinctrl-names = "default"; + + wifi { + label = "wifi"; + gpios = <&qcom_pinmux 54 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + reset { + label = "reset"; + gpios = <&qcom_pinmux 7 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + wps { + label = "wps"; + gpios = <&qcom_pinmux 67 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + ledgeneral { + label = "ledswitch"; + gpios = <&qcom_pinmux 53 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-0 = <&led_pins>; + pinctrl-names = "default"; + + lan { + label = "blue:lan"; + gpios = <&qcom_pinmux 2 GPIO_ACTIVE_HIGH>; + }; + + usb1 { + label = "blue:usb_1"; + gpios = <&qcom_pinmux 8 GPIO_ACTIVE_HIGH>; + }; + + usb3 { + label = "blue:usb_3"; + gpios = <&qcom_pinmux 16 GPIO_ACTIVE_HIGH>; + }; + + wps { + label = "blue:wps"; + gpios = <&qcom_pinmux 55 GPIO_ACTIVE_HIGH>; + }; + + wan_orange { + label = "orange:wan"; + gpios = <&qcom_pinmux 26 GPIO_ACTIVE_LOW>; + }; + + wan_blue { + label = "blue:wan"; + gpios = <&qcom_pinmux 33 GPIO_ACTIVE_LOW>; + }; + + power: status { + label = "blue:status"; + gpios = <&qcom_pinmux 66 GPIO_ACTIVE_HIGH>; + }; + + wlan2g { + label = "blue:wlan2g"; + gpios = <&qcom_pinmux 17 GPIO_ACTIVE_HIGH>; + + }; + + wlan5g { + label = "blue:wlan5g"; + gpios = <&qcom_pinmux 15 GPIO_ACTIVE_HIGH>; + + }; + + wlan60g { + label = "blue:wlan60g"; + gpios = <&qcom_pinmux 56 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&qcom_pinmux { + button_pins: button_pins { + mux { + pins = "gpio53", "gpio54", "gpio67"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + led_pins: led_pins { + mux { + pins = "gpio2", "gpio8", "gpio15", "gpio16", "gpio17", "gpio26", + "gpio33", "gpio55", "gpio56", "gpio66"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + spi_pins: spi_pins { + mux { + pins = "gpio18", "gpio19", "gpio21"; + function = "gsbi5"; + bias-pull-down; + }; + + data { + pins = "gpio18", "gpio19"; + drive-strength = <10>; + }; + + cs { + pins = "gpio20"; + function = "gpio"; + drive-strength = <10>; + bias-pull-up; + }; + + clk { + pins = "gpio21"; + drive-strength = <12>; + }; + }; + + usb0_pwr_en_pin: usb0_pwr_en_pin { + mux { + pins = "gpio25"; + function = "gpio"; + drive-strength = <10>; + bias-pull-up; + output-high; + }; + }; + + usb1_pwr_en_pin: usb1_pwr_en_pin { + mux { + pins = "gpio23"; + function = "gpio"; + drive-strength = <10>; + bias-pull-up; + output-high; + }; + }; +}; + +&gsbi5 { + qcom,mode = ; + status = "okay"; + + spi4: spi@1a280000 { + status = "okay"; + + pinctrl-0 = <&spi_pins>; + pinctrl-names = "default"; + + cs-gpios = <&qcom_pinmux 20 GPIO_ACTIVE_HIGH>; + + m25p80@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <50000000>; + reg = <0>; + + SBL1@0 { + label = "SBL1"; + reg = <0x0 0x20000>; + read-only; + }; + + MIBIB@20000 { + label = "MIBIB"; + reg = <0x20000 0x20000>; + read-only; + }; + + SBL2@40000 { + label = "SBL2"; + reg = <0x40000 0x20000>; + read-only; + }; + + SBL3@60000 { + label = "SBL3"; + reg = <0x60000 0x30000>; + read-only; + }; + + DDRCONFIG@90000 { + label = "DDRCONFIG"; + reg = <0x90000 0x10000>; + read-only; + }; + + SSD@a0000 { + label = "SSD"; + reg = <0xa0000 0x10000>; + read-only; + }; + + TZ@b0000 { + label = "TZ"; + reg = <0xb0000 0x30000>; + read-only; + }; + + RPM@e0000 { + label = "RPM"; + reg = <0xe0000 0x20000>; + read-only; + }; + + fs-uboot@100000 { + label = "fs-uboot"; + reg = <0x100000 0x70000>; + read-only; + }; + + uboot-env@170000 { + label = "uboot-env"; + reg = <0x170000 0x40000>; + read-only; + }; + + radio@1b0000 { + label = "radio"; + reg = <0x1b0000 0x40000>; + read-only; + }; + + os-image@1f0000 { + label = "os-image"; + reg = <0x1f0000 0x400000>; + }; + + rootfs@5f0000 { + label = "rootfs"; + reg = <0x5f0000 0x1900000>; + }; + + defaultmac: default-mac@1ef0000 { + label = "default-mac"; + reg = <0x1ef0000 0x00200>; + read-only; + }; + + pin@1ef0200 { + label = "pin"; + reg = <0x1ef0200 0x00200>; + read-only; + }; + + device-id@1ef0400 { + label = "device-id"; + reg = <0x1ef0400 0x00200>; + read-only; + }; + + product-info@1ef0600 { + label = "product-info"; + reg = <0x1ef0600 0x0fa00>; + read-only; + }; + + partition-table@1f00000 { + label = "partition-table"; + reg = <0x1f00000 0x10000>; + read-only; + }; + + soft-version@1f10000 { + label = "soft-version"; + reg = <0x1f10000 0x10000>; + read-only; + }; + + support-list@1f20000 { + label = "support-list"; + reg = <0x1f20000 0x10000>; + read-only; + }; + + profile@1f30000 { + label = "profile"; + reg = <0x1f30000 0x10000>; + read-only; + }; + + default-config@1f40000 { + label = "default-config"; + reg = <0x1f40000 0x10000>; + read-only; + }; + + user-config@1f50000 { + label = "user-config"; + reg = <0x1f50000 0x40000>; + read-only; + }; + + qos-db@1f90000 { + label = "qos-db"; + reg = <0x1f90000 0x40000>; + read-only; + }; + + usb-config@1fd0000 { + label = "usb-config"; + reg = <0x1fd0000 0x10000>; + read-only; + }; + + log@1fe0000 { + label = "log"; + reg = <0x1fe0000 0x20000>; + read-only; + }; + }; + }; +}; + +&usb3_0 { + status = "okay"; + + pinctrl-0 = <&usb0_pwr_en_pin>; + pinctrl-names = "default"; +}; + +&usb3_1 { + status = "okay"; + + pinctrl-0 = <&usb1_pwr_en_pin>; + pinctrl-names = "default"; +}; + +&pcie0 { + status = "okay"; +}; + +&pcie1 { + status = "okay"; + max-link-speed = <1>; +}; + +&pcie2 { + status = "okay"; + max-link-speed = <1>; +}; + +&mdio0 { + status = "okay"; + + pinctrl-0 = <&mdio0_pins>; + pinctrl-names = "default"; + + phy0: ethernet-phy@0 { + reg = <0>; + qca,ar8327-initvals = < + 0x00004 0x7600000 /* PAD0_MODE */ + 0x00008 0x1000000 /* PAD5_MODE */ + 0x0000c 0x80 /* PAD6_MODE */ + 0x000e4 0x6a545 /* MAC_POWER_SEL */ + 0x000e0 0xc74164de /* SGMII_CTRL */ + 0x0007c 0x4e /* PORT0_STATUS */ + 0x00094 0x4e /* PORT6_STATUS */ + >; + }; + + phy4: ethernet-phy@4 { + reg = <4>; + }; +}; + +&gmac1 { + status = "okay"; + phy-mode = "rgmii"; + qcom,id = <1>; + + pinctrl-0 = <&rgmii2_pins>; + pinctrl-names = "default"; + + mtd-mac-address = <&defaultmac 0x8>; + mtd-mac-address-increment = <1>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&gmac2 { + status = "okay"; + phy-mode = "sgmii"; + qcom,id = <2>; + + mtd-mac-address = <&defaultmac 0x8>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&adm_dma { + status = "okay"; +}; diff --git a/target/linux/ipq806x/image/Makefile b/target/linux/ipq806x/image/Makefile index 80bfec5ad9..876f337bba 100644 --- a/target/linux/ipq806x/image/Makefile +++ b/target/linux/ipq806x/image/Makefile @@ -333,6 +333,21 @@ define Device/qcom_ipq8064-db149 endef TARGET_DEVICES += qcom_ipq8064-db149 +define Device/tplink_ad7200 + $(call Device/TpSafeImage) + DEVICE_VENDOR := TP-Link + DEVICE_MODEL := Talon AD7200 + DEVICE_VARIANT := v1 + SOC := qcom-ipq8064 + BLOCKSIZE := 128k + PAGESIZE := 2048 + BOARD_NAME := ad7200 + SUPPORTED_DEVICES += ad7200 + TPLINK_BOARD_ID := AD7200 + DEVICE_PACKAGES := ath10k-firmware-qca99x0-ct kmod-wil6210 +endef +TARGET_DEVICES += tplink_ad7200 + define Device/tplink_c2600 $(call Device/TpSafeImage) DEVICE_VENDOR := TP-Link diff --git a/tools/firmware-utils/src/tplink-safeloader.c b/tools/firmware-utils/src/tplink-safeloader.c index deba84c6d1..785ff39642 100644 --- a/tools/firmware-utils/src/tplink-safeloader.c +++ b/tools/firmware-utils/src/tplink-safeloader.c @@ -668,6 +668,50 @@ static struct device_info boards[] = { .last_sysupgrade_partition = "support-list", }, + /** Firmware layout for the AD7200 */ + { + .id = "AD7200", + .vendor = "", + .support_list = + "SupportList:\r\n" + "{product_name:Talon AD7200,product_ver:1.0.0,special_id:00000000}\r\n", + .part_trail = 0x00, + .soft_ver = NULL, + + .partitions = { + {"SBL1", 0x00000, 0x20000}, + {"MIBIB", 0x20000, 0x20000}, + {"SBL2", 0x40000, 0x20000}, + {"SBL3", 0x60000, 0x30000}, + {"DDRCONFIG", 0x90000, 0x10000}, + {"SSD", 0xa0000, 0x10000}, + {"TZ", 0xb0000, 0x30000}, + {"RPM", 0xe0000, 0x20000}, + {"fs-uboot", 0x100000, 0x70000}, + {"uboot-env", 0x170000, 0x40000}, + {"radio", 0x1b0000, 0x40000}, + {"os-image", 0x1f0000, 0x400000}, + {"file-system", 0x5f0000, 0x1900000}, + {"default-mac", 0x1ef0000, 0x00200}, + {"pin", 0x1ef0200, 0x00200}, + {"device-id", 0x1ef0400, 0x00200}, + {"product-info", 0x1ef0600, 0x0fa00}, + {"partition-table", 0x1f00000, 0x10000}, + {"soft-version", 0x1f10000, 0x10000}, + {"support-list", 0x1f20000, 0x10000}, + {"profile", 0x1f30000, 0x10000}, + {"default-config", 0x1f40000, 0x10000}, + {"user-config", 0x1f50000, 0x40000}, + {"qos-db", 0x1f90000, 0x40000}, + {"usb-config", 0x1fd0000, 0x10000}, + {"log", 0x1fe0000, 0x20000}, + {NULL, 0, 0} + }, + + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system" + }, + /** Firmware layout for the C2600 */ { .id = "C2600",