wlan: Add support to get wlan version info from cfg layer
Add support to send wlan driver related information
to user space for debugging.
Change-Id: Id8d1583eac9e8259b5a5cd86e755c1064f879382
CRs-Fixed: 818318
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index faeb0da..4a8ecfe 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -165,6 +165,8 @@
/* Get Concurrency Matrix */
QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX = 42,
+ /* Get Wifi Specific Info */
+ QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO = 61,
QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST = 65,
QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST = 66,
QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND = 67,
@@ -979,6 +981,20 @@
QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_AFTER_LAST - 1,
};
+/* NL attributes for data used by
+ * QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO sub command.
+ */
+enum qca_wlan_vendor_attr_get_wifi_info {
+ QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION = 1,
+ QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION = 2,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX =
+ QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_AFTER_LAST - 1,
+};
+
enum qca_wlan_vendor_attr_get_supported_features {
QCA_WLAN_VENDOR_ATTR_FEATURE_SET_INVALID = 0,
/* Unsigned 32-bit value */
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 823e11c..caef24e 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1471,6 +1471,7 @@
struct mutex wmmLock;
v_BOOL_t mgmt_frame_logging;
v_BOOL_t isSetBandByNL;
+ v_U8_t fw_Version[SIR_VERSION_STRING_LEN];
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
struct hdd_ll_stats_context ll_stats_context;
#endif /* End of WLAN_FEATURE_LINK_LAYER_STATS */
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 9243f56..de675e1 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -95,6 +95,8 @@
#include "wlan_qct_wda.h"
#include "wlan_nv.h"
#include "wlan_hdd_dev_pwr.h"
+#include "qwlan_version.h"
+
#define g_mode_rates_size (12)
#define a_mode_rates_size (8)
@@ -6198,6 +6200,12 @@
.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
},
+ {
+ .vendor_id = QCA_NL80211_VENDOR_ID,
+ .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
+ }
+
+
};
/*
@@ -14327,6 +14335,88 @@
return ret;
}
+static const struct
+nla_policy
+qca_wlan_vendor_get_wifi_info_policy[
+ QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
+ [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * This is called when wlan driver needs to send wifi driver related info
+ * (driver/fw version) to the user space application upon request.
+ *
+ * Return: Return the Success or Failure code.
+ */
+static int
+wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
+ tSirVersionString version;
+ uint32 version_len;
+ uint8 attr;
+ int status;
+ struct sk_buff *reply_skb = NULL;
+
+ if (VOS_FTM_MODE == hdd_get_conparam()) {
+ hddLog(LOGE, FL("Command not allowed in FTM mode"));
+ return -EINVAL;
+ }
+
+ status = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != status) {
+ hddLog(LOGE, FL("HDD context is not valid"));
+ return -EINVAL;
+ }
+
+ if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
+ data_len, qca_wlan_vendor_get_wifi_info_policy)) {
+ hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
+ return -EINVAL;
+ }
+
+ if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
+ hddLog(LOG1, FL("Rcvd req for Driver version "
+ "Driver version is %s"),QWLAN_VERSIONSTR);
+ strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
+ attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
+ } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
+ hddLog(LOG1, FL("Rcvd req for FW version "
+ "FW version is %s"), hdd_ctx->fw_Version);
+ strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
+ attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
+ } else {
+ hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
+ return -EINVAL;
+ }
+
+ version_len = strlen(version);
+ reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
+ version_len + NLA_HDRLEN + NLMSG_HDRLEN);
+ if (!reply_skb) {
+ hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
+ return -ENOMEM;
+ }
+
+ if (nla_put(reply_skb, attr, version_len, version)) {
+ hddLog(LOGE, FL("nla put fail"));
+ kfree_skb(reply_skb);
+ return -EINVAL;
+ }
+
+ return cfg80211_vendor_cmd_reply(reply_skb);
+}
+
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
struct net_device *netdev,
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index bd373c6..9f489d0 100755
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -9134,6 +9134,7 @@
pr_info("%s: WCNSS software version %s\n",
WLAN_MODULE_NAME, versionString);
+ vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
versionString,