| From 38cce019a8791ff3d295bd936362432cc592e061 Mon Sep 17 00:00:00 2001 |
| From: Shayne Chen <shayne.chen@mediatek.com> |
| Date: Tue, 12 Mar 2024 11:27:11 +0800 |
| Subject: [PATCH 05/61] sync backports patches/ath10k |
| |
| --- |
| drivers/net/wireless/ath/ath10k/Kconfig | 16 ++++ |
| drivers/net/wireless/ath/ath10k/Makefile | 3 +- |
| drivers/net/wireless/ath/ath10k/core.c | 34 ++++++++ |
| drivers/net/wireless/ath/ath10k/core.h | 12 +++ |
| drivers/net/wireless/ath/ath10k/htt.h | 4 + |
| drivers/net/wireless/ath/ath10k/hw.h | 1 + |
| drivers/net/wireless/ath/ath10k/leds.c | 101 ++++++++++++++++++++++ |
| drivers/net/wireless/ath/ath10k/leds.h | 41 +++++++++ |
| drivers/net/wireless/ath/ath10k/mac.c | 66 +++++++++++++- |
| drivers/net/wireless/ath/ath10k/pci.c | 16 ++++ |
| drivers/net/wireless/ath/ath10k/thermal.h | 2 +- |
| drivers/net/wireless/ath/ath10k/wmi-ops.h | 32 +++++++ |
| drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 + |
| drivers/net/wireless/ath/ath10k/wmi.c | 54 ++++++++++++ |
| drivers/net/wireless/ath/ath10k/wmi.h | 35 ++++++++ |
| local-symbols | 2 + |
| 16 files changed, 415 insertions(+), 6 deletions(-) |
| create mode 100644 drivers/net/wireless/ath/ath10k/leds.c |
| create mode 100644 drivers/net/wireless/ath/ath10k/leds.h |
| |
| diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig |
| index d10c65d..5cabe0e 100644 |
| --- a/drivers/net/wireless/ath/ath10k/Kconfig |
| +++ b/drivers/net/wireless/ath/ath10k/Kconfig |
| @@ -72,6 +72,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 |
| @@ -87,6 +97,12 @@ config ATH10K_TRACING |
| help |
| Select this to ath10k use tracing infrastructure. |
| |
| +config ATH10K_THERMAL |
| + bool "Atheros ath10k thermal monitoring support" |
| + depends on THERMAL |
| + ---help--- |
| + Select this to ath10k use hwmon for thermal measurement. |
| + |
| config ATH10K_DFS_CERTIFIED |
| bool "Atheros DFS support for certified platforms" |
| depends on ATH10K && CFG80211_CERTIFICATION_ONUS |
| diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile |
| index 24d846a..e040d84 100644 |
| --- a/drivers/net/wireless/ath/ath10k/Makefile |
| +++ b/drivers/net/wireless/ath/ath10k/Makefile |
| @@ -18,7 +18,8 @@ ath10k_core-y += mac.o \ |
| ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o |
| ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o |
| ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o |
| -ath10k_core-$(CONFIG_THERMAL) += thermal.o |
| +ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o |
| +ath10k_core-$(CPTCFG_ATH10K_LEDS) += leds.o |
| ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o |
| ath10k_core-$(CONFIG_PM) += wow.o |
| ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o |
| diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c |
| index 9ce6f49..a168fdf 100644 |
| --- a/drivers/net/wireless/ath/ath10k/core.c |
| +++ b/drivers/net/wireless/ath/ath10k/core.c |
| @@ -9,6 +9,7 @@ |
| #include <linux/module.h> |
| #include <linux/firmware.h> |
| #include <linux/of.h> |
| +#include <linux/of_net.h> |
| #include <linux/property.h> |
| #include <linux/dmi.h> |
| #include <linux/ctype.h> |
| @@ -27,6 +28,7 @@ |
| #include "testmode.h" |
| #include "wmi-ops.h" |
| #include "coredump.h" |
| +#include "leds.h" |
| |
| unsigned int ath10k_debug_mask; |
| EXPORT_SYMBOL(ath10k_debug_mask); |
| @@ -66,6 +68,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
| .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, |
| @@ -149,6 +152,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
| .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, |
| @@ -396,6 +400,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
| .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, |
| @@ -443,6 +448,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
| .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, |
| @@ -497,6 +503,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
| .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, |
| @@ -3239,6 +3246,10 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode, |
| goto err_hif_stop; |
| } |
| |
| + status = ath10k_leds_start(ar); |
| + if (status) |
| + goto err_hif_stop; |
| + |
| return 0; |
| |
| err_hif_stop: |
| @@ -3405,6 +3416,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar) |
| |
| device_get_mac_address(ar->dev, ar->mac_addr); |
| |
| + of_get_mac_address(ar->dev->of_node, ar->mac_addr); |
| + |
| ret = ath10k_core_init_firmware_features(ar); |
| if (ret) { |
| ath10k_err(ar, "fatal problem with firmware features: %d\n", |
| @@ -3497,9 +3510,18 @@ static void ath10k_core_register_work(struct work_struct *work) |
| 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: |
| @@ -3524,6 +3546,16 @@ int ath10k_core_register(struct ath10k *ar, |
| |
| queue_work(ar->workqueue, &ar->register_work); |
| |
| + /* OpenWrt requires all PHYs to be initialized to create the |
| + * configuration files during bootup. ath10k violates this |
| + * because it delays the creation of the PHY to a not well defined |
| + * point in the future. |
| + * |
| + * Forcing the work to be done immediately works around this problem |
| + * but may also delay the boot when firmware images cannot be found. |
| + */ |
| + flush_workqueue(ar->workqueue); |
| + |
| return 0; |
| } |
| EXPORT_SYMBOL(ath10k_core_register); |
| @@ -3535,6 +3567,8 @@ void ath10k_core_unregister(struct ath10k *ar) |
| 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 |
| diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h |
| index 2435291..8546f2f 100644 |
| --- a/drivers/net/wireless/ath/ath10k/core.h |
| +++ b/drivers/net/wireless/ath/ath10k/core.h |
| @@ -15,6 +15,7 @@ |
| #include <linux/pci.h> |
| #include <linux/uuid.h> |
| #include <linux/time.h> |
| +#include <linux/leds.h> |
| |
| #include "htt.h" |
| #include "htc.h" |
| @@ -1256,6 +1257,13 @@ struct ath10k { |
| bool utf_monitor; |
| } 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 rx_crc_err_drop; |
| @@ -1305,6 +1313,10 @@ struct ath10k { |
| s32 tx_power_2g_limit; |
| s32 tx_power_5g_limit; |
| |
| +#ifdef CPTCFG_MAC80211_LEDS |
| + const char *led_default_trigger; |
| +#endif |
| + |
| /* must be last */ |
| u8 drv_priv[] __aligned(sizeof(void *)); |
| }; |
| diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h |
| index 603f6de..bea1d16 100644 |
| --- a/drivers/net/wireless/ath/ath10k/htt.h |
| +++ b/drivers/net/wireless/ath/ath10k/htt.h |
| @@ -236,7 +236,11 @@ enum htt_rx_ring_flags { |
| }; |
| |
| #define HTT_RX_RING_SIZE_MIN 128 |
| +#ifndef CONFIG_ATH10K_SMALLBUFFERS |
| #define HTT_RX_RING_SIZE_MAX 2048 |
| +#else |
| +#define HTT_RX_RING_SIZE_MAX 512 |
| +#endif |
| #define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX |
| #define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1) |
| #define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1) |
| diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h |
| index 3b26994..aeada6c 100644 |
| --- a/drivers/net/wireless/ath/ath10k/hw.h |
| +++ b/drivers/net/wireless/ath/ath10k/hw.h |
| @@ -520,6 +520,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 |
| diff --git a/drivers/net/wireless/ath/ath10k/leds.c b/drivers/net/wireless/ath/ath10k/leds.c |
| new file mode 100644 |
| index 0000000..be8f255 |
| --- /dev/null |
| +++ b/drivers/net/wireless/ath/ath10k/leds.c |
| @@ -0,0 +1,101 @@ |
| +/* |
| + * Copyright (c) 2005-2011 Atheros Communications Inc. |
| + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. |
| + * Copyright (c) 2018 Sebastian Gottschall <s.gottschall@dd-wrt.com> |
| + * 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 <linux/leds.h> |
| + |
| +#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; |
| + ar->leds.cdev.default_trigger = ar->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); |
| +} |
| + |
| diff --git a/drivers/net/wireless/ath/ath10k/leds.h b/drivers/net/wireless/ath/ath10k/leds.h |
| new file mode 100644 |
| index 0000000..a0f5c84 |
| --- /dev/null |
| +++ b/drivers/net/wireless/ath/ath10k/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 CPTCFG_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_ */ |
| diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c |
| index ec43216..f179dff 100644 |
| --- a/drivers/net/wireless/ath/ath10k/mac.c |
| +++ b/drivers/net/wireless/ath/ath10k/mac.c |
| @@ -25,6 +25,7 @@ |
| #include "wmi-tlv.h" |
| #include "wmi-ops.h" |
| #include "wow.h" |
| +#include "leds.h" |
| |
| /*********/ |
| /* Rates */ |
| @@ -1021,6 +1022,40 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar) |
| return ar->last_wmi_vdev_start_status; |
| } |
| |
| +static u32 ath10k_get_max_antenna_gain(struct ath10k *ar, |
| + u32 ch_max_antenna_gain) |
| +{ |
| + u32 max_antenna_gain; |
| + |
| + if (ar->dfs_detector && ar->dfs_detector->region == NL80211_DFS_FCC) { |
| + /* FCC allows maximum antenna gain of 6 dBi. 15.247(b)(4): |
| + * |
| + * > (4) The conducted output power limit |
| + * > specified in paragraph (b) of this section |
| + * > is based on the use of antennas |
| + * > with directional gains that do not exceed |
| + * > 6 dBi. Except as shown in paragraph |
| + * > (c) of this section, if transmitting |
| + * > antennas of directional gain greater |
| + * > than 6 dBi are used, the conducted |
| + * > output power from the intentional radiator |
| + * > shall be reduced below the stated |
| + * > values in paragraphs (b)(1), (b)(2), |
| + * > and (b)(3) of this section, as appropriate, |
| + * > by the amount in dB that the |
| + * > directional gain of the antenna exceeds |
| + * > 6 dBi. |
| + * |
| + * https://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol1/pdf/CFR-2013-title47-vol1-sec15-247.pdf |
| + */ |
| + max_antenna_gain = 6; |
| + } else { |
| + max_antenna_gain = 0; |
| + } |
| + |
| + return max(ch_max_antenna_gain, max_antenna_gain); |
| +} |
| + |
| static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) |
| { |
| struct cfg80211_chan_def *chandef = NULL; |
| @@ -1053,7 +1088,8 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) |
| arg.channel.min_power = 0; |
| arg.channel.max_power = channel->max_power * 2; |
| arg.channel.max_reg_power = channel->max_reg_power * 2; |
| - arg.channel.max_antenna_gain = channel->max_antenna_gain; |
| + arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar, |
| + channel->max_antenna_gain); |
| |
| reinit_completion(&ar->vdev_setup_done); |
| reinit_completion(&ar->vdev_delete_done); |
| @@ -1499,7 +1535,8 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, |
| arg.channel.min_power = 0; |
| arg.channel.max_power = chandef->chan->max_power * 2; |
| arg.channel.max_reg_power = chandef->chan->max_reg_power * 2; |
| - arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain; |
| + arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar, |
| + chandef->chan->max_antenna_gain); |
| |
| if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { |
| arg.ssid = arvif->u.ap.ssid; |
| @@ -3430,7 +3467,8 @@ static int ath10k_update_channel_list(struct ath10k *ar) |
| ch->min_power = 0; |
| ch->max_power = channel->max_power * 2; |
| ch->max_reg_power = channel->max_reg_power * 2; |
| - ch->max_antenna_gain = channel->max_antenna_gain; |
| + ch->max_antenna_gain = ath10k_get_max_antenna_gain(ar, |
| + channel->max_antenna_gain); |
| ch->reg_class_id = 0; /* FIXME */ |
| |
| /* FIXME: why use only legacy modes, why not any |
| @@ -9918,6 +9956,21 @@ static int ath10k_mac_init_rd(struct ath10k *ar) |
| return 0; |
| } |
| |
| +#ifdef CPTCFG_MAC80211_LEDS |
| +static const struct ieee80211_tpt_blink ath10k_tpt_blink[] = { |
| + { .throughput = 0 * 1024, .blink_time = 334 }, |
| + { .throughput = 1 * 1024, .blink_time = 260 }, |
| + { .throughput = 2 * 1024, .blink_time = 220 }, |
| + { .throughput = 5 * 1024, .blink_time = 190 }, |
| + { .throughput = 10 * 1024, .blink_time = 170 }, |
| + { .throughput = 25 * 1024, .blink_time = 150 }, |
| + { .throughput = 54 * 1024, .blink_time = 130 }, |
| + { .throughput = 120 * 1024, .blink_time = 110 }, |
| + { .throughput = 265 * 1024, .blink_time = 80 }, |
| + { .throughput = 586 * 1024, .blink_time = 50 }, |
| +}; |
| +#endif |
| + |
| int ath10k_mac_register(struct ath10k *ar) |
| { |
| static const u32 cipher_suites[] = { |
| @@ -10036,7 +10089,6 @@ int ath10k_mac_register(struct ath10k *ar) |
| ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA); |
| ieee80211_hw_set(ar->hw, QUEUE_CONTROL); |
| ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG); |
| - ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK); |
| |
| if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) |
| ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL); |
| @@ -10280,6 +10332,12 @@ int ath10k_mac_register(struct ath10k *ar) |
| |
| ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; |
| |
| +#ifdef CPTCFG_MAC80211_LEDS |
| + 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 |
| + |
| ret = ieee80211_register_hw(ar->hw); |
| if (ret) { |
| ath10k_err(ar, "failed to register ieee80211: %d\n", ret); |
| diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c |
| index d7ac5ae..c7e8e90 100644 |
| --- a/drivers/net/wireless/ath/ath10k/pci.c |
| +++ b/drivers/net/wireless/ath/ath10k/pci.c |
| @@ -132,7 +132,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = { |
| .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, |
| }, |
| |
| @@ -141,7 +145,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = { |
| .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, |
| }, |
| |
| @@ -168,7 +176,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = { |
| .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, |
| }, |
| |
| @@ -193,7 +205,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = { |
| .flags = CE_ATTR_FLAGS, |
| .src_nentries = 0, |
| .src_sz_max = 2048, |
| +#ifndef CONFIG_ATH10K_SMALLBUFFERS |
| .dest_nentries = 128, |
| +#else |
| + .dest_nentries = 96, |
| +#endif |
| .recv_cb = ath10k_pci_pktlog_rx_cb, |
| }, |
| |
| diff --git a/drivers/net/wireless/ath/ath10k/thermal.h b/drivers/net/wireless/ath/ath10k/thermal.h |
| index 1f4de9f..fcfa3c2 100644 |
| --- a/drivers/net/wireless/ath/ath10k/thermal.h |
| +++ b/drivers/net/wireless/ath/ath10k/thermal.h |
| @@ -25,7 +25,7 @@ struct ath10k_thermal { |
| int temperature; |
| }; |
| |
| -#if IS_REACHABLE(CONFIG_THERMAL) |
| +#if IS_REACHABLE(CPTCFG_ATH10K_THERMAL) |
| int ath10k_thermal_register(struct ath10k *ar); |
| void ath10k_thermal_unregister(struct ath10k *ar); |
| void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); |
| diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h |
| index aa57d80..f3f6b59 100644 |
| --- a/drivers/net/wireless/ath/ath10k/wmi-ops.h |
| +++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h |
| @@ -226,7 +226,10 @@ struct wmi_ops { |
| const struct wmi_bb_timing_cfg_arg *arg); |
| struct sk_buff *(*gen_per_peer_per_tid_cfg)(struct ath10k *ar, |
| const struct wmi_per_peer_per_tid_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); |
| @@ -1122,6 +1125,35 @@ ath10k_wmi_force_fw_hang(struct ath10k *ar, |
| 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) |
| { |
| diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c |
| index aed97fd..dbaf26d 100644 |
| --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c |
| +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c |
| @@ -4606,6 +4606,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 = { |
| diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c |
| index 5d80988..6b428b4 100644 |
| --- a/drivers/net/wireless/ath/ath10k/wmi.c |
| +++ b/drivers/net/wireless/ath/ath10k/wmi.c |
| @@ -7493,6 +7493,49 @@ ath10k_wmi_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id, |
| 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) |
| @@ -9157,6 +9200,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 */ |
| @@ -9227,6 +9273,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 */ |
| @@ -9299,6 +9347,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 */ |
| }; |
| |
| @@ -9370,6 +9420,8 @@ static const struct wmi_ops wmi_10_2_4_ops = { |
| 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 */ |
| @@ -9451,6 +9503,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) |
| diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h |
| index 2379501..0faefc0 100644 |
| --- a/drivers/net/wireless/ath/ath10k/wmi.h |
| +++ b/drivers/net/wireless/ath/ath10k/wmi.h |
| @@ -3034,6 +3034,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/local-symbols b/local-symbols |
| index b5745bf..3d81ba5 100644 |
| --- a/local-symbols |
| +++ b/local-symbols |
| @@ -160,6 +160,8 @@ ATH10K_SNOC= |
| ATH10K_DEBUG= |
| ATH10K_DEBUGFS= |
| ATH10K_SPECTRAL= |
| +ATH10K_THERMAL= |
| +ATH10K_LEDS= |
| ATH10K_TRACING= |
| ATH10K_DFS_CERTIFIED= |
| WCN36XX= |
| -- |
| 2.39.2 |
| |