2016-11-17 11:44:07

by Tamizh Chelvam Raja

[permalink] [raw]
Subject: [PATCHv2 0/4] ath10k: Add support for BTCOEX feature.

From: Tamizh chelvam <[email protected]>

This patch set add support to enable/disable BTCOEX via nl80211,
also support to update BTCOEX priority value for 10.4 based firmware.
Document the dt entry in qcom,ath10k.txt and reads btcoex support
flag and btcoex gpio pin detail from dt.

Tamizh chelvam (4):
ath10k: Add support to enable or disable btcoex via nl80211
ath10k: Add support to update btcoex priority value via nl80211
dt: bindings: add new dt entry for BTCOEX feature in qcom,ath10k.txt
ath10k: Add support to read btcoex related data from DT

V2:

* Added device tree list in CC
* fixed mutex unlock issue in
"ath10k: Add support to update btcoex priority value via nl80211"

.../bindings/net/wireless/qcom,ath10k.txt | 4 +
drivers/net/wireless/ath/ath10k/core.c | 44 +++++-
drivers/net/wireless/ath/ath10k/core.h | 9 ++
drivers/net/wireless/ath/ath10k/debug.c | 40 +-----
drivers/net/wireless/ath/ath10k/mac.c | 140 +++++++++++++++++++-
drivers/net/wireless/ath/ath10k/mac.h | 1 +
drivers/net/wireless/ath/ath10k/wmi-ops.h | 19 +++
drivers/net/wireless/ath/ath10k/wmi.c | 20 +++
drivers/net/wireless/ath/ath10k/wmi.h | 20 +++
9 files changed, 261 insertions(+), 36 deletions(-)

--
1.7.9.5


2016-11-17 11:44:38

by Tamizh Chelvam Raja

[permalink] [raw]
Subject: [PATCHv2 3/4] dt: bindings: add new dt entry for BTCOEX feature in qcom,ath10k.txt

From: Tamizh chelvam <[email protected]>

There two things done in this patch.

1) 'btcoex_support' flag for BTCOEX feature support by the hardware.
2) 'wlan_btcoex_gpio' is used to fill wlan priority pin number for
BTCOEX priority feature support.

Signed-off-by: Tamizh chelvam <[email protected]>
---
.../bindings/net/wireless/qcom,ath10k.txt | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
index 74d7f0a..08150e2d 100644
--- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
@@ -46,6 +46,10 @@ Optional properties:
hw versions.
- qcom,ath10k-pre-calibration-data : pre calibration data as an array,
the length can vary between hw versions.
+- btcoex_support : should contain eithr "0" or "1" to indicate btcoex
+ support by the hardware.
+- btcoex_gpio_pin : btcoex gpio pin number for the device which
+ supports BTCOEX.

Example (to supply the calibration data alone):

--
1.7.9.5

2016-11-18 14:44:09

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCHv2 3/4] dt: bindings: add new dt entry for BTCOEX feature in qcom,ath10k.txt

On Thu, Nov 17, 2016 at 05:14:23PM +0530, [email protected] wrote:
> From: Tamizh chelvam <[email protected]>
>
> There two things done in this patch.
>
> 1) 'btcoex_support' flag for BTCOEX feature support by the hardware.
> 2) 'wlan_btcoex_gpio' is used to fill wlan priority pin number for
> BTCOEX priority feature support.
>
> Signed-off-by: Tamizh chelvam <[email protected]>
> ---
> .../bindings/net/wireless/qcom,ath10k.txt | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
> index 74d7f0a..08150e2d 100644
> --- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
> +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
> @@ -46,6 +46,10 @@ Optional properties:
> hw versions.
> - qcom,ath10k-pre-calibration-data : pre calibration data as an array,
> the length can vary between hw versions.
> +- btcoex_support : should contain eithr "0" or "1" to indicate btcoex
> + support by the hardware.

This is BT coexistence? Make this boolean and n

> +- btcoex_gpio_pin : btcoex gpio pin number for the device which
> + supports BTCOEX.

This is a pin number on the chip, not any pin number Linux GPIO subsys
cares about, right? Is there a connection to the host too, or this is
internal between BT and WiFi?

Do you really need 2 properties? Does supporting this feature require
the GPIO? If so, then the first property is redundant.

Needs vendor prefix and don't use '_'. Should be something like
'qcom,bt-coexist-gpio-pin'.

Rob

2016-11-17 11:44:51

by Tamizh Chelvam Raja

[permalink] [raw]
Subject: [PATCHv2 4/4] ath10k: Add support to read btcoex related data from DT

From: Tamizh chelvam <[email protected]>

BTCOEX feature is not supported by all qca40xx chipsets.
Since btcoex enabled by default in firmware, host needs to
enable COEX support depends on the hardware. This patch is
used to read btcoex_support flag and btcoex gpio pin
number from DT. Depends on the btcoex_support flag value
host will expose BTCOEX support and btcoex gpio pin
number to target.

