From daaf54b44308f74d50308dcb4d3b52f56dde6c01 Mon Sep 17 00:00:00 2001 From: Asutosh Mohapatra Date: Tue, 23 Aug 2022 11:18:22 +0530 Subject: [PATCH] qcacld-3.0: Add support to advertise SAR version to userspace Currently there is no support to advertise SAR version to user space for new QCA vendor command QCA_NL80211_VENDOR_SUBCMD_GET_SAR_CAPABILITY. Add support for the new vendor command to send SAR version to user space. Change-Id: I6890da31d2e60c1a363fd8fbc8d0d0bddd29ef74 CRs-Fixed: 3273690 --- core/hdd/src/wlan_hdd_sar_limits.c | 145 +++++++++++++++++++++++++++++ core/hdd/src/wlan_hdd_sar_limits.h | 24 +++++ 2 files changed, 169 insertions(+) diff --git a/core/hdd/src/wlan_hdd_sar_limits.c b/core/hdd/src/wlan_hdd_sar_limits.c index eae3fc27b3..5a915cb44e 100644 --- a/core/hdd/src/wlan_hdd_sar_limits.c +++ b/core/hdd/src/wlan_hdd_sar_limits.c @@ -306,6 +306,120 @@ cleanup: return ret; } +/** + * hdd_to_nl_sar_version - Map SAR version enum from hdd to nl + * @cur_sar_version - Current SAR version stored in hdd_ctx + * + * This function is used to map SAR version enum stored in hdd_ctx to + * nl + * + * Return - NL SAR version + */ +static u32 hdd_to_nl_sar_version(enum sar_version hdd_sar_version) +{ + switch (hdd_sar_version) { + case (SAR_VERSION_1): + return QCA_WLAN_VENDOR_SAR_VERSION_1; + case (SAR_VERSION_2): + return QCA_WLAN_VENDOR_SAR_VERSION_2; + default: + return QCA_WLAN_VENDOR_SAR_VERSION_INVALID; + } +} + +/** + * hdd_sar_fill_capability_response - Fill SAR capability + * @skb - Pointer to socket buffer + * @hdd_ctx - pointer to hdd context + * + * This function fills SAR Capability in the socket buffer + * + * Return - 0 on success, negative errno on failure + */ +static int hdd_sar_fill_capability_response(struct sk_buff *skb, + struct hdd_context *hdd_ctx) +{ + int errno = 0; + u32 attr; + u32 value; + + attr = QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION; + value = hdd_to_nl_sar_version(hdd_ctx->sar_version); + errno = nla_put_u32(skb, attr, value); + + return errno; +} + +/** + * hdd_sar_send_capability_response - Send SAR capability response + * @wiphy: Pointer to wireless phy + * @hdd_ctx: Pointer to hdd context + * + * This function sends SAR capability. + */ +static int hdd_sar_send_capability_response(struct wiphy *wiphy, + struct hdd_context *hdd_ctx) +{ + uint32_t len; + struct sk_buff *skb; + int errno; + + len = NLMSG_HDRLEN; + + /* QCA_WLAN_VENDOR_ATTR_SAR_CAPABILITY_VERSION */ + len += NLA_HDRLEN + sizeof(u32); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len); + if (!skb) { + hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed"); + return -ENOMEM; + } + + errno = hdd_sar_fill_capability_response(skb, hdd_ctx); + if (errno) { + kfree_skb(skb); + return errno; + } + + return cfg80211_vendor_cmd_reply(skb); +} + +/** + * __wlan_hdd_get_sar_capability - Get SAR Capabilities + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Length of @data + * + * This function is used to retrieve SAR Version . + * + * Return: 0 on success, negative errno on failure + */ + +static int __wlan_hdd_get_sar_capability(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + int ret; + + hdd_enter(); + + if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE || + hdd_get_conparam() == QDF_GLOBAL_MONITOR_MODE) { + hdd_err("Command not allowed in FTM/MONITOR mode"); + return -EPERM; + } + + if (wlan_hdd_validate_context(hdd_ctx)) + return -EINVAL; + + ret = hdd_sar_send_capability_response(wiphy, hdd_ctx); + + return ret; +} + #define SAR_LIMITS_SAR_ENABLE QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE #define SAR_LIMITS_NUM_SPECS QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS #define SAR_LIMITS_SPEC QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC @@ -824,6 +938,37 @@ int wlan_hdd_cfg80211_get_sar_power_limits(struct wiphy *wiphy, return errno; } +/** + * wlan_hdd_cfg80211_get_sar_capability() - Get SAR capability + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Length of @data + * + * Wrapper function of __wlan_hdd_get_sar_capability() + * + * Return: 0 on success, negative errno on failure + */ + +int wlan_hdd_cfg80211_get_sar_capability(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct osif_psoc_sync *psoc_sync; + int errno; + + errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync); + if (errno) + return errno; + + errno = __wlan_hdd_get_sar_capability(wiphy, wdev, data, data_len); + + osif_psoc_sync_op_stop(psoc_sync); + + return errno; +} + #ifdef SAR_SAFETY_FEATURE void hdd_disable_sar(struct hdd_context *hdd_ctx) { diff --git a/core/hdd/src/wlan_hdd_sar_limits.h b/core/hdd/src/wlan_hdd_sar_limits.h index dd6c3a3cc7..65d67c5bb4 100644 --- a/core/hdd/src/wlan_hdd_sar_limits.h +++ b/core/hdd/src/wlan_hdd_sar_limits.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 @@ -178,7 +179,22 @@ int wlan_hdd_cfg80211_set_sar_power_limits(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); +/** + * wlan_hdd_cfg80211_get_sar_capability() - Get SAR capability + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Length of @data + * + * Wrapper function of __wlan_hdd_get_sar_capability() + * + * Return: 0 on success, negative errno on failure + */ +int wlan_hdd_cfg80211_get_sar_capability(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len); /** * hdd_store_sar_config() - Store SAR config in HDD context * @hdd_ctx: The HDD context @@ -225,6 +241,14 @@ wlan_hdd_sar_limits_policy[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX + 1]; .doit = wlan_hdd_cfg80211_set_sar_power_limits, \ vendor_command_policy(wlan_hdd_sar_limits_policy, \ QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX) \ +}, \ +{ \ + .info.vendor_id = QCA_NL80211_VENDOR_ID, \ + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SAR_CAPABILITY, \ + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \ + WIPHY_VENDOR_CMD_NEED_RUNNING, \ + .doit = wlan_hdd_cfg80211_get_sar_capability, \ + vendor_command_policy(VENDOR_CMD_RAW_DATA, 0) \ }, #else /* FEATURE_SAR_LIMITS */ #define FEATURE_SAR_LIMITS_VENDOR_COMMANDS