[Refactor and sync wifi from Openwrt]

[Description]
Refactor and sync wifi from Openwrt
1.mt76/mac80211/hostapd/iw/wireless-regdb

[Release-log]
N/A

diff --git a/recipes-kernel/linux-mac80211/files/patches/subsys/330-mac80211-fix-overflow-issues-in-airtime-fairness-cod.patch b/recipes-kernel/linux-mac80211/files/patches/subsys/330-mac80211-fix-overflow-issues-in-airtime-fairness-cod.patch
new file mode 100644
index 0000000..b7c1507
--- /dev/null
+++ b/recipes-kernel/linux-mac80211/files/patches/subsys/330-mac80211-fix-overflow-issues-in-airtime-fairness-cod.patch
@@ -0,0 +1,143 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sat, 28 May 2022 16:44:53 +0200
+Subject: [PATCH] mac80211: fix overflow issues in airtime fairness code
+
+The airtime weight calculation overflows with a default weight value of 256
+whenever more than 8ms worth of airtime is reported.
+Bigger weight values impose even smaller limits on maximum airtime values.
+This can mess up airtime based calculations for drivers that don't report
+per-PPDU airtime values, but batch up values instead.
+
+Fix this by reordering multiplications/shifts and by reducing unnecessary
+intermediate precision (which was lost in a later stage anyway).
+
+The new shift value limits the maximum weight to 4096, which should be more
+than enough. Any values bigger than that will be rejected.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1602,6 +1602,9 @@ static int sta_apply_parameters(struct i
+ 	mask = params->sta_flags_mask;
+ 	set = params->sta_flags_set;
+ 
++	if (params->airtime_weight > BIT(IEEE80211_RECIPROCAL_SHIFT_STA))
++		return -EINVAL;
++
+ 	if (ieee80211_vif_is_mesh(&sdata->vif)) {
+ 		/*
+ 		 * In mesh mode, ASSOCIATED isn't part of the nl80211
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1666,50 +1666,33 @@ static inline struct airtime_info *to_ai
+ /* To avoid divisions in the fast path, we keep pre-computed reciprocals for
+  * airtime weight calculations. There are two different weights to keep track
+  * of: The per-station weight and the sum of weights per phy.
+- *
+- * For the per-station weights (kept in airtime_info below), we use 32-bit
+- * reciprocals with a devisor of 2^19. This lets us keep the multiplications and
+- * divisions for the station weights as 32-bit operations at the cost of a bit
+- * of rounding error for high weights; but the choice of divisor keeps rounding
+- * errors <10% for weights <2^15, assuming no more than 8ms of airtime is
+- * reported at a time.
+- *
+- * For the per-phy sum of weights the values can get higher, so we use 64-bit
+- * operations for those with a 32-bit divisor, which should avoid any
+- * significant rounding errors.
++ * The per-sta shift value supports weight values of 1-4096
+  */
+-#define IEEE80211_RECIPROCAL_DIVISOR_64 0x100000000ULL
+-#define IEEE80211_RECIPROCAL_SHIFT_64 32
+-#define IEEE80211_RECIPROCAL_DIVISOR_32 0x80000U
+-#define IEEE80211_RECIPROCAL_SHIFT_32 19
++#define IEEE80211_RECIPROCAL_SHIFT_SUM	24
++#define IEEE80211_RECIPROCAL_SHIFT_STA	12
++#define IEEE80211_WEIGHT_SHIFT		8
+ 
+-static inline void airtime_weight_set(struct airtime_info *air_info, u16 weight)
++static inline void airtime_weight_set(struct airtime_info *air_info, u32 weight)
+ {
+ 	if (air_info->weight == weight)
+ 		return;
+ 
+ 	air_info->weight = weight;
+-	if (weight) {
+-		air_info->weight_reciprocal =
+-			IEEE80211_RECIPROCAL_DIVISOR_32 / weight;
+-	} else {
+-		air_info->weight_reciprocal = 0;
+-	}
++	if (weight)
++		weight = BIT(IEEE80211_RECIPROCAL_SHIFT_STA) / weight;
++	air_info->weight_reciprocal = weight;
+ }
+ 
+ static inline void airtime_weight_sum_set(struct airtime_sched_info *air_sched,
+-					  int weight_sum)
++					  u32 weight_sum)
+ {
+ 	if (air_sched->weight_sum == weight_sum)
+ 		return;
+ 
+ 	air_sched->weight_sum = weight_sum;
+-	if (air_sched->weight_sum) {
+-		air_sched->weight_sum_reciprocal = IEEE80211_RECIPROCAL_DIVISOR_64;
+-		do_div(air_sched->weight_sum_reciprocal, air_sched->weight_sum);
+-	} else {
+-		air_sched->weight_sum_reciprocal = 0;
+-	}
++	if (weight_sum)
++		weight_sum = BIT(IEEE80211_RECIPROCAL_SHIFT_SUM) / weight_sum;
++	air_sched->weight_sum_reciprocal = weight_sum;
+ }
+ 
+ /* A problem when trying to enforce airtime fairness is that we want to divide
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -1894,9 +1894,9 @@ void ieee80211_register_airtime(struct i
+ {
+ 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
+ 	struct ieee80211_local *local = sdata->local;
+-	u64 weight_sum, weight_sum_reciprocal;
+ 	struct airtime_sched_info *air_sched;
+ 	struct airtime_info *air_info;
++	u64 weight_sum_reciprocal;
+ 	u32 airtime = 0;
+ 
+ 	air_sched = &local->airtime[txq->ac];
+@@ -1907,27 +1907,21 @@ void ieee80211_register_airtime(struct i
+ 	if (local->airtime_flags & AIRTIME_USE_RX)
+ 		airtime += rx_airtime;
+ 
+-	/* Weights scale so the unit weight is 256 */
+-	airtime <<= 8;
+-
+ 	spin_lock_bh(&air_sched->lock);
+ 
+ 	air_info->tx_airtime += tx_airtime;
+ 	air_info->rx_airtime += rx_airtime;
+ 
+-	if (air_sched->weight_sum) {
+-		weight_sum = air_sched->weight_sum;
++	if (air_sched->weight_sum)
+ 		weight_sum_reciprocal = air_sched->weight_sum_reciprocal;
+-	} else {
+-		weight_sum = air_info->weight;
++	else
+ 		weight_sum_reciprocal = air_info->weight_reciprocal;
+-	}
+ 
+ 	/* Round the calculation of global vt */
+-	air_sched->v_t += (u64)((airtime + (weight_sum >> 1)) *
+-				weight_sum_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_64;
+-	air_info->v_t += (u32)((airtime + (air_info->weight >> 1)) *
+-			       air_info->weight_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_32;
++	air_sched->v_t += ((u64)airtime * weight_sum_reciprocal) >>
++			  (IEEE80211_RECIPROCAL_SHIFT_SUM - IEEE80211_WEIGHT_SHIFT);
++	air_info->v_t += (airtime * air_info->weight_reciprocal) >>
++			 (IEEE80211_RECIPROCAL_SHIFT_STA - IEEE80211_WEIGHT_SHIFT);
+ 	ieee80211_resort_txq(&local->hw, txq);
+ 
+ 	spin_unlock_bh(&air_sched->lock);