Signed-off-by: Tamizh chelvam <[email protected]>
---
drivers/net/wireless/ath/ath10k/core.c | 44 ++++++++++++++++++++++++++++++-
drivers/net/wireless/ath/ath10k/core.h | 9 +++++++
drivers/net/wireless/ath/ath10k/debug.c | 3 +++
drivers/net/wireless/ath/ath10k/mac.c | 4 ++-
drivers/net/wireless/ath/ath10k/wmi.c | 1 +
drivers/net/wireless/ath/ath10k/wmi.h | 2 ++
6 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 7005e2a..eec2436 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1439,6 +1439,39 @@ static int ath10k_download_cal_data(struct ath10k *ar)
return 0;
}

+static void ath10k_core_fetch_btcoex_dt(struct ath10k *ar)
+{
+ struct device_node *node;
+ u32 btcoex_support = 0;
+ int ret;
+
+ node = ar->dev->of_node;
+ if (!node)
+ goto out;
+
+ ret = of_property_read_u32(node, "btcoex_support", &btcoex_support);
+ if (ret) {
+ ar->btcoex_support = ATH10K_DT_BTCOEX_NOT_FOUND;
+ goto out;
+ }
+
+ if (btcoex_support)
+ ar->btcoex_support = ATH10K_DT_BTCOEX_SUPPORTED;
+ else
+ ar->btcoex_support = ATH10K_DT_BTCOEX_NOT_SUPPORTED;
+
+ ret = of_property_read_u32(node, "btcoex_gpio_pin",
+ &ar->btcoex_gpio_pin);
+ if (ret) {
+ ar->btcoex_gpio_pin = -1;
+ goto out;
+ }
+
+out:
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "btcoex support flag :%d gpio %d\n",
+ ar->btcoex_support, ar->btcoex_gpio_pin);
+}
+
static int ath10k_init_uart(struct ath10k *ar)
{
int ret;
@@ -1920,14 +1953,23 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map))
val |= WMI_10_4_BSS_CHANNEL_INFO_64;

+ ath10k_core_fetch_btcoex_dt(ar);
+
/* 10.4 firmware supports BT-Coex without reloading firmware
* via pdev param. To support Bluetooth coexistence pdev param,
* WMI_COEX_GPIO_SUPPORT of extended resource config should be
* enabled always.
*/
+
+ /* we can still enable BTCOEX if firmware has the support
+ * eventhough btceox_support value is
+ * ATH10K_DT_BTCOEX_NOT_FOUND
+ */
+
if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
- ar->running_fw->fw_file.fw_features))
+ ar->running_fw->fw_file.fw_features) &&
+ ar->btcoex_support != ATH10K_DT_BTCOEX_NOT_SUPPORTED)
val |= WMI_10_4_COEX_GPIO_SUPPORT;

status = ath10k_mac_ext_resource_config(ar, val);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index e8decfa..440e41c 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -656,6 +656,12 @@ enum ath10k_tx_pause_reason {
ATH10K_TX_PAUSE_MAX,
};

+enum ath10k_dt_btcoex_support_flag {
+ ATH10K_DT_BTCOEX_NOT_FOUND,
+ ATH10K_DT_BTCOEX_SUPPORTED,
+ ATH10K_DT_BTCOEX_NOT_SUPPORTED,
+};
+
struct ath10k_fw_file {
const struct firmware *firmware;

@@ -924,6 +930,9 @@ struct ath10k {
u32 reg_ack_cts_timeout_orig;
} fw_coverage;

+ enum ath10k_dt_btcoex_support_flag btcoex_support;
+ int btcoex_gpio_pin;
+
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
};
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index ea30fbe..e0e316c 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -2149,6 +2149,9 @@ static ssize_t ath10k_write_btcoex(struct file *file,
if (strtobool(buf, &val) != 0)
return -EINVAL;

+ if (ar->btcoex_support == ATH10K_DT_BTCOEX_NOT_SUPPORTED)
+ return -EOPNOTSUPP;
+
mutex_lock(&ar->conf_mutex);
ret = ath10k_mac_set_btcoex(ar, val);
if (!ret)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index ce5d529..25d6c0a 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4562,9 +4562,11 @@ static int ath10k_start(struct ieee80211_hw *hw)
}

