diff --git a/package/kernel/ath10k-ct/patches/161-ath10k-add-support-for-configuring-management-packet.patch b/package/kernel/ath10k-ct/patches/161-ath10k-add-support-for-configuring-management-packet.patch deleted file mode 100644 index f18afae327..0000000000 --- a/package/kernel/ath10k-ct/patches/161-ath10k-add-support-for-configuring-management-packet.patch +++ /dev/null @@ -1,89 +0,0 @@ -From: Sriram R -Date: Mon, 10 Sep 2018 11:09:40 +0530 -Subject: [PATCH] ath10k: add support for configuring management packet rate - -By default the firmware uses 1Mbps and 6Mbps rate for management packets -in 2G and 5G bands respectively. But when the user selects different -basic rates from the userspace, we need to send the management -packets at the lowest basic rate selected by the user. - -This change makes use of WMI_VDEV_PARAM_MGMT_RATE param for configuring the -management packets rate to the firmware. - -Chipsets Tested : QCA988X, QCA9887, QCA9984 -FW Tested : 10.2.4-1.0-41, 10.4-3.6.104 - -Signed-off-by: Sriram R -Signed-off-by: Kalle Valo - -Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f279294e9ee22a8f306fdc8e4181cf555e6f0f70 ---- ---- a/ath10k-4.19/mac.c -+++ b/ath10k-4.19/mac.c -@@ -157,6 +157,22 @@ u8 ath10k_mac_bitrate_to_idx(const struc - return 0; - } - -+static int ath10k_mac_get_rate_hw_value(int bitrate) -+{ -+ int i; -+ u8 hw_value_prefix = 0; -+ -+ if (ath10k_mac_bitrate_is_cck(bitrate)) -+ hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6; -+ -+ for (i = 0; i < sizeof(ath10k_rates); i++) { -+ if (ath10k_rates[i].bitrate == bitrate) -+ return hw_value_prefix | ath10k_rates[i].hw_value; -+ } -+ -+ return -EINVAL; -+} -+ - static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss) - { - switch ((mcs_map >> (2 * nss)) & 0x3) { -@@ -6413,9 +6429,10 @@ static void ath10k_bss_info_changed(stru - struct cfg80211_chan_def def; - u32 vdev_param, pdev_param, slottime, preamble; - u16 bitrate, hw_value; -- u8 rate; -- int rateidx, ret = 0; -+ u8 rate, basic_rate_idx; -+ int rateidx, ret = 0, hw_rate_code; - enum nl80211_band band; -+ const struct ieee80211_supported_band *sband; - - mutex_lock(&ar->conf_mutex); - -@@ -6621,6 +6638,30 @@ static void ath10k_bss_info_changed(stru - arvif->vdev_id, ret); - } - -+ if (changed & BSS_CHANGED_BASIC_RATES) { -+ if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) { -+ mutex_unlock(&ar->conf_mutex); -+ return; -+ } -+ -+ sband = ar->hw->wiphy->bands[def.chan->band]; -+ basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1; -+ bitrate = sband->bitrates[basic_rate_idx].bitrate; -+ -+ hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate); -+ if (hw_rate_code < 0) { -+ ath10k_warn(ar, "bitrate not supported %d\n", bitrate); -+ mutex_unlock(&ar->conf_mutex); -+ return; -+ } -+ -+ vdev_param = ar->wmi.vdev_param->mgmt_rate; -+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, -+ hw_rate_code); -+ if (ret) -+ ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret); -+ } -+ - mutex_unlock(&ar->conf_mutex); - } - diff --git a/package/kernel/ath10k-ct/patches/162-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch b/package/kernel/ath10k-ct/patches/162-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch deleted file mode 100644 index aa473e8fea..0000000000 --- a/package/kernel/ath10k-ct/patches/162-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch +++ /dev/null @@ -1,66 +0,0 @@ -From: Sriram R -Date: Wed, 3 Oct 2018 08:43:50 +0530 -Subject: [PATCH] ath10k: fix possible out of bound access of ath10k_rates array - -While using 'ath10k_mac_get_rate_hw_value()' to obtain the hw value -from the passed bitrate, there is a chance of out of bound array access -when wrong bitrate is passed. This is fixed by comparing the bitrates -within the correct size of the ath10k_rates array. - -Fixes commit f279294e9ee2 ("ath10k: add support for configuring management -packet rate"). Also correction made to some indents used in the above commit. - -Signed-off-by: Sriram R -Signed-off-by: Kalle Valo - -Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e141eea7dd8525dd1ef7a925459e455b4d307f ---- ---- a/ath10k-4.19/mac.c -+++ b/ath10k-4.19/mac.c -@@ -165,7 +165,7 @@ static int ath10k_mac_get_rate_hw_value( - if (ath10k_mac_bitrate_is_cck(bitrate)) - hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6; - -- for (i = 0; i < sizeof(ath10k_rates); i++) { -+ for (i = 0; i < ARRAY_SIZE(ath10k_rates); i++) { - if (ath10k_rates[i].bitrate == bitrate) - return hw_value_prefix | ath10k_rates[i].hw_value; - } -@@ -6644,22 +6644,22 @@ static void ath10k_bss_info_changed(stru - return; - } - -- sband = ar->hw->wiphy->bands[def.chan->band]; -- basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1; -- bitrate = sband->bitrates[basic_rate_idx].bitrate; -- -- hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate); -- if (hw_rate_code < 0) { -- ath10k_warn(ar, "bitrate not supported %d\n", bitrate); -- mutex_unlock(&ar->conf_mutex); -- return; -- } -+ sband = ar->hw->wiphy->bands[def.chan->band]; -+ basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1; -+ bitrate = sband->bitrates[basic_rate_idx].bitrate; -+ -+ hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate); -+ if (hw_rate_code < 0) { -+ ath10k_warn(ar, "bitrate not supported %d\n", bitrate); -+ mutex_unlock(&ar->conf_mutex); -+ return; -+ } - -- vdev_param = ar->wmi.vdev_param->mgmt_rate; -- ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, -- hw_rate_code); -- if (ret) -- ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret); -+ vdev_param = ar->wmi.vdev_param->mgmt_rate; -+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, -+ hw_rate_code); -+ if (ret) -+ ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret); - } - - mutex_unlock(&ar->conf_mutex); diff --git a/package/kernel/ath10k-ct/patches/163-ath10k-fix-incorrect-multicast-broadcast-rate-settin.patch b/package/kernel/ath10k-ct/patches/163-ath10k-fix-incorrect-multicast-broadcast-rate-settin.patch deleted file mode 100644 index fc866f49b5..0000000000 --- a/package/kernel/ath10k-ct/patches/163-ath10k-fix-incorrect-multicast-broadcast-rate-settin.patch +++ /dev/null @@ -1,43 +0,0 @@ -From: Pradeep kumar Chitrapu -Date: Mon, 10 Dec 2018 20:56:11 -0800 -Subject: ath10k: fix incorrect multicast/broadcast rate setting - -Invalid rate code is sent to firmware when multicast rate value of 0 is -sent to driver indicating disabled case, causing broken mesh path. -so fix that. - -Tested on QCA9984 with firmware 10.4-3.6.1-00827 - -Fixes: cd93b83ad92 ("ath10k: support for multicast rate control") -Co-developed-by: Zhi Chen -Signed-off-by: Zhi Chen -Signed-off-by: Pradeep Kumar Chitrapu - -Origin: other, https://patchwork.kernel.org/patch/10723033/ - ---- a/ath10k-4.19/mac.c -+++ b/ath10k-4.19/mac.c -@@ -6429,8 +6429,8 @@ static void ath10k_bss_info_changed(stru - struct cfg80211_chan_def def; - u32 vdev_param, pdev_param, slottime, preamble; - u16 bitrate, hw_value; -- u8 rate, basic_rate_idx; -- int rateidx, ret = 0, hw_rate_code; -+ u8 rate, basic_rate_idx, rateidx; -+ int ret = 0, hw_rate_code, mcast_rate; - enum nl80211_band band; - const struct ieee80211_supported_band *sband; - -@@ -6603,7 +6603,11 @@ static void ath10k_bss_info_changed(stru - if (changed & BSS_CHANGED_MCAST_RATE && - !WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def))) { - band = def.chan->band; -- rateidx = vif->bss_conf.mcast_rate[band] - 1; -+ mcast_rate = vif->bss_conf.mcast_rate[band]; -+ if (mcast_rate > 0) -+ rateidx = mcast_rate - 1; -+ else -+ rateidx = ffs(vif->bss_conf.basic_rates) - 1; - - if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) - rateidx += ATH10K_MAC_FIRST_OFDM_RATE_IDX; 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 05d65e24ea..4e88c8a19f 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 @@ -9,58 +9,6 @@ mcast_rate set for a wifi-iface. Signed-off-by: Sven Eckelmann ---- a/ath10k-4.19/mac.c -+++ b/ath10k-4.19/mac.c -@@ -6625,6 +6625,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); -@@ -6633,6 +6634,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); -@@ -6659,6 +6661,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.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 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 deleted file mode 100644 index 180b0d5bf7..0000000000 --- a/package/kernel/ath10k-ct/patches/170-mac80211-pass-the-vif-to-cancel_remain_on_channel.patch +++ /dev/null @@ -1,41 +0,0 @@ -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 deleted file mode 100644 index 696da7b455..0000000000 --- a/package/kernel/ath10k-ct/patches/201-ath10k-4.16_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch +++ /dev/null @@ -1,1634 +0,0 @@ -From: Sebastian Gottschall - -Adds LED and GPIO Control support for 988x, 9887, 9888, 99x0, 9984 based -chipsets with on chipset connected led's using WMI Firmware API. The LED -device will get available named as "ath10k-phyX" at sysfs and can be controlled -with various triggers. adds also debugfs interface for gpio control. - -This patch is specific for OpenWRt base, as is use old backported package -with old wireless source. Support for QCA9984 is removed. -Reworked to use ath10k-ct custom source - - -Signed-off-by: Sebastian Gottschall -Reviewed-by: Steve deRosier -[kvalo: major reorg and cleanup] -Signed-off-by: Kalle Valo -Signed-off-by: Ansuel Smith ---- - -v13: - -* only compile tested! - -* fix all checkpatch warnings - -* fix commit log - -* sizeof(struct ath10k_gpiocontrol) -> sizeof(*gpio) - -* unsigned -> unsigned int - -* remove GPIOLIB code, that should be added in a separate patch - -* rename gpio.c to leds.c - -* add leds.h - -* rename some functions: - - ath10k_attach_led() -> ath10k_leds_register() - ath10k_unregister_led() -> ath10k_leds_unregister() - ath10k_reset_led_pin() -> ath10k_leds_start() - -* call ath10k_leds_unregister() before ath10k_thermal_unregister() to preserve ordering - -* call ath10k_leds_start() only from ath10k_core_start() and not from mac.c - -* rename struct ath10k_gpiocontrol as anonymous function under struct - ath10k::leds, no need for memory allocation - -* merge ath10k_add_led() to ath10k_attach_led(), which is it's only caller - -* remove #if IS_ENABLED() checks from most of places, memory savings from those were not worth it - -* Kconfig help text improvement and move it lower in the menu, also don't enable it by default - -* switch to set_brightness_blocking() so that the callback can sleep, - then no need to use ath10k_wmi_cmd_send_nowait() and can take mutex - to access ar->state - -* don't touch ath10k_wmi_pdev_get_temperature() - -* as QCA6174/QCA9377 are not (yet) supported don't add the command to WMI-TLV interface - -* remove debugfs interface, that should be added in another patch - -* cleanup includes - - - ath10k-4.16/Kconfig | 10 +++ - ath10k-4.16/Makefile | 1 + - ath10k-4.16/core.c | 22 +++++++ - ath10k-4.16/core.h | 9 ++- - ath10k-4.16/hw.h | 1 + - ath10k-4.16/leds.c | 103 ++++++++++++++++++++++++++++++ - ath10k-4.16/leds.h | 45 +++++++++++++ - ath10k-4.16/mac.c | 1 + - ath10k-4.16/wmi-ops.h | 32 ++++++++++ - ath10k-4.16/wmi-tlv.c | 2 + - ath10k-4.16/wmi.c | 54 ++++++++++++++++ - ath10k-4.16/wmi.h | 35 ++++++++++ - 12 files changed, 314 insertions(+), 1 deletion(-) - create mode 100644 ath10k-4.16/leds.c - create mode 100644 ath10k-4.16/leds.h ---- a/ath10k-4.19/Kconfig -+++ b/ath10k-4.19/Kconfig -@@ -64,6 +64,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-4.19/Makefile -+++ b/ath10k-4.19/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-4.19/core.c -+++ b/ath10k-4.19/core.c -@@ -35,6 +35,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; -@@ -72,6 +73,7 @@ static const struct ath10k_hw_params ath - .id = QCA988X_HW_2_0_VERSION, - .dev_id = QCA988X_2_0_DEVICE_ID, - .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 - .id = QCA9887_HW_1_0_VERSION, - .dev_id = QCA9887_1_0_DEVICE_ID, - .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, -@@ -301,6 +304,7 @@ static const struct ath10k_hw_params ath - .id = QCA99X0_HW_2_0_DEV_VERSION, - .dev_id = QCA99X0_2_0_DEVICE_ID, - .name = "qca99x0 hw2.0", -+ .led_pin = 17, - .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, - .uart_pin = 7, - .otp_exe_param = 0x00000700, -@@ -339,6 +343,7 @@ static const struct ath10k_hw_params ath - .id = QCA9984_HW_1_0_DEV_VERSION, - .dev_id = QCA9984_1_0_DEVICE_ID, - .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, -@@ -382,6 +387,7 @@ static const struct ath10k_hw_params ath - .id = QCA9888_HW_2_0_DEV_VERSION, - .dev_id = QCA9888_2_0_DEVICE_ID, - .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, -@@ -3176,6 +3182,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: -@@ -3430,9 +3440,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: -@@ -3490,6 +3509,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-4.19/core.h -+++ b/ath10k-4.19/core.h -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #include "htt.h" - #include "htc.h" -@@ -1138,7 +1139,6 @@ struct ath10k { - u32 low_5ghz_chan; - u32 high_5ghz_chan; - bool ani_enabled; -- - bool p2p; - bool ct_all_pkts_htt; /* CT firmware only: native-wifi for all pkts */ - -@@ -1391,6 +1391,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-4.19/hw.h -+++ b/ath10k-4.19/hw.h -@@ -508,6 +508,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-4.19/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-4.19/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-4.19/mac.c -+++ b/ath10k-4.19/mac.c -@@ -34,6 +34,7 @@ - #include "wmi-tlv.h" - #include "wmi-ops.h" - #include "wow.h" -+#include "leds.h" - - /*********/ - /* Rates */ ---- a/ath10k-4.19/wmi-ops.h -+++ b/ath10k-4.19/wmi-ops.h -@@ -218,7 +218,10 @@ struct wmi_ops { - struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value); - struct sk_buff *(*gen_pdev_get_tpc_table_cmdid)(struct ath10k *ar, - u32 param); -+ 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); -@@ -1079,6 +1082,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-4.19/wmi-tlv.c -+++ b/ath10k-4.19/wmi-tlv.c -@@ -3976,6 +3976,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-4.19/wmi.c -+++ b/ath10k-4.19/wmi.c -@@ -8071,6 +8071,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) -@@ -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, -+ .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 */ -@@ -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, -+ .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 */ -@@ -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, -+ .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 */ - }; - -@@ -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, -+ .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 */ -@@ -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, -+ .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-4.19/wmi.h -+++ b/ath10k-4.19/wmi.h -@@ -3084,6 +3084,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.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/201-ath10k-add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/package/kernel/ath10k-ct/patches/201-ath10k-add-LED-and-GPIO-controlling-support-for-various-chipsets.patch new file mode 100644 index 0000000000..c20800209d --- /dev/null +++ b/package/kernel/ath10k-ct/patches/201-ath10k-add-LED-and-GPIO-controlling-support-for-various-chipsets.patch @@ -0,0 +1,598 @@ +From: Sebastian Gottschall + +Adds LED and GPIO Control support for 988x, 9887, 9888, 99x0, 9984 based +chipsets with on chipset connected led's using WMI Firmware API. The LED +device will get available named as "ath10k-phyX" at sysfs and can be controlled +with various triggers. adds also debugfs interface for gpio control. + +This patch is specific for OpenWRt base, as is use old backported package +with old wireless source. Support for QCA9984 is removed. +Reworked to use ath10k-ct custom source + + +Signed-off-by: Sebastian Gottschall +Reviewed-by: Steve deRosier +[kvalo: major reorg and cleanup] +Signed-off-by: Kalle Valo +Signed-off-by: Ansuel Smith +--- + +v13: + +* only compile tested! + +* fix all checkpatch warnings + +* fix commit log + +* sizeof(struct ath10k_gpiocontrol) -> sizeof(*gpio) + +* unsigned -> unsigned int + +* remove GPIOLIB code, that should be added in a separate patch + +* rename gpio.c to leds.c + +* add leds.h + +* rename some functions: + + ath10k_attach_led() -> ath10k_leds_register() + ath10k_unregister_led() -> ath10k_leds_unregister() + ath10k_reset_led_pin() -> ath10k_leds_start() + +* call ath10k_leds_unregister() before ath10k_thermal_unregister() to preserve ordering + +* call ath10k_leds_start() only from ath10k_core_start() and not from mac.c + +* rename struct ath10k_gpiocontrol as anonymous function under struct + ath10k::leds, no need for memory allocation + +* merge ath10k_add_led() to ath10k_attach_led(), which is it's only caller + +* remove #if IS_ENABLED() checks from most of places, memory savings from those were not worth it + +* Kconfig help text improvement and move it lower in the menu, also don't enable it by default + +* switch to set_brightness_blocking() so that the callback can sleep, + then no need to use ath10k_wmi_cmd_send_nowait() and can take mutex + to access ar->state + +* don't touch ath10k_wmi_pdev_get_temperature() + +* as QCA6174/QCA9377 are not (yet) supported don't add the command to WMI-TLV interface + +* remove debugfs interface, that should be added in another patch + +* cleanup includes + + ath10k-5.4/Kconfig | 10 +++ + ath10k-5.4/Makefile | 1 + + ath10k-5.4/core.c | 22 +++++++ + ath10k-5.4/core.h | 9 ++- + ath10k-5.4/hw.h | 1 + + ath10k-5.4/leds.c | 103 ++++++++++++++++++++++++++++++ + ath10k-5.4/leds.h | 45 +++++++++++++ + ath10k-5.4/mac.c | 1 + + ath10k-5.4/wmi-ops.h | 32 ++++++++++ + ath10k-5.4/wmi-tlv.c | 2 + + ath10k-5.4/wmi.c | 54 ++++++++++++++++ + ath10k-5.4/wmi.h | 35 ++++++++++ + 12 files changed, 314 insertions(+), 1 deletion(-) + create mode 100644 ath10k-5.4/leds.c + create mode 100644 ath10k-5.4/leds.h + +--- 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 deleted file mode 100644 index c23c31417b..0000000000 --- a/package/kernel/ath10k-ct/patches/202-ath10k-4.16-use-tpt-trigger-by-default.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 79c9d7aabae1d1da9eea97d83b61e1517a8a2221 Mon Sep 17 00:00:00 2001 -From: Mathias Kresin -Date: Fri, 22 Jun 2018 18:59:44 +0200 -Subject: [PATCH] ath10k: use tpt LED trigger by default - -Use the tpt LED trigger for each created phy led. Ths way LEDs attached -to the ath10k GPIO pins are indicating the phy status and blink on -traffic. - -Signed-off-by: Mathias Kresin ---- - ath10k-4.16/core.h | 4 ++++ - ath10k-4.16/leds.c | 4 +--- - ath10k-4.16/mac.c | 2 +- - 3 files changed, 6 insertions(+), 4 deletions(-) - ---- a/ath10k-4.19/core.h -+++ b/ath10k-4.19/core.h -@@ -1491,6 +1491,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-4.19/leds.c -+++ b/ath10k-4.19/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-4.19/mac.c -+++ b/ath10k-4.19/mac.c -@@ -9987,7 +9987,7 @@ int ath10k_mac_register(struct ath10k *a - wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); - - #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.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/202-ath10k-use-tpt-trigger-by-default.patch b/package/kernel/ath10k-ct/patches/202-ath10k-use-tpt-trigger-by-default.patch new file mode 100644 index 0000000000..b1c7bae193 --- /dev/null +++ b/package/kernel/ath10k-ct/patches/202-ath10k-use-tpt-trigger-by-default.patch @@ -0,0 +1,53 @@ +From 79c9d7aabae1d1da9eea97d83b61e1517a8a2221 Mon Sep 17 00:00:00 2001 +From: Mathias Kresin +Date: Fri, 22 Jun 2018 18:59:44 +0200 +Subject: [PATCH] ath10k: use tpt LED trigger by default + +Use the tpt LED trigger for each created phy led. Ths way LEDs attached +to the ath10k GPIO pins are indicating the phy status and blink on +traffic. + +Signed-off-by: Mathias Kresin +--- + ath10k-5.4/core.h | 4 ++++ + ath10k-5.4/leds.c | 4 +--- + ath10k-5.4/mac.c | 2 +- + 3 files changed, 6 insertions(+), 4 deletions(-) + +--- 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/203-ath10k-Limit-available-channels-via-DT-ieee80211-fre.patch b/package/kernel/ath10k-ct/patches/203-ath10k-Limit-available-channels-via-DT-ieee80211-fre.patch deleted file mode 100644 index f47e9d64c0..0000000000 --- a/package/kernel/ath10k-ct/patches/203-ath10k-Limit-available-channels-via-DT-ieee80211-fre.patch +++ /dev/null @@ -1,39 +0,0 @@ -From bbf0a8af2261bc7ae39b227ff6a1e9f45a008c27 Mon Sep 17 00:00:00 2001 -From: Sven Eckelmann -Date: Mon, 30 Jul 2018 17:31:41 +0200 -Subject: [PATCH] ath10k: Limit available channels via DT ieee80211-freq-limit - -Tri-band devices (1x 2.4GHz + 2x 5GHz) often incorporate special filters in -the RX and TX path. These filtered channel can in theory still be used by -the hardware but the signal strength is reduced so much that it makes no -sense. - -There is already a DT property to limit the available channels but ath10k -has to manually call this functionality to limit the currrently set wiphy -channels further. - -Signed-off-by: Sven Eckelmann - -Forwarded: https://patchwork.kernel.org/patch/10549245/ ---- - drivers/net/wireless/ath/ath10k/mac.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/ath10k-4.19/mac.c -+++ b/ath10k-4.19/mac.c -@@ -18,6 +18,7 @@ - - #include "mac.h" - -+#include - #include - #include - #include -@@ -9711,6 +9712,7 @@ int ath10k_mac_register(struct ath10k *a - ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band; - } - -+ wiphy_read_of_freq_limits(ar->hw->wiphy); - ath10k_mac_setup_ht_vht_cap(ar); - - ar->hw->wiphy->interface_modes = 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 70f4fb0546..c527430898 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 @@ -1,31 +1,3 @@ ---- a/ath10k-4.19/htt.h -+++ b/ath10k-4.19/htt.h -@@ -237,7 +237,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.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 { 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 0b691217b2..f559a78f29 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 @@ -1,103 +1,3 @@ ---- a/ath10k-4.19/pci.c -+++ b/ath10k-4.19/pci.c -@@ -142,7 +142,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, - }, - -@@ -151,7 +155,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, - }, - -@@ -178,7 +186,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, - }, - -@@ -203,7 +215,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.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 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 deleted file mode 100644 index 0ff885d95a..0000000000 --- a/package/kernel/ath10k-ct/patches/976-ath10k-Check-if-station-exists-before-forwarding-tx-.patch +++ /dev/null @@ -1,81 +0,0 @@ -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;