From: Felix Fietkau Date: Sun, 10 Mar 2019 20:34:09 +0000 (+0100) Subject: mac80211: update and fix the patch to allow 4-byte aligned tx skbs X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=5cda4a3e309faa314bab6297958db2413eeacdf3;p=openwrt%2Fstaging%2Fthess.git mac80211: update and fix the patch to allow 4-byte aligned tx skbs Signed-off-by: Felix Fietkau --- diff --git a/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch b/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch new file mode 100644 index 0000000000..661fb46ea4 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch @@ -0,0 +1,82 @@ +From: Chaitanya T K +Date: Mon, 27 Jun 2016 15:23:26 +0530 +Subject: [PATCH] mac80211: minstrel: Enable STBC and LDPC for VHT Rates + +If peer support reception of STBC and LDPC, enable them for better +performance. + +Signed-off-by: Chaitanya TK +--- + +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -1659,6 +1659,7 @@ struct ieee80211_mu_edca_param_set { + #define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300 + #define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400 + #define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700 ++#define IEEE80211_VHT_CAP_RXSTBC_SHIFT 8 + #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 + #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 + #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT 13 +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1130,7 +1130,7 @@ minstrel_ht_update_caps(void *priv, stru + struct minstrel_ht_sta_priv *msp = priv_sta; + struct minstrel_ht_sta *mi = &msp->ht; + struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; +- u16 sta_cap = sta->ht_cap.cap; ++ u16 ht_cap = sta->ht_cap.cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + struct sta_info *sinfo = container_of(sta, struct sta_info, sta); + int use_vht; +@@ -1138,6 +1138,7 @@ minstrel_ht_update_caps(void *priv, stru + int ack_dur; + int stbc; + int i; ++ bool ldpc = false; + + /* fall back to the old minstrel for legacy stations */ + if (!sta->ht_cap.ht_supported) +@@ -1175,16 +1176,24 @@ minstrel_ht_update_caps(void *priv, stru + } + mi->sample_tries = 4; + +- /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */ + if (!use_vht) { +- stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> ++ stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >> + IEEE80211_HT_CAP_RX_STBC_SHIFT; +- mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; + +- if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) +- mi->tx_flags |= IEEE80211_TX_CTL_LDPC; ++ if (ht_cap & IEEE80211_HT_CAP_LDPC_CODING) ++ ldpc = true; ++ } else { ++ stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >> ++ IEEE80211_VHT_CAP_RXSTBC_SHIFT; ++ ++ if (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC) ++ ldpc = true; + } + ++ mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; ++ if (ldpc) ++ mi->tx_flags |= IEEE80211_TX_CTL_LDPC; ++ + for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { + u32 gflags = minstrel_mcs_groups[i].flags; + int bw, nss; +@@ -1197,10 +1206,10 @@ minstrel_ht_update_caps(void *priv, stru + + if (gflags & IEEE80211_TX_RC_SHORT_GI) { + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) { +- if (!(sta_cap & IEEE80211_HT_CAP_SGI_40)) ++ if (!(ht_cap & IEEE80211_HT_CAP_SGI_40)) + continue; + } else { +- if (!(sta_cap & IEEE80211_HT_CAP_SGI_20)) ++ if (!(ht_cap & IEEE80211_HT_CAP_SGI_20)) + continue; + } + } diff --git a/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch b/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch new file mode 100644 index 0000000000..95d4f294aa --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch @@ -0,0 +1,150 @@ +From: Felix Fietkau +Date: Sat, 10 Feb 2018 12:41:51 +0100 +Subject: [PATCH] mac80211: minstrel: remove unnecessary debugfs cleanup + code + +debugfs entries are cleaned up by debugfs_remove_recursive already. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel.c ++++ b/net/mac80211/rc80211_minstrel.c +@@ -689,8 +689,8 @@ minstrel_alloc(struct ieee80211_hw *hw, + + #ifdef CPTCFG_MAC80211_DEBUGFS + mp->fixed_rate_idx = (u32) -1; +- mp->dbg_fixed_rate = debugfs_create_u32("fixed_rate_idx", +- 0666, debugfsdir, &mp->fixed_rate_idx); ++ debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, ++ &mp->fixed_rate_idx); + #endif + + minstrel_init_cck_rates(mp); +@@ -701,9 +701,6 @@ minstrel_alloc(struct ieee80211_hw *hw, + static void + minstrel_free(void *priv) + { +-#ifdef CPTCFG_MAC80211_DEBUGFS +- debugfs_remove(((struct minstrel_priv *)priv)->dbg_fixed_rate); +-#endif + kfree(priv); + } + +@@ -735,7 +732,6 @@ const struct rate_control_ops mac80211_m + .free_sta = minstrel_free_sta, + #ifdef CPTCFG_MAC80211_DEBUGFS + .add_sta_debugfs = minstrel_add_sta_debugfs, +- .remove_sta_debugfs = minstrel_remove_sta_debugfs, + #endif + .get_expected_throughput = minstrel_get_expected_throughput, + }; +--- a/net/mac80211/rc80211_minstrel.h ++++ b/net/mac80211/rc80211_minstrel.h +@@ -109,11 +109,6 @@ struct minstrel_sta_info { + + /* sampling table */ + u8 *sample_table; +- +-#ifdef CPTCFG_MAC80211_DEBUGFS +- struct dentry *dbg_stats; +- struct dentry *dbg_stats_csv; +-#endif + }; + + struct minstrel_priv { +@@ -137,7 +132,6 @@ struct minstrel_priv { + * - setting will be applied on next update + */ + u32 fixed_rate_idx; +- struct dentry *dbg_fixed_rate; + #endif + }; + +@@ -156,7 +150,6 @@ minstrel_get_ewmsd10(struct minstrel_rat + + extern const struct rate_control_ops mac80211_minstrel; + void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); +-void minstrel_remove_sta_debugfs(void *priv, void *priv_sta); + + /* Recalculate success probabilities and counters for a given rate using EWMA */ + void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs); +--- a/net/mac80211/rc80211_minstrel_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_debugfs.c +@@ -214,19 +214,7 @@ minstrel_add_sta_debugfs(void *priv, voi + { + struct minstrel_sta_info *mi = priv_sta; + +- mi->dbg_stats = debugfs_create_file("rc_stats", 0444, dir, mi, +- &minstrel_stat_fops); +- +- mi->dbg_stats_csv = debugfs_create_file("rc_stats_csv", 0444, dir, mi, +- &minstrel_stat_csv_fops); +-} +- +-void +-minstrel_remove_sta_debugfs(void *priv, void *priv_sta) +-{ +- struct minstrel_sta_info *mi = priv_sta; +- +- debugfs_remove(mi->dbg_stats); +- +- debugfs_remove(mi->dbg_stats_csv); ++ debugfs_create_file("rc_stats", S_IRUGO, dir, mi, &minstrel_stat_fops); ++ debugfs_create_file("rc_stats_csv", S_IRUGO, dir, mi, ++ &minstrel_stat_csv_fops); + } +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1393,7 +1393,6 @@ static const struct rate_control_ops mac + .free = minstrel_ht_free, + #ifdef CPTCFG_MAC80211_DEBUGFS + .add_sta_debugfs = minstrel_ht_add_sta_debugfs, +- .remove_sta_debugfs = minstrel_ht_remove_sta_debugfs, + #endif + .get_expected_throughput = minstrel_ht_get_expected_throughput, + }; +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -110,17 +110,12 @@ struct minstrel_ht_sta_priv { + struct minstrel_ht_sta ht; + struct minstrel_sta_info legacy; + }; +-#ifdef CPTCFG_MAC80211_DEBUGFS +- struct dentry *dbg_stats; +- struct dentry *dbg_stats_csv; +-#endif + void *ratelist; + void *sample_table; + bool is_ht; + }; + + void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); +-void minstrel_ht_remove_sta_debugfs(void *priv, void *priv_sta); + int minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate, + int prob_ewma); + +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -303,17 +303,8 @@ minstrel_ht_add_sta_debugfs(void *priv, + { + struct minstrel_ht_sta_priv *msp = priv_sta; + +- msp->dbg_stats = debugfs_create_file("rc_stats", 0444, dir, msp, +- &minstrel_ht_stat_fops); +- msp->dbg_stats_csv = debugfs_create_file("rc_stats_csv", 0444, dir, msp, +- &minstrel_ht_stat_csv_fops); +-} +- +-void +-minstrel_ht_remove_sta_debugfs(void *priv, void *priv_sta) +-{ +- struct minstrel_ht_sta_priv *msp = priv_sta; +- +- debugfs_remove(msp->dbg_stats); +- debugfs_remove(msp->dbg_stats_csv); ++ debugfs_create_file("rc_stats", S_IRUGO, dir, msp, ++ &minstrel_ht_stat_fops); ++ debugfs_create_file("rc_stats_csv", S_IRUGO, dir, msp, ++ &minstrel_ht_stat_csv_fops); + } diff --git a/package/kernel/mac80211/patches/subsys/305-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch b/package/kernel/mac80211/patches/subsys/305-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch new file mode 100644 index 0000000000..9a233753ad --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/305-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch @@ -0,0 +1,575 @@ +From: Felix Fietkau +Date: Sat, 10 Feb 2018 12:43:30 +0100 +Subject: [PATCH] mac80211: minstrel: merge with minstrel_ht, always enable + VHT support + +Legacy-only devices are not very common and the overhead of the extra +code for HT and VHT rates is not big enough to justify all those extra +lines of code to make it optional. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/Kconfig ++++ b/net/mac80211/Kconfig +@@ -25,20 +25,6 @@ config MAC80211_RC_MINSTREL + ---help--- + This option enables the 'minstrel' TX rate control algorithm + +-config MAC80211_RC_MINSTREL_HT +- bool "Minstrel 802.11n support" if EXPERT +- depends on MAC80211_RC_MINSTREL +- default y +- ---help--- +- This option enables the 'minstrel_ht' TX rate control algorithm +- +-config MAC80211_RC_MINSTREL_VHT +- bool "Minstrel 802.11ac support" if EXPERT +- depends on MAC80211_RC_MINSTREL_HT +- default n +- ---help--- +- This option enables VHT in the 'minstrel_ht' TX rate control algorithm +- + choice + prompt "Default rate control algorithm" + depends on MAC80211_HAS_RC +@@ -60,8 +46,7 @@ endchoice + + config MAC80211_RC_DEFAULT + string +- default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL && MAC80211_RC_MINSTREL_HT +- default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL ++ default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL + default "" + + endif +--- a/net/mac80211/Makefile ++++ b/net/mac80211/Makefile +@@ -52,13 +52,14 @@ mac80211-$(CONFIG_PM) += pm.o + + CFLAGS_trace.o := -I$(src) + +-rc80211_minstrel-y := rc80211_minstrel.o +-rc80211_minstrel-$(CPTCFG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o ++rc80211_minstrel-y := \ ++ rc80211_minstrel.o \ ++ rc80211_minstrel_ht.o + +-rc80211_minstrel_ht-y := rc80211_minstrel_ht.o +-rc80211_minstrel_ht-$(CPTCFG_MAC80211_DEBUGFS) += rc80211_minstrel_ht_debugfs.o ++rc80211_minstrel-$(CPTCFG_MAC80211_DEBUGFS) += \ ++ rc80211_minstrel_debugfs.o \ ++ rc80211_minstrel_ht_debugfs.o + + mac80211-$(CPTCFG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) +-mac80211-$(CPTCFG_MAC80211_RC_MINSTREL_HT) += $(rc80211_minstrel_ht-y) + + ccflags-y += -DDEBUG +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -1308,18 +1308,12 @@ static int __init ieee80211_init(void) + if (ret) + return ret; + +- ret = rc80211_minstrel_ht_init(); +- if (ret) +- goto err_minstrel; +- + ret = ieee80211_iface_init(); + if (ret) + goto err_netdev; + + return 0; + err_netdev: +- rc80211_minstrel_ht_exit(); +- err_minstrel: + rc80211_minstrel_exit(); + + return ret; +@@ -1327,7 +1321,6 @@ static int __init ieee80211_init(void) + + static void __exit ieee80211_exit(void) + { +- rc80211_minstrel_ht_exit(); + rc80211_minstrel_exit(); + + ieee80211s_stop(); +--- a/net/mac80211/rate.h ++++ b/net/mac80211/rate.h +@@ -95,18 +95,5 @@ static inline void rc80211_minstrel_exit + } + #endif + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_HT +-int rc80211_minstrel_ht_init(void); +-void rc80211_minstrel_ht_exit(void); +-#else +-static inline int rc80211_minstrel_ht_init(void) +-{ +- return 0; +-} +-static inline void rc80211_minstrel_ht_exit(void) +-{ +-} +-#endif +- + + #endif /* IEEE80211_RATE_H */ +--- a/net/mac80211/rc80211_minstrel.c ++++ b/net/mac80211/rc80211_minstrel.c +@@ -572,138 +572,6 @@ minstrel_rate_init(void *priv, struct ie + minstrel_update_rates(mp, mi); + } + +-static void * +-minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) +-{ +- struct ieee80211_supported_band *sband; +- struct minstrel_sta_info *mi; +- struct minstrel_priv *mp = priv; +- struct ieee80211_hw *hw = mp->hw; +- int max_rates = 0; +- int i; +- +- mi = kzalloc(sizeof(struct minstrel_sta_info), gfp); +- if (!mi) +- return NULL; +- +- for (i = 0; i < NUM_NL80211_BANDS; i++) { +- sband = hw->wiphy->bands[i]; +- if (sband && sband->n_bitrates > max_rates) +- max_rates = sband->n_bitrates; +- } +- +- mi->r = kcalloc(max_rates, sizeof(struct minstrel_rate), gfp); +- if (!mi->r) +- goto error; +- +- mi->sample_table = kmalloc_array(max_rates, SAMPLE_COLUMNS, gfp); +- if (!mi->sample_table) +- goto error1; +- +- mi->last_stats_update = jiffies; +- return mi; +- +-error1: +- kfree(mi->r); +-error: +- kfree(mi); +- return NULL; +-} +- +-static void +-minstrel_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta) +-{ +- struct minstrel_sta_info *mi = priv_sta; +- +- kfree(mi->sample_table); +- kfree(mi->r); +- kfree(mi); +-} +- +-static void +-minstrel_init_cck_rates(struct minstrel_priv *mp) +-{ +- 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, j = 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++) { +- if (rate->bitrate != bitrates[j]) +- continue; +- +- mp->cck_rates[j] = i; +- break; +- } +- } +-} +- +-static void * +-minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +-{ +- struct minstrel_priv *mp; +- +- mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC); +- if (!mp) +- return NULL; +- +- /* contention window settings +- * Just an approximation. Using the per-queue values would complicate +- * the calculations and is probably unnecessary */ +- 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; +- +- if (hw->max_rate_tries > 0) +- mp->max_retry = hw->max_rate_tries; +- else +- /* safe default, does not necessarily have to match hw properties */ +- mp->max_retry = 7; +- +- if (hw->max_rates >= 4) +- mp->has_mrr = true; +- +- mp->hw = hw; +- mp->update_interval = 100; +- +-#ifdef CPTCFG_MAC80211_DEBUGFS +- mp->fixed_rate_idx = (u32) -1; +- debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, +- &mp->fixed_rate_idx); +-#endif +- +- minstrel_init_cck_rates(mp); +- +- return mp; +-} +- +-static void +-minstrel_free(void *priv) +-{ +- kfree(priv); +-} +- + static u32 minstrel_get_expected_throughput(void *priv_sta) + { + struct minstrel_sta_info *mi = priv_sta; +@@ -722,28 +590,8 @@ static u32 minstrel_get_expected_through + } + + const struct rate_control_ops mac80211_minstrel = { +- .name = "minstrel", + .tx_status_ext = minstrel_tx_status, + .get_rate = minstrel_get_rate, + .rate_init = minstrel_rate_init, +- .alloc = minstrel_alloc, +- .free = minstrel_free, +- .alloc_sta = minstrel_alloc_sta, +- .free_sta = minstrel_free_sta, +-#ifdef CPTCFG_MAC80211_DEBUGFS +- .add_sta_debugfs = minstrel_add_sta_debugfs, +-#endif + .get_expected_throughput = minstrel_get_expected_throughput, + }; +- +-int __init +-rc80211_minstrel_init(void) +-{ +- return ieee80211_rate_control_register(&mac80211_minstrel); +-} +- +-void +-rc80211_minstrel_exit(void) +-{ +- ieee80211_rate_control_unregister(&mac80211_minstrel); +-} +--- a/net/mac80211/rc80211_minstrel.h ++++ b/net/mac80211/rc80211_minstrel.h +@@ -158,7 +158,5 @@ int minstrel_get_tp_avg(struct minstrel_ + /* debugfs */ + int minstrel_stats_open(struct inode *inode, struct file *file); + int minstrel_stats_csv_open(struct inode *inode, struct file *file); +-ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos); +-int minstrel_stats_release(struct inode *inode, struct file *file); + + #endif +--- a/net/mac80211/rc80211_minstrel_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_debugfs.c +@@ -54,22 +54,6 @@ + #include + #include "rc80211_minstrel.h" + +-ssize_t +-minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) +-{ +- struct minstrel_debugfs_info *ms; +- +- ms = file->private_data; +- return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len); +-} +- +-int +-minstrel_stats_release(struct inode *inode, struct file *file) +-{ +- kfree(file->private_data); +- return 0; +-} +- + int + minstrel_stats_open(struct inode *inode, struct file *file) + { +@@ -135,14 +119,6 @@ minstrel_stats_open(struct inode *inode, + return 0; + } + +-static const struct file_operations minstrel_stat_fops = { +- .owner = THIS_MODULE, +- .open = minstrel_stats_open, +- .read = minstrel_stats_read, +- .release = minstrel_stats_release, +- .llseek = default_llseek, +-}; +- + int + minstrel_stats_csv_open(struct inode *inode, struct file *file) + { +@@ -200,21 +176,3 @@ minstrel_stats_csv_open(struct inode *in + + return 0; + } +- +-static const struct file_operations minstrel_stat_csv_fops = { +- .owner = THIS_MODULE, +- .open = minstrel_stats_csv_open, +- .read = minstrel_stats_read, +- .release = minstrel_stats_release, +- .llseek = default_llseek, +-}; +- +-void +-minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir) +-{ +- struct minstrel_sta_info *mi = priv_sta; +- +- debugfs_create_file("rc_stats", S_IRUGO, dir, mi, &minstrel_stat_fops); +- debugfs_create_file("rc_stats_csv", S_IRUGO, dir, mi, +- &minstrel_stat_csv_fops); +-} +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -137,12 +137,10 @@ + } \ + } + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + static bool minstrel_vht_only = true; + module_param(minstrel_vht_only, bool, 0644); + MODULE_PARM_DESC(minstrel_vht_only, + "Use only VHT rates when VHT is supported by sta."); +-#endif + + /* + * To enable sufficiently targeted rate sampling, MCS rates are divided into +@@ -171,7 +169,6 @@ const struct mcs_group minstrel_mcs_grou + + CCK_GROUP, + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + VHT_GROUP(1, 0, BW_20), + VHT_GROUP(2, 0, BW_20), + VHT_GROUP(3, 0, BW_20), +@@ -195,7 +192,6 @@ const struct mcs_group minstrel_mcs_grou + VHT_GROUP(1, 1, BW_80), + VHT_GROUP(2, 1, BW_80), + VHT_GROUP(3, 1, BW_80), +-#endif + }; + + static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; +@@ -1146,12 +1142,10 @@ minstrel_ht_update_caps(void *priv, stru + + BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB); + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + if (vht_cap->vht_supported) + use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0); + else +-#endif +- use_vht = 0; ++ use_vht = 0; + + msp->is_ht = true; + memset(mi, 0, sizeof(*mi)); +@@ -1226,10 +1220,9 @@ minstrel_ht_update_caps(void *priv, stru + + /* HT rate */ + if (gflags & IEEE80211_TX_RC_MCS) { +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + if (use_vht && minstrel_vht_only) + continue; +-#endif ++ + mi->supported[i] = mcs->rx_mask[nss - 1]; + if (mi->supported[i]) + n_supported++; +@@ -1349,16 +1342,88 @@ minstrel_ht_free_sta(void *priv, struct + kfree(msp); + } + ++static void ++minstrel_ht_init_cck_rates(struct minstrel_priv *mp) ++{ ++ 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, j = 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++) { ++ if (rate->bitrate != bitrates[j]) ++ continue; ++ ++ mp->cck_rates[j] = i; ++ break; ++ } ++ } ++} ++ + static void * + minstrel_ht_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) + { +- return mac80211_minstrel.alloc(hw, debugfsdir); ++ struct minstrel_priv *mp; ++ ++ mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC); ++ if (!mp) ++ return NULL; ++ ++ /* contention window settings ++ * Just an approximation. Using the per-queue values would complicate ++ * the calculations and is probably unnecessary */ ++ 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; ++ ++ if (hw->max_rate_tries > 0) ++ mp->max_retry = hw->max_rate_tries; ++ else ++ /* safe default, does not necessarily have to match hw properties */ ++ mp->max_retry = 7; ++ ++ if (hw->max_rates >= 4) ++ mp->has_mrr = true; ++ ++ mp->hw = hw; ++ mp->update_interval = 100; ++ ++#ifdef CPTCFG_MAC80211_DEBUGFS ++ mp->fixed_rate_idx = (u32) -1; ++ debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, ++ &mp->fixed_rate_idx); ++#endif ++ ++ minstrel_ht_init_cck_rates(mp); ++ ++ return mp; + } + + static void + minstrel_ht_free(void *priv) + { +- mac80211_minstrel.free(priv); ++ kfree(priv); + } + + static u32 minstrel_ht_get_expected_throughput(void *priv_sta) +@@ -1417,14 +1482,14 @@ static void __init init_sample_table(voi + } + + int __init +-rc80211_minstrel_ht_init(void) ++rc80211_minstrel_init(void) + { + init_sample_table(); + return ieee80211_rate_control_register(&mac80211_minstrel_ht); + } + + void +-rc80211_minstrel_ht_exit(void) ++rc80211_minstrel_exit(void) + { + ieee80211_rate_control_unregister(&mac80211_minstrel_ht); + } +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -15,11 +15,7 @@ + */ + #define MINSTREL_MAX_STREAMS 3 + #define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */ +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + #define MINSTREL_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */ +-#else +-#define MINSTREL_VHT_STREAM_GROUPS 0 +-#endif + + #define MINSTREL_HT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ + MINSTREL_HT_STREAM_GROUPS) +@@ -34,11 +30,7 @@ + #define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB) + #define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1) + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + #define MCS_GROUP_RATES 10 +-#else +-#define MCS_GROUP_RATES 8 +-#endif + + struct mcs_group { + u32 flags; +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -15,6 +15,22 @@ + #include "rc80211_minstrel.h" + #include "rc80211_minstrel_ht.h" + ++static ssize_t ++minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) ++{ ++ struct minstrel_debugfs_info *ms; ++ ++ ms = file->private_data; ++ return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len); ++} ++ ++static int ++minstrel_stats_release(struct inode *inode, struct file *file) ++{ ++ kfree(file->private_data); ++ return 0; ++} ++ + static char * + minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) + { diff --git a/package/kernel/mac80211/patches/subsys/306-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch b/package/kernel/mac80211/patches/subsys/306-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch new file mode 100644 index 0000000000..fa51f1be7e --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/306-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch @@ -0,0 +1,358 @@ +From: Felix Fietkau +Date: Sat, 10 Feb 2018 12:45:47 +0100 +Subject: [PATCH] mac80211: minstrel: reduce minstrel_mcs_groups size + +By storing a shift value for all duration values of a group, we can +reduce precision by a neglegible amount to make it fit into a u16 value. +This improves cache footprint and reduces size: + +Before: + text data bss dec hex filename + 10024 116 0 10140 279c rc80211_minstrel_ht.o + +After: + text data bss dec hex filename + 9368 116 0 9484 250c rc80211_minstrel_ht.o + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -52,22 +52,23 @@ + _streams - 1 + + /* MCS rate information for an MCS group */ +-#define MCS_GROUP(_streams, _sgi, _ht40) \ ++#define MCS_GROUP(_streams, _sgi, _ht40, _s) \ + [GROUP_IDX(_streams, _sgi, _ht40)] = { \ + .streams = _streams, \ ++ .shift = _s, \ + .flags = \ + IEEE80211_TX_RC_MCS | \ + (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ + (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ + .duration = { \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) >> _s \ + } \ + } + +@@ -80,9 +81,10 @@ + #define BW2VBPS(_bw, r3, r2, r1) \ + (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1) + +-#define VHT_GROUP(_streams, _sgi, _bw) \ ++#define VHT_GROUP(_streams, _sgi, _bw, _s) \ + [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \ + .streams = _streams, \ ++ .shift = _s, \ + .flags = \ + IEEE80211_TX_RC_VHT_MCS | \ + (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ +@@ -90,25 +92,25 @@ + _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ + .duration = { \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 117, 54, 26)), \ ++ BW2VBPS(_bw, 117, 54, 26)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 234, 108, 52)), \ ++ BW2VBPS(_bw, 234, 108, 52)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 351, 162, 78)), \ ++ BW2VBPS(_bw, 351, 162, 78)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 468, 216, 104)), \ ++ BW2VBPS(_bw, 468, 216, 104)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 702, 324, 156)), \ ++ BW2VBPS(_bw, 702, 324, 156)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 936, 432, 208)), \ ++ BW2VBPS(_bw, 936, 432, 208)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 1053, 486, 234)), \ ++ BW2VBPS(_bw, 1053, 486, 234)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 1170, 540, 260)), \ ++ BW2VBPS(_bw, 1170, 540, 260)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 1404, 648, 312)), \ ++ BW2VBPS(_bw, 1404, 648, 312)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 1560, 720, 346)) \ ++ BW2VBPS(_bw, 1560, 720, 346)) >> _s \ + } \ + } + +@@ -121,19 +123,20 @@ + (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \ + CCK_DURATION(_bitrate, _short, AVG_PKT_SIZE)) + +-#define CCK_DURATION_LIST(_short) \ +- CCK_ACK_DURATION(10, _short), \ +- CCK_ACK_DURATION(20, _short), \ +- CCK_ACK_DURATION(55, _short), \ +- CCK_ACK_DURATION(110, _short) ++#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 + +-#define CCK_GROUP \ ++#define CCK_GROUP(_s) \ + [MINSTREL_CCK_GROUP] = { \ + .streams = 0, \ + .flags = 0, \ ++ .shift = _s, \ + .duration = { \ +- CCK_DURATION_LIST(false), \ +- CCK_DURATION_LIST(true) \ ++ CCK_DURATION_LIST(false, _s), \ ++ CCK_DURATION_LIST(true, _s) \ + } \ + } + +@@ -151,47 +154,47 @@ MODULE_PARM_DESC(minstrel_vht_only, + * BW -> SGI -> #streams + */ + const struct mcs_group minstrel_mcs_groups[] = { +- MCS_GROUP(1, 0, BW_20), +- MCS_GROUP(2, 0, BW_20), +- MCS_GROUP(3, 0, BW_20), ++ MCS_GROUP(1, 0, BW_20, 5), ++ MCS_GROUP(2, 0, BW_20, 4), ++ MCS_GROUP(3, 0, BW_20, 4), + +- MCS_GROUP(1, 1, BW_20), +- MCS_GROUP(2, 1, BW_20), +- MCS_GROUP(3, 1, BW_20), ++ MCS_GROUP(1, 1, BW_20, 5), ++ MCS_GROUP(2, 1, BW_20, 4), ++ MCS_GROUP(3, 1, BW_20, 4), + +- MCS_GROUP(1, 0, BW_40), +- MCS_GROUP(2, 0, BW_40), +- MCS_GROUP(3, 0, BW_40), ++ MCS_GROUP(1, 0, BW_40, 4), ++ MCS_GROUP(2, 0, BW_40, 4), ++ MCS_GROUP(3, 0, BW_40, 4), + +- MCS_GROUP(1, 1, BW_40), +- MCS_GROUP(2, 1, BW_40), +- MCS_GROUP(3, 1, BW_40), ++ MCS_GROUP(1, 1, BW_40, 4), ++ MCS_GROUP(2, 1, BW_40, 4), ++ MCS_GROUP(3, 1, BW_40, 4), + +- CCK_GROUP, ++ CCK_GROUP(8), + +- VHT_GROUP(1, 0, BW_20), +- VHT_GROUP(2, 0, BW_20), +- VHT_GROUP(3, 0, BW_20), ++ VHT_GROUP(1, 0, BW_20, 5), ++ VHT_GROUP(2, 0, BW_20, 4), ++ VHT_GROUP(3, 0, BW_20, 4), + +- VHT_GROUP(1, 1, BW_20), +- VHT_GROUP(2, 1, BW_20), +- VHT_GROUP(3, 1, BW_20), ++ VHT_GROUP(1, 1, BW_20, 5), ++ VHT_GROUP(2, 1, BW_20, 4), ++ VHT_GROUP(3, 1, BW_20, 4), + +- VHT_GROUP(1, 0, BW_40), +- VHT_GROUP(2, 0, BW_40), +- VHT_GROUP(3, 0, BW_40), ++ VHT_GROUP(1, 0, BW_40, 4), ++ VHT_GROUP(2, 0, BW_40, 4), ++ VHT_GROUP(3, 0, BW_40, 4), + +- VHT_GROUP(1, 1, BW_40), +- VHT_GROUP(2, 1, BW_40), +- VHT_GROUP(3, 1, BW_40), ++ VHT_GROUP(1, 1, BW_40, 4), ++ VHT_GROUP(2, 1, BW_40, 4), ++ VHT_GROUP(3, 1, BW_40, 4), + +- VHT_GROUP(1, 0, BW_80), +- VHT_GROUP(2, 0, BW_80), +- VHT_GROUP(3, 0, BW_80), ++ VHT_GROUP(1, 0, BW_80, 4), ++ VHT_GROUP(2, 0, BW_80, 4), ++ VHT_GROUP(3, 0, BW_80, 4), + +- VHT_GROUP(1, 1, BW_80), +- VHT_GROUP(2, 1, BW_80), +- VHT_GROUP(3, 1, BW_80), ++ VHT_GROUP(1, 1, BW_80, 4), ++ VHT_GROUP(2, 1, BW_80, 4), ++ VHT_GROUP(3, 1, BW_80, 4), + }; + + static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; +@@ -307,7 +310,8 @@ minstrel_ht_get_tp_avg(struct minstrel_h + if (group != MINSTREL_CCK_GROUP) + nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); + +- nsecs += minstrel_mcs_groups[group].duration[rate]; ++ nsecs += minstrel_mcs_groups[group].duration[rate] << ++ minstrel_mcs_groups[group].shift; + + /* + * For the throughput calculation, limit the probability value to 90% to +@@ -755,12 +759,19 @@ minstrel_ht_tx_status(void *priv, struct + minstrel_ht_update_rates(mp, mi); + } + ++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 void + minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, + int index) + { + struct minstrel_rate_stats *mrs; +- const struct mcs_group *group; + unsigned int tx_time, tx_time_rtscts, tx_time_data; + unsigned int cw = mp->cw_min; + unsigned int ctime = 0; +@@ -779,8 +790,7 @@ minstrel_calc_retransmit(struct minstrel + mrs->retry_count_rtscts = 2; + mrs->retry_updated = true; + +- group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +- tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000; ++ tx_time_data = minstrel_get_duration(index) * ampdu_len / 1000; + + /* Contention time for first 2 tries */ + ctime = (t_slot * cw) >> 1; +@@ -874,20 +884,24 @@ minstrel_ht_get_max_amsdu_len(struct min + int group = mi->max_prob_rate / MCS_GROUP_RATES; + const struct mcs_group *g = &minstrel_mcs_groups[group]; + int rate = mi->max_prob_rate % MCS_GROUP_RATES; ++ unsigned int duration; + + /* Disable A-MSDU if max_prob_rate is bad */ + if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100)) + return 1; + ++ duration = g->duration[rate]; ++ duration <<= g->shift; ++ + /* If the rate is slower than single-stream MCS1, make A-MSDU limit small */ +- if (g->duration[rate] > MCS_DURATION(1, 0, 52)) ++ if (duration > MCS_DURATION(1, 0, 52)) + return 500; + + /* + * If the rate is slower than single-stream MCS4, limit A-MSDU to usual + * data packet size + */ +- if (g->duration[rate] > MCS_DURATION(1, 0, 104)) ++ if (duration > MCS_DURATION(1, 0, 104)) + return 1600; + + /* +@@ -895,7 +909,7 @@ minstrel_ht_get_max_amsdu_len(struct min + * rate success probability is less than 75%, limit A-MSDU to twice the usual + * data packet size + */ +- if (g->duration[rate] > MCS_DURATION(1, 0, 260) || ++ if (duration > MCS_DURATION(1, 0, 260) || + (minstrel_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) < + MINSTREL_FRAC(75, 100))) + return 3200; +@@ -942,13 +956,6 @@ minstrel_ht_update_rates(struct minstrel + rate_control_set_rates(mp->hw, mi->sta, rates); + } + +-static inline int +-minstrel_get_duration(int index) +-{ +- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +- return group->duration[index % MCS_GROUP_RATES]; +-} +- + static int + minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) + { +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -33,9 +33,10 @@ + #define MCS_GROUP_RATES 10 + + struct mcs_group { +- u32 flags; +- unsigned int streams; +- unsigned int duration[MCS_GROUP_RATES]; ++ u16 flags; ++ u8 streams; ++ u8 shift; ++ u16 duration[MCS_GROUP_RATES]; + }; + + extern const struct mcs_group minstrel_mcs_groups[]; +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -58,6 +58,7 @@ minstrel_ht_stats_dump(struct minstrel_h + static const int bitrates[4] = { 10, 20, 55, 110 }; + int idx = i * MCS_GROUP_RATES + j; + unsigned int prob_ewmsd; ++ unsigned int duration; + + if (!(mi->supported[i] & BIT(j))) + continue; +@@ -95,7 +96,9 @@ minstrel_ht_stats_dump(struct minstrel_h + p += sprintf(p, " %3u ", idx); + + /* tx_time[rate(i)] in usec */ +- tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000); ++ duration = mg->duration[j]; ++ duration <<= mg->shift; ++ tx_time = DIV_ROUND_CLOSEST(duration, 1000); + p += sprintf(p, "%6u ", tx_time); + + tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); +@@ -204,6 +207,7 @@ minstrel_ht_stats_csv_dump(struct minstr + static const int bitrates[4] = { 10, 20, 55, 110 }; + int idx = i * MCS_GROUP_RATES + j; + unsigned int prob_ewmsd; ++ unsigned int duration; + + if (!(mi->supported[i] & BIT(j))) + continue; +@@ -238,7 +242,10 @@ minstrel_ht_stats_csv_dump(struct minstr + } + + p += sprintf(p, "%u,", idx); +- tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000); ++ ++ duration = mg->duration[j]; ++ duration <<= mg->shift; ++ tx_time = DIV_ROUND_CLOSEST(duration, 1000); + p += sprintf(p, "%u,", tx_time); + + tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); diff --git a/package/kernel/mac80211/patches/subsys/307-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch b/package/kernel/mac80211/patches/subsys/307-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch new file mode 100644 index 0000000000..502d8c7768 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/307-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch @@ -0,0 +1,31 @@ +From: Felix Fietkau +Date: Sat, 10 Feb 2018 13:43:07 +0100 +Subject: [PATCH] mac80211: minstrel: fix using short preamble CCK rates on + HT clients + +mi->supported[MINSTREL_CCK_GROUP] needs to be updated + +Fixes: 782dda00ab8e ("mac80211: minstrel_ht: move short preamble check out of get_rate") +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1135,7 +1135,6 @@ 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; +- struct sta_info *sinfo = container_of(sta, struct sta_info, sta); + int use_vht; + int n_supported = 0; + int ack_dur; +@@ -1267,8 +1266,7 @@ minstrel_ht_update_caps(void *priv, stru + if (!n_supported) + goto use_legacy; + +- if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE)) +- mi->cck_supported_short |= mi->cck_supported_short << 4; ++ 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); diff --git a/package/kernel/mac80211/patches/subsys/308-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch b/package/kernel/mac80211/patches/subsys/308-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch new file mode 100644 index 0000000000..f0ffcd9655 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/308-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch @@ -0,0 +1,20 @@ +From: Felix Fietkau +Date: Thu, 1 Mar 2018 13:27:54 +0100 +Subject: [PATCH] mac80211: minstrel: fix CCK rate group streams value + +Fixes a harmless underflow issue when CCK rates are actively being used + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -131,7 +131,7 @@ + + #define CCK_GROUP(_s) \ + [MINSTREL_CCK_GROUP] = { \ +- .streams = 0, \ ++ .streams = 1, \ + .flags = 0, \ + .shift = _s, \ + .duration = { \ diff --git a/package/kernel/mac80211/patches/subsys/309-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch b/package/kernel/mac80211/patches/subsys/309-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch new file mode 100644 index 0000000000..e0049c36eb --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/309-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch @@ -0,0 +1,58 @@ +From: Felix Fietkau +Date: Thu, 1 Mar 2018 13:28:48 +0100 +Subject: [PATCH] mac80211: minstrel: fix sampling/reporting of CCK rates + in HT mode + +Long/short preamble selection cannot be sampled separately, since it +depends on the BSS state. Because of that, sampling attempts to +currently not used preamble modes are not counted in the statistics, +which leads to CCK rates being sampled too often. + +Fix statistics accounting for long/short preamble by increasing the +index where necessary. +Fix excessive CCK rate sampling by dropping unsupported sample attempts. + +This improves throughput on 2.4 GHz channels + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -281,7 +281,8 @@ minstrel_ht_get_stats(struct minstrel_pr + break; + + /* short preamble */ +- if (!(mi->supported[group] & BIT(idx))) ++ if ((mi->supported[group] & BIT(idx + 4)) && ++ (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) + idx += 4; + } + return &mi->groups[group].rates[idx]; +@@ -1080,18 +1081,23 @@ minstrel_ht_get_rate(void *priv, struct + return; + + sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES]; ++ sample_idx %= MCS_GROUP_RATES; ++ ++ if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP] && ++ (sample_idx >= 4) != txrc->short_preamble) ++ return; ++ + info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; + rate->count = 1; + +- if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { ++ 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->flags & IEEE80211_TX_RC_VHT_MCS) { + ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES, + sample_group->streams); + } else { +- rate->idx = sample_idx % MCS_GROUP_RATES + +- (sample_group->streams - 1) * 8; ++ rate->idx = sample_idx + (sample_group->streams - 1) * 8; + } + + rate->flags = sample_group->flags; diff --git a/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch b/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch new file mode 100644 index 0000000000..414cb137de --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch @@ -0,0 +1,40 @@ +From: Felix Fietkau +Date: Sat, 3 Mar 2018 18:48:58 +0100 +Subject: [PATCH] mac80211: minstrel: do not sample rates 3 times slower than + max_prob_rate + +These rates are highly unlikely to be used quickly, even if the link +deteriorates rapidly. This improves throughput in cases where CCK rates +are not reliable enough to be skipped entirely during sampling. +Sampling these rates regularly can cost a lot of airtime. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1004,10 +1004,13 @@ minstrel_get_sample_rate(struct minstrel + return -1; + + /* +- * Do not sample if the probability is already higher than 95% +- * to avoid wasting airtime. ++ * Do not sample if the probability is already higher than 95%, ++ * or if the rate is 3 times slower than the current max probability ++ * rate, to avoid wasting airtime. + */ +- if (mrs->prob_ewma > MINSTREL_FRAC(95, 100)) ++ sample_dur = minstrel_get_duration(sample_idx); ++ if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) || ++ minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur) + return -1; + + /* +@@ -1017,7 +1020,6 @@ minstrel_get_sample_rate(struct minstrel + + cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 / + MCS_GROUP_RATES].streams; +- sample_dur = minstrel_get_duration(sample_idx); + if (sample_dur >= minstrel_get_duration(tp_rate2) && + (cur_max_tp_streams - 1 < + minstrel_mcs_groups[sample_group].streams || diff --git a/package/kernel/mac80211/patches/subsys/311-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch b/package/kernel/mac80211/patches/subsys/311-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch new file mode 100644 index 0000000000..1fd2b25271 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/311-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch @@ -0,0 +1,58 @@ +From: Felix Fietkau +Date: Thu, 8 Mar 2018 21:00:56 +0100 +Subject: [PATCH] mac80211: fix memory accounting with A-MSDU aggregation + +fq uses skb->truesize for memory usage tracking. Increments/decrements +are done on enqueue/dequeue. +When A-MSDU aggregation is performed on tx side, the packet is +aggregated with the last packet in the queue belonging to the same flow. +There are multiple bugs here: +- The truesize field of the aggregated packet isn't updated, so memory +usage is underestimated +- fq->memory_usage isn't adjusted. + +Because of the combination of both bugs, this only causes tx issues in +rare cases, mainly when the A-MSDU head needs to be reallocated. + +Fix this by adjusting both truesize of the A-MSDU head and adding the +truesize delta to fq->memory_usage. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3185,6 +3185,7 @@ static bool ieee80211_amsdu_aggregate(st + u8 max_subframes = sta->sta.max_amsdu_subframes; + int max_frags = local->hw.max_tx_fragments; + int max_amsdu_len = sta->sta.max_amsdu_len; ++ int orig_truesize; + __be16 len; + void *data; + bool ret = false; +@@ -3216,12 +3217,13 @@ static bool ieee80211_amsdu_aggregate(st + flow = fq_flow_classify(fq, tin, skb, fq_flow_get_default_func); + head = skb_peek_tail(&flow->queue); + if (!head) +- goto out; ++ goto unlock; + ++ orig_truesize = head->truesize; + orig_len = head->len; + + if (skb->len + head->len > max_amsdu_len) +- goto out; ++ goto unlock; + + nfrags = 1 + skb_shinfo(skb)->nr_frags; + nfrags += 1 + skb_shinfo(head)->nr_frags; +@@ -3279,6 +3281,9 @@ out_recalc: + fq_recalc_backlog(fq, tin, flow); + } + out: ++ fq->memory_usage += head->truesize - orig_truesize; ++ ++unlock: + spin_unlock_bh(&fq->lock); + + return ret; diff --git a/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch b/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch new file mode 100644 index 0000000000..f221d36bf8 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch @@ -0,0 +1,122 @@ +From: Felix Fietkau +Date: Wed, 16 Jan 2019 22:32:12 +0100 +Subject: [PATCH] mac80211: minstrel_ht: add flag to indicate + missing/inaccurate tx A-MPDU length + +Some hardware (e.g. MediaTek MT7603) cannot report A-MPDU length in tx status +information. Add support for a flag to indicate that, to allow minstrel_ht +to use a fixed value in its internal calculation (which gives better results +than just defaulting to 1). + +Signed-off-by: Felix Fietkau +Signed-off-by: Johannes Berg +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2131,6 +2131,9 @@ struct ieee80211_txq { + * @IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP: The driver (or firmware) doesn't + * support QoS NDP for AP probing - that's most likely a driver bug. + * ++ * @IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN: Driver does not report accurate A-MPDU ++ * length in tx status information ++ * + * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays + */ + enum ieee80211_hw_flags { +@@ -2176,6 +2179,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA, + IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP, + IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP, ++ IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -214,6 +214,7 @@ static const char *hw_flag_names[] = { + FLAG(SUPPORTS_TDLS_BUFFER_STA), + FLAG(DEAUTH_NEED_MGD_TX_PREP), + FLAG(DOESNT_SUPPORT_QOS_NDP), ++ FLAG(TX_STATUS_NO_AMPDU_LEN), + #undef FLAG + }; + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -294,6 +294,15 @@ minstrel_get_ratestats(struct minstrel_h + return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES]; + } + ++static unsigned int ++minstrel_ht_avg_ampdu_len(struct minstrel_ht_sta *mi) ++{ ++ if (!mi->avg_ampdu_len) ++ return AVG_AMPDU_SIZE; ++ ++ return MINSTREL_TRUNC(mi->avg_ampdu_len); ++} ++ + /* + * Return current throughput based on the average A-MPDU length, taking into + * account the expected number of retransmissions and their expected length +@@ -309,7 +318,7 @@ minstrel_ht_get_tp_avg(struct minstrel_h + return 0; + + if (group != MINSTREL_CCK_GROUP) +- nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); ++ nsecs = 1000 * mi->overhead / minstrel_ht_avg_ampdu_len(mi); + + nsecs += minstrel_mcs_groups[group].duration[rate] << + minstrel_mcs_groups[group].shift; +@@ -503,8 +512,12 @@ minstrel_ht_update_stats(struct minstrel + u16 tmp_cck_tp_rate[MAX_THR_RATES], index; + + if (mi->ampdu_packets > 0) { +- mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, +- MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), EWMA_LEVEL); ++ if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN)) ++ mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, ++ MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), ++ EWMA_LEVEL); ++ else ++ mi->avg_ampdu_len = 0; + mi->ampdu_len = 0; + mi->ampdu_packets = 0; + } +@@ -709,7 +722,9 @@ minstrel_ht_tx_status(void *priv, struct + mi->ampdu_len += info->status.ampdu_len; + + if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) { +- mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len); ++ int avg_ampdu_len = minstrel_ht_avg_ampdu_len(mi); ++ ++ mi->sample_wait = 16 + 2 * avg_ampdu_len; + mi->sample_tries = 1; + mi->sample_count--; + } +@@ -777,7 +792,7 @@ minstrel_calc_retransmit(struct minstrel + unsigned int cw = mp->cw_min; + unsigned int ctime = 0; + unsigned int t_slot = 9; /* FIXME */ +- unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len); ++ unsigned int ampdu_len = minstrel_ht_avg_ampdu_len(mi); + unsigned int overhead = 0, overhead_rtscts = 0; + + mrs = minstrel_get_ratestats(mi, index); +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -163,9 +163,10 @@ minstrel_ht_stats_open(struct inode *ino + "lookaround %d\n", + max(0, (int) mi->total_packets - (int) mi->sample_packets), + mi->sample_packets); +- p += sprintf(p, "Average # of aggregated frames per A-MPDU: %d.%d\n", +- MINSTREL_TRUNC(mi->avg_ampdu_len), +- MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); ++ if (mi->avg_ampdu_len) ++ p += sprintf(p, "Average # of aggregated frames per A-MPDU: %d.%d\n", ++ MINSTREL_TRUNC(mi->avg_ampdu_len), ++ MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); + ms->len = p - ms->buf; + WARN_ON(ms->len + sizeof(*ms) > 32768); + diff --git a/package/kernel/mac80211/patches/subsys/350-mac80211-add-hdrlen-to-ieee80211_tx_data.patch b/package/kernel/mac80211/patches/subsys/350-mac80211-add-hdrlen-to-ieee80211_tx_data.patch new file mode 100644 index 0000000000..0dfd0fbcfe --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/350-mac80211-add-hdrlen-to-ieee80211_tx_data.patch @@ -0,0 +1,228 @@ +From: Janusz Dziedzic +Date: Fri, 19 Feb 2016 11:01:49 +0100 +Subject: [PATCH] mac80211: add hdrlen to ieee80211_tx_data + +This is preparation for adding support for inserting padding between the +802.11 header and LLC data + +Signed-off-by: Janusz Dziedzic +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -179,6 +179,7 @@ struct ieee80211_tx_data { + struct ieee80211_tx_rate rate; + + unsigned int flags; ++ unsigned int hdrlen; + }; + + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -925,7 +925,7 @@ ieee80211_tx_h_fragment(struct ieee80211 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; + int frag_threshold = tx->local->hw.wiphy->frag_threshold; +- int hdrlen; ++ int hdrlen = tx->hdrlen; + int fragnum; + + /* no matter what happens, tx->skb moves to tx->skbs */ +@@ -946,8 +946,6 @@ ieee80211_tx_h_fragment(struct ieee80211 + if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) + return TX_DROP; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); +- + /* internal error, why isn't DONTFRAG set? */ + if (WARN_ON(skb->len + FCS_LEN <= frag_threshold)) + return TX_DROP; +@@ -1178,6 +1176,8 @@ ieee80211_tx_prepare(struct ieee80211_su + + hdr = (struct ieee80211_hdr *) skb->data; + ++ tx->hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ + if (likely(sta)) { + if (!IS_ERR(sta)) + tx->sta = sta; +@@ -3518,6 +3518,7 @@ begin: + tx.local = local; + tx.skb = skb; + tx.sdata = vif_to_sdata(info->control.vif); ++ tx.hdrlen = ieee80211_hdrlen(hdr->frame_control); + + if (txq->sta) + tx.sta = container_of(txq->sta, struct sta_info, sta); +@@ -3544,7 +3545,7 @@ begin: + + if (tx.key && + (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) +- pn_offs = ieee80211_hdrlen(hdr->frame_control); ++ pn_offs = tx.hdrlen; + + ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs, + tx.key, skb); +@@ -3855,6 +3856,7 @@ ieee80211_build_data_template(struct iee + hdr = (void *)skb->data; + tx.sta = sta_info_get(sdata, hdr->addr1); + tx.skb = skb; ++ tx.hdrlen = ieee80211_hdrlen(hdr->frame_control); + + if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) { + rcu_read_unlock(); +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1390,6 +1390,7 @@ void ieee80211_send_auth(struct ieee8021 + struct ieee80211_local *local = sdata->local; + struct sk_buff *skb; + struct ieee80211_mgmt *mgmt; ++ unsigned int hdrlen; + int err; + + /* 24 + 6 = header + auth_algo + auth_transaction + status_code */ +@@ -1413,8 +1414,10 @@ void ieee80211_send_auth(struct ieee8021 + skb_put_data(skb, extra, extra_len); + + if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { ++ hdrlen = ieee80211_hdrlen(mgmt->frame_control); + mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); +- err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx); ++ err = ieee80211_wep_encrypt(local, skb, hdrlen, key, ++ key_len, key_idx); + WARN_ON(err); + } + +--- a/net/mac80211/wep.c ++++ b/net/mac80211/wep.c +@@ -89,11 +89,11 @@ static void ieee80211_wep_get_iv(struct + + static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, + struct sk_buff *skb, ++ unsigned int hdrlen, + int keylen, int keyidx) + { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +- unsigned int hdrlen; + u8 *newhdr; + + hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); +@@ -101,7 +101,6 @@ static u8 *ieee80211_wep_add_iv(struct i + if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN)) + return NULL; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); + newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN); + memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen); + +@@ -160,6 +159,7 @@ int ieee80211_wep_encrypt_data(struct cr + */ + int ieee80211_wep_encrypt(struct ieee80211_local *local, + struct sk_buff *skb, ++ unsigned int hdrlen, + const u8 *key, int keylen, int keyidx) + { + u8 *iv; +@@ -169,7 +169,7 @@ int ieee80211_wep_encrypt(struct ieee802 + if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN)) + return -1; + +- iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx); ++ iv = ieee80211_wep_add_iv(local, skb, hdrlen, keylen, keyidx); + if (!iv) + return -1; + +@@ -307,13 +307,14 @@ static int wep_encrypt_skb(struct ieee80 + struct ieee80211_key_conf *hw_key = info->control.hw_key; + + if (!hw_key) { +- if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key, ++ if (ieee80211_wep_encrypt(tx->local, skb, tx->hdrlen, ++ tx->key->conf.key, + tx->key->conf.keylen, + tx->key->conf.keyidx)) + return -1; + } else if ((hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) || + (hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { +- if (!ieee80211_wep_add_iv(tx->local, skb, ++ if (!ieee80211_wep_add_iv(tx->local, skb, tx->hdrlen, + tx->key->conf.keylen, + tx->key->conf.keyidx)) + return -1; +--- a/net/mac80211/wep.h ++++ b/net/mac80211/wep.h +@@ -22,6 +22,7 @@ int ieee80211_wep_encrypt_data(struct cr + size_t klen, u8 *data, size_t data_len); + int ieee80211_wep_encrypt(struct ieee80211_local *local, + struct sk_buff *skb, ++ unsigned int hdrlen, + const u8 *key, int keylen, int keyidx); + int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, + size_t klen, u8 *data, size_t data_len); +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -44,7 +44,7 @@ ieee80211_tx_h_michael_mic_add(struct ie + skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control)) + return TX_CONTINUE; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + if (skb->len < hdrlen) + return TX_DROP; + +@@ -195,7 +195,6 @@ mic_fail_no_key: + + static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct ieee80211_key *key = tx->key; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + unsigned int hdrlen; +@@ -210,7 +209,7 @@ static int tkip_encrypt_skb(struct ieee8 + return 0; + } + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + len = skb->len - hdrlen; + + if (info->control.hw_key) +@@ -428,7 +427,7 @@ static int ccmp_encrypt_skb(struct ieee8 + return 0; + } + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + len = skb->len - hdrlen; + + if (info->control.hw_key) +@@ -660,7 +659,7 @@ static int gcmp_encrypt_skb(struct ieee8 + return 0; + } + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + len = skb->len - hdrlen; + + if (info->control.hw_key) +@@ -800,7 +799,6 @@ static ieee80211_tx_result + ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx, + struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_key *key = tx->key; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + int hdrlen; +@@ -816,8 +814,7 @@ ieee80211_crypto_cs_encrypt(struct ieee8 + pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC))) + return TX_DROP; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); +- ++ hdrlen = tx->hdrlen; + pos = skb_push(skb, iv_len); + memmove(pos, pos + iv_len, hdrlen); + diff --git a/package/kernel/mac80211/patches/subsys/351-mac80211-add-TX_NEEDS_ALIGNED4_SKBS-hw-flag.patch b/package/kernel/mac80211/patches/subsys/351-mac80211-add-TX_NEEDS_ALIGNED4_SKBS-hw-flag.patch new file mode 100644 index 0000000000..352246d592 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/351-mac80211-add-TX_NEEDS_ALIGNED4_SKBS-hw-flag.patch @@ -0,0 +1,304 @@ +From: Janusz Dziedzic +Date: Sun, 10 Mar 2019 17:22:08 +0100 +Subject: [PATCH] mac80211: add TX_NEEDS_ALIGNED4_SKBS hw flag + +The driver should set this flag if the hardware requires tx skb data +(starting with the LLC header) to be aligned to 4 bytes. + +Padding is added after ieee80211_hdr, before IV/LLC. + +Before this patch, we have to do memmove(hdrlen) twice in the driver: +Once before we pass this to HW and once again in tx completion +(to fix up the skb for monitor mode). + +With this patch we can skip this memmove() and thus reduce CPU cycles in +the data path. + +Signed-off-by: Janusz Dziedzic +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2134,6 +2134,9 @@ struct ieee80211_txq { + * @IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN: Driver does not report accurate A-MPDU + * length in tx status information + * ++ * @IEEE80211_HW_TX_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte. ++ * Padding will be added after ieee80211_hdr, before IV/LLC. ++ * + * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays + */ + enum ieee80211_hw_flags { +@@ -2180,6 +2183,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP, + IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP, + IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN, ++ IEEE80211_HW_TX_NEEDS_ALIGNED4_SKBS, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +@@ -2462,6 +2466,40 @@ ieee80211_get_alt_retry_rate(const struc + void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); + + /** ++ * ieee80211_hdr_padsize - get size of padding between 802.11 header and LLC ++ * @hw: the hardware ++ * @hdrlen: 802.11 header length ++ */ ++static inline unsigned int ++ieee80211_hdr_padsize(struct ieee80211_hw *hw, unsigned int hdrlen) ++{ ++ /* ++ * While hdrlen is already aligned to two-byte boundaries, ++ * simple check with & 2 will return correct padsize. ++ */ ++ if (ieee80211_hw_check(hw, TX_NEEDS_ALIGNED4_SKBS)) ++ return hdrlen & 2; ++ return 0; ++} ++ ++/** ++ * ieee80211_padded_hdrlen - get padded 802.11 header size ++ * @hw: the hardware ++ * @fc: frame control field in little-endian format ++ */ ++static inline unsigned int ++ieee80211_padded_hdrlen(struct ieee80211_hw *hw, __le16 fc) ++{ ++ unsigned int hdrlen; ++ ++ hdrlen = ieee80211_hdrlen(fc); ++ hdrlen += ieee80211_hdr_padsize(hw, hdrlen); ++ ++ return hdrlen; ++} ++ ++ ++/** + * DOC: Hardware crypto acceleration + * + * mac80211 is capable of taking advantage of many hardware +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -1871,6 +1871,10 @@ int ieee80211_if_add(struct ieee80211_lo + + 8 /* rfc1042/bridge tunnel */ + - ETH_HLEN /* ethernet hard_header_len */ + + IEEE80211_ENCRYPT_HEADROOM; ++ ++ if (ieee80211_hw_check(&local->hw, TX_NEEDS_ALIGNED4_SKBS)) ++ ndev->needed_headroom += 2; /* padding */ ++ + ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; + + ret = dev_alloc_name(ndev, ndev->name); +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -103,13 +103,15 @@ void mesh_path_assign_nexthop(struct mes + static void prepare_for_gate(struct sk_buff *skb, char *dst_addr, + struct mesh_path *gate_mpath) + { ++ struct ieee80211_sub_if_data *sdata = gate_mpath->sdata; ++ struct ieee80211_hw *hw = &sdata->local->hw; + struct ieee80211_hdr *hdr; + struct ieee80211s_hdr *mshdr; + int mesh_hdrlen, hdrlen; + char *next_hop; + + hdr = (struct ieee80211_hdr *) skb->data; +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = ieee80211_padded_hdrlen(hw, hdr->frame_control); + mshdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); + + if (!(mshdr->flags & MESH_FLAGS_AE)) { +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2597,7 +2597,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 + struct ieee80211_local *local = rx->local; + struct ieee80211_sub_if_data *sdata = rx->sdata; + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; +- u16 ac, q, hdrlen; ++ u16 ac, q, hdrlen, padsize; + int tailroom = 0; + + hdr = (struct ieee80211_hdr *) skb->data; +@@ -2688,7 +2688,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 + if (sdata->crypto_tx_tailroom_needed_cnt) + tailroom = IEEE80211_ENCRYPT_TAILROOM; + +- fwd_skb = skb_copy_expand(skb, local->tx_headroom + ++ padsize = ieee80211_hdr_padsize(&local->hw, hdrlen); ++ ++ fwd_skb = skb_copy_expand(skb, local->tx_headroom + padsize + + sdata->encrypt_headroom, + tailroom, GFP_ATOMIC); + if (!fwd_skb) +@@ -2720,6 +2722,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 + return RX_DROP_MONITOR; + } + ++ if (padsize) { ++ skb_push(fwd_skb, padsize); ++ memmove(fwd_skb->data, skb->data + padsize, hdrlen); ++ memset(fwd_skb->data + hdrlen, 0, padsize); ++ } ++ + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); + ieee80211_add_pending_skb(local, fwd_skb); + out: +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -301,7 +301,7 @@ struct ieee80211_fast_tx { + u8 hdr_len; + u8 sa_offs, da_offs, pn_offs; + u8 band; +- u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV + ++ u8 hdr[30 + 2 + 2 + IEEE80211_FAST_XMIT_MAX_IV + + sizeof(rfc1042_header)] __aligned(2); + + struct rcu_head rcu_head; +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -515,6 +515,7 @@ static void ieee80211_report_used_skb(st + { + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; ++ struct ieee80211_hw *hw = &local->hw; + bool acked = info->flags & IEEE80211_TX_STAT_ACK; + + if (dropped) +@@ -531,7 +532,7 @@ static void ieee80211_report_used_skb(st + skb->dev = NULL; + } else { + unsigned int hdr_size = +- ieee80211_hdrlen(hdr->frame_control); ++ ieee80211_padded_hdrlen(hw, hdr->frame_control); + + /* Check to see if packet is a TDLS teardown packet */ + if (ieee80211_is_data(hdr->frame_control) && +@@ -655,9 +656,22 @@ void ieee80211_tx_monitor(struct ieee802 + struct sk_buff *skb2; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_sub_if_data *sdata; ++ struct ieee80211_hdr *hdr = (void *)skb->data; + struct net_device *prev_dev = NULL; ++ unsigned int hdrlen, padsize; + int rtap_len; + ++ /* Remove padding if was added */ ++ if (ieee80211_hw_check(&local->hw, TX_NEEDS_ALIGNED4_SKBS)) { ++ hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ padsize = ieee80211_hdr_padsize(&local->hw, hdrlen); ++ ++ if (padsize && skb->len > hdrlen + padsize) { ++ memmove(skb->data + padsize, skb->data, hdrlen); ++ skb_pull(skb, padsize); ++ } ++ } ++ + /* send frame to monitor interfaces now */ + rtap_len = ieee80211_tx_radiotap_len(info); + if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { +--- a/net/mac80211/tkip.c ++++ b/net/mac80211/tkip.c +@@ -201,10 +201,12 @@ void ieee80211_get_tkip_p2k(struct ieee8 + { + struct ieee80211_key *key = (struct ieee80211_key *) + container_of(keyconf, struct ieee80211_key, conf); ++ struct ieee80211_hw *hw = &key->local->hw; + const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; + struct tkip_ctx *ctx = &key->u.tkip.tx; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; +- const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); ++ const u8 *data = (u8 *)hdr + ieee80211_padded_hdrlen(hw, ++ hdr->frame_control); + u32 iv32 = get_unaligned_le32(&data[4]); + u16 iv16 = data[2] | (data[0] << 8); + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1175,8 +1175,7 @@ ieee80211_tx_prepare(struct ieee80211_su + info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING; + + hdr = (struct ieee80211_hdr *) skb->data; +- +- tx->hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ tx->hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control); + + if (likely(sta)) { + if (!IS_ERR(sta)) +@@ -2215,7 +2214,7 @@ netdev_tx_t ieee80211_monitor_start_xmit + goto fail; + + hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control); + + if (skb->len < len_rthdr + hdrlen) + goto fail; +@@ -2433,7 +2432,7 @@ static struct sk_buff *ieee80211_build_h + struct ieee80211_chanctx_conf *chanctx_conf; + struct ieee80211_sub_if_data *ap_sdata; + enum nl80211_band band; +- int ret; ++ int padsize, ret; + + if (IS_ERR(sta)) + sta = NULL; +@@ -2732,7 +2731,9 @@ static struct sk_buff *ieee80211_build_h + } + + skb_pull(skb, skip_header_bytes); ++ padsize = ieee80211_hdr_padsize(&local->hw, hdrlen); + head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb); ++ head_need += padsize; + + /* + * So we need to modify the skb header and hence need a copy of +@@ -2765,6 +2766,9 @@ static struct sk_buff *ieee80211_build_h + memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen); + #endif + ++ if (padsize) ++ memset(skb_push(skb, padsize), 0, padsize); ++ + if (ieee80211_is_data_qos(fc)) { + __le16 *qos_control; + +@@ -2940,6 +2944,8 @@ void ieee80211_check_fast_xmit(struct st + fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); + } + ++ build.hdr_len += ieee80211_hdr_padsize(&local->hw, build.hdr_len); ++ + /* We store the key here so there's no point in using rcu_dereference() + * but that's fine because the code that changes the pointers will call + * this function after doing so. For a single CPU that would be enough, +@@ -3518,7 +3524,7 @@ begin: + tx.local = local; + tx.skb = skb; + tx.sdata = vif_to_sdata(info->control.vif); +- tx.hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ tx.hdrlen = ieee80211_padded_hdrlen(hw, hdr->frame_control); + + if (txq->sta) + tx.sta = container_of(txq->sta, struct sta_info, sta); +@@ -3856,7 +3862,7 @@ ieee80211_build_data_template(struct iee + hdr = (void *)skb->data; + tx.sta = sta_info_get(sdata, hdr->addr1); + tx.skb = skb; +- tx.hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ tx.hdrlen = ieee80211_padded_hdrlen(&tx.local->hw, hdr->frame_control); + + if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) { + rcu_read_unlock(); +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -215,6 +215,7 @@ static const char *hw_flag_names[] = { + FLAG(DEAUTH_NEED_MGD_TX_PREP), + FLAG(DOESNT_SUPPORT_QOS_NDP), + FLAG(TX_STATUS_NO_AMPDU_LEN), ++ FLAG(TX_NEEDS_ALIGNED4_SKBS), + #undef FLAG + }; + diff --git a/package/kernel/mac80211/patches/subsys/357-mac80211-add-hdrlen-to-ieee80211_tx_data.patch b/package/kernel/mac80211/patches/subsys/357-mac80211-add-hdrlen-to-ieee80211_tx_data.patch deleted file mode 100644 index 2914461b41..0000000000 --- a/package/kernel/mac80211/patches/subsys/357-mac80211-add-hdrlen-to-ieee80211_tx_data.patch +++ /dev/null @@ -1,219 +0,0 @@ -From: Janusz Dziedzic -Date: Fri, 19 Feb 2016 11:01:49 +0100 -Subject: [PATCH] mac80211: add hdrlen to ieee80211_tx_data - -Add hdrlen to ieee80211_tx_data and use this -when wep/ccmd/tkip. This is preparation for -aligned4 code. - -Signed-off-by: Janusz Dziedzic ---- - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -179,6 +179,7 @@ struct ieee80211_tx_data { - struct ieee80211_tx_rate rate; - - unsigned int flags; -+ unsigned int hdrlen; - }; - - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -925,7 +925,7 @@ ieee80211_tx_h_fragment(struct ieee80211 - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_hdr *hdr = (void *)skb->data; - int frag_threshold = tx->local->hw.wiphy->frag_threshold; -- int hdrlen; -+ int hdrlen = tx->hdrlen; - int fragnum; - - /* no matter what happens, tx->skb moves to tx->skbs */ -@@ -946,8 +946,6 @@ ieee80211_tx_h_fragment(struct ieee80211 - if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) - return TX_DROP; - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -- - /* internal error, why isn't DONTFRAG set? */ - if (WARN_ON(skb->len + FCS_LEN <= frag_threshold)) - return TX_DROP; -@@ -1178,6 +1176,8 @@ ieee80211_tx_prepare(struct ieee80211_su - - hdr = (struct ieee80211_hdr *) skb->data; - -+ tx->hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ - if (likely(sta)) { - if (!IS_ERR(sta)) - tx->sta = sta; -@@ -3513,6 +3513,7 @@ begin: - tx.local = local; - tx.skb = skb; - tx.sdata = vif_to_sdata(info->control.vif); -+ tx.hdrlen = ieee80211_padded_hdrlen(hw, hdr->frame_control); - - if (txq->sta) - tx.sta = container_of(txq->sta, struct sta_info, sta); -@@ -3850,6 +3851,7 @@ ieee80211_build_data_template(struct iee - hdr = (void *)skb->data; - tx.sta = sta_info_get(sdata, hdr->addr1); - tx.skb = skb; -+ tx.hdrlen = ieee80211_padded_hdrlen(&tx.local->hw, hdr->frame_control); - - if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) { - rcu_read_unlock(); ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -1390,6 +1390,7 @@ void ieee80211_send_auth(struct ieee8021 - struct ieee80211_local *local = sdata->local; - struct sk_buff *skb; - struct ieee80211_mgmt *mgmt; -+ unsigned int hdrlen; - int err; - - /* 24 + 6 = header + auth_algo + auth_transaction + status_code */ -@@ -1413,8 +1414,10 @@ void ieee80211_send_auth(struct ieee8021 - skb_put_data(skb, extra, extra_len); - - if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { -+ hdrlen = ieee80211_hdrlen(mgmt->frame_control); - mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); -- err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx); -+ err = ieee80211_wep_encrypt(local, skb, hdrlen, key, -+ key_len, key_idx); - WARN_ON(err); - } - ---- a/net/mac80211/wep.c -+++ b/net/mac80211/wep.c -@@ -89,11 +89,11 @@ static void ieee80211_wep_get_iv(struct - - static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, - struct sk_buff *skb, -+ unsigned int hdrlen, - int keylen, int keyidx) - { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -- unsigned int hdrlen; - u8 *newhdr; - - hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); -@@ -101,7 +101,6 @@ static u8 *ieee80211_wep_add_iv(struct i - if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN)) - return NULL; - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); - newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN); - memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen); - -@@ -160,6 +159,7 @@ int ieee80211_wep_encrypt_data(struct cr - */ - int ieee80211_wep_encrypt(struct ieee80211_local *local, - struct sk_buff *skb, -+ unsigned int hdrlen, - const u8 *key, int keylen, int keyidx) - { - u8 *iv; -@@ -169,7 +169,7 @@ int ieee80211_wep_encrypt(struct ieee802 - if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN)) - return -1; - -- iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx); -+ iv = ieee80211_wep_add_iv(local, skb, hdrlen, keylen, keyidx); - if (!iv) - return -1; - -@@ -307,13 +307,14 @@ static int wep_encrypt_skb(struct ieee80 - struct ieee80211_key_conf *hw_key = info->control.hw_key; - - if (!hw_key) { -- if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key, -+ if (ieee80211_wep_encrypt(tx->local, skb, tx->hdrlen, -+ tx->key->conf.key, - tx->key->conf.keylen, - tx->key->conf.keyidx)) - return -1; - } else if ((hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) || - (hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { -- if (!ieee80211_wep_add_iv(tx->local, skb, -+ if (!ieee80211_wep_add_iv(tx->local, skb, tx->hdrlen, - tx->key->conf.keylen, - tx->key->conf.keyidx)) - return -1; ---- a/net/mac80211/wep.h -+++ b/net/mac80211/wep.h -@@ -22,6 +22,7 @@ int ieee80211_wep_encrypt_data(struct cr - size_t klen, u8 *data, size_t data_len); - int ieee80211_wep_encrypt(struct ieee80211_local *local, - struct sk_buff *skb, -+ unsigned int hdrlen, - const u8 *key, int keylen, int keyidx); - int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, - size_t klen, u8 *data, size_t data_len); ---- a/net/mac80211/wpa.c -+++ b/net/mac80211/wpa.c -@@ -44,7 +44,7 @@ ieee80211_tx_h_michael_mic_add(struct ie - skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control)) - return TX_CONTINUE; - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ hdrlen = tx->hdrlen; - if (skb->len < hdrlen) - return TX_DROP; - -@@ -195,7 +195,6 @@ mic_fail_no_key: - - static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) - { -- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - struct ieee80211_key *key = tx->key; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - unsigned int hdrlen; -@@ -210,7 +209,7 @@ static int tkip_encrypt_skb(struct ieee8 - return 0; - } - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ hdrlen = tx->hdrlen; - len = skb->len - hdrlen; - - if (info->control.hw_key) -@@ -428,7 +427,7 @@ static int ccmp_encrypt_skb(struct ieee8 - return 0; - } - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ hdrlen = tx->hdrlen; - len = skb->len - hdrlen; - - if (info->control.hw_key) -@@ -660,7 +659,7 @@ static int gcmp_encrypt_skb(struct ieee8 - return 0; - } - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ hdrlen = tx->hdrlen; - len = skb->len - hdrlen; - - if (info->control.hw_key) -@@ -800,7 +799,6 @@ static ieee80211_tx_result - ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx, - struct sk_buff *skb) - { -- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_key *key = tx->key; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - int hdrlen; -@@ -816,8 +814,7 @@ ieee80211_crypto_cs_encrypt(struct ieee8 - pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC))) - return TX_DROP; - -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -- -+ hdrlen = tx->hdrlen; - pos = skb_push(skb, iv_len); - memmove(pos, pos + iv_len, hdrlen); - diff --git a/package/kernel/mac80211/patches/subsys/358-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch b/package/kernel/mac80211/patches/subsys/358-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch deleted file mode 100644 index f4048b0420..0000000000 --- a/package/kernel/mac80211/patches/subsys/358-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch +++ /dev/null @@ -1,233 +0,0 @@ -From: Janusz Dziedzic -Date: Fri, 19 Feb 2016 11:01:50 +0100 -Subject: [PATCH] mac80211: add NEED_ALIGNED4_SKBS hw flag - -HW/driver should set NEED_ALIGNED4_SKBS flag in case -require aligned skbs to four-byte boundaries. -This affect only TX direction. - -Padding is added after ieee80211_hdr, before IV/LLC. - -Before we have to do memmove(hdrlen) twice in the -dirver. Once before we pass this to HW and next -in tx completion (to be sure monitor will report -this tx frame correctly). - -With this patch we can skip this memmove() and save CPU. - -Currently this was tested with ath9k, both hw/sw crypt for -wep/tkip/ccmp. - -Signed-off-by: Janusz Dziedzic ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -2131,6 +2131,9 @@ struct ieee80211_txq { - * @IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP: The driver (or firmware) doesn't - * support QoS NDP for AP probing - that's most likely a driver bug. - * -+ * @IEEE80211_HW_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte. -+ * Padding will be added after ieee80211_hdr, before IV/LLC. -+ * - * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays - */ - enum ieee80211_hw_flags { -@@ -2176,6 +2179,7 @@ enum ieee80211_hw_flags { - IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA, - IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP, - IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP, -+ IEEE80211_HW_NEEDS_ALIGNED4_SKBS, - - /* keep last, obviously */ - NUM_IEEE80211_HW_FLAGS ---- a/net/mac80211/debugfs.c -+++ b/net/mac80211/debugfs.c -@@ -214,6 +214,7 @@ static const char *hw_flag_names[] = { - FLAG(SUPPORTS_TDLS_BUFFER_STA), - FLAG(DEAUTH_NEED_MGD_TX_PREP), - FLAG(DOESNT_SUPPORT_QOS_NDP), -+ FLAG(NEEDS_ALIGNED4_SKBS), - #undef FLAG - }; - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -1559,6 +1559,29 @@ ieee80211_vif_get_num_mcast_if(struct ie - return -1; - } - -+static inline unsigned int -+ieee80211_hdr_padsize(struct ieee80211_hw *hw, unsigned int hdrlen) -+{ -+ /* -+ * While hdrlen is already aligned to two-byte boundaries, -+ * simple check with & 2 will return correct padsize. -+ */ -+ if (ieee80211_hw_check(hw, NEEDS_ALIGNED4_SKBS)) -+ return hdrlen & 2; -+ return 0; -+} -+ -+static inline unsigned int -+ieee80211_padded_hdrlen(struct ieee80211_hw *hw, __le16 fc) -+{ -+ unsigned int hdrlen; -+ -+ hdrlen = ieee80211_hdrlen(fc); -+ hdrlen += ieee80211_hdr_padsize(hw, hdrlen); -+ -+ return hdrlen; -+} -+ - u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, - struct ieee80211_rx_status *status, - unsigned int mpdu_len, ---- a/net/mac80211/sta_info.h -+++ b/net/mac80211/sta_info.h -@@ -301,7 +301,7 @@ struct ieee80211_fast_tx { - u8 hdr_len; - u8 sa_offs, da_offs, pn_offs; - u8 band; -- u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV + -+ u8 hdr[30 + 2 + 2 + IEEE80211_FAST_XMIT_MAX_IV + - sizeof(rfc1042_header)] __aligned(2); - - struct rcu_head rcu_head; ---- a/net/mac80211/status.c -+++ b/net/mac80211/status.c -@@ -655,9 +655,22 @@ void ieee80211_tx_monitor(struct ieee802 - struct sk_buff *skb2; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_sub_if_data *sdata; -+ struct ieee80211_hdr *hdr = (void *)skb->data; - struct net_device *prev_dev = NULL; -+ unsigned int hdrlen, padsize; - int rtap_len; - -+ /* Remove padding if was added */ -+ if (ieee80211_hw_check(&local->hw, NEEDS_ALIGNED4_SKBS)) { -+ hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ padsize = ieee80211_hdr_padsize(&local->hw, hdrlen); -+ -+ if (padsize && skb->len > hdrlen + padsize) { -+ memmove(skb->data + padsize, skb->data, hdrlen); -+ skb_pull(skb, padsize); -+ } -+ } -+ - /* send frame to monitor interfaces now */ - rtap_len = ieee80211_tx_radiotap_len(info); - if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { ---- a/net/mac80211/tkip.c -+++ b/net/mac80211/tkip.c -@@ -201,10 +201,12 @@ void ieee80211_get_tkip_p2k(struct ieee8 - { - struct ieee80211_key *key = (struct ieee80211_key *) - container_of(keyconf, struct ieee80211_key, conf); -+ struct ieee80211_hw *hw = &key->local->hw; - const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; - struct tkip_ctx *ctx = &key->u.tkip.tx; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -- const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); -+ const u8 *data = (u8 *)hdr + ieee80211_padded_hdrlen(hw, -+ hdr->frame_control); - u32 iv32 = get_unaligned_le32(&data[4]); - u16 iv16 = data[2] | (data[0] << 8); - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -1175,8 +1175,7 @@ ieee80211_tx_prepare(struct ieee80211_su - info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING; - - hdr = (struct ieee80211_hdr *) skb->data; -- -- tx->hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ tx->hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control); - - if (likely(sta)) { - if (!IS_ERR(sta)) -@@ -2215,7 +2214,7 @@ netdev_tx_t ieee80211_monitor_start_xmit - goto fail; - - hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+ hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control); - - if (skb->len < len_rthdr + hdrlen) - goto fail; -@@ -2433,7 +2432,7 @@ static struct sk_buff *ieee80211_build_h - struct ieee80211_chanctx_conf *chanctx_conf; - struct ieee80211_sub_if_data *ap_sdata; - enum nl80211_band band; -- int ret; -+ int padsize, ret; - - if (IS_ERR(sta)) - sta = NULL; -@@ -2653,6 +2652,9 @@ static struct sk_buff *ieee80211_build_h - hdrlen += 2; - } - -+ /* Check aligned4 skb required */ -+ padsize = ieee80211_hdr_padsize(&sdata->local->hw, hdrlen); -+ - /* - * Drop unicast frames to unauthorised stations unless they are - * EAPOL frames from the local station. -@@ -2733,6 +2735,7 @@ static struct sk_buff *ieee80211_build_h - - skb_pull(skb, skip_header_bytes); - head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb); -+ head_need += padsize; - - /* - * So we need to modify the skb header and hence need a copy of -@@ -2765,6 +2768,9 @@ static struct sk_buff *ieee80211_build_h - memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen); - #endif - -+ if (padsize) -+ memset(skb_push(skb, padsize), 0, padsize); -+ - if (ieee80211_is_data_qos(fc)) { - __le16 *qos_control; - -@@ -2940,6 +2946,9 @@ void ieee80211_check_fast_xmit(struct st - fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); - } - -+ /* Check aligned4 skb required */ -+ build.hdr_len += ieee80211_hdr_padsize(&local->hw, build.hdr_len); -+ - /* We store the key here so there's no point in using rcu_dereference() - * but that's fine because the code that changes the pointers will call - * this function after doing so. For a single CPU that would be enough, -@@ -3540,7 +3549,7 @@ begin: - - if (tx.key && - (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) -- pn_offs = ieee80211_hdrlen(hdr->frame_control); -+ pn_offs = tx.hdrlen; - - ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs, - tx.key, skb); ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -1388,6 +1388,7 @@ void ieee80211_send_auth(struct ieee8021 - u32 tx_flags) - { - struct ieee80211_local *local = sdata->local; -+ struct ieee80211_hw *hw = &local->hw; - struct sk_buff *skb; - struct ieee80211_mgmt *mgmt; - unsigned int hdrlen; -@@ -1414,7 +1415,7 @@ void ieee80211_send_auth(struct ieee8021 - skb_put_data(skb, extra, extra_len); - - if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { -- hdrlen = ieee80211_hdrlen(mgmt->frame_control); -+ hdrlen = ieee80211_padded_hdrlen(hw, mgmt->frame_control); - mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); - err = ieee80211_wep_encrypt(local, skb, hdrlen, key, - key_len, key_idx); diff --git a/package/kernel/mac80211/patches/subsys/359-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch b/package/kernel/mac80211/patches/subsys/359-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch deleted file mode 100644 index 661fb46ea4..0000000000 --- a/package/kernel/mac80211/patches/subsys/359-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch +++ /dev/null @@ -1,82 +0,0 @@ -From: Chaitanya T K -Date: Mon, 27 Jun 2016 15:23:26 +0530 -Subject: [PATCH] mac80211: minstrel: Enable STBC and LDPC for VHT Rates - -If peer support reception of STBC and LDPC, enable them for better -performance. - -Signed-off-by: Chaitanya TK ---- - ---- a/include/linux/ieee80211.h -+++ b/include/linux/ieee80211.h -@@ -1659,6 +1659,7 @@ struct ieee80211_mu_edca_param_set { - #define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300 - #define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400 - #define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700 -+#define IEEE80211_VHT_CAP_RXSTBC_SHIFT 8 - #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 - #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 - #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT 13 ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -1130,7 +1130,7 @@ minstrel_ht_update_caps(void *priv, stru - struct minstrel_ht_sta_priv *msp = priv_sta; - struct minstrel_ht_sta *mi = &msp->ht; - struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; -- u16 sta_cap = sta->ht_cap.cap; -+ u16 ht_cap = sta->ht_cap.cap; - struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; - struct sta_info *sinfo = container_of(sta, struct sta_info, sta); - int use_vht; -@@ -1138,6 +1138,7 @@ minstrel_ht_update_caps(void *priv, stru - int ack_dur; - int stbc; - int i; -+ bool ldpc = false; - - /* fall back to the old minstrel for legacy stations */ - if (!sta->ht_cap.ht_supported) -@@ -1175,16 +1176,24 @@ minstrel_ht_update_caps(void *priv, stru - } - mi->sample_tries = 4; - -- /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */ - if (!use_vht) { -- stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> -+ stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >> - IEEE80211_HT_CAP_RX_STBC_SHIFT; -- mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; - -- if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) -- mi->tx_flags |= IEEE80211_TX_CTL_LDPC; -+ if (ht_cap & IEEE80211_HT_CAP_LDPC_CODING) -+ ldpc = true; -+ } else { -+ stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >> -+ IEEE80211_VHT_CAP_RXSTBC_SHIFT; -+ -+ if (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC) -+ ldpc = true; - } - -+ mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; -+ if (ldpc) -+ mi->tx_flags |= IEEE80211_TX_CTL_LDPC; -+ - for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { - u32 gflags = minstrel_mcs_groups[i].flags; - int bw, nss; -@@ -1197,10 +1206,10 @@ minstrel_ht_update_caps(void *priv, stru - - if (gflags & IEEE80211_TX_RC_SHORT_GI) { - if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) { -- if (!(sta_cap & IEEE80211_HT_CAP_SGI_40)) -+ if (!(ht_cap & IEEE80211_HT_CAP_SGI_40)) - continue; - } else { -- if (!(sta_cap & IEEE80211_HT_CAP_SGI_20)) -+ if (!(ht_cap & IEEE80211_HT_CAP_SGI_20)) - continue; - } - } diff --git a/package/kernel/mac80211/patches/subsys/370-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch b/package/kernel/mac80211/patches/subsys/370-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch deleted file mode 100644 index 95d4f294aa..0000000000 --- a/package/kernel/mac80211/patches/subsys/370-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch +++ /dev/null @@ -1,150 +0,0 @@ -From: Felix Fietkau -Date: Sat, 10 Feb 2018 12:41:51 +0100 -Subject: [PATCH] mac80211: minstrel: remove unnecessary debugfs cleanup - code - -debugfs entries are cleaned up by debugfs_remove_recursive already. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel.c -+++ b/net/mac80211/rc80211_minstrel.c -@@ -689,8 +689,8 @@ minstrel_alloc(struct ieee80211_hw *hw, - - #ifdef CPTCFG_MAC80211_DEBUGFS - mp->fixed_rate_idx = (u32) -1; -- mp->dbg_fixed_rate = debugfs_create_u32("fixed_rate_idx", -- 0666, debugfsdir, &mp->fixed_rate_idx); -+ debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, -+ &mp->fixed_rate_idx); - #endif - - minstrel_init_cck_rates(mp); -@@ -701,9 +701,6 @@ minstrel_alloc(struct ieee80211_hw *hw, - static void - minstrel_free(void *priv) - { --#ifdef CPTCFG_MAC80211_DEBUGFS -- debugfs_remove(((struct minstrel_priv *)priv)->dbg_fixed_rate); --#endif - kfree(priv); - } - -@@ -735,7 +732,6 @@ const struct rate_control_ops mac80211_m - .free_sta = minstrel_free_sta, - #ifdef CPTCFG_MAC80211_DEBUGFS - .add_sta_debugfs = minstrel_add_sta_debugfs, -- .remove_sta_debugfs = minstrel_remove_sta_debugfs, - #endif - .get_expected_throughput = minstrel_get_expected_throughput, - }; ---- a/net/mac80211/rc80211_minstrel.h -+++ b/net/mac80211/rc80211_minstrel.h -@@ -109,11 +109,6 @@ struct minstrel_sta_info { - - /* sampling table */ - u8 *sample_table; -- --#ifdef CPTCFG_MAC80211_DEBUGFS -- struct dentry *dbg_stats; -- struct dentry *dbg_stats_csv; --#endif - }; - - struct minstrel_priv { -@@ -137,7 +132,6 @@ struct minstrel_priv { - * - setting will be applied on next update - */ - u32 fixed_rate_idx; -- struct dentry *dbg_fixed_rate; - #endif - }; - -@@ -156,7 +150,6 @@ minstrel_get_ewmsd10(struct minstrel_rat - - extern const struct rate_control_ops mac80211_minstrel; - void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); --void minstrel_remove_sta_debugfs(void *priv, void *priv_sta); - - /* Recalculate success probabilities and counters for a given rate using EWMA */ - void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs); ---- a/net/mac80211/rc80211_minstrel_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_debugfs.c -@@ -214,19 +214,7 @@ minstrel_add_sta_debugfs(void *priv, voi - { - struct minstrel_sta_info *mi = priv_sta; - -- mi->dbg_stats = debugfs_create_file("rc_stats", 0444, dir, mi, -- &minstrel_stat_fops); -- -- mi->dbg_stats_csv = debugfs_create_file("rc_stats_csv", 0444, dir, mi, -- &minstrel_stat_csv_fops); --} -- --void --minstrel_remove_sta_debugfs(void *priv, void *priv_sta) --{ -- struct minstrel_sta_info *mi = priv_sta; -- -- debugfs_remove(mi->dbg_stats); -- -- debugfs_remove(mi->dbg_stats_csv); -+ debugfs_create_file("rc_stats", S_IRUGO, dir, mi, &minstrel_stat_fops); -+ debugfs_create_file("rc_stats_csv", S_IRUGO, dir, mi, -+ &minstrel_stat_csv_fops); - } ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -1393,7 +1393,6 @@ static const struct rate_control_ops mac - .free = minstrel_ht_free, - #ifdef CPTCFG_MAC80211_DEBUGFS - .add_sta_debugfs = minstrel_ht_add_sta_debugfs, -- .remove_sta_debugfs = minstrel_ht_remove_sta_debugfs, - #endif - .get_expected_throughput = minstrel_ht_get_expected_throughput, - }; ---- a/net/mac80211/rc80211_minstrel_ht.h -+++ b/net/mac80211/rc80211_minstrel_ht.h -@@ -110,17 +110,12 @@ struct minstrel_ht_sta_priv { - struct minstrel_ht_sta ht; - struct minstrel_sta_info legacy; - }; --#ifdef CPTCFG_MAC80211_DEBUGFS -- struct dentry *dbg_stats; -- struct dentry *dbg_stats_csv; --#endif - void *ratelist; - void *sample_table; - bool is_ht; - }; - - void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); --void minstrel_ht_remove_sta_debugfs(void *priv, void *priv_sta); - int minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate, - int prob_ewma); - ---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c -@@ -303,17 +303,8 @@ minstrel_ht_add_sta_debugfs(void *priv, - { - struct minstrel_ht_sta_priv *msp = priv_sta; - -- msp->dbg_stats = debugfs_create_file("rc_stats", 0444, dir, msp, -- &minstrel_ht_stat_fops); -- msp->dbg_stats_csv = debugfs_create_file("rc_stats_csv", 0444, dir, msp, -- &minstrel_ht_stat_csv_fops); --} -- --void --minstrel_ht_remove_sta_debugfs(void *priv, void *priv_sta) --{ -- struct minstrel_ht_sta_priv *msp = priv_sta; -- -- debugfs_remove(msp->dbg_stats); -- debugfs_remove(msp->dbg_stats_csv); -+ debugfs_create_file("rc_stats", S_IRUGO, dir, msp, -+ &minstrel_ht_stat_fops); -+ debugfs_create_file("rc_stats_csv", S_IRUGO, dir, msp, -+ &minstrel_ht_stat_csv_fops); - } diff --git a/package/kernel/mac80211/patches/subsys/371-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch b/package/kernel/mac80211/patches/subsys/371-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch deleted file mode 100644 index 9a233753ad..0000000000 --- a/package/kernel/mac80211/patches/subsys/371-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch +++ /dev/null @@ -1,575 +0,0 @@ -From: Felix Fietkau -Date: Sat, 10 Feb 2018 12:43:30 +0100 -Subject: [PATCH] mac80211: minstrel: merge with minstrel_ht, always enable - VHT support - -Legacy-only devices are not very common and the overhead of the extra -code for HT and VHT rates is not big enough to justify all those extra -lines of code to make it optional. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/Kconfig -+++ b/net/mac80211/Kconfig -@@ -25,20 +25,6 @@ config MAC80211_RC_MINSTREL - ---help--- - This option enables the 'minstrel' TX rate control algorithm - --config MAC80211_RC_MINSTREL_HT -- bool "Minstrel 802.11n support" if EXPERT -- depends on MAC80211_RC_MINSTREL -- default y -- ---help--- -- This option enables the 'minstrel_ht' TX rate control algorithm -- --config MAC80211_RC_MINSTREL_VHT -- bool "Minstrel 802.11ac support" if EXPERT -- depends on MAC80211_RC_MINSTREL_HT -- default n -- ---help--- -- This option enables VHT in the 'minstrel_ht' TX rate control algorithm -- - choice - prompt "Default rate control algorithm" - depends on MAC80211_HAS_RC -@@ -60,8 +46,7 @@ endchoice - - config MAC80211_RC_DEFAULT - string -- default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL && MAC80211_RC_MINSTREL_HT -- default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL -+ default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL - default "" - - endif ---- a/net/mac80211/Makefile -+++ b/net/mac80211/Makefile -@@ -52,13 +52,14 @@ mac80211-$(CONFIG_PM) += pm.o - - CFLAGS_trace.o := -I$(src) - --rc80211_minstrel-y := rc80211_minstrel.o --rc80211_minstrel-$(CPTCFG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o -+rc80211_minstrel-y := \ -+ rc80211_minstrel.o \ -+ rc80211_minstrel_ht.o - --rc80211_minstrel_ht-y := rc80211_minstrel_ht.o --rc80211_minstrel_ht-$(CPTCFG_MAC80211_DEBUGFS) += rc80211_minstrel_ht_debugfs.o -+rc80211_minstrel-$(CPTCFG_MAC80211_DEBUGFS) += \ -+ rc80211_minstrel_debugfs.o \ -+ rc80211_minstrel_ht_debugfs.o - - mac80211-$(CPTCFG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) --mac80211-$(CPTCFG_MAC80211_RC_MINSTREL_HT) += $(rc80211_minstrel_ht-y) - - ccflags-y += -DDEBUG ---- a/net/mac80211/main.c -+++ b/net/mac80211/main.c -@@ -1308,18 +1308,12 @@ static int __init ieee80211_init(void) - if (ret) - return ret; - -- ret = rc80211_minstrel_ht_init(); -- if (ret) -- goto err_minstrel; -- - ret = ieee80211_iface_init(); - if (ret) - goto err_netdev; - - return 0; - err_netdev: -- rc80211_minstrel_ht_exit(); -- err_minstrel: - rc80211_minstrel_exit(); - - return ret; -@@ -1327,7 +1321,6 @@ static int __init ieee80211_init(void) - - static void __exit ieee80211_exit(void) - { -- rc80211_minstrel_ht_exit(); - rc80211_minstrel_exit(); - - ieee80211s_stop(); ---- a/net/mac80211/rate.h -+++ b/net/mac80211/rate.h -@@ -95,18 +95,5 @@ static inline void rc80211_minstrel_exit - } - #endif - --#ifdef CPTCFG_MAC80211_RC_MINSTREL_HT --int rc80211_minstrel_ht_init(void); --void rc80211_minstrel_ht_exit(void); --#else --static inline int rc80211_minstrel_ht_init(void) --{ -- return 0; --} --static inline void rc80211_minstrel_ht_exit(void) --{ --} --#endif -- - - #endif /* IEEE80211_RATE_H */ ---- a/net/mac80211/rc80211_minstrel.c -+++ b/net/mac80211/rc80211_minstrel.c -@@ -572,138 +572,6 @@ minstrel_rate_init(void *priv, struct ie - minstrel_update_rates(mp, mi); - } - --static void * --minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) --{ -- struct ieee80211_supported_band *sband; -- struct minstrel_sta_info *mi; -- struct minstrel_priv *mp = priv; -- struct ieee80211_hw *hw = mp->hw; -- int max_rates = 0; -- int i; -- -- mi = kzalloc(sizeof(struct minstrel_sta_info), gfp); -- if (!mi) -- return NULL; -- -- for (i = 0; i < NUM_NL80211_BANDS; i++) { -- sband = hw->wiphy->bands[i]; -- if (sband && sband->n_bitrates > max_rates) -- max_rates = sband->n_bitrates; -- } -- -- mi->r = kcalloc(max_rates, sizeof(struct minstrel_rate), gfp); -- if (!mi->r) -- goto error; -- -- mi->sample_table = kmalloc_array(max_rates, SAMPLE_COLUMNS, gfp); -- if (!mi->sample_table) -- goto error1; -- -- mi->last_stats_update = jiffies; -- return mi; -- --error1: -- kfree(mi->r); --error: -- kfree(mi); -- return NULL; --} -- --static void --minstrel_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta) --{ -- struct minstrel_sta_info *mi = priv_sta; -- -- kfree(mi->sample_table); -- kfree(mi->r); -- kfree(mi); --} -- --static void --minstrel_init_cck_rates(struct minstrel_priv *mp) --{ -- 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, j = 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++) { -- if (rate->bitrate != bitrates[j]) -- continue; -- -- mp->cck_rates[j] = i; -- break; -- } -- } --} -- --static void * --minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) --{ -- struct minstrel_priv *mp; -- -- mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC); -- if (!mp) -- return NULL; -- -- /* contention window settings -- * Just an approximation. Using the per-queue values would complicate -- * the calculations and is probably unnecessary */ -- 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; -- -- if (hw->max_rate_tries > 0) -- mp->max_retry = hw->max_rate_tries; -- else -- /* safe default, does not necessarily have to match hw properties */ -- mp->max_retry = 7; -- -- if (hw->max_rates >= 4) -- mp->has_mrr = true; -- -- mp->hw = hw; -- mp->update_interval = 100; -- --#ifdef CPTCFG_MAC80211_DEBUGFS -- mp->fixed_rate_idx = (u32) -1; -- debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, -- &mp->fixed_rate_idx); --#endif -- -- minstrel_init_cck_rates(mp); -- -- return mp; --} -- --static void --minstrel_free(void *priv) --{ -- kfree(priv); --} -- - static u32 minstrel_get_expected_throughput(void *priv_sta) - { - struct minstrel_sta_info *mi = priv_sta; -@@ -722,28 +590,8 @@ static u32 minstrel_get_expected_through - } - - const struct rate_control_ops mac80211_minstrel = { -- .name = "minstrel", - .tx_status_ext = minstrel_tx_status, - .get_rate = minstrel_get_rate, - .rate_init = minstrel_rate_init, -- .alloc = minstrel_alloc, -- .free = minstrel_free, -- .alloc_sta = minstrel_alloc_sta, -- .free_sta = minstrel_free_sta, --#ifdef CPTCFG_MAC80211_DEBUGFS -- .add_sta_debugfs = minstrel_add_sta_debugfs, --#endif - .get_expected_throughput = minstrel_get_expected_throughput, - }; -- --int __init --rc80211_minstrel_init(void) --{ -- return ieee80211_rate_control_register(&mac80211_minstrel); --} -- --void --rc80211_minstrel_exit(void) --{ -- ieee80211_rate_control_unregister(&mac80211_minstrel); --} ---- a/net/mac80211/rc80211_minstrel.h -+++ b/net/mac80211/rc80211_minstrel.h -@@ -158,7 +158,5 @@ int minstrel_get_tp_avg(struct minstrel_ - /* debugfs */ - int minstrel_stats_open(struct inode *inode, struct file *file); - int minstrel_stats_csv_open(struct inode *inode, struct file *file); --ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos); --int minstrel_stats_release(struct inode *inode, struct file *file); - - #endif ---- a/net/mac80211/rc80211_minstrel_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_debugfs.c -@@ -54,22 +54,6 @@ - #include - #include "rc80211_minstrel.h" - --ssize_t --minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) --{ -- struct minstrel_debugfs_info *ms; -- -- ms = file->private_data; -- return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len); --} -- --int --minstrel_stats_release(struct inode *inode, struct file *file) --{ -- kfree(file->private_data); -- return 0; --} -- - int - minstrel_stats_open(struct inode *inode, struct file *file) - { -@@ -135,14 +119,6 @@ minstrel_stats_open(struct inode *inode, - return 0; - } - --static const struct file_operations minstrel_stat_fops = { -- .owner = THIS_MODULE, -- .open = minstrel_stats_open, -- .read = minstrel_stats_read, -- .release = minstrel_stats_release, -- .llseek = default_llseek, --}; -- - int - minstrel_stats_csv_open(struct inode *inode, struct file *file) - { -@@ -200,21 +176,3 @@ minstrel_stats_csv_open(struct inode *in - - return 0; - } -- --static const struct file_operations minstrel_stat_csv_fops = { -- .owner = THIS_MODULE, -- .open = minstrel_stats_csv_open, -- .read = minstrel_stats_read, -- .release = minstrel_stats_release, -- .llseek = default_llseek, --}; -- --void --minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir) --{ -- struct minstrel_sta_info *mi = priv_sta; -- -- debugfs_create_file("rc_stats", S_IRUGO, dir, mi, &minstrel_stat_fops); -- debugfs_create_file("rc_stats_csv", S_IRUGO, dir, mi, -- &minstrel_stat_csv_fops); --} ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -137,12 +137,10 @@ - } \ - } - --#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT - static bool minstrel_vht_only = true; - module_param(minstrel_vht_only, bool, 0644); - MODULE_PARM_DESC(minstrel_vht_only, - "Use only VHT rates when VHT is supported by sta."); --#endif - - /* - * To enable sufficiently targeted rate sampling, MCS rates are divided into -@@ -171,7 +169,6 @@ const struct mcs_group minstrel_mcs_grou - - CCK_GROUP, - --#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT - VHT_GROUP(1, 0, BW_20), - VHT_GROUP(2, 0, BW_20), - VHT_GROUP(3, 0, BW_20), -@@ -195,7 +192,6 @@ const struct mcs_group minstrel_mcs_grou - VHT_GROUP(1, 1, BW_80), - VHT_GROUP(2, 1, BW_80), - VHT_GROUP(3, 1, BW_80), --#endif - }; - - static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; -@@ -1146,12 +1142,10 @@ minstrel_ht_update_caps(void *priv, stru - - BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB); - --#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT - if (vht_cap->vht_supported) - use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0); - else --#endif -- use_vht = 0; -+ use_vht = 0; - - msp->is_ht = true; - memset(mi, 0, sizeof(*mi)); -@@ -1226,10 +1220,9 @@ minstrel_ht_update_caps(void *priv, stru - - /* HT rate */ - if (gflags & IEEE80211_TX_RC_MCS) { --#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT - if (use_vht && minstrel_vht_only) - continue; --#endif -+ - mi->supported[i] = mcs->rx_mask[nss - 1]; - if (mi->supported[i]) - n_supported++; -@@ -1349,16 +1342,88 @@ minstrel_ht_free_sta(void *priv, struct - kfree(msp); - } - -+static void -+minstrel_ht_init_cck_rates(struct minstrel_priv *mp) -+{ -+ 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, j = 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++) { -+ if (rate->bitrate != bitrates[j]) -+ continue; -+ -+ mp->cck_rates[j] = i; -+ break; -+ } -+ } -+} -+ - static void * - minstrel_ht_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) - { -- return mac80211_minstrel.alloc(hw, debugfsdir); -+ struct minstrel_priv *mp; -+ -+ mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC); -+ if (!mp) -+ return NULL; -+ -+ /* contention window settings -+ * Just an approximation. Using the per-queue values would complicate -+ * the calculations and is probably unnecessary */ -+ 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; -+ -+ if (hw->max_rate_tries > 0) -+ mp->max_retry = hw->max_rate_tries; -+ else -+ /* safe default, does not necessarily have to match hw properties */ -+ mp->max_retry = 7; -+ -+ if (hw->max_rates >= 4) -+ mp->has_mrr = true; -+ -+ mp->hw = hw; -+ mp->update_interval = 100; -+ -+#ifdef CPTCFG_MAC80211_DEBUGFS -+ mp->fixed_rate_idx = (u32) -1; -+ debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, -+ &mp->fixed_rate_idx); -+#endif -+ -+ minstrel_ht_init_cck_rates(mp); -+ -+ return mp; - } - - static void - minstrel_ht_free(void *priv) - { -- mac80211_minstrel.free(priv); -+ kfree(priv); - } - - static u32 minstrel_ht_get_expected_throughput(void *priv_sta) -@@ -1417,14 +1482,14 @@ static void __init init_sample_table(voi - } - - int __init --rc80211_minstrel_ht_init(void) -+rc80211_minstrel_init(void) - { - init_sample_table(); - return ieee80211_rate_control_register(&mac80211_minstrel_ht); - } - - void --rc80211_minstrel_ht_exit(void) -+rc80211_minstrel_exit(void) - { - ieee80211_rate_control_unregister(&mac80211_minstrel_ht); - } ---- a/net/mac80211/rc80211_minstrel_ht.h -+++ b/net/mac80211/rc80211_minstrel_ht.h -@@ -15,11 +15,7 @@ - */ - #define MINSTREL_MAX_STREAMS 3 - #define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */ --#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT - #define MINSTREL_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */ --#else --#define MINSTREL_VHT_STREAM_GROUPS 0 --#endif - - #define MINSTREL_HT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ - MINSTREL_HT_STREAM_GROUPS) -@@ -34,11 +30,7 @@ - #define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB) - #define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1) - --#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT - #define MCS_GROUP_RATES 10 --#else --#define MCS_GROUP_RATES 8 --#endif - - struct mcs_group { - u32 flags; ---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c -@@ -15,6 +15,22 @@ - #include "rc80211_minstrel.h" - #include "rc80211_minstrel_ht.h" - -+static ssize_t -+minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) -+{ -+ struct minstrel_debugfs_info *ms; -+ -+ ms = file->private_data; -+ return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len); -+} -+ -+static int -+minstrel_stats_release(struct inode *inode, struct file *file) -+{ -+ kfree(file->private_data); -+ return 0; -+} -+ - static char * - minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) - { diff --git a/package/kernel/mac80211/patches/subsys/372-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch b/package/kernel/mac80211/patches/subsys/372-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch deleted file mode 100644 index 02a0ca0a52..0000000000 --- a/package/kernel/mac80211/patches/subsys/372-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch +++ /dev/null @@ -1,368 +0,0 @@ -From: Felix Fietkau -Date: Sat, 10 Feb 2018 12:45:47 +0100 -Subject: [PATCH] mac80211: minstrel: reduce minstrel_mcs_groups size - -By storing a shift value for all duration values of a group, we can -reduce precision by a neglegible amount to make it fit into a u16 value. -This improves cache footprint and reduces size: - -Before: - text data bss dec hex filename - 10024 116 0 10140 279c rc80211_minstrel_ht.o - -After: - text data bss dec hex filename - 9368 116 0 9484 250c rc80211_minstrel_ht.o - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -52,22 +52,23 @@ - _streams - 1 - - /* MCS rate information for an MCS group */ --#define MCS_GROUP(_streams, _sgi, _ht40) \ -+#define MCS_GROUP(_streams, _sgi, _ht40, _s) \ - [GROUP_IDX(_streams, _sgi, _ht40)] = { \ - .streams = _streams, \ -+ .shift = _s, \ - .flags = \ - IEEE80211_TX_RC_MCS | \ - (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ - (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ - .duration = { \ -- MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26), \ -- MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52), \ -- MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78), \ -- MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104), \ -- MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156), \ -- MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208), \ -- MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234), \ -- MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) \ -+ MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26) >> _s, \ -+ MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52) >> _s, \ -+ MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78) >> _s, \ -+ MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104) >> _s, \ -+ MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156) >> _s, \ -+ MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208) >> _s, \ -+ MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234) >> _s, \ -+ MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) >> _s \ - } \ - } - -@@ -80,9 +81,10 @@ - #define BW2VBPS(_bw, r3, r2, r1) \ - (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1) - --#define VHT_GROUP(_streams, _sgi, _bw) \ -+#define VHT_GROUP(_streams, _sgi, _bw, _s) \ - [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \ - .streams = _streams, \ -+ .shift = _s, \ - .flags = \ - IEEE80211_TX_RC_VHT_MCS | \ - (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ -@@ -90,25 +92,25 @@ - _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ - .duration = { \ - MCS_DURATION(_streams, _sgi, \ -- BW2VBPS(_bw, 117, 54, 26)), \ -+ BW2VBPS(_bw, 117, 54, 26)) >> _s, \ - MCS_DURATION(_streams, _sgi, \ -- BW2VBPS(_bw, 234, 108, 52)), \ -+ BW2VBPS(_bw, 234, 108, 52)) >> _s, \ - MCS_DURATION(_streams, _sgi, \ -- BW2VBPS(_bw, 351, 162, 78)), \ -+ BW2VBPS(_bw, 351, 162, 78)) >> _s, \ - MCS_DURATION(_streams, _sgi, \ -- BW2VBPS(_bw, 468, 216, 104)), \ -+ BW2VBPS(_bw, 468, 216, 104)) >> _s, \ - MCS_DURATION(_streams, _sgi, \ -- BW2VBPS(_bw, 702, 324, 156)), \ -+ BW2VBPS(_bw, 702, 324, 156)) >> _s, \ - MCS_DURATION(_streams, _sgi, \ -- BW2VBPS(_bw, 936, 432, 208)), \ -+ BW2VBPS(_bw, 936, 432, 208)) >> _s, \ - MCS_DURATION(_streams, _sgi, \ -- BW2VBPS(_bw, 1053, 486, 234)), \ -+ BW2VBPS(_bw, 1053, 486, 234)) >> _s, \ - MCS_DURATION(_streams, _sgi, \ -- BW2VBPS(_bw, 1170, 540, 260)), \ -+ BW2VBPS(_bw, 1170, 540, 260)) >> _s, \ - MCS_DURATION(_streams, _sgi, \ -- BW2VBPS(_bw, 1404, 648, 312)), \ -+ BW2VBPS(_bw, 1404, 648, 312)) >> _s, \ - MCS_DURATION(_streams, _sgi, \ -- BW2VBPS(_bw, 1560, 720, 346)) \ -+ BW2VBPS(_bw, 1560, 720, 346)) >> _s \ - } \ - } - -@@ -121,19 +123,20 @@ - (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \ - CCK_DURATION(_bitrate, _short, AVG_PKT_SIZE)) - --#define CCK_DURATION_LIST(_short) \ -- CCK_ACK_DURATION(10, _short), \ -- CCK_ACK_DURATION(20, _short), \ -- CCK_ACK_DURATION(55, _short), \ -- CCK_ACK_DURATION(110, _short) -+#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 - --#define CCK_GROUP \ -+#define CCK_GROUP(_s) \ - [MINSTREL_CCK_GROUP] = { \ - .streams = 0, \ - .flags = 0, \ -+ .shift = _s, \ - .duration = { \ -- CCK_DURATION_LIST(false), \ -- CCK_DURATION_LIST(true) \ -+ CCK_DURATION_LIST(false, _s), \ -+ CCK_DURATION_LIST(true, _s) \ - } \ - } - -@@ -151,47 +154,47 @@ MODULE_PARM_DESC(minstrel_vht_only, - * BW -> SGI -> #streams - */ - const struct mcs_group minstrel_mcs_groups[] = { -- MCS_GROUP(1, 0, BW_20), -- MCS_GROUP(2, 0, BW_20), -- MCS_GROUP(3, 0, BW_20), -- -- MCS_GROUP(1, 1, BW_20), -- MCS_GROUP(2, 1, BW_20), -- MCS_GROUP(3, 1, BW_20), -- -- MCS_GROUP(1, 0, BW_40), -- MCS_GROUP(2, 0, BW_40), -- MCS_GROUP(3, 0, BW_40), -- -- MCS_GROUP(1, 1, BW_40), -- MCS_GROUP(2, 1, BW_40), -- MCS_GROUP(3, 1, BW_40), -- -- CCK_GROUP, -- -- VHT_GROUP(1, 0, BW_20), -- VHT_GROUP(2, 0, BW_20), -- VHT_GROUP(3, 0, BW_20), -- -- VHT_GROUP(1, 1, BW_20), -- VHT_GROUP(2, 1, BW_20), -- VHT_GROUP(3, 1, BW_20), -- -- VHT_GROUP(1, 0, BW_40), -- VHT_GROUP(2, 0, BW_40), -- VHT_GROUP(3, 0, BW_40), -- -- VHT_GROUP(1, 1, BW_40), -- VHT_GROUP(2, 1, BW_40), -- VHT_GROUP(3, 1, BW_40), -- -- VHT_GROUP(1, 0, BW_80), -- VHT_GROUP(2, 0, BW_80), -- VHT_GROUP(3, 0, BW_80), -- -- VHT_GROUP(1, 1, BW_80), -- VHT_GROUP(2, 1, BW_80), -- VHT_GROUP(3, 1, BW_80), -+ MCS_GROUP(1, 0, BW_20, 5), -+ MCS_GROUP(2, 0, BW_20, 4), -+ MCS_GROUP(3, 0, BW_20, 4), -+ -+ MCS_GROUP(1, 1, BW_20, 5), -+ MCS_GROUP(2, 1, BW_20, 4), -+ MCS_GROUP(3, 1, BW_20, 4), -+ -+ MCS_GROUP(1, 0, BW_40, 4), -+ MCS_GROUP(2, 0, BW_40, 4), -+ MCS_GROUP(3, 0, BW_40, 4), -+ -+ MCS_GROUP(1, 1, BW_40, 4), -+ MCS_GROUP(2, 1, BW_40, 4), -+ MCS_GROUP(3, 1, BW_40, 4), -+ -+ CCK_GROUP(8), -+ -+ VHT_GROUP(1, 0, BW_20, 5), -+ VHT_GROUP(2, 0, BW_20, 4), -+ VHT_GROUP(3, 0, BW_20, 4), -+ -+ VHT_GROUP(1, 1, BW_20, 5), -+ VHT_GROUP(2, 1, BW_20, 4), -+ VHT_GROUP(3, 1, BW_20, 4), -+ -+ VHT_GROUP(1, 0, BW_40, 4), -+ VHT_GROUP(2, 0, BW_40, 4), -+ VHT_GROUP(3, 0, BW_40, 4), -+ -+ VHT_GROUP(1, 1, BW_40, 4), -+ VHT_GROUP(2, 1, BW_40, 4), -+ VHT_GROUP(3, 1, BW_40, 4), -+ -+ VHT_GROUP(1, 0, BW_80, 4), -+ VHT_GROUP(2, 0, BW_80, 4), -+ VHT_GROUP(3, 0, BW_80, 4), -+ -+ VHT_GROUP(1, 1, BW_80, 4), -+ VHT_GROUP(2, 1, BW_80, 4), -+ VHT_GROUP(3, 1, BW_80, 4), - }; - - static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; -@@ -307,7 +310,8 @@ minstrel_ht_get_tp_avg(struct minstrel_h - if (group != MINSTREL_CCK_GROUP) - nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); - -- nsecs += minstrel_mcs_groups[group].duration[rate]; -+ nsecs += minstrel_mcs_groups[group].duration[rate] << -+ minstrel_mcs_groups[group].shift; - - /* - * For the throughput calculation, limit the probability value to 90% to -@@ -755,12 +759,19 @@ minstrel_ht_tx_status(void *priv, struct - minstrel_ht_update_rates(mp, mi); - } - -+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 void - minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, - int index) - { - struct minstrel_rate_stats *mrs; -- const struct mcs_group *group; - unsigned int tx_time, tx_time_rtscts, tx_time_data; - unsigned int cw = mp->cw_min; - unsigned int ctime = 0; -@@ -779,8 +790,7 @@ minstrel_calc_retransmit(struct minstrel - mrs->retry_count_rtscts = 2; - mrs->retry_updated = true; - -- group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; -- tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000; -+ tx_time_data = minstrel_get_duration(index) * ampdu_len / 1000; - - /* Contention time for first 2 tries */ - ctime = (t_slot * cw) >> 1; -@@ -874,20 +884,24 @@ minstrel_ht_get_max_amsdu_len(struct min - int group = mi->max_prob_rate / MCS_GROUP_RATES; - const struct mcs_group *g = &minstrel_mcs_groups[group]; - int rate = mi->max_prob_rate % MCS_GROUP_RATES; -+ unsigned int duration; - - /* Disable A-MSDU if max_prob_rate is bad */ - if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100)) - return 1; - -+ duration = g->duration[rate]; -+ duration <<= g->shift; -+ - /* If the rate is slower than single-stream MCS1, make A-MSDU limit small */ -- if (g->duration[rate] > MCS_DURATION(1, 0, 52)) -+ if (duration > MCS_DURATION(1, 0, 52)) - return 500; - - /* - * If the rate is slower than single-stream MCS4, limit A-MSDU to usual - * data packet size - */ -- if (g->duration[rate] > MCS_DURATION(1, 0, 104)) -+ if (duration > MCS_DURATION(1, 0, 104)) - return 1600; - - /* -@@ -895,7 +909,7 @@ minstrel_ht_get_max_amsdu_len(struct min - * rate success probability is less than 75%, limit A-MSDU to twice the usual - * data packet size - */ -- if (g->duration[rate] > MCS_DURATION(1, 0, 260) || -+ if (duration > MCS_DURATION(1, 0, 260) || - (minstrel_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) < - MINSTREL_FRAC(75, 100))) - return 3200; -@@ -942,13 +956,6 @@ minstrel_ht_update_rates(struct minstrel - rate_control_set_rates(mp->hw, mi->sta, rates); - } - --static inline int --minstrel_get_duration(int index) --{ -- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; -- return group->duration[index % MCS_GROUP_RATES]; --} -- - static int - minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) - { ---- a/net/mac80211/rc80211_minstrel_ht.h -+++ b/net/mac80211/rc80211_minstrel_ht.h -@@ -33,9 +33,10 @@ - #define MCS_GROUP_RATES 10 - - struct mcs_group { -- u32 flags; -- unsigned int streams; -- unsigned int duration[MCS_GROUP_RATES]; -+ u16 flags; -+ u8 streams; -+ u8 shift; -+ u16 duration[MCS_GROUP_RATES]; - }; - - extern const struct mcs_group minstrel_mcs_groups[]; ---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c -@@ -58,6 +58,7 @@ minstrel_ht_stats_dump(struct minstrel_h - static const int bitrates[4] = { 10, 20, 55, 110 }; - int idx = i * MCS_GROUP_RATES + j; - unsigned int prob_ewmsd; -+ unsigned int duration; - - if (!(mi->supported[i] & BIT(j))) - continue; -@@ -95,7 +96,9 @@ minstrel_ht_stats_dump(struct minstrel_h - p += sprintf(p, " %3u ", idx); - - /* tx_time[rate(i)] in usec */ -- tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000); -+ duration = mg->duration[j]; -+ duration <<= mg->shift; -+ tx_time = DIV_ROUND_CLOSEST(duration, 1000); - p += sprintf(p, "%6u ", tx_time); - - tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); -@@ -204,6 +207,7 @@ minstrel_ht_stats_csv_dump(struct minstr - static const int bitrates[4] = { 10, 20, 55, 110 }; - int idx = i * MCS_GROUP_RATES + j; - unsigned int prob_ewmsd; -+ unsigned int duration; - - if (!(mi->supported[i] & BIT(j))) - continue; -@@ -238,7 +242,10 @@ minstrel_ht_stats_csv_dump(struct minstr - } - - p += sprintf(p, "%u,", idx); -- tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000); -+ -+ duration = mg->duration[j]; -+ duration <<= mg->shift; -+ tx_time = DIV_ROUND_CLOSEST(duration, 1000); - p += sprintf(p, "%u,", tx_time); - - tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); diff --git a/package/kernel/mac80211/patches/subsys/373-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch b/package/kernel/mac80211/patches/subsys/373-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch deleted file mode 100644 index 502d8c7768..0000000000 --- a/package/kernel/mac80211/patches/subsys/373-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Felix Fietkau -Date: Sat, 10 Feb 2018 13:43:07 +0100 -Subject: [PATCH] mac80211: minstrel: fix using short preamble CCK rates on - HT clients - -mi->supported[MINSTREL_CCK_GROUP] needs to be updated - -Fixes: 782dda00ab8e ("mac80211: minstrel_ht: move short preamble check out of get_rate") -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -1135,7 +1135,6 @@ 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; -- struct sta_info *sinfo = container_of(sta, struct sta_info, sta); - int use_vht; - int n_supported = 0; - int ack_dur; -@@ -1267,8 +1266,7 @@ minstrel_ht_update_caps(void *priv, stru - if (!n_supported) - goto use_legacy; - -- if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE)) -- mi->cck_supported_short |= mi->cck_supported_short << 4; -+ 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); diff --git a/package/kernel/mac80211/patches/subsys/375-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch b/package/kernel/mac80211/patches/subsys/375-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch deleted file mode 100644 index f0ffcd9655..0000000000 --- a/package/kernel/mac80211/patches/subsys/375-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Felix Fietkau -Date: Thu, 1 Mar 2018 13:27:54 +0100 -Subject: [PATCH] mac80211: minstrel: fix CCK rate group streams value - -Fixes a harmless underflow issue when CCK rates are actively being used - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -131,7 +131,7 @@ - - #define CCK_GROUP(_s) \ - [MINSTREL_CCK_GROUP] = { \ -- .streams = 0, \ -+ .streams = 1, \ - .flags = 0, \ - .shift = _s, \ - .duration = { \ diff --git a/package/kernel/mac80211/patches/subsys/376-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch b/package/kernel/mac80211/patches/subsys/376-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch deleted file mode 100644 index e0049c36eb..0000000000 --- a/package/kernel/mac80211/patches/subsys/376-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Felix Fietkau -Date: Thu, 1 Mar 2018 13:28:48 +0100 -Subject: [PATCH] mac80211: minstrel: fix sampling/reporting of CCK rates - in HT mode - -Long/short preamble selection cannot be sampled separately, since it -depends on the BSS state. Because of that, sampling attempts to -currently not used preamble modes are not counted in the statistics, -which leads to CCK rates being sampled too often. - -Fix statistics accounting for long/short preamble by increasing the -index where necessary. -Fix excessive CCK rate sampling by dropping unsupported sample attempts. - -This improves throughput on 2.4 GHz channels - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -281,7 +281,8 @@ minstrel_ht_get_stats(struct minstrel_pr - break; - - /* short preamble */ -- if (!(mi->supported[group] & BIT(idx))) -+ if ((mi->supported[group] & BIT(idx + 4)) && -+ (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) - idx += 4; - } - return &mi->groups[group].rates[idx]; -@@ -1080,18 +1081,23 @@ minstrel_ht_get_rate(void *priv, struct - return; - - sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES]; -+ sample_idx %= MCS_GROUP_RATES; -+ -+ if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP] && -+ (sample_idx >= 4) != txrc->short_preamble) -+ return; -+ - info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; - rate->count = 1; - -- if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { -+ 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->flags & IEEE80211_TX_RC_VHT_MCS) { - ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES, - sample_group->streams); - } else { -- rate->idx = sample_idx % MCS_GROUP_RATES + -- (sample_group->streams - 1) * 8; -+ rate->idx = sample_idx + (sample_group->streams - 1) * 8; - } - - rate->flags = sample_group->flags; diff --git a/package/kernel/mac80211/patches/subsys/377-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch b/package/kernel/mac80211/patches/subsys/377-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch deleted file mode 100644 index 414cb137de..0000000000 --- a/package/kernel/mac80211/patches/subsys/377-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch +++ /dev/null @@ -1,40 +0,0 @@ -From: Felix Fietkau -Date: Sat, 3 Mar 2018 18:48:58 +0100 -Subject: [PATCH] mac80211: minstrel: do not sample rates 3 times slower than - max_prob_rate - -These rates are highly unlikely to be used quickly, even if the link -deteriorates rapidly. This improves throughput in cases where CCK rates -are not reliable enough to be skipped entirely during sampling. -Sampling these rates regularly can cost a lot of airtime. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -1004,10 +1004,13 @@ minstrel_get_sample_rate(struct minstrel - return -1; - - /* -- * Do not sample if the probability is already higher than 95% -- * to avoid wasting airtime. -+ * Do not sample if the probability is already higher than 95%, -+ * or if the rate is 3 times slower than the current max probability -+ * rate, to avoid wasting airtime. - */ -- if (mrs->prob_ewma > MINSTREL_FRAC(95, 100)) -+ sample_dur = minstrel_get_duration(sample_idx); -+ if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) || -+ minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur) - return -1; - - /* -@@ -1017,7 +1020,6 @@ minstrel_get_sample_rate(struct minstrel - - cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 / - MCS_GROUP_RATES].streams; -- sample_dur = minstrel_get_duration(sample_idx); - if (sample_dur >= minstrel_get_duration(tp_rate2) && - (cur_max_tp_streams - 1 < - minstrel_mcs_groups[sample_group].streams || diff --git a/package/kernel/mac80211/patches/subsys/378-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch b/package/kernel/mac80211/patches/subsys/378-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch deleted file mode 100644 index 4e83ff1ea0..0000000000 --- a/package/kernel/mac80211/patches/subsys/378-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Felix Fietkau -Date: Thu, 8 Mar 2018 21:00:56 +0100 -Subject: [PATCH] mac80211: fix memory accounting with A-MSDU aggregation - -fq uses skb->truesize for memory usage tracking. Increments/decrements -are done on enqueue/dequeue. -When A-MSDU aggregation is performed on tx side, the packet is -aggregated with the last packet in the queue belonging to the same flow. -There are multiple bugs here: -- The truesize field of the aggregated packet isn't updated, so memory -usage is underestimated -- fq->memory_usage isn't adjusted. - -Because of the combination of both bugs, this only causes tx issues in -rare cases, mainly when the A-MSDU head needs to be reallocated. - -Fix this by adjusting both truesize of the A-MSDU head and adding the -truesize delta to fq->memory_usage. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3194,6 +3194,7 @@ static bool ieee80211_amsdu_aggregate(st - u8 max_subframes = sta->sta.max_amsdu_subframes; - int max_frags = local->hw.max_tx_fragments; - int max_amsdu_len = sta->sta.max_amsdu_len; -+ int orig_truesize; - __be16 len; - void *data; - bool ret = false; -@@ -3225,12 +3226,13 @@ static bool ieee80211_amsdu_aggregate(st - flow = fq_flow_classify(fq, tin, skb, fq_flow_get_default_func); - head = skb_peek_tail(&flow->queue); - if (!head) -- goto out; -+ goto unlock; - -+ orig_truesize = head->truesize; - orig_len = head->len; - - if (skb->len + head->len > max_amsdu_len) -- goto out; -+ goto unlock; - - nfrags = 1 + skb_shinfo(skb)->nr_frags; - nfrags += 1 + skb_shinfo(head)->nr_frags; -@@ -3288,6 +3290,9 @@ out_recalc: - fq_recalc_backlog(fq, tin, flow); - } - out: -+ fq->memory_usage += head->truesize - orig_truesize; -+ -+unlock: - spin_unlock_bh(&fq->lock); - - return ret; diff --git a/package/kernel/mac80211/patches/subsys/383-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch b/package/kernel/mac80211/patches/subsys/383-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch deleted file mode 100644 index 5b12e87c84..0000000000 --- a/package/kernel/mac80211/patches/subsys/383-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch +++ /dev/null @@ -1,121 +0,0 @@ -From: Felix Fietkau -Date: Wed, 16 Jan 2019 21:47:54 +0100 -Subject: [PATCH] mac80211: minstrel_ht: add flag to indicate - missing/inaccurate tx A-MPDU length - -Some hardware (e.g. MediaTek MT7603) cannot report A-MPDU length in tx status -information. Add support for a flag to indicate that, to allow minstrel_ht -to use a fixed value in its internal calculation (which gives better results -than just defaulting to 1). - -Signed-off-by: Felix Fietkau ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -2134,6 +2134,9 @@ struct ieee80211_txq { - * @IEEE80211_HW_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte. - * Padding will be added after ieee80211_hdr, before IV/LLC. - * -+ * @IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN: Driver does not report accurate A-MPDU -+ * length in tx status information -+ * - * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays - */ - enum ieee80211_hw_flags { -@@ -2180,6 +2183,7 @@ enum ieee80211_hw_flags { - IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP, - IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP, - IEEE80211_HW_NEEDS_ALIGNED4_SKBS, -+ IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN, - - /* keep last, obviously */ - NUM_IEEE80211_HW_FLAGS ---- a/net/mac80211/debugfs.c -+++ b/net/mac80211/debugfs.c -@@ -215,6 +215,7 @@ static const char *hw_flag_names[] = { - FLAG(DEAUTH_NEED_MGD_TX_PREP), - FLAG(DOESNT_SUPPORT_QOS_NDP), - FLAG(NEEDS_ALIGNED4_SKBS), -+ FLAG(TX_STATUS_NO_AMPDU_LEN), - #undef FLAG - }; - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -294,6 +294,15 @@ minstrel_get_ratestats(struct minstrel_h - return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES]; - } - -+static unsigned int -+minstrel_ht_avg_ampdu_len(struct minstrel_ht_sta *mi) -+{ -+ if (!mi->avg_ampdu_len) -+ return AVG_AMPDU_SIZE; -+ -+ return MINSTREL_TRUNC(mi->avg_ampdu_len); -+} -+ - /* - * Return current throughput based on the average A-MPDU length, taking into - * account the expected number of retransmissions and their expected length -@@ -309,7 +318,7 @@ minstrel_ht_get_tp_avg(struct minstrel_h - return 0; - - if (group != MINSTREL_CCK_GROUP) -- nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); -+ nsecs = 1000 * mi->overhead / minstrel_ht_avg_ampdu_len(mi); - - nsecs += minstrel_mcs_groups[group].duration[rate] << - minstrel_mcs_groups[group].shift; -@@ -503,8 +512,12 @@ minstrel_ht_update_stats(struct minstrel - u16 tmp_cck_tp_rate[MAX_THR_RATES], index; - - if (mi->ampdu_packets > 0) { -- mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, -- MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), EWMA_LEVEL); -+ if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN)) -+ mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, -+ MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), -+ EWMA_LEVEL); -+ else -+ mi->avg_ampdu_len = 0; - mi->ampdu_len = 0; - mi->ampdu_packets = 0; - } -@@ -709,7 +722,9 @@ minstrel_ht_tx_status(void *priv, struct - mi->ampdu_len += info->status.ampdu_len; - - if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) { -- mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len); -+ int avg_ampdu_len = minstrel_ht_avg_ampdu_len(mi); -+ -+ mi->sample_wait = 16 + 2 * avg_ampdu_len; - mi->sample_tries = 1; - mi->sample_count--; - } -@@ -777,7 +792,7 @@ minstrel_calc_retransmit(struct minstrel - unsigned int cw = mp->cw_min; - unsigned int ctime = 0; - unsigned int t_slot = 9; /* FIXME */ -- unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len); -+ unsigned int ampdu_len = minstrel_ht_avg_ampdu_len(mi); - unsigned int overhead = 0, overhead_rtscts = 0; - - mrs = minstrel_get_ratestats(mi, index); ---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c -@@ -163,9 +163,10 @@ minstrel_ht_stats_open(struct inode *ino - "lookaround %d\n", - max(0, (int) mi->total_packets - (int) mi->sample_packets), - mi->sample_packets); -- p += sprintf(p, "Average # of aggregated frames per A-MPDU: %d.%d\n", -- MINSTREL_TRUNC(mi->avg_ampdu_len), -- MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); -+ if (mi->avg_ampdu_len) -+ p += sprintf(p, "Average # of aggregated frames per A-MPDU: %d.%d\n", -+ MINSTREL_TRUNC(mi->avg_ampdu_len), -+ MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); - ms->len = p - ms->buf; - WARN_ON(ms->len + sizeof(*ms) > 32768); - diff --git a/package/kernel/mac80211/patches/subsys/390-nl-mac-80211-allow-4addr-AP-operation-on-crypto-cont.patch b/package/kernel/mac80211/patches/subsys/390-nl-mac-80211-allow-4addr-AP-operation-on-crypto-cont.patch index 3f933f8c3b..70670b3ebf 100644 --- a/package/kernel/mac80211/patches/subsys/390-nl-mac-80211-allow-4addr-AP-operation-on-crypto-cont.patch +++ b/package/kernel/mac80211/patches/subsys/390-nl-mac-80211-allow-4addr-AP-operation-on-crypto-cont.patch @@ -50,7 +50,7 @@ Signed-off-by: Manikanta Pubbisetty * control port protocol ethertype. The device also honours the --- a/net/mac80211/util.c +++ b/net/mac80211/util.c -@@ -3523,7 +3523,9 @@ int ieee80211_check_combinations(struct +@@ -3622,7 +3622,9 @@ int ieee80211_check_combinations(struct } /* Always allow software iftypes */