param = ar->wmi.pdev_param->enable_btcoex;
+
if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
- ar->running_fw->fw_file.fw_features)) {
+ ar->running_fw->fw_file.fw_features) &&
+ ar->btcoex_support != ATH10K_DT_BTCOEX_NOT_SUPPORTED) {
ret = ath10k_wmi_pdev_set_param(ar, param, 0);
if (ret) {
ath10k_warn(ar,
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index de35c17..1eb5678 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -7811,6 +7811,7 @@ static int ath10k_wmi_10_4_op_get_vdev_subtype(struct ath10k *ar,
cmd = (struct wmi_ext_resource_config_10_4_cmd *)skb->data;
cmd->host_platform_config = __cpu_to_le32(type);
cmd->fw_feature_bitmap = __cpu_to_le32(fw_feature_bitmap);
+ cmd->btcoex_gpio_pin = __cpu_to_le32(ar->btcoex_gpio_pin);

ath10k_dbg(ar, ATH10K_DBG_WMI,
"wmi ext resource config host type %d firmware feature bitmap %08x\n",
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 3a739e3..f83a21e 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -2734,6 +2734,8 @@ struct wmi_ext_resource_config_10_4_cmd {
__le32 host_platform_config;
/* see enum wmi_10_4_feature_mask */
__le32 fw_feature_bitmap;
+ /* Contains btcoex gpio pin number */
+ __le32 btcoex_gpio_pin;
};

struct wmi_set_coex_param_10_4_cmd {
--
1.7.9.5

2016-11-23 10:20:23

by Tamizh chelvam

[permalink] [raw]
Subject: Re: [PATCHv2 3/4] dt: bindings: add new dt entry for BTCOEX feature in qcom,ath10k.txt

Thanks for the comments.

On 2016-11-18 20:14, Rob Herring wrote:
> On Thu, Nov 17, 2016 at 05:14:23PM +0530, [email protected]
> wrote:
>> From: Tamizh chelvam <[email protected]>
>>
>> There two things done in this patch.
>>
>> 1) 'btcoex_support' flag for BTCOEX feature support by the hardware.
>> 2) 'wlan_btcoex_gpio' is used to fill wlan priority pin number for
>> BTCOEX priority feature support.
>>
>> Signed-off-by: Tamizh chelvam <[email protected]>
>> ---
>> .../bindings/net/wireless/qcom,ath10k.txt | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git
>> a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
>> b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
>> index 74d7f0a..08150e2d 100644
>> --- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
>> +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
>> @@ -46,6 +46,10 @@ Optional properties:
>> hw versions.
>> - qcom,ath10k-pre-calibration-data : pre calibration data as an
>> array,
>> the length can vary between hw versions.
>> +- btcoex_support : should contain eithr "0" or "1" to indicate
>> btcoex
>> + support by the hardware.
>
> This is BT coexistence? Make this boolean and n

Yes, this is BT coexistence. And I didn't get what are you trying to say
in this "Make this boolean and n"
>
>> +- btcoex_gpio_pin : btcoex gpio pin number for the device which
>> + supports BTCOEX.
>
> This is a pin number on the chip, not any pin number Linux GPIO subsys
> cares about, right? Is there a connection to the host too, or this is
> internal between BT and WiFi?

This is internal between BT and wifi.
>
> Do you really need 2 properties? Does supporting this feature require
> the GPIO? If so, then the first property is redundant.
>
Target/driver can hard copy this gpio pin for some chipsets and there we
will need btcoex_support flag to find the btcoex support.

> Needs vendor prefix and don't use '_'. Should be something like
> 'qcom,bt-coexist-gpio-pin'.
>
Sure I'll update this and send in v3 patch

2016-11-17 17:03:21

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCHv2 2/4] ath10k: Add support to update btcoex priority value via nl80211

Hi Tamizh,

[auto build test ERROR on ath6kl/ath-next]
[also build test ERROR on next-20161117]
[cannot apply to v4.9-rc5]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/c_traja-qti-qualcomm-com/ath10k-Add-support-for-BTCOEX-feature/20161117-200322
base: https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git ath-next
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386

All errors (new ones prefixed by >>):

drivers/net/wireless/ath/ath10k/mac.c:7506:35: warning: 'struct cfg80211_btcoex_priority' declared inside parameter list will not be visible outside of this definition or declaration
ath10k_mac_get_btcoex_prio(struct cfg80211_btcoex_priority *btcoex_priority)
^~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c: In function 'ath10k_mac_get_btcoex_prio':
>> drivers/net/wireless/ath/ath10k/mac.c:7510:21: error: dereferencing pointer to incomplete type 'struct cfg80211_btcoex_priority'
if (btcoex_priority->wlan_be_preferred)
^~
>> drivers/net/wireless/ath/ath10k/mac.c:7511:18: error: 'WIPHY_WLAN_BE_PREFERRED' undeclared (first use in this function)
btcoex_prio |= WIPHY_WLAN_BE_PREFERRED;
^~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c:7511:18: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/net/wireless/ath/ath10k/mac.c:7514:18: error: 'WIPHY_WLAN_BK_PREFERRED' undeclared (first use in this function)
btcoex_prio |= WIPHY_WLAN_BK_PREFERRED;
^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/net/wireless/ath/ath10k/mac.c:7517:18: error: 'WIPHY_WLAN_VI_PREFERRED' undeclared (first use in this function)
btcoex_prio |= WIPHY_WLAN_VI_PREFERRED;
^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/net/wireless/ath/ath10k/mac.c:7520:18: error: 'WIPHY_WLAN_VO_PREFERRED' undeclared (first use in this function)
btcoex_prio |= WIPHY_WLAN_VO_PREFERRED;
^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/net/wireless/ath/ath10k/mac.c:7523:18: error: 'WIPHY_WLAN_BEACON_PREFERRED' undeclared (first use in this function)
btcoex_prio |= WIPHY_WLAN_BEACON_PREFERRED;
^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/net/wireless/ath/ath10k/mac.c:7526:18: error: 'WIPHY_WLAN_MGMT_PREFERRED' undeclared (first use in this function)
btcoex_prio |= WIPHY_WLAN_MGMT_PREFERRED;
^~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c: At top level:
drivers/net/wireless/ath/ath10k/mac.c:7532:11: warning: 'struct cfg80211_btcoex_priority' declared inside parameter list will not be visible outside of this definition or declaration
struct cfg80211_btcoex_priority *btcoex_priority)
^~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c: In function 'ath10k_mac_op_set_btcoex_priority':
>> drivers/net/wireless/ath/ath10k/mac.c:7551:43: error: passing argument 1 of 'ath10k_mac_get_btcoex_prio' from incompatible pointer type [-Werror=incompatible-pointer-types]
btcoex_prio = ath10k_mac_get_btcoex_prio(btcoex_priority);
^~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c:7506:1: note: expected 'struct cfg80211_btcoex_priority *' but argument is of type 'struct cfg80211_btcoex_priority *'
ath10k_mac_get_btcoex_prio(struct cfg80211_btcoex_priority *btcoex_priority)
^~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c: At top level:
drivers/net/wireless/ath/ath10k/mac.c:7611:2: error: unknown field 'set_btcoex' specified in initializer
.set_btcoex = ath10k_mac_op_set_btcoex,
^
drivers/net/wireless/ath/ath10k/mac.c:7611:36: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.set_btcoex = ath10k_mac_op_set_btcoex,
^~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c:7611:36: note: (near initialization for 'ath10k_ops.reconfig_complete')
>> drivers/net/wireless/ath/ath10k/mac.c:7612:2: error: unknown field 'set_btcoex_priority' specified in initializer
.set_btcoex_priority = ath10k_mac_op_set_btcoex_priority,
^
drivers/net/wireless/ath/ath10k/mac.c:7612:26: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.set_btcoex_priority = ath10k_mac_op_set_btcoex_priority,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c:7612:26: note: (near initialization for 'ath10k_ops.ipv6_addr_change')
drivers/net/wireless/ath/ath10k/mac.c: In function 'ath10k_mac_register':
>> drivers/net/wireless/ath/ath10k/mac.c:8203:16: error: 'struct wiphy' has no member named 'btcoex_support_flags'
ar->hw->wiphy->btcoex_support_flags =
^~
drivers/net/wireless/ath/ath10k/mac.c:8204:4: error: 'WIPHY_WLAN_BE_PREFERRED' undeclared (first use in this function)
WIPHY_WLAN_BE_PREFERRED |
^~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c:8205:4: error: 'WIPHY_WLAN_BK_PREFERRED' undeclared (first use in this function)
WIPHY_WLAN_BK_PREFERRED |
^~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c:8206:4: error: 'WIPHY_WLAN_VI_PREFERRED' undeclared (first use in this function)
WIPHY_WLAN_VI_PREFERRED |
^~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c:8207:4: error: 'WIPHY_WLAN_VO_PREFERRED' undeclared (first use in this function)
WIPHY_WLAN_VO_PREFERRED |
^~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c:8208:4: error: 'WIPHY_WLAN_BEACON_PREFERRED' undeclared (first use in this function)
WIPHY_WLAN_BEACON_PREFERRED |
^~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c:8209:4: error: 'WIPHY_WLAN_MGMT_PREFERRED' undeclared (first use in this function)
WIPHY_WLAN_MGMT_PREFERRED;
^~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c:8211:20: error: 'struct wiphy' has no member named 'btcoex_support_flags'
ar->hw->wiphy->btcoex_support_flags);
^~
cc1: some warnings being treated as errors

vim +7510 drivers/net/wireless/ath/ath10k/mac.c

7500 mutex_unlock(&ar->conf_mutex);
7501
7502 return ret;
7503 }
7504
7505 u32
> 7506 ath10k_mac_get_btcoex_prio(struct cfg80211_btcoex_priority *btcoex_priority)
7507 {
7508 u32 btcoex_prio = 0;
7509
> 7510 if (btcoex_priority->wlan_be_preferred)
> 7511 btcoex_prio |= WIPHY_WLAN_BE_PREFERRED;
7512
7513 if (btcoex_priority->wlan_bk_preferred)
> 7514 btcoex_prio |= WIPHY_WLAN_BK_PREFERRED;
7515
7516 if (btcoex_priority->wlan_vi_preferred)
> 7517 btcoex_prio |= WIPHY_WLAN_VI_PREFERRED;
7518
7519 if (btcoex_priority->wlan_vo_preferred)
> 7520 btcoex_prio |= WIPHY_WLAN_VO_PREFERRED;
7521
7522 if (btcoex_priority->wlan_beacon_preferred)
> 7523 btcoex_prio |= WIPHY_WLAN_BEACON_PREFERRED;
7524
7525 if (btcoex_priority->wlan_mgmt_preferred)
> 7526 btcoex_prio |= WIPHY_WLAN_MGMT_PREFERRED;
7527
7528 return btcoex_prio;
7529 }
7530
7531 static int ath10k_mac_op_set_btcoex_priority(struct ieee80211_hw *hw,
7532 struct cfg80211_btcoex_priority *btcoex_priority)
7533 {
7534 u32 btcoex_prio;
7535 struct ath10k *ar = hw->priv;
7536 int ret;
7537
7538 if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags))) {
7539 ret = -EINVAL;
7540 goto exit;
7541 }
7542
7543 mutex_lock(&ar->conf_mutex);
7544
7545 if (ar->state != ATH10K_STATE_ON &&
7546 ar->state != ATH10K_STATE_RESTARTED) {
7547 ret = -ENETDOWN;
7548 goto exit;
7549 }
7550
> 7551 btcoex_prio = ath10k_mac_get_btcoex_prio(btcoex_priority);
7552
7553 if (btcoex_prio > 0x3f) {
7554 ret = -E2BIG;
7555 goto exit;
7556 }
7557
7558 ret = ath10k_wmi_set_coex_param(ar, btcoex_prio);
7559
7560 if (ret) {
7561 ath10k_warn(ar, "failed to set btcoex priority: %d\n", ret);
7562 goto exit;
7563 }
7564
7565 exit:
7566 mutex_unlock(&ar->conf_mutex);
7567 return ret;
7568 }
7569
7570 static const struct ieee80211_ops ath10k_ops = {
7571 .tx = ath10k_mac_op_tx,
7572 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
7573 .start = ath10k_start,
7574 .stop = ath10k_stop,
7575 .config = ath10k_config,
7576 .add_interface = ath10k_add_interface,
7577 .remove_interface = ath10k_remove_interface,
7578 .configure_filter = ath10k_configure_filter,
7579 .bss_info_changed = ath10k_bss_info_changed,
7580 .set_coverage_class = ath10k_mac_op_set_coverage_class,
7581 .hw_scan = ath10k_hw_scan,
7582 .cancel_hw_scan = ath10k_cancel_hw_scan,
7583 .set_key = ath10k_set_key,
7584 .set_default_unicast_key = ath10k_set_default_unicast_key,
7585 .sta_state = ath10k_sta_state,
7586 .conf_tx = ath10k_conf_tx,
7587 .remain_on_channel = ath10k_remain_on_channel,
7588 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
7589 .set_rts_threshold = ath10k_set_rts_threshold,
7590 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
7591 .flush = ath10k_flush,
7592 .tx_last_beacon = ath10k_tx_last_beacon,
7593 .set_antenna = ath10k_set_antenna,
7594 .get_antenna = ath10k_get_antenna,
7595 .reconfig_complete = ath10k_reconfig_complete,
7596 .get_survey = ath10k_get_survey,
7597 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
7598 .sta_rc_update = ath10k_sta_rc_update,
7599 .get_tsf = ath10k_get_tsf,
7600 .set_tsf = ath10k_set_tsf,
7601 .ampdu_action = ath10k_ampdu_action,
7602 .get_et_sset_count = ath10k_debug_get_et_sset_count,
7603 .get_et_stats = ath10k_debug_get_et_stats,
7604 .get_et_strings = ath10k_debug_get_et_strings,
7605 .add_chanctx = ath10k_mac_op_add_chanctx,
7606 .remove_chanctx = ath10k_mac_op_remove_chanctx,
7607 .change_chanctx = ath10k_mac_op_change_chanctx,
7608 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
7609 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
7610 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
> 7611 .set_btcoex = ath10k_mac_op_set_btcoex,
> 7612 .set_btcoex_priority = ath10k_mac_op_set_btcoex_priority,
7613
7614 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
7615

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (10.70 kB)
.config.gz (55.49 kB)
Download all attachments

2016-11-17 11:44:29

by Tamizh Chelvam Raja

[permalink] [raw]
Subject: [PATCHv2 2/4] ath10k: Add support to update btcoex priority value via nl80211

From: Tamizh chelvam <[email protected]>

This patch adds support to update btcoex priority value via nl80211.
Here driver will be exposing the supported frame format for this
feature via btcoex_support_flags which is a member of
wiphy structure. 10.4 based firmware support this feature.
WMI service WMI_SERVICE_BTCOEX is used to identify the firmware support
of this feature. BTCOEX needs to enable to modify this value.

This patch has dependency of
"cfg80211: Add new NL80211_CMD_SET_BTCOEX_PRIORITY to support BTCOEX"
patch.

Signed-off-by: Tamizh chelvam <[email protected]>
---
drivers/net/wireless/ath/ath10k/mac.c | 78 +++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath10k/wmi-ops.h | 19 +++++++
drivers/net/wireless/ath/ath10k/wmi.c | 19 +++++++
drivers/net/wireless/ath/ath10k/wmi.h | 18 +++++++
4 files changed, 134 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index e7131b9..ce5d529 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -7502,6 +7502,71 @@ static int ath10k_mac_op_set_btcoex(struct ieee80211_hw *hw, bool enabled)
return ret;
}

