From b344bfb5d9e3912d90ca240682ea40dc0226f94f Mon Sep 17 00:00:00 2001 From: AmadeusGhost <42570690+AmadeusGhost@users.noreply.github.com> Date: Sat, 4 Apr 2020 15:56:30 +0800 Subject: [PATCH] ath10k-ct: bump to 5.4 (#4165) --- package/firmware/ath10k-firmware/Makefile | 48 +- package/kernel/ath10k-ct/Makefile | 10 +- ...64-ath10k-commit-rates-from-mac80211.patch | 52 + ...-the-vif-to-cancel_remain_on_channel.patch | 41 + ...rolling-support-for-various-chipsets.patch | 1046 ++++++++++++++++- ...h10k-4.16-use-tpt-trigger-by-default.patch | 76 +- ...10k-Add-NL80211_EXT_FEATURE_AQL-flag.patch | 10 + ...0-0010-ath10k-limit-htt-rx-ring-size.patch | 28 + ...60-0011-ath10k-limit-pci-buffer-size.patch | 100 ++ ...station-exists-before-forwarding-tx-.patch | 81 ++ 10 files changed, 1453 insertions(+), 39 deletions(-) create mode 100644 package/kernel/ath10k-ct/patches/170-mac80211-pass-the-vif-to-cancel_remain_on_channel.patch create mode 100644 package/kernel/ath10k-ct/patches/205-ath10k-Add-NL80211_EXT_FEATURE_AQL-flag.patch create mode 100644 package/kernel/ath10k-ct/patches/976-ath10k-Check-if-station-exists-before-forwarding-tx-.patch diff --git a/package/firmware/ath10k-firmware/Makefile b/package/firmware/ath10k-firmware/Makefile index 1c4c9ef01..f82115364 100644 --- a/package/firmware/ath10k-firmware/Makefile +++ b/package/firmware/ath10k-firmware/Makefile @@ -64,92 +64,92 @@ define Download/ct-firmware-htt URL_FILE:=$($(1)_FIRMWARE_FILE_CT_HTT) endef -QCA988X_FIRMWARE_FILE_CT:=firmware-2-ct-full-community-22.bin.lede.015 +QCA988X_FIRMWARE_FILE_CT:=firmware-2-ct-full-community-22.bin.lede.017 define Download/ath10k-firmware-qca988x-ct $(call Download/ct-firmware,QCA988X,) - HASH:=a3a760d0d72707feffa496b6d2266bd9195f09806553b36420b60c0f12b8b87e + HASH:=2f0bf766e400a4c5726e77b128eb8c141ebaa778526fe2c7c5083f3b17659dbf endef $(eval $(call Download,ath10k-firmware-qca988x-ct)) -QCA988X_FIRMWARE_FILE_CT_HTT:=firmware-2-ct-full-htt-mgt-community-22.bin.lede.015 +QCA988X_FIRMWARE_FILE_CT_HTT:=firmware-2-ct-full-htt-mgt-community-22.bin.lede.017 define Download/ath10k-firmware-qca988x-ct-htt $(call Download/ct-firmware-htt,QCA988X,) - HASH:=3114a54103d2b492fa1ef903769721f59953c829020d62502a1ec411ab4146d5 + HASH:=5e4285d5c6eee159a25ca14c6ce26022c32380bd7bafaedfc0c5de1510119007 endef $(eval $(call Download,ath10k-firmware-qca988x-ct-htt)) -QCA9887_FIRMWARE_FILE_CT:=firmware-2-ct-full-community-22.bin.lede.015 +QCA9887_FIRMWARE_FILE_CT:=firmware-2-ct-full-community-22.bin.lede.017 define Download/ath10k-firmware-qca9887-ct $(call Download/ct-firmware,QCA9887,ath10k-9887) - HASH:=71e8b76dfd7c786d2f57bb7df207dcd13a91d3b492cfbd28916f084d0d1bb5e7 + HASH:=4fa30e0e1972ca3b06225a731df0f93a1b73ac67fea5bf54bb55dea3bbc0da6a endef $(eval $(call Download,ath10k-firmware-qca9887-ct)) -QCA9887_FIRMWARE_FILE_CT_HTT:=firmware-2-ct-full-htt-mgt-community-22.bin.lede.015 +QCA9887_FIRMWARE_FILE_CT_HTT:=firmware-2-ct-full-htt-mgt-community-22.bin.lede.017 define Download/ath10k-firmware-qca9887-ct-htt $(call Download/ct-firmware-htt,QCA9887,ath10k-9887) - HASH:=b085e5d2239727b72bc647a76864431b8ac48438e6a33b1d55edc2222468f6ff + HASH:=dc681b6b1e45956e7c2e418ab05eee5c943d13e775209196d9bd931ff6493935 endef $(eval $(call Download,ath10k-firmware-qca9887-ct-htt)) -QCA99X0_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.015 +QCA99X0_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.017 define Download/ath10k-firmware-qca99x0-ct $(call Download/ct-firmware,QCA99X0,ath10k-10-4b) - HASH:=edebe2f6f169cdd05c81a8a78156fb3426a66f415e7946af2ae4b7310fca5fe3 + HASH:=289ea845d4bbae6f36b3af2a13a5eaa07097f52d10f7b7306cfc9e2dd394f889 endef $(eval $(call Download,ath10k-firmware-qca99x0-ct)) -QCA99X0_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.015 +QCA99X0_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.017 define Download/ath10k-firmware-qca99x0-ct-htt $(call Download/ct-firmware-htt,QCA99X0,ath10k-10-4b) - HASH:=1ef67fb07da9082886e4dd554dfc19256e10b500faf9e4b2a5774d0238130bae + HASH:=adedcd3d379a910bc3a5257d75f8970e11319f4cd9c1b34440d35821602a8b9c endef $(eval $(call Download,ath10k-firmware-qca99x0-ct-htt)) -QCA9984_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.015 +QCA9984_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.017 define Download/ath10k-firmware-qca9984-ct $(call Download/ct-firmware,QCA9984,ath10k-9984-10-4b) - HASH:=c2f04da3285aad37baef9c37c9905a31927175dd234cd4378fd56c106e5c9379 + HASH:=8175be5b3946bddc042be018ff7713e67b41b59374ef4cdd183185b59274c91a endef $(eval $(call Download,ath10k-firmware-qca9984-ct)) -QCA9984_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.015 +QCA9984_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.017 define Download/ath10k-firmware-qca9984-ct-htt $(call Download/ct-firmware-htt,QCA9984,ath10k-9984-10-4b) - HASH:=0c9ede1036750d68885e6481fa84f3cb72192b8440b47719344f7327a030f05d + HASH:=eb8b894cfe0d1aaa87f130bb7fd1815ef07b951c14df8a2ceaeb780df8f640e0 endef $(eval $(call Download,ath10k-firmware-qca9984-ct-htt)) -QCA4019_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.015 +QCA4019_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.017 define Download/ath10k-firmware-qca4019-ct $(call Download/ct-firmware,QCA4019,ath10k-4019-10-4b) - HASH:=1acbb7e7a6300091715a3dfe1b248c7833734961de52cc3465c1ed231a4d84f1 + HASH:=29e9f662c4cd287213877abfbb90fbabb5e32dd3710d3ade82aa94a0921972ae endef $(eval $(call Download,ath10k-firmware-qca4019-ct)) -QCA4019_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.015 +QCA4019_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.017 define Download/ath10k-firmware-qca4019-ct-htt $(call Download/ct-firmware-htt,QCA4019,ath10k-4019-10-4b) - HASH:=1065e4d3e55da84ec9e69268a4c5dba55ea33827c48a7c14bb8f0c167eb11b4c + HASH:=559c911f23856b1d3d864ce714d1bef7262bf6638e93e057ecf8d5dba48ca1e6 endef $(eval $(call Download,ath10k-firmware-qca4019-ct-htt)) -QCA9888_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.015 +QCA9888_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-12.bin-lede.017 define Download/ath10k-firmware-qca9888-ct $(call Download/ct-firmware,QCA9888,ath10k-9888-10-4b) - HASH:=559ebd16872a8b43443c51bb4b7d021e5b75e65893d333d9393f3f6012f4ac79 + HASH:=b295880a8b08ec2680d85daaf5f20232a0e73d9cc579bf3efd7ffae24ea340d7 endef $(eval $(call Download,ath10k-firmware-qca9888-ct)) -QCA9888_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.015 +QCA9888_FIRMWARE_FILE_CT_HTT:=firmware-5-ct-full-htt-mgt-community-12.bin-lede.017 define Download/ath10k-firmware-qca9888-ct-htt $(call Download/ct-firmware-htt,QCA9888,ath10k-9888-10-4b) - HASH:=4feaf5e7c4c1745f499ba8c3125db41675800ebedaea455c418c117805c5b372 + HASH:=26fe7c00df10e93373a0f9f105e85d02bb8b1cdd629183ce22a5147138336aec endef $(eval $(call Download,ath10k-firmware-qca9888-ct-htt)) diff --git a/package/kernel/ath10k-ct/Makefile b/package/kernel/ath10k-ct/Makefile index fb60f5d94..63052071f 100644 --- a/package/kernel/ath10k-ct/Makefile +++ b/package/kernel/ath10k-ct/Makefile @@ -8,14 +8,14 @@ PKG_LICENSE_FILES:= PKG_SOURCE_URL:=https://github.com/greearb/ath10k-ct.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2020-01-29 -PKG_SOURCE_VERSION:=3e3d0adb3cc6c6cf56a05ff661796948f09c5aa8 -PKG_MIRROR_HASH:=6341de2d3b19b2a32205a1633bf9556815943a2cff38acbbe5f61c6c0164fdcc +PKG_SOURCE_DATE:=2020-03-25 +PKG_SOURCE_VERSION:=3d173a471d3e583f2885ce68190c4387424cecc5 +PKG_MIRROR_HASH:=496279322f3cd26b262d4999cb5a8c1ea022e92a7bb0d43d008bce235abb9a65 -# Build the 4.19 ath10k-ct driver version. Other option is "-4.16". +# Build the 5.4 ath10k-ct driver version. Other option is "-4.19". # Probably this should match as closely as # possible to whatever mac80211 backports version is being used. -CT_KVER="-4.19" +CT_KVER="-5.4" PKG_MAINTAINER:=Ben Greear PKG_BUILD_PARALLEL:=1 diff --git a/package/kernel/ath10k-ct/patches/164-ath10k-commit-rates-from-mac80211.patch b/package/kernel/ath10k-ct/patches/164-ath10k-commit-rates-from-mac80211.patch index 617d3570b..05d65e24e 100644 --- a/package/kernel/ath10k-ct/patches/164-ath10k-commit-rates-from-mac80211.patch +++ b/package/kernel/ath10k-ct/patches/164-ath10k-commit-rates-from-mac80211.patch @@ -35,3 +35,55 @@ Signed-off-by: Sven Eckelmann vdev_param = ar->wmi.vdev_param->mgmt_rate; ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, hw_rate_code); +--- a/ath10k-5.2/mac.c ++++ b/ath10k-5.2/mac.c +@@ -6742,6 +6742,7 @@ static void ath10k_bss_info_changed(stru + "mac vdev %d mcast_rate %x\n", + arvif->vdev_id, rate); + ++ arvif->mcast_rate[band] = rate; + vdev_param = ar->wmi.vdev_param->mcast_data_rate; + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + vdev_param, rate); +@@ -6750,6 +6751,7 @@ static void ath10k_bss_info_changed(stru + "failed to set mcast rate on vdev %i: %d\n", + arvif->vdev_id, ret); + ++ arvif->bcast_rate[band] = rate; + vdev_param = ar->wmi.vdev_param->bcast_data_rate; + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + vdev_param, rate); +@@ -6776,6 +6778,7 @@ static void ath10k_bss_info_changed(stru + return; + } + ++ arvif->mgt_rate[def.chan->band] = hw_rate_code; + vdev_param = ar->wmi.vdev_param->mgmt_rate; + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, + hw_rate_code); +--- a/ath10k-5.4/mac.c ++++ b/ath10k-5.4/mac.c +@@ -6793,6 +6793,7 @@ static void ath10k_bss_info_changed(stru + "mac vdev %d mcast_rate %x\n", + arvif->vdev_id, rate); + ++ arvif->mcast_rate[band] = rate; + vdev_param = ar->wmi.vdev_param->mcast_data_rate; + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + vdev_param, rate); +@@ -6801,6 +6802,7 @@ static void ath10k_bss_info_changed(stru + "failed to set mcast rate on vdev %i: %d\n", + arvif->vdev_id, ret); + ++ arvif->bcast_rate[band] = rate; + vdev_param = ar->wmi.vdev_param->bcast_data_rate; + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + vdev_param, rate); +@@ -6827,6 +6829,7 @@ static void ath10k_bss_info_changed(stru + return; + } + ++ arvif->mgt_rate[def.chan->band] = hw_rate_code; + vdev_param = ar->wmi.vdev_param->mgmt_rate; + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, + hw_rate_code); diff --git a/package/kernel/ath10k-ct/patches/170-mac80211-pass-the-vif-to-cancel_remain_on_channel.patch b/package/kernel/ath10k-ct/patches/170-mac80211-pass-the-vif-to-cancel_remain_on_channel.patch new file mode 100644 index 000000000..180b0d5bf --- /dev/null +++ b/package/kernel/ath10k-ct/patches/170-mac80211-pass-the-vif-to-cancel_remain_on_channel.patch @@ -0,0 +1,41 @@ +From 5db4c4b9559f8cddd5f7f74e58c7b8f172120e6d Mon Sep 17 00:00:00 2001 +From: Emmanuel Grumbach +Date: Tue, 23 Jul 2019 21:00:01 +0300 +Subject: [PATCH] mac80211: pass the vif to cancel_remain_on_channel + +This low level driver can find it useful to get the vif +when a remain on channel session is cancelled. + +iwlwifi will need this soon. + +Signed-off-by: Emmanuel Grumbach +Link: https://lore.kernel.org/r/20190723180001.5828-1-emmanuel.grumbach@intel.com +Signed-off-by: Johannes Berg +--- + drivers/net/wireless/ath/ath10k/mac.c | 3 ++- + 10 files changed, 4 insertions(+), 2 deletions(-) + +--- a/ath10k-4.19/mac.c ++++ b/ath10k-4.19/mac.c +@@ -7783,7 +7783,8 @@ exit: + return ret; + } + +-static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw) ++static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) + { + struct ath10k *ar = hw->priv; + +--- a/ath10k-5.2/mac.c ++++ b/ath10k-5.2/mac.c +@@ -7893,7 +7893,8 @@ exit: + return ret; + } + +-static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw) ++static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) + { + struct ath10k *ar = hw->priv; + diff --git a/package/kernel/ath10k-ct/patches/201-ath10k-4.16_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/package/kernel/ath10k-ct/patches/201-ath10k-4.16_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch index 311bd22d4..696da7b45 100644 --- a/package/kernel/ath10k-ct/patches/201-ath10k-4.16_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch +++ b/package/kernel/ath10k-ct/patches/201-ath10k-4.16_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch @@ -161,7 +161,7 @@ v13: .patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR, .uart_pin = 7, .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, -@@ -3170,6 +3176,10 @@ int ath10k_core_start(struct ath10k *ar, +@@ -3176,6 +3182,10 @@ int ath10k_core_start(struct ath10k *ar, ath10k_wmi_check_apply_board_power_ctl_table(ar); } @@ -172,7 +172,7 @@ v13: return 0; err_hif_stop: -@@ -3424,9 +3434,18 @@ static void ath10k_core_register_work(st +@@ -3430,9 +3440,18 @@ static void ath10k_core_register_work(st goto err_spectral_destroy; } @@ -191,7 +191,7 @@ v13: err_spectral_destroy: ath10k_spectral_destroy(ar); err_debug_destroy: -@@ -3484,6 +3503,8 @@ void ath10k_core_unregister(struct ath10 +@@ -3490,6 +3509,8 @@ void ath10k_core_unregister(struct ath10 if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) return; @@ -218,7 +218,7 @@ v13: bool p2p; bool ct_all_pkts_htt; /* CT firmware only: native-wifi for all pkts */ -@@ -1389,6 +1389,13 @@ struct ath10k { +@@ -1391,6 +1391,13 @@ struct ath10k { } testmode; struct { @@ -514,7 +514,7 @@ v13: static struct sk_buff * ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, enum wmi_sta_ps_mode psmode) -@@ -9822,6 +9865,9 @@ static const struct wmi_ops wmi_ops = { +@@ -9824,6 +9867,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, @@ -524,7 +524,7 @@ v13: /* .gen_bcn_tmpl not implemented */ /* .gen_prb_tmpl not implemented */ /* .gen_p2p_go_bcn_ie not implemented */ -@@ -9892,6 +9938,8 @@ static const struct wmi_ops wmi_10_1_ops +@@ -9894,6 +9940,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, @@ -533,7 +533,7 @@ v13: /* .gen_bcn_tmpl not implemented */ /* .gen_prb_tmpl not implemented */ /* .gen_p2p_go_bcn_ie not implemented */ -@@ -9970,6 +10018,8 @@ static const struct wmi_ops wmi_10_2_ops +@@ -9972,6 +10020,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, @@ -542,7 +542,7 @@ v13: /* .gen_pdev_enable_adaptive_cca not implemented */ }; -@@ -10040,6 +10090,8 @@ static const struct wmi_ops wmi_10_2_4_o +@@ -10042,6 +10092,8 @@ static const struct wmi_ops wmi_10_2_4_o .gen_pdev_enable_adaptive_cca = ath10k_wmi_op_gen_pdev_enable_adaptive_cca, .get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype, @@ -551,7 +551,7 @@ v13: /* .gen_bcn_tmpl not implemented */ /* .gen_prb_tmpl not implemented */ /* .gen_p2p_go_bcn_ie not implemented */ -@@ -10120,6 +10172,8 @@ static const struct wmi_ops wmi_10_4_ops +@@ -10122,6 +10174,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, @@ -604,3 +604,1031 @@ v13: struct wmi_ext_resource_config_10_4_cmd { /* contains enum wmi_host_platform_type */ __le32 host_platform_config; +--- a/ath10k-5.2/Kconfig ++++ b/ath10k-5.2/Kconfig +@@ -66,6 +66,16 @@ config ATH10K_DEBUGFS + + If unsure, say Y to make it easier to debug problems. + ++config ATH10K_LEDS ++ bool "Atheros ath10k LED support" ++ depends on ATH10K ++ select MAC80211_LEDS ++ select LEDS_CLASS ++ select NEW_LEDS ++ default y ++ ---help--- ++ This option is necessary, if you want LED support for chipset connected led pins. If unsure, say N. ++ + config ATH10K_SPECTRAL + bool "Atheros ath10k spectral scan support" + depends on ATH10K_DEBUGFS +--- a/ath10k-5.2/Makefile ++++ b/ath10k-5.2/Makefile +@@ -19,6 +19,7 @@ ath10k_core-$(CONFIG_ATH10K_SPECTRAL) += + ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o + ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o + ath10k_core-$(CONFIG_THERMAL) += thermal.o ++ath10k_core-$(CONFIG_ATH10K_LEDS) += leds.o + ath10k_core-$(CONFIG_MAC80211_DEBUGFS) += debugfs_sta.o + ath10k_core-$(CONFIG_PM) += wow.o + ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o +--- a/ath10k-5.2/core.c ++++ b/ath10k-5.2/core.c +@@ -25,6 +25,7 @@ + #include "testmode.h" + #include "wmi-ops.h" + #include "coredump.h" ++#include "leds.h" + + /* Disable ath10k-ct DBGLOG output by default */ + unsigned int ath10k_debug_mask = ATH10K_DBG_NO_DBGLOG; +@@ -63,6 +64,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA988X_2_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca988x hw2.0", ++ .led_pin = 1, + .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, +@@ -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", ++ .led_pin = 1, + .patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, +@@ -305,6 +308,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA99X0_2_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca99x0 hw2.0", ++ .led_pin = 17, + .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .otp_exe_param = 0x00000700, +@@ -345,6 +349,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA9984_1_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca9984/qca9994 hw1.0", ++ .led_pin = 17, + .patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, +@@ -392,6 +397,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA9888_2_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca9888 hw2.0", ++ .led_pin = 17, + .patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, +@@ -3503,6 +3509,10 @@ int ath10k_core_start(struct ath10k *ar, + ath10k_wmi_check_apply_board_power_ctl_table(ar); + } + ++ status = ath10k_leds_start(ar); ++ if (status) ++ goto err_hif_stop; ++ + return 0; + + err_hif_stop: +@@ -3759,9 +3769,18 @@ static void ath10k_core_register_work(st + goto err_spectral_destroy; + } + ++ status = ath10k_leds_register(ar); ++ if (status) { ++ ath10k_err(ar, "could not register leds: %d\n", ++ status); ++ goto err_thermal_unregister; ++ } ++ + set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); + return; + ++err_thermal_unregister: ++ ath10k_thermal_unregister(ar); + err_spectral_destroy: + ath10k_spectral_destroy(ar); + err_debug_destroy: +@@ -3821,6 +3840,8 @@ void ath10k_core_unregister(struct ath10 + if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) + return; + ++ ath10k_leds_unregister(ar); ++ + ath10k_thermal_unregister(ar); + /* Stop spectral before unregistering from mac80211 to remove the + * relayfs debugfs file cleanly. Otherwise the parent debugfs tree +--- a/ath10k-5.2/core.h ++++ b/ath10k-5.2/core.h +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + #include "htt.h" + #include "htc.h" +@@ -1449,6 +1450,13 @@ struct ath10k { + } testmode; + + struct { ++ struct gpio_led wifi_led; ++ struct led_classdev cdev; ++ char label[48]; ++ u32 gpio_state_pin; ++ } leds; ++ ++ struct { + /* protected by data_lock */ + u32 fw_crash_counter; + u32 fw_warm_reset_counter; +--- a/ath10k-5.2/hw.h ++++ b/ath10k-5.2/hw.h +@@ -515,6 +515,7 @@ struct ath10k_hw_params { + const char *name; + u32 patch_load_addr; + int uart_pin; ++ int led_pin; + u32 otp_exe_param; + + /* Type of hw cycle counter wraparound logic, for more info +--- /dev/null ++++ b/ath10k-5.2/leds.c +@@ -0,0 +1,103 @@ ++/* ++ * Copyright (c) 2005-2011 Atheros Communications Inc. ++ * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2018 Sebastian Gottschall ++ * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include ++ ++#include "core.h" ++#include "wmi.h" ++#include "wmi-ops.h" ++ ++#include "leds.h" ++ ++static int ath10k_leds_set_brightness_blocking(struct led_classdev *led_cdev, ++ enum led_brightness brightness) ++{ ++ struct ath10k *ar = container_of(led_cdev, struct ath10k, ++ leds.cdev); ++ struct gpio_led *led = &ar->leds.wifi_led; ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ if (ar->state != ATH10K_STATE_ON) ++ goto out; ++ ++ ar->leds.gpio_state_pin = (brightness != LED_OFF) ^ led->active_low; ++ ath10k_wmi_gpio_output(ar, led->gpio, ar->leds.gpio_state_pin); ++ ++out: ++ mutex_unlock(&ar->conf_mutex); ++ ++ return 0; ++} ++ ++int ath10k_leds_start(struct ath10k *ar) ++{ ++ if (ar->hw_params.led_pin == 0) ++ /* leds not supported */ ++ return 0; ++ ++ /* under some circumstances, the gpio pin gets reconfigured ++ * to default state by the firmware, so we need to ++ * reconfigure it this behaviour has only ben seen on ++ * QCA9984 and QCA99XX devices so far ++ */ ++ ath10k_wmi_gpio_config(ar, ar->hw_params.led_pin, 0, ++ WMI_GPIO_PULL_NONE, WMI_GPIO_INTTYPE_DISABLE); ++ ath10k_wmi_gpio_output(ar, ar->hw_params.led_pin, 1); ++ ++ return 0; ++} ++ ++int ath10k_leds_register(struct ath10k *ar) ++{ ++ int ret; ++ ++ if (ar->hw_params.led_pin == 0) ++ /* leds not supported */ ++ return 0; ++ ++ snprintf(ar->leds.label, sizeof(ar->leds.label), "ath10k-%s", ++ wiphy_name(ar->hw->wiphy)); ++ ar->leds.wifi_led.active_low = 1; ++ ar->leds.wifi_led.gpio = ar->hw_params.led_pin; ++ ar->leds.wifi_led.name = ar->leds.label; ++ ar->leds.wifi_led.default_state = LEDS_GPIO_DEFSTATE_KEEP; ++ ++ ar->leds.cdev.name = ar->leds.label; ++ ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking; ++ ++ /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */ ++ ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger; ++ ++ ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++void ath10k_leds_unregister(struct ath10k *ar) ++{ ++ if (ar->hw_params.led_pin == 0) ++ /* leds not supported */ ++ return; ++ ++ led_classdev_unregister(&ar->leds.cdev); ++} ++ +--- /dev/null ++++ b/ath10k-5.2/leds.h +@@ -0,0 +1,41 @@ ++/* ++ * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++#ifndef _LEDS_H_ ++#define _LEDS_H_ ++ ++#include "core.h" ++ ++#ifdef CONFIG_ATH10K_LEDS ++void ath10k_leds_unregister(struct ath10k *ar); ++int ath10k_leds_start(struct ath10k *ar); ++int ath10k_leds_register(struct ath10k *ar); ++#else ++static inline void ath10k_leds_unregister(struct ath10k *ar) ++{ ++} ++ ++static inline int ath10k_leds_start(struct ath10k *ar) ++{ ++ return 0; ++} ++ ++static inline int ath10k_leds_register(struct ath10k *ar) ++{ ++ return 0; ++} ++ ++#endif ++#endif /* _LEDS_H_ */ +--- a/ath10k-5.2/mac.c ++++ b/ath10k-5.2/mac.c +@@ -24,6 +24,7 @@ + #include "wmi-tlv.h" + #include "wmi-ops.h" + #include "wow.h" ++#include "leds.h" + + /*********/ + /* Rates */ +--- a/ath10k-5.2/wmi-ops.h ++++ b/ath10k-5.2/wmi-ops.h +@@ -218,7 +218,10 @@ struct wmi_ops { + struct sk_buff *(*gen_bb_timing) + (struct ath10k *ar, + const struct wmi_bb_timing_cfg_arg *arg); ++ struct sk_buff *(*gen_gpio_config)(struct ath10k *ar, u32 gpio_num, ++ u32 input, u32 pull_type, u32 intr_mode); + ++ struct sk_buff *(*gen_gpio_output)(struct ath10k *ar, u32 gpio_num, u32 set); + }; + + int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); +@@ -1105,6 +1108,35 @@ ath10k_wmi_force_fw_hang(struct ath10k * + return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); + } + ++static inline int ath10k_wmi_gpio_config(struct ath10k *ar, u32 gpio_num, ++ u32 input, u32 pull_type, u32 intr_mode) ++{ ++ struct sk_buff *skb; ++ ++ if (!ar->wmi.ops->gen_gpio_config) ++ return -EOPNOTSUPP; ++ ++ skb = ar->wmi.ops->gen_gpio_config(ar, gpio_num, input, pull_type, intr_mode); ++ if (IS_ERR(skb)) ++ return PTR_ERR(skb); ++ ++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_config_cmdid); ++} ++ ++static inline int ath10k_wmi_gpio_output(struct ath10k *ar, u32 gpio_num, u32 set) ++{ ++ struct sk_buff *skb; ++ ++ if (!ar->wmi.ops->gen_gpio_config) ++ return -EOPNOTSUPP; ++ ++ skb = ar->wmi.ops->gen_gpio_output(ar, gpio_num, set); ++ if (IS_ERR(skb)) ++ return PTR_ERR(skb); ++ ++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_output_cmdid); ++} ++ + static inline int + ath10k_wmi_dbglog_cfg(struct ath10k *ar, u64 module_enable, u32 log_level) + { +--- a/ath10k-5.2/wmi-tlv.c ++++ b/ath10k-5.2/wmi-tlv.c +@@ -4311,6 +4311,8 @@ static const struct wmi_ops wmi_tlv_ops + .gen_echo = ath10k_wmi_tlv_op_gen_echo, + .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, + .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, ++ /* .gen_gpio_config not implemented */ ++ /* .gen_gpio_output not implemented */ + }; + + static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = { +--- a/ath10k-5.2/wmi.c ++++ b/ath10k-5.2/wmi.c +@@ -8295,6 +8295,49 @@ ath10k_wmi_op_gen_peer_set_param(struct + return skb; + } + ++static struct sk_buff *ath10k_wmi_op_gen_gpio_config(struct ath10k *ar, ++ u32 gpio_num, u32 input, ++ u32 pull_type, u32 intr_mode) ++{ ++ struct wmi_gpio_config_cmd *cmd; ++ struct sk_buff *skb; ++ ++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); ++ if (!skb) ++ return ERR_PTR(-ENOMEM); ++ ++ cmd = (struct wmi_gpio_config_cmd *)skb->data; ++ cmd->pull_type = __cpu_to_le32(pull_type); ++ cmd->gpio_num = __cpu_to_le32(gpio_num); ++ cmd->input = __cpu_to_le32(input); ++ cmd->intr_mode = __cpu_to_le32(intr_mode); ++ ++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_config gpio_num 0x%08x input 0x%08x pull_type 0x%08x intr_mode 0x%08x\n", ++ gpio_num, input, pull_type, intr_mode); ++ ++ return skb; ++} ++ ++static struct sk_buff *ath10k_wmi_op_gen_gpio_output(struct ath10k *ar, ++ u32 gpio_num, u32 set) ++{ ++ struct wmi_gpio_output_cmd *cmd; ++ struct sk_buff *skb; ++ ++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); ++ if (!skb) ++ return ERR_PTR(-ENOMEM); ++ ++ cmd = (struct wmi_gpio_output_cmd *)skb->data; ++ cmd->gpio_num = __cpu_to_le32(gpio_num); ++ cmd->set = __cpu_to_le32(set); ++ ++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_output gpio_num 0x%08x set 0x%08x\n", ++ gpio_num, set); ++ ++ return skb; ++} ++ + static struct sk_buff * + ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, + enum wmi_sta_ps_mode psmode) +@@ -10069,6 +10112,9 @@ static const struct wmi_ops wmi_ops = { + .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, + .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, + .gen_echo = ath10k_wmi_op_gen_echo, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, ++ + /* .gen_bcn_tmpl not implemented */ + /* .gen_prb_tmpl not implemented */ + /* .gen_p2p_go_bcn_ie not implemented */ +@@ -10139,6 +10185,8 @@ static const struct wmi_ops wmi_10_1_ops + .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, + .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, + .gen_echo = ath10k_wmi_op_gen_echo, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, + /* .gen_bcn_tmpl not implemented */ + /* .gen_prb_tmpl not implemented */ + /* .gen_p2p_go_bcn_ie not implemented */ +@@ -10218,6 +10266,8 @@ static const struct wmi_ops wmi_10_2_ops + .gen_delba_send = ath10k_wmi_op_gen_delba_send, + .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, + .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, + /* .gen_pdev_enable_adaptive_cca not implemented */ + }; + +@@ -10289,6 +10339,8 @@ static const struct wmi_ops wmi_10_2_4_o + ath10k_wmi_op_gen_pdev_enable_adaptive_cca, + .get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype, + .gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, + /* .gen_bcn_tmpl not implemented */ + /* .gen_prb_tmpl not implemented */ + /* .gen_p2p_go_bcn_ie not implemented */ +@@ -10370,6 +10422,8 @@ static const struct wmi_ops wmi_10_4_ops + .gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info, + .gen_echo = ath10k_wmi_op_gen_echo, + .gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, + }; + + int ath10k_wmi_attach(struct ath10k *ar) +--- a/ath10k-5.2/wmi.h ++++ b/ath10k-5.2/wmi.h +@@ -3103,6 +3103,41 @@ enum wmi_10_4_feature_mask { + + }; + ++/* WMI_GPIO_CONFIG_CMDID */ ++enum { ++ WMI_GPIO_PULL_NONE, ++ WMI_GPIO_PULL_UP, ++ WMI_GPIO_PULL_DOWN, ++}; ++ ++enum { ++ WMI_GPIO_INTTYPE_DISABLE, ++ WMI_GPIO_INTTYPE_RISING_EDGE, ++ WMI_GPIO_INTTYPE_FALLING_EDGE, ++ WMI_GPIO_INTTYPE_BOTH_EDGE, ++ WMI_GPIO_INTTYPE_LEVEL_LOW, ++ WMI_GPIO_INTTYPE_LEVEL_HIGH ++}; ++ ++/* WMI_GPIO_CONFIG_CMDID */ ++struct wmi_gpio_config_cmd { ++ __le32 gpio_num; /* GPIO number to be setup */ ++ __le32 input; /* 0 - Output/ 1 - Input */ ++ __le32 pull_type; /* Pull type defined above */ ++ __le32 intr_mode; /* Interrupt mode defined above (Input) */ ++} __packed; ++ ++/* WMI_GPIO_OUTPUT_CMDID */ ++struct wmi_gpio_output_cmd { ++ __le32 gpio_num; /* GPIO number to be setup */ ++ __le32 set; /* Set the GPIO pin*/ ++} __packed; ++ ++/* WMI_GPIO_INPUT_EVENTID */ ++struct wmi_gpio_input_event { ++ __le32 gpio_num; /* GPIO number which changed state */ ++} __packed; ++ + struct wmi_ext_resource_config_10_4_cmd { + /* contains enum wmi_host_platform_type */ + __le32 host_platform_config; +--- a/ath10k-5.4/Kconfig ++++ b/ath10k-5.4/Kconfig +@@ -66,6 +66,16 @@ config ATH10K_DEBUGFS + + If unsure, say Y to make it easier to debug problems. + ++config ATH10K_LEDS ++ bool "Atheros ath10k LED support" ++ depends on ATH10K ++ select MAC80211_LEDS ++ select LEDS_CLASS ++ select NEW_LEDS ++ default y ++ ---help--- ++ This option is necessary, if you want LED support for chipset connected led pins. If unsure, say N. ++ + config ATH10K_SPECTRAL + bool "Atheros ath10k spectral scan support" + depends on ATH10K_DEBUGFS +--- a/ath10k-5.4/Makefile ++++ b/ath10k-5.4/Makefile +@@ -19,6 +19,7 @@ ath10k_core-$(CONFIG_ATH10K_SPECTRAL) += + ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o + ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o + ath10k_core-$(CONFIG_THERMAL) += thermal.o ++ath10k_core-$(CONFIG_ATH10K_LEDS) += leds.o + ath10k_core-$(CONFIG_MAC80211_DEBUGFS) += debugfs_sta.o + ath10k_core-$(CONFIG_PM) += wow.o + ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o +--- a/ath10k-5.4/core.c ++++ b/ath10k-5.4/core.c +@@ -25,6 +25,7 @@ + #include "testmode.h" + #include "wmi-ops.h" + #include "coredump.h" ++#include "leds.h" + + /* Disable ath10k-ct DBGLOG output by default */ + unsigned int ath10k_debug_mask = ATH10K_DBG_NO_DBGLOG; +@@ -67,6 +68,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA988X_2_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca988x hw2.0", ++ .led_pin = 1, + .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, +@@ -137,6 +139,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA9887_1_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca9887 hw1.0", ++ .led_pin = 1, + .patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, +@@ -344,6 +347,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA99X0_2_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca99x0 hw2.0", ++ .led_pin = 17, + .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .otp_exe_param = 0x00000700, +@@ -385,6 +389,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA9984_1_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca9984/qca9994 hw1.0", ++ .led_pin = 17, + .patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, +@@ -433,6 +438,7 @@ static const struct ath10k_hw_params ath + .dev_id = QCA9888_2_0_DEVICE_ID, + .bus = ATH10K_BUS_PCI, + .name = "qca9888 hw2.0", ++ .led_pin = 17, + .patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, +@@ -3573,6 +3579,10 @@ int ath10k_core_start(struct ath10k *ar, + ath10k_wmi_check_apply_board_power_ctl_table(ar); + } + ++ status = ath10k_leds_start(ar); ++ if (status) ++ goto err_hif_stop; ++ + return 0; + + err_hif_stop: +@@ -3829,9 +3839,18 @@ static void ath10k_core_register_work(st + goto err_spectral_destroy; + } + ++ status = ath10k_leds_register(ar); ++ if (status) { ++ ath10k_err(ar, "could not register leds: %d\n", ++ status); ++ goto err_thermal_unregister; ++ } ++ + set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); + return; + ++err_thermal_unregister: ++ ath10k_thermal_unregister(ar); + err_spectral_destroy: + ath10k_spectral_destroy(ar); + err_debug_destroy: +@@ -3891,6 +3910,8 @@ void ath10k_core_unregister(struct ath10 + if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) + return; + ++ ath10k_leds_unregister(ar); ++ + ath10k_thermal_unregister(ar); + /* Stop spectral before unregistering from mac80211 to remove the + * relayfs debugfs file cleanly. Otherwise the parent debugfs tree +--- a/ath10k-5.4/core.h ++++ b/ath10k-5.4/core.h +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + #include "htt.h" + #include "htc.h" +@@ -1469,6 +1470,13 @@ struct ath10k { + } testmode; + + struct { ++ struct gpio_led wifi_led; ++ struct led_classdev cdev; ++ char label[48]; ++ u32 gpio_state_pin; ++ } leds; ++ ++ struct { + /* protected by data_lock */ + u32 fw_crash_counter; + u32 fw_warm_reset_counter; +--- a/ath10k-5.4/hw.h ++++ b/ath10k-5.4/hw.h +@@ -518,6 +518,7 @@ struct ath10k_hw_params { + const char *name; + u32 patch_load_addr; + int uart_pin; ++ int led_pin; + u32 otp_exe_param; + + /* Type of hw cycle counter wraparound logic, for more info +--- /dev/null ++++ b/ath10k-5.4/leds.c +@@ -0,0 +1,103 @@ ++/* ++ * Copyright (c) 2005-2011 Atheros Communications Inc. ++ * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2018 Sebastian Gottschall ++ * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include ++ ++#include "core.h" ++#include "wmi.h" ++#include "wmi-ops.h" ++ ++#include "leds.h" ++ ++static int ath10k_leds_set_brightness_blocking(struct led_classdev *led_cdev, ++ enum led_brightness brightness) ++{ ++ struct ath10k *ar = container_of(led_cdev, struct ath10k, ++ leds.cdev); ++ struct gpio_led *led = &ar->leds.wifi_led; ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ if (ar->state != ATH10K_STATE_ON) ++ goto out; ++ ++ ar->leds.gpio_state_pin = (brightness != LED_OFF) ^ led->active_low; ++ ath10k_wmi_gpio_output(ar, led->gpio, ar->leds.gpio_state_pin); ++ ++out: ++ mutex_unlock(&ar->conf_mutex); ++ ++ return 0; ++} ++ ++int ath10k_leds_start(struct ath10k *ar) ++{ ++ if (ar->hw_params.led_pin == 0) ++ /* leds not supported */ ++ return 0; ++ ++ /* under some circumstances, the gpio pin gets reconfigured ++ * to default state by the firmware, so we need to ++ * reconfigure it this behaviour has only ben seen on ++ * QCA9984 and QCA99XX devices so far ++ */ ++ ath10k_wmi_gpio_config(ar, ar->hw_params.led_pin, 0, ++ WMI_GPIO_PULL_NONE, WMI_GPIO_INTTYPE_DISABLE); ++ ath10k_wmi_gpio_output(ar, ar->hw_params.led_pin, 1); ++ ++ return 0; ++} ++ ++int ath10k_leds_register(struct ath10k *ar) ++{ ++ int ret; ++ ++ if (ar->hw_params.led_pin == 0) ++ /* leds not supported */ ++ return 0; ++ ++ snprintf(ar->leds.label, sizeof(ar->leds.label), "ath10k-%s", ++ wiphy_name(ar->hw->wiphy)); ++ ar->leds.wifi_led.active_low = 1; ++ ar->leds.wifi_led.gpio = ar->hw_params.led_pin; ++ ar->leds.wifi_led.name = ar->leds.label; ++ ar->leds.wifi_led.default_state = LEDS_GPIO_DEFSTATE_KEEP; ++ ++ ar->leds.cdev.name = ar->leds.label; ++ ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking; ++ ++ /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */ ++ ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger; ++ ++ ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++void ath10k_leds_unregister(struct ath10k *ar) ++{ ++ if (ar->hw_params.led_pin == 0) ++ /* leds not supported */ ++ return; ++ ++ led_classdev_unregister(&ar->leds.cdev); ++} ++ +--- /dev/null ++++ b/ath10k-5.4/leds.h +@@ -0,0 +1,41 @@ ++/* ++ * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++#ifndef _LEDS_H_ ++#define _LEDS_H_ ++ ++#include "core.h" ++ ++#ifdef CONFIG_ATH10K_LEDS ++void ath10k_leds_unregister(struct ath10k *ar); ++int ath10k_leds_start(struct ath10k *ar); ++int ath10k_leds_register(struct ath10k *ar); ++#else ++static inline void ath10k_leds_unregister(struct ath10k *ar) ++{ ++} ++ ++static inline int ath10k_leds_start(struct ath10k *ar) ++{ ++ return 0; ++} ++ ++static inline int ath10k_leds_register(struct ath10k *ar) ++{ ++ return 0; ++} ++ ++#endif ++#endif /* _LEDS_H_ */ +--- a/ath10k-5.4/mac.c ++++ b/ath10k-5.4/mac.c +@@ -24,6 +24,7 @@ + #include "wmi-tlv.h" + #include "wmi-ops.h" + #include "wow.h" ++#include "leds.h" + + /*********/ + /* Rates */ +--- a/ath10k-5.4/wmi-ops.h ++++ b/ath10k-5.4/wmi-ops.h +@@ -218,7 +218,10 @@ struct wmi_ops { + struct sk_buff *(*gen_bb_timing) + (struct ath10k *ar, + const struct wmi_bb_timing_cfg_arg *arg); ++ struct sk_buff *(*gen_gpio_config)(struct ath10k *ar, u32 gpio_num, ++ u32 input, u32 pull_type, u32 intr_mode); + ++ struct sk_buff *(*gen_gpio_output)(struct ath10k *ar, u32 gpio_num, u32 set); + }; + + int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); +@@ -1105,6 +1108,35 @@ ath10k_wmi_force_fw_hang(struct ath10k * + return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); + } + ++static inline int ath10k_wmi_gpio_config(struct ath10k *ar, u32 gpio_num, ++ u32 input, u32 pull_type, u32 intr_mode) ++{ ++ struct sk_buff *skb; ++ ++ if (!ar->wmi.ops->gen_gpio_config) ++ return -EOPNOTSUPP; ++ ++ skb = ar->wmi.ops->gen_gpio_config(ar, gpio_num, input, pull_type, intr_mode); ++ if (IS_ERR(skb)) ++ return PTR_ERR(skb); ++ ++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_config_cmdid); ++} ++ ++static inline int ath10k_wmi_gpio_output(struct ath10k *ar, u32 gpio_num, u32 set) ++{ ++ struct sk_buff *skb; ++ ++ if (!ar->wmi.ops->gen_gpio_config) ++ return -EOPNOTSUPP; ++ ++ skb = ar->wmi.ops->gen_gpio_output(ar, gpio_num, set); ++ if (IS_ERR(skb)) ++ return PTR_ERR(skb); ++ ++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_output_cmdid); ++} ++ + static inline int + ath10k_wmi_dbglog_cfg(struct ath10k *ar, u64 module_enable, u32 log_level) + { +--- a/ath10k-5.4/wmi-tlv.c ++++ b/ath10k-5.4/wmi-tlv.c +@@ -4364,6 +4364,8 @@ static const struct wmi_ops wmi_tlv_ops + .gen_echo = ath10k_wmi_tlv_op_gen_echo, + .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, + .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, ++ /* .gen_gpio_config not implemented */ ++ /* .gen_gpio_output not implemented */ + }; + + static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = { +--- a/ath10k-5.4/wmi.c ++++ b/ath10k-5.4/wmi.c +@@ -8295,6 +8295,49 @@ ath10k_wmi_op_gen_peer_set_param(struct + return skb; + } + ++static struct sk_buff *ath10k_wmi_op_gen_gpio_config(struct ath10k *ar, ++ u32 gpio_num, u32 input, ++ u32 pull_type, u32 intr_mode) ++{ ++ struct wmi_gpio_config_cmd *cmd; ++ struct sk_buff *skb; ++ ++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); ++ if (!skb) ++ return ERR_PTR(-ENOMEM); ++ ++ cmd = (struct wmi_gpio_config_cmd *)skb->data; ++ cmd->pull_type = __cpu_to_le32(pull_type); ++ cmd->gpio_num = __cpu_to_le32(gpio_num); ++ cmd->input = __cpu_to_le32(input); ++ cmd->intr_mode = __cpu_to_le32(intr_mode); ++ ++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_config gpio_num 0x%08x input 0x%08x pull_type 0x%08x intr_mode 0x%08x\n", ++ gpio_num, input, pull_type, intr_mode); ++ ++ return skb; ++} ++ ++static struct sk_buff *ath10k_wmi_op_gen_gpio_output(struct ath10k *ar, ++ u32 gpio_num, u32 set) ++{ ++ struct wmi_gpio_output_cmd *cmd; ++ struct sk_buff *skb; ++ ++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); ++ if (!skb) ++ return ERR_PTR(-ENOMEM); ++ ++ cmd = (struct wmi_gpio_output_cmd *)skb->data; ++ cmd->gpio_num = __cpu_to_le32(gpio_num); ++ cmd->set = __cpu_to_le32(set); ++ ++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_output gpio_num 0x%08x set 0x%08x\n", ++ gpio_num, set); ++ ++ return skb; ++} ++ + static struct sk_buff * + ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, + enum wmi_sta_ps_mode psmode) +@@ -10094,6 +10137,9 @@ static const struct wmi_ops wmi_ops = { + .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, + .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, + .gen_echo = ath10k_wmi_op_gen_echo, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, ++ + /* .gen_bcn_tmpl not implemented */ + /* .gen_prb_tmpl not implemented */ + /* .gen_p2p_go_bcn_ie not implemented */ +@@ -10164,6 +10210,8 @@ static const struct wmi_ops wmi_10_1_ops + .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, + .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, + .gen_echo = ath10k_wmi_op_gen_echo, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, + /* .gen_bcn_tmpl not implemented */ + /* .gen_prb_tmpl not implemented */ + /* .gen_p2p_go_bcn_ie not implemented */ +@@ -10243,6 +10291,8 @@ static const struct wmi_ops wmi_10_2_ops + .gen_delba_send = ath10k_wmi_op_gen_delba_send, + .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, + .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, + /* .gen_pdev_enable_adaptive_cca not implemented */ + }; + +@@ -10314,6 +10364,8 @@ static const struct wmi_ops wmi_10_2_4_o + ath10k_wmi_op_gen_pdev_enable_adaptive_cca, + .get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype, + .gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, + /* .gen_bcn_tmpl not implemented */ + /* .gen_prb_tmpl not implemented */ + /* .gen_p2p_go_bcn_ie not implemented */ +@@ -10395,6 +10447,8 @@ static const struct wmi_ops wmi_10_4_ops + .gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info, + .gen_echo = ath10k_wmi_op_gen_echo, + .gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, + }; + + int ath10k_wmi_attach(struct ath10k *ar) +--- a/ath10k-5.4/wmi.h ++++ b/ath10k-5.4/wmi.h +@@ -3110,6 +3110,41 @@ enum wmi_10_4_feature_mask { + + }; + ++/* WMI_GPIO_CONFIG_CMDID */ ++enum { ++ WMI_GPIO_PULL_NONE, ++ WMI_GPIO_PULL_UP, ++ WMI_GPIO_PULL_DOWN, ++}; ++ ++enum { ++ WMI_GPIO_INTTYPE_DISABLE, ++ WMI_GPIO_INTTYPE_RISING_EDGE, ++ WMI_GPIO_INTTYPE_FALLING_EDGE, ++ WMI_GPIO_INTTYPE_BOTH_EDGE, ++ WMI_GPIO_INTTYPE_LEVEL_LOW, ++ WMI_GPIO_INTTYPE_LEVEL_HIGH ++}; ++ ++/* WMI_GPIO_CONFIG_CMDID */ ++struct wmi_gpio_config_cmd { ++ __le32 gpio_num; /* GPIO number to be setup */ ++ __le32 input; /* 0 - Output/ 1 - Input */ ++ __le32 pull_type; /* Pull type defined above */ ++ __le32 intr_mode; /* Interrupt mode defined above (Input) */ ++} __packed; ++ ++/* WMI_GPIO_OUTPUT_CMDID */ ++struct wmi_gpio_output_cmd { ++ __le32 gpio_num; /* GPIO number to be setup */ ++ __le32 set; /* Set the GPIO pin*/ ++} __packed; ++ ++/* WMI_GPIO_INPUT_EVENTID */ ++struct wmi_gpio_input_event { ++ __le32 gpio_num; /* GPIO number which changed state */ ++} __packed; ++ + struct wmi_ext_resource_config_10_4_cmd { + /* contains enum wmi_host_platform_type */ + __le32 host_platform_config; diff --git a/package/kernel/ath10k-ct/patches/202-ath10k-4.16-use-tpt-trigger-by-default.patch b/package/kernel/ath10k-ct/patches/202-ath10k-4.16-use-tpt-trigger-by-default.patch index 3f9c6dc39..c23c31417 100644 --- a/package/kernel/ath10k-ct/patches/202-ath10k-4.16-use-tpt-trigger-by-default.patch +++ b/package/kernel/ath10k-ct/patches/202-ath10k-4.16-use-tpt-trigger-by-default.patch @@ -16,7 +16,7 @@ Signed-off-by: Mathias Kresin --- a/ath10k-4.19/core.h +++ b/ath10k-4.19/core.h -@@ -1489,6 +1489,10 @@ struct ath10k { +@@ -1491,6 +1491,10 @@ struct ath10k { u8 csi_data[4096]; u16 csi_data_len; @@ -51,3 +51,77 @@ Signed-off-by: Mathias Kresin IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink, ARRAY_SIZE(ath10k_tpt_blink)); #endif +--- a/ath10k-5.2/core.h ++++ b/ath10k-5.2/core.h +@@ -1552,6 +1552,10 @@ struct ath10k { + u8 csi_data[4096]; + u16 csi_data_len; + ++#ifdef CPTCFG_MAC80211_LEDS ++ const char *led_default_trigger; ++#endif ++ + /* must be last */ + u8 drv_priv[0] __aligned(sizeof(void *)); + }; +--- a/ath10k-5.2/leds.c ++++ b/ath10k-5.2/leds.c +@@ -81,9 +81,7 @@ int ath10k_leds_register(struct ath10k * + + ar->leds.cdev.name = ar->leds.label; + ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking; +- +- /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */ +- ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger; ++ ar->leds.cdev.default_trigger = ar->led_default_trigger; + + ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev); + if (ret) +--- a/ath10k-5.2/mac.c ++++ b/ath10k-5.2/mac.c +@@ -10187,7 +10187,7 @@ int ath10k_mac_register(struct ath10k *a + ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; + + #ifdef CPTCFG_MAC80211_LEDS +- ieee80211_create_tpt_led_trigger(ar->hw, ++ ar->led_default_trigger = ieee80211_create_tpt_led_trigger(ar->hw, + IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink, + ARRAY_SIZE(ath10k_tpt_blink)); + #endif +--- a/ath10k-5.4/core.h ++++ b/ath10k-5.4/core.h +@@ -1573,6 +1573,10 @@ struct ath10k { + u8 csi_data[4096]; + u16 csi_data_len; + ++#ifdef CPTCFG_MAC80211_LEDS ++ const char *led_default_trigger; ++#endif ++ + /* must be last */ + u8 drv_priv[0] __aligned(sizeof(void *)); + }; +--- a/ath10k-5.4/leds.c ++++ b/ath10k-5.4/leds.c +@@ -81,9 +81,7 @@ int ath10k_leds_register(struct ath10k * + + ar->leds.cdev.name = ar->leds.label; + ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking; +- +- /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */ +- ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger; ++ ar->leds.cdev.default_trigger = ar->led_default_trigger; + + ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev); + if (ret) +--- a/ath10k-5.4/mac.c ++++ b/ath10k-5.4/mac.c +@@ -10367,7 +10367,7 @@ int ath10k_mac_register(struct ath10k *a + ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; + + #ifdef CPTCFG_MAC80211_LEDS +- ieee80211_create_tpt_led_trigger(ar->hw, ++ ar->led_default_trigger = ieee80211_create_tpt_led_trigger(ar->hw, + IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink, + ARRAY_SIZE(ath10k_tpt_blink)); + #endif diff --git a/package/kernel/ath10k-ct/patches/205-ath10k-Add-NL80211_EXT_FEATURE_AQL-flag.patch b/package/kernel/ath10k-ct/patches/205-ath10k-Add-NL80211_EXT_FEATURE_AQL-flag.patch new file mode 100644 index 000000000..41b917089 --- /dev/null +++ b/package/kernel/ath10k-ct/patches/205-ath10k-Add-NL80211_EXT_FEATURE_AQL-flag.patch @@ -0,0 +1,10 @@ +--- a/ath10k-5.4/mac.c ++++ b/ath10k-5.4/mac.c +@@ -10180,6 +10180,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)) diff --git a/package/kernel/ath10k-ct/patches/960-0010-ath10k-limit-htt-rx-ring-size.patch b/package/kernel/ath10k-ct/patches/960-0010-ath10k-limit-htt-rx-ring-size.patch index a62d9b791..70f4fb054 100644 --- a/package/kernel/ath10k-ct/patches/960-0010-ath10k-limit-htt-rx-ring-size.patch +++ b/package/kernel/ath10k-ct/patches/960-0010-ath10k-limit-htt-rx-ring-size.patch @@ -12,3 +12,31 @@ #define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX #define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1) #define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1) +--- a/ath10k-5.2/htt.h ++++ b/ath10k-5.2/htt.h +@@ -225,7 +225,11 @@ enum htt_rx_ring_flags { + }; + + #define HTT_RX_RING_SIZE_MIN 128 ++#ifndef CONFIG_ATH10K_SMALLBUFFERS + #define HTT_RX_RING_SIZE_MAX 2048 ++#else ++#define HTT_RX_RING_SIZE_MAX 512 ++#endif + #define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX + #define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1) + #define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1) +--- a/ath10k-5.4/htt.h ++++ b/ath10k-5.4/htt.h +@@ -225,7 +225,11 @@ enum htt_rx_ring_flags { + }; + + #define HTT_RX_RING_SIZE_MIN 128 ++#ifndef CONFIG_ATH10K_SMALLBUFFERS + #define HTT_RX_RING_SIZE_MAX 2048 ++#else ++#define HTT_RX_RING_SIZE_MAX 512 ++#endif + #define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX + #define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1) + #define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1) diff --git a/package/kernel/ath10k-ct/patches/960-0011-ath10k-limit-pci-buffer-size.patch b/package/kernel/ath10k-ct/patches/960-0011-ath10k-limit-pci-buffer-size.patch index 2cbcb08af..0b691217b 100644 --- a/package/kernel/ath10k-ct/patches/960-0011-ath10k-limit-pci-buffer-size.patch +++ b/package/kernel/ath10k-ct/patches/960-0011-ath10k-limit-pci-buffer-size.patch @@ -48,3 +48,103 @@ .recv_cb = ath10k_pci_pktlog_rx_cb, }, +--- a/ath10k-5.2/pci.c ++++ b/ath10k-5.2/pci.c +@@ -131,7 +131,11 @@ static struct ce_attr host_ce_config_wla + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, ++#ifndef CONFIG_ATH10K_SMALLBUFFERS + .dest_nentries = 512, ++#else ++ .dest_nentries = 128, ++#endif + .recv_cb = ath10k_pci_htt_htc_rx_cb, + }, + +@@ -140,7 +144,11 @@ static struct ce_attr host_ce_config_wla + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, ++#ifndef CONFIG_ATH10K_SMALLBUFFERS + .dest_nentries = 128, ++#else ++ .dest_nentries = 64, ++#endif + .recv_cb = ath10k_pci_htc_rx_cb, + }, + +@@ -167,7 +175,11 @@ static struct ce_attr host_ce_config_wla + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 512, ++#ifndef CONFIG_ATH10K_SMALLBUFFERS + .dest_nentries = 512, ++#else ++ .dest_nentries = 128, ++#endif + .recv_cb = ath10k_pci_htt_rx_cb, + }, + +@@ -192,7 +204,11 @@ static struct ce_attr host_ce_config_wla + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, ++#ifndef CONFIG_ATH10K_SMALLBUFFERS + .dest_nentries = 128, ++#else ++ .dest_nentries = 96, ++#endif + .recv_cb = ath10k_pci_pktlog_rx_cb, + }, + +--- a/ath10k-5.4/pci.c ++++ b/ath10k-5.4/pci.c +@@ -131,7 +131,11 @@ static struct ce_attr host_ce_config_wla + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, ++#ifndef CONFIG_ATH10K_SMALLBUFFERS + .dest_nentries = 512, ++#else ++ .dest_nentries = 128, ++#endif + .recv_cb = ath10k_pci_htt_htc_rx_cb, + }, + +@@ -140,7 +144,11 @@ static struct ce_attr host_ce_config_wla + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, ++#ifndef CONFIG_ATH10K_SMALLBUFFERS + .dest_nentries = 128, ++#else ++ .dest_nentries = 64, ++#endif + .recv_cb = ath10k_pci_htc_rx_cb, + }, + +@@ -167,7 +175,11 @@ static struct ce_attr host_ce_config_wla + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 512, ++#ifndef CONFIG_ATH10K_SMALLBUFFERS + .dest_nentries = 512, ++#else ++ .dest_nentries = 128, ++#endif + .recv_cb = ath10k_pci_htt_rx_cb, + }, + +@@ -192,7 +204,11 @@ static struct ce_attr host_ce_config_wla + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, ++#ifndef CONFIG_ATH10K_SMALLBUFFERS + .dest_nentries = 128, ++#else ++ .dest_nentries = 96, ++#endif + .recv_cb = ath10k_pci_pktlog_rx_cb, + }, + diff --git a/package/kernel/ath10k-ct/patches/976-ath10k-Check-if-station-exists-before-forwarding-tx-.patch b/package/kernel/ath10k-ct/patches/976-ath10k-Check-if-station-exists-before-forwarding-tx-.patch new file mode 100644 index 000000000..0ff885d95 --- /dev/null +++ b/package/kernel/ath10k-ct/patches/976-ath10k-Check-if-station-exists-before-forwarding-tx-.patch @@ -0,0 +1,81 @@ +From cc8ec75f5ad4acf9babe5e26a10c9bca10624593 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Sun, 18 Aug 2019 15:33:51 +0200 +Subject: [PATCH] ath10k: Check if station exists before forwarding tx airtime + report + +It looks like the FW on QCA9984 already reports the tx airtimes before +the station is added to the peer entry. The peer entry is created in +ath10k_peer_map_event() just with the vdev_id and the ethaddr, but +not with a station entry, this is added later in ath10k_peer_create() in +callbacks from mac80211. + +When there is no sta added to the peer entry, this function fails +because it calls ieee80211_sta_register_airtime() with NULL. + +This was reported in OpenWrt some time ago: +https://bugs.openwrt.org/index.php?do=details&task_id=2414 + +This commit should fix this crash: +[ 75.991714] Unable to handle kernel paging request at virtual address fffff9e8 +[ 75.991756] pgd = c0204000 +[ 75.997955] [fffff9e8] *pgd=5fdfd861, *pte=00000000, *ppte=00000000 +[ 76.000537] Internal error: Oops: 37 [#1] SMP ARM +[ 76.006686] Modules linked in: pppoe ppp_async ath10k_pci ath10k_core ath pptp pppox ppp_mppe ppp_generic mac80211 iptable_nat ipt_REJECT ipt_MASQUERADE cfg80211 xt_time xt_tcpudp xt_tcpmss xt_statistic xt_state xt_recent xt_nat xt_multiport xt_mark xt_mac xt_limit xt_length xt_hl xt_helper xt_esp xt_ecn xt_dscp xt_conntrack xt_connmark xt_connlimit xt_connbytes xt_comment xt_TCPMSS xt_REDIRECT xt_LOG xt_HL xt_FLOWOFFLOAD xt_DSCP xt_CT xt_CLASSIFY usbserial slhc nf_reject_ipv4 nf_nat_redirect nf_nat_masquerade_ipv4 nf_conntrack_ipv4 nf_nat_ipv4 nf_log_ipv4 nf_flow_table_hw nf_flow_table nf_defrag_ipv4 nf_conntrack_rtcache nf_conntrack_netlink iptable_raw iptable_mangle iptable_filter ipt_ah ipt_ECN ip_tables crc_ccitt compat chaoskey fuse sch_cake sch_tbf sch_ingress sch_htb sch_hfsc em_u32 cls_u32 +[ 76.059974] cls_tcindex cls_route cls_matchall cls_fw cls_flow cls_basic act_skbedit act_mirred ledtrig_usbport xt_set ip_set_list_set ip_set_hash_netportnet ip_set_hash_netport ip_set_hash_netnet ip_set_hash_netiface ip_set_hash_net ip_set_hash_mac ip_set_hash_ipportnet ip_set_hash_ipportip ip_set_hash_ipport ip_set_hash_ipmark ip_set_hash_ip ip_set_bitmap_port ip_set_bitmap_ipmac ip_set_bitmap_ip ip_set nfnetlink ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6t_NPT ip6t_MASQUERADE nf_nat_masquerade_ipv6 nf_nat nf_conntrack nf_log_ipv6 nf_log_common ip6table_mangle ip6table_filter ip6_tables ip6t_REJECT x_tables nf_reject_ipv6 msdos ip_gre gre ifb sit tunnel4 ip_tunnel tun vfat fat hfsplus cifs nls_utf8 nls_iso8859_15 nls_iso8859_1 nls_cp850 nls_cp437 nls_cp1250 sha1_generic md5 md4 +[ 76.130634] usb_storage leds_gpio xhci_plat_hcd xhci_pci xhci_hcd dwc3 dwc3_of_simple ohci_platform ohci_hcd phy_qcom_dwc3 ahci ehci_platform sd_mod ahci_platform libahci_platform libahci libata scsi_mod ehci_hcd gpio_button_hotplug ext4 mbcache jbd2 exfat crc32c_generic +[ 76.154772] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.14.132 #0 +[ 76.177001] Hardware name: Generic DT based system +[ 76.182990] task: c0b06d80 task.stack: c0b00000 +[ 76.187832] PC is at ieee80211_sta_register_airtime+0x24/0x148 [mac80211] +[ 76.192211] LR is at ath10k_htt_t2h_msg_handler+0x678/0x10f4 [ath10k_core] +[ 76.199052] pc : [] lr : [] psr: a0000113 +[ 76.205820] sp : c0b01d54 ip : 00000002 fp : bf869c0c +[ 76.211981] r10: 0000003c r9 : dbdca138 r8 : 00060002 +[ 76.217192] r7 : 00000000 r6 : dabe1150 r5 : 00000000 r4 : dbdc95c0 +[ 76.222401] r3 : 00000000 r2 : 00060002 r1 : 00000000 r0 : 00000000 +[ 76.229003] Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none +[ 76.235509] Control: 10c5787d Table: 5c94006a DAC: 00000051 +[ 76.242716] Process swapper/0 (pid: 0, stack limit = 0xc0b00210) +[ 76.248446] Stack: (0xc0b01d54 to 0xc0b02000) +[ 76.254532] 1d40: dbdc95c0 00000000 dabe1150 +[ 76.258808] 1d60: 00000001 dabe1150 dbdca138 0000003c bf869c0c bf83e8b0 00000002 c0314b10 +[ 76.266969] 1d80: dbdc9c70 00000001 00000001 dabe114c 00010000 00000000 dbdcd724 bf88f3d8 +[ 76.275126] 1da0: c0310d28 db393c00 dbdc95c0 00000000 c0b01dd0 c07fb4c4 dbdcd724 00000001 +[ 76.283286] 1dc0: 00000022 bf88b09c db393c00 00000022 c0b01dd0 c0b01dd0 00000000 dbdcc5c0 +[ 76.291445] 1de0: bf88f04c dbdcd654 dbdcd71c dbdc95c0 00000014 dbdcd724 dbdcc5c0 00000005 +[ 76.299605] 1e00: 0004b400 bf85c360 00000000 bf87101c c0b01e24 00000006 00000000 dbdc95c0 +[ 76.307764] 1e20: 00000001 00000040 0000012c c0b01e80 1cf51000 bf85c448 dbdcd440 dbdc95c0 +[ 76.315925] 1e40: dbdca440 ffffa880 00000040 bf88cb68 dbdcd440 00000001 00000040 ffffa880 +[ 76.324084] 1e60: c0b02d00 c06d72e0 dd990080 c0a3f080 c0b255dc c0b047e4 c090afac c090e80c +[ 76.332244] 1e80: c0b01e80 c0b01e80 c0b01e88 c0b01e88 dd4cc200 00000000 00000003 c0b0208c +[ 76.340405] 1ea0: c0b02080 40000003 ffffe000 00000100 c0b02080 c03015c8 00000000 00000001 +[ 76.348564] 1ec0: dd408000 c0a38210 c0b2c7c0 0000000a ffffa880 c0b02d00 c07fb764 00200102 +[ 76.356723] 1ee0: dd4cc268 c0a3e414 00000000 00000000 00000001 dd408000 de803000 00000000 +[ 76.364883] 1f00: 00000000 c03247cc c0a3e414 c0368f1c c0b03f60 c0b153cc de80200c de802000 +[ 76.373042] 1f20: c0b01f48 c0301488 c0308630 60000013 ffffffff c0b01f7c 00000000 c0b00000 +[ 76.381204] 1f40: 00000000 c030c08c 00000001 00000000 00000000 c0315180 ffffe000 c0b03cc0 +[ 76.389363] 1f60: c0b03c70 00000000 00000000 c0a2da28 00000000 00000000 c0b01f90 c0b01f98 +[ 76.397522] 1f80: c030862c c0308630 60000013 ffffffff 00000051 00000000 ffffe000 c035dd18 +[ 76.405681] 1fa0: 000000bf c0b03c40 00000000 c0b2c000 dddfce80 c035e060 c0b2c040 c0a00cf4 +[ 76.413842] 1fc0: ffffffff ffffffff 00000000 c0a0067c c0a2da28 00000000 00000000 c0b2c1d4 +[ 76.422001] 1fe0: c0b03c5c c0a2da24 c0b07ee0 4220406a 512f04d0 4220807c 00000000 00000000 +[ 76.430335] [] (ieee80211_sta_register_airtime [mac80211]) from [<00000002>] (0x2) +[ 76.438314] Code: e1cd81f0 e1a08002 e1cda1f8 e58de020 (e5102618) +[ 76.446965] ---[ end trace 227a38ade964d642 ]--- + +Fixes: bb31b7cb106c ("ath10k: report tx airtime provided by fw") +Signed-off-by: Hauke Mehrtens +--- + +--- a/ath10k-5.2/htt_rx.c ++++ b/ath10k-5.2/htt_rx.c +@@ -2568,7 +2568,7 @@ do_generic: + spin_lock_bh(&ar->data_lock); + + peer = ath10k_peer_find_by_id(ar, peer_id); +- if (!peer) { ++ if (!peer || !peer->sta) { + spin_unlock_bh(&ar->data_lock); + rcu_read_unlock(); + continue;