mirror of
https://github.com/hanwckf/immortalwrt-mt798x.git
synced 2025-01-08 10:23:47 +08:00
Merge Official Source
This commit is contained in:
commit
8f33412f16
@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=mac80211
|
||||
|
||||
PKG_VERSION:=5.4.27-1
|
||||
PKG_RELEASE:=3
|
||||
PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.4.27/
|
||||
PKG_HASH:=4c853a2f4c4fcc81cf60a3d59c5efbdb60c3e4acda22996cb192443581753950
|
||||
PKG_VERSION:=5.7-rc3-1
|
||||
PKG_RELEASE:=2
|
||||
PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.7-rc3/
|
||||
PKG_HASH:=7bc785c932f011c65adb75ffa746be2fa90b16ab61a6e1fd883acee403ffeed1
|
||||
|
||||
PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)
|
||||
|
@ -11,7 +11,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c
|
||||
@@ -104,6 +104,7 @@ static void owl_fw_cb(const struct firmw
|
||||
@@ -103,6 +103,7 @@ static void owl_fw_cb(const struct firmw
|
||||
{
|
||||
struct pci_dev *pdev = (struct pci_dev *)context;
|
||||
struct owl_ctx *ctx = (struct owl_ctx *)pci_get_drvdata(pdev);
|
||||
@ -19,7 +19,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
struct pci_bus *bus;
|
||||
|
||||
complete(&ctx->eeprom_load);
|
||||
@@ -119,6 +120,16 @@ static void owl_fw_cb(const struct firmw
|
||||
@@ -118,6 +119,16 @@ static void owl_fw_cb(const struct firmw
|
||||
goto release;
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
if (ath9k_pci_fixup(pdev, (const u16 *)fw->data, fw->size))
|
||||
goto release;
|
||||
|
||||
@@ -138,8 +149,14 @@ release:
|
||||
@@ -137,8 +148,14 @@ release:
|
||||
static const char *owl_get_eeprom_name(struct pci_dev *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/wireless/ath/Makefile
|
||||
+++ b/drivers/net/wireless/ath/Makefile
|
||||
@@ -14,10 +14,10 @@ ath-objs := main.o \
|
||||
@@ -15,10 +15,10 @@ ath-objs := main.o \
|
||||
regd.o \
|
||||
hw.o \
|
||||
key.o \
|
||||
|
@ -4,15 +4,15 @@
|
||||
NL80211_RRF_NO_OFDM)
|
||||
|
||||
/* We allow IBSS on these on a case by case basis by regulatory domain */
|
||||
-#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\
|
||||
+#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5240+10, 80, 0, 30, 0),\
|
||||
-#define ATH_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\
|
||||
+#define ATH_5GHZ_5150_5350 REG_RULE(5150-10, 5240+10, 80, 0, 30, 0),\
|
||||
+ REG_RULE(5260-10, 5350+10, 80, 0, 30,\
|
||||
NL80211_RRF_NO_IR)
|
||||
#define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\
|
||||
#define ATH_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\
|
||||
NL80211_RRF_NO_IR)
|
||||
@@ -62,57 +63,56 @@ static struct reg_dmn_pair_mapping *ath_
|
||||
#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \
|
||||
ATH9K_5GHZ_5725_5850
|
||||
#define ATH_5GHZ_NO_MIDBAND ATH_5GHZ_5150_5350, \
|
||||
ATH_5GHZ_5725_5850
|
||||
|
||||
+#define REGD_RULES(...) \
|
||||
+ .reg_rules = { __VA_ARGS__ }, \
|
||||
@ -25,8 +25,8 @@
|
||||
.alpha2 = "99",
|
||||
- .reg_rules = {
|
||||
+ REGD_RULES(
|
||||
ATH9K_2GHZ_ALL,
|
||||
ATH9K_5GHZ_ALL,
|
||||
ATH_2GHZ_ALL,
|
||||
ATH_5GHZ_ALL,
|
||||
- }
|
||||
+ )
|
||||
};
|
||||
@ -37,9 +37,9 @@
|
||||
.alpha2 = "99",
|
||||
- .reg_rules = {
|
||||
+ REGD_RULES(
|
||||
ATH9K_2GHZ_CH01_11,
|
||||
ATH9K_2GHZ_CH12_13,
|
||||
ATH9K_5GHZ_NO_MIDBAND,
|
||||
ATH_2GHZ_CH01_11,
|
||||
ATH_2GHZ_CH12_13,
|
||||
ATH_5GHZ_NO_MIDBAND,
|
||||
- }
|
||||
+ )
|
||||
};
|
||||
@ -50,8 +50,8 @@
|
||||
.alpha2 = "99",
|
||||
- .reg_rules = {
|
||||
+ REGD_RULES(
|
||||
ATH9K_2GHZ_CH01_11,
|
||||
ATH9K_5GHZ_NO_MIDBAND,
|
||||
ATH_2GHZ_CH01_11,
|
||||
ATH_5GHZ_NO_MIDBAND,
|
||||
- }
|
||||
+ )
|
||||
};
|
||||
@ -62,8 +62,8 @@
|
||||
.alpha2 = "99",
|
||||
- .reg_rules = {
|
||||
+ REGD_RULES(
|
||||
ATH9K_2GHZ_CH01_11,
|
||||
ATH9K_5GHZ_ALL,
|
||||
ATH_2GHZ_CH01_11,
|
||||
ATH_5GHZ_ALL,
|
||||
- }
|
||||
+ )
|
||||
};
|
||||
@ -74,9 +74,9 @@
|
||||
.alpha2 = "99",
|
||||
- .reg_rules = {
|
||||
+ REGD_RULES(
|
||||
ATH9K_2GHZ_CH01_11,
|
||||
ATH9K_2GHZ_CH12_13,
|
||||
ATH9K_5GHZ_ALL,
|
||||
ATH_2GHZ_CH01_11,
|
||||
ATH_2GHZ_CH12_13,
|
||||
ATH_5GHZ_ALL,
|
||||
- }
|
||||
+ )
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/net/wireless/reg.c
|
||||
+++ b/net/wireless/reg.c
|
||||
@@ -3039,6 +3039,8 @@ void regulatory_hint_country_ie(struct w
|
||||
@@ -3041,6 +3041,8 @@ void regulatory_hint_country_ie(struct w
|
||||
enum environment_cap env = ENVIRON_ANY;
|
||||
struct regulatory_request *request = NULL, *lr;
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
/* IE len must be evenly divisible by 2 */
|
||||
if (country_ie_len & 0x01)
|
||||
return;
|
||||
@@ -3290,6 +3292,7 @@ static bool is_wiphy_all_set_reg_flag(en
|
||||
@@ -3292,6 +3294,7 @@ static bool is_wiphy_all_set_reg_flag(en
|
||||
|
||||
void regulatory_hint_disconnect(void)
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
|
||||
@@ -3074,6 +3074,16 @@ int ath10k_core_register(struct ath10k *
|
||||
@@ -3174,6 +3174,16 @@ int ath10k_core_register(struct ath10k *
|
||||
|
||||
queue_work(ar->workqueue, &ar->register_work);
|
||||
|
||||
|
@ -26,7 +26,7 @@ Forwarded: https://patchwork.kernel.org/patch/11367055/
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/htt.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/htt.h
|
||||
@@ -2219,7 +2219,7 @@ struct htt_rx_chan_info {
|
||||
@@ -2221,7 +2221,7 @@ struct htt_rx_chan_info {
|
||||
* Should be: sizeof(struct htt_host_rx_desc) + max rx MSDU size,
|
||||
* rounded up to a cache line size.
|
||||
*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -8673,6 +8673,21 @@ static int ath10k_mac_init_rd(struct ath
|
||||
@@ -8781,6 +8781,21 @@ static int ath10k_mac_init_rd(struct ath
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
int ath10k_mac_register(struct ath10k *ar)
|
||||
{
|
||||
static const u32 cipher_suites[] = {
|
||||
@@ -9000,6 +9015,12 @@ int ath10k_mac_register(struct ath10k *a
|
||||
@@ -9109,6 +9124,12 @@ int ath10k_mac_register(struct ath10k *a
|
||||
|
||||
ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
|
||||
|
||||
|
@ -23,7 +23,7 @@ v9: use SM/MS macros from code.h to simplify shift/mask handling
|
||||
3 files changed, 52 insertions(+), 23 deletions(-)
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -2515,7 +2515,7 @@ static void ath10k_peer_assoc_h_vht(stru
|
||||
@@ -2517,7 +2517,7 @@ static void ath10k_peer_assoc_h_vht(stru
|
||||
const u16 *vht_mcs_mask;
|
||||
u8 ampdu_factor;
|
||||
u8 max_nss, vht_mcs;
|
||||
@ -32,7 +32,7 @@ v9: use SM/MS macros from code.h to simplify shift/mask handling
|
||||
|
||||
if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
|
||||
return;
|
||||
@@ -2575,23 +2575,45 @@ static void ath10k_peer_assoc_h_vht(stru
|
||||
@@ -2577,23 +2577,45 @@ static void ath10k_peer_assoc_h_vht(stru
|
||||
__le16_to_cpu(vht_cap->vht_mcs.tx_highest);
|
||||
arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
|
||||
__le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
|
||||
@ -92,7 +92,7 @@ v9: use SM/MS macros from code.h to simplify shift/mask handling
|
||||
}
|
||||
|
||||
static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
|
||||
@@ -2743,9 +2765,9 @@ static int ath10k_peer_assoc_prepare(str
|
||||
@@ -2745,9 +2767,9 @@ static int ath10k_peer_assoc_prepare(str
|
||||
ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
|
||||
@ -105,7 +105,7 @@ v9: use SM/MS macros from code.h to simplify shift/mask handling
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -7552,12 +7552,7 @@ ath10k_wmi_peer_assoc_fill_10_4(struct a
|
||||
@@ -7628,12 +7628,7 @@ ath10k_wmi_peer_assoc_fill_10_4(struct a
|
||||
struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf;
|
||||
|
||||
ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg);
|
||||
@ -121,7 +121,7 @@ v9: use SM/MS macros from code.h to simplify shift/mask handling
|
||||
static int
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
@@ -6478,7 +6478,19 @@ struct wmi_10_2_peer_assoc_complete_cmd
|
||||
@@ -6508,7 +6508,19 @@ struct wmi_10_2_peer_assoc_complete_cmd
|
||||
__le32 info0; /* WMI_PEER_ASSOC_INFO0_ */
|
||||
} __packed;
|
||||
|
||||
|
@ -13,7 +13,7 @@ v2: fix trailing whitespace issue and fix some typos within the commit note
|
||||
2 files changed, 8 insertions(+), 10 deletions(-)
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -4575,13 +4575,6 @@ static struct ieee80211_sta_vht_cap ath1
|
||||
@@ -4585,13 +4585,6 @@ static struct ieee80211_sta_vht_cap ath1
|
||||
vht_cap.cap |= val;
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ v2: fix trailing whitespace issue and fix some typos within the commit note
|
||||
if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -1700,13 +1700,18 @@ void ath10k_wmi_put_wmi_channel(struct w
|
||||
@@ -1713,13 +1713,18 @@ void ath10k_wmi_put_wmi_channel(struct w
|
||||
flags |= WMI_CHAN_FLAG_HT40_PLUS;
|
||||
if (arg->chan_radar)
|
||||
flags |= WMI_CHAN_FLAG_DFS;
|
||||
|
@ -124,7 +124,7 @@ v13:
|
||||
WCN36XX=
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
|
||||
@@ -24,6 +24,7 @@
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "testmode.h"
|
||||
#include "wmi-ops.h"
|
||||
#include "coredump.h"
|
||||
@ -132,7 +132,7 @@ v13:
|
||||
|
||||
unsigned int ath10k_debug_mask;
|
||||
EXPORT_SYMBOL(ath10k_debug_mask);
|
||||
@@ -60,6 +61,7 @@ static const struct ath10k_hw_params ath
|
||||
@@ -61,6 +62,7 @@ static const struct ath10k_hw_params ath
|
||||
.dev_id = QCA988X_2_0_DEVICE_ID,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.name = "qca988x hw2.0",
|
||||
@ -140,7 +140,7 @@ v13:
|
||||
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
||||
@@ -130,6 +132,7 @@ static const struct ath10k_hw_params ath
|
||||
@@ -131,6 +133,7 @@ static const struct ath10k_hw_params ath
|
||||
.dev_id = QCA9887_1_0_DEVICE_ID,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.name = "qca9887 hw1.0",
|
||||
@ -148,7 +148,7 @@ v13:
|
||||
.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
||||
@@ -337,6 +340,7 @@ static const struct ath10k_hw_params ath
|
||||
@@ -339,6 +342,7 @@ static const struct ath10k_hw_params ath
|
||||
.dev_id = QCA99X0_2_0_DEVICE_ID,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.name = "qca99x0 hw2.0",
|
||||
@ -156,7 +156,7 @@ v13:
|
||||
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.otp_exe_param = 0x00000700,
|
||||
@@ -378,6 +382,7 @@ static const struct ath10k_hw_params ath
|
||||
@@ -380,6 +384,7 @@ static const struct ath10k_hw_params ath
|
||||
.dev_id = QCA9984_1_0_DEVICE_ID,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.name = "qca9984/qca9994 hw1.0",
|
||||
@ -164,7 +164,7 @@ v13:
|
||||
.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
||||
@@ -426,6 +431,7 @@ static const struct ath10k_hw_params ath
|
||||
@@ -428,6 +433,7 @@ static const struct ath10k_hw_params ath
|
||||
.dev_id = QCA9888_2_0_DEVICE_ID,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.name = "qca9888 hw2.0",
|
||||
@ -172,7 +172,7 @@ v13:
|
||||
.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
||||
@@ -2791,6 +2797,10 @@ int ath10k_core_start(struct ath10k *ar,
|
||||
@@ -2889,6 +2895,10 @@ int ath10k_core_start(struct ath10k *ar,
|
||||
goto err_hif_stop;
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ v13:
|
||||
return 0;
|
||||
|
||||
err_hif_stop:
|
||||
@@ -3047,9 +3057,18 @@ static void ath10k_core_register_work(st
|
||||
@@ -3147,9 +3157,18 @@ static void ath10k_core_register_work(st
|
||||
goto err_spectral_destroy;
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ v13:
|
||||
err_spectral_destroy:
|
||||
ath10k_spectral_destroy(ar);
|
||||
err_debug_destroy:
|
||||
@@ -3095,6 +3114,8 @@ void ath10k_core_unregister(struct ath10
|
||||
@@ -3195,6 +3214,8 @@ void ath10k_core_unregister(struct ath10
|
||||
if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
|
||||
return;
|
||||
|
||||
@ -221,7 +221,7 @@ v13:
|
||||
|
||||
#include "htt.h"
|
||||
#include "htc.h"
|
||||
@@ -1170,6 +1171,13 @@ struct ath10k {
|
||||
@@ -1182,6 +1183,13 @@ struct ath10k {
|
||||
} testmode;
|
||||
|
||||
struct {
|
||||
@ -233,11 +233,11 @@ v13:
|
||||
+
|
||||
+ struct {
|
||||
/* protected by data_lock */
|
||||
u32 rx_crc_err_drop;
|
||||
u32 fw_crash_counter;
|
||||
u32 fw_warm_reset_counter;
|
||||
--- a/drivers/net/wireless/ath/ath10k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/hw.h
|
||||
@@ -514,6 +514,7 @@ struct ath10k_hw_params {
|
||||
@@ -517,6 +517,7 @@ struct ath10k_hw_params {
|
||||
const char *name;
|
||||
u32 patch_load_addr;
|
||||
int uart_pin;
|
||||
@ -397,7 +397,7 @@ v13:
|
||||
+#endif /* _LEDS_H_ */
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -23,6 +23,7 @@
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "wmi-tlv.h"
|
||||
#include "wmi-ops.h"
|
||||
#include "wow.h"
|
||||
@ -456,7 +456,7 @@ v13:
|
||||
{
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
|
||||
@@ -4367,6 +4367,8 @@ static const struct wmi_ops wmi_tlv_ops
|
||||
@@ -4447,6 +4447,8 @@ static const struct wmi_ops wmi_tlv_ops
|
||||
.gen_echo = ath10k_wmi_tlv_op_gen_echo,
|
||||
.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
|
||||
.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
|
||||
@ -467,7 +467,7 @@ v13:
|
||||
static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -7372,6 +7372,49 @@ ath10k_wmi_op_gen_peer_set_param(struct
|
||||
@@ -7448,6 +7448,49 @@ ath10k_wmi_op_gen_peer_set_param(struct
|
||||
return skb;
|
||||
}
|
||||
|
||||
@ -517,7 +517,7 @@ v13:
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_sta_ps_mode psmode)
|
||||
@@ -9029,6 +9072,9 @@ static const struct wmi_ops wmi_ops = {
|
||||
@@ -9105,6 +9148,9 @@ static const struct wmi_ops wmi_ops = {
|
||||
.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
.gen_echo = ath10k_wmi_op_gen_echo,
|
||||
@ -527,7 +527,7 @@ v13:
|
||||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
@@ -9099,6 +9145,8 @@ static const struct wmi_ops wmi_10_1_ops
|
||||
@@ -9175,6 +9221,8 @@ static const struct wmi_ops wmi_10_1_ops
|
||||
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
.gen_echo = ath10k_wmi_op_gen_echo,
|
||||
@ -536,7 +536,7 @@ v13:
|
||||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
@@ -9171,6 +9219,8 @@ static const struct wmi_ops wmi_10_2_ops
|
||||
@@ -9247,6 +9295,8 @@ static const struct wmi_ops wmi_10_2_ops
|
||||
.gen_delba_send = ath10k_wmi_op_gen_delba_send,
|
||||
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
@ -545,7 +545,7 @@ v13:
|
||||
/* .gen_pdev_enable_adaptive_cca not implemented */
|
||||
};
|
||||
|
||||
@@ -9242,6 +9292,8 @@ static const struct wmi_ops wmi_10_2_4_o
|
||||
@@ -9318,6 +9368,8 @@ static const struct wmi_ops wmi_10_2_4_o
|
||||
ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
|
||||
.get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype,
|
||||
.gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing,
|
||||
@ -554,7 +554,7 @@ v13:
|
||||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
@@ -9322,6 +9374,8 @@ static const struct wmi_ops wmi_10_4_ops
|
||||
@@ -9398,6 +9450,8 @@ static const struct wmi_ops wmi_10_4_ops
|
||||
.gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info,
|
||||
.gen_echo = ath10k_wmi_op_gen_echo,
|
||||
.gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
|
||||
@ -565,7 +565,7 @@ v13:
|
||||
int ath10k_wmi_attach(struct ath10k *ar)
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
@@ -3005,6 +3005,41 @@ enum wmi_10_4_feature_mask {
|
||||
@@ -3014,6 +3014,41 @@ enum wmi_10_4_feature_mask {
|
||||
|
||||
};
|
||||
|
||||
|
@ -16,9 +16,9 @@ Signed-off-by: Mathias Kresin <dev@kresin.me>
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.h
|
||||
@@ -1219,6 +1219,10 @@ struct ath10k {
|
||||
struct ath10k_bus_params bus_param;
|
||||
struct completion peer_delete_done;
|
||||
@@ -1235,6 +1235,10 @@ struct ath10k {
|
||||
bool coex_support;
|
||||
int coex_gpio_pin;
|
||||
|
||||
+#ifdef CPTCFG_MAC80211_LEDS
|
||||
+ const char *led_default_trigger;
|
||||
@ -42,7 +42,7 @@ Signed-off-by: Mathias Kresin <dev@kresin.me>
|
||||
if (ret)
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -9032,7 +9032,7 @@ int ath10k_mac_register(struct ath10k *a
|
||||
@@ -9141,7 +9141,7 @@ int ath10k_mac_register(struct ath10k *a
|
||||
ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
|
||||
|
||||
#ifdef CPTCFG_MAC80211_LEDS
|
||||
|
@ -20,7 +20,7 @@ Forwarded: https://patchwork.kernel.org/patch/10986723/
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -1041,7 +1041,7 @@ static int ath10k_monitor_vdev_start(str
|
||||
@@ -1043,7 +1043,7 @@ static int ath10k_monitor_vdev_start(str
|
||||
arg.channel.min_power = 0;
|
||||
arg.channel.max_power = channel->max_power * 2;
|
||||
arg.channel.max_reg_power = channel->max_reg_power * 2;
|
||||
@ -29,7 +29,7 @@ Forwarded: https://patchwork.kernel.org/patch/10986723/
|
||||
|
||||
reinit_completion(&ar->vdev_setup_done);
|
||||
reinit_completion(&ar->vdev_delete_done);
|
||||
@@ -1487,7 +1487,7 @@ static int ath10k_vdev_start_restart(str
|
||||
@@ -1489,7 +1489,7 @@ static int ath10k_vdev_start_restart(str
|
||||
arg.channel.min_power = 0;
|
||||
arg.channel.max_power = chandef->chan->max_power * 2;
|
||||
arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
|
||||
@ -38,7 +38,7 @@ Forwarded: https://patchwork.kernel.org/patch/10986723/
|
||||
|
||||
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
|
||||
arg.ssid = arvif->u.ap.ssid;
|
||||
@@ -3168,7 +3168,7 @@ static int ath10k_update_channel_list(st
|
||||
@@ -3170,7 +3170,7 @@ static int ath10k_update_channel_list(st
|
||||
ch->min_power = 0;
|
||||
ch->max_power = channel->max_power * 2;
|
||||
ch->max_reg_power = channel->max_reg_power * 2;
|
||||
|
@ -28,7 +28,7 @@ Forwarded: no
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -1009,6 +1009,40 @@ static inline int ath10k_vdev_setup_sync
|
||||
@@ -1011,6 +1011,40 @@ static inline int ath10k_vdev_setup_sync
|
||||
return ar->last_wmi_vdev_start_status;
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ Forwarded: no
|
||||
static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
|
||||
{
|
||||
struct cfg80211_chan_def *chandef = NULL;
|
||||
@@ -1041,7 +1075,8 @@ static int ath10k_monitor_vdev_start(str
|
||||
@@ -1043,7 +1077,8 @@ static int ath10k_monitor_vdev_start(str
|
||||
arg.channel.min_power = 0;
|
||||
arg.channel.max_power = channel->max_power * 2;
|
||||
arg.channel.max_reg_power = channel->max_reg_power * 2;
|
||||
@ -79,7 +79,7 @@ Forwarded: no
|
||||
|
||||
reinit_completion(&ar->vdev_setup_done);
|
||||
reinit_completion(&ar->vdev_delete_done);
|
||||
@@ -1487,7 +1522,8 @@ static int ath10k_vdev_start_restart(str
|
||||
@@ -1489,7 +1524,8 @@ static int ath10k_vdev_start_restart(str
|
||||
arg.channel.min_power = 0;
|
||||
arg.channel.max_power = chandef->chan->max_power * 2;
|
||||
arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
|
||||
@ -89,7 +89,7 @@ Forwarded: no
|
||||
|
||||
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
|
||||
arg.ssid = arvif->u.ap.ssid;
|
||||
@@ -3168,7 +3204,8 @@ static int ath10k_update_channel_list(st
|
||||
@@ -3170,7 +3206,8 @@ static int ath10k_update_channel_list(st
|
||||
ch->min_power = 0;
|
||||
ch->max_power = channel->max_power * 2;
|
||||
ch->max_reg_power = channel->max_reg_power * 2;
|
||||
|
@ -1,28 +0,0 @@
|
||||
From 1524cbf3621576c639405e7aabeac415f9617c8d Mon Sep 17 00:00:00 2001
|
||||
From: Adrian Ratiu <adrian.ratiu@collabora.com>
|
||||
Date: Wed, 25 Sep 2019 16:44:57 +0300
|
||||
Subject: [PATCH] brcmfmac: don't WARN when there are no requests
|
||||
|
||||
When n_reqs == 0 there is nothing to do so it doesn't make sense to
|
||||
search for requests and issue a warning because none is found.
|
||||
|
||||
Signed-off-by: Martyn Welch <martyn.welch@collabora.com>
|
||||
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
|
||||
@@ -57,6 +57,10 @@ static int brcmf_pno_remove_request(stru
|
||||
|
||||
mutex_lock(&pi->req_lock);
|
||||
|
||||
+ /* Nothing to do if we have no requests */
|
||||
+ if (pi->n_reqs == 0)
|
||||
+ goto done;
|
||||
+
|
||||
/* find request */
|
||||
for (i = 0; i < pi->n_reqs; i++) {
|
||||
if (pi->reqs[i]->reqid == reqid)
|
@ -1,109 +0,0 @@
|
||||
From e0ae4bac22effbd644add326f658a3aeeb8d45ee Mon Sep 17 00:00:00 2001
|
||||
From: Adrian Ratiu <adrian.ratiu@collabora.com>
|
||||
Date: Wed, 25 Sep 2019 16:44:58 +0300
|
||||
Subject: [PATCH] brcmfmac: fix suspend/resume when power is cut off
|
||||
|
||||
brcmfmac assumed the wifi device always remains powered on and thus
|
||||
hardcoded the MMC_PM_KEEP_POWER flag expecting the wifi device to
|
||||
remain on even during suspend/resume cycles.
|
||||
|
||||
This is not always the case, some appliances cut power to everything
|
||||
connected via SDIO for efficiency reasons and this leads to wifi not
|
||||
being usable after coming out of suspend because the device was not
|
||||
correctly reinitialized.
|
||||
|
||||
So we check for the keep_power capability and if it's not present then
|
||||
we remove the device and probe it again during resume to mirror what's
|
||||
happening in hardware and ensure correct reinitialization in the case
|
||||
when MMC_PM_KEEP_POWER is not supported.
|
||||
|
||||
Suggested-by: Gustavo Padovan <gustavo.padovan@collabora.com>
|
||||
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/bcmsdh.c | 53 ++++++++++++++-----
|
||||
1 file changed, 39 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -1108,7 +1108,8 @@ static int brcmf_ops_sdio_suspend(struct
|
||||
struct sdio_func *func;
|
||||
struct brcmf_bus *bus_if;
|
||||
struct brcmf_sdio_dev *sdiodev;
|
||||
- mmc_pm_flag_t sdio_flags;
|
||||
+ mmc_pm_flag_t pm_caps, sdio_flags;
|
||||
+ int ret = 0;
|
||||
|
||||
func = container_of(dev, struct sdio_func, dev);
|
||||
brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
|
||||
@@ -1119,19 +1120,33 @@ static int brcmf_ops_sdio_suspend(struct
|
||||
bus_if = dev_get_drvdata(dev);
|
||||
sdiodev = bus_if->bus_priv.sdio;
|
||||
|
||||
- brcmf_sdiod_freezer_on(sdiodev);
|
||||
- brcmf_sdio_wd_timer(sdiodev->bus, 0);
|
||||
+ pm_caps = sdio_get_host_pm_caps(func);
|
||||
|
||||
- sdio_flags = MMC_PM_KEEP_POWER;
|
||||
- if (sdiodev->wowl_enabled) {
|
||||
- if (sdiodev->settings->bus.sdio.oob_irq_supported)
|
||||
- enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
|
||||
- else
|
||||
- sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;
|
||||
+ if (pm_caps & MMC_PM_KEEP_POWER) {
|
||||
+ /* preserve card power during suspend */
|
||||
+ brcmf_sdiod_freezer_on(sdiodev);
|
||||
+ brcmf_sdio_wd_timer(sdiodev->bus, 0);
|
||||
+
|
||||
+ sdio_flags = MMC_PM_KEEP_POWER;
|
||||
+ if (sdiodev->wowl_enabled) {
|
||||
+ if (sdiodev->settings->bus.sdio.oob_irq_supported)
|
||||
+ enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
|
||||
+ else
|
||||
+ sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;
|
||||
+ }
|
||||
+
|
||||
+ if (sdio_set_host_pm_flags(sdiodev->func1, sdio_flags))
|
||||
+ brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
|
||||
+
|
||||
+ } else {
|
||||
+ /* power will be cut so remove device, probe again in resume */
|
||||
+ brcmf_sdiod_intr_unregister(sdiodev);
|
||||
+ ret = brcmf_sdiod_remove(sdiodev);
|
||||
+ if (ret)
|
||||
+ brcmf_err("Failed to remove device on suspend\n");
|
||||
}
|
||||
- if (sdio_set_host_pm_flags(sdiodev->func1, sdio_flags))
|
||||
- brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
|
||||
- return 0;
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int brcmf_ops_sdio_resume(struct device *dev)
|
||||
@@ -1139,13 +1154,23 @@ static int brcmf_ops_sdio_resume(struct
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
struct sdio_func *func = container_of(dev, struct sdio_func, dev);
|
||||
+ mmc_pm_flag_t pm_caps = sdio_get_host_pm_caps(func);
|
||||
+ int ret = 0;
|
||||
|
||||
brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
|
||||
if (func->num != 2)
|
||||
return 0;
|
||||
|
||||
- brcmf_sdiod_freezer_off(sdiodev);
|
||||
- return 0;
|
||||
+ if (!(pm_caps & MMC_PM_KEEP_POWER)) {
|
||||
+ /* bus was powered off and device removed, probe again */
|
||||
+ ret = brcmf_sdiod_probe(sdiodev);
|
||||
+ if (ret)
|
||||
+ brcmf_err("Failed to probe device on resume\n");
|
||||
+ } else {
|
||||
+ brcmf_sdiod_freezer_off(sdiodev);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops brcmf_sdio_pm_ops = {
|
@ -1,58 +0,0 @@
|
||||
From 7af496b9eb0433bc4cb478c9a46f85509cdb5541 Mon Sep 17 00:00:00 2001
|
||||
From: zhengbin <zhengbin13@huawei.com>
|
||||
Date: Sat, 16 Nov 2019 15:22:47 +0800
|
||||
Subject: [PATCH] brcmfmac: remove set but not used variable
|
||||
'mpnum','nsp','nmp'
|
||||
|
||||
Fixes gcc '-Wunused-but-set-variable' warning:
|
||||
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c: In function brcmf_chip_dmp_get_regaddr:
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c:790:5: warning: variable mpnum set but not used [-Wunused-but-set-variable]
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c: In function brcmf_chip_dmp_erom_scan:
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c:866:10: warning: variable nsp set but not used [-Wunused-but-set-variable]
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c: In function brcmf_chip_dmp_erom_scan:
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c:866:5: warning: variable nmp set but not used [-Wunused-but-set-variable]
|
||||
|
||||
Reported-by: Hulk Robot <hulkci@huawei.com>
|
||||
Signed-off-by: zhengbin <zhengbin13@huawei.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 6 +-----
|
||||
1 file changed, 1 insertion(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
@@ -778,7 +778,6 @@ static int brcmf_chip_dmp_get_regaddr(st
|
||||
{
|
||||
u8 desc;
|
||||
u32 val, szdesc;
|
||||
- u8 mpnum = 0;
|
||||
u8 stype, sztype, wraptype;
|
||||
|
||||
*regbase = 0;
|
||||
@@ -786,7 +785,6 @@ static int brcmf_chip_dmp_get_regaddr(st
|
||||
|
||||
val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
|
||||
if (desc == DMP_DESC_MASTER_PORT) {
|
||||
- mpnum = (val & DMP_MASTER_PORT_NUM) >> DMP_MASTER_PORT_NUM_S;
|
||||
wraptype = DMP_SLAVE_TYPE_MWRAP;
|
||||
} else if (desc == DMP_DESC_ADDRESS) {
|
||||
/* revert erom address */
|
||||
@@ -854,7 +852,7 @@ int brcmf_chip_dmp_erom_scan(struct brcm
|
||||
u8 desc_type = 0;
|
||||
u32 val;
|
||||
u16 id;
|
||||
- u8 nmp, nsp, nmw, nsw, rev;
|
||||
+ u8 nmw, nsw, rev;
|
||||
u32 base, wrap;
|
||||
int err;
|
||||
|
||||
@@ -880,8 +878,6 @@ int brcmf_chip_dmp_erom_scan(struct brcm
|
||||
return -EFAULT;
|
||||
|
||||
/* only look at cores with master port(s) */
|
||||
- nmp = (val & DMP_COMP_NUM_MPORT) >> DMP_COMP_NUM_MPORT_S;
|
||||
- nsp = (val & DMP_COMP_NUM_SPORT) >> DMP_COMP_NUM_SPORT_S;
|
||||
nmw = (val & DMP_COMP_NUM_MWRAP) >> DMP_COMP_NUM_MWRAP_S;
|
||||
nsw = (val & DMP_COMP_NUM_SWRAP) >> DMP_COMP_NUM_SWRAP_S;
|
||||
rev = (val & DMP_COMP_REVISION) >> DMP_COMP_REVISION_S;
|
@ -1,29 +0,0 @@
|
||||
From 8d9627b05b2c33e4468e65739eb7caf9c3f274d8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Tue, 10 Dec 2019 12:35:55 +0100
|
||||
Subject: [PATCH] brcmfmac: set interface carrier to off by default
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
It's important as brcmfmac creates one main interface for each PHY and
|
||||
doesn't allow deleting it. Not setting carrier could result in other
|
||||
subsystems misbehaving (e.g. LEDs "netdev" trigger turning LED on).
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -678,6 +678,8 @@ int brcmf_net_attach(struct brcmf_if *if
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ netif_carrier_off(ndev);
|
||||
+
|
||||
netdev_set_priv_destructor(ndev, brcmf_cfg80211_free_netdev);
|
||||
brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
|
||||
return 0;
|
@ -1,121 +0,0 @@
|
||||
From 1b8d2e0a9e4221b99eea375c079507ce8ef655f5 Mon Sep 17 00:00:00 2001
|
||||
From: Wright Feng <wright.feng@cypress.com>
|
||||
Date: Thu, 12 Dec 2019 00:52:45 +0100
|
||||
Subject: [PATCH 1/7] brcmfmac: reset two D11 cores if chip has two D11 cores
|
||||
|
||||
There are two D11 cores in RSDB chips like 4359. We have to reset two
|
||||
D11 cores simutaneously before firmware download, or the firmware may
|
||||
not be initialized correctly and cause "fw initialized failed" error.
|
||||
|
||||
Signed-off-by: Wright Feng <wright.feng@cypress.com>
|
||||
Signed-off-by: Soeren Moch <smoch@web.de>
|
||||
Reviewed-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/chip.c | 50 +++++++++++++++++++
|
||||
.../broadcom/brcm80211/brcmfmac/chip.h | 1 +
|
||||
.../broadcom/brcm80211/brcmfmac/pcie.c | 2 +-
|
||||
3 files changed, 52 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
@@ -433,11 +433,25 @@ static void brcmf_chip_ai_resetcore(stru
|
||||
{
|
||||
struct brcmf_chip_priv *ci;
|
||||
int count;
|
||||
+ struct brcmf_core *d11core2 = NULL;
|
||||
+ struct brcmf_core_priv *d11priv2 = NULL;
|
||||
|
||||
ci = core->chip;
|
||||
|
||||
+ /* special handle two D11 cores reset */
|
||||
+ if (core->pub.id == BCMA_CORE_80211) {
|
||||
+ d11core2 = brcmf_chip_get_d11core(&ci->pub, 1);
|
||||
+ if (d11core2) {
|
||||
+ brcmf_dbg(INFO, "found two d11 cores, reset both\n");
|
||||
+ d11priv2 = container_of(d11core2,
|
||||
+ struct brcmf_core_priv, pub);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* must disable first to work for arbitrary current core state */
|
||||
brcmf_chip_ai_coredisable(core, prereset, reset);
|
||||
+ if (d11priv2)
|
||||
+ brcmf_chip_ai_coredisable(d11priv2, prereset, reset);
|
||||
|
||||
count = 0;
|
||||
while (ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) &
|
||||
@@ -449,9 +463,30 @@ static void brcmf_chip_ai_resetcore(stru
|
||||
usleep_range(40, 60);
|
||||
}
|
||||
|
||||
+ if (d11priv2) {
|
||||
+ count = 0;
|
||||
+ while (ci->ops->read32(ci->ctx,
|
||||
+ d11priv2->wrapbase + BCMA_RESET_CTL) &
|
||||
+ BCMA_RESET_CTL_RESET) {
|
||||
+ ci->ops->write32(ci->ctx,
|
||||
+ d11priv2->wrapbase + BCMA_RESET_CTL,
|
||||
+ 0);
|
||||
+ count++;
|
||||
+ if (count > 50)
|
||||
+ break;
|
||||
+ usleep_range(40, 60);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
|
||||
postreset | BCMA_IOCTL_CLK);
|
||||
ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
|
||||
+
|
||||
+ if (d11priv2) {
|
||||
+ ci->ops->write32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL,
|
||||
+ postreset | BCMA_IOCTL_CLK);
|
||||
+ ci->ops->read32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL);
|
||||
+ }
|
||||
}
|
||||
|
||||
char *brcmf_chip_name(u32 id, u32 rev, char *buf, uint len)
|
||||
@@ -1109,6 +1144,21 @@ void brcmf_chip_detach(struct brcmf_chip
|
||||
kfree(chip);
|
||||
}
|
||||
|
||||
+struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit)
|
||||
+{
|
||||
+ struct brcmf_chip_priv *chip;
|
||||
+ struct brcmf_core_priv *core;
|
||||
+
|
||||
+ chip = container_of(pub, struct brcmf_chip_priv, pub);
|
||||
+ list_for_each_entry(core, &chip->cores, list) {
|
||||
+ if (core->pub.id == BCMA_CORE_80211) {
|
||||
+ if (unit-- == 0)
|
||||
+ return &core->pub;
|
||||
+ }
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)
|
||||
{
|
||||
struct brcmf_chip_priv *chip;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
|
||||
@@ -74,6 +74,7 @@ struct brcmf_chip *brcmf_chip_attach(voi
|
||||
const struct brcmf_buscore_ops *ops);
|
||||
void brcmf_chip_detach(struct brcmf_chip *chip);
|
||||
struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid);
|
||||
+struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit);
|
||||
struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip);
|
||||
struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub);
|
||||
bool brcmf_chip_iscoreup(struct brcmf_core *core);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -78,7 +78,7 @@ static const struct brcmf_firmware_mappi
|
||||
BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
|
||||
};
|
||||
|
||||
-#define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */
|
||||
+#define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */
|
||||
|
||||
#define BRCMF_PCIE_REG_MAP_SIZE (32 * 1024)
|
||||
|
@ -1,79 +0,0 @@
|
||||
From 172f6854551d48d1c9530f84513b421db944e714 Mon Sep 17 00:00:00 2001
|
||||
From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
|
||||
Date: Thu, 12 Dec 2019 00:52:46 +0100
|
||||
Subject: [PATCH 2/7] brcmfmac: set F2 blocksize and watermark for 4359
|
||||
|
||||
Set F2 blocksize to 256 bytes and watermark to 0x40 for 4359. Also
|
||||
enable and configure F1 MesBusyCtrl. It fixes DMA error while having
|
||||
UDP bi-directional traffic.
|
||||
|
||||
Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com>
|
||||
[slightly adapted for rebase on mainline linux]
|
||||
Signed-off-by: Soeren Moch <smoch@web.de>
|
||||
Reviewed-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 6 +++++-
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 15 +++++++++++++++
|
||||
2 files changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -43,6 +43,7 @@
|
||||
|
||||
#define SDIO_FUNC1_BLOCKSIZE 64
|
||||
#define SDIO_FUNC2_BLOCKSIZE 512
|
||||
+#define SDIO_4359_FUNC2_BLOCKSIZE 256
|
||||
/* Maximum milliseconds to wait for F2 to come up */
|
||||
#define SDIO_WAIT_F2RDY 3000
|
||||
|
||||
@@ -903,6 +904,7 @@ static void brcmf_sdiod_host_fixup(struc
|
||||
static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
int ret = 0;
|
||||
+ unsigned int f2_blksz = SDIO_FUNC2_BLOCKSIZE;
|
||||
|
||||
sdio_claim_host(sdiodev->func1);
|
||||
|
||||
@@ -912,7 +914,9 @@ static int brcmf_sdiod_probe(struct brcm
|
||||
sdio_release_host(sdiodev->func1);
|
||||
goto out;
|
||||
}
|
||||
- ret = sdio_set_block_size(sdiodev->func2, SDIO_FUNC2_BLOCKSIZE);
|
||||
+ if (sdiodev->func2->device == SDIO_DEVICE_ID_BROADCOM_4359)
|
||||
+ f2_blksz = SDIO_4359_FUNC2_BLOCKSIZE;
|
||||
+ ret = sdio_set_block_size(sdiodev->func2, f2_blksz);
|
||||
if (ret) {
|
||||
brcmf_err("Failed to set F2 blocksize\n");
|
||||
sdio_release_host(sdiodev->func1);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -42,6 +42,8 @@
|
||||
#define DEFAULT_F2_WATERMARK 0x8
|
||||
#define CY_4373_F2_WATERMARK 0x40
|
||||
#define CY_43012_F2_WATERMARK 0x60
|
||||
+#define CY_4359_F2_WATERMARK 0x40
|
||||
+#define CY_4359_F1_MESBUSYCTRL (CY_4359_F2_WATERMARK | SBSDIO_MESBUSYCTRL_ENAB)
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
@@ -4206,6 +4208,19 @@ static void brcmf_sdio_firmware_callback
|
||||
brcmf_sdiod_writeb(sdiod, SBSDIO_DEVICE_CTL, devctl,
|
||||
&err);
|
||||
break;
|
||||
+ case SDIO_DEVICE_ID_BROADCOM_4359:
|
||||
+ brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes\n",
|
||||
+ CY_4359_F2_WATERMARK);
|
||||
+ brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK,
|
||||
+ CY_4359_F2_WATERMARK, &err);
|
||||
+ devctl = brcmf_sdiod_readb(sdiod, SBSDIO_DEVICE_CTL,
|
||||
+ &err);
|
||||
+ devctl |= SBSDIO_DEVCTL_F2WM_ENAB;
|
||||
+ brcmf_sdiod_writeb(sdiod, SBSDIO_DEVICE_CTL, devctl,
|
||||
+ &err);
|
||||
+ brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_MESBUSYCTRL,
|
||||
+ CY_4359_F1_MESBUSYCTRL, &err);
|
||||
+ break;
|
||||
default:
|
||||
brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK,
|
||||
DEFAULT_F2_WATERMARK, &err);
|
@ -1,34 +0,0 @@
|
||||
From 6647274ed995a172369cb04754eb5f8b85f68f6d Mon Sep 17 00:00:00 2001
|
||||
From: Soeren Moch <smoch@web.de>
|
||||
Date: Thu, 12 Dec 2019 00:52:47 +0100
|
||||
Subject: [PATCH 3/7] brcmfmac: fix rambase for 4359/9
|
||||
|
||||
Newer 4359 chip revisions need a different rambase address.
|
||||
This fixes firmware download on such devices which fails otherwise.
|
||||
|
||||
Signed-off-by: Soeren Moch <smoch@web.de>
|
||||
Acked-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
@@ -712,7 +712,6 @@ static u32 brcmf_chip_tcm_rambase(struct
|
||||
case BRCM_CC_43569_CHIP_ID:
|
||||
case BRCM_CC_43570_CHIP_ID:
|
||||
case BRCM_CC_4358_CHIP_ID:
|
||||
- case BRCM_CC_4359_CHIP_ID:
|
||||
case BRCM_CC_43602_CHIP_ID:
|
||||
case BRCM_CC_4371_CHIP_ID:
|
||||
return 0x180000;
|
||||
@@ -722,6 +721,8 @@ static u32 brcmf_chip_tcm_rambase(struct
|
||||
case BRCM_CC_4366_CHIP_ID:
|
||||
case BRCM_CC_43664_CHIP_ID:
|
||||
return 0x200000;
|
||||
+ case BRCM_CC_4359_CHIP_ID:
|
||||
+ return (ci->pub.chiprev < 9) ? 0x180000 : 0x160000;
|
||||
case CY_CC_4373_CHIP_ID:
|
||||
return 0x160000;
|
||||
default:
|
@ -1,42 +0,0 @@
|
||||
From c12c8913d79c49ceccb38f42714d25b783833758 Mon Sep 17 00:00:00 2001
|
||||
From: Soeren Moch <smoch@web.de>
|
||||
Date: Thu, 12 Dec 2019 00:52:48 +0100
|
||||
Subject: [PATCH 4/7] brcmfmac: make errors when setting roaming parameters
|
||||
non-fatal
|
||||
|
||||
4359 dongles do not support setting roaming parameters (error -52).
|
||||
Do not fail the 80211 configuration in this case.
|
||||
|
||||
Signed-off-by: Soeren Moch <smoch@web.de>
|
||||
Acked-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -5944,19 +5944,17 @@ static s32 brcmf_dongle_roam(struct brcm
|
||||
roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
|
||||
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
|
||||
(void *)roamtrigger, sizeof(roamtrigger));
|
||||
- if (err) {
|
||||
+ if (err)
|
||||
bphy_err(drvr, "WLC_SET_ROAM_TRIGGER error (%d)\n", err);
|
||||
- goto roam_setup_done;
|
||||
- }
|
||||
|
||||
roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
|
||||
roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
|
||||
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
|
||||
(void *)roam_delta, sizeof(roam_delta));
|
||||
- if (err) {
|
||||
+ if (err)
|
||||
bphy_err(drvr, "WLC_SET_ROAM_DELTA error (%d)\n", err);
|
||||
- goto roam_setup_done;
|
||||
- }
|
||||
+
|
||||
+ return 0;
|
||||
|
||||
roam_setup_done:
|
||||
return err;
|
@ -1,75 +0,0 @@
|
||||
From d4aef159394d5940bd7158ab789969dab82f7c76 Mon Sep 17 00:00:00 2001
|
||||
From: Soeren Moch <smoch@web.de>
|
||||
Date: Thu, 12 Dec 2019 00:52:49 +0100
|
||||
Subject: [PATCH 5/7] brcmfmac: add support for BCM4359 SDIO chipset
|
||||
|
||||
BCM4359 is a 2x2 802.11 abgn+ac Dual-Band HT80 combo chip and it
|
||||
supports Real Simultaneous Dual Band feature.
|
||||
|
||||
Based on a similar patch by: Wright Feng <wright.feng@cypress.com>
|
||||
|
||||
Signed-off-by: Soeren Moch <smoch@web.de>
|
||||
Acked-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
|
||||
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 ++
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 1 +
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 ++
|
||||
include/linux/mmc/sdio_ids.h | 2 ++
|
||||
4 files changed, 7 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -973,8 +973,10 @@ static const struct sdio_device_id brcmf
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43455),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356),
|
||||
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4359),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_4373),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_43012),
|
||||
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_89359),
|
||||
{ /* end: all zeroes */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
|
||||
@@ -1408,6 +1408,7 @@ bool brcmf_chip_sr_capable(struct brcmf_
|
||||
addr = CORE_CC_REG(base, sr_control0);
|
||||
reg = chip->ops->read32(chip->ctx, addr);
|
||||
return (reg & CC_SR_CTL0_ENABLE_MASK) != 0;
|
||||
+ case BRCM_CC_4359_CHIP_ID:
|
||||
case CY_CC_43012_CHIP_ID:
|
||||
addr = CORE_CC_REG(pmu->base, retention_ctl);
|
||||
reg = chip->ops->read32(chip->ctx, addr);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -616,6 +616,7 @@ BRCMF_FW_DEF(43455, "brcmfmac43455-sdio"
|
||||
BRCMF_FW_DEF(43456, "brcmfmac43456-sdio");
|
||||
BRCMF_FW_DEF(4354, "brcmfmac4354-sdio");
|
||||
BRCMF_FW_DEF(4356, "brcmfmac4356-sdio");
|
||||
+BRCMF_FW_DEF(4359, "brcmfmac4359-sdio");
|
||||
BRCMF_FW_DEF(4373, "brcmfmac4373-sdio");
|
||||
BRCMF_FW_DEF(43012, "brcmfmac43012-sdio");
|
||||
|
||||
@@ -638,6 +639,7 @@ static const struct brcmf_firmware_mappi
|
||||
BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFDC0, 43455),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
|
||||
+ BRCMF_FW_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359),
|
||||
BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373),
|
||||
BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012)
|
||||
};
|
||||
--- a/include/linux/mmc/sdio_ids.h
|
||||
+++ b/include/linux/mmc/sdio_ids.h
|
||||
@@ -41,8 +41,10 @@
|
||||
#define SDIO_DEVICE_ID_BROADCOM_43455 0xa9bf
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4356 0x4356
|
||||
+#define SDIO_DEVICE_ID_BROADCOM_4359 0x4359
|
||||
#define SDIO_DEVICE_ID_CYPRESS_4373 0x4373
|
||||
#define SDIO_DEVICE_ID_CYPRESS_43012 43012
|
||||
+#define SDIO_DEVICE_ID_CYPRESS_89359 0x4355
|
||||
|
||||
#define SDIO_VENDOR_ID_INTEL 0x0089
|
||||
#define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402
|
@ -1,130 +0,0 @@
|
||||
From 837482e69a3f0d7cbc73922020012f83635f5ddb Mon Sep 17 00:00:00 2001
|
||||
From: Wright Feng <wright.feng@cypress.com>
|
||||
Date: Thu, 12 Dec 2019 00:52:50 +0100
|
||||
Subject: [PATCH 6/7] brcmfmac: add RSDB condition when setting interface
|
||||
combinations
|
||||
|
||||
With firmware RSDB feature
|
||||
1. The maximum support interface is four.
|
||||
2. The maximum difference channel is two.
|
||||
3. The maximum interfaces of {station/p2p client/AP} are two.
|
||||
4. The maximum interface of p2p device is one.
|
||||
|
||||
Signed-off-by: Wright Feng <wright.feng@cypress.com>
|
||||
Signed-off-by: Soeren Moch <smoch@web.de>
|
||||
Reviewed-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 54 ++++++++++++++++---
|
||||
1 file changed, 46 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -6452,6 +6452,9 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] =
|
||||
* #STA <= 1, #AP <= 1, channels = 1, 2 total
|
||||
* #AP <= 4, matching BI, channels = 1, 4 total
|
||||
*
|
||||
+ * no p2p and rsdb:
|
||||
+ * #STA <= 2, #AP <= 2, channels = 2, 4 total
|
||||
+ *
|
||||
* p2p, no mchan, and mbss:
|
||||
*
|
||||
* #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
|
||||
@@ -6463,6 +6466,10 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] =
|
||||
* #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
|
||||
* #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
|
||||
* #AP <= 4, matching BI, channels = 1, 4 total
|
||||
+ *
|
||||
+ * p2p, rsdb, and no mbss:
|
||||
+ * #STA <= 2, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2,
|
||||
+ * channels = 2, 4 total
|
||||
*/
|
||||
static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
|
||||
{
|
||||
@@ -6470,13 +6477,14 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
struct ieee80211_iface_limit *c0_limits = NULL;
|
||||
struct ieee80211_iface_limit *p2p_limits = NULL;
|
||||
struct ieee80211_iface_limit *mbss_limits = NULL;
|
||||
- bool mbss, p2p;
|
||||
+ bool mbss, p2p, rsdb;
|
||||
int i, c, n_combos;
|
||||
|
||||
mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
|
||||
p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
|
||||
+ rsdb = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB);
|
||||
|
||||
- n_combos = 1 + !!p2p + !!mbss;
|
||||
+ n_combos = 1 + !!(p2p && !rsdb) + !!mbss;
|
||||
combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
|
||||
if (!combo)
|
||||
goto err;
|
||||
@@ -6487,16 +6495,36 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
|
||||
c = 0;
|
||||
i = 0;
|
||||
- c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
|
||||
+ if (p2p && rsdb)
|
||||
+ c0_limits = kcalloc(4, sizeof(*c0_limits), GFP_KERNEL);
|
||||
+ else if (p2p)
|
||||
+ c0_limits = kcalloc(3, sizeof(*c0_limits), GFP_KERNEL);
|
||||
+ else
|
||||
+ c0_limits = kcalloc(2, sizeof(*c0_limits), GFP_KERNEL);
|
||||
if (!c0_limits)
|
||||
goto err;
|
||||
- c0_limits[i].max = 1;
|
||||
- c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
- if (p2p) {
|
||||
+ if (p2p && rsdb) {
|
||||
+ combo[c].num_different_channels = 2;
|
||||
+ wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
+ BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
+ BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
+ c0_limits[i].max = 2;
|
||||
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
+ c0_limits[i].max = 1;
|
||||
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
+ c0_limits[i].max = 2;
|
||||
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
+ BIT(NL80211_IFTYPE_P2P_GO);
|
||||
+ c0_limits[i].max = 2;
|
||||
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||
+ combo[c].max_interfaces = 5;
|
||||
+ } else if (p2p) {
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
|
||||
combo[c].num_different_channels = 2;
|
||||
else
|
||||
combo[c].num_different_channels = 1;
|
||||
+ c0_limits[i].max = 1;
|
||||
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
@@ -6505,16 +6533,26 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
c0_limits[i].max = 1;
|
||||
c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO);
|
||||
+ combo[c].max_interfaces = i;
|
||||
+ } else if (rsdb) {
|
||||
+ combo[c].num_different_channels = 2;
|
||||
+ c0_limits[i].max = 2;
|
||||
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
+ c0_limits[i].max = 2;
|
||||
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||
+ combo[c].max_interfaces = 3;
|
||||
} else {
|
||||
combo[c].num_different_channels = 1;
|
||||
c0_limits[i].max = 1;
|
||||
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
+ c0_limits[i].max = 1;
|
||||
c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||
+ combo[c].max_interfaces = i;
|
||||
}
|
||||
- combo[c].max_interfaces = i;
|
||||
combo[c].n_limits = i;
|
||||
combo[c].limits = c0_limits;
|
||||
|
||||
- if (p2p) {
|
||||
+ if (p2p && !rsdb) {
|
||||
c++;
|
||||
i = 0;
|
||||
p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
|
@ -1,38 +0,0 @@
|
||||
From 2635853ce4ab7654a77ab7080fb56de83408606b Mon Sep 17 00:00:00 2001
|
||||
From: Wright Feng <wright.feng@cypress.com>
|
||||
Date: Thu, 12 Dec 2019 00:52:51 +0100
|
||||
Subject: [PATCH 7/7] brcmfmac: not set mbss in vif if firmware does not
|
||||
support MBSS
|
||||
|
||||
With RSDB mode, FMAC and firmware are able to create 2 or more AP,
|
||||
so we should not set mbss in vif structure if firmware does not
|
||||
support MBSS feature.
|
||||
|
||||
Signed-off-by: Wright Feng <wright.feng@cypress.com>
|
||||
Signed-off-by: Soeren Moch <smoch@web.de>
|
||||
Reviewed-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -5301,6 +5301,7 @@ struct brcmf_cfg80211_vif *brcmf_alloc_v
|
||||
struct brcmf_cfg80211_vif *vif_walk;
|
||||
struct brcmf_cfg80211_vif *vif;
|
||||
bool mbss;
|
||||
+ struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
|
||||
|
||||
brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
|
||||
sizeof(*vif));
|
||||
@@ -5313,7 +5314,8 @@ struct brcmf_cfg80211_vif *brcmf_alloc_v
|
||||
|
||||
brcmf_init_prof(&vif->profile);
|
||||
|
||||
- if (type == NL80211_IFTYPE_AP) {
|
||||
+ if (type == NL80211_IFTYPE_AP &&
|
||||
+ brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
|
||||
mbss = false;
|
||||
list_for_each_entry(vif_walk, &cfg->vif_list, list) {
|
||||
if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
|
@ -1,66 +0,0 @@
|
||||
From a32de68edab7b73ded850bcf76cdf6858e92a7e5 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Osipenko <digetx@gmail.com>
|
||||
Date: Sun, 15 Dec 2019 21:42:24 +0300
|
||||
Subject: [PATCH] brcmfmac: Keep OOB wake-interrupt disabled when it shouldn't
|
||||
be enabled
|
||||
|
||||
NVIDIA Tegra SoCs do not like when OOB wake is enabled and WiFi interface
|
||||
is in DOWN state during suspend. This results in a CPU hang on programming
|
||||
OOB wake-up state of the GPIO controller during of system's suspend.
|
||||
|
||||
The solution is trivial: don't enable wake for the OOB interrupt when it
|
||||
should be disabled.
|
||||
|
||||
This fixes hang on Tegra20 (Acer A500) and Tegra30 (Nexus 7) devices which
|
||||
are using BCM4329 and BCM4330 WiFi chips respectively.
|
||||
|
||||
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 10 +++++-----
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 1 -
|
||||
2 files changed, 5 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -120,7 +120,7 @@ int brcmf_sdiod_intr_register(struct brc
|
||||
brcmf_err("enable_irq_wake failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
- sdiodev->irq_wake = true;
|
||||
+ disable_irq_wake(pdata->oob_irq_nr);
|
||||
|
||||
sdio_claim_host(sdiodev->func1);
|
||||
|
||||
@@ -179,10 +179,6 @@ void brcmf_sdiod_intr_unregister(struct
|
||||
sdio_release_host(sdiodev->func1);
|
||||
|
||||
sdiodev->oob_irq_requested = false;
|
||||
- if (sdiodev->irq_wake) {
|
||||
- disable_irq_wake(pdata->oob_irq_nr);
|
||||
- sdiodev->irq_wake = false;
|
||||
- }
|
||||
free_irq(pdata->oob_irq_nr, &sdiodev->func1->dev);
|
||||
sdiodev->irq_en = false;
|
||||
sdiodev->oob_irq_requested = false;
|
||||
@@ -1173,6 +1169,10 @@ static int brcmf_ops_sdio_resume(struct
|
||||
if (ret)
|
||||
brcmf_err("Failed to probe device on resume\n");
|
||||
} else {
|
||||
+ if (sdiodev->wowl_enabled &&
|
||||
+ sdiodev->settings->bus.sdio.oob_irq_supported)
|
||||
+ disable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
|
||||
+
|
||||
brcmf_sdiod_freezer_off(sdiodev);
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -178,7 +178,6 @@ struct brcmf_sdio_dev {
|
||||
bool sd_irq_requested;
|
||||
bool irq_en; /* irq enable flags */
|
||||
spinlock_t irq_en_lock;
|
||||
- bool irq_wake; /* irq wake enable flags */
|
||||
bool sg_support;
|
||||
uint max_request_size;
|
||||
ushort max_segment_count;
|
@ -1,27 +0,0 @@
|
||||
From b92c017deda819e45a0f054f6df6b53e645d7fe4 Mon Sep 17 00:00:00 2001
|
||||
From: zhengbin <zhengbin13@huawei.com>
|
||||
Date: Tue, 24 Dec 2019 22:16:06 +0800
|
||||
Subject: [PATCH] brcmfmac: use true,false for bool variable
|
||||
|
||||
Fixes coccicheck warning:
|
||||
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c:911:2-24: WARNING: Assignment of 0/1 to bool variable
|
||||
|
||||
Reported-by: Hulk Robot <hulkci@huawei.com>
|
||||
Signed-off-by: zhengbin <zhengbin13@huawei.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
|
||||
@@ -908,7 +908,7 @@ static u8 brcmf_fws_hdrpush(struct brcmf
|
||||
wlh += wlh[1] + 2;
|
||||
|
||||
if (entry->send_tim_signal) {
|
||||
- entry->send_tim_signal = 0;
|
||||
+ entry->send_tim_signal = false;
|
||||
wlh[0] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP;
|
||||
wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
|
||||
wlh[2] = entry->mac_handle;
|
@ -1,103 +0,0 @@
|
||||
From 24332f8068ff6df7f16aefee45d514de1de4de80 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Thu, 26 Dec 2019 14:30:49 +0100
|
||||
Subject: [PATCH] brcmfmac: simplify building interface combinations
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Move similar/duplicated code out of combination specific code blocks.
|
||||
This simplifies code a bit and allows adding more combinations later.
|
||||
A list of combinations remains unchanged.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 43 ++++++-------------
|
||||
1 file changed, 14 insertions(+), 29 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -6479,12 +6479,13 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
struct ieee80211_iface_limit *c0_limits = NULL;
|
||||
struct ieee80211_iface_limit *p2p_limits = NULL;
|
||||
struct ieee80211_iface_limit *mbss_limits = NULL;
|
||||
- bool mbss, p2p, rsdb;
|
||||
+ bool mbss, p2p, rsdb, mchan;
|
||||
int i, c, n_combos;
|
||||
|
||||
mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
|
||||
p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
|
||||
rsdb = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB);
|
||||
+ mchan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN);
|
||||
|
||||
n_combos = 1 + !!(p2p && !rsdb) + !!mbss;
|
||||
combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
|
||||
@@ -6494,6 +6495,10 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_ADHOC) |
|
||||
BIT(NL80211_IFTYPE_AP);
|
||||
+ if (p2p)
|
||||
+ wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
+ BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
+ BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
|
||||
c = 0;
|
||||
i = 0;
|
||||
@@ -6505,48 +6510,28 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
c0_limits = kcalloc(2, sizeof(*c0_limits), GFP_KERNEL);
|
||||
if (!c0_limits)
|
||||
goto err;
|
||||
- if (p2p && rsdb) {
|
||||
- combo[c].num_different_channels = 2;
|
||||
- wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
- BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
- BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
- c0_limits[i].max = 2;
|
||||
- c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
+
|
||||
+ combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan));
|
||||
+ c0_limits[i].max = 1 + rsdb;
|
||||
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
+ if (p2p) {
|
||||
c0_limits[i].max = 1;
|
||||
c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
- c0_limits[i].max = 2;
|
||||
+ c0_limits[i].max = 1 + rsdb;
|
||||
c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO);
|
||||
+ }
|
||||
+ if (p2p && rsdb) {
|
||||
c0_limits[i].max = 2;
|
||||
c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||
combo[c].max_interfaces = 5;
|
||||
} else if (p2p) {
|
||||
- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
|
||||
- combo[c].num_different_channels = 2;
|
||||
- else
|
||||
- combo[c].num_different_channels = 1;
|
||||
- c0_limits[i].max = 1;
|
||||
- c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
- wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
- BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
- BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
- c0_limits[i].max = 1;
|
||||
- c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
- c0_limits[i].max = 1;
|
||||
- c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
- BIT(NL80211_IFTYPE_P2P_GO);
|
||||
combo[c].max_interfaces = i;
|
||||
} else if (rsdb) {
|
||||
- combo[c].num_different_channels = 2;
|
||||
- c0_limits[i].max = 2;
|
||||
- c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
c0_limits[i].max = 2;
|
||||
c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||
combo[c].max_interfaces = 3;
|
||||
} else {
|
||||
- combo[c].num_different_channels = 1;
|
||||
- c0_limits[i].max = 1;
|
||||
- c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
c0_limits[i].max = 1;
|
||||
c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||
combo[c].max_interfaces = i;
|
@ -1,345 +0,0 @@
|
||||
From 20f2c5fa3af060401c72e444999470a4cab641cf Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Thu, 26 Dec 2019 14:30:50 +0100
|
||||
Subject: [PATCH] brcmfmac: add initial support for monitor mode
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Report monitor interface availability using cfg80211 and support it in
|
||||
the add_virtual_intf() and del_virtual_intf() callbacks. This new
|
||||
feature is conditional and depends on firmware flagging monitor packets.
|
||||
Receiving monitor frames is already handled by the brcmf_netif_mon_rx().
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 112 ++++++++++++++++--
|
||||
.../broadcom/brcm80211/brcmfmac/core.c | 68 ++++++++++-
|
||||
.../broadcom/brcm80211/brcmfmac/core.h | 2 +
|
||||
.../broadcom/brcm80211/brcmfmac/feature.c | 1 +
|
||||
.../broadcom/brcm80211/brcmfmac/feature.h | 2 +
|
||||
.../broadcom/brcm80211/brcmfmac/fwil.h | 2 +
|
||||
6 files changed, 174 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <net/netlink.h>
|
||||
+#include <uapi/linux/if_arp.h>
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <defs.h>
|
||||
@@ -619,6 +620,82 @@ static bool brcmf_is_ibssmode(struct brc
|
||||
return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * brcmf_mon_add_vif() - create monitor mode virtual interface
|
||||
+ *
|
||||
+ * @wiphy: wiphy device of new interface.
|
||||
+ * @name: name of the new interface.
|
||||
+ */
|
||||
+static struct wireless_dev *brcmf_mon_add_vif(struct wiphy *wiphy,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
+ struct brcmf_cfg80211_vif *vif;
|
||||
+ struct net_device *ndev;
|
||||
+ struct brcmf_if *ifp;
|
||||
+ int err;
|
||||
+
|
||||
+ if (cfg->pub->mon_if) {
|
||||
+ err = -EEXIST;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_MONITOR);
|
||||
+ if (IS_ERR(vif)) {
|
||||
+ err = PTR_ERR(vif);
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ ndev = alloc_netdev(sizeof(*ifp), name, NET_NAME_UNKNOWN, ether_setup);
|
||||
+ if (!ndev) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_free_vif;
|
||||
+ }
|
||||
+ ndev->type = ARPHRD_IEEE80211_RADIOTAP;
|
||||
+ ndev->ieee80211_ptr = &vif->wdev;
|
||||
+ ndev->needs_free_netdev = true;
|
||||
+ ndev->priv_destructor = brcmf_cfg80211_free_netdev;
|
||||
+ SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
|
||||
+
|
||||
+ ifp = netdev_priv(ndev);
|
||||
+ ifp->vif = vif;
|
||||
+ ifp->ndev = ndev;
|
||||
+ ifp->drvr = cfg->pub;
|
||||
+
|
||||
+ vif->ifp = ifp;
|
||||
+ vif->wdev.netdev = ndev;
|
||||
+
|
||||
+ err = brcmf_net_mon_attach(ifp);
|
||||
+ if (err) {
|
||||
+ brcmf_err("Failed to attach %s device\n", ndev->name);
|
||||
+ free_netdev(ndev);
|
||||
+ goto err_free_vif;
|
||||
+ }
|
||||
+
|
||||
+ cfg->pub->mon_if = ifp;
|
||||
+
|
||||
+ return &vif->wdev;
|
||||
+
|
||||
+err_free_vif:
|
||||
+ brcmf_free_vif(vif);
|
||||
+err_out:
|
||||
+ return ERR_PTR(err);
|
||||
+}
|
||||
+
|
||||
+static int brcmf_mon_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
|
||||
+{
|
||||
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
+ struct net_device *ndev = wdev->netdev;
|
||||
+
|
||||
+ ndev->netdev_ops->ndo_stop(ndev);
|
||||
+
|
||||
+ brcmf_net_detach(ndev, true);
|
||||
+
|
||||
+ cfg->pub->mon_if = NULL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
|
||||
const char *name,
|
||||
unsigned char name_assign_type,
|
||||
@@ -641,9 +718,10 @@ static struct wireless_dev *brcmf_cfg802
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
case NL80211_IFTYPE_WDS:
|
||||
- case NL80211_IFTYPE_MONITOR:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
+ case NL80211_IFTYPE_MONITOR:
|
||||
+ return brcmf_mon_add_vif(wiphy, name);
|
||||
case NL80211_IFTYPE_AP:
|
||||
wdev = brcmf_ap_add_vif(wiphy, name, params);
|
||||
break;
|
||||
@@ -826,9 +904,10 @@ int brcmf_cfg80211_del_iface(struct wiph
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
case NL80211_IFTYPE_WDS:
|
||||
- case NL80211_IFTYPE_MONITOR:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
return -EOPNOTSUPP;
|
||||
+ case NL80211_IFTYPE_MONITOR:
|
||||
+ return brcmf_mon_del_vif(wiphy, wdev);
|
||||
case NL80211_IFTYPE_AP:
|
||||
return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
@@ -6479,9 +6558,10 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
struct ieee80211_iface_limit *c0_limits = NULL;
|
||||
struct ieee80211_iface_limit *p2p_limits = NULL;
|
||||
struct ieee80211_iface_limit *mbss_limits = NULL;
|
||||
- bool mbss, p2p, rsdb, mchan;
|
||||
- int i, c, n_combos;
|
||||
+ bool mon_flag, mbss, p2p, rsdb, mchan;
|
||||
+ int i, c, n_combos, n_limits;
|
||||
|
||||
+ mon_flag = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FLAG);
|
||||
mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
|
||||
p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
|
||||
rsdb = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB);
|
||||
@@ -6495,6 +6575,8 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_ADHOC) |
|
||||
BIT(NL80211_IFTYPE_AP);
|
||||
+ if (mon_flag)
|
||||
+ wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
|
||||
if (p2p)
|
||||
wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
@@ -6502,18 +6584,18 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
|
||||
c = 0;
|
||||
i = 0;
|
||||
- if (p2p && rsdb)
|
||||
- c0_limits = kcalloc(4, sizeof(*c0_limits), GFP_KERNEL);
|
||||
- else if (p2p)
|
||||
- c0_limits = kcalloc(3, sizeof(*c0_limits), GFP_KERNEL);
|
||||
- else
|
||||
- c0_limits = kcalloc(2, sizeof(*c0_limits), GFP_KERNEL);
|
||||
+ n_limits = 1 + mon_flag + (p2p ? 2 : 0) + (rsdb || !p2p);
|
||||
+ c0_limits = kcalloc(n_limits, sizeof(*c0_limits), GFP_KERNEL);
|
||||
if (!c0_limits)
|
||||
goto err;
|
||||
|
||||
combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan));
|
||||
c0_limits[i].max = 1 + rsdb;
|
||||
c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
+ if (mon_flag) {
|
||||
+ c0_limits[i].max = 1;
|
||||
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_MONITOR);
|
||||
+ }
|
||||
if (p2p) {
|
||||
c0_limits[i].max = 1;
|
||||
c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
@@ -6562,14 +6644,20 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
if (mbss) {
|
||||
c++;
|
||||
i = 0;
|
||||
- mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
|
||||
+ n_limits = 1 + mon_flag;
|
||||
+ mbss_limits = kcalloc(n_limits, sizeof(*mbss_limits),
|
||||
+ GFP_KERNEL);
|
||||
if (!mbss_limits)
|
||||
goto err;
|
||||
mbss_limits[i].max = 4;
|
||||
mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||
+ if (mon_flag) {
|
||||
+ mbss_limits[i].max = 1;
|
||||
+ mbss_limits[i++].types = BIT(NL80211_IFTYPE_MONITOR);
|
||||
+ }
|
||||
combo[c].beacon_int_infra_match = true;
|
||||
combo[c].num_different_channels = 1;
|
||||
- combo[c].max_interfaces = 4;
|
||||
+ combo[c].max_interfaces = 4 + mon_flag;
|
||||
combo[c].n_limits = i;
|
||||
combo[c].limits = mbss_limits;
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -690,7 +690,7 @@ fail:
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
-static void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked)
|
||||
+void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked)
|
||||
{
|
||||
if (ndev->reg_state == NETREG_REGISTERED) {
|
||||
if (rtnl_locked)
|
||||
@@ -703,6 +703,72 @@ static void brcmf_net_detach(struct net_
|
||||
}
|
||||
}
|
||||
|
||||
+static int brcmf_net_mon_open(struct net_device *ndev)
|
||||
+{
|
||||
+ struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
+ struct brcmf_pub *drvr = ifp->drvr;
|
||||
+ u32 monitor;
|
||||
+ int err;
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "Enter\n");
|
||||
+
|
||||
+ err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_MONITOR, &monitor);
|
||||
+ if (err) {
|
||||
+ bphy_err(drvr, "BRCMF_C_GET_MONITOR error (%d)\n", err);
|
||||
+ return err;
|
||||
+ } else if (monitor) {
|
||||
+ bphy_err(drvr, "Monitor mode is already enabled\n");
|
||||
+ return -EEXIST;
|
||||
+ }
|
||||
+
|
||||
+ monitor = 3;
|
||||
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_MONITOR, monitor);
|
||||
+ if (err)
|
||||
+ bphy_err(drvr, "BRCMF_C_SET_MONITOR error (%d)\n", err);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int brcmf_net_mon_stop(struct net_device *ndev)
|
||||
+{
|
||||
+ struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
+ struct brcmf_pub *drvr = ifp->drvr;
|
||||
+ u32 monitor;
|
||||
+ int err;
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "Enter\n");
|
||||
+
|
||||
+ monitor = 0;
|
||||
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_MONITOR, monitor);
|
||||
+ if (err)
|
||||
+ bphy_err(drvr, "BRCMF_C_SET_MONITOR error (%d)\n", err);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static const struct net_device_ops brcmf_netdev_ops_mon = {
|
||||
+ .ndo_open = brcmf_net_mon_open,
|
||||
+ .ndo_stop = brcmf_net_mon_stop,
|
||||
+};
|
||||
+
|
||||
+int brcmf_net_mon_attach(struct brcmf_if *ifp)
|
||||
+{
|
||||
+ struct brcmf_pub *drvr = ifp->drvr;
|
||||
+ struct net_device *ndev;
|
||||
+ int err;
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "Enter\n");
|
||||
+
|
||||
+ ndev = ifp->ndev;
|
||||
+ ndev->netdev_ops = &brcmf_netdev_ops_mon;
|
||||
+
|
||||
+ err = register_netdevice(ndev);
|
||||
+ if (err)
|
||||
+ bphy_err(drvr, "Failed to register %s device\n", ndev->name);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on)
|
||||
{
|
||||
struct net_device *ndev;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -210,6 +210,8 @@ void brcmf_txflowblock_if(struct brcmf_i
|
||||
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
|
||||
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||
void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||
+void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked);
|
||||
+int brcmf_net_mon_attach(struct brcmf_if *ifp);
|
||||
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
|
||||
int __init brcmf_core_init(void);
|
||||
void __exit brcmf_core_exit(void);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||
@@ -38,6 +38,7 @@ static const struct brcmf_feat_fwcap brc
|
||||
{ BRCMF_FEAT_MCHAN, "mchan" },
|
||||
{ BRCMF_FEAT_P2P, "p2p" },
|
||||
{ BRCMF_FEAT_MONITOR, "monitor" },
|
||||
+ { BRCMF_FEAT_MONITOR_FLAG, "rtap" },
|
||||
{ BRCMF_FEAT_MONITOR_FMT_RADIOTAP, "rtap" },
|
||||
{ BRCMF_FEAT_DOT11H, "802.11h" }
|
||||
};
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
|
||||
@@ -23,6 +23,7 @@
|
||||
* GSCAN: enhanced scan offload feature.
|
||||
* FWSUP: Firmware supplicant.
|
||||
* MONITOR: firmware can pass monitor packets to host.
|
||||
+ * MONITOR_FLAG: firmware flags monitor packets.
|
||||
* MONITOR_FMT_RADIOTAP: firmware provides monitor packets with radiotap header
|
||||
* MONITOR_FMT_HW_RX_HDR: firmware provides monitor packets with hw/ucode header
|
||||
* DOT11H: firmware supports 802.11h
|
||||
@@ -43,6 +44,7 @@
|
||||
BRCMF_FEAT_DEF(GSCAN) \
|
||||
BRCMF_FEAT_DEF(FWSUP) \
|
||||
BRCMF_FEAT_DEF(MONITOR) \
|
||||
+ BRCMF_FEAT_DEF(MONITOR_FLAG) \
|
||||
BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) \
|
||||
BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) \
|
||||
BRCMF_FEAT_DEF(DOT11H)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
|
||||
@@ -49,6 +49,8 @@
|
||||
#define BRCMF_C_GET_PM 85
|
||||
#define BRCMF_C_SET_PM 86
|
||||
#define BRCMF_C_GET_REVINFO 98
|
||||
+#define BRCMF_C_GET_MONITOR 107
|
||||
+#define BRCMF_C_SET_MONITOR 108
|
||||
#define BRCMF_C_GET_CURR_RATESET 114
|
||||
#define BRCMF_C_GET_AP 117
|
||||
#define BRCMF_C_SET_AP 118
|
@ -1,24 +0,0 @@
|
||||
From 627b0d094240c38393b2f2d40626c33a8fff6103 Mon Sep 17 00:00:00 2001
|
||||
From: yuehaibing <yuehaibing@huawei.com>
|
||||
Date: Wed, 8 Jan 2020 21:57:48 +0800
|
||||
Subject: [PATCH] brcmfmac: Remove always false 'idx < 0' statement
|
||||
|
||||
idx is declared as u32, it will never less than 0.
|
||||
|
||||
Signed-off-by: yuehaibing <yuehaibing@huawei.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||
@@ -365,7 +365,7 @@ brcmf_msgbuf_get_pktid(struct device *de
|
||||
struct brcmf_msgbuf_pktid *pktid;
|
||||
struct sk_buff *skb;
|
||||
|
||||
- if (idx < 0 || idx >= pktids->array_size) {
|
||||
+ if (idx >= pktids->array_size) {
|
||||
brcmf_err("Invalid packet id %d (max %d)\n", idx,
|
||||
pktids->array_size);
|
||||
return NULL;
|
@ -1,100 +0,0 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Fri, 27 Mar 2020 13:40:50 +0100
|
||||
Subject: [PATCH] brcmfmac: add stub for monitor interface xmit
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
According to the struct net_device_ops documentation .ndo_start_xmit is
|
||||
"Required; cannot be NULL.". Missing it may crash kernel easily:
|
||||
|
||||
[ 341.216709] Unable to handle kernel NULL pointer dereference at virtual address 00000000
|
||||
[ 341.224836] pgd = 26088755
|
||||
[ 341.227544] [00000000] *pgd=00000000
|
||||
[ 341.231135] Internal error: Oops: 80000007 [#1] SMP ARM
|
||||
[ 341.236367] Modules linked in: pppoe ppp_async iptable_nat brcmfmac xt_state xt_nat xt_conntrack xt_REDIRECT xt_MASQU
|
||||
[ 341.304689] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.24 #0
|
||||
[ 341.310621] Hardware name: BCM5301X
|
||||
[ 341.314116] PC is at 0x0
|
||||
[ 341.316664] LR is at dev_hard_start_xmit+0x8c/0x11c
|
||||
[ 341.321546] pc : [<00000000>] lr : [<c0469fa8>] psr: 60000113
|
||||
[ 341.327821] sp : c0801c30 ip : c610cf00 fp : c08048e4
|
||||
[ 341.333051] r10: c073a63a r9 : c08044dc r8 : c6c04e00
|
||||
[ 341.338283] r7 : 00000000 r6 : c60f5000 r5 : 00000000 r4 : c6a9c3c0
|
||||
[ 341.344820] r3 : 00000000 r2 : bf25a13c r1 : c60f5000 r0 : c6a9c3c0
|
||||
[ 341.351358] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
|
||||
[ 341.358504] Control: 10c5387d Table: 0611c04a DAC: 00000051
|
||||
[ 341.364257] Process swapper/0 (pid: 0, stack limit = 0xc68ed0ca)
|
||||
[ 341.370271] Stack: (0xc0801c30 to 0xc0802000)
|
||||
[ 341.374633] 1c20: c6e7d480 c0802d00 c60f5050 c0801c6c
|
||||
[ 341.382825] 1c40: c60f5000 c6a9c3c0 c6f90000 c6f9005c c6c04e00 c60f5000 00000000 c6f9005c
|
||||
[ 341.391015] 1c60: 00000000 c04a033c 00f90200 00000010 c6a9c3c0 c6a9c3c0 c6f90000 00000000
|
||||
[ 341.399205] 1c80: 00000000 00000000 00000000 c046a7ac c6f9005c 00000001 fffffff4 00000000
|
||||
[ 341.407395] 1ca0: c6f90200 00000000 c60f5000 c0479550 00000000 c6f90200 c6a9c3c0 16000000
|
||||
[ 341.415586] 1cc0: 0000001c 6f4ad52f c6197040 b6df9387 36000000 c0520404 c073a80c c6a9c3c0
|
||||
[ 341.423777] 1ce0: 00000000 c6d643c0 c6a9c3c0 c0800024 00000001 00000001 c6d643c8 c6a9c3c0
|
||||
[ 341.431967] 1d00: c081b9c0 c7abca80 c610c840 c081b9c0 0000001c 00400000 c6bc5e6c c0522fb4
|
||||
[ 341.440157] 1d20: c6d64400 00000004 c6bc5e0a 00000000 c60f5000 c7abca80 c081b9c0 c0522f54
|
||||
[ 341.448348] 1d40: c6a9c3c0 c7abca80 c0803e48 c0549c94 c610c828 0000000a c0801d74 00000003
|
||||
[ 341.456538] 1d60: c6ec8f0a 00000000 c60f5000 c7abca80 c081b9c0 c0548520 0000000a 00000000
|
||||
[ 341.464728] 1d80: 00000000 003a0000 00000000 00000000 00000000 00000000 00000000 00000000
|
||||
[ 341.472919] 1da0: 000002ff 00000000 00000000 16000000 00000000 00000000 00000000 00000000
|
||||
[ 341.481110] 1dc0: 00000000 0000008f 00000000 00000000 00000000 2d132a69 c6bc5e40 00000000
|
||||
[ 341.489300] 1de0: c6bc5e40 c6a9c3c0 00000000 c6ec8e50 00000001 c054b070 00000001 00000000
|
||||
[ 341.497490] 1e00: c0807200 c6bc5e00 00000000 ffffe000 00000100 c054aea4 00000000 00000000
|
||||
[ 341.505681] 1e20: 00000122 00400000 c0802d00 c0172e80 6f56a70e ffffffff 6f56a70e c7eb9cc0
|
||||
[ 341.513871] 1e40: c7eb82c0 00000000 c0801e60 c017309c 00000000 00000000 07780000 c07382c0
|
||||
[ 341.522061] 1e60: 00000000 c7eb9cc0 c0739cc0 c0803f74 c0801e70 c0801e70 c0801ea4 c013d380
|
||||
[ 341.530253] 1e80: 00000000 000000a0 00000001 c0802084 c0802080 40000001 ffffe000 00000100
|
||||
[ 341.538443] 1ea0: c0802080 c01021e8 c8803100 10c5387d 00000000 c07341f0 c0739880 0000000a
|
||||
[ 341.546633] 1ec0: c0734180 00001017 c0802d00 c062aa98 00200002 c062aa60 c8803100 c073984c
|
||||
[ 341.554823] 1ee0: 00000000 00000001 00000000 c7810000 c8803100 10c5387d 00000000 c011c188
|
||||
[ 341.563014] 1f00: c073984c c015f0f8 c0804244 c0815ae4 c880210c c8802100 c0801f40 c037c584
|
||||
[ 341.571204] 1f20: c01035f8 60000013 ffffffff c0801f74 c080afd4 c0800000 10c5387d c0101a8c
|
||||
[ 341.579395] 1f40: 00000000 004ac9dc c7eba4b4 c010ee60 ffffe000 c0803e68 c0803ea8 00000001
|
||||
[ 341.587587] 1f60: c080afd4 c062ca20 10c5387d 00000000 00000000 c0801f90 c01035f4 c01035f8
|
||||
[ 341.595776] 1f80: 60000013 ffffffff 00000051 00000000 ffffe000 c013ff50 000000ce c0803e40
|
||||
[ 341.603967] 1fa0: c082216c 00000000 00000001 c072ba38 10c5387d c0140214 c0822184 c0700df8
|
||||
[ 341.612157] 1fc0: ffffffff ffffffff 00000000 c070058c c072ba38 2d162e71 00000000 c0700330
|
||||
[ 341.620348] 1fe0: 00000051 10c0387d 000000ff 00a521d0 413fc090 00000000 00000000 00000000
|
||||
[ 341.628558] [<c0469fa8>] (dev_hard_start_xmit) from [<c04a033c>] (sch_direct_xmit+0xe4/0x2bc)
|
||||
[ 341.637106] [<c04a033c>] (sch_direct_xmit) from [<c046a7ac>] (__dev_queue_xmit+0x6a4/0x72c)
|
||||
[ 341.645481] [<c046a7ac>] (__dev_queue_xmit) from [<c0520404>] (ip6_finish_output2+0x18c/0x434)
|
||||
[ 341.654112] [<c0520404>] (ip6_finish_output2) from [<c0522fb4>] (ip6_output+0x5c/0xd0)
|
||||
[ 341.662053] [<c0522fb4>] (ip6_output) from [<c0549c94>] (mld_sendpack+0x1a0/0x1a8)
|
||||
[ 341.669640] [<c0549c94>] (mld_sendpack) from [<c054b070>] (mld_ifc_timer_expire+0x1cc/0x2e4)
|
||||
[ 341.678111] [<c054b070>] (mld_ifc_timer_expire) from [<c0172e80>] (call_timer_fn.constprop.3+0x24/0x98)
|
||||
[ 341.687527] [<c0172e80>] (call_timer_fn.constprop.3) from [<c017309c>] (run_timer_softirq+0x1a8/0x1e4)
|
||||
[ 341.696860] [<c017309c>] (run_timer_softirq) from [<c01021e8>] (__do_softirq+0x120/0x2b0)
|
||||
[ 341.705066] [<c01021e8>] (__do_softirq) from [<c011c188>] (irq_exit+0x78/0x84)
|
||||
[ 341.712317] [<c011c188>] (irq_exit) from [<c015f0f8>] (__handle_domain_irq+0x60/0xb4)
|
||||
[ 341.720179] [<c015f0f8>] (__handle_domain_irq) from [<c037c584>] (gic_handle_irq+0x4c/0x90)
|
||||
[ 341.728549] [<c037c584>] (gic_handle_irq) from [<c0101a8c>] (__irq_svc+0x6c/0x90)
|
||||
|
||||
Fixes: 20f2c5fa3af0 ("brcmfmac: add initial support for monitor mode")
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -746,9 +746,18 @@ static int brcmf_net_mon_stop(struct net
|
||||
return err;
|
||||
}
|
||||
|
||||
+static netdev_tx_t brcmf_net_mon_start_xmit(struct sk_buff *skb,
|
||||
+ struct net_device *ndev)
|
||||
+{
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+
|
||||
+ return NETDEV_TX_OK;
|
||||
+}
|
||||
+
|
||||
static const struct net_device_ops brcmf_netdev_ops_mon = {
|
||||
.ndo_open = brcmf_net_mon_open,
|
||||
.ndo_stop = brcmf_net_mon_stop,
|
||||
+ .ndo_start_xmit = brcmf_net_mon_start_xmit,
|
||||
};
|
||||
|
||||
int brcmf_net_mon_attach(struct brcmf_if *ifp)
|
@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -705,8 +705,36 @@ static struct wireless_dev *brcmf_cfg802
|
||||
@@ -711,8 +711,36 @@ static struct wireless_dev *brcmf_cfg802
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct brcmf_pub *drvr = cfg->pub;
|
||||
struct wireless_dev *wdev;
|
||||
|
@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -2874,6 +2874,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
|
||||
@@ -2942,6 +2942,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
|
||||
* preference in cfg struct to apply this to
|
||||
* FW later while initializing the dongle
|
||||
*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -2826,6 +2826,63 @@ done:
|
||||
@@ -2894,6 +2894,63 @@ done:
|
||||
}
|
||||
|
||||
static int
|
||||
@ -64,7 +64,7 @@
|
||||
brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
|
||||
int idx, u8 *mac, struct station_info *sinfo)
|
||||
{
|
||||
@@ -2915,6 +2972,7 @@ static s32 brcmf_inform_single_bss(struc
|
||||
@@ -2983,6 +3040,7 @@ static s32 brcmf_inform_single_bss(struc
|
||||
struct brcmu_chan ch;
|
||||
u16 channel;
|
||||
u32 freq;
|
||||
@ -72,7 +72,7 @@
|
||||
u16 notify_capability;
|
||||
u16 notify_interval;
|
||||
u8 *notify_ie;
|
||||
@@ -2939,6 +2997,17 @@ static s32 brcmf_inform_single_bss(struc
|
||||
@@ -3007,6 +3065,17 @@ static s32 brcmf_inform_single_bss(struc
|
||||
band = NL80211_BAND_5GHZ;
|
||||
|
||||
freq = ieee80211_channel_to_frequency(channel, band);
|
||||
@ -90,7 +90,7 @@
|
||||
bss_data.chan = ieee80211_get_channel(wiphy, freq);
|
||||
bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20;
|
||||
bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime());
|
||||
@@ -5356,6 +5425,7 @@ static struct cfg80211_ops brcmf_cfg8021
|
||||
@@ -5424,6 +5493,7 @@ static struct cfg80211_ops brcmf_cfg8021
|
||||
.leave_ibss = brcmf_cfg80211_leave_ibss,
|
||||
.get_station = brcmf_cfg80211_get_station,
|
||||
.dump_station = brcmf_cfg80211_dump_station,
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
|
||||
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
|
||||
@@ -11482,6 +11482,15 @@ static const struct attribute_group ipw_
|
||||
@@ -11479,6 +11479,15 @@ static const struct attribute_group ipw_
|
||||
.attrs = ipw_sysfs_entries,
|
||||
};
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
#ifdef CPTCFG_IPW2200_PROMISCUOUS
|
||||
static int ipw_prom_open(struct net_device *dev)
|
||||
{
|
||||
@@ -11530,15 +11539,6 @@ static netdev_tx_t ipw_prom_hard_start_x
|
||||
@@ -11527,15 +11536,6 @@ static netdev_tx_t ipw_prom_hard_start_x
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/net/wireless/Kconfig
|
||||
+++ b/net/wireless/Kconfig
|
||||
@@ -186,7 +186,7 @@ config CFG80211_WEXT_EXPORT
|
||||
@@ -187,7 +187,7 @@ config CFG80211_WEXT_EXPORT
|
||||
endif # CFG80211
|
||||
|
||||
config LIB80211
|
||||
@ -9,7 +9,7 @@
|
||||
depends on m
|
||||
default n
|
||||
help
|
||||
@@ -196,18 +196,18 @@ config LIB80211
|
||||
@@ -197,18 +197,18 @@ config LIB80211
|
||||
Drivers should select this themselves if needed.
|
||||
|
||||
config LIB80211_CRYPT_WEP
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -412,43 +412,6 @@ USB_SIERRA_NET=
|
||||
@@ -417,43 +417,6 @@ USB_SIERRA_NET=
|
||||
USB_VL600=
|
||||
USB_NET_CH9200=
|
||||
USB_NET_AQC111=
|
||||
@ -192,7 +192,7 @@
|
||||
select BRCMUTIL
|
||||
--- a/Kconfig.local
|
||||
+++ b/Kconfig.local
|
||||
@@ -1240,117 +1240,6 @@ config BACKPORTED_USB_NET_CH9200
|
||||
@@ -1255,117 +1255,6 @@ config BACKPORTED_USB_NET_CH9200
|
||||
config BACKPORTED_USB_NET_AQC111
|
||||
tristate
|
||||
default USB_NET_AQC111
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -313,6 +313,7 @@ RT2X00_LIB_FIRMWARE=
|
||||
@@ -318,6 +318,7 @@ RT2X00_LIB_FIRMWARE=
|
||||
RT2X00_LIB_CRYPTO=
|
||||
RT2X00_LIB_LEDS=
|
||||
RT2X00_LIB_DEBUGFS=
|
||||
@ -95,7 +95,7 @@
|
||||
/* Firmware functions */
|
||||
static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
@@ -166,7 +153,6 @@ static const struct rt2800_ops rt2800soc
|
||||
@@ -167,7 +154,6 @@ static const struct rt2800_ops rt2800soc
|
||||
.register_multiread = rt2x00mmio_register_multiread,
|
||||
.register_multiwrite = rt2x00mmio_register_multiwrite,
|
||||
.regbusy_read = rt2x00mmio_regbusy_read,
|
||||
@ -127,7 +127,7 @@
|
||||
DECLARE_KFIFO_PTR(txstatus_fifo, u32);
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1418,6 +1418,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
|
||||
@@ -1407,6 +1407,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
|
||||
INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
|
||||
INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
|
||||
|
||||
@ -138,7 +138,7 @@
|
||||
/*
|
||||
* Let the driver probe the device to detect the capabilities.
|
||||
*/
|
||||
@@ -1561,6 +1565,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
|
||||
@@ -1550,6 +1554,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
|
||||
* Free the driver data.
|
||||
*/
|
||||
kfree(rt2x00dev->drv_data);
|
||||
|
@ -13,7 +13,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
@@ -223,10 +223,17 @@ static int rt2800soc_probe(struct platfo
|
||||
@@ -224,10 +224,17 @@ static int rt2800soc_probe(struct platfo
|
||||
return rt2x00soc_probe(pdev, &rt2800soc_ops);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "rt2x00.h"
|
||||
#include "rt2800lib.h"
|
||||
@@ -9531,6 +9532,17 @@ static int rt2800_init_eeprom(struct rt2
|
||||
@@ -9528,6 +9529,17 @@ static int rt2800_init_eeprom(struct rt2
|
||||
rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
|
||||
rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1356,7 +1356,7 @@ static inline void rt2x00lib_set_if_comb
|
||||
@@ -1345,7 +1345,7 @@ static inline void rt2x00lib_set_if_comb
|
||||
*/
|
||||
if_limit = &rt2x00dev->if_limits_ap;
|
||||
if_limit->max = rt2x00dev->ops->max_ap_intf;
|
||||
|
@ -30,7 +30,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
|
||||
* EEPROM LNA
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -4359,6 +4359,45 @@ static void rt2800_config_channel(struct
|
||||
@@ -4356,6 +4356,45 @@ static void rt2800_config_channel(struct
|
||||
rt2800_iq_calibrate(rt2x00dev, rf->channel);
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
|
||||
bbp = rt2800_bbp_read(rt2x00dev, 4);
|
||||
rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
|
||||
rt2800_bbp_write(rt2x00dev, 4, bbp);
|
||||
@@ -9560,7 +9599,8 @@ static int rt2800_init_eeprom(struct rt2
|
||||
@@ -9557,7 +9596,8 @@ static int rt2800_init_eeprom(struct rt2
|
||||
*/
|
||||
eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1);
|
||||
|
||||
@ -86,7 +86,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
|
||||
if (rt2x00_get_field16(eeprom,
|
||||
EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
|
||||
__set_bit(CAPABILITY_EXTERNAL_PA_TX0,
|
||||
@@ -9571,6 +9611,18 @@ static int rt2800_init_eeprom(struct rt2
|
||||
@@ -9568,6 +9608,18 @@ static int rt2800_init_eeprom(struct rt2
|
||||
&rt2x00dev->cap_flags);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -8422,6 +8422,56 @@ static void rt2800_init_rfcsr_5592(struc
|
||||
@@ -8419,6 +8419,56 @@ static void rt2800_init_rfcsr_5592(struc
|
||||
rt2800_led_open_drain_enable(rt2x00dev);
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9029,6 +9079,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
@@ -9026,6 +9076,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -8472,6 +8472,155 @@ static void rt2800_rf_self_txdc_cal(stru
|
||||
@@ -8469,6 +8469,155 @@ static void rt2800_rf_self_txdc_cal(stru
|
||||
rt2x00_info(rt2x00dev, "RF Tx self calibration end\n");
|
||||
}
|
||||
|
||||
@ -156,7 +156,7 @@
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9079,6 +9228,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
@@ -9076,6 +9225,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -8621,6 +8621,70 @@ static void rt2800_r_calibration(struct
|
||||
@@ -8618,6 +8618,70 @@ static void rt2800_r_calibration(struct
|
||||
rt2800_register_write(rt2x00dev, PWR_PIN_CFG, MAC_PWR_PIN_CFG);
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9230,6 +9294,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
@@ -9227,6 +9291,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
|
||||
rt2800_r_calibration(rt2x00dev);
|
||||
rt2800_rf_self_txdc_cal(rt2x00dev);
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -8685,6 +8685,384 @@ static void rt2800_rxdcoc_calibration(st
|
||||
@@ -8682,6 +8682,384 @@ static void rt2800_rxdcoc_calibration(st
|
||||
rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, saverfb0r2);
|
||||
}
|
||||
|
||||
@ -385,7 +385,7 @@
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9297,6 +9675,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
@@ -9294,6 +9672,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rxdcoc_calibration(rt2x00dev);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, true);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -9063,6 +9063,943 @@ restore_value:
|
||||
@@ -9060,6 +9060,943 @@ restore_value:
|
||||
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
|
||||
}
|
||||
|
||||
@ -944,7 +944,7 @@
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9675,6 +10612,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
@@ -9672,6 +10609,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rxdcoc_calibration(rt2x00dev);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, true);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
|
@ -0,0 +1,31 @@
|
||||
From e1f04bf9d38633f0bf9d041089366fea0ad22623 Mon Sep 17 00:00:00 2001
|
||||
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
Date: Thu, 21 May 2020 19:50:05 +0200
|
||||
Subject: [PATCH] wireless: Use linux/stddef.h instead of stddef.h
|
||||
|
||||
When compiling inside the kernel include linux/stddef.h instead of
|
||||
stddef.h. When I compile this header file in backports for power PC I
|
||||
run into a conflict with ptrdiff_t. I was unable to reproduce this in
|
||||
mainline kernel. I still would like to fix this problem in the kernel.
|
||||
|
||||
Fixes: 6989310f5d43 ("wireless: Use offsetof instead of custom macro.")
|
||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
---
|
||||
include/uapi/linux/wireless.h | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/include/uapi/linux/wireless.h
|
||||
+++ b/include/uapi/linux/wireless.h
|
||||
@@ -74,7 +74,11 @@
|
||||
#include <linux/socket.h> /* for "struct sockaddr" et al */
|
||||
#include <linux/if.h> /* for IFNAMSIZ and co... */
|
||||
|
||||
-#include <stddef.h> /* for offsetof */
|
||||
+#ifdef __KERNEL__
|
||||
+# include <linux/stddef.h> /* for offsetof */
|
||||
+#else
|
||||
+# include <stddef.h> /* for offsetof */
|
||||
+#endif
|
||||
|
||||
/***************************** VERSION *****************************/
|
||||
/*
|
@ -687,7 +687,7 @@
|
||||
#endif /* AES_GMAC_H */
|
||||
--- a/net/mac80211/key.h
|
||||
+++ b/net/mac80211/key.h
|
||||
@@ -88,7 +88,7 @@ struct ieee80211_key {
|
||||
@@ -89,7 +89,7 @@ struct ieee80211_key {
|
||||
* Management frames.
|
||||
*/
|
||||
u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
|
||||
|
@ -2,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1172,7 +1172,6 @@ static int ieee80211_stop_ap(struct wiph
|
||||
@@ -1186,7 +1186,6 @@ static int ieee80211_stop_ap(struct wiph
|
||||
sdata->vif.bss_conf.ftmr_params = NULL;
|
||||
|
||||
__sta_info_flush(sdata, true);
|
||||
|
@ -21,7 +21,7 @@ Disable FILS support, since it pulls in crypto hash support
|
||||
* FILS AEAD for (Re)Association Request/Response frames
|
||||
--- a/net/mac80211/main.c
|
||||
+++ b/net/mac80211/main.c
|
||||
@@ -571,7 +571,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
|
||||
@@ -586,7 +586,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
|
||||
NL80211_FEATURE_MAC_ON_CREATE |
|
||||
NL80211_FEATURE_USERSPACE_MPM |
|
||||
NL80211_FEATURE_FULL_AP_CLIENT_STATE;
|
||||
|
@ -11,14 +11,13 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/mac80211/aes_cmac.c
|
||||
+++ b/net/mac80211/aes_cmac.c
|
||||
@@ -19,50 +19,126 @@
|
||||
@@ -19,67 +19,151 @@
|
||||
#define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */
|
||||
#define AAD_LEN 20
|
||||
|
||||
-static const u8 zero[CMAC_TLEN_256];
|
||||
|
||||
-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
|
||||
- const u8 *data, size_t data_len, u8 *mic)
|
||||
+void gf_mulx(u8 *pad)
|
||||
+{
|
||||
+ int i, carry;
|
||||
@ -34,9 +33,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
|
||||
+ const u8 *addr[], const size_t *len, u8 *mac,
|
||||
+ size_t mac_len)
|
||||
{
|
||||
- SHASH_DESC_ON_STACK(desc, tfm);
|
||||
- u8 out[AES_BLOCK_SIZE];
|
||||
+{
|
||||
+ u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
|
||||
+ const u8 *pos, *end;
|
||||
+ size_t i, e, left, total_len;
|
||||
@ -88,30 +85,48 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
+ crypto_cipher_encrypt_one(tfm, pad, pad);
|
||||
+ memcpy(mac, pad, mac_len);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
|
||||
const u8 *data, size_t data_len, u8 *mic)
|
||||
{
|
||||
- SHASH_DESC_ON_STACK(desc, tfm);
|
||||
- u8 out[AES_BLOCK_SIZE];
|
||||
+ const u8 *addr[4];
|
||||
+ size_t len[4];
|
||||
+ u8 zero[CMAC_TLEN];
|
||||
const __le16 *fc;
|
||||
|
||||
- desc->tfm = tfm;
|
||||
|
||||
-
|
||||
- crypto_shash_init(desc);
|
||||
- crypto_shash_update(desc, aad, AAD_LEN);
|
||||
- crypto_shash_update(desc, data, data_len - CMAC_TLEN);
|
||||
- crypto_shash_finup(desc, zero, CMAC_TLEN, out);
|
||||
+void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
|
||||
+ const u8 *data, size_t data_len, u8 *mic)
|
||||
+{
|
||||
+ const u8 *addr[3];
|
||||
+ size_t len[3];
|
||||
+ u8 zero[CMAC_TLEN];
|
||||
+
|
||||
+ memset(zero, 0, CMAC_TLEN);
|
||||
+ addr[0] = aad;
|
||||
+ len[0] = AAD_LEN;
|
||||
+ addr[1] = data;
|
||||
+ len[1] = data_len - CMAC_TLEN;
|
||||
+ addr[2] = zero;
|
||||
+ len[2] = CMAC_TLEN;
|
||||
|
||||
fc = (const __le16 *)aad;
|
||||
if (ieee80211_is_beacon(*fc)) {
|
||||
/* mask Timestamp field to zero */
|
||||
- crypto_shash_update(desc, zero, 8);
|
||||
- crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN);
|
||||
+ addr[1] = zero;
|
||||
+ len[1] = 8;
|
||||
+ addr[2] = data + 8;
|
||||
+ len[2] = data_len - 8 - CMAC_TLEN;
|
||||
+ addr[3] = zero;
|
||||
+ len[3] = CMAC_TLEN;
|
||||
+ aes_cmac_vector(tfm, 4, addr, len, mic, CMAC_TLEN);
|
||||
} else {
|
||||
- crypto_shash_update(desc, data, data_len - CMAC_TLEN);
|
||||
+ addr[1] = data;
|
||||
+ len[1] = data_len - CMAC_TLEN;
|
||||
+ addr[2] = zero;
|
||||
+ len[2] = CMAC_TLEN;
|
||||
+ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN);
|
||||
}
|
||||
- crypto_shash_finup(desc, zero, CMAC_TLEN, out);
|
||||
-
|
||||
- memcpy(mic, out, CMAC_TLEN);
|
||||
+ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN);
|
||||
}
|
||||
|
||||
-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
|
||||
@ -119,25 +134,41 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
const u8 *data, size_t data_len, u8 *mic)
|
||||
{
|
||||
- SHASH_DESC_ON_STACK(desc, tfm);
|
||||
+ const u8 *addr[3];
|
||||
+ size_t len[3];
|
||||
+ const u8 *addr[4];
|
||||
+ size_t len[4];
|
||||
+ u8 zero[CMAC_TLEN_256];
|
||||
+
|
||||
+ memset(zero, 0, CMAC_TLEN_256);
|
||||
+ addr[0] = aad;
|
||||
+ len[0] = AAD_LEN;
|
||||
+ addr[1] = data;
|
||||
+ len[1] = data_len - CMAC_TLEN_256;
|
||||
+ addr[2] = zero;
|
||||
+ len[2] = CMAC_TLEN_256;
|
||||
const __le16 *fc;
|
||||
|
||||
- desc->tfm = tfm;
|
||||
-
|
||||
- crypto_shash_init(desc);
|
||||
- crypto_shash_update(desc, aad, AAD_LEN);
|
||||
- crypto_shash_update(desc, data, data_len - CMAC_TLEN_256);
|
||||
+ memset(zero, 0, CMAC_TLEN_256);
|
||||
+ addr[0] = aad;
|
||||
+ len[0] = AAD_LEN;
|
||||
+ addr[1] = data;
|
||||
fc = (const __le16 *)aad;
|
||||
if (ieee80211_is_beacon(*fc)) {
|
||||
/* mask Timestamp field to zero */
|
||||
- crypto_shash_update(desc, zero, 8);
|
||||
- crypto_shash_update(desc, data + 8,
|
||||
- data_len - 8 - CMAC_TLEN_256);
|
||||
+ addr[1] = zero;
|
||||
+ len[1] = 8;
|
||||
+ addr[2] = data + 8;
|
||||
+ len[2] = data_len - 8 - CMAC_TLEN_256;
|
||||
+ addr[3] = zero;
|
||||
+ len[3] = CMAC_TLEN_256;
|
||||
+ aes_cmac_vector(tfm, 4, addr, len, mic, CMAC_TLEN_256);
|
||||
} else {
|
||||
- crypto_shash_update(desc, data, data_len - CMAC_TLEN_256);
|
||||
+ addr[1] = data;
|
||||
+ len[1] = data_len - CMAC_TLEN_256;
|
||||
+ addr[2] = zero;
|
||||
+ len[2] = CMAC_TLEN_256;
|
||||
+ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN_256);
|
||||
}
|
||||
- crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic);
|
||||
+ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN_256);
|
||||
}
|
||||
|
||||
-struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
|
||||
@ -188,7 +219,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
#endif /* AES_CMAC_H */
|
||||
--- a/net/mac80211/key.h
|
||||
+++ b/net/mac80211/key.h
|
||||
@@ -93,7 +93,7 @@ struct ieee80211_key {
|
||||
@@ -94,7 +94,7 @@ struct ieee80211_key {
|
||||
} ccmp;
|
||||
struct {
|
||||
u8 rx_pn[IEEE80211_CMAC_PN_LEN];
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -4024,6 +4024,12 @@ out:
|
||||
@@ -4119,6 +4119,12 @@ out:
|
||||
netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/net/mac80211/main.c
|
||||
+++ b/net/mac80211/main.c
|
||||
@@ -314,7 +314,7 @@ void ieee80211_restart_hw(struct ieee802
|
||||
@@ -316,7 +316,7 @@ void ieee80211_restart_hw(struct ieee802
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_restart_hw);
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
static int ieee80211_ifa_changed(struct notifier_block *nb,
|
||||
unsigned long data, void *arg)
|
||||
{
|
||||
@@ -373,7 +373,7 @@ static int ieee80211_ifa_changed(struct
|
||||
@@ -375,7 +375,7 @@ static int ieee80211_ifa_changed(struct
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
static int ieee80211_ifa6_changed(struct notifier_block *nb,
|
||||
unsigned long data, void *arg)
|
||||
{
|
||||
@@ -1264,14 +1264,14 @@ int ieee80211_register_hw(struct ieee802
|
||||
@@ -1292,14 +1292,14 @@ int ieee80211_register_hw(struct ieee802
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
|
||||
result = register_inet6addr_notifier(&local->ifa6_notifier);
|
||||
if (result)
|
||||
@@ -1280,13 +1280,13 @@ int ieee80211_register_hw(struct ieee802
|
||||
@@ -1308,13 +1308,13 @@ int ieee80211_register_hw(struct ieee802
|
||||
|
||||
return 0;
|
||||
|
||||
@ -51,8 +51,8 @@
|
||||
+#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6)
|
||||
fail_ifa:
|
||||
#endif
|
||||
rtnl_lock();
|
||||
@@ -1314,10 +1314,10 @@ void ieee80211_unregister_hw(struct ieee
|
||||
wiphy_unregister(local->hw.wiphy);
|
||||
@@ -1342,10 +1342,10 @@ void ieee80211_unregister_hw(struct ieee
|
||||
tasklet_kill(&local->tx_pending_tasklet);
|
||||
tasklet_kill(&local->tasklet);
|
||||
|
||||
|
@ -24,7 +24,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1782,6 +1782,9 @@ int ieee80211_tx_control_port(struct wip
|
||||
@@ -1801,6 +1801,9 @@ int ieee80211_tx_control_port(struct wip
|
||||
const u8 *dest, __be16 proto, bool unencrypted);
|
||||
int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *buf, size_t len);
|
||||
@ -36,7 +36,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
|
||||
--- a/net/mac80211/status.c
|
||||
+++ b/net/mac80211/status.c
|
||||
@@ -815,6 +815,11 @@ void ieee80211_tx_monitor(struct ieee802
|
||||
@@ -828,6 +828,11 @@ void ieee80211_tx_monitor(struct ieee802
|
||||
struct net_device *prev_dev = NULL;
|
||||
int rtap_len;
|
||||
|
||||
@ -143,7 +143,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
ieee80211_free_txskb(&local->hw, skb);
|
||||
return;
|
||||
}
|
||||
@@ -2784,29 +2790,13 @@ static struct sk_buff *ieee80211_build_h
|
||||
@@ -2796,29 +2802,13 @@ static struct sk_buff *ieee80211_build_h
|
||||
}
|
||||
|
||||
skb_pull(skb, skip_header_bytes);
|
||||
@ -179,7 +179,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
}
|
||||
|
||||
if (encaps_data)
|
||||
@@ -3421,7 +3411,6 @@ static bool ieee80211_xmit_fast(struct i
|
||||
@@ -3433,7 +3423,6 @@ static bool ieee80211_xmit_fast(struct i
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
u16 ethertype = (skb->data[12] << 8) | skb->data[13];
|
||||
int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2);
|
||||
@ -187,7 +187,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
struct ethhdr eth;
|
||||
struct ieee80211_tx_info *info;
|
||||
struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
|
||||
@@ -3473,10 +3462,7 @@ static bool ieee80211_xmit_fast(struct i
|
||||
@@ -3485,10 +3474,7 @@ static bool ieee80211_xmit_fast(struct i
|
||||
* as the may-encrypt argument for the resize to not account for
|
||||
* more room than we already have in 'extra_head'
|
||||
*/
|
||||
|
@ -1,61 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 28 Sep 2019 15:44:06 +0200
|
||||
Subject: [PATCH] mac80211: minstrel: remove divisions in tx status path
|
||||
|
||||
Use a slightly different threshold for downgrading spatial streams to
|
||||
make it easier to calculate without divisions.
|
||||
Slightly reduces CPU overhead.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel.c
|
||||
+++ b/net/mac80211/rc80211_minstrel.c
|
||||
@@ -289,8 +289,7 @@ minstrel_tx_status(void *priv, struct ie
|
||||
if (mi->sample_deferred > 0)
|
||||
mi->sample_deferred--;
|
||||
|
||||
- if (time_after(jiffies, mi->last_stats_update +
|
||||
- (mp->update_interval * HZ) / 1000))
|
||||
+ if (time_after(jiffies, mi->last_stats_update + mp->update_interval))
|
||||
minstrel_update_stats(mp, mi);
|
||||
}
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -970,23 +970,21 @@ minstrel_ht_tx_status(void *priv, struct
|
||||
*/
|
||||
rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
|
||||
if (rate->attempts > 30 &&
|
||||
- MINSTREL_FRAC(rate->success, rate->attempts) <
|
||||
- MINSTREL_FRAC(20, 100)) {
|
||||
+ rate->success < rate->attempts / 4) {
|
||||
minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true);
|
||||
update = true;
|
||||
}
|
||||
|
||||
rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]);
|
||||
if (rate2->attempts > 30 &&
|
||||
- MINSTREL_FRAC(rate2->success, rate2->attempts) <
|
||||
- MINSTREL_FRAC(20, 100)) {
|
||||
+ rate2->success < rate2->attempts / 4) {
|
||||
minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false);
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (time_after(jiffies, mi->last_stats_update +
|
||||
- (mp->update_interval / 2 * HZ) / 1000)) {
|
||||
+ mp->update_interval / 2)) {
|
||||
update = true;
|
||||
minstrel_ht_update_stats(mp, mi, true);
|
||||
}
|
||||
@@ -1666,7 +1664,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h
|
||||
mp->has_mrr = true;
|
||||
|
||||
mp->hw = hw;
|
||||
- mp->update_interval = 100;
|
||||
+ mp->update_interval = HZ / 10;
|
||||
|
||||
#ifdef CPTCFG_MAC80211_DEBUGFS
|
||||
mp->fixed_rate_idx = (u32) -1;
|
@ -1,235 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 28 Sep 2019 15:46:06 +0200
|
||||
Subject: [PATCH] mac80211: minstrel_ht: replace rate stats ewma with a
|
||||
better moving average
|
||||
|
||||
Rate success probability usually fluctuates a lot under normal conditions.
|
||||
With a simple EWMA, noise and fluctuation can be reduced by increasing the
|
||||
window length, but that comes at the cost of introducing lag on sudden
|
||||
changes.
|
||||
|
||||
This change replaces the EWMA implementation with a moving average that's
|
||||
designed to significantly reduce lag while keeping a bigger window size
|
||||
by being better at filtering out noise.
|
||||
|
||||
It is only slightly more expensive than the simple EWMA and still avoids
|
||||
divisions in its calculation.
|
||||
|
||||
The algorithm is adapted from an implementation intended for a completely
|
||||
different field (stock market trading), where the tradeoff of lag vs
|
||||
noise filtering is equally important.
|
||||
|
||||
The algorithm works in the same way as the "smoothing filter" from
|
||||
http://www.stockspotter.com/files/PredictiveIndicators.pdf adapted for
|
||||
fixed-point math with some constants, using only addition, bit shifts
|
||||
and multiplication
|
||||
|
||||
To better make use of the filtering and bigger window size, the update
|
||||
interval is cut in half.
|
||||
|
||||
For testing, the algorithm can be reverted to the older one via debugfs
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel.c
|
||||
+++ b/net/mac80211/rc80211_minstrel.c
|
||||
@@ -157,14 +157,18 @@ minstrel_update_rates(struct minstrel_pr
|
||||
* Recalculate statistics and counters of a given rate
|
||||
*/
|
||||
void
|
||||
-minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs)
|
||||
+minstrel_calc_rate_stats(struct minstrel_priv *mp,
|
||||
+ struct minstrel_rate_stats *mrs)
|
||||
{
|
||||
unsigned int cur_prob;
|
||||
|
||||
if (unlikely(mrs->attempts > 0)) {
|
||||
mrs->sample_skipped = 0;
|
||||
cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
|
||||
- if (unlikely(!mrs->att_hist)) {
|
||||
+ if (mp->new_avg) {
|
||||
+ mrs->prob_ewma = minstrel_filter_avg_add(&mrs->avg,
|
||||
+ cur_prob);
|
||||
+ } else if (unlikely(!mrs->att_hist)) {
|
||||
mrs->prob_ewma = cur_prob;
|
||||
} else {
|
||||
/*update exponential weighted moving avarage */
|
||||
@@ -200,7 +204,7 @@ minstrel_update_stats(struct minstrel_pr
|
||||
struct minstrel_rate_stats *tmp_mrs = &mi->r[tmp_prob_rate].stats;
|
||||
|
||||
/* Update statistics of success probability per rate */
|
||||
- minstrel_calc_rate_stats(mrs);
|
||||
+ minstrel_calc_rate_stats(mp, mrs);
|
||||
|
||||
/* Sample less often below the 10% chance of success.
|
||||
* Sample less often above the 95% chance of success. */
|
||||
@@ -289,7 +293,8 @@ minstrel_tx_status(void *priv, struct ie
|
||||
if (mi->sample_deferred > 0)
|
||||
mi->sample_deferred--;
|
||||
|
||||
- if (time_after(jiffies, mi->last_stats_update + mp->update_interval))
|
||||
+ if (time_after(jiffies, mi->last_stats_update +
|
||||
+ mp->update_interval / (mp->new_avg ? 2 : 1)))
|
||||
minstrel_update_stats(mp, mi);
|
||||
}
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel.h
|
||||
+++ b/net/mac80211/rc80211_minstrel.h
|
||||
@@ -19,6 +19,21 @@
|
||||
#define MAX_THR_RATES 4
|
||||
|
||||
/*
|
||||
+ * Coefficients for moving average with noise filter (period=16),
|
||||
+ * scaled by 10 bits
|
||||
+ *
|
||||
+ * a1 = exp(-pi * sqrt(2) / period)
|
||||
+ * coeff2 = 2 * a1 * cos(sqrt(2) * 2 * pi / period)
|
||||
+ * coeff3 = -sqr(a1)
|
||||
+ * coeff1 = 1 - coeff2 - coeff3
|
||||
+ */
|
||||
+#define MINSTREL_AVG_COEFF1 (MINSTREL_FRAC(1, 1) - \
|
||||
+ MINSTREL_AVG_COEFF2 - \
|
||||
+ MINSTREL_AVG_COEFF3)
|
||||
+#define MINSTREL_AVG_COEFF2 0x00001499
|
||||
+#define MINSTREL_AVG_COEFF3 -0x0000092e
|
||||
+
|
||||
+/*
|
||||
* Perform EWMA (Exponentially Weighted Moving Average) calculation
|
||||
*/
|
||||
static inline int
|
||||
@@ -32,6 +47,41 @@ minstrel_ewma(int old, int new, int weig
|
||||
return old + incr;
|
||||
}
|
||||
|
||||
+struct minstrel_avg_ctx {
|
||||
+ s32 prev[2];
|
||||
+};
|
||||
+
|
||||
+static inline int minstrel_filter_avg_add(struct minstrel_avg_ctx *ctx, s32 in)
|
||||
+{
|
||||
+ s32 out_1 = ctx->prev[0];
|
||||
+ s32 out_2 = ctx->prev[1];
|
||||
+ s32 val;
|
||||
+
|
||||
+ if (!in)
|
||||
+ in += 1;
|
||||
+
|
||||
+ if (!out_1) {
|
||||
+ val = out_1 = in;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ val = MINSTREL_AVG_COEFF1 * in;
|
||||
+ val += MINSTREL_AVG_COEFF2 * out_1;
|
||||
+ val += MINSTREL_AVG_COEFF3 * out_2;
|
||||
+ val >>= MINSTREL_SCALE;
|
||||
+
|
||||
+ if (val > 1 << MINSTREL_SCALE)
|
||||
+ val = 1 << MINSTREL_SCALE;
|
||||
+ if (val < 0)
|
||||
+ val = 1;
|
||||
+
|
||||
+out:
|
||||
+ ctx->prev[1] = out_1;
|
||||
+ ctx->prev[0] = val;
|
||||
+
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
struct minstrel_rate_stats {
|
||||
/* current / last sampling period attempts/success counters */
|
||||
u16 attempts, last_attempts;
|
||||
@@ -40,6 +90,8 @@ struct minstrel_rate_stats {
|
||||
/* total attempts/success counters */
|
||||
u32 att_hist, succ_hist;
|
||||
|
||||
+ struct minstrel_avg_ctx avg;
|
||||
+
|
||||
/* prob_ewma - exponential weighted moving average of prob */
|
||||
u16 prob_ewma;
|
||||
|
||||
@@ -95,6 +147,7 @@ struct minstrel_sta_info {
|
||||
struct minstrel_priv {
|
||||
struct ieee80211_hw *hw;
|
||||
bool has_mrr;
|
||||
+ bool new_avg;
|
||||
u32 sample_switch;
|
||||
unsigned int cw_min;
|
||||
unsigned int cw_max;
|
||||
@@ -126,7 +179,8 @@ extern const struct rate_control_ops mac
|
||||
void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
|
||||
|
||||
/* Recalculate success probabilities and counters for a given rate using EWMA */
|
||||
-void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs);
|
||||
+void minstrel_calc_rate_stats(struct minstrel_priv *mp,
|
||||
+ struct minstrel_rate_stats *mrs);
|
||||
int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma);
|
||||
|
||||
/* debugfs */
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -737,7 +737,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
|
||||
mrs = &mg->rates[i];
|
||||
mrs->retry_updated = false;
|
||||
- minstrel_calc_rate_stats(mrs);
|
||||
+ minstrel_calc_rate_stats(mp, mrs);
|
||||
cur_prob = mrs->prob_ewma;
|
||||
|
||||
if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0)
|
||||
@@ -773,6 +773,8 @@ minstrel_ht_update_stats(struct minstrel
|
||||
|
||||
/* try to sample all available rates during each interval */
|
||||
mi->sample_count *= 8;
|
||||
+ if (mp->new_avg)
|
||||
+ mi->sample_count /= 2;
|
||||
|
||||
if (sample)
|
||||
minstrel_ht_rate_sample_switch(mp, mi);
|
||||
@@ -889,6 +891,7 @@ minstrel_ht_tx_status(void *priv, struct
|
||||
struct ieee80211_tx_rate *ar = info->status.rates;
|
||||
struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL;
|
||||
struct minstrel_priv *mp = priv;
|
||||
+ u32 update_interval = mp->update_interval / 2;
|
||||
bool last, update = false;
|
||||
bool sample_status = false;
|
||||
int i;
|
||||
@@ -943,6 +946,10 @@ minstrel_ht_tx_status(void *priv, struct
|
||||
|
||||
switch (mi->sample_mode) {
|
||||
case MINSTREL_SAMPLE_IDLE:
|
||||
+ if (mp->new_avg &&
|
||||
+ (mp->hw->max_rates > 1 ||
|
||||
+ mi->total_packets_cur < SAMPLE_SWITCH_THR))
|
||||
+ update_interval /= 2;
|
||||
break;
|
||||
|
||||
case MINSTREL_SAMPLE_ACTIVE:
|
||||
@@ -983,8 +990,7 @@ minstrel_ht_tx_status(void *priv, struct
|
||||
}
|
||||
}
|
||||
|
||||
- if (time_after(jiffies, mi->last_stats_update +
|
||||
- mp->update_interval / 2)) {
|
||||
+ if (time_after(jiffies, mi->last_stats_update + update_interval)) {
|
||||
update = true;
|
||||
minstrel_ht_update_stats(mp, mi, true);
|
||||
}
|
||||
@@ -1665,6 +1671,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h
|
||||
|
||||
mp->hw = hw;
|
||||
mp->update_interval = HZ / 10;
|
||||
+ mp->new_avg = true;
|
||||
|
||||
#ifdef CPTCFG_MAC80211_DEBUGFS
|
||||
mp->fixed_rate_idx = (u32) -1;
|
||||
@@ -1672,6 +1679,8 @@ minstrel_ht_alloc(struct ieee80211_hw *h
|
||||
&mp->fixed_rate_idx);
|
||||
debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir,
|
||||
&mp->sample_switch);
|
||||
+ debugfs_create_bool("new_avg", S_IRUGO | S_IWUSR, debugfsdir,
|
||||
+ &mp->new_avg);
|
||||
#endif
|
||||
|
||||
minstrel_ht_init_cck_rates(mp);
|
@ -1,424 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 8 Oct 2019 18:54:46 +0200
|
||||
Subject: [PATCH] mac80211: minstrel_ht: rename prob_ewma to prob_avg, use it
|
||||
for the new average
|
||||
|
||||
Reduces per-rate data structure size
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel.c
|
||||
+++ b/net/mac80211/rc80211_minstrel.c
|
||||
@@ -70,7 +70,7 @@ rix_to_ndx(struct minstrel_sta_info *mi,
|
||||
}
|
||||
|
||||
/* return current EMWA throughput */
|
||||
-int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma)
|
||||
+int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg)
|
||||
{
|
||||
int usecs;
|
||||
|
||||
@@ -79,13 +79,13 @@ int minstrel_get_tp_avg(struct minstrel_
|
||||
usecs = 1000000;
|
||||
|
||||
/* reset thr. below 10% success */
|
||||
- if (mr->stats.prob_ewma < MINSTREL_FRAC(10, 100))
|
||||
+ if (mr->stats.prob_avg < MINSTREL_FRAC(10, 100))
|
||||
return 0;
|
||||
|
||||
- if (prob_ewma > MINSTREL_FRAC(90, 100))
|
||||
+ if (prob_avg > MINSTREL_FRAC(90, 100))
|
||||
return MINSTREL_TRUNC(100000 * (MINSTREL_FRAC(90, 100) / usecs));
|
||||
else
|
||||
- return MINSTREL_TRUNC(100000 * (prob_ewma / usecs));
|
||||
+ return MINSTREL_TRUNC(100000 * (prob_avg / usecs));
|
||||
}
|
||||
|
||||
/* find & sort topmost throughput rates */
|
||||
@@ -98,8 +98,8 @@ minstrel_sort_best_tp_rates(struct minst
|
||||
|
||||
for (j = MAX_THR_RATES; j > 0; --j) {
|
||||
tmp_mrs = &mi->r[tp_list[j - 1]].stats;
|
||||
- if (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_ewma) <=
|
||||
- minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_ewma))
|
||||
+ if (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_avg) <=
|
||||
+ minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_avg))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -166,15 +166,15 @@ minstrel_calc_rate_stats(struct minstrel
|
||||
mrs->sample_skipped = 0;
|
||||
cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
|
||||
if (mp->new_avg) {
|
||||
- mrs->prob_ewma = minstrel_filter_avg_add(&mrs->avg,
|
||||
- cur_prob);
|
||||
+ minstrel_filter_avg_add(&mrs->prob_avg,
|
||||
+ &mrs->prob_avg_1, cur_prob);
|
||||
} else if (unlikely(!mrs->att_hist)) {
|
||||
- mrs->prob_ewma = cur_prob;
|
||||
+ mrs->prob_avg = cur_prob;
|
||||
} else {
|
||||
/*update exponential weighted moving avarage */
|
||||
- mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma,
|
||||
- cur_prob,
|
||||
- EWMA_LEVEL);
|
||||
+ mrs->prob_avg = minstrel_ewma(mrs->prob_avg,
|
||||
+ cur_prob,
|
||||
+ EWMA_LEVEL);
|
||||
}
|
||||
mrs->att_hist += mrs->attempts;
|
||||
mrs->succ_hist += mrs->success;
|
||||
@@ -208,8 +208,8 @@ minstrel_update_stats(struct minstrel_pr
|
||||
|
||||
/* Sample less often below the 10% chance of success.
|
||||
* Sample less often above the 95% chance of success. */
|
||||
- if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) ||
|
||||
- mrs->prob_ewma < MINSTREL_FRAC(10, 100)) {
|
||||
+ if (mrs->prob_avg > MINSTREL_FRAC(95, 100) ||
|
||||
+ mrs->prob_avg < MINSTREL_FRAC(10, 100)) {
|
||||
mr->adjusted_retry_count = mrs->retry_count >> 1;
|
||||
if (mr->adjusted_retry_count > 2)
|
||||
mr->adjusted_retry_count = 2;
|
||||
@@ -229,14 +229,14 @@ minstrel_update_stats(struct minstrel_pr
|
||||
* choose the maximum throughput rate as max_prob_rate
|
||||
* (2) if all success probabilities < 95%, the rate with
|
||||
* highest success probability is chosen as max_prob_rate */
|
||||
- if (mrs->prob_ewma >= MINSTREL_FRAC(95, 100)) {
|
||||
- tmp_cur_tp = minstrel_get_tp_avg(mr, mrs->prob_ewma);
|
||||
+ if (mrs->prob_avg >= MINSTREL_FRAC(95, 100)) {
|
||||
+ tmp_cur_tp = minstrel_get_tp_avg(mr, mrs->prob_avg);
|
||||
tmp_prob_tp = minstrel_get_tp_avg(&mi->r[tmp_prob_rate],
|
||||
- tmp_mrs->prob_ewma);
|
||||
+ tmp_mrs->prob_avg);
|
||||
if (tmp_cur_tp >= tmp_prob_tp)
|
||||
tmp_prob_rate = i;
|
||||
} else {
|
||||
- if (mrs->prob_ewma >= tmp_mrs->prob_ewma)
|
||||
+ if (mrs->prob_avg >= tmp_mrs->prob_avg)
|
||||
tmp_prob_rate = i;
|
||||
}
|
||||
}
|
||||
@@ -426,7 +426,7 @@ minstrel_get_rate(void *priv, struct iee
|
||||
* has a probability of >95%, we shouldn't be attempting
|
||||
* to use it, as this only wastes precious airtime */
|
||||
if (!mrr_capable &&
|
||||
- (mi->r[ndx].stats.prob_ewma > MINSTREL_FRAC(95, 100)))
|
||||
+ (mi->r[ndx].stats.prob_avg > MINSTREL_FRAC(95, 100)))
|
||||
return;
|
||||
|
||||
mi->prev_sample = true;
|
||||
@@ -577,7 +577,7 @@ static u32 minstrel_get_expected_through
|
||||
* computing cur_tp
|
||||
*/
|
||||
tmp_mrs = &mi->r[idx].stats;
|
||||
- tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_ewma) * 10;
|
||||
+ tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_avg) * 10;
|
||||
tmp_cur_tp = tmp_cur_tp * 1200 * 8 / 1024;
|
||||
|
||||
return tmp_cur_tp;
|
||||
--- a/net/mac80211/rc80211_minstrel.h
|
||||
+++ b/net/mac80211/rc80211_minstrel.h
|
||||
@@ -47,14 +47,10 @@ minstrel_ewma(int old, int new, int weig
|
||||
return old + incr;
|
||||
}
|
||||
|
||||
-struct minstrel_avg_ctx {
|
||||
- s32 prev[2];
|
||||
-};
|
||||
-
|
||||
-static inline int minstrel_filter_avg_add(struct minstrel_avg_ctx *ctx, s32 in)
|
||||
+static inline int minstrel_filter_avg_add(u16 *prev_1, u16 *prev_2, s32 in)
|
||||
{
|
||||
- s32 out_1 = ctx->prev[0];
|
||||
- s32 out_2 = ctx->prev[1];
|
||||
+ s32 out_1 = *prev_1;
|
||||
+ s32 out_2 = *prev_2;
|
||||
s32 val;
|
||||
|
||||
if (!in)
|
||||
@@ -76,8 +72,8 @@ static inline int minstrel_filter_avg_ad
|
||||
val = 1;
|
||||
|
||||
out:
|
||||
- ctx->prev[1] = out_1;
|
||||
- ctx->prev[0] = val;
|
||||
+ *prev_2 = out_1;
|
||||
+ *prev_1 = val;
|
||||
|
||||
return val;
|
||||
}
|
||||
@@ -90,10 +86,9 @@ struct minstrel_rate_stats {
|
||||
/* total attempts/success counters */
|
||||
u32 att_hist, succ_hist;
|
||||
|
||||
- struct minstrel_avg_ctx avg;
|
||||
-
|
||||
- /* prob_ewma - exponential weighted moving average of prob */
|
||||
- u16 prob_ewma;
|
||||
+ /* prob_avg - moving average of prob */
|
||||
+ u16 prob_avg;
|
||||
+ u16 prob_avg_1;
|
||||
|
||||
/* maximum retry counts */
|
||||
u8 retry_count;
|
||||
@@ -181,7 +176,7 @@ void minstrel_add_sta_debugfs(void *priv
|
||||
/* Recalculate success probabilities and counters for a given rate using EWMA */
|
||||
void minstrel_calc_rate_stats(struct minstrel_priv *mp,
|
||||
struct minstrel_rate_stats *mrs);
|
||||
-int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma);
|
||||
+int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg);
|
||||
|
||||
/* debugfs */
|
||||
int minstrel_stats_open(struct inode *inode, struct file *file);
|
||||
--- a/net/mac80211/rc80211_minstrel_debugfs.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
|
||||
@@ -90,8 +90,8 @@ minstrel_stats_open(struct inode *inode,
|
||||
p += sprintf(p, "%6u ", mr->perfect_tx_time);
|
||||
|
||||
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
|
||||
- tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
|
||||
- eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
|
||||
+ tp_avg = minstrel_get_tp_avg(mr, mrs->prob_avg);
|
||||
+ eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000);
|
||||
|
||||
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u"
|
||||
" %3u %3u %-3u "
|
||||
@@ -147,8 +147,8 @@ minstrel_stats_csv_open(struct inode *in
|
||||
p += sprintf(p, "%u,",mr->perfect_tx_time);
|
||||
|
||||
tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100));
|
||||
- tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma);
|
||||
- eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
|
||||
+ tp_avg = minstrel_get_tp_avg(mr, mrs->prob_avg);
|
||||
+ eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000);
|
||||
|
||||
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u,%u,"
|
||||
"%llu,%llu,%d,%d\n",
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -346,12 +346,12 @@ minstrel_ht_avg_ampdu_len(struct minstre
|
||||
*/
|
||||
int
|
||||
minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate,
|
||||
- int prob_ewma)
|
||||
+ int prob_avg)
|
||||
{
|
||||
unsigned int nsecs = 0;
|
||||
|
||||
/* do not account throughput if sucess prob is below 10% */
|
||||
- if (prob_ewma < MINSTREL_FRAC(10, 100))
|
||||
+ if (prob_avg < MINSTREL_FRAC(10, 100))
|
||||
return 0;
|
||||
|
||||
if (group != MINSTREL_CCK_GROUP)
|
||||
@@ -365,11 +365,11 @@ minstrel_ht_get_tp_avg(struct minstrel_h
|
||||
* account for collision related packet error rate fluctuation
|
||||
* (prob is scaled - see MINSTREL_FRAC above)
|
||||
*/
|
||||
- if (prob_ewma > MINSTREL_FRAC(90, 100))
|
||||
+ if (prob_avg > MINSTREL_FRAC(90, 100))
|
||||
return MINSTREL_TRUNC(100000 * ((MINSTREL_FRAC(90, 100) * 1000)
|
||||
/ nsecs));
|
||||
else
|
||||
- return MINSTREL_TRUNC(100000 * ((prob_ewma * 1000) / nsecs));
|
||||
+ return MINSTREL_TRUNC(100000 * ((prob_avg * 1000) / nsecs));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -389,13 +389,13 @@ minstrel_ht_sort_best_tp_rates(struct mi
|
||||
|
||||
cur_group = index / MCS_GROUP_RATES;
|
||||
cur_idx = index % MCS_GROUP_RATES;
|
||||
- cur_prob = mi->groups[cur_group].rates[cur_idx].prob_ewma;
|
||||
+ cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg;
|
||||
cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, cur_prob);
|
||||
|
||||
do {
|
||||
tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
|
||||
tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
|
||||
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
|
||||
+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx,
|
||||
tmp_prob);
|
||||
if (cur_tp_avg < tmp_tp_avg ||
|
||||
@@ -432,7 +432,7 @@ minstrel_ht_set_best_prob_rate(struct mi
|
||||
|
||||
tmp_group = mi->max_prob_rate / MCS_GROUP_RATES;
|
||||
tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES;
|
||||
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
|
||||
+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
|
||||
|
||||
/* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from
|
||||
@@ -444,11 +444,11 @@ minstrel_ht_set_best_prob_rate(struct mi
|
||||
|
||||
max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES;
|
||||
max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
|
||||
- max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_ewma;
|
||||
+ max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
|
||||
|
||||
- if (mrs->prob_ewma > MINSTREL_FRAC(75, 100)) {
|
||||
+ if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) {
|
||||
cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx,
|
||||
- mrs->prob_ewma);
|
||||
+ mrs->prob_avg);
|
||||
if (cur_tp_avg > tmp_tp_avg)
|
||||
mi->max_prob_rate = index;
|
||||
|
||||
@@ -458,9 +458,9 @@ minstrel_ht_set_best_prob_rate(struct mi
|
||||
if (cur_tp_avg > max_gpr_tp_avg)
|
||||
mg->max_group_prob_rate = index;
|
||||
} else {
|
||||
- if (mrs->prob_ewma > tmp_prob)
|
||||
+ if (mrs->prob_avg > tmp_prob)
|
||||
mi->max_prob_rate = index;
|
||||
- if (mrs->prob_ewma > max_gpr_prob)
|
||||
+ if (mrs->prob_avg > max_gpr_prob)
|
||||
mg->max_group_prob_rate = index;
|
||||
}
|
||||
}
|
||||
@@ -482,12 +482,12 @@ minstrel_ht_assign_best_tp_rates(struct
|
||||
|
||||
tmp_group = tmp_cck_tp_rate[0] / MCS_GROUP_RATES;
|
||||
tmp_idx = tmp_cck_tp_rate[0] % MCS_GROUP_RATES;
|
||||
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
|
||||
+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
|
||||
|
||||
tmp_group = tmp_mcs_tp_rate[0] / MCS_GROUP_RATES;
|
||||
tmp_idx = tmp_mcs_tp_rate[0] % MCS_GROUP_RATES;
|
||||
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma;
|
||||
+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
|
||||
|
||||
if (tmp_cck_tp_rate && tmp_cck_tp > tmp_mcs_tp) {
|
||||
@@ -518,7 +518,7 @@ minstrel_ht_prob_rate_reduce_streams(str
|
||||
continue;
|
||||
|
||||
tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
|
||||
- tmp_prob = mi->groups[group].rates[tmp_idx].prob_ewma;
|
||||
+ tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg;
|
||||
|
||||
if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) &&
|
||||
(minstrel_mcs_groups[group].streams < tmp_max_streams)) {
|
||||
@@ -623,7 +623,7 @@ minstrel_ht_rate_sample_switch(struct mi
|
||||
* If that fails, look again for a rate that is at least as fast
|
||||
*/
|
||||
mrs = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
|
||||
- faster_rate = mrs->prob_ewma > MINSTREL_FRAC(75, 100);
|
||||
+ faster_rate = mrs->prob_avg > MINSTREL_FRAC(75, 100);
|
||||
minstrel_ht_find_probe_rates(mi, rates, &n_rates, faster_rate);
|
||||
if (!n_rates && faster_rate)
|
||||
minstrel_ht_find_probe_rates(mi, rates, &n_rates, false);
|
||||
@@ -738,7 +738,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
mrs = &mg->rates[i];
|
||||
mrs->retry_updated = false;
|
||||
minstrel_calc_rate_stats(mp, mrs);
|
||||
- cur_prob = mrs->prob_ewma;
|
||||
+ cur_prob = mrs->prob_avg;
|
||||
|
||||
if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0)
|
||||
continue;
|
||||
@@ -1012,7 +1012,7 @@ minstrel_calc_retransmit(struct minstrel
|
||||
unsigned int overhead = 0, overhead_rtscts = 0;
|
||||
|
||||
mrs = minstrel_get_ratestats(mi, index);
|
||||
- if (mrs->prob_ewma < MINSTREL_FRAC(1, 10)) {
|
||||
+ if (mrs->prob_avg < MINSTREL_FRAC(1, 10)) {
|
||||
mrs->retry_count = 1;
|
||||
mrs->retry_count_rtscts = 1;
|
||||
return;
|
||||
@@ -1069,7 +1069,7 @@ minstrel_ht_set_rate(struct minstrel_pri
|
||||
if (!mrs->retry_updated)
|
||||
minstrel_calc_retransmit(mp, mi, index);
|
||||
|
||||
- if (mrs->prob_ewma < MINSTREL_FRAC(20, 100) || !mrs->retry_count) {
|
||||
+ if (mrs->prob_avg < MINSTREL_FRAC(20, 100) || !mrs->retry_count) {
|
||||
ratetbl->rate[offset].count = 2;
|
||||
ratetbl->rate[offset].count_rts = 2;
|
||||
ratetbl->rate[offset].count_cts = 2;
|
||||
@@ -1103,11 +1103,11 @@ minstrel_ht_set_rate(struct minstrel_pri
|
||||
}
|
||||
|
||||
static inline int
|
||||
-minstrel_ht_get_prob_ewma(struct minstrel_ht_sta *mi, int rate)
|
||||
+minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate)
|
||||
{
|
||||
int group = rate / MCS_GROUP_RATES;
|
||||
rate %= MCS_GROUP_RATES;
|
||||
- return mi->groups[group].rates[rate].prob_ewma;
|
||||
+ return mi->groups[group].rates[rate].prob_avg;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1119,7 +1119,7 @@ minstrel_ht_get_max_amsdu_len(struct min
|
||||
unsigned int duration;
|
||||
|
||||
/* Disable A-MSDU if max_prob_rate is bad */
|
||||
- if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100))
|
||||
+ if (mi->groups[group].rates[rate].prob_avg < MINSTREL_FRAC(50, 100))
|
||||
return 1;
|
||||
|
||||
duration = g->duration[rate];
|
||||
@@ -1142,7 +1142,7 @@ minstrel_ht_get_max_amsdu_len(struct min
|
||||
* data packet size
|
||||
*/
|
||||
if (duration > MCS_DURATION(1, 0, 260) ||
|
||||
- (minstrel_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) <
|
||||
+ (minstrel_ht_get_prob_avg(mi, mi->max_tp_rate[0]) <
|
||||
MINSTREL_FRAC(75, 100)))
|
||||
return 3200;
|
||||
|
||||
@@ -1247,7 +1247,7 @@ minstrel_get_sample_rate(struct minstrel
|
||||
* rate, to avoid wasting airtime.
|
||||
*/
|
||||
sample_dur = minstrel_get_duration(sample_idx);
|
||||
- if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) ||
|
||||
+ if (mrs->prob_avg > MINSTREL_FRAC(95, 100) ||
|
||||
minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur)
|
||||
return -1;
|
||||
|
||||
@@ -1705,7 +1705,7 @@ static u32 minstrel_ht_get_expected_thro
|
||||
|
||||
i = mi->max_tp_rate[0] / MCS_GROUP_RATES;
|
||||
j = mi->max_tp_rate[0] % MCS_GROUP_RATES;
|
||||
- prob = mi->groups[i].rates[j].prob_ewma;
|
||||
+ prob = mi->groups[i].rates[j].prob_avg;
|
||||
|
||||
/* convert tp_avg from pkt per second in kbps */
|
||||
tp_avg = minstrel_ht_get_tp_avg(mi, i, j, prob) * 10;
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.h
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
||||
@@ -119,6 +119,6 @@ struct minstrel_ht_sta_priv {
|
||||
|
||||
void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
|
||||
int minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate,
|
||||
- int prob_ewma);
|
||||
+ int prob_avg);
|
||||
|
||||
#endif
|
||||
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
|
||||
@@ -98,8 +98,8 @@ minstrel_ht_stats_dump(struct minstrel_h
|
||||
p += sprintf(p, "%6u ", tx_time);
|
||||
|
||||
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
|
||||
- tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
|
||||
- eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
|
||||
+ tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_avg);
|
||||
+ eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000);
|
||||
|
||||
p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u"
|
||||
" %3u %3u %-3u "
|
||||
@@ -243,8 +243,8 @@ minstrel_ht_stats_csv_dump(struct minstr
|
||||
p += sprintf(p, "%u,", tx_time);
|
||||
|
||||
tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100));
|
||||
- tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma);
|
||||
- eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000);
|
||||
+ tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_avg);
|
||||
+ eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000);
|
||||
|
||||
p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u,"
|
||||
"%u,%llu,%llu,",
|
@ -28,7 +28,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
|
||||
--- a/net/mac80211/sta_info.c
|
||||
+++ b/net/mac80211/sta_info.c
|
||||
@@ -324,6 +324,7 @@ struct sta_info *sta_info_alloc(struct i
|
||||
@@ -339,6 +339,7 @@ struct sta_info *sta_info_alloc(struct i
|
||||
INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames);
|
||||
INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
|
||||
mutex_init(&sta->ampdu_mlme.mtx);
|
||||
|
@ -1,82 +0,0 @@
|
||||
From: Markus Theil <markus.theil@tu-ilmenau.de>
|
||||
Date: Wed, 18 Dec 2019 15:27:36 +0100
|
||||
Subject: [PATCH] mac80211: fix tx status for no ack cases
|
||||
|
||||
Before this patch, frames which where successfully transmitted without
|
||||
requiring acks where accounted as lost frames.
|
||||
|
||||
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
|
||||
Link: https://lore.kernel.org/r/20191218142736.15843-1-markus.theil@tu-ilmenau.de
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/status.c
|
||||
+++ b/net/mac80211/status.c
|
||||
@@ -881,6 +881,7 @@ static void __ieee80211_tx_status(struct
|
||||
int rates_idx;
|
||||
bool send_to_cooked;
|
||||
bool acked;
|
||||
+ bool noack_success;
|
||||
struct ieee80211_bar *bar;
|
||||
int shift = 0;
|
||||
int tid = IEEE80211_NUM_TIDS;
|
||||
@@ -898,6 +899,8 @@ static void __ieee80211_tx_status(struct
|
||||
clear_sta_flag(sta, WLAN_STA_SP);
|
||||
|
||||
acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
|
||||
+ noack_success = !!(info->flags &
|
||||
+ IEEE80211_TX_STAT_NOACK_TRANSMITTED);
|
||||
|
||||
/* mesh Peer Service Period support */
|
||||
if (ieee80211_vif_is_mesh(&sta->sdata->vif) &&
|
||||
@@ -962,12 +965,12 @@ static void __ieee80211_tx_status(struct
|
||||
ieee80211_handle_filtered_frame(local, sta, skb);
|
||||
return;
|
||||
} else {
|
||||
- if (!acked)
|
||||
+ if (!acked && !noack_success)
|
||||
sta->status_stats.retry_failed++;
|
||||
sta->status_stats.retry_count += retry_count;
|
||||
|
||||
if (ieee80211_is_data_present(fc)) {
|
||||
- if (!acked)
|
||||
+ if (!acked && !noack_success)
|
||||
sta->status_stats.msdu_failed[tid]++;
|
||||
|
||||
sta->status_stats.msdu_retries[tid] +=
|
||||
@@ -994,7 +997,7 @@ static void __ieee80211_tx_status(struct
|
||||
info->status.tx_time, 0);
|
||||
|
||||
if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
|
||||
- if (info->flags & IEEE80211_TX_STAT_ACK) {
|
||||
+ if (acked) {
|
||||
if (sta->status_stats.lost_packets)
|
||||
sta->status_stats.lost_packets = 0;
|
||||
|
||||
@@ -1002,6 +1005,8 @@ static void __ieee80211_tx_status(struct
|
||||
if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
|
||||
sta->status_stats.last_tdls_pkt_time =
|
||||
jiffies;
|
||||
+ } else if (noack_success) {
|
||||
+ /* nothing to do here, do not account as lost */
|
||||
} else {
|
||||
ieee80211_lost_packet(sta, info);
|
||||
}
|
||||
@@ -1128,7 +1133,7 @@ void ieee80211_tx_status_ext(struct ieee
|
||||
|
||||
sta = container_of(pubsta, struct sta_info, sta);
|
||||
|
||||
- if (!acked)
|
||||
+ if (!acked && !noack_success)
|
||||
sta->status_stats.retry_failed++;
|
||||
sta->status_stats.retry_count += retry_count;
|
||||
|
||||
@@ -1143,6 +1148,8 @@ void ieee80211_tx_status_ext(struct ieee
|
||||
sta->status_stats.last_tdls_pkt_time = jiffies;
|
||||
} else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
|
||||
return;
|
||||
+ } else if (noack_success) {
|
||||
+ /* nothing to do here, do not account as lost */
|
||||
} else {
|
||||
ieee80211_lost_packet(sta, info);
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
From: John Crispin <john@phrozen.org>
|
||||
Date: Tue, 29 Oct 2019 10:13:02 +0100
|
||||
Subject: [PATCH] mac80211: move store skb ack code to its own function
|
||||
|
||||
This patch moves the code handling SKBTX_WIFI_STATUS inside the TX path
|
||||
into an extra function. This allows us to reuse it inside the 802.11 encap
|
||||
offloading datapath.
|
||||
|
||||
Signed-off-by: John Crispin <john@phrozen.org>
|
||||
Link: https://lore.kernel.org/r/20191029091304.7330-2-john@phrozen.org
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -2439,6 +2439,33 @@ static int ieee80211_lookup_ra_sta(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int ieee80211_store_ack_skb(struct ieee80211_local *local,
|
||||
+ struct sk_buff *skb,
|
||||
+ u32 *info_flags)
|
||||
+{
|
||||
+ struct sk_buff *ack_skb = skb_clone_sk(skb);
|
||||
+ u16 info_id = 0;
|
||||
+
|
||||
+ if (ack_skb) {
|
||||
+ unsigned long flags;
|
||||
+ int id;
|
||||
+
|
||||
+ spin_lock_irqsave(&local->ack_status_lock, flags);
|
||||
+ id = idr_alloc(&local->ack_status_frames, ack_skb,
|
||||
+ 1, 0x10000, GFP_ATOMIC);
|
||||
+ spin_unlock_irqrestore(&local->ack_status_lock, flags);
|
||||
+
|
||||
+ if (id >= 0) {
|
||||
+ info_id = id;
|
||||
+ *info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
+ } else {
|
||||
+ kfree_skb(ack_skb);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return info_id;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* ieee80211_build_hdr - build 802.11 header in the given frame
|
||||
* @sdata: virtual interface to build the header for
|
||||
@@ -2732,26 +2759,8 @@ static struct sk_buff *ieee80211_build_h
|
||||
}
|
||||
|
||||
if (unlikely(!multicast && skb->sk &&
|
||||
- skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) {
|
||||
- struct sk_buff *ack_skb = skb_clone_sk(skb);
|
||||
-
|
||||
- if (ack_skb) {
|
||||
- unsigned long flags;
|
||||
- int id;
|
||||
-
|
||||
- spin_lock_irqsave(&local->ack_status_lock, flags);
|
||||
- id = idr_alloc(&local->ack_status_frames, ack_skb,
|
||||
- 1, 0x10000, GFP_ATOMIC);
|
||||
- spin_unlock_irqrestore(&local->ack_status_lock, flags);
|
||||
-
|
||||
- if (id >= 0) {
|
||||
- info_id = id;
|
||||
- info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
- } else {
|
||||
- kfree_skb(ack_skb);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS))
|
||||
+ info_id = ieee80211_store_ack_skb(local, skb, &info_flags);
|
||||
|
||||
/*
|
||||
* If the skb is shared we need to obtain our own copy.
|
@ -1,67 +0,0 @@
|
||||
From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com>
|
||||
Date: Wed, 23 Oct 2019 11:59:00 +0200
|
||||
Subject: [PATCH] mac80211: Shrink the size of ack_frame_id to make room for
|
||||
tx_time_est
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
To implement airtime queue limiting, we need to keep a running account of
|
||||
the estimated airtime of all skbs queued into the device. Do to this
|
||||
correctly, we need to store the airtime estimate into the skb so we can
|
||||
decrease the outstanding balance when the skb is freed. This means that the
|
||||
time estimate must be stored somewhere that will survive for the lifetime
|
||||
of the skb.
|
||||
|
||||
To get this, decrease the size of the ack_frame_id field to 6 bits, and
|
||||
lower the size of the ID space accordingly. This leaves 10 bits for use for
|
||||
tx_time_est, which is enough to store a maximum of 4096 us, if we shift the
|
||||
values so they become units of 4us.
|
||||
|
||||
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
||||
Link: https://lore.kernel.org/r/157182474063.150713.16132669599100802716.stgit@toke.dk
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -967,6 +967,7 @@ ieee80211_rate_get_vht_nss(const struct
|
||||
* @band: the band to transmit on (use for checking for races)
|
||||
* @hw_queue: HW queue to put the frame on, skb_get_queue_mapping() gives the AC
|
||||
* @ack_frame_id: internal frame ID for TX status, used internally
|
||||
+ * @tx_time_est: TX time estimate in units of 4us, used internally
|
||||
* @control: union part for control data
|
||||
* @control.rates: TX rates array to try
|
||||
* @control.rts_cts_rate_idx: rate for RTS or CTS
|
||||
@@ -1007,7 +1008,8 @@ struct ieee80211_tx_info {
|
||||
|
||||
u8 hw_queue;
|
||||
|
||||
- u16 ack_frame_id;
|
||||
+ u16 ack_frame_id:6;
|
||||
+ u16 tx_time_est:10;
|
||||
|
||||
union {
|
||||
struct {
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -3449,7 +3449,7 @@ int ieee80211_attach_ack_skb(struct ieee
|
||||
|
||||
spin_lock_irqsave(&local->ack_status_lock, spin_flags);
|
||||
id = idr_alloc(&local->ack_status_frames, ack_skb,
|
||||
- 1, 0x10000, GFP_ATOMIC);
|
||||
+ 1, 0x40, GFP_ATOMIC);
|
||||
spin_unlock_irqrestore(&local->ack_status_lock, spin_flags);
|
||||
|
||||
if (id < 0) {
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -2452,7 +2452,7 @@ static int ieee80211_store_ack_skb(struc
|
||||
|
||||
spin_lock_irqsave(&local->ack_status_lock, flags);
|
||||
id = idr_alloc(&local->ack_status_frames, ack_skb,
|
||||
- 1, 0x10000, GFP_ATOMIC);
|
||||
+ 1, 0x40, GFP_ATOMIC);
|
||||
spin_unlock_irqrestore(&local->ack_status_lock, flags);
|
||||
|
||||
if (id >= 0) {
|
@ -1,78 +0,0 @@
|
||||
From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com>
|
||||
Date: Tue, 12 Nov 2019 14:08:35 +0100
|
||||
Subject: [PATCH] mac80211: Add new sta_info getter by sta/vif addrs
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In ieee80211_tx_status() we don't have an sdata struct when looking up the
|
||||
destination sta. Instead, we just do a lookup by the vif addr that is the
|
||||
source of the packet being completed. Factor this out into a new sta_info
|
||||
getter helper, since we need to use it for accounting AQL as well.
|
||||
|
||||
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
||||
Link: https://lore.kernel.org/r/20191112130835.382062-1-toke@redhat.com
|
||||
[remove internal rcu_read_lock(), document instead]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/sta_info.c
|
||||
+++ b/net/mac80211/sta_info.c
|
||||
@@ -210,6 +210,20 @@ struct sta_info *sta_info_get_bss(struct
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+struct sta_info *sta_info_get_by_addrs(struct ieee80211_local *local,
|
||||
+ const u8 *sta_addr, const u8 *vif_addr)
|
||||
+{
|
||||
+ struct rhlist_head *tmp;
|
||||
+ struct sta_info *sta;
|
||||
+
|
||||
+ for_each_sta_info(local, sta_addr, sta, tmp) {
|
||||
+ if (ether_addr_equal(vif_addr, sta->sdata->vif.addr))
|
||||
+ return sta;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
|
||||
int idx)
|
||||
{
|
||||
--- a/net/mac80211/sta_info.h
|
||||
+++ b/net/mac80211/sta_info.h
|
||||
@@ -725,6 +725,10 @@ struct sta_info *sta_info_get(struct iee
|
||||
struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
|
||||
const u8 *addr);
|
||||
|
||||
+/* user must hold sta_mtx or be in RCU critical section */
|
||||
+struct sta_info *sta_info_get_by_addrs(struct ieee80211_local *local,
|
||||
+ const u8 *sta_addr, const u8 *vif_addr);
|
||||
+
|
||||
#define for_each_sta_info(local, _addr, _sta, _tmp) \
|
||||
rhl_for_each_entry_rcu(_sta, _tmp, \
|
||||
sta_info_hash_lookup(local, _addr), hash_node)
|
||||
--- a/net/mac80211/status.c
|
||||
+++ b/net/mac80211/status.c
|
||||
@@ -1086,19 +1086,13 @@ void ieee80211_tx_status(struct ieee8021
|
||||
.skb = skb,
|
||||
.info = IEEE80211_SKB_CB(skb),
|
||||
};
|
||||
- struct rhlist_head *tmp;
|
||||
struct sta_info *sta;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
- for_each_sta_info(local, hdr->addr1, sta, tmp) {
|
||||
- /* skip wrong virtual interface */
|
||||
- if (!ether_addr_equal(hdr->addr2, sta->sdata->vif.addr))
|
||||
- continue;
|
||||
-
|
||||
+ sta = sta_info_get_by_addrs(local, hdr->addr1, hdr->addr2);
|
||||
+ if (sta)
|
||||
status.sta = &sta->sta;
|
||||
- break;
|
||||
- }
|
||||
|
||||
__ieee80211_tx_status(hw, &status);
|
||||
rcu_read_unlock();
|
@ -1,690 +0,0 @@
|
||||
From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com>
|
||||
Date: Mon, 18 Nov 2019 22:06:08 -0800
|
||||
Subject: [PATCH] mac80211: Import airtime calculation code from mt76
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Felix recently added code to calculate airtime of packets to the mt76
|
||||
driver. Import this into mac80211 so we can use it for airtime queue limit
|
||||
calculations.
|
||||
|
||||
The airtime.c file is copied verbatim from the mt76 driver, and adjusted to
|
||||
be usable in mac80211. This involves:
|
||||
|
||||
- Switching to mac80211 data structures.
|
||||
- Adding support for 160 MHz channels and HE mode.
|
||||
- Moving the symbol and duration calculations around a bit to avoid
|
||||
rounding with the higher rates and longer symbol times used for HE rates.
|
||||
|
||||
The per-rate TX rate calculation is also split out to its own function so
|
||||
it can be used directly for the AQL calculations later.
|
||||
|
||||
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
||||
Link: https://lore.kernel.org/r/20191119060610.76681-3-kyan@google.com
|
||||
[fix HE_GROUP_IDX() to use 3 * bw, since there are 3 _gi values]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
create mode 100644 net/mac80211/airtime.c
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -6417,4 +6417,33 @@ void ieee80211_nan_func_match(struct iee
|
||||
struct cfg80211_nan_match_params *match,
|
||||
gfp_t gfp);
|
||||
|
||||
+/**
|
||||
+ * ieee80211_calc_rx_airtime - calculate estimated transmission airtime for RX.
|
||||
+ *
|
||||
+ * This function calculates the estimated airtime usage of a frame based on the
|
||||
+ * rate information in the RX status struct and the frame length.
|
||||
+ *
|
||||
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
|
||||
+ * @status: &struct ieee80211_rx_status containing the transmission rate
|
||||
+ * information.
|
||||
+ * @len: frame length in bytes
|
||||
+ */
|
||||
+u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_rx_status *status,
|
||||
+ int len);
|
||||
+
|
||||
+/**
|
||||
+ * ieee80211_calc_tx_airtime - calculate estimated transmission airtime for TX.
|
||||
+ *
|
||||
+ * This function calculates the estimated airtime usage of a frame based on the
|
||||
+ * rate information in the TX info struct and the frame length.
|
||||
+ *
|
||||
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
|
||||
+ * @info: &struct ieee80211_tx_info of the frame.
|
||||
+ * @len: frame length in bytes
|
||||
+ */
|
||||
+u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_tx_info *info,
|
||||
+ int len);
|
||||
+
|
||||
#endif /* MAC80211_H */
|
||||
--- a/net/mac80211/Makefile
|
||||
+++ b/net/mac80211/Makefile
|
||||
@@ -31,7 +31,8 @@ mac80211-y := \
|
||||
chan.o \
|
||||
trace.o mlme.o \
|
||||
tdls.o \
|
||||
- ocb.o
|
||||
+ ocb.o \
|
||||
+ airtime.o
|
||||
|
||||
mac80211-$(CPTCFG_MAC80211_LEDS) += led.o
|
||||
mac80211-$(CPTCFG_MAC80211_DEBUGFS) += \
|
||||
--- /dev/null
|
||||
+++ b/net/mac80211/airtime.c
|
||||
@@ -0,0 +1,597 @@
|
||||
+// SPDX-License-Identifier: ISC
|
||||
+/*
|
||||
+ * Copyright (C) 2019 Felix Fietkau <nbd@nbd.name>
|
||||
+ */
|
||||
+
|
||||
+#include <net/mac80211.h>
|
||||
+#include "ieee80211_i.h"
|
||||
+#include "sta_info.h"
|
||||
+
|
||||
+#define AVG_PKT_SIZE 1024
|
||||
+
|
||||
+/* Number of bits for an average sized packet */
|
||||
+#define MCS_NBITS (AVG_PKT_SIZE << 3)
|
||||
+
|
||||
+/* Number of kilo-symbols (symbols * 1024) for a packet with (bps) bits per
|
||||
+ * symbol. We use k-symbols to avoid rounding in the _TIME macros below.
|
||||
+ */
|
||||
+#define MCS_N_KSYMS(bps) DIV_ROUND_UP(MCS_NBITS << 10, (bps))
|
||||
+
|
||||
+/* Transmission time (in 1024 * usec) for a packet containing (ksyms) * 1024
|
||||
+ * symbols.
|
||||
+ */
|
||||
+#define MCS_SYMBOL_TIME(sgi, ksyms) \
|
||||
+ (sgi ? \
|
||||
+ ((ksyms) * 4 * 18) / 20 : /* 3.6 us per sym */ \
|
||||
+ ((ksyms) * 4) /* 4.0 us per sym */ \
|
||||
+ )
|
||||
+
|
||||
+/* Transmit duration for the raw data part of an average sized packet */
|
||||
+#define MCS_DURATION(streams, sgi, bps) \
|
||||
+ ((u32)MCS_SYMBOL_TIME(sgi, MCS_N_KSYMS((streams) * (bps))))
|
||||
+
|
||||
+#define MCS_DURATION_S(shift, streams, sgi, bps) \
|
||||
+ ((u16)((MCS_DURATION(streams, sgi, bps) >> shift)))
|
||||
+
|
||||
+/* These should match the values in enum nl80211_he_gi */
|
||||
+#define HE_GI_08 0
|
||||
+#define HE_GI_16 1
|
||||
+#define HE_GI_32 2
|
||||
+
|
||||
+/* Transmission time (1024 usec) for a packet containing (ksyms) * k-symbols */
|
||||
+#define HE_SYMBOL_TIME(gi, ksyms) \
|
||||
+ (gi == HE_GI_08 ? \
|
||||
+ ((ksyms) * 16 * 17) / 20 : /* 13.6 us per sym */ \
|
||||
+ (gi == HE_GI_16 ? \
|
||||
+ ((ksyms) * 16 * 18) / 20 : /* 14.4 us per sym */ \
|
||||
+ ((ksyms) * 16) /* 16.0 us per sym */ \
|
||||
+ ))
|
||||
+
|
||||
+/* Transmit duration for the raw data part of an average sized packet */
|
||||
+#define HE_DURATION(streams, gi, bps) \
|
||||
+ ((u32)HE_SYMBOL_TIME(gi, MCS_N_KSYMS((streams) * (bps))))
|
||||
+
|
||||
+#define HE_DURATION_S(shift, streams, gi, bps) \
|
||||
+ (HE_DURATION(streams, gi, bps) >> shift)
|
||||
+
|
||||
+#define BW_20 0
|
||||
+#define BW_40 1
|
||||
+#define BW_80 2
|
||||
+#define BW_160 3
|
||||
+
|
||||
+/*
|
||||
+ * Define group sort order: HT40 -> SGI -> #streams
|
||||
+ */
|
||||
+#define IEEE80211_MAX_STREAMS 4
|
||||
+#define IEEE80211_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */
|
||||
+#define IEEE80211_VHT_STREAM_GROUPS 8 /* BW(=4) * SGI(=2) */
|
||||
+
|
||||
+#define IEEE80211_HE_MAX_STREAMS 8
|
||||
+#define IEEE80211_HE_STREAM_GROUPS 12 /* BW(=4) * GI(=3) */
|
||||
+
|
||||
+#define IEEE80211_HT_GROUPS_NB (IEEE80211_MAX_STREAMS * \
|
||||
+ IEEE80211_HT_STREAM_GROUPS)
|
||||
+#define IEEE80211_VHT_GROUPS_NB (IEEE80211_MAX_STREAMS * \
|
||||
+ IEEE80211_VHT_STREAM_GROUPS)
|
||||
+#define IEEE80211_HE_GROUPS_NB (IEEE80211_HE_MAX_STREAMS * \
|
||||
+ IEEE80211_HE_STREAM_GROUPS)
|
||||
+#define IEEE80211_GROUPS_NB (IEEE80211_HT_GROUPS_NB + \
|
||||
+ IEEE80211_VHT_GROUPS_NB + \
|
||||
+ IEEE80211_HE_GROUPS_NB)
|
||||
+
|
||||
+#define IEEE80211_HT_GROUP_0 0
|
||||
+#define IEEE80211_VHT_GROUP_0 (IEEE80211_HT_GROUP_0 + IEEE80211_HT_GROUPS_NB)
|
||||
+#define IEEE80211_HE_GROUP_0 (IEEE80211_VHT_GROUP_0 + IEEE80211_VHT_GROUPS_NB)
|
||||
+
|
||||
+#define MCS_GROUP_RATES 12
|
||||
+
|
||||
+#define HT_GROUP_IDX(_streams, _sgi, _ht40) \
|
||||
+ IEEE80211_HT_GROUP_0 + \
|
||||
+ IEEE80211_MAX_STREAMS * 2 * _ht40 + \
|
||||
+ IEEE80211_MAX_STREAMS * _sgi + \
|
||||
+ _streams - 1
|
||||
+
|
||||
+#define _MAX(a, b) (((a)>(b))?(a):(b))
|
||||
+
|
||||
+#define GROUP_SHIFT(duration) \
|
||||
+ _MAX(0, 16 - __builtin_clz(duration))
|
||||
+
|
||||
+/* MCS rate information for an MCS group */
|
||||
+#define __MCS_GROUP(_streams, _sgi, _ht40, _s) \
|
||||
+ [HT_GROUP_IDX(_streams, _sgi, _ht40)] = { \
|
||||
+ .shift = _s, \
|
||||
+ .duration = { \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 54 : 26), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 108 : 52), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 162 : 78), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 216 : 104), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 324 : 156), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 432 : 208), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 486 : 234), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, _ht40 ? 540 : 260) \
|
||||
+ } \
|
||||
+}
|
||||
+
|
||||
+#define MCS_GROUP_SHIFT(_streams, _sgi, _ht40) \
|
||||
+ GROUP_SHIFT(MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26))
|
||||
+
|
||||
+#define MCS_GROUP(_streams, _sgi, _ht40) \
|
||||
+ __MCS_GROUP(_streams, _sgi, _ht40, \
|
||||
+ MCS_GROUP_SHIFT(_streams, _sgi, _ht40))
|
||||
+
|
||||
+#define VHT_GROUP_IDX(_streams, _sgi, _bw) \
|
||||
+ (IEEE80211_VHT_GROUP_0 + \
|
||||
+ IEEE80211_MAX_STREAMS * 2 * (_bw) + \
|
||||
+ IEEE80211_MAX_STREAMS * (_sgi) + \
|
||||
+ (_streams) - 1)
|
||||
+
|
||||
+#define BW2VBPS(_bw, r4, r3, r2, r1) \
|
||||
+ (_bw == BW_160 ? r4 : _bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1)
|
||||
+
|
||||
+#define __VHT_GROUP(_streams, _sgi, _bw, _s) \
|
||||
+ [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \
|
||||
+ .shift = _s, \
|
||||
+ .duration = { \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, \
|
||||
+ BW2VBPS(_bw, 234, 117, 54, 26)), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, \
|
||||
+ BW2VBPS(_bw, 468, 234, 108, 52)), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, \
|
||||
+ BW2VBPS(_bw, 702, 351, 162, 78)), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, \
|
||||
+ BW2VBPS(_bw, 936, 468, 216, 104)), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, \
|
||||
+ BW2VBPS(_bw, 1404, 702, 324, 156)), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, \
|
||||
+ BW2VBPS(_bw, 1872, 936, 432, 208)), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, \
|
||||
+ BW2VBPS(_bw, 2106, 1053, 486, 234)), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, \
|
||||
+ BW2VBPS(_bw, 2340, 1170, 540, 260)), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, \
|
||||
+ BW2VBPS(_bw, 2808, 1404, 648, 312)), \
|
||||
+ MCS_DURATION_S(_s, _streams, _sgi, \
|
||||
+ BW2VBPS(_bw, 3120, 1560, 720, 346)) \
|
||||
+ } \
|
||||
+}
|
||||
+
|
||||
+#define VHT_GROUP_SHIFT(_streams, _sgi, _bw) \
|
||||
+ GROUP_SHIFT(MCS_DURATION(_streams, _sgi, \
|
||||
+ BW2VBPS(_bw, 243, 117, 54, 26)))
|
||||
+
|
||||
+#define VHT_GROUP(_streams, _sgi, _bw) \
|
||||
+ __VHT_GROUP(_streams, _sgi, _bw, \
|
||||
+ VHT_GROUP_SHIFT(_streams, _sgi, _bw))
|
||||
+
|
||||
+
|
||||
+#define HE_GROUP_IDX(_streams, _gi, _bw) \
|
||||
+ (IEEE80211_HE_GROUP_0 + \
|
||||
+ IEEE80211_HE_MAX_STREAMS * 3 * (_bw) + \
|
||||
+ IEEE80211_HE_MAX_STREAMS * (_gi) + \
|
||||
+ (_streams) - 1)
|
||||
+
|
||||
+#define __HE_GROUP(_streams, _gi, _bw, _s) \
|
||||
+ [HE_GROUP_IDX(_streams, _gi, _bw)] = { \
|
||||
+ .shift = _s, \
|
||||
+ .duration = { \
|
||||
+ HE_DURATION_S(_s, _streams, _gi, \
|
||||
+ BW2VBPS(_bw, 979, 489, 230, 115)), \
|
||||
+ HE_DURATION_S(_s, _streams, _gi, \
|
||||
+ BW2VBPS(_bw, 1958, 979, 475, 230)), \
|
||||
+ HE_DURATION_S(_s, _streams, _gi, \
|
||||
+ BW2VBPS(_bw, 2937, 1468, 705, 345)), \
|
||||
+ HE_DURATION_S(_s, _streams, _gi, \
|
||||
+ BW2VBPS(_bw, 3916, 1958, 936, 475)), \
|
||||
+ HE_DURATION_S(_s, _streams, _gi, \
|
||||
+ BW2VBPS(_bw, 5875, 2937, 1411, 705)), \
|
||||
+ HE_DURATION_S(_s, _streams, _gi, \
|
||||
+ BW2VBPS(_bw, 7833, 3916, 1872, 936)), \
|
||||
+ HE_DURATION_S(_s, _streams, _gi, \
|
||||
+ BW2VBPS(_bw, 8827, 4406, 2102, 1051)), \
|
||||
+ HE_DURATION_S(_s, _streams, _gi, \
|
||||
+ BW2VBPS(_bw, 9806, 4896, 2347, 1166)), \
|
||||
+ HE_DURATION_S(_s, _streams, _gi, \
|
||||
+ BW2VBPS(_bw, 11764, 5875, 2808, 1411)), \
|
||||
+ HE_DURATION_S(_s, _streams, _gi, \
|
||||
+ BW2VBPS(_bw, 13060, 6523, 3124, 1555)), \
|
||||
+ HE_DURATION_S(_s, _streams, _gi, \
|
||||
+ BW2VBPS(_bw, 14702, 7344, 3513, 1756)), \
|
||||
+ HE_DURATION_S(_s, _streams, _gi, \
|
||||
+ BW2VBPS(_bw, 16329, 8164, 3902, 1944)) \
|
||||
+ } \
|
||||
+}
|
||||
+
|
||||
+#define HE_GROUP_SHIFT(_streams, _gi, _bw) \
|
||||
+ GROUP_SHIFT(HE_DURATION(_streams, _gi, \
|
||||
+ BW2VBPS(_bw, 979, 489, 230, 115)))
|
||||
+
|
||||
+#define HE_GROUP(_streams, _gi, _bw) \
|
||||
+ __HE_GROUP(_streams, _gi, _bw, \
|
||||
+ HE_GROUP_SHIFT(_streams, _gi, _bw))
|
||||
+struct mcs_group {
|
||||
+ u8 shift;
|
||||
+ u16 duration[MCS_GROUP_RATES];
|
||||
+};
|
||||
+
|
||||
+static const struct mcs_group airtime_mcs_groups[] = {
|
||||
+ MCS_GROUP(1, 0, BW_20),
|
||||
+ MCS_GROUP(2, 0, BW_20),
|
||||
+ MCS_GROUP(3, 0, BW_20),
|
||||
+ MCS_GROUP(4, 0, BW_20),
|
||||
+
|
||||
+ MCS_GROUP(1, 1, BW_20),
|
||||
+ MCS_GROUP(2, 1, BW_20),
|
||||
+ MCS_GROUP(3, 1, BW_20),
|
||||
+ MCS_GROUP(4, 1, BW_20),
|
||||
+
|
||||
+ MCS_GROUP(1, 0, BW_40),
|
||||
+ MCS_GROUP(2, 0, BW_40),
|
||||
+ MCS_GROUP(3, 0, BW_40),
|
||||
+ MCS_GROUP(4, 0, BW_40),
|
||||
+
|
||||
+ MCS_GROUP(1, 1, BW_40),
|
||||
+ MCS_GROUP(2, 1, BW_40),
|
||||
+ MCS_GROUP(3, 1, BW_40),
|
||||
+ MCS_GROUP(4, 1, BW_40),
|
||||
+
|
||||
+ VHT_GROUP(1, 0, BW_20),
|
||||
+ VHT_GROUP(2, 0, BW_20),
|
||||
+ VHT_GROUP(3, 0, BW_20),
|
||||
+ VHT_GROUP(4, 0, BW_20),
|
||||
+
|
||||
+ VHT_GROUP(1, 1, BW_20),
|
||||
+ VHT_GROUP(2, 1, BW_20),
|
||||
+ VHT_GROUP(3, 1, BW_20),
|
||||
+ VHT_GROUP(4, 1, BW_20),
|
||||
+
|
||||
+ VHT_GROUP(1, 0, BW_40),
|
||||
+ VHT_GROUP(2, 0, BW_40),
|
||||
+ VHT_GROUP(3, 0, BW_40),
|
||||
+ VHT_GROUP(4, 0, BW_40),
|
||||
+
|
||||
+ VHT_GROUP(1, 1, BW_40),
|
||||
+ VHT_GROUP(2, 1, BW_40),
|
||||
+ VHT_GROUP(3, 1, BW_40),
|
||||
+ VHT_GROUP(4, 1, BW_40),
|
||||
+
|
||||
+ VHT_GROUP(1, 0, BW_80),
|
||||
+ VHT_GROUP(2, 0, BW_80),
|
||||
+ VHT_GROUP(3, 0, BW_80),
|
||||
+ VHT_GROUP(4, 0, BW_80),
|
||||
+
|
||||
+ VHT_GROUP(1, 1, BW_80),
|
||||
+ VHT_GROUP(2, 1, BW_80),
|
||||
+ VHT_GROUP(3, 1, BW_80),
|
||||
+ VHT_GROUP(4, 1, BW_80),
|
||||
+
|
||||
+ VHT_GROUP(1, 0, BW_160),
|
||||
+ VHT_GROUP(2, 0, BW_160),
|
||||
+ VHT_GROUP(3, 0, BW_160),
|
||||
+ VHT_GROUP(4, 0, BW_160),
|
||||
+
|
||||
+ VHT_GROUP(1, 1, BW_160),
|
||||
+ VHT_GROUP(2, 1, BW_160),
|
||||
+ VHT_GROUP(3, 1, BW_160),
|
||||
+ VHT_GROUP(4, 1, BW_160),
|
||||
+
|
||||
+ HE_GROUP(1, HE_GI_08, BW_20),
|
||||
+ HE_GROUP(2, HE_GI_08, BW_20),
|
||||
+ HE_GROUP(3, HE_GI_08, BW_20),
|
||||
+ HE_GROUP(4, HE_GI_08, BW_20),
|
||||
+ HE_GROUP(5, HE_GI_08, BW_20),
|
||||
+ HE_GROUP(6, HE_GI_08, BW_20),
|
||||
+ HE_GROUP(7, HE_GI_08, BW_20),
|
||||
+ HE_GROUP(8, HE_GI_08, BW_20),
|
||||
+
|
||||
+ HE_GROUP(1, HE_GI_16, BW_20),
|
||||
+ HE_GROUP(2, HE_GI_16, BW_20),
|
||||
+ HE_GROUP(3, HE_GI_16, BW_20),
|
||||
+ HE_GROUP(4, HE_GI_16, BW_20),
|
||||
+ HE_GROUP(5, HE_GI_16, BW_20),
|
||||
+ HE_GROUP(6, HE_GI_16, BW_20),
|
||||
+ HE_GROUP(7, HE_GI_16, BW_20),
|
||||
+ HE_GROUP(8, HE_GI_16, BW_20),
|
||||
+
|
||||
+ HE_GROUP(1, HE_GI_32, BW_20),
|
||||
+ HE_GROUP(2, HE_GI_32, BW_20),
|
||||
+ HE_GROUP(3, HE_GI_32, BW_20),
|
||||
+ HE_GROUP(4, HE_GI_32, BW_20),
|
||||
+ HE_GROUP(5, HE_GI_32, BW_20),
|
||||
+ HE_GROUP(6, HE_GI_32, BW_20),
|
||||
+ HE_GROUP(7, HE_GI_32, BW_20),
|
||||
+ HE_GROUP(8, HE_GI_32, BW_20),
|
||||
+
|
||||
+ HE_GROUP(1, HE_GI_08, BW_40),
|
||||
+ HE_GROUP(2, HE_GI_08, BW_40),
|
||||
+ HE_GROUP(3, HE_GI_08, BW_40),
|
||||
+ HE_GROUP(4, HE_GI_08, BW_40),
|
||||
+ HE_GROUP(5, HE_GI_08, BW_40),
|
||||
+ HE_GROUP(6, HE_GI_08, BW_40),
|
||||
+ HE_GROUP(7, HE_GI_08, BW_40),
|
||||
+ HE_GROUP(8, HE_GI_08, BW_40),
|
||||
+
|
||||
+ HE_GROUP(1, HE_GI_16, BW_40),
|
||||
+ HE_GROUP(2, HE_GI_16, BW_40),
|
||||
+ HE_GROUP(3, HE_GI_16, BW_40),
|
||||
+ HE_GROUP(4, HE_GI_16, BW_40),
|
||||
+ HE_GROUP(5, HE_GI_16, BW_40),
|
||||
+ HE_GROUP(6, HE_GI_16, BW_40),
|
||||
+ HE_GROUP(7, HE_GI_16, BW_40),
|
||||
+ HE_GROUP(8, HE_GI_16, BW_40),
|
||||
+
|
||||
+ HE_GROUP(1, HE_GI_32, BW_40),
|
||||
+ HE_GROUP(2, HE_GI_32, BW_40),
|
||||
+ HE_GROUP(3, HE_GI_32, BW_40),
|
||||
+ HE_GROUP(4, HE_GI_32, BW_40),
|
||||
+ HE_GROUP(5, HE_GI_32, BW_40),
|
||||
+ HE_GROUP(6, HE_GI_32, BW_40),
|
||||
+ HE_GROUP(7, HE_GI_32, BW_40),
|
||||
+ HE_GROUP(8, HE_GI_32, BW_40),
|
||||
+
|
||||
+ HE_GROUP(1, HE_GI_08, BW_80),
|
||||
+ HE_GROUP(2, HE_GI_08, BW_80),
|
||||
+ HE_GROUP(3, HE_GI_08, BW_80),
|
||||
+ HE_GROUP(4, HE_GI_08, BW_80),
|
||||
+ HE_GROUP(5, HE_GI_08, BW_80),
|
||||
+ HE_GROUP(6, HE_GI_08, BW_80),
|
||||
+ HE_GROUP(7, HE_GI_08, BW_80),
|
||||
+ HE_GROUP(8, HE_GI_08, BW_80),
|
||||
+
|
||||
+ HE_GROUP(1, HE_GI_16, BW_80),
|
||||
+ HE_GROUP(2, HE_GI_16, BW_80),
|
||||
+ HE_GROUP(3, HE_GI_16, BW_80),
|
||||
+ HE_GROUP(4, HE_GI_16, BW_80),
|
||||
+ HE_GROUP(5, HE_GI_16, BW_80),
|
||||
+ HE_GROUP(6, HE_GI_16, BW_80),
|
||||
+ HE_GROUP(7, HE_GI_16, BW_80),
|
||||
+ HE_GROUP(8, HE_GI_16, BW_80),
|
||||
+
|
||||
+ HE_GROUP(1, HE_GI_32, BW_80),
|
||||
+ HE_GROUP(2, HE_GI_32, BW_80),
|
||||
+ HE_GROUP(3, HE_GI_32, BW_80),
|
||||
+ HE_GROUP(4, HE_GI_32, BW_80),
|
||||
+ HE_GROUP(5, HE_GI_32, BW_80),
|
||||
+ HE_GROUP(6, HE_GI_32, BW_80),
|
||||
+ HE_GROUP(7, HE_GI_32, BW_80),
|
||||
+ HE_GROUP(8, HE_GI_32, BW_80),
|
||||
+
|
||||
+ HE_GROUP(1, HE_GI_08, BW_160),
|
||||
+ HE_GROUP(2, HE_GI_08, BW_160),
|
||||
+ HE_GROUP(3, HE_GI_08, BW_160),
|
||||
+ HE_GROUP(4, HE_GI_08, BW_160),
|
||||
+ HE_GROUP(5, HE_GI_08, BW_160),
|
||||
+ HE_GROUP(6, HE_GI_08, BW_160),
|
||||
+ HE_GROUP(7, HE_GI_08, BW_160),
|
||||
+ HE_GROUP(8, HE_GI_08, BW_160),
|
||||
+
|
||||
+ HE_GROUP(1, HE_GI_16, BW_160),
|
||||
+ HE_GROUP(2, HE_GI_16, BW_160),
|
||||
+ HE_GROUP(3, HE_GI_16, BW_160),
|
||||
+ HE_GROUP(4, HE_GI_16, BW_160),
|
||||
+ HE_GROUP(5, HE_GI_16, BW_160),
|
||||
+ HE_GROUP(6, HE_GI_16, BW_160),
|
||||
+ HE_GROUP(7, HE_GI_16, BW_160),
|
||||
+ HE_GROUP(8, HE_GI_16, BW_160),
|
||||
+
|
||||
+ HE_GROUP(1, HE_GI_32, BW_160),
|
||||
+ HE_GROUP(2, HE_GI_32, BW_160),
|
||||
+ HE_GROUP(3, HE_GI_32, BW_160),
|
||||
+ HE_GROUP(4, HE_GI_32, BW_160),
|
||||
+ HE_GROUP(5, HE_GI_32, BW_160),
|
||||
+ HE_GROUP(6, HE_GI_32, BW_160),
|
||||
+ HE_GROUP(7, HE_GI_32, BW_160),
|
||||
+ HE_GROUP(8, HE_GI_32, BW_160),
|
||||
+};
|
||||
+
|
||||
+static u32
|
||||
+ieee80211_calc_legacy_rate_duration(u16 bitrate, bool short_pre,
|
||||
+ bool cck, int len)
|
||||
+{
|
||||
+ u32 duration;
|
||||
+
|
||||
+ if (cck) {
|
||||
+ duration = 144 + 48; /* preamble + PLCP */
|
||||
+ if (short_pre)
|
||||
+ duration >>= 1;
|
||||
+
|
||||
+ duration += 10; /* SIFS */
|
||||
+ } else {
|
||||
+ duration = 20 + 16; /* premable + SIFS */
|
||||
+ }
|
||||
+
|
||||
+ len <<= 3;
|
||||
+ duration += (len * 10) / bitrate;
|
||||
+
|
||||
+ return duration;
|
||||
+}
|
||||
+
|
||||
+u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_rx_status *status,
|
||||
+ int len)
|
||||
+{
|
||||
+ struct ieee80211_supported_band *sband;
|
||||
+ const struct ieee80211_rate *rate;
|
||||
+ bool sgi = status->enc_flags & RX_ENC_FLAG_SHORT_GI;
|
||||
+ bool sp = status->enc_flags & RX_ENC_FLAG_SHORTPRE;
|
||||
+ int bw, streams;
|
||||
+ int group, idx;
|
||||
+ u32 duration;
|
||||
+ bool cck;
|
||||
+
|
||||
+ switch (status->bw) {
|
||||
+ case RATE_INFO_BW_20:
|
||||
+ bw = BW_20;
|
||||
+ break;
|
||||
+ case RATE_INFO_BW_40:
|
||||
+ bw = BW_40;
|
||||
+ break;
|
||||
+ case RATE_INFO_BW_80:
|
||||
+ bw = BW_80;
|
||||
+ break;
|
||||
+ case RATE_INFO_BW_160:
|
||||
+ bw = BW_160;
|
||||
+ break;
|
||||
+ default:
|
||||
+ WARN_ON_ONCE(1);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ switch (status->encoding) {
|
||||
+ case RX_ENC_LEGACY:
|
||||
+ if (WARN_ON_ONCE(status->band > NL80211_BAND_5GHZ))
|
||||
+ return 0;
|
||||
+
|
||||
+ sband = hw->wiphy->bands[status->band];
|
||||
+ if (!sband || status->rate_idx > sband->n_bitrates)
|
||||
+ return 0;
|
||||
+
|
||||
+ rate = &sband->bitrates[status->rate_idx];
|
||||
+ cck = rate->flags & IEEE80211_RATE_MANDATORY_B;
|
||||
+
|
||||
+ return ieee80211_calc_legacy_rate_duration(rate->bitrate, sp,
|
||||
+ cck, len);
|
||||
+
|
||||
+ case RX_ENC_VHT:
|
||||
+ streams = status->nss;
|
||||
+ idx = status->rate_idx;
|
||||
+ group = VHT_GROUP_IDX(streams, sgi, bw);
|
||||
+ break;
|
||||
+ case RX_ENC_HT:
|
||||
+ streams = ((status->rate_idx >> 3) & 3) + 1;
|
||||
+ idx = status->rate_idx & 7;
|
||||
+ group = HT_GROUP_IDX(streams, sgi, bw);
|
||||
+ break;
|
||||
+ case RX_ENC_HE:
|
||||
+ streams = status->nss;
|
||||
+ idx = status->rate_idx;
|
||||
+ group = HE_GROUP_IDX(streams, status->he_gi, bw);
|
||||
+ break;
|
||||
+ default:
|
||||
+ WARN_ON_ONCE(1);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (WARN_ON_ONCE((status->encoding != RX_ENC_HE && streams > 4) ||
|
||||
+ (status->encoding == RX_ENC_HE && streams > 8)))
|
||||
+ return 0;
|
||||
+
|
||||
+ duration = airtime_mcs_groups[group].duration[idx];
|
||||
+ duration <<= airtime_mcs_groups[group].shift;
|
||||
+ duration *= len;
|
||||
+ duration /= AVG_PKT_SIZE;
|
||||
+ duration /= 1024;
|
||||
+
|
||||
+ duration += 36 + (streams << 2);
|
||||
+
|
||||
+ return duration;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ieee80211_calc_rx_airtime);
|
||||
+
|
||||
+static u32 ieee80211_calc_tx_airtime_rate(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_tx_rate *rate,
|
||||
+ u8 band, int len)
|
||||
+{
|
||||
+ struct ieee80211_rx_status stat = {
|
||||
+ .band = band,
|
||||
+ };
|
||||
+
|
||||
+ if (rate->idx < 0 || !rate->count)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
|
||||
+ stat.bw = RATE_INFO_BW_80;
|
||||
+ else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
+ stat.bw = RATE_INFO_BW_40;
|
||||
+ else
|
||||
+ stat.bw = RATE_INFO_BW_20;
|
||||
+
|
||||
+ stat.enc_flags = 0;
|
||||
+ if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
|
||||
+ stat.enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
+ if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
+ stat.enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
+
|
||||
+ stat.rate_idx = rate->idx;
|
||||
+ if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
|
||||
+ stat.encoding = RX_ENC_VHT;
|
||||
+ stat.rate_idx = ieee80211_rate_get_vht_mcs(rate);
|
||||
+ stat.nss = ieee80211_rate_get_vht_nss(rate);
|
||||
+ } else if (rate->flags & IEEE80211_TX_RC_MCS) {
|
||||
+ stat.encoding = RX_ENC_HT;
|
||||
+ } else {
|
||||
+ stat.encoding = RX_ENC_LEGACY;
|
||||
+ }
|
||||
+
|
||||
+ return ieee80211_calc_rx_airtime(hw, &stat, len);
|
||||
+}
|
||||
+
|
||||
+u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_tx_info *info,
|
||||
+ int len)
|
||||
+{
|
||||
+ u32 duration = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(info->status.rates); i++) {
|
||||
+ struct ieee80211_tx_rate *rate = &info->status.rates[i];
|
||||
+ u32 cur_duration;
|
||||
+
|
||||
+ cur_duration = ieee80211_calc_tx_airtime_rate(hw, rate,
|
||||
+ info->band, len);
|
||||
+ if (!cur_duration)
|
||||
+ break;
|
||||
+
|
||||
+ duration += cur_duration * rate->count;
|
||||
+ }
|
||||
+
|
||||
+ return duration;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ieee80211_calc_tx_airtime);
|
||||
+
|
||||
+u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_vif *vif,
|
||||
+ struct ieee80211_sta *pubsta,
|
||||
+ int len)
|
||||
+{
|
||||
+ struct ieee80211_supported_band *sband;
|
||||
+ struct ieee80211_chanctx_conf *conf;
|
||||
+ int rateidx, shift = 0;
|
||||
+ bool cck, short_pream;
|
||||
+ u32 basic_rates;
|
||||
+ u8 band = 0;
|
||||
+ u16 rate;
|
||||
+
|
||||
+ len += 38; /* Ethernet header length */
|
||||
+
|
||||
+ conf = rcu_dereference(vif->chanctx_conf);
|
||||
+ if (conf) {
|
||||
+ band = conf->def.chan->band;
|
||||
+ shift = ieee80211_chandef_get_shift(&conf->def);
|
||||
+ }
|
||||
+
|
||||
+ if (pubsta) {
|
||||
+ struct sta_info *sta = container_of(pubsta, struct sta_info,
|
||||
+ sta);
|
||||
+
|
||||
+ return ieee80211_calc_tx_airtime_rate(hw,
|
||||
+ &sta->tx_stats.last_rate,
|
||||
+ band, len);
|
||||
+ }
|
||||
+
|
||||
+ if (!conf)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* No station to get latest rate from, so calculate the worst-case
|
||||
+ * duration using the lowest configured basic rate.
|
||||
+ */
|
||||
+ sband = hw->wiphy->bands[band];
|
||||
+
|
||||
+ basic_rates = vif->bss_conf.basic_rates;
|
||||
+ short_pream = vif->bss_conf.use_short_preamble;
|
||||
+
|
||||
+ rateidx = basic_rates ? ffs(basic_rates) - 1 : 0;
|
||||
+ rate = sband->bitrates[rateidx].bitrate << shift;
|
||||
+ cck = sband->bitrates[rateidx].flags & IEEE80211_RATE_MANDATORY_B;
|
||||
+
|
||||
+ return ieee80211_calc_legacy_rate_duration(rate, short_pream, cck, len);
|
||||
+}
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -2253,6 +2253,10 @@ const char *ieee80211_get_reason_code_st
|
||||
|
||||
extern const struct ethtool_ops ieee80211_ethtool_ops;
|
||||
|
||||
+u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_vif *vif,
|
||||
+ struct ieee80211_sta *pubsta,
|
||||
+ int len);
|
||||
#ifdef CPTCFG_MAC80211_NOINLINE
|
||||
#define debug_noinline noinline
|
||||
#else
|
@ -1,446 +0,0 @@
|
||||
From: Kan Yan <kyan@google.com>
|
||||
Date: Mon, 18 Nov 2019 22:06:09 -0800
|
||||
Subject: [PATCH] mac80211: Implement Airtime-based Queue Limit (AQL)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In order for the Fq_CoDel algorithm integrated in mac80211 layer to operate
|
||||
effectively to control excessive queueing latency, the CoDel algorithm
|
||||
requires an accurate measure of how long packets stays in the queue, AKA
|
||||
sojourn time. The sojourn time measured at the mac80211 layer doesn't
|
||||
include queueing latency in the lower layer (firmware/hardware) and CoDel
|
||||
expects lower layer to have a short queue. However, most 802.11ac chipsets
|
||||
offload tasks such TX aggregation to firmware or hardware, thus have a deep
|
||||
lower layer queue.
|
||||
|
||||
Without a mechanism to control the lower layer queue size, packets only
|
||||
stay in mac80211 layer transiently before being sent to firmware queue.
|
||||
As a result, the sojourn time measured by CoDel in the mac80211 layer is
|
||||
almost always lower than the CoDel latency target, hence CoDel does little
|
||||
to control the latency, even when the lower layer queue causes excessive
|
||||
latency.
|
||||
|
||||
The Byte Queue Limits (BQL) mechanism is commonly used to address the
|
||||
similar issue with wired network interface. However, this method cannot be
|
||||
applied directly to the wireless network interface. "Bytes" is not a
|
||||
suitable measure of queue depth in the wireless network, as the data rate
|
||||
can vary dramatically from station to station in the same network, from a
|
||||
few Mbps to over Gbps.
|
||||
|
||||
This patch implements an Airtime-based Queue Limit (AQL) to make CoDel work
|
||||
effectively with wireless drivers that utilized firmware/hardware
|
||||
offloading. AQL allows each txq to release just enough packets to the lower
|
||||
layer to form 1-2 large aggregations to keep hardware fully utilized and
|
||||
retains the rest of the frames in mac80211 layer to be controlled by the
|
||||
CoDel algorithm.
|
||||
|
||||
Signed-off-by: Kan Yan <kyan@google.com>
|
||||
[ Toke: Keep API to set pending airtime internal, fix nits in commit msg ]
|
||||
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
||||
Link: https://lore.kernel.org/r/20191119060610.76681-4-kyan@google.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -2603,6 +2603,13 @@ enum wiphy_params_flags {
|
||||
|
||||
#define IEEE80211_DEFAULT_AIRTIME_WEIGHT 256
|
||||
|
||||
+/* The per TXQ device queue limit in airtime */
|
||||
+#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L 5000
|
||||
+#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H 12000
|
||||
+
|
||||
+/* The per interface airtime threshold to switch to lower queue limit */
|
||||
+#define IEEE80211_AQL_THRESHOLD 24000
|
||||
+
|
||||
/**
|
||||
* struct cfg80211_pmksa - PMK Security Association
|
||||
*
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -5559,6 +5559,18 @@ void ieee80211_sta_register_airtime(stru
|
||||
u32 tx_airtime, u32 rx_airtime);
|
||||
|
||||
/**
|
||||
+ * ieee80211_txq_airtime_check - check if a txq can send frame to device
|
||||
+ *
|
||||
+ * @hw: pointer obtained from ieee80211_alloc_hw()
|
||||
+ * @txq: pointer obtained from station or virtual interface
|
||||
+ *
|
||||
+ * Return true if the AQL's airtime limit has not been reached and the txq can
|
||||
+ * continue to send more packets to the device. Otherwise return false.
|
||||
+ */
|
||||
+bool
|
||||
+ieee80211_txq_airtime_check(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
|
||||
+
|
||||
+/**
|
||||
* ieee80211_iter_keys - iterate keys programmed into the device
|
||||
* @hw: pointer obtained from ieee80211_alloc_hw()
|
||||
* @vif: virtual interface to iterate, may be %NULL for all
|
||||
--- a/net/mac80211/debugfs.c
|
||||
+++ b/net/mac80211/debugfs.c
|
||||
@@ -148,6 +148,87 @@ static const struct file_operations aqm_
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
+static ssize_t aql_txq_limit_read(struct file *file,
|
||||
+ char __user *user_buf,
|
||||
+ size_t count,
|
||||
+ loff_t *ppos)
|
||||
+{
|
||||
+ struct ieee80211_local *local = file->private_data;
|
||||
+ char buf[400];
|
||||
+ int len = 0;
|
||||
+
|
||||
+ len = scnprintf(buf, sizeof(buf),
|
||||
+ "AC AQL limit low AQL limit high\n"
|
||||
+ "VO %u %u\n"
|
||||
+ "VI %u %u\n"
|
||||
+ "BE %u %u\n"
|
||||
+ "BK %u %u\n",
|
||||
+ local->aql_txq_limit_low[IEEE80211_AC_VO],
|
||||
+ local->aql_txq_limit_high[IEEE80211_AC_VO],
|
||||
+ local->aql_txq_limit_low[IEEE80211_AC_VI],
|
||||
+ local->aql_txq_limit_high[IEEE80211_AC_VI],
|
||||
+ local->aql_txq_limit_low[IEEE80211_AC_BE],
|
||||
+ local->aql_txq_limit_high[IEEE80211_AC_BE],
|
||||
+ local->aql_txq_limit_low[IEEE80211_AC_BK],
|
||||
+ local->aql_txq_limit_high[IEEE80211_AC_BK]);
|
||||
+ return simple_read_from_buffer(user_buf, count, ppos,
|
||||
+ buf, len);
|
||||
+}
|
||||
+
|
||||
+static ssize_t aql_txq_limit_write(struct file *file,
|
||||
+ const char __user *user_buf,
|
||||
+ size_t count,
|
||||
+ loff_t *ppos)
|
||||
+{
|
||||
+ struct ieee80211_local *local = file->private_data;
|
||||
+ char buf[100];
|
||||
+ size_t len;
|
||||
+ u32 ac, q_limit_low, q_limit_high, q_limit_low_old, q_limit_high_old;
|
||||
+ struct sta_info *sta;
|
||||
+
|
||||
+ if (count > sizeof(buf))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (copy_from_user(buf, user_buf, count))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ buf[sizeof(buf) - 1] = 0;
|
||||
+ len = strlen(buf);
|
||||
+ if (len > 0 && buf[len - 1] == '\n')
|
||||
+ buf[len - 1] = 0;
|
||||
+
|
||||
+ if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (ac >= IEEE80211_NUM_ACS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ q_limit_low_old = local->aql_txq_limit_low[ac];
|
||||
+ q_limit_high_old = local->aql_txq_limit_high[ac];
|
||||
+
|
||||
+ local->aql_txq_limit_low[ac] = q_limit_low;
|
||||
+ local->aql_txq_limit_high[ac] = q_limit_high;
|
||||
+
|
||||
+ mutex_lock(&local->sta_mtx);
|
||||
+ list_for_each_entry(sta, &local->sta_list, list) {
|
||||
+ /* If a sta has customized queue limits, keep it */
|
||||
+ if (sta->airtime[ac].aql_limit_low == q_limit_low_old &&
|
||||
+ sta->airtime[ac].aql_limit_high == q_limit_high_old) {
|
||||
+ sta->airtime[ac].aql_limit_low = q_limit_low;
|
||||
+ sta->airtime[ac].aql_limit_high = q_limit_high;
|
||||
+ }
|
||||
+ }
|
||||
+ mutex_unlock(&local->sta_mtx);
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations aql_txq_limit_ops = {
|
||||
+ .write = aql_txq_limit_write,
|
||||
+ .read = aql_txq_limit_read,
|
||||
+ .open = simple_open,
|
||||
+ .llseek = default_llseek,
|
||||
+};
|
||||
+
|
||||
static ssize_t force_tx_status_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count,
|
||||
@@ -441,6 +522,10 @@ void debugfs_hw_add(struct ieee80211_loc
|
||||
debugfs_create_u16("airtime_flags", 0600,
|
||||
phyd, &local->airtime_flags);
|
||||
|
||||
+ DEBUGFS_ADD(aql_txq_limit);
|
||||
+ debugfs_create_u32("aql_threshold", 0600,
|
||||
+ phyd, &local->aql_threshold);
|
||||
+
|
||||
statsd = debugfs_create_dir("statistics", phyd);
|
||||
|
||||
/* if the dir failed, don't put all the other things into the root! */
|
||||
--- a/net/mac80211/debugfs_sta.c
|
||||
+++ b/net/mac80211/debugfs_sta.c
|
||||
@@ -197,10 +197,12 @@ static ssize_t sta_airtime_read(struct f
|
||||
{
|
||||
struct sta_info *sta = file->private_data;
|
||||
struct ieee80211_local *local = sta->sdata->local;
|
||||
- size_t bufsz = 200;
|
||||
+ size_t bufsz = 400;
|
||||
char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
|
||||
u64 rx_airtime = 0, tx_airtime = 0;
|
||||
s64 deficit[IEEE80211_NUM_ACS];
|
||||
+ u32 q_depth[IEEE80211_NUM_ACS];
|
||||
+ u32 q_limit_l[IEEE80211_NUM_ACS], q_limit_h[IEEE80211_NUM_ACS];
|
||||
ssize_t rv;
|
||||
int ac;
|
||||
|
||||
@@ -212,19 +214,22 @@ static ssize_t sta_airtime_read(struct f
|
||||
rx_airtime += sta->airtime[ac].rx_airtime;
|
||||
tx_airtime += sta->airtime[ac].tx_airtime;
|
||||
deficit[ac] = sta->airtime[ac].deficit;
|
||||
+ q_limit_l[ac] = sta->airtime[ac].aql_limit_low;
|
||||
+ q_limit_h[ac] = sta->airtime[ac].aql_limit_high;
|
||||
spin_unlock_bh(&local->active_txq_lock[ac]);
|
||||
+ q_depth[ac] = atomic_read(&sta->airtime[ac].aql_tx_pending);
|
||||
}
|
||||
|
||||
p += scnprintf(p, bufsz + buf - p,
|
||||
"RX: %llu us\nTX: %llu us\nWeight: %u\n"
|
||||
- "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
|
||||
- rx_airtime,
|
||||
- tx_airtime,
|
||||
- sta->airtime_weight,
|
||||
- deficit[0],
|
||||
- deficit[1],
|
||||
- deficit[2],
|
||||
- deficit[3]);
|
||||
+ "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n"
|
||||
+ "Q depth: VO: %u us VI: %u us BE: %u us BK: %u us\n"
|
||||
+ "Q limit[low/high]: VO: %u/%u VI: %u/%u BE: %u/%u BK: %u/%u\n",
|
||||
+ rx_airtime, tx_airtime, sta->airtime_weight,
|
||||
+ deficit[0], deficit[1], deficit[2], deficit[3],
|
||||
+ q_depth[0], q_depth[1], q_depth[2], q_depth[3],
|
||||
+ q_limit_l[0], q_limit_h[0], q_limit_l[1], q_limit_h[1],
|
||||
+ q_limit_l[2], q_limit_h[2], q_limit_l[3], q_limit_h[3]),
|
||||
|
||||
rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
|
||||
kfree(buf);
|
||||
@@ -236,7 +241,25 @@ static ssize_t sta_airtime_write(struct
|
||||
{
|
||||
struct sta_info *sta = file->private_data;
|
||||
struct ieee80211_local *local = sta->sdata->local;
|
||||
- int ac;
|
||||
+ u32 ac, q_limit_l, q_limit_h;
|
||||
+ char _buf[100] = {}, *buf = _buf;
|
||||
+
|
||||
+ if (count > sizeof(_buf))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (copy_from_user(buf, userbuf, count))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ buf[sizeof(_buf) - 1] = '\0';
|
||||
+ if (sscanf(buf, "queue limit %u %u %u", &ac, &q_limit_l, &q_limit_h)
|
||||
+ != 3)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (ac >= IEEE80211_NUM_ACS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ sta->airtime[ac].aql_limit_low = q_limit_l;
|
||||
+ sta->airtime[ac].aql_limit_high = q_limit_h;
|
||||
|
||||
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
||||
spin_lock_bh(&local->active_txq_lock[ac]);
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1142,6 +1142,10 @@ struct ieee80211_local {
|
||||
u16 schedule_round[IEEE80211_NUM_ACS];
|
||||
|
||||
u16 airtime_flags;
|
||||
+ u32 aql_txq_limit_low[IEEE80211_NUM_ACS];
|
||||
+ u32 aql_txq_limit_high[IEEE80211_NUM_ACS];
|
||||
+ u32 aql_threshold;
|
||||
+ atomic_t aql_total_pending_airtime;
|
||||
|
||||
const struct ieee80211_ops *ops;
|
||||
|
||||
--- a/net/mac80211/main.c
|
||||
+++ b/net/mac80211/main.c
|
||||
@@ -669,8 +669,16 @@ struct ieee80211_hw *ieee80211_alloc_hw_
|
||||
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
|
||||
INIT_LIST_HEAD(&local->active_txqs[i]);
|
||||
spin_lock_init(&local->active_txq_lock[i]);
|
||||
+ local->aql_txq_limit_low[i] = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L;
|
||||
+ local->aql_txq_limit_high[i] =
|
||||
+ IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H;
|
||||
}
|
||||
- local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX;
|
||||
+
|
||||
+ local->airtime_flags = AIRTIME_USE_TX |
|
||||
+ AIRTIME_USE_RX |
|
||||
+ AIRTIME_USE_AQL;
|
||||
+ local->aql_threshold = IEEE80211_AQL_THRESHOLD;
|
||||
+ atomic_set(&local->aql_total_pending_airtime, 0);
|
||||
|
||||
INIT_LIST_HEAD(&local->chanctx_list);
|
||||
mutex_init(&local->chanctx_mtx);
|
||||
--- a/net/mac80211/sta_info.c
|
||||
+++ b/net/mac80211/sta_info.c
|
||||
@@ -411,6 +411,9 @@ struct sta_info *sta_info_alloc(struct i
|
||||
skb_queue_head_init(&sta->ps_tx_buf[i]);
|
||||
skb_queue_head_init(&sta->tx_filtered[i]);
|
||||
sta->airtime[i].deficit = sta->airtime_weight;
|
||||
+ atomic_set(&sta->airtime[i].aql_tx_pending, 0);
|
||||
+ sta->airtime[i].aql_limit_low = local->aql_txq_limit_low[i];
|
||||
+ sta->airtime[i].aql_limit_high = local->aql_txq_limit_high[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
|
||||
@@ -1908,6 +1911,41 @@ void ieee80211_sta_register_airtime(stru
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_sta_register_airtime);
|
||||
|
||||
+void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
|
||||
+ struct sta_info *sta, u8 ac,
|
||||
+ u16 tx_airtime, bool tx_completed)
|
||||
+{
|
||||
+ int tx_pending;
|
||||
+
|
||||
+ if (!tx_completed) {
|
||||
+ if (sta)
|
||||
+ atomic_add(tx_airtime,
|
||||
+ &sta->airtime[ac].aql_tx_pending);
|
||||
+
|
||||
+ atomic_add(tx_airtime, &local->aql_total_pending_airtime);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (sta) {
|
||||
+ tx_pending = atomic_sub_return(tx_airtime,
|
||||
+ &sta->airtime[ac].aql_tx_pending);
|
||||
+ if (WARN_ONCE(tx_pending < 0,
|
||||
+ "STA %pM AC %d txq pending airtime underflow: %u, %u",
|
||||
+ sta->addr, ac, tx_pending, tx_airtime))
|
||||
+ atomic_cmpxchg(&sta->airtime[ac].aql_tx_pending,
|
||||
+ tx_pending, 0);
|
||||
+ }
|
||||
+
|
||||
+ tx_pending = atomic_sub_return(tx_airtime,
|
||||
+ &local->aql_total_pending_airtime);
|
||||
+ if (WARN_ONCE(tx_pending < 0,
|
||||
+ "Device %s AC %d pending airtime underflow: %u, %u",
|
||||
+ wiphy_name(local->hw.wiphy), ac, tx_pending,
|
||||
+ tx_airtime))
|
||||
+ atomic_cmpxchg(&local->aql_total_pending_airtime,
|
||||
+ tx_pending, 0);
|
||||
+}
|
||||
+
|
||||
int sta_info_move_state(struct sta_info *sta,
|
||||
enum ieee80211_sta_state new_state)
|
||||
{
|
||||
--- a/net/mac80211/sta_info.h
|
||||
+++ b/net/mac80211/sta_info.h
|
||||
@@ -127,13 +127,21 @@ enum ieee80211_agg_stop_reason {
|
||||
/* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */
|
||||
#define AIRTIME_USE_TX BIT(0)
|
||||
#define AIRTIME_USE_RX BIT(1)
|
||||
+#define AIRTIME_USE_AQL BIT(2)
|
||||
|
||||
struct airtime_info {
|
||||
u64 rx_airtime;
|
||||
u64 tx_airtime;
|
||||
s64 deficit;
|
||||
+ atomic_t aql_tx_pending; /* Estimated airtime for frames pending */
|
||||
+ u32 aql_limit_low;
|
||||
+ u32 aql_limit_high;
|
||||
};
|
||||
|
||||
+void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
|
||||
+ struct sta_info *sta, u8 ac,
|
||||
+ u16 tx_airtime, bool tx_completed);
|
||||
+
|
||||
struct sta_info;
|
||||
|
||||
/**
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3676,7 +3676,8 @@ struct ieee80211_txq *ieee80211_next_txq
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct ieee80211_txq *ret = NULL;
|
||||
- struct txq_info *txqi = NULL;
|
||||
+ struct txq_info *txqi = NULL, *head = NULL;
|
||||
+ bool found_eligible_txq = false;
|
||||
|
||||
spin_lock_bh(&local->active_txq_lock[ac]);
|
||||
|
||||
@@ -3687,13 +3688,30 @@ struct ieee80211_txq *ieee80211_next_txq
|
||||
if (!txqi)
|
||||
goto out;
|
||||
|
||||
+ if (txqi == head) {
|
||||
+ if (!found_eligible_txq)
|
||||
+ goto out;
|
||||
+ else
|
||||
+ found_eligible_txq = false;
|
||||
+ }
|
||||
+
|
||||
+ if (!head)
|
||||
+ head = txqi;
|
||||
+
|
||||
if (txqi->txq.sta) {
|
||||
struct sta_info *sta = container_of(txqi->txq.sta,
|
||||
- struct sta_info, sta);
|
||||
+ struct sta_info, sta);
|
||||
+ bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
|
||||
+ s64 deficit = sta->airtime[txqi->txq.ac].deficit;
|
||||
|
||||
- if (sta->airtime[txqi->txq.ac].deficit < 0) {
|
||||
+ if (aql_check)
|
||||
+ found_eligible_txq = true;
|
||||
+
|
||||
+ if (deficit < 0)
|
||||
sta->airtime[txqi->txq.ac].deficit +=
|
||||
sta->airtime_weight;
|
||||
+
|
||||
+ if (deficit < 0 || !aql_check) {
|
||||
list_move_tail(&txqi->schedule_order,
|
||||
&local->active_txqs[txqi->txq.ac]);
|
||||
goto begin;
|
||||
@@ -3747,6 +3765,33 @@ void __ieee80211_schedule_txq(struct iee
|
||||
}
|
||||
EXPORT_SYMBOL(__ieee80211_schedule_txq);
|
||||
|
||||
+bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_txq *txq)
|
||||
+{
|
||||
+ struct sta_info *sta;
|
||||
+ struct ieee80211_local *local = hw_to_local(hw);
|
||||
+
|
||||
+ if (!(local->airtime_flags & AIRTIME_USE_AQL))
|
||||
+ return true;
|
||||
+
|
||||
+ if (!txq->sta)
|
||||
+ return true;
|
||||
+
|
||||
+ sta = container_of(txq->sta, struct sta_info, sta);
|
||||
+ if (atomic_read(&sta->airtime[txq->ac].aql_tx_pending) <
|
||||
+ sta->airtime[txq->ac].aql_limit_low)
|
||||
+ return true;
|
||||
+
|
||||
+ if (atomic_read(&local->aql_total_pending_airtime) <
|
||||
+ local->aql_threshold &&
|
||||
+ atomic_read(&sta->airtime[txq->ac].aql_tx_pending) <
|
||||
+ sta->airtime[txq->ac].aql_limit_high)
|
||||
+ return true;
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_txq_airtime_check);
|
||||
+
|
||||
bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
|
||||
struct ieee80211_txq *txq)
|
||||
{
|
@ -1,146 +0,0 @@
|
||||
From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com>
|
||||
Date: Mon, 18 Nov 2019 22:06:10 -0800
|
||||
Subject: [PATCH] mac80211: Use Airtime-based Queue Limits (AQL) on packet
|
||||
dequeue
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The previous commit added the ability to throttle stations when they queue
|
||||
too much airtime in the hardware. This commit enables the functionality by
|
||||
calculating the expected airtime usage of each packet that is dequeued from
|
||||
the TXQs in mac80211, and accounting that as pending airtime.
|
||||
|
||||
The estimated airtime for each skb is stored in the tx_info, so we can
|
||||
subtract the same amount from the running total when the skb is freed or
|
||||
recycled. The throttling mechanism relies on this accounting to be
|
||||
accurate (i.e., that we are not freeing skbs without subtracting any
|
||||
airtime they were accounted for), so we put the subtraction into
|
||||
ieee80211_report_used_skb(). As an optimisation, we also subtract the
|
||||
airtime on regular TX completion, zeroing out the value stored in the
|
||||
packet afterwards, to avoid having to do an expensive lookup of the station
|
||||
from the packet data on every packet.
|
||||
|
||||
This patch does *not* include any mechanism to wake a throttled TXQ again,
|
||||
on the assumption that this will happen anyway as a side effect of whatever
|
||||
freed the skb (most commonly a TX completion).
|
||||
|
||||
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
||||
Link: https://lore.kernel.org/r/20191119060610.76681-5-kyan@google.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -1060,6 +1060,22 @@ struct ieee80211_tx_info {
|
||||
};
|
||||
};
|
||||
|
||||
+static inline u16
|
||||
+ieee80211_info_set_tx_time_est(struct ieee80211_tx_info *info, u16 tx_time_est)
|
||||
+{
|
||||
+ /* We only have 10 bits in tx_time_est, so store airtime
|
||||
+ * in increments of 4us and clamp the maximum to 2**12-1
|
||||
+ */
|
||||
+ info->tx_time_est = min_t(u16, tx_time_est, 4095) >> 2;
|
||||
+ return info->tx_time_est << 2;
|
||||
+}
|
||||
+
|
||||
+static inline u16
|
||||
+ieee80211_info_get_tx_time_est(struct ieee80211_tx_info *info)
|
||||
+{
|
||||
+ return info->tx_time_est << 2;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* struct ieee80211_tx_status - extended tx staus info for rate control
|
||||
*
|
||||
--- a/net/mac80211/status.c
|
||||
+++ b/net/mac80211/status.c
|
||||
@@ -670,12 +670,26 @@ static void ieee80211_report_used_skb(st
|
||||
struct sk_buff *skb, bool dropped)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
+ u16 tx_time_est = ieee80211_info_get_tx_time_est(info);
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
bool acked = info->flags & IEEE80211_TX_STAT_ACK;
|
||||
|
||||
if (dropped)
|
||||
acked = false;
|
||||
|
||||
+ if (tx_time_est) {
|
||||
+ struct sta_info *sta;
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+
|
||||
+ sta = sta_info_get_by_addrs(local, hdr->addr1, hdr->addr2);
|
||||
+ ieee80211_sta_update_pending_airtime(local, sta,
|
||||
+ skb_get_queue_mapping(skb),
|
||||
+ tx_time_est,
|
||||
+ true);
|
||||
+ rcu_read_unlock();
|
||||
+ }
|
||||
+
|
||||
if (info->flags & IEEE80211_TX_INTFL_MLME_CONN_TX) {
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
|
||||
@@ -885,6 +899,7 @@ static void __ieee80211_tx_status(struct
|
||||
struct ieee80211_bar *bar;
|
||||
int shift = 0;
|
||||
int tid = IEEE80211_NUM_TIDS;
|
||||
+ u16 tx_time_est;
|
||||
|
||||
rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
|
||||
|
||||
@@ -996,6 +1011,17 @@ static void __ieee80211_tx_status(struct
|
||||
ieee80211_sta_register_airtime(&sta->sta, tid,
|
||||
info->status.tx_time, 0);
|
||||
|
||||
+ if ((tx_time_est = ieee80211_info_get_tx_time_est(info)) > 0) {
|
||||
+ /* Do this here to avoid the expensive lookup of the sta
|
||||
+ * in ieee80211_report_used_skb().
|
||||
+ */
|
||||
+ ieee80211_sta_update_pending_airtime(local, sta,
|
||||
+ skb_get_queue_mapping(skb),
|
||||
+ tx_time_est,
|
||||
+ true);
|
||||
+ ieee80211_info_set_tx_time_est(info, 0);
|
||||
+ }
|
||||
+
|
||||
if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
|
||||
if (acked) {
|
||||
if (sta->status_stats.lost_packets)
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3553,6 +3553,9 @@ struct sk_buff *ieee80211_tx_dequeue(str
|
||||
|
||||
WARN_ON_ONCE(softirq_count() == 0);
|
||||
|
||||
+ if (!ieee80211_txq_airtime_check(hw, txq))
|
||||
+ return NULL;
|
||||
+
|
||||
begin:
|
||||
spin_lock_bh(&fq->lock);
|
||||
|
||||
@@ -3663,6 +3666,21 @@ begin:
|
||||
}
|
||||
|
||||
IEEE80211_SKB_CB(skb)->control.vif = vif;
|
||||
+
|
||||
+ if (local->airtime_flags & AIRTIME_USE_AQL) {
|
||||
+ u32 airtime;
|
||||
+
|
||||
+ airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
|
||||
+ skb->len);
|
||||
+ if (airtime) {
|
||||
+ airtime = ieee80211_info_set_tx_time_est(info, airtime);
|
||||
+ ieee80211_sta_update_pending_airtime(local, tx.sta,
|
||||
+ txq->ac,
|
||||
+ airtime,
|
||||
+ false);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return skb;
|
||||
|
||||
out:
|
@ -1,31 +0,0 @@
|
||||
From: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Date: Tue, 26 Nov 2019 15:09:39 +0300
|
||||
Subject: [PATCH] mac80211: airtime: Fix an off by one in
|
||||
ieee80211_calc_rx_airtime()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This code was copied from mt76 and inherited an off by one bug from
|
||||
there. The > should be >= so that we don't read one element beyond
|
||||
the end of the array.
|
||||
|
||||
Fixes: db3e1c40cf2f ("mac80211: Import airtime calculation code from mt76")
|
||||
Reported-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
||||
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
||||
Link: https://lore.kernel.org/r/20191126120910.ftr4t7me3by32aiz@kili.mountain
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/airtime.c
|
||||
+++ b/net/mac80211/airtime.c
|
||||
@@ -442,7 +442,7 @@ u32 ieee80211_calc_rx_airtime(struct iee
|
||||
return 0;
|
||||
|
||||
sband = hw->wiphy->bands[status->band];
|
||||
- if (!sband || status->rate_idx > sband->n_bitrates)
|
||||
+ if (!sband || status->rate_idx >= sband->n_bitrates)
|
||||
return 0;
|
||||
|
||||
rate = &sband->bitrates[status->rate_idx];
|
@ -1,253 +0,0 @@
|
||||
From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com>
|
||||
Date: Thu, 12 Dec 2019 12:14:37 +0100
|
||||
Subject: [PATCH] mac80211: Turn AQL into an NL80211_EXT_FEATURE
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Instead of just having an airtime flag in debugfs, turn AQL into a proper
|
||||
NL80211_EXT_FEATURE, so drivers can turn it on when they are ready, and so
|
||||
we also expose the presence of the feature to userspace.
|
||||
|
||||
This also has the effect of flipping the default, so drivers have to opt in
|
||||
to using AQL instead of getting it by default with TXQs. To keep
|
||||
functionality the same as pre-patch, we set this feature for ath10k (which
|
||||
is where it is needed the most).
|
||||
|
||||
While we're at it, split out the debugfs interface so AQL gets its own
|
||||
per-station debugfs file instead of using the 'airtime' file.
|
||||
|
||||
[Johannes:]
|
||||
This effectively disables AQL for iwlwifi, where it fixes a number of
|
||||
issues:
|
||||
* TSO in iwlwifi is causing underflows and associated warnings in AQL
|
||||
* HE (802.11ax) rates aren't reported properly so at HE rates, AQL could
|
||||
never have a valid estimate (it'd use 6 Mbps instead of up to 2400!)
|
||||
|
||||
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
||||
Link: https://lore.kernel.org/r/20191212111437.224294-1-toke@redhat.com
|
||||
Fixes: 3ace10f5b5ad ("mac80211: Implement Airtime-based Queue Limit (AQL)")
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -8870,6 +8870,7 @@ int ath10k_mac_register(struct ath10k *a
|
||||
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
|
||||
wiphy_ext_feature_set(ar->hw->wiphy,
|
||||
NL80211_EXT_FEATURE_SET_SCAN_DWELL);
|
||||
+ wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_AQL);
|
||||
|
||||
if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map) ||
|
||||
test_bit(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, ar->wmi.svc_map))
|
||||
--- a/include/uapi/linux/nl80211.h
|
||||
+++ b/include/uapi/linux/nl80211.h
|
||||
@@ -5484,6 +5484,10 @@ enum nl80211_feature_flags {
|
||||
* @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in
|
||||
* station mode (SAE password is passed as part of the connect command).
|
||||
*
|
||||
+ * @NL80211_EXT_FEATURE_AQL: The driver supports the Airtime Queue Limit (AQL)
|
||||
+ * feature, which prevents bufferbloat by using the expected transmission
|
||||
+ * time to limit the amount of data buffered in the hardware.
|
||||
+ *
|
||||
* @NUM_NL80211_EXT_FEATURES: number of extended features.
|
||||
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
|
||||
*/
|
||||
@@ -5529,6 +5533,8 @@ enum nl80211_ext_feature_index {
|
||||
NL80211_EXT_FEATURE_EXT_KEY_ID,
|
||||
NL80211_EXT_FEATURE_STA_TX_PWR,
|
||||
NL80211_EXT_FEATURE_SAE_OFFLOAD,
|
||||
+ NL80211_EXT_FEATURE_VLAN_OFFLOAD,
|
||||
+ NL80211_EXT_FEATURE_AQL,
|
||||
|
||||
/* add new features before the definition below */
|
||||
NUM_NL80211_EXT_FEATURES,
|
||||
--- a/net/mac80211/debugfs_sta.c
|
||||
+++ b/net/mac80211/debugfs_sta.c
|
||||
@@ -201,8 +201,6 @@ static ssize_t sta_airtime_read(struct f
|
||||
char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
|
||||
u64 rx_airtime = 0, tx_airtime = 0;
|
||||
s64 deficit[IEEE80211_NUM_ACS];
|
||||
- u32 q_depth[IEEE80211_NUM_ACS];
|
||||
- u32 q_limit_l[IEEE80211_NUM_ACS], q_limit_h[IEEE80211_NUM_ACS];
|
||||
ssize_t rv;
|
||||
int ac;
|
||||
|
||||
@@ -214,6 +212,56 @@ static ssize_t sta_airtime_read(struct f
|
||||
rx_airtime += sta->airtime[ac].rx_airtime;
|
||||
tx_airtime += sta->airtime[ac].tx_airtime;
|
||||
deficit[ac] = sta->airtime[ac].deficit;
|
||||
+ spin_unlock_bh(&local->active_txq_lock[ac]);
|
||||
+ }
|
||||
+
|
||||
+ p += scnprintf(p, bufsz + buf - p,
|
||||
+ "RX: %llu us\nTX: %llu us\nWeight: %u\n"
|
||||
+ "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
|
||||
+ rx_airtime, tx_airtime, sta->airtime_weight,
|
||||
+ deficit[0], deficit[1], deficit[2], deficit[3]);
|
||||
+
|
||||
+ rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
|
||||
+ kfree(buf);
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
+static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct sta_info *sta = file->private_data;
|
||||
+ struct ieee80211_local *local = sta->sdata->local;
|
||||
+ int ac;
|
||||
+
|
||||
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
||||
+ spin_lock_bh(&local->active_txq_lock[ac]);
|
||||
+ sta->airtime[ac].rx_airtime = 0;
|
||||
+ sta->airtime[ac].tx_airtime = 0;
|
||||
+ sta->airtime[ac].deficit = sta->airtime_weight;
|
||||
+ spin_unlock_bh(&local->active_txq_lock[ac]);
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+STA_OPS_RW(airtime);
|
||||
+
|
||||
+static ssize_t sta_aql_read(struct file *file, char __user *userbuf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct sta_info *sta = file->private_data;
|
||||
+ struct ieee80211_local *local = sta->sdata->local;
|
||||
+ size_t bufsz = 400;
|
||||
+ char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
|
||||
+ u32 q_depth[IEEE80211_NUM_ACS];
|
||||
+ u32 q_limit_l[IEEE80211_NUM_ACS], q_limit_h[IEEE80211_NUM_ACS];
|
||||
+ ssize_t rv;
|
||||
+ int ac;
|
||||
+
|
||||
+ if (!buf)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
||||
+ spin_lock_bh(&local->active_txq_lock[ac]);
|
||||
q_limit_l[ac] = sta->airtime[ac].aql_limit_low;
|
||||
q_limit_h[ac] = sta->airtime[ac].aql_limit_high;
|
||||
spin_unlock_bh(&local->active_txq_lock[ac]);
|
||||
@@ -221,12 +269,8 @@ static ssize_t sta_airtime_read(struct f
|
||||
}
|
||||
|
||||
p += scnprintf(p, bufsz + buf - p,
|
||||
- "RX: %llu us\nTX: %llu us\nWeight: %u\n"
|
||||
- "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n"
|
||||
"Q depth: VO: %u us VI: %u us BE: %u us BK: %u us\n"
|
||||
"Q limit[low/high]: VO: %u/%u VI: %u/%u BE: %u/%u BK: %u/%u\n",
|
||||
- rx_airtime, tx_airtime, sta->airtime_weight,
|
||||
- deficit[0], deficit[1], deficit[2], deficit[3],
|
||||
q_depth[0], q_depth[1], q_depth[2], q_depth[3],
|
||||
q_limit_l[0], q_limit_h[0], q_limit_l[1], q_limit_h[1],
|
||||
q_limit_l[2], q_limit_h[2], q_limit_l[3], q_limit_h[3]),
|
||||
@@ -236,11 +280,10 @@ static ssize_t sta_airtime_read(struct f
|
||||
return rv;
|
||||
}
|
||||
|
||||
-static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
|
||||
+static ssize_t sta_aql_write(struct file *file, const char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct sta_info *sta = file->private_data;
|
||||
- struct ieee80211_local *local = sta->sdata->local;
|
||||
u32 ac, q_limit_l, q_limit_h;
|
||||
char _buf[100] = {}, *buf = _buf;
|
||||
|
||||
@@ -251,7 +294,7 @@ static ssize_t sta_airtime_write(struct
|
||||
return -EFAULT;
|
||||
|
||||
buf[sizeof(_buf) - 1] = '\0';
|
||||
- if (sscanf(buf, "queue limit %u %u %u", &ac, &q_limit_l, &q_limit_h)
|
||||
+ if (sscanf(buf, "limit %u %u %u", &ac, &q_limit_l, &q_limit_h)
|
||||
!= 3)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -261,17 +304,10 @@ static ssize_t sta_airtime_write(struct
|
||||
sta->airtime[ac].aql_limit_low = q_limit_l;
|
||||
sta->airtime[ac].aql_limit_high = q_limit_h;
|
||||
|
||||
- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
||||
- spin_lock_bh(&local->active_txq_lock[ac]);
|
||||
- sta->airtime[ac].rx_airtime = 0;
|
||||
- sta->airtime[ac].tx_airtime = 0;
|
||||
- sta->airtime[ac].deficit = sta->airtime_weight;
|
||||
- spin_unlock_bh(&local->active_txq_lock[ac]);
|
||||
- }
|
||||
-
|
||||
return count;
|
||||
}
|
||||
-STA_OPS_RW(airtime);
|
||||
+STA_OPS_RW(aql);
|
||||
+
|
||||
|
||||
static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
@@ -1001,6 +1037,10 @@ void ieee80211_sta_debugfs_add(struct st
|
||||
NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
|
||||
DEBUGFS_ADD(airtime);
|
||||
|
||||
+ if (wiphy_ext_feature_isset(local->hw.wiphy,
|
||||
+ NL80211_EXT_FEATURE_AQL))
|
||||
+ DEBUGFS_ADD(aql);
|
||||
+
|
||||
if (sizeof(sta->driver_buffered_tids) == sizeof(u32))
|
||||
debugfs_create_x32("driver_buffered_tids", 0400,
|
||||
sta->debugfs_dir,
|
||||
--- a/net/mac80211/main.c
|
||||
+++ b/net/mac80211/main.c
|
||||
@@ -674,9 +674,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
|
||||
IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H;
|
||||
}
|
||||
|
||||
- local->airtime_flags = AIRTIME_USE_TX |
|
||||
- AIRTIME_USE_RX |
|
||||
- AIRTIME_USE_AQL;
|
||||
+ local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX;
|
||||
local->aql_threshold = IEEE80211_AQL_THRESHOLD;
|
||||
atomic_set(&local->aql_total_pending_airtime, 0);
|
||||
|
||||
--- a/net/mac80211/sta_info.c
|
||||
+++ b/net/mac80211/sta_info.c
|
||||
@@ -1917,6 +1917,9 @@ void ieee80211_sta_update_pending_airtim
|
||||
{
|
||||
int tx_pending;
|
||||
|
||||
+ if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
|
||||
+ return;
|
||||
+
|
||||
if (!tx_completed) {
|
||||
if (sta)
|
||||
atomic_add(tx_airtime,
|
||||
--- a/net/mac80211/sta_info.h
|
||||
+++ b/net/mac80211/sta_info.h
|
||||
@@ -127,7 +127,6 @@ enum ieee80211_agg_stop_reason {
|
||||
/* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */
|
||||
#define AIRTIME_USE_TX BIT(0)
|
||||
#define AIRTIME_USE_RX BIT(1)
|
||||
-#define AIRTIME_USE_AQL BIT(2)
|
||||
|
||||
struct airtime_info {
|
||||
u64 rx_airtime;
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3667,7 +3667,7 @@ begin:
|
||||
|
||||
IEEE80211_SKB_CB(skb)->control.vif = vif;
|
||||
|
||||
- if (local->airtime_flags & AIRTIME_USE_AQL) {
|
||||
+ if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
|
||||
u32 airtime;
|
||||
|
||||
airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
|
||||
@@ -3789,7 +3789,7 @@ bool ieee80211_txq_airtime_check(struct
|
||||
struct sta_info *sta;
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
|
||||
- if (!(local->airtime_flags & AIRTIME_USE_AQL))
|
||||
+ if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
|
||||
return true;
|
||||
|
||||
if (!txq->sta)
|
@ -1,148 +0,0 @@
|
||||
From a0761a301746ec2d92d7fcb82af69c0a6a4339aa Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Thu, 26 Mar 2020 15:09:42 +0200
|
||||
Subject: mac80211: drop data frames without key on encrypted links
|
||||
|
||||
If we know that we have an encrypted link (based on having had
|
||||
a key configured for TX in the past) then drop all data frames
|
||||
in the key selection handler if there's no key anymore.
|
||||
|
||||
This fixes an issue with mac80211 internal TXQs - there we can
|
||||
buffer frames for an encrypted link, but then if the key is no
|
||||
longer there when they're dequeued, the frames are sent without
|
||||
encryption. This happens if a station is disconnected while the
|
||||
frames are still on the TXQ.
|
||||
|
||||
Detecting that a link should be encrypted based on a first key
|
||||
having been configured for TX is fine as there are no use cases
|
||||
for a connection going from with encryption to no encryption.
|
||||
With extended key IDs, however, there is a case of having a key
|
||||
configured for only decryption, so we can't just trigger this
|
||||
behaviour on a key being configured.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Reported-by: Jouni Malinen <j@w1.fi>
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
---
|
||||
net/mac80211/debugfs_sta.c | 3 ++-
|
||||
net/mac80211/key.c | 20 ++++++++++++--------
|
||||
net/mac80211/sta_info.h | 1 +
|
||||
net/mac80211/tx.c | 12 +++++++++---
|
||||
4 files changed, 24 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/net/mac80211/debugfs_sta.c
|
||||
+++ b/net/mac80211/debugfs_sta.c
|
||||
@@ -5,7 +5,7 @@
|
||||
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
- * Copyright (C) 2018 - 2019 Intel Corporation
|
||||
+ * Copyright (C) 2018 - 2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
@@ -78,6 +78,7 @@ static const char * const sta_flag_names
|
||||
FLAG(MPSP_OWNER),
|
||||
FLAG(MPSP_RECIPIENT),
|
||||
FLAG(PS_DELIVER),
|
||||
+ FLAG(USES_ENCRYPTION),
|
||||
#undef FLAG
|
||||
};
|
||||
|
||||
--- a/net/mac80211/key.c
|
||||
+++ b/net/mac80211/key.c
|
||||
@@ -6,7 +6,7 @@
|
||||
* Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright 2015-2017 Intel Deutschland GmbH
|
||||
- * Copyright 2018-2019 Intel Corporation
|
||||
+ * Copyright 2018-2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/if_ether.h>
|
||||
@@ -262,22 +262,29 @@ static void ieee80211_key_disable_hw_acc
|
||||
sta ? sta->sta.addr : bcast_addr, ret);
|
||||
}
|
||||
|
||||
-int ieee80211_set_tx_key(struct ieee80211_key *key)
|
||||
+static int _ieee80211_set_tx_key(struct ieee80211_key *key, bool force)
|
||||
{
|
||||
struct sta_info *sta = key->sta;
|
||||
struct ieee80211_local *local = key->local;
|
||||
|
||||
assert_key_lock(local);
|
||||
|
||||
+ set_sta_flag(sta, WLAN_STA_USES_ENCRYPTION);
|
||||
+
|
||||
sta->ptk_idx = key->conf.keyidx;
|
||||
|
||||
- if (!ieee80211_hw_check(&local->hw, AMPDU_KEYBORDER_SUPPORT))
|
||||
+ if (force || !ieee80211_hw_check(&local->hw, AMPDU_KEYBORDER_SUPPORT))
|
||||
clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
||||
ieee80211_check_fast_xmit(sta);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int ieee80211_set_tx_key(struct ieee80211_key *key)
|
||||
+{
|
||||
+ return _ieee80211_set_tx_key(key, false);
|
||||
+}
|
||||
+
|
||||
static void ieee80211_pairwise_rekey(struct ieee80211_key *old,
|
||||
struct ieee80211_key *new)
|
||||
{
|
||||
@@ -441,11 +448,8 @@ static int ieee80211_key_replace(struct
|
||||
if (pairwise) {
|
||||
rcu_assign_pointer(sta->ptk[idx], new);
|
||||
if (new &&
|
||||
- !(new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX)) {
|
||||
- sta->ptk_idx = idx;
|
||||
- clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
||||
- ieee80211_check_fast_xmit(sta);
|
||||
- }
|
||||
+ !(new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX))
|
||||
+ _ieee80211_set_tx_key(new, true);
|
||||
} else {
|
||||
rcu_assign_pointer(sta->gtk[idx], new);
|
||||
}
|
||||
--- a/net/mac80211/sta_info.h
|
||||
+++ b/net/mac80211/sta_info.h
|
||||
@@ -98,6 +98,7 @@ enum ieee80211_sta_info_flags {
|
||||
WLAN_STA_MPSP_OWNER,
|
||||
WLAN_STA_MPSP_RECIPIENT,
|
||||
WLAN_STA_PS_DELIVER,
|
||||
+ WLAN_STA_USES_ENCRYPTION,
|
||||
|
||||
NUM_WLAN_STA_FLAGS,
|
||||
};
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -590,10 +590,13 @@ ieee80211_tx_h_select_key(struct ieee802
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
|
||||
|
||||
- if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
|
||||
+ if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) {
|
||||
tx->key = NULL;
|
||||
- else if (tx->sta &&
|
||||
- (key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx])))
|
||||
+ return TX_CONTINUE;
|
||||
+ }
|
||||
+
|
||||
+ if (tx->sta &&
|
||||
+ (key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx])))
|
||||
tx->key = key;
|
||||
else if (ieee80211_is_group_privacy_action(tx->skb) &&
|
||||
(key = rcu_dereference(tx->sdata->default_multicast_key)))
|
||||
@@ -654,6 +657,9 @@ ieee80211_tx_h_select_key(struct ieee802
|
||||
if (!skip_hw && tx->key &&
|
||||
tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
|
||||
info->control.hw_key = &tx->key->conf;
|
||||
+ } else if (!ieee80211_is_mgmt(hdr->frame_control) && tx->sta &&
|
||||
+ test_sta_flag(tx->sta, WLAN_STA_USES_ENCRYPTION)) {
|
||||
+ return TX_DROP;
|
||||
}
|
||||
|
||||
return TX_CONTINUE;
|
@ -1,70 +0,0 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Wed, 15 Jan 2020 12:25:50 +0100
|
||||
Subject: [PATCH] mac80211: use more bits for ack_frame_id
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
It turns out that this wasn't a good idea, I hit a test failure in
|
||||
hwsim due to this. That particular failure was easily worked around,
|
||||
but it raised questions: if an AP needs to, for example, send action
|
||||
frames to each connected station, the current limit is nowhere near
|
||||
enough (especially if those stations are sleeping and the frames are
|
||||
queued for a while.)
|
||||
|
||||
Shuffle around some bits to make more room for ack_frame_id to allow
|
||||
up to 8192 queued up frames, that's enough for queueing 4 frames to
|
||||
each connected station, even at the maximum of 2007 stations on a
|
||||
single AP.
|
||||
|
||||
We take the bits from band (which currently only 2 but I leave 3 in
|
||||
case we add another band) and from the hw_queue, which can only need
|
||||
4 since it has a limit of 16 queues.
|
||||
|
||||
Fixes: 6912daed05e1 ("mac80211: Shrink the size of ack_frame_id to make room for tx_time_est")
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -1004,12 +1004,11 @@ ieee80211_rate_get_vht_nss(const struct
|
||||
struct ieee80211_tx_info {
|
||||
/* common information */
|
||||
u32 flags;
|
||||
- u8 band;
|
||||
-
|
||||
- u8 hw_queue;
|
||||
-
|
||||
- u16 ack_frame_id:6;
|
||||
- u16 tx_time_est:10;
|
||||
+ u32 band:3,
|
||||
+ ack_frame_id:13,
|
||||
+ hw_queue:4,
|
||||
+ tx_time_est:10;
|
||||
+ /* 2 free bits */
|
||||
|
||||
union {
|
||||
struct {
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -3449,7 +3449,7 @@ int ieee80211_attach_ack_skb(struct ieee
|
||||
|
||||
spin_lock_irqsave(&local->ack_status_lock, spin_flags);
|
||||
id = idr_alloc(&local->ack_status_frames, ack_skb,
|
||||
- 1, 0x40, GFP_ATOMIC);
|
||||
+ 1, 0x2000, GFP_ATOMIC);
|
||||
spin_unlock_irqrestore(&local->ack_status_lock, spin_flags);
|
||||
|
||||
if (id < 0) {
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -2458,7 +2458,7 @@ static int ieee80211_store_ack_skb(struc
|
||||
|
||||
spin_lock_irqsave(&local->ack_status_lock, flags);
|
||||
id = idr_alloc(&local->ack_status_frames, ack_skb,
|
||||
- 1, 0x40, GFP_ATOMIC);
|
||||
+ 1, 0x2000, GFP_ATOMIC);
|
||||
spin_unlock_irqrestore(&local->ack_status_lock, flags);
|
||||
|
||||
if (id >= 0) {
|
@ -1,6 +1,6 @@
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -3454,6 +3454,7 @@ struct cfg80211_update_owe_info {
|
||||
@@ -3552,6 +3552,7 @@ struct cfg80211_update_owe_info {
|
||||
* (as advertised by the nl80211 feature flag.)
|
||||
* @get_tx_power: store the current TX power into the dbm variable;
|
||||
* return 0 if successful
|
||||
@ -8,7 +8,7 @@
|
||||
*
|
||||
* @set_wds_peer: set the WDS peer for a WDS interface
|
||||
*
|
||||
@@ -3769,6 +3770,7 @@ struct cfg80211_ops {
|
||||
@@ -3874,6 +3875,7 @@ struct cfg80211_ops {
|
||||
enum nl80211_tx_power_setting type, int mbm);
|
||||
int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
int *dbm);
|
||||
@ -18,7 +18,7 @@
|
||||
const u8 *addr);
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -1501,6 +1501,7 @@ enum ieee80211_smps_mode {
|
||||
@@ -1504,6 +1504,7 @@ enum ieee80211_smps_mode {
|
||||
*
|
||||
* @power_level: requested transmit power (in dBm), backward compatibility
|
||||
* value only that is set to the minimum of all interfaces
|
||||
@ -26,7 +26,7 @@
|
||||
*
|
||||
* @chandef: the channel definition to tune to
|
||||
* @radar_enabled: whether radar detection is enabled
|
||||
@@ -1521,6 +1522,7 @@ enum ieee80211_smps_mode {
|
||||
@@ -1524,6 +1525,7 @@ enum ieee80211_smps_mode {
|
||||
struct ieee80211_conf {
|
||||
u32 flags;
|
||||
int power_level, dynamic_ps_timeout;
|
||||
@ -36,9 +36,9 @@
|
||||
u8 ps_dtim_period;
|
||||
--- a/include/uapi/linux/nl80211.h
|
||||
+++ b/include/uapi/linux/nl80211.h
|
||||
@@ -2373,6 +2373,9 @@ enum nl80211_commands {
|
||||
* the allowed channel bandwidth configurations. (u8 attribute)
|
||||
* Defined by IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13.
|
||||
@@ -2470,6 +2470,9 @@ enum nl80211_commands {
|
||||
* no roaming occurs between the reauth threshold and PMK expiration,
|
||||
* disassociation is still forced.
|
||||
*
|
||||
+ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
|
||||
+ * transmit power to stay within regulatory limits. u32, dBi.
|
||||
@ -46,9 +46,9 @@
|
||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
@@ -2835,6 +2838,8 @@ enum nl80211_attrs {
|
||||
NL80211_ATTR_WIPHY_EDMG_CHANNELS,
|
||||
NL80211_ATTR_WIPHY_EDMG_BW_CONFIG,
|
||||
@@ -2945,6 +2948,8 @@ enum nl80211_attrs {
|
||||
NL80211_ATTR_PMK_LIFETIME,
|
||||
NL80211_ATTR_PMK_REAUTH_THRESHOLD,
|
||||
|
||||
+ NL80211_ATTR_WIPHY_ANTENNA_GAIN,
|
||||
+
|
||||
@ -77,7 +77,7 @@
|
||||
static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *addr)
|
||||
{
|
||||
@@ -4017,6 +4030,7 @@ const struct cfg80211_ops mac80211_confi
|
||||
@@ -4004,6 +4017,7 @@ const struct cfg80211_ops mac80211_confi
|
||||
.set_wiphy_params = ieee80211_set_wiphy_params,
|
||||
.set_tx_power = ieee80211_set_tx_power,
|
||||
.get_tx_power = ieee80211_get_tx_power,
|
||||
@ -87,7 +87,7 @@
|
||||
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1376,6 +1376,7 @@ struct ieee80211_local {
|
||||
@@ -1380,6 +1380,7 @@ struct ieee80211_local {
|
||||
int dynamic_ps_forced_timeout;
|
||||
|
||||
int user_power_level; /* in dBm, for all interfaces */
|
||||
@ -106,7 +106,7 @@
|
||||
u32 offchannel_flag;
|
||||
|
||||
offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
|
||||
@@ -150,6 +150,12 @@ static u32 ieee80211_hw_conf_chan(struct
|
||||
@@ -152,6 +152,12 @@ static u32 ieee80211_hw_conf_chan(struct
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
@ -119,7 +119,7 @@
|
||||
if (local->hw.conf.power_level != power) {
|
||||
changed |= IEEE80211_CONF_CHANGE_POWER;
|
||||
local->hw.conf.power_level = power;
|
||||
@@ -639,6 +645,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
|
||||
@@ -656,6 +662,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
|
||||
IEEE80211_RADIOTAP_MCS_HAVE_BW;
|
||||
local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
|
||||
IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
|
||||
@ -129,15 +129,15 @@
|
||||
local->hw.max_mtu = IEEE80211_MAX_DATA_LEN;
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -630,6 +630,7 @@ const struct nla_policy nl80211_policy[N
|
||||
.len = SAE_PASSWORD_MAX_LEN },
|
||||
[NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
|
||||
@@ -661,6 +661,7 @@ const struct nla_policy nl80211_policy[N
|
||||
[NL80211_ATTR_CONTROL_PORT_NO_PREAUTH] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1),
|
||||
[NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100),
|
||||
+ [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@@ -2994,6 +2995,20 @@ static int nl80211_set_wiphy(struct sk_b
|
||||
@@ -3132,6 +3133,20 @@ static int nl80211_set_wiphy(struct sk_b
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
@ -130,6 +130,19 @@ config rule
|
||||
option proto udp
|
||||
option target ACCEPT
|
||||
|
||||
# allow interoperability with traceroute classic
|
||||
# note that traceroute uses a fixed port range, and depends on getting
|
||||
# back ICMP Unreachables. if we're operating in DROP mode, it won't
|
||||
# work so we explicitly REJECT packets on these ports.
|
||||
config rule
|
||||
option name Support-UDP-Traceroute
|
||||
option src wan
|
||||
option dest_port 33434:33689
|
||||
option proto udp
|
||||
option family ipv4
|
||||
option target REJECT
|
||||
option enabled false
|
||||
|
||||
# include a file with users custom iptables rules
|
||||
config include
|
||||
option path /etc/firewall.user
|
||||
|
@ -5,9 +5,9 @@ PKG_RELEASE:=3
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git
|
||||
PKG_SOURCE_DATE:=2020-04-14
|
||||
PKG_SOURCE_VERSION:=cfccdc22ca6d8f28d70a2546a495c9ead4bbb765
|
||||
PKG_MIRROR_HASH:=4c680fa979f21b2a1280e8bffca9fa1412215a4058dfcde2569df9befea43999
|
||||
PKG_SOURCE_DATE:=2020-05-17
|
||||
PKG_SOURCE_VERSION:=74e0222eeb9e62f4d5073a5b3d9208678782a198
|
||||
PKG_MIRROR_HASH:=5caa2472ab569d5bd908850c4089366c53c3309ea43cc0ea81b7ec60f912b721
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
@ -73,3 +73,12 @@ config DRIVER_11AC_SUPPORT
|
||||
config DRIVER_11W_SUPPORT
|
||||
bool
|
||||
default n
|
||||
|
||||
config WPA_ENABLE_WEP
|
||||
bool "Enable support for unsecure and obsolete WEP"
|
||||
help
|
||||
Wired equivalent privacy (WEP) is an obsolete cryptographic data
|
||||
confidentiality algorithm that is not considered secure. It should not be used
|
||||
for anything anymore. The functionality needed to use WEP is available in the
|
||||
current hostapd release under this optional build parameter and completely
|
||||
removed in a future release.
|
||||
|
@ -7,13 +7,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=hostapd
|
||||
PKG_RELEASE:=10
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE_URL:=http://w1.fi/hostap.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2019-08-08
|
||||
PKG_SOURCE_VERSION:=ca8c2bd28ad53f431d6ee60ef754e98cfdb4c17b
|
||||
PKG_MIRROR_HASH:=9d9f1c60afa5324ee17219bd3ec61c1a6fa4043b4187da9bb44e59025d3ed31d
|
||||
PKG_SOURCE_DATE:=2020-05-20
|
||||
PKG_SOURCE_VERSION:=dd2daf0848ed8854065cc5cfca07a0538cd380af
|
||||
PKG_MIRROR_HASH:=5f198ba4f9098e8bddb32e41f82a24d0510c6e25317a86dcfafc70fb8db260e2
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
@ -32,6 +32,7 @@ PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_DRIVER_WEXT_SUPPORT \
|
||||
CONFIG_DRIVER_11N_SUPPORT \
|
||||
CONFIG_DRIVER_11AC_SUPPORT \
|
||||
CONFIG_WPA_ENABLE_WEP
|
||||
|
||||
EAPOL_TEST_PROVIDERS:=eapol-test eapol-test-openssl eapol-test-wolfssl
|
||||
|
||||
@ -445,6 +446,10 @@ ifdef CONFIG_PACKAGE_kmod-cfg80211
|
||||
TARGET_LDFLAGS += -lm -lnl-tiny
|
||||
endif
|
||||
|
||||
ifdef CONFIG_WPA_ENABLE_WEP
|
||||
DRIVER_MAKEOPTS += CONFIG_WEP=y
|
||||
endif
|
||||
|
||||
define Build/RunMake
|
||||
CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
|
||||
$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/$(1) \
|
||||
|
@ -25,7 +25,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
--- a/src/ap/hostapd.c
|
||||
+++ b/src/ap/hostapd.c
|
||||
@@ -423,6 +423,8 @@ static void hostapd_free_hapd_data(struc
|
||||
@@ -434,6 +434,8 @@ static void hostapd_free_hapd_data(struc
|
||||
#ifdef CONFIG_MESH
|
||||
wpabuf_free(hapd->mesh_pending_auth);
|
||||
hapd->mesh_pending_auth = NULL;
|
||||
@ -34,7 +34,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
#endif /* CONFIG_MESH */
|
||||
|
||||
hostapd_clean_rrm(hapd);
|
||||
@@ -2049,6 +2051,13 @@ dfs_offload:
|
||||
@@ -2145,6 +2147,13 @@ dfs_offload:
|
||||
if (hapd->setup_complete_cb)
|
||||
hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
|
||||
|
||||
@ -48,7 +48,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
|
||||
iface->bss[0]->conf->iface);
|
||||
if (iface->interfaces && iface->interfaces->terminate_on_error > 0)
|
||||
@@ -2192,7 +2201,7 @@ int hostapd_setup_interface(struct hosta
|
||||
@@ -2288,7 +2297,7 @@ int hostapd_setup_interface(struct hosta
|
||||
ret = setup_interface(iface);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
|
||||
@ -59,7 +59,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -190,8 +190,9 @@ static int wpas_mesh_init_rsn(struct wpa
|
||||
@@ -194,8 +194,9 @@ static int wpas_mesh_init_rsn(struct wpa
|
||||
}
|
||||
|
||||
|
||||
@ -70,7 +70,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
struct hostapd_iface *ifmsh = wpa_s->ifmsh;
|
||||
struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
|
||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||
@@ -200,7 +201,7 @@ static int wpas_mesh_complete(struct wpa
|
||||
@@ -204,7 +205,7 @@ static int wpas_mesh_complete(struct wpa
|
||||
if (!params || !ssid || !ifmsh) {
|
||||
wpa_printf(MSG_ERROR, "mesh: %s called without active mesh",
|
||||
__func__);
|
||||
@ -79,7 +79,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
}
|
||||
|
||||
if (ifmsh->mconf->security != MESH_CONF_SEC_NONE &&
|
||||
@@ -209,7 +210,7 @@ static int wpas_mesh_complete(struct wpa
|
||||
@@ -213,7 +214,7 @@ static int wpas_mesh_complete(struct wpa
|
||||
"mesh: RSN initialization failed - deinit mesh");
|
||||
wpa_supplicant_mesh_deinit(wpa_s);
|
||||
wpa_drv_leave_mesh(wpa_s);
|
||||
@ -88,7 +88,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
}
|
||||
|
||||
if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
|
||||
@@ -235,8 +236,6 @@ static int wpas_mesh_complete(struct wpa
|
||||
@@ -239,8 +240,6 @@ static int wpas_mesh_complete(struct wpa
|
||||
|
||||
if (!ret)
|
||||
wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
|
||||
@ -97,15 +97,15 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
}
|
||||
|
||||
|
||||
@@ -263,6 +262,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -267,6 +266,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
if (!ifmsh)
|
||||
return -ENOMEM;
|
||||
|
||||
+ ifmsh->owner = wpa_s;
|
||||
ifmsh->drv_flags = wpa_s->drv_flags;
|
||||
ifmsh->drv_flags2 = wpa_s->drv_flags2;
|
||||
ifmsh->num_bss = 1;
|
||||
ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
|
||||
@@ -280,6 +280,8 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -285,6 +285,8 @@ static int wpa_supplicant_mesh_init(stru
|
||||
bss->drv_priv = wpa_s->drv_priv;
|
||||
bss->iface = ifmsh;
|
||||
bss->mesh_sta_free_cb = mesh_mpm_free_sta;
|
||||
@ -114,7 +114,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
frequency = ssid->frequency;
|
||||
if (frequency != freq->freq &&
|
||||
frequency == freq->freq + freq->sec_channel_offset * 20) {
|
||||
@@ -521,7 +523,6 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
@@ -526,7 +528,6 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -287,6 +287,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -292,6 +292,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
frequency == freq->freq + freq->sec_channel_offset * 20) {
|
||||
wpa_printf(MSG_DEBUG, "mesh: pri/sec channels switched");
|
||||
frequency = freq->freq;
|
||||
|
@ -16,17 +16,17 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -1477,6 +1477,7 @@ struct wpa_driver_mesh_join_params {
|
||||
@@ -1542,6 +1542,7 @@ struct wpa_driver_mesh_join_params {
|
||||
#define WPA_DRIVER_MESH_FLAG_SAE_AUTH 0x00000004
|
||||
#define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008
|
||||
unsigned int flags;
|
||||
+ u8 handle_dfs;
|
||||
};
|
||||
|
||||
/**
|
||||
struct wpa_driver_set_key_params {
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -9624,6 +9624,9 @@ static int nl80211_join_mesh(struct i802
|
||||
@@ -10038,6 +10038,9 @@ static int nl80211_join_mesh(struct i802
|
||||
|
||||
wpa_printf(MSG_DEBUG, " * flags=%08X", params->flags);
|
||||
|
||||
@ -38,7 +38,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
goto fail;
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -309,6 +309,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -314,6 +314,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
conf->country[0] = wpa_s->conf->country[0];
|
||||
conf->country[1] = wpa_s->conf->country[1];
|
||||
conf->country[2] = ' ';
|
||||
|
@ -13,7 +13,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -249,7 +249,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -253,7 +253,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
struct mesh_conf *mconf;
|
||||
int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 };
|
||||
int rate_len;
|
||||
@ -22,7 +22,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
if (!wpa_s->conf->user_mpm) {
|
||||
/* not much for us to do here */
|
||||
@@ -386,6 +386,13 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -391,6 +391,13 @@ static int wpa_supplicant_mesh_init(stru
|
||||
conf->basic_rates[rate_len] = -1;
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
if (wpa_drv_init_mesh(wpa_s)) {
|
||||
wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
|
||||
return -1;
|
||||
@@ -397,8 +404,6 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -402,8 +409,6 @@ static int wpa_supplicant_mesh_init(stru
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -13,16 +13,16 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -2153,6 +2153,8 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
struct hostapd_freq_params vht_freq;
|
||||
@@ -2345,6 +2345,8 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
int chwidth, seg0, seg1;
|
||||
u32 vht_caps = 0;
|
||||
int is_24ghz;
|
||||
+ int dfs_enabled = wpa_s->conf->country[0] &&
|
||||
+ (wpa_s->drv_flags & WPA_DRIVER_FLAGS_RADAR);
|
||||
|
||||
freq->freq = ssid->frequency;
|
||||
|
||||
@@ -2232,8 +2234,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
@@ -2432,8 +2434,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
return;
|
||||
|
||||
/* Check primary channel flags */
|
||||
@ -35,7 +35,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
freq->channel = pri_chan->chan;
|
||||
|
||||
@@ -2264,8 +2269,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
@@ -2466,8 +2471,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
return;
|
||||
|
||||
/* Check secondary channel flags */
|
||||
@ -48,7 +48,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
if (ht40 == -1) {
|
||||
if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
|
||||
@@ -2356,8 +2364,11 @@ skip_ht40:
|
||||
@@ -2560,8 +2568,11 @@ skip_ht40:
|
||||
return;
|
||||
|
||||
/* Back to HT configuration if channel not usable */
|
||||
@ -61,7 +61,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
}
|
||||
|
||||
chwidth = CHANWIDTH_80MHZ;
|
||||
@@ -2377,10 +2388,11 @@ skip_ht40:
|
||||
@@ -2581,10 +2592,11 @@ skip_ht40:
|
||||
if (!chan)
|
||||
continue;
|
||||
|
||||
|
@ -19,7 +19,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -386,6 +386,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -391,6 +391,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
conf->basic_rates[rate_len] = -1;
|
||||
}
|
||||
|
||||
|
@ -17,18 +17,18 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -7462,6 +7462,10 @@ static int wpa_driver_nl80211_send_actio
|
||||
int ret = -1;
|
||||
@@ -7788,6 +7788,10 @@ static int wpa_driver_nl80211_send_actio
|
||||
u8 *buf;
|
||||
struct ieee80211_hdr *hdr;
|
||||
int offchanok = 1;
|
||||
+ struct hostapd_hw_modes *modes;
|
||||
+ int i, offchanok = 1;
|
||||
+ int i;
|
||||
+ u16 num_modes, flags;
|
||||
+ u8 dfs_domain;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
|
||||
"freq=%u MHz wait=%d ms no_cck=%d)",
|
||||
@@ -7486,6 +7490,21 @@ static int wpa_driver_nl80211_send_actio
|
||||
if (is_ap_interface(drv->nlmode) && (int) freq == bss->freq &&
|
||||
bss->beacon_set)
|
||||
@@ -7816,6 +7820,21 @@ static int wpa_driver_nl80211_send_actio
|
||||
os_memset(bss->rand_addr, 0, ETH_ALEN);
|
||||
}
|
||||
|
||||
@ -50,12 +50,3 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
if (is_ap_interface(drv->nlmode) &&
|
||||
(!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
|
||||
(int) freq == bss->freq || drv->device_ap_sme ||
|
||||
@@ -7497,7 +7516,7 @@ static int wpa_driver_nl80211_send_actio
|
||||
ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
|
||||
24 + data_len,
|
||||
&drv->send_action_cookie,
|
||||
- no_cck, 0, 1, NULL, 0);
|
||||
+ no_cck, 0, offchanok, NULL, 0);
|
||||
|
||||
os_free(buf);
|
||||
return ret;
|
||||
|
@ -24,7 +24,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
#include "ap/sta_info.h"
|
||||
#include "ap/hostapd.h"
|
||||
#include "ap/ieee802_11.h"
|
||||
@@ -204,6 +205,32 @@ static void wpas_mesh_complete_cb(void *
|
||||
@@ -208,6 +209,34 @@ static void wpas_mesh_complete_cb(void *
|
||||
return;
|
||||
}
|
||||
|
||||
@ -39,6 +39,8 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
|
||||
+ ifmsh->conf->hw_mode,
|
||||
+ ifmsh->freq,
|
||||
+ ifmsh->conf->channel,
|
||||
+ ifmsh->conf->enable_edmg,
|
||||
+ ifmsh->conf->edmg_channel,
|
||||
+ ifmsh->conf->ieee80211n,
|
||||
+ ifmsh->conf->ieee80211ac,
|
||||
+ ifmsh->conf->ieee80211ax,
|
||||
|
@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
};
|
||||
|
||||
#define MAX_STA_COUNT 2007
|
||||
@@ -666,6 +667,7 @@ struct hostapd_bss_config {
|
||||
@@ -691,6 +692,7 @@ struct hostapd_bss_config {
|
||||
|
||||
#define MESH_ENABLED BIT(0)
|
||||
int mesh;
|
||||
@ -41,7 +41,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -1450,6 +1450,7 @@ struct wpa_driver_mesh_bss_params {
|
||||
@@ -1515,6 +1515,7 @@ struct wpa_driver_mesh_bss_params {
|
||||
#define WPA_DRIVER_MESH_CONF_FLAG_MAX_PEER_LINKS 0x00000004
|
||||
#define WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE 0x00000008
|
||||
#define WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD 0x00000010
|
||||
@ -49,7 +49,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
/*
|
||||
* TODO: Other mesh configuration parameters would go here.
|
||||
* See NL80211_MESHCONF_* for all the mesh config parameters.
|
||||
@@ -1459,6 +1460,7 @@ struct wpa_driver_mesh_bss_params {
|
||||
@@ -1524,6 +1525,7 @@ struct wpa_driver_mesh_bss_params {
|
||||
int peer_link_timeout;
|
||||
int max_peer_links;
|
||||
int rssi_threshold;
|
||||
@ -59,7 +59,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -9592,6 +9592,9 @@ static int nl80211_put_mesh_config(struc
|
||||
@@ -10006,6 +10006,9 @@ static int nl80211_put_mesh_config(struc
|
||||
if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) &&
|
||||
nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
|
||||
params->auto_plinks)) ||
|
||||
@ -71,7 +71,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
params->max_peer_links)) ||
|
||||
--- a/wpa_supplicant/config.c
|
||||
+++ b/wpa_supplicant/config.c
|
||||
@@ -2307,6 +2307,7 @@ static const struct parse_data ssid_fiel
|
||||
@@ -2473,6 +2473,7 @@ static const struct parse_data ssid_fiel
|
||||
#ifdef CONFIG_MESH
|
||||
{ INT_RANGE(mode, 0, 5) },
|
||||
{ INT_RANGE(no_auto_peer, 0, 1) },
|
||||
@ -79,7 +79,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
{ INT_RANGE(mesh_rssi_threshold, -255, 1) },
|
||||
#else /* CONFIG_MESH */
|
||||
{ INT_RANGE(mode, 0, 4) },
|
||||
@@ -2869,6 +2870,7 @@ void wpa_config_set_network_defaults(str
|
||||
@@ -3046,6 +3047,7 @@ void wpa_config_set_network_defaults(str
|
||||
ssid->dot11MeshRetryTimeout = DEFAULT_MESH_RETRY_TIMEOUT;
|
||||
ssid->dot11MeshConfirmTimeout = DEFAULT_MESH_CONFIRM_TIMEOUT;
|
||||
ssid->dot11MeshHoldingTimeout = DEFAULT_MESH_HOLDING_TIMEOUT;
|
||||
@ -87,7 +87,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
ssid->mesh_rssi_threshold = DEFAULT_MESH_RSSI_THRESHOLD;
|
||||
#endif /* CONFIG_MESH */
|
||||
#ifdef CONFIG_HT_OVERRIDES
|
||||
@@ -4089,6 +4091,7 @@ struct wpa_config * wpa_config_alloc_emp
|
||||
@@ -4273,6 +4275,7 @@ struct wpa_config * wpa_config_alloc_emp
|
||||
config->user_mpm = DEFAULT_USER_MPM;
|
||||
config->max_peer_links = DEFAULT_MAX_PEER_LINKS;
|
||||
config->mesh_max_inactivity = DEFAULT_MESH_MAX_INACTIVITY;
|
||||
@ -95,7 +95,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
config->dot11RSNASAERetransPeriod =
|
||||
DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD;
|
||||
config->fast_reauth = DEFAULT_FAST_REAUTH;
|
||||
@@ -4726,6 +4729,7 @@ static const struct global_parse_data gl
|
||||
@@ -4911,6 +4914,7 @@ static const struct global_parse_data gl
|
||||
{ INT(user_mpm), 0 },
|
||||
{ INT_RANGE(max_peer_links, 0, 255), 0 },
|
||||
{ INT(mesh_max_inactivity), 0 },
|
||||
@ -113,7 +113,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
/*
|
||||
* The default dot11RSNASAERetransPeriod is defined as 40 ms in the standard,
|
||||
* but use 1000 ms in practice to avoid issues on low power CPUs.
|
||||
@@ -1327,6 +1328,14 @@ struct wpa_config {
|
||||
@@ -1351,6 +1352,14 @@ struct wpa_config {
|
||||
int mesh_max_inactivity;
|
||||
|
||||
/**
|
||||
@ -130,15 +130,15 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
* This timeout value is used in mesh STA to retransmit
|
||||
--- a/wpa_supplicant/config_file.c
|
||||
+++ b/wpa_supplicant/config_file.c
|
||||
@@ -829,6 +829,7 @@ static void wpa_config_write_network(FIL
|
||||
@@ -866,6 +866,7 @@ static void wpa_config_write_network(FIL
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
INT(mode);
|
||||
INT(no_auto_peer);
|
||||
+ INT(mesh_fwding);
|
||||
INT(frequency);
|
||||
INT(fixed_freq);
|
||||
#ifdef CONFIG_ACS
|
||||
@@ -1472,6 +1473,9 @@ static void wpa_config_write_global(FILE
|
||||
INT(enable_edmg);
|
||||
INT(edmg_channel);
|
||||
@@ -1526,6 +1527,9 @@ static void wpa_config_write_global(FILE
|
||||
fprintf(f, "mesh_max_inactivity=%d\n",
|
||||
config->mesh_max_inactivity);
|
||||
|
||||
@ -150,7 +150,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
fprintf(f, "dot11RSNASAERetransPeriod=%d\n",
|
||||
--- a/wpa_supplicant/config_ssid.h
|
||||
+++ b/wpa_supplicant/config_ssid.h
|
||||
@@ -516,6 +516,11 @@ struct wpa_ssid {
|
||||
@@ -540,6 +540,11 @@ struct wpa_ssid {
|
||||
int dot11MeshConfirmTimeout; /* msec */
|
||||
int dot11MeshHoldingTimeout; /* msec */
|
||||
|
||||
@ -164,7 +164,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -126,6 +126,7 @@ static struct mesh_conf * mesh_config_cr
|
||||
@@ -130,6 +130,7 @@ static struct mesh_conf * mesh_config_cr
|
||||
conf->mesh_cc_id = 0;
|
||||
conf->mesh_sp_id = MESH_SYNC_METHOD_NEIGHBOR_OFFSET;
|
||||
conf->mesh_auth_id = (conf->security & MESH_CONF_SEC_AUTH) ? 1 : 0;
|
||||
@ -172,7 +172,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
conf->dot11MeshMaxRetries = ssid->dot11MeshMaxRetries;
|
||||
conf->dot11MeshRetryTimeout = ssid->dot11MeshRetryTimeout;
|
||||
conf->dot11MeshConfirmTimeout = ssid->dot11MeshConfirmTimeout;
|
||||
@@ -328,6 +329,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -335,6 +336,7 @@ static int wpa_supplicant_mesh_init(stru
|
||||
bss->conf->start_disabled = 1;
|
||||
bss->conf->mesh = MESH_ENABLED;
|
||||
bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
|
||||
@ -180,7 +180,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
|
||||
wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
|
||||
@@ -549,6 +551,10 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
@@ -556,6 +558,10 @@ int wpa_supplicant_join_mesh(struct wpa_
|
||||
}
|
||||
params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
|
||||
|
||||
@ -193,7 +193,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms->freq)) {
|
||||
--- a/wpa_supplicant/mesh_mpm.c
|
||||
+++ b/wpa_supplicant/mesh_mpm.c
|
||||
@@ -305,9 +305,9 @@ static void mesh_mpm_send_plink_action(s
|
||||
@@ -303,9 +303,9 @@ static void mesh_mpm_send_plink_action(s
|
||||
info = (bss->num_plinks > 63 ? 63 : bss->num_plinks) << 1;
|
||||
/* TODO: Add Connected to Mesh Gate/AS subfields */
|
||||
wpabuf_put_u8(buf, info);
|
||||
@ -207,7 +207,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
wpabuf_put_u8(buf, WLAN_EID_MESH_ID);
|
||||
--- a/wpa_supplicant/wpa_supplicant.conf
|
||||
+++ b/wpa_supplicant/wpa_supplicant.conf
|
||||
@@ -153,6 +153,9 @@ ap_scan=1
|
||||
@@ -150,6 +150,9 @@ ap_scan=1
|
||||
# This timeout value is used in mesh STA to clean up inactive stations.
|
||||
#mesh_max_inactivity=300
|
||||
|
||||
|
@ -1,34 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 12 Feb 2019 14:22:43 +0100
|
||||
Subject: [PATCH v2] wpa_supplicant: fix race condition in mesh mpm new peer
|
||||
handling
|
||||
|
||||
When wpa_supplicant receives another new peer event before the first one
|
||||
has been processed, it tries to add a station to the driver a second time
|
||||
(which fails) and then tears down the station entry until another event
|
||||
comes in.
|
||||
Fix this by only adding a station to the driver if it didn't exist already.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/wpa_supplicant/mesh_mpm.c
|
||||
+++ b/wpa_supplicant/mesh_mpm.c
|
||||
@@ -710,11 +710,12 @@ static struct sta_info * mesh_mpm_add_pe
|
||||
}
|
||||
|
||||
sta = ap_get_sta(data, addr);
|
||||
- if (!sta) {
|
||||
- sta = ap_sta_add(data, addr);
|
||||
- if (!sta)
|
||||
- return NULL;
|
||||
- }
|
||||
+ if (sta)
|
||||
+ return NULL;
|
||||
+
|
||||
+ sta = ap_sta_add(data, addr);
|
||||
+ if (!sta)
|
||||
+ return NULL;
|
||||
|
||||
/* Set WMM by default since Mesh STAs are QoS STAs */
|
||||
sta->flags |= WLAN_STA_WMM;
|
@ -1,66 +0,0 @@
|
||||
From 8c07fa9eda13e835f3f968b2e1c9a8be3a851ff9 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Thu, 29 Aug 2019 11:52:04 +0300
|
||||
Subject: [PATCH] AP: Silently ignore management frame from unexpected source
|
||||
address
|
||||
|
||||
Do not process any received Management frames with unexpected/invalid SA
|
||||
so that we do not add any state for unexpected STA addresses or end up
|
||||
sending out frames to unexpected destination. This prevents unexpected
|
||||
sequences where an unprotected frame might end up causing the AP to send
|
||||
out a response to another device and that other device processing the
|
||||
unexpected response.
|
||||
|
||||
In particular, this prevents some potential denial of service cases
|
||||
where the unexpected response frame from the AP might result in a
|
||||
connected station dropping its association.
|
||||
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
---
|
||||
src/ap/drv_callbacks.c | 13 +++++++++++++
|
||||
src/ap/ieee802_11.c | 12 ++++++++++++
|
||||
2 files changed, 25 insertions(+)
|
||||
|
||||
--- a/src/ap/drv_callbacks.c
|
||||
+++ b/src/ap/drv_callbacks.c
|
||||
@@ -131,6 +131,19 @@ int hostapd_notif_assoc(struct hostapd_d
|
||||
"hostapd_notif_assoc: Skip event with no address");
|
||||
return -1;
|
||||
}
|
||||
+
|
||||
+ if (is_multicast_ether_addr(addr) ||
|
||||
+ is_zero_ether_addr(addr) ||
|
||||
+ os_memcmp(addr, hapd->own_addr, ETH_ALEN) == 0) {
|
||||
+ /* Do not process any frames with unexpected/invalid SA so that
|
||||
+ * we do not add any state for unexpected STA addresses or end
|
||||
+ * up sending out frames to unexpected destination. */
|
||||
+ wpa_printf(MSG_DEBUG, "%s: Invalid SA=" MACSTR
|
||||
+ " in received indication - ignore this indication silently",
|
||||
+ __func__, MAC2STR(addr));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
random_add_randomness(addr, ETH_ALEN);
|
||||
|
||||
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -4626,6 +4626,18 @@ int ieee802_11_mgmt(struct hostapd_data
|
||||
fc = le_to_host16(mgmt->frame_control);
|
||||
stype = WLAN_FC_GET_STYPE(fc);
|
||||
|
||||
+ if (is_multicast_ether_addr(mgmt->sa) ||
|
||||
+ is_zero_ether_addr(mgmt->sa) ||
|
||||
+ os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
|
||||
+ /* Do not process any frames with unexpected/invalid SA so that
|
||||
+ * we do not add any state for unexpected STA addresses or end
|
||||
+ * up sending out frames to unexpected destination. */
|
||||
+ wpa_printf(MSG_DEBUG, "MGMT: Invalid SA=" MACSTR
|
||||
+ " in received frame - ignore this frame silently",
|
||||
+ MAC2STR(mgmt->sa));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
if (stype == WLAN_FC_STYPE_BEACON) {
|
||||
handle_beacon(hapd, mgmt, len, fi);
|
||||
return 1;
|
@ -1,41 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Thu, 23 Jan 2020 13:50:47 +0100
|
||||
Subject: [PATCH] driver_nl80211: fix WMM queue mapping for regulatory
|
||||
limit
|
||||
|
||||
nl80211 uses a different queue mapping from hostap, so AC indexes need to
|
||||
be converted.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/src/drivers/driver_nl80211_capa.c
|
||||
+++ b/src/drivers/driver_nl80211_capa.c
|
||||
@@ -1403,6 +1403,12 @@ static void phy_info_freq(struct hostapd
|
||||
[NL80211_WMMR_AIFSN] = { .type = NLA_U8 },
|
||||
[NL80211_WMMR_TXOP] = { .type = NLA_U16 },
|
||||
};
|
||||
+ static const u8 wmm_map[4] = {
|
||||
+ [NL80211_AC_BE] = WMM_AC_BE,
|
||||
+ [NL80211_AC_BK] = WMM_AC_BK,
|
||||
+ [NL80211_AC_VI] = WMM_AC_VI,
|
||||
+ [NL80211_AC_VO] = WMM_AC_VO,
|
||||
+ };
|
||||
struct nlattr *nl_wmm;
|
||||
struct nlattr *tb_wmm[NL80211_WMMR_MAX + 1];
|
||||
int rem_wmm, ac, count = 0;
|
||||
@@ -1424,12 +1430,13 @@ static void phy_info_freq(struct hostapd
|
||||
return;
|
||||
}
|
||||
ac = nl_wmm->nla_type;
|
||||
- if (ac < 0 || ac >= WMM_AC_NUM) {
|
||||
+ if (ac >= ARRAY_SIZE(wmm_map)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Invalid AC value %d", ac);
|
||||
return;
|
||||
}
|
||||
|
||||
+ ac = wmm_map[ac];
|
||||
chan->wmm_rules[ac].min_cwmin =
|
||||
nla_get_u16(tb_wmm[NL80211_WMMR_CW_MIN]);
|
||||
chan->wmm_rules[ac].min_cwmax =
|
@ -1,47 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Thu, 23 Jan 2020 14:10:20 +0100
|
||||
Subject: [PATCH] driver_nl80211: fix regulatory limits for wmm cwmin/cwmax
|
||||
values
|
||||
|
||||
The internal WMM AC parameters use just the exponent of the CW value, while
|
||||
nl80211 reports the full CW value.
|
||||
This led to completely bogus CWmin/CWmax values in the WMM IE when a regulatory
|
||||
limit was present. Fix this by converting the value to the exponent before
|
||||
passing it on
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/src/drivers/driver_nl80211_capa.c
|
||||
+++ b/src/drivers/driver_nl80211_capa.c
|
||||
@@ -1336,6 +1336,18 @@ static void phy_info_vht_capa(struct hos
|
||||
}
|
||||
}
|
||||
|
||||
+static inline int cw2ecw(unsigned int cw)
|
||||
+{
|
||||
+ int bit;
|
||||
+
|
||||
+ if (cw == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ for (bit = 1; cw != 1; bit++)
|
||||
+ cw >>= 1;
|
||||
+
|
||||
+ return bit;
|
||||
+}
|
||||
|
||||
static void phy_info_freq(struct hostapd_hw_modes *mode,
|
||||
struct hostapd_channel_data *chan,
|
||||
@@ -1438,9 +1450,9 @@ static void phy_info_freq(struct hostapd
|
||||
|
||||
ac = wmm_map[ac];
|
||||
chan->wmm_rules[ac].min_cwmin =
|
||||
- nla_get_u16(tb_wmm[NL80211_WMMR_CW_MIN]);
|
||||
+ cw2ecw(nla_get_u16(tb_wmm[NL80211_WMMR_CW_MIN]));
|
||||
chan->wmm_rules[ac].min_cwmax =
|
||||
- nla_get_u16(tb_wmm[NL80211_WMMR_CW_MAX]);
|
||||
+ cw2ecw(nla_get_u16(tb_wmm[NL80211_WMMR_CW_MAX]));
|
||||
chan->wmm_rules[ac].min_aifs =
|
||||
nla_get_u8(tb_wmm[NL80211_WMMR_AIFSN]);
|
||||
chan->wmm_rules[ac].max_txop =
|
@ -1,26 +0,0 @@
|
||||
From 1766e608ba1114220f3b3598e77aa53b50c38a6e Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <jouni@codeaurora.org>
|
||||
Date: Mon, 14 Oct 2019 19:27:47 +0300
|
||||
Subject: [PATCH] wolfSSL: Fix crypto_bignum_sub()
|
||||
|
||||
The initial crypto wrapper implementation for wolfSSL seems to have
|
||||
included a copy-paste error in crypto_bignum_sub() implementation that
|
||||
was identical to crypto_bignum_add() while mp_sub() should have been
|
||||
used instead of mp_add().
|
||||
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
---
|
||||
src/crypto/crypto_wolfssl.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/src/crypto/crypto_wolfssl.c
|
||||
+++ b/src/crypto/crypto_wolfssl.c
|
||||
@@ -1151,7 +1151,7 @@ int crypto_bignum_sub(const struct crypt
|
||||
if (TEST_FAIL())
|
||||
return -1;
|
||||
|
||||
- return mp_add((mp_int *) a, (mp_int *) b,
|
||||
+ return mp_sub((mp_int *) a, (mp_int *) b,
|
||||
(mp_int *) r) == MP_OKAY ? 0 : -1;
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 6a28c4dbc102de3fed9db44637f47a10e7adfb78 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Sat, 16 May 2020 21:01:51 +0300
|
||||
Subject: [PATCH 1/3] wolfssl: Fix compiler warnings on size_t printf format
|
||||
use
|
||||
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
---
|
||||
src/crypto/tls_wolfssl.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/src/crypto/tls_wolfssl.c
|
||||
+++ b/src/crypto/tls_wolfssl.c
|
||||
@@ -1741,7 +1741,7 @@ struct wpabuf * tls_connection_encrypt(v
|
||||
if (!conn)
|
||||
return NULL;
|
||||
|
||||
- wpa_printf(MSG_DEBUG, "SSL: encrypt: %ld bytes", wpabuf_len(in_data));
|
||||
+ wpa_printf(MSG_DEBUG, "SSL: encrypt: %zu bytes", wpabuf_len(in_data));
|
||||
|
||||
wolfssl_reset_out_data(&conn->output);
|
||||
|
||||
@@ -1792,7 +1792,7 @@ struct wpabuf * tls_connection_decrypt(v
|
||||
}
|
||||
wpabuf_put(buf, res);
|
||||
|
||||
- wpa_printf(MSG_DEBUG, "SSL: decrypt: %ld bytes", wpabuf_len(buf));
|
||||
+ wpa_printf(MSG_DEBUG, "SSL: decrypt: %zu bytes", wpabuf_len(buf));
|
||||
|
||||
return buf;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
From eb595b3e3ab531645a5bde71cf6385335b7a4b95 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Sat, 16 May 2020 21:02:17 +0300
|
||||
Subject: [PATCH 2/3] wolfssl: Fix crypto_bignum_rand() implementation
|
||||
|
||||
The previous implementation used mp_rand_prime() to generate a random
|
||||
value in range 0..m. That is insanely slow way of generating a random
|
||||
value since mp_rand_prime() is for generating a random _prime_ which is
|
||||
not what is needed here. Replace that implementation with generationg of
|
||||
a random value in the requested range without doing any kind of prime
|
||||
number checks or loops to reject values that are not primes.
|
||||
|
||||
This speeds up SAE and EAP-pwd routines by couple of orders of
|
||||
magnitude..
|
||||
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
---
|
||||
src/crypto/crypto_wolfssl.c | 12 +++++++-----
|
||||
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/src/crypto/crypto_wolfssl.c
|
||||
+++ b/src/crypto/crypto_wolfssl.c
|
||||
@@ -1084,19 +1084,21 @@ int crypto_bignum_rand(struct crypto_big
|
||||
{
|
||||
int ret = 0;
|
||||
WC_RNG rng;
|
||||
+ size_t len;
|
||||
+ u8 *buf;
|
||||
|
||||
if (TEST_FAIL())
|
||||
return -1;
|
||||
if (wc_InitRng(&rng) != 0)
|
||||
return -1;
|
||||
- if (mp_rand_prime((mp_int *) r,
|
||||
- (mp_count_bits((mp_int *) m) + 7) / 8 * 2,
|
||||
- &rng, NULL) != 0)
|
||||
- ret = -1;
|
||||
- if (ret == 0 &&
|
||||
+ len = (mp_count_bits((mp_int *) m) + 7) / 8;
|
||||
+ buf = os_malloc(len);
|
||||
+ if (!buf || wc_RNG_GenerateBlock(&rng, buf, len) != 0 ||
|
||||
+ mp_read_unsigned_bin((mp_int *) r, buf, len) != MP_OKAY ||
|
||||
mp_mod((mp_int *) r, (mp_int *) m, (mp_int *) r) != 0)
|
||||
ret = -1;
|
||||
wc_FreeRng(&rng);
|
||||
+ bin_clear_free(buf, len);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
From 79488da576aeeb9400e1742fab7f463eed0fa7a1 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Sat, 16 May 2020 21:07:45 +0300
|
||||
Subject: [PATCH 3/3] wolfssl: Do not hardcode include directory in
|
||||
wpa_supplicant build
|
||||
|
||||
This is not really appropriate for any kind of cross compilations and is
|
||||
not really needed in general since system specific values can be set in
|
||||
.config.
|
||||
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
---
|
||||
wpa_supplicant/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/wpa_supplicant/Makefile
|
||||
+++ b/wpa_supplicant/Makefile
|
||||
@@ -1086,7 +1086,7 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_TLS), wolfssl)
|
||||
ifdef TLS_FUNCS
|
||||
-CFLAGS += -DWOLFSSL_DER_LOAD -I/usr/local/include/wolfssl
|
||||
+CFLAGS += -DWOLFSSL_DER_LOAD
|
||||
OBJS += ../src/crypto/tls_wolfssl.o
|
||||
endif
|
||||
OBJS += ../src/crypto/crypto_wolfssl.o
|
@ -8,7 +8,7 @@
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <sys/capability.h>
|
||||
@@ -182,59 +183,46 @@ int os_gmtime(os_time_t t, struct os_tm
|
||||
@@ -188,59 +189,46 @@ int os_gmtime(os_time_t t, struct os_tm
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
ifndef CONFIG_NO_GITVER
|
||||
# Add VERSION_STR postfix for builds from a git repository
|
||||
@@ -198,7 +199,8 @@ endif
|
||||
@@ -200,7 +201,8 @@ endif
|
||||
|
||||
ifdef CONFIG_NO_VLAN
|
||||
CFLAGS += -DCONFIG_NO_VLAN
|
||||
@ -18,7 +18,7 @@
|
||||
OBJS += ../src/ap/vlan_init.o
|
||||
OBJS += ../src/ap/vlan_ifconfig.o
|
||||
OBJS += ../src/ap/vlan.o
|
||||
@@ -366,10 +368,14 @@ CFLAGS += -DCONFIG_MBO
|
||||
@@ -346,10 +348,14 @@ CFLAGS += -DCONFIG_MBO
|
||||
OBJS += ../src/ap/mbo_ap.o
|
||||
endif
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
LIBS += $(DRV_AP_LIBS)
|
||||
|
||||
ifdef CONFIG_L2_PACKET
|
||||
@@ -1316,6 +1322,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR)
|
||||
@@ -1300,6 +1306,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR)
|
||||
|
||||
BCHECK=../src/drivers/build.hostapd
|
||||
|
||||
@ -49,7 +49,7 @@
|
||||
hostapd: $(BCHECK) $(OBJS)
|
||||
$(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
|
||||
@$(E) " LD " $@
|
||||
@@ -1358,6 +1370,12 @@ ifeq ($(CONFIG_TLS), linux)
|
||||
@@ -1341,6 +1353,12 @@ ifeq ($(CONFIG_TLS), linux)
|
||||
HOBJS += ../src/crypto/crypto_linux.o
|
||||
endif
|
||||
|
||||
@ -72,7 +72,7 @@
|
||||
|
||||
ifndef CONFIG_NO_GITVER
|
||||
# Add VERSION_STR postfix for builds from a git repository
|
||||
@@ -363,7 +364,9 @@ endif
|
||||
@@ -365,7 +366,9 @@ endif
|
||||
ifdef CONFIG_IBSS_RSN
|
||||
NEED_RSN_AUTHENTICATOR=y
|
||||
CFLAGS += -DCONFIG_IBSS_RSN
|
||||
@ -82,7 +82,7 @@
|
||||
OBJS += ibss_rsn.o
|
||||
endif
|
||||
|
||||
@@ -892,6 +895,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS
|
||||
@@ -886,6 +889,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS
|
||||
CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS
|
||||
LIBS += -ldl -rdynamic
|
||||
endif
|
||||
@ -93,7 +93,7 @@
|
||||
endif
|
||||
|
||||
ifdef CONFIG_AP
|
||||
@@ -899,9 +906,11 @@ NEED_EAP_COMMON=y
|
||||
@@ -893,9 +900,11 @@ NEED_EAP_COMMON=y
|
||||
NEED_RSN_AUTHENTICATOR=y
|
||||
CFLAGS += -DCONFIG_AP
|
||||
OBJS += ap.o
|
||||
@ -105,7 +105,7 @@
|
||||
OBJS += ../src/ap/hostapd.o
|
||||
OBJS += ../src/ap/wpa_auth_glue.o
|
||||
OBJS += ../src/ap/utils.o
|
||||
@@ -983,6 +992,12 @@ endif
|
||||
@@ -975,6 +984,12 @@ endif
|
||||
ifdef CONFIG_HS20
|
||||
OBJS += ../src/ap/hs20.o
|
||||
endif
|
||||
@ -118,7 +118,7 @@
|
||||
endif
|
||||
|
||||
ifdef CONFIG_MBO
|
||||
@@ -991,7 +1006,9 @@ CFLAGS += -DCONFIG_MBO
|
||||
@@ -983,7 +998,9 @@ CFLAGS += -DCONFIG_MBO
|
||||
endif
|
||||
|
||||
ifdef NEED_RSN_AUTHENTICATOR
|
||||
@ -128,7 +128,7 @@
|
||||
NEED_AES_WRAP=y
|
||||
OBJS += ../src/ap/wpa_auth.o
|
||||
OBJS += ../src/ap/wpa_auth_ie.o
|
||||
@@ -1899,6 +1916,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
|
||||
@@ -1893,6 +1910,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
|
||||
|
||||
$(OBJS_c) $(OBJS_t) $(OBJS_t2) $(OBJS) $(BCHECK) $(EXTRA_progs): .config
|
||||
|
||||
@ -141,7 +141,7 @@
|
||||
wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
|
||||
$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS)
|
||||
@$(E) " LD " $@
|
||||
@@ -1999,6 +2022,12 @@ endif
|
||||
@@ -1993,6 +2016,12 @@ endif
|
||||
$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
|
||||
@$(E) " sed" $<
|
||||
|
||||
@ -156,7 +156,7 @@
|
||||
wpa_cli.exe: wpa_cli
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -5657,8 +5657,8 @@ union wpa_event_data {
|
||||
@@ -5879,8 +5879,8 @@ union wpa_event_data {
|
||||
* Driver wrapper code should call this function whenever an event is received
|
||||
* from the driver.
|
||||
*/
|
||||
@ -167,7 +167,7 @@
|
||||
|
||||
/**
|
||||
* wpa_supplicant_event_global - Report a driver event for wpa_supplicant
|
||||
@@ -5670,7 +5670,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
@@ -5892,7 +5892,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
* Same as wpa_supplicant_event(), but we search for the interface in
|
||||
* wpa_global.
|
||||
*/
|
||||
@ -178,7 +178,7 @@
|
||||
/*
|
||||
--- a/src/ap/drv_callbacks.c
|
||||
+++ b/src/ap/drv_callbacks.c
|
||||
@@ -1669,8 +1669,8 @@ err:
|
||||
@@ -1768,8 +1768,8 @@ err:
|
||||
#endif /* CONFIG_OWE */
|
||||
|
||||
|
||||
@ -189,7 +189,7 @@
|
||||
{
|
||||
struct hostapd_data *hapd = ctx;
|
||||
#ifndef CONFIG_NO_STDOUT_DEBUG
|
||||
@@ -1915,7 +1915,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
@@ -2014,7 +2014,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
}
|
||||
|
||||
|
||||
@ -200,7 +200,7 @@
|
||||
struct hapd_interfaces *interfaces = ctx;
|
||||
--- a/wpa_supplicant/wpa_priv.c
|
||||
+++ b/wpa_supplicant/wpa_priv.c
|
||||
@@ -1031,8 +1031,8 @@ static void wpa_priv_send_ft_response(st
|
||||
@@ -1038,8 +1038,8 @@ static void wpa_priv_send_ft_response(st
|
||||
}
|
||||
|
||||
|
||||
@ -211,7 +211,7 @@
|
||||
{
|
||||
struct wpa_priv_interface *iface = ctx;
|
||||
|
||||
@@ -1095,7 +1095,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
@@ -1102,7 +1102,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
}
|
||||
|
||||
|
||||
@ -220,7 +220,7 @@
|
||||
union wpa_event_data *data)
|
||||
{
|
||||
struct wpa_priv_global *global = ctx;
|
||||
@@ -1207,6 +1207,8 @@ int main(int argc, char *argv[])
|
||||
@@ -1215,6 +1215,8 @@ int main(int argc, char *argv[])
|
||||
if (os_program_init())
|
||||
return -1;
|
||||
|
||||
@ -231,7 +231,7 @@
|
||||
os_memset(&global, 0, sizeof(global));
|
||||
--- a/wpa_supplicant/events.c
|
||||
+++ b/wpa_supplicant/events.c
|
||||
@@ -4184,8 +4184,8 @@ static void wpas_event_assoc_reject(stru
|
||||
@@ -4500,8 +4500,8 @@ static void wpas_event_unprot_beacon(str
|
||||
}
|
||||
|
||||
|
||||
@ -242,7 +242,7 @@
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = ctx;
|
||||
int resched;
|
||||
@@ -4967,7 +4967,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
@@ -5319,7 +5319,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
}
|
||||
|
||||
|
||||
@ -253,7 +253,7 @@
|
||||
struct wpa_supplicant *wpa_s;
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -6096,7 +6096,6 @@ struct wpa_interface * wpa_supplicant_ma
|
||||
@@ -6593,7 +6593,6 @@ struct wpa_interface * wpa_supplicant_ma
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@
|
||||
/**
|
||||
* wpa_supplicant_match_existing - Match existing interfaces
|
||||
* @global: Pointer to global data from wpa_supplicant_init()
|
||||
@@ -6133,6 +6132,11 @@ static int wpa_supplicant_match_existing
|
||||
@@ -6630,6 +6629,11 @@ static int wpa_supplicant_match_existing
|
||||
|
||||
#endif /* CONFIG_MATCH_IFACE */
|
||||
|
||||
@ -273,7 +273,7 @@
|
||||
|
||||
/**
|
||||
* wpa_supplicant_add_iface - Add a new network interface
|
||||
@@ -6389,6 +6393,8 @@ struct wpa_global * wpa_supplicant_init(
|
||||
@@ -6886,6 +6890,8 @@ struct wpa_global * wpa_supplicant_init(
|
||||
#ifndef CONFIG_NO_WPA_MSG
|
||||
wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
|
||||
#endif /* CONFIG_NO_WPA_MSG */
|
||||
@ -284,7 +284,7 @@
|
||||
wpa_debug_open_file(params->wpa_debug_file_path);
|
||||
--- a/hostapd/main.c
|
||||
+++ b/hostapd/main.c
|
||||
@@ -592,6 +592,11 @@ fail:
|
||||
@@ -590,6 +590,11 @@ fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -296,7 +296,7 @@
|
||||
|
||||
#ifdef CONFIG_WPS
|
||||
static int gen_uuid(const char *txt_addr)
|
||||
@@ -682,6 +687,8 @@ int main(int argc, char *argv[])
|
||||
@@ -684,6 +689,8 @@ int main(int argc, char *argv[])
|
||||
return -1;
|
||||
#endif /* CONFIG_DPP */
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -3411,6 +3411,10 @@ static int hostapd_config_fill(struct ho
|
||||
@@ -3452,6 +3452,10 @@ static int hostapd_config_fill(struct ho
|
||||
if (bss->ocv && !bss->ieee80211w)
|
||||
bss->ieee80211w = 1;
|
||||
#endif /* CONFIG_OCV */
|
||||
#ifdef CONFIG_IEEE80211N
|
||||
+ } else if (os_strcmp(buf, "noscan") == 0) {
|
||||
+ conf->noscan = atoi(pos);
|
||||
+ } else if (os_strcmp(buf, "ht_coex") == 0) {
|
||||
@ -13,7 +13,7 @@
|
||||
} else if (os_strcmp(buf, "ht_capab") == 0) {
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -934,6 +934,8 @@ struct hostapd_config {
|
||||
@@ -974,6 +974,8 @@ struct hostapd_config {
|
||||
|
||||
int ht_op_mode_fixed;
|
||||
u16 ht_capab;
|
||||
@ -24,7 +24,7 @@
|
||||
int no_pri_sec_switch;
|
||||
--- a/src/ap/hw_features.c
|
||||
+++ b/src/ap/hw_features.c
|
||||
@@ -477,7 +477,8 @@ static int ieee80211n_check_40mhz(struct
|
||||
@@ -500,7 +500,8 @@ static int ieee80211n_check_40mhz(struct
|
||||
int ret;
|
||||
|
||||
/* Check that HT40 is used and PRI / SEC switch is allowed */
|
||||
@ -36,7 +36,7 @@
|
||||
hostapd_set_state(iface, HAPD_IFACE_HT_SCAN);
|
||||
--- a/src/ap/ieee802_11_ht.c
|
||||
+++ b/src/ap/ieee802_11_ht.c
|
||||
@@ -252,6 +252,9 @@ void hostapd_2040_coex_action(struct hos
|
||||
@@ -230,6 +230,9 @@ void hostapd_2040_coex_action(struct hos
|
||||
return;
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Ignore too short 20/40 BSS Coexistence Management frame");
|
||||
@@ -412,6 +415,9 @@ void ht40_intolerant_add(struct hostapd_
|
||||
@@ -390,6 +393,9 @@ void ht40_intolerant_add(struct hostapd_
|
||||
if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
|
||||
return;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/wpa_supplicant/config.c
|
||||
+++ b/wpa_supplicant/config.c
|
||||
@@ -2312,6 +2312,7 @@ static const struct parse_data ssid_fiel
|
||||
@@ -2478,6 +2478,7 @@ static const struct parse_data ssid_fiel
|
||||
#else /* CONFIG_MESH */
|
||||
{ INT_RANGE(mode, 0, 4) },
|
||||
#endif /* CONFIG_MESH */
|
||||
@ -10,17 +10,17 @@
|
||||
{ STR(id_str) },
|
||||
--- a/wpa_supplicant/config_file.c
|
||||
+++ b/wpa_supplicant/config_file.c
|
||||
@@ -829,6 +829,7 @@ static void wpa_config_write_network(FIL
|
||||
@@ -866,6 +866,7 @@ static void wpa_config_write_network(FIL
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
INT(mode);
|
||||
INT(no_auto_peer);
|
||||
+ INT(noscan);
|
||||
INT(mesh_fwding);
|
||||
INT(frequency);
|
||||
INT(fixed_freq);
|
||||
INT(enable_edmg);
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -361,6 +361,8 @@ static int wpa_supplicant_mesh_init(stru
|
||||
@@ -368,6 +368,8 @@ static int wpa_supplicant_mesh_init(stru
|
||||
frequency);
|
||||
goto out_free;
|
||||
}
|
||||
@ -31,7 +31,7 @@
|
||||
if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A && ssid->vht) {
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -2143,12 +2143,12 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
@@ -2334,12 +2334,12 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode);
|
||||
enum hostapd_hw_mode hw_mode;
|
||||
struct hostapd_hw_modes *mode = NULL;
|
||||
@ -46,8 +46,8 @@
|
||||
unsigned int j, k;
|
||||
struct hostapd_freq_params vht_freq;
|
||||
int chwidth, seg0, seg1;
|
||||
@@ -2221,7 +2221,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
return;
|
||||
@@ -2421,7 +2421,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
#endif /* CONFIG_HE_OVERRIDES */
|
||||
|
||||
/* Setup higher BW only for 5 GHz */
|
||||
- if (mode->mode != HOSTAPD_MODE_IEEE80211A)
|
||||
@ -57,7 +57,7 @@
|
||||
for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
|
||||
--- a/wpa_supplicant/config_ssid.h
|
||||
+++ b/wpa_supplicant/config_ssid.h
|
||||
@@ -918,6 +918,8 @@ struct wpa_ssid {
|
||||
@@ -965,6 +965,8 @@ struct wpa_ssid {
|
||||
*/
|
||||
int no_auto_peer;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -4474,7 +4474,7 @@ wpa_supplicant_alloc(struct wpa_supplica
|
||||
@@ -4948,7 +4948,7 @@ wpa_supplicant_alloc(struct wpa_supplica
|
||||
if (wpa_s == NULL)
|
||||
return NULL;
|
||||
wpa_s->scan_req = INITIAL_SCAN_REQ;
|
||||
|
@ -24,7 +24,7 @@
|
||||
endif
|
||||
|
||||
ifdef NEED_NETLINK
|
||||
@@ -146,6 +143,7 @@ endif
|
||||
@@ -142,6 +139,7 @@ endif
|
||||
|
||||
ifdef NEED_RFKILL
|
||||
DRV_OBJS += ../src/drivers/rfkill.o
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -4431,7 +4431,7 @@ static int nl80211_set_channel(struct i8
|
||||
@@ -4645,7 +4645,7 @@ static int nl80211_set_channel(struct i8
|
||||
freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled,
|
||||
freq->bandwidth, freq->center_freq1, freq->center_freq2);
|
||||
|
||||
|
@ -1,12 +1,14 @@
|
||||
--- a/src/ap/hostapd.c
|
||||
+++ b/src/ap/hostapd.c
|
||||
@@ -108,6 +108,26 @@ static void hostapd_reload_bss(struct ho
|
||||
@@ -114,6 +114,28 @@ static void hostapd_reload_bss(struct ho
|
||||
#endif /* CONFIG_NO_RADIUS */
|
||||
|
||||
ssid = &hapd->conf->ssid;
|
||||
+
|
||||
+ hostapd_set_freq(hapd, hapd->iconf->hw_mode, hapd->iface->freq,
|
||||
+ hapd->iconf->channel,
|
||||
+ hapd->iconf->enable_edmg,
|
||||
+ hapd->iconf->edmg_channel,
|
||||
+ hapd->iconf->ieee80211n,
|
||||
+ hapd->iconf->ieee80211ac,
|
||||
+ hapd->iconf->ieee80211ax,
|
||||
@ -27,7 +29,7 @@
|
||||
if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next &&
|
||||
ssid->wpa_passphrase_set && ssid->wpa_passphrase) {
|
||||
/*
|
||||
@@ -205,6 +225,7 @@ int hostapd_reload_config(struct hostapd
|
||||
@@ -215,6 +237,7 @@ int hostapd_reload_config(struct hostapd
|
||||
struct hostapd_data *hapd = iface->bss[0];
|
||||
struct hostapd_config *newconf, *oldconf;
|
||||
size_t j;
|
||||
@ -35,7 +37,7 @@
|
||||
|
||||
if (iface->config_fname == NULL) {
|
||||
/* Only in-memory config in use - assume it has been updated */
|
||||
@@ -255,24 +276,20 @@ int hostapd_reload_config(struct hostapd
|
||||
@@ -265,24 +288,20 @@ int hostapd_reload_config(struct hostapd
|
||||
}
|
||||
iface->conf = newconf;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user