+u32
+ath10k_mac_get_btcoex_prio(struct cfg80211_btcoex_priority *btcoex_priority)
+{
+ u32 btcoex_prio = 0;
+
+ if (btcoex_priority->wlan_be_preferred)
+ btcoex_prio |= WIPHY_WLAN_BE_PREFERRED;
+
+ if (btcoex_priority->wlan_bk_preferred)
+ btcoex_prio |= WIPHY_WLAN_BK_PREFERRED;
+
+ if (btcoex_priority->wlan_vi_preferred)
+ btcoex_prio |= WIPHY_WLAN_VI_PREFERRED;
+
+ if (btcoex_priority->wlan_vo_preferred)
+ btcoex_prio |= WIPHY_WLAN_VO_PREFERRED;
+
+ if (btcoex_priority->wlan_beacon_preferred)
+ btcoex_prio |= WIPHY_WLAN_BEACON_PREFERRED;
+
+ if (btcoex_priority->wlan_mgmt_preferred)
+ btcoex_prio |= WIPHY_WLAN_MGMT_PREFERRED;
+
+ return btcoex_prio;
+}
+
+static int ath10k_mac_op_set_btcoex_priority(struct ieee80211_hw *hw,
+ struct cfg80211_btcoex_priority *btcoex_priority)
+{
+ u32 btcoex_prio;
+ struct ath10k *ar = hw->priv;
+ int ret;
+
+ if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags))) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ mutex_lock(&ar->conf_mutex);
+
+ if (ar->state != ATH10K_STATE_ON &&
+ ar->state != ATH10K_STATE_RESTARTED) {
+ ret = -ENETDOWN;
+ goto exit;
+ }
+
+ btcoex_prio = ath10k_mac_get_btcoex_prio(btcoex_priority);
+
+ if (btcoex_prio > 0x3f) {
+ ret = -E2BIG;
+ goto exit;
+ }
+
+ ret = ath10k_wmi_set_coex_param(ar, btcoex_prio);
+
+ if (ret) {
+ ath10k_warn(ar, "failed to set btcoex priority: %d\n", ret);
+ goto exit;
+ }
+
+exit:
+ mutex_unlock(&ar->conf_mutex);
+ return ret;
+}
+
static const struct ieee80211_ops ath10k_ops = {
.tx = ath10k_mac_op_tx,
.wake_tx_queue = ath10k_mac_op_wake_tx_queue,
@@ -7544,6 +7609,7 @@ static int ath10k_mac_op_set_btcoex(struct ieee80211_hw *hw, bool enabled)
.unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
.switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
.set_btcoex = ath10k_mac_op_set_btcoex,
+ .set_btcoex_priority = ath10k_mac_op_set_btcoex_priority,

CFG80211_TESTMODE_CMD(ath10k_tm_cmd)

@@ -8134,6 +8200,18 @@ int ath10k_mac_register(struct ath10k *ar)
*/
ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;

+ if (test_bit(WMI_SERVICE_BTCOEX, ar->wmi.svc_map)) {
+ ar->hw->wiphy->btcoex_support_flags =
+ WIPHY_WLAN_BE_PREFERRED |
+ WIPHY_WLAN_BK_PREFERRED |
+ WIPHY_WLAN_VI_PREFERRED |
+ WIPHY_WLAN_VO_PREFERRED |
+ WIPHY_WLAN_BEACON_PREFERRED |
+ WIPHY_WLAN_MGMT_PREFERRED;
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "btcoex supported mask :%u\n",
+ ar->hw->wiphy->btcoex_support_flags);
+ }
+
switch (ar->running_fw->fw_file.wmi_op_version) {
case ATH10K_FW_WMI_OP_VERSION_MAIN:
ar->hw->wiphy->iface_combinations = ath10k_if_comb;
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index c9a8bb1..90c8390 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -197,6 +197,8 @@ struct wmi_ops {
(struct ath10k *ar,
enum wmi_bss_survey_req_type type);
struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value);
+ struct sk_buff *(*gen_set_coex_param)(struct ath10k *ar,
+ u32 btcoex_prio);
};

