Jelajahi Sumber

qcacld-3.0: Dynamic OTA test mode enable

For OEM to do OTA tests, power save, background scan, and low RSSI
scanning need to be disabled and it should be done dynamically.
Implement a vendor command to enable and disable OTA test mode.

CRs-fixed: 941776
Change-Id: Ic9da11cf5f4bb19a01d9b55c50c0aea196abbfb6
Peng Xu 9 tahun lalu
induk
melakukan
278d012c68
2 mengubah file dengan 145 tambahan dan 0 penghapusan
  1. 123 0
      core/hdd/src/wlan_hdd_cfg80211.c
  2. 22 0
      core/hdd/src/wlan_hdd_cfg80211.h

+ 123 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -52,6 +52,7 @@
 #include "wlan_hdd_assoc.h"
 #include "wlan_hdd_wext.h"
 #include "sme_api.h"
+#include "sme_power_save_api.h"
 #include "wlan_hdd_p2p.h"
 #include "wlan_hdd_cfg80211.h"
 #include "wlan_hdd_hostapd.h"
@@ -4441,6 +4442,121 @@ static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
 	return ret;
 }
 
+static const struct
+nla_policy
+qca_wlan_vendor_ota_test_policy
+[QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE] = {.type = NLA_U8 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_set_ota_test () - enable/disable OTA test
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_set_ota_test(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
+	hdd_context_t *hdd_ctx  = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX + 1];
+	uint8_t ota_enable = 0;
+	CDF_STATUS status;
+	uint32_t current_roam_state;
+
+	if (CDF_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	if (0 != wlan_hdd_validate_context(hdd_ctx))
+		return -EINVAL;
+
+	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX,
+		      data, data_len,
+		      qca_wlan_vendor_ota_test_policy)) {
+		hdd_err("invalid attr");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE]) {
+		hdd_err("attr ota test failed");
+		return -EINVAL;
+	}
+
+	ota_enable = nla_get_u8(
+		tb[QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE]);
+
+	hdd_info(" OTA test enable = %d", ota_enable);
+	if (ota_enable != 1) {
+		hdd_err("Invalid value, only enable test mode is supported!");
+		return -EINVAL;
+	}
+
+	current_roam_state =
+			sme_get_current_roam_state(hal, adapter->sessionId);
+	status = sme_stop_roaming(hal, adapter->sessionId,
+					eCsrHddIssued);
+	if (status != CDF_STATUS_SUCCESS) {
+		hdd_err("Enable/Disable roaming failed");
+		return -EINVAL;
+	}
+
+	status = sme_ps_enable_disable(hal, adapter->sessionId,
+					SME_PS_DISABLE);
+	if (status != CDF_STATUS_SUCCESS) {
+		hdd_err("Enable/Disable power save failed");
+		/* restore previous roaming setting */
+		if (current_roam_state == eCSR_ROAMING_STATE_JOINING ||
+			 current_roam_state == eCSR_ROAMING_STATE_JOINED)
+			status = sme_start_roaming(hal, adapter->sessionId,
+						eCsrHddIssued);
+		else if (current_roam_state == eCSR_ROAMING_STATE_STOP ||
+			 current_roam_state == eCSR_ROAMING_STATE_IDLE)
+			status = sme_stop_roaming(hal, adapter->sessionId,
+						eCsrHddIssued);
+
+		if (status != CDF_STATUS_SUCCESS)
+			hdd_err("Restoring roaming state failed");
+
+		return -EINVAL;
+	}
+
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_ota_test () - Enable or disable OTA test
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int wlan_hdd_cfg80211_set_ota_test(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	int ret = 0;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_ota_test(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
 const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
 	{
 		.info.vendor_id = QCA_NL80211_VENDOR_ID,
@@ -4862,6 +4978,13 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
 			 WIPHY_VENDOR_CMD_NEED_RUNNING,
 		.doit = wlan_hdd_cfg80211_get_link_properties
 	},
+	{
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OTA_TEST,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				 WIPHY_VENDOR_CMD_NEED_NETDEV |
+				 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_ota_test
+	},
 };
 
 /*

+ 22 - 0
core/hdd/src/wlan_hdd_cfg80211.h

@@ -248,6 +248,7 @@ typedef enum {
  * @QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES: get link properties
  * @QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN: venodr scan command
  * @QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE: vendor scan complete
+ * @QCA_NL80211_VENDOR_SUBCMD_OTA_TEST: enable OTA test
  */
 
 enum qca_nl80211_vendor_subcmds {
@@ -357,6 +358,10 @@ enum qca_nl80211_vendor_subcmds {
 	/* Vendor scan commands */
 	QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN = 106,
 	QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE = 107,
+
+	/* OTA test subcommand */
+	QCA_NL80211_VENDOR_SUBCMD_OTA_TEST = 108,
+
 };
 
 /**
@@ -2172,6 +2177,23 @@ enum drv_dbs_capability {
 	DRV_DBS_CAPABILITY_2X2,
 };
 
+/**
+ * enum qca_vendor_attr_ota_test - Enable OTA test
+ * @QCA_WLAN_VENDOR_ATTR_OTA_TEST_INVALID: invalid value
+ * @QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE: enable OTA test
+ * @QCA_WLAN_VENDOR_ATTR_OTA_TEST_AFTER_LAST: after last
+ * @QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX: max
+ */
+enum qca_vendor_attr_ota_test {
+	QCA_WLAN_VENDOR_ATTR_OTA_TEST_INVALID,
+	/* 8-bit unsigned value to indicate if OTA test is enabled */
+	QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE,
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_OTA_TEST_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX =
+	QCA_WLAN_VENDOR_ATTR_OTA_TEST_AFTER_LAST - 1
+};
+
 struct cfg80211_bss *wlan_hdd_cfg80211_update_bss_db(hdd_adapter_t *pAdapter,
 						tCsrRoamInfo *pRoamInfo);