Przeglądaj źródła

qcacld-3.0: Add Vendor command for QDF Debug Framework

There is no vendor command support for QDF Debug Framework.

Add vendor command support to dynamically update the trace levels
for modules.

Change-Id: I807365ec035d75372d4ff0f1ea27ba6f7bbff62d
CRs-Fixed: 2003455
Ashish Kumar Dhanotiya 8 lat temu
rodzic
commit
53c2f693ab

+ 2 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -1740,6 +1740,8 @@ static inline void hdd_bus_bandwidth_destroy(hdd_context_t *hdd_ctx)
 }
 #endif
 
+int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask);
+
 int hdd_init(void);
 void hdd_deinit(void);
 

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

@@ -8409,6 +8409,126 @@ static int wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
 	return ret;
 }
 
+static const struct nla_policy qca_wlan_vendor_set_trace_level_policy[
+		QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM] = {.type = NLA_NESTED },
+	[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MODULE_ID] = {.type = NLA_U32 },
+	[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_TRACE_MASK] = {.type = NLA_U32 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_set_trace_level() - Set the trace level
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_set_trace_level(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data,
+					int data_len)
+{
+	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb1[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX + 1];
+	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX + 1];
+	struct nlattr *apth;
+	int rem;
+	int ret = 1;
+	int print_idx = -1;
+	int module_id = -1;
+	int bit_mask = -1;
+	int status;
+
+	ENTER();
+
+	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (ret != 0)
+		return -EINVAL;
+
+	print_idx = qdf_get_pidx();
+	if (print_idx < 0 || print_idx >= MAX_PRINT_CONFIG_SUPPORTED) {
+		hdd_err("Invalid print controle object index");
+		return -EINVAL;
+	}
+
+	if (nla_parse(tb1, QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX, data,
+			data_len, qca_wlan_vendor_set_trace_level_policy)) {
+		hdd_err("Invalid attr");
+		return -EINVAL;
+	}
+
+	if (!tb1[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM]) {
+		hdd_err("attr trace level param failed");
+		return -EINVAL;
+	}
+
+	nla_for_each_nested(apth,
+			tb1[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM], rem) {
+		if (nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX,
+				nla_data(apth), nla_len(apth), NULL)) {
+			hdd_err("Invalid attr");
+			return -EINVAL;
+		}
+
+		if (!tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MODULE_ID]) {
+			hdd_err("attr Module ID failed");
+			return -EINVAL;
+		}
+		module_id = nla_get_u32
+			(tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MODULE_ID]);
+
+		if (!tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_TRACE_MASK]) {
+			hdd_err("attr Verbose mask failed");
+			return -EINVAL;
+		}
+		bit_mask = nla_get_u32
+		      (tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_TRACE_MASK]);
+
+		status = hdd_qdf_trace_enable(module_id, bit_mask);
+
+		if (status != 0)
+			hdd_err("can not set verbose mask %d for the category %d",
+				bit_mask, module_id);
+	}
+
+	EXIT();
+	return ret;
+}
+
+/**
+  * wlan_hdd_cfg80211_set_trace_level() - Set the trace level
+  * @wiphy: Pointer to wireless phy
+  * @wdev: Pointer to wireless device
+  * @data: Pointer to data
+  * @data_len: Length of @data
+  *
+  * Wrapper function of __wlan_hdd_cfg80211_set_trace_level()
+  *
+  * Return: 0 on success, negative errno on failure
+  */
+
+static int wlan_hdd_cfg80211_set_trace_level(struct wiphy *wiphy,
+						struct wireless_dev *wdev,
+						const void *data,
+						int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_trace_level(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,
@@ -9048,6 +9168,15 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
 			 WIPHY_VENDOR_CMD_NEED_RUNNING,
 		.doit = wlan_hdd_cfg80211_set_sar_power_limits
 	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_TRACE_LEVEL,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_trace_level
+	},
+
 #ifdef WLAN_UMAC_CONVERGENCE
 	COMMON_VENDOR_COMMANDS
 #endif

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

@@ -455,6 +455,33 @@ enum qca_nl80211_vendor_subcmds {
 
 	/* Set Specific Absorption Rate(SAR) Power Limits */
 	QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS = 146,
+	/* Set the trace level for QDF */
+	QCA_NL80211_VENDOR_SUBCMD_SET_TRACE_LEVEL = 152,
+};
+
+/**
+ * enum qca_vendor_attr_set_trace_level - Config params for QDF set trace level
+ * @QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_INVALID: Invalid trace level
+ * @QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM : Trace level parameters
+ * @QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MODULE_ID : Module of which trace
+    level needs to be updated.
+ * @QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_TRACE_MASK : verbose mask, which need
+ * to be set.
+ * @QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_AFTER_LAST : after last.
+ * @QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX : Max attribute.
+ */
+enum qca_vendor_attr_set_trace_level {
+	QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_INVALID = 0,
+	/*
+	* Array of QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM
+	* attributes.
+	*/
+	QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM = 1,
+	QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MODULE_ID = 2,
+	QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_TRACE_MASK = 3,
+	QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX =
+		QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_AFTER_LAST - 1,
 };
 
 /**

+ 8 - 7
core/hdd/src/wlan_hdd_main.c

@@ -522,7 +522,7 @@ uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel,
 
 /**
  * hdd_qdf_trace_enable() - configure initial QDF Trace enable
- * @moduleId:	Module whose trace level is being configured
+ * @module_id:	Module whose trace level is being configured
  * @bitmask:	Bitmask of log levels to be enabled
  *
  * Called immediately after the cfg.ini is read in order to configure
@@ -530,7 +530,7 @@ uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel,
  *
  * Return: None
  */
-static void hdd_qdf_trace_enable(QDF_MODULE_ID moduleId, uint32_t bitmask)
+int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
 {
 	QDF_TRACE_LEVEL level;
 	int qdf_print_idx = -1;
@@ -541,29 +541,30 @@ static void hdd_qdf_trace_enable(QDF_MODULE_ID moduleId, uint32_t bitmask)
 	 * will remain at the "compiled in" default value)
 	 */
 	if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask) {
-		return;
+		return 0;
 	}
 
 	qdf_print_idx = qdf_get_pidx();
 
 	/* a mask was specified.  start by disabling all logging */
-	status = qdf_print_set_category_verbose(qdf_print_idx, moduleId,
+	status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
 					QDF_TRACE_LEVEL_NONE, 0);
 
 	if (QDF_STATUS_SUCCESS != status)
-		return;
+		return -EINVAL;
 	/* now cycle through the bitmask until all "set" bits are serviced */
 	level = QDF_TRACE_LEVEL_FATAL;
 	while (0 != bitmask) {
 		if (bitmask & 1) {
 			status = qdf_print_set_category_verbose(qdf_print_idx,
-							moduleId, level, 1);
+							module_id, level, 1);
 			if (QDF_STATUS_SUCCESS != status)
-				return;
+				return -EINVAL;
 		}
 		level++;
 		bitmask >>= 1;
 	}
+	return 0;
 }
 
 /**