int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -1411,4 +1413,21 @@ struct wmi_ops {
return ath10k_wmi_cmd_send(ar, skb, wmi->cmd->echo_cmdid);
}

+static inline int
+ath10k_wmi_set_coex_param(struct ath10k *ar, u32 btcoex_prio)
+{
+ struct sk_buff *skb;
+
+ if (!ar->wmi.ops->gen_set_coex_param)
+ return -EOPNOTSUPP;
+
+ skb = ar->wmi.ops->gen_set_coex_param(ar, btcoex_prio);
+
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ return ath10k_wmi_cmd_send(ar, skb,
+ ar->wmi.cmd->set_coex_param_cmdid);
+}
+
#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 387c4ee..de35c17 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -710,6 +710,7 @@
.pdev_bss_chan_info_request_cmdid =
WMI_10_4_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
.ext_resource_cfg_cmdid = WMI_10_4_EXT_RESOURCE_CFG_CMDID,
+ .set_coex_param_cmdid = WMI_10_4_BTCOEX_CFG_CMDID,
};

/* MAIN WMI VDEV param map */
@@ -7859,6 +7860,23 @@ static int ath10k_wmi_10_4_op_get_vdev_subtype(struct ath10k *ar,
return 0;
}

+static struct sk_buff *
+ath10k_wmi_10_4_op_gen_set_coex_param(struct ath10k *ar,
+ u32 btcoex_prio)
+{
+ struct wmi_set_coex_param_10_4_cmd *cmd;
+ struct sk_buff *skb;
+
+ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
+ if (!skb)
+ return ERR_PTR(-ENOMEM);
+
+ cmd = (struct wmi_set_coex_param_10_4_cmd *)skb->data;
+ cmd->btcoex_prio = __cpu_to_le32(btcoex_prio);
+
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "BTCOEX priority :%u\n", btcoex_prio);
+ return skb;
+}
static const struct wmi_ops wmi_ops = {
.rx = ath10k_wmi_op_rx,
.map_svc = wmi_main_svc_map,
@@ -8205,6 +8223,7 @@ static int ath10k_wmi_10_4_op_get_vdev_subtype(struct ath10k *ar,
.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_set_coex_param = ath10k_wmi_10_4_op_gen_set_coex_param,
};

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 1b243c8..3a739e3 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -184,6 +184,8 @@ enum wmi_service {
WMI_SERVICE_TX_MODE_PUSH_ONLY,
WMI_SERVICE_TX_MODE_PUSH_PULL,
WMI_SERVICE_TX_MODE_DYNAMIC,
+ WMI_SERVICE_VDEV_RX_FILTER,
+ WMI_SERVICE_BTCOEX,

/* keep last */
WMI_SERVICE_MAX,
@@ -310,6 +312,8 @@ enum wmi_10_4_service {
WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY,
WMI_10_4_SERVICE_TX_MODE_PUSH_PULL,
WMI_10_4_SERVICE_TX_MODE_DYNAMIC,
+ WMI_10_4_SERVICE_VDEV_RX_FILTER,
+ WMI_10_4_SERVICE_BTCOEX,
};

static inline char *wmi_service_name(int service_id)
@@ -408,6 +412,7 @@ static inline char *wmi_service_name(int service_id)
SVCSTR(WMI_SERVICE_TX_MODE_PUSH_ONLY);
SVCSTR(WMI_SERVICE_TX_MODE_PUSH_PULL);
SVCSTR(WMI_SERVICE_TX_MODE_DYNAMIC);
+ SVCSTR(WMI_SERVICE_BTCOEX);
default:
return NULL;
}
@@ -663,6 +668,8 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out,
WMI_SERVICE_TX_MODE_PUSH_PULL, len);
SVCMAP(WMI_10_4_SERVICE_TX_MODE_DYNAMIC,
WMI_SERVICE_TX_MODE_DYNAMIC, len);
+ SVCMAP(WMI_10_4_SERVICE_BTCOEX,
+ WMI_SERVICE_BTCOEX, len);
}

#undef SVCMAP
@@ -837,6 +844,7 @@ struct wmi_cmd_map {
u32 pdev_bss_chan_info_request_cmdid;
u32 pdev_enable_adaptive_cca_cmdid;
u32 ext_resource_cfg_cmdid;
+ u32 set_coex_param_cmdid;
};

/*
@@ -1646,6 +1654,11 @@ enum wmi_10_4_cmd_id {
WMI_10_4_EXT_RESOURCE_CFG_CMDID,
WMI_10_4_VDEV_SET_IE_CMDID,
WMI_10_4_SET_LTEU_CONFIG_CMDID,
+ WMI_10_4_ATF_SSID_GROUPING_REQUEST_CMDID,
+ WMI_10_4_PEER_ATF_EXT_REQUEST_CMDID,
+ WMI_10_4_SET_PERIODIC_CHANNEL_STATS_CONFIG,
+ WMI_10_4_PEER_BWF_REQUEST_CMDID,
+ WMI_10_4_BTCOEX_CFG_CMDID,
WMI_10_4_PDEV_UTF_CMDID = WMI_10_4_END_CMDID - 1,
};

@@ -2723,6 +2736,11 @@ struct wmi_ext_resource_config_10_4_cmd {
__le32 fw_feature_bitmap;
};

+struct wmi_set_coex_param_10_4_cmd {
+ /* contains wlan priority frame type value preferred over bt */
+ __le32 btcoex_prio;
+};
+
/* strucutre describing host memory chunk. */
struct host_memory_chunk {
/* id of the request that is passed up in service ready */
--
1.7.9.5

2016-11-17 17:18:14

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCHv2 1/4] ath10k: Add support to enable or disable btcoex via nl80211

Hi Tamizh,

[auto build test ERROR on ath6kl/ath-next]
[also build test ERROR on v4.9-rc5 next-20161117]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/c_traja-qti-qualcomm-com/ath10k-Add-support-for-BTCOEX-feature/20161117-200322
base: https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git ath-next
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386

All errors (new ones prefixed by >>):

>> drivers/net/wireless/ath/ath10k/mac.c:7546:2: error: unknown field 'set_btcoex' specified in initializer
.set_btcoex = ath10k_mac_op_set_btcoex,
^
>> drivers/net/wireless/ath/ath10k/mac.c:7546:36: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.set_btcoex = ath10k_mac_op_set_btcoex,
^~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/ath/ath10k/mac.c:7546:36: note: (near initialization for 'ath10k_ops.reconfig_complete')
cc1: some warnings being treated as errors

vim +/set_btcoex +7546 drivers/net/wireless/ath/ath10k/mac.c

7540 .add_chanctx = ath10k_mac_op_add_chanctx,
7541 .remove_chanctx = ath10k_mac_op_remove_chanctx,
7542 .change_chanctx = ath10k_mac_op_change_chanctx,
7543 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
7544 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
7545 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
> 7546 .set_btcoex = ath10k_mac_op_set_btcoex,
7547
7548 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
7549

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (1.92 kB)
.config.gz (55.49 kB)
Download all attachments

2016-11-17 11:44:18

by Tamizh Chelvam Raja

[permalink] [raw]
Subject: [PATCHv2 1/4] ath10k: Add support to enable or disable btcoex via nl80211

From: Tamizh chelvam <[email protected]>

This patch add support to enable or disable btcoex via nl80211.
The firmware support this feature since 10.2.4.54 on 2G-only board,
dual band or 5G boards don't support this. WMI service
WMI_SERVICE_COEX_GPIO is used to identify the firmware support of this
feature.

Signed-off-by: Tamizh chelvam <[email protected]>
---
drivers/net/wireless/ath/ath10k/debug.c | 37 ++------------------
drivers/net/wireless/ath/ath10k/mac.c | 58 +++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath10k/mac.h | 1 +
3 files changed, 62 insertions(+), 34 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 82a4c67..ea30fbe 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -26,6 +26,7 @@
#include "debug.h"
#include "hif.h"
#include "wmi-ops.h"
+#include "mac.h"

/* ms */
#define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
@@ -2138,7 +2139,6 @@ static ssize_t ath10k_write_btcoex(struct file *file,
size_t buf_size;
int ret;
bool val;
- u32 pdev_param;

buf_size = min(count, (sizeof(buf) - 1));
if (copy_from_user(buf, ubuf, buf_size))
@@ -2150,40 +2150,9 @@ static ssize_t ath10k_write_btcoex(struct file *file,
return -EINVAL;

mutex_lock(&ar->conf_mutex);
-
- if (ar->state != ATH10K_STATE_ON &&
- ar->state != ATH10K_STATE_RESTARTED) {
- ret = -ENETDOWN;
- goto exit;
- }
-
- if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val)) {
+ ret = ath10k_mac_set_btcoex(ar, val);
+ if (!ret)
ret = count;
- goto exit;
- }
-
- pdev_param = ar->wmi.pdev_param->enable_btcoex;
- if (test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
- ar->running_fw->fw_file.fw_features)) {
- ret = ath10k_wmi_pdev_set_param(ar, pdev_param, val);
- if (ret) {
- ath10k_warn(ar, "failed to enable btcoex: %d\n", ret);
- ret = count;
- goto exit;
- }
- } else {
- ath10k_info(ar, "restarting firmware due to btcoex change");
- queue_work(ar->workqueue, &ar->restart_work);
- }
-
- if (val)
- set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
- else
- clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
-
- ret = count;
-
-exit:
mutex_unlock(&ar->conf_mutex);

return ret;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 717b2fa..e7131b9 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -7445,6 +7445,63 @@ struct ath10k_mac_change_chanctx_arg {
return 0;
}

+static inline void ath10k_mac_update_btcoex_flag(struct ath10k *ar, bool val)
+{
+ if (val)
+ set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
+ else
+ clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
+}
+
+int ath10k_mac_set_btcoex(struct ath10k *ar, bool val)
+{
+ u32 pdev_param;
+ int ret;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ if (ar->state != ATH10K_STATE_ON &&
+ ar->state != ATH10K_STATE_RESTARTED)
+ return -ENETDOWN;
+
+ if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val))
+ return 0;
+
+ pdev_param = ar->wmi.pdev_param->enable_btcoex;
+ if (test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
+ ar->running_fw->fw_file.fw_features)) {
+ ret = ath10k_wmi_pdev_set_param(ar, pdev_param, val);
+
+ if (ret) {
+ ath10k_warn(ar,
+ "failed to modify btcoex state: %d\n", ret);
+ return ret;
+ }
+ ath10k_mac_update_btcoex_flag(ar, val);
+ } else {
+ ath10k_info(ar, "restarting firmware due to btcoex change");
+ ath10k_mac_update_btcoex_flag(ar, val);
+ queue_work(ar->workqueue, &ar->restart_work);
+ }
+
+ return 0;
+}
+
+static int ath10k_mac_op_set_btcoex(struct ieee80211_hw *hw, bool enabled)
+{
+ int ret;
+ struct ath10k *ar = hw->priv;
+
+ if (!test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
+ return -EOPNOTSUPP;
+
+ mutex_lock(&ar->conf_mutex);
+ ret = ath10k_mac_set_btcoex(ar, enabled);
+ mutex_unlock(&ar->conf_mutex);
+
+ return ret;
+}
+
static const struct ieee80211_ops ath10k_ops = {
.tx = ath10k_mac_op_tx,
.wake_tx_queue = ath10k_mac_op_wake_tx_queue,
@@ -7486,6 +7543,7 @@ struct ath10k_mac_change_chanctx_arg {
.assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
.unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
.switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
+ .set_btcoex = ath10k_mac_op_set_btcoex,

CFG80211_TESTMODE_CMD(ath10k_tm_cmd)

diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h
index 1bd29ec..de1fa72 100644
--- a/drivers/net/wireless/ath/ath10k/mac.h
+++ b/drivers/net/wireless/ath/ath10k/mac.h
@@ -82,6 +82,7 @@ struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
u16 peer_id,
u8 tid);
int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val);
+int ath10k_mac_set_btcoex(struct ath10k *ar, bool val);

static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif)
{
--
1.7.9.5