ソースを参照

qcacmn: QDF Converged Debug Framework

QDF Debug Framework is implemented that will be used across
WIN and MCL to converge the debug methods used currently.

These changes have passed basic dev validation, carried out
by exercising each of the APIs.

Also, WIN validation is complete with these framework changes tested by
registering to the framework and adapting to the new converged trace API
qdf_trace_msg_cmn.

Change-Id: I4b87c910906cf0a49e91b1000f5218402cd45fe2
CRs-Fixed: 1102956
Sathish Kumar 8 年 前
コミット
fc93b2d84d
3 ファイル変更857 行追加128 行削除
  1. 395 49
      qdf/inc/qdf_trace.h
  2. 0 70
      qdf/inc/qdf_types.h
  3. 462 9
      qdf/linux/src/qdf_trace.c

+ 395 - 49
qdf/inc/qdf_trace.h

@@ -44,24 +44,48 @@
 /* Type declarations */
 
 #define FL(x)    "%s: %d: " x, __func__, __LINE__
+#define QDF_TRACE_BUFFER_SIZE (512)
+
+#ifdef CONFIG_MCL
+#define QDF_DEFAULT_TRACE_LEVEL \
+	((1 << QDF_TRACE_LEVEL_FATAL) | (1 << QDF_TRACE_LEVEL_ERROR))
+#else
+#define QDF_DEFAULT_TRACE_LEVEL (1 << QDF_TRACE_LEVEL_INFO)
+#endif
+
+/*
+ * Log levels
+ */
+#define QDF_DEBUG_FUNCTRACE     0x01
+#define QDF_DEBUG_LEVEL0        0x02
+#define QDF_DEBUG_LEVEL1        0x04
+#define QDF_DEBUG_LEVEL2        0x08
+#define QDF_DEBUG_LEVEL3        0x10
+#define QDF_DEBUG_ERROR         0x20
+#define QDF_DEBUG_CFG           0x40
 
 /**
- * typedef enum QDF_TRACE_LEVEL - Debug Trace level
+ * typedef enum QDF_TRACE_LEVEL - Debug verbose level
  * @QDF_TRACE_LEVEL_NONE: no trace will be logged. This value is in place
- * for the qdf_trace_setlevel() to allow the user to turn off all traces
- * @QDF_TRACE_LEVEL_FATAL: enable trace for fatal Error
- * @QDF_TRACE_LEVEL_ERROR: enable trace for errors
- * @QDF_TRACE_LEVEL_WARN: enable trace for warnings
- * @QDF_TRACE_LEVEL_INFO: enable trace for information
- * @QDF_TRACE_LEVEL_INFO_HIGH: enable high level trace information
- * @QDF_TRACE_LEVEL_INFO_MED: enable middle level trace information
- * @QDF_TRACE_LEVEL_INFO_LOW: enable low level trace information
- * @QDF_TRACE_LEVEL_DEBUG: enable trace for debugging
- * @QDF_TRACE_LEVEL_ALL: enable all trace
- * @QDF_TRACE_LEVEL_MAX: enable max level trace
+ *                        for the qdf_trace_setlevel() to allow the user
+ *                        to turn off all traces
+ * @QDF_TRACE_LEVEL_FATAL: Indicates fatal error conditions
+ * @QDF_TRACE_LEVEL_ERROR: Indicates error conditions
+ * @QDF_TRACE_LEVEL_WARN: May indicate that an error will occur if action
+ *                        is not taken
+ * @QDF_TRACE_LEVEL_INFO: Normal operational messages that require no action
+ * @QDF_TRACE_LEVEL_INFO_HIGH: High level operational messages that require
+ *                             no action
+ * @QDF_TRACE_LEVEL_INFO_MED: Middle level operational messages that require
+ *                            no action
+ * @QDF_TRACE_LEVEL_INFO_LOW: Low level operational messages that require
+ *                            no action
+ * @QDF_TRACE_LEVEL_DEBUG: Information useful to developers for debugging
+ * @QDF_TRACE_LEVEL_ALL: All trace levels
+ * @QDF_TRACE_LEVEL_MAX: Max trace level
  */
 typedef enum {
-	QDF_TRACE_LEVEL_NONE = 0,
+	QDF_TRACE_LEVEL_NONE,
 	QDF_TRACE_LEVEL_FATAL,
 	QDF_TRACE_LEVEL_ERROR,
 	QDF_TRACE_LEVEL_WARN,
@@ -74,44 +98,153 @@ typedef enum {
 	QDF_TRACE_LEVEL_MAX
 } QDF_TRACE_LEVEL;
 
-/*
- * Log levels
- */
-#define QDF_DEBUG_FUNCTRACE     0x01
-#define QDF_DEBUG_LEVEL0        0x02
-#define QDF_DEBUG_LEVEL1        0x04
-#define QDF_DEBUG_LEVEL2        0x08
-#define QDF_DEBUG_LEVEL3        0x10
-#define QDF_DEBUG_ERROR         0x20
-#define QDF_DEBUG_CFG           0x40
-
-/*
- * Shared print control index
- * for converged debug framework
- */
-#define QDF_PRINT_IDX_SHARED -1
-
 /**
- * QDF_PRINT_INFO() - Generic wrapper API for logging
- * @idx: Index of print control object
- * @module: Module identifier. A member of QDF_MODULE_ID enumeration that
- *           identifies the module issuing the trace message
- * @level: Trace level. A member of QDF_TRACE_LEVEL enumeration indicating
- *          the severity of the condition causing the trace message to be
- *          issued.
- * @str_format: Format string that contains the message to be logged.
- * @...:.
- *
- *
- * This wrapper will be used for any generic logging messages. Wrapper will
- * compile a call to converged QDF trace message API.
- *
- * Return: Nothing
- *
+ * typedef enum QDF_MODULE_ID - Debug category level
+ * @QDF_MODULE_ID_TDLS          : TDLS
+ * @QDF_MODULE_ID_ACS           : auto channel selection
+ * @QDF_MODULE_ID_SCAN_SM       : scan state machine
+ * @QDF_MODULE_ID_SCANENTRY     : scan entry
+ * @QDF_MODULE_ID_WDS           : WDS handling
+ * @QDF_MODULE_ID_ACTION        : action management frames
+ * @QDF_MODULE_ID_ROAM          : sta-mode roaming
+ * @QDF_MODULE_ID_INACT         : inactivity handling
+ * @QDF_MODULE_ID_DOTH          : 11.h
+ * @QDF_MODULE_ID_IQUE          : IQUE features
+ * @QDF_MODULE_ID_WME           : WME protocol
+ * @QDF_MODULE_ID_ACL           : ACL handling
+ * @QDF_MODULE_ID_WPA           : WPA/RSN protocol
+ * @QDF_MODULE_ID_RADKEYS       : dump 802.1x keys
+ * @QDF_MODULE_ID_RADDUMP       : dump 802.1x radius packets
+ * @QDF_MODULE_ID_RADIUS        : 802.1x radius client
+ * @QDF_MODULE_ID_DOT1XSM       : 802.1x state machine
+ * @QDF_MODULE_ID_DOT1X         : 802.1x authenticator
+ * @QDF_MODULE_ID_POWER         : power save handling
+ * @QDF_MODULE_ID_STATS         : state machine
+ * @QDF_MODULE_ID_OUTPUT        : output handling
+ * @QDF_MODULE_ID_SCAN          : scanning
+ * @QDF_MODULE_ID_AUTH          : authentication handling
+ * @QDF_MODULE_ID_ASSOC         : association handling
+ * @QDF_MODULE_ID_NODE          : node handling
+ * @QDF_MODULE_ID_ELEMID        : element id parsing
+ * @QDF_MODULE_ID_XRATE         : rate set handling
+ * @QDF_MODULE_ID_INPUT         : input handling
+ * @QDF_MODULE_ID_CRYPTO        : crypto work
+ * @QDF_MODULE_ID_DUMPPKTS      : IFF_LINK2 equivalant
+ * @QDF_MODULE_ID_DEBUG         : IFF_DEBUG equivalent
+ * @QDF_MODULE_ID_MLME          : MLME
+ * @QDF_MODULE_ID_RRM           : Radio resource measurement
+ * @QDF_MODULE_ID_WNM           : Wireless Network Management
+ * @QDF_MODULE_ID_P2P_PROT      : P2P Protocol driver
+ * @QDF_MODULE_ID_PROXYARP      : 11v Proxy ARP
+ * @QDF_MODULE_ID_L2TIF         : Hotspot 2.0 L2 TIF
+ * @QDF_MODULE_ID_WIFIPOS       : WifiPositioning Feature
+ * @QDF_MODULE_ID_WRAP          : WRAP or Wireless ProxySTA
+ * @QDF_MODULE_ID_DFS           : DFS debug mesg
+ * @QDF_MODULE_ID_TLSHIM        : TLSHIM module ID
+ * @QDF_MODULE_ID_WMI           : WMI module ID
+ * @QDF_MODULE_ID_HTT           : HTT module ID
+ * @QDF_MODULE_ID_RSV4          : Reserved
+ * @QDF_MODULE_ID_HDD           : HDD module ID
+ * @QDF_MODULE_ID_SME           : SME module ID
+ * @QDF_MODULE_ID_PE            : PE module ID
+ * @QDF_MODULE_ID_WMA           : WMA module ID
+ * @QDF_MODULE_ID_SYS           : SYS module ID
+ * @QDF_MODULE_ID_QDF           : QDF module ID
+ * @QDF_MODULE_ID_SAP           : SAP module ID
+ * @QDF_MODULE_ID_HDD_SOFTAP    : HDD SAP module ID
+ * @QDF_MODULE_ID_HDD_DATA      : HDD DATA module ID
+ * @QDF_MODULE_ID_HDD_SAP_DATA  : HDD SAP DATA module ID
+ * @QDF_MODULE_ID_HIF           : HIF module ID
+ * @QDF_MODULE_ID_HTC           : HTC module ID
+ * @QDF_MODULE_ID_TXRX          : TXRX module ID
+ * @QDF_MODULE_ID_QDF_DEVICE    : QDF DEVICE module ID
+ * @QDF_MODULE_ID_CFG           : CFG module ID
+ * @QDF_MODULE_ID_BMI           : BMI module ID
+ * @QDF_MODULE_ID_EPPING        : EPPING module ID
+ * @QDF_MODULE_ID_QVIT          : QVIT module ID
+ * @QDF_MODULE_ID_ANY           : anything
+ * @QDF_MODULE_ID_MAX           : Max place holder module ID
  */
-void QDF_PRINT_INFO(unsigned int idx, QDF_MODULE_ID module,
-		    QDF_TRACE_LEVEL level,
-		    char *str_format, ...);
+typedef enum {
+	QDF_MODULE_ID_TDLS      = 0,
+	QDF_MODULE_ID_ACS,
+	QDF_MODULE_ID_SCAN_SM,
+	QDF_MODULE_ID_SCANENTRY,
+	QDF_MODULE_ID_WDS,
+	QDF_MODULE_ID_ACTION,
+	QDF_MODULE_ID_ROAM,
+	QDF_MODULE_ID_INACT,
+	QDF_MODULE_ID_DOTH      = 8,
+	QDF_MODULE_ID_IQUE,
+	QDF_MODULE_ID_WME,
+	QDF_MODULE_ID_ACL,
+	QDF_MODULE_ID_WPA,
+	QDF_MODULE_ID_RADKEYS,
+	QDF_MODULE_ID_RADDUMP,
+	QDF_MODULE_ID_RADIUS,
+	QDF_MODULE_ID_DOT1XSM   = 16,
+	QDF_MODULE_ID_DOT1X,
+	QDF_MODULE_ID_POWER,
+	QDF_MODULE_ID_STATE,
+	QDF_MODULE_ID_OUTPUT,
+	QDF_MODULE_ID_SCAN,
+	QDF_MODULE_ID_AUTH,
+	QDF_MODULE_ID_ASSOC,
+	QDF_MODULE_ID_NODE      = 24,
+	QDF_MODULE_ID_ELEMID,
+	QDF_MODULE_ID_XRATE,
+	QDF_MODULE_ID_INPUT,
+	QDF_MODULE_ID_CRYPTO,
+	QDF_MODULE_ID_DUMPPKTS,
+	QDF_MODULE_ID_DEBUG,
+	QDF_MODULE_ID_MLME,
+	QDF_MODULE_ID_RRM       = 32,
+	QDF_MODULE_ID_WNM,
+	QDF_MODULE_ID_P2P_PROT,
+	QDF_MODULE_ID_PROXYARP,
+	QDF_MODULE_ID_L2TIF,
+	QDF_MODULE_ID_WIFIPOS,
+	QDF_MODULE_ID_WRAP,
+	QDF_MODULE_ID_DFS,
+	QDF_MODULE_ID_ATF       = 40,
+	QDF_MODULE_ID_SPLITMAC,
+	QDF_MODULE_ID_IOCTL,
+	QDF_MODULE_ID_NAC,
+	QDF_MODULE_ID_MESH,
+	QDF_MODULE_ID_MBO,
+	QDF_MODULE_ID_EXTIOCTL_CHANSWITCH,
+	QDF_MODULE_ID_EXTIOCTL_CHANSSCAN,
+	QDF_MODULE_ID_TLSHIM    = 48,
+	QDF_MODULE_ID_WMI,
+	QDF_MODULE_ID_HTT,
+	QDF_MODULE_ID_HDD,
+	QDF_MODULE_ID_SME,
+	QDF_MODULE_ID_PE,
+	QDF_MODULE_ID_WMA,
+	QDF_MODULE_ID_SYS,
+	QDF_MODULE_ID_QDF       = 56,
+	QDF_MODULE_ID_SAP,
+	QDF_MODULE_ID_HDD_SOFTAP,
+	QDF_MODULE_ID_HDD_DATA,
+	QDF_MODULE_ID_HDD_SAP_DATA,
+	QDF_MODULE_ID_HIF,
+	QDF_MODULE_ID_HTC,
+	QDF_MODULE_ID_TXRX,
+	QDF_MODULE_ID_QDF_DEVICE = 64,
+	QDF_MODULE_ID_CFG,
+	QDF_MODULE_ID_BMI,
+	QDF_MODULE_ID_EPPING,
+	QDF_MODULE_ID_QVIT,
+	QDF_MODULE_ID_DP,
+	QDF_MODULE_ID_SOC,
+	QDF_MODULE_ID_OS_IF,
+	QDF_MODULE_ID_TARGET_IF,
+	QDF_MODULE_ID_SCHEDULER,
+	QDF_MODULE_ID_MGMT_TXRX,
+	QDF_MODULE_ID_RSV4,
+	QDF_MODULE_ID_ANY,
+	QDF_MODULE_ID_MAX,
+} QDF_MODULE_ID;
 
 #ifdef CONFIG_MCL
 /* By default Data Path module will have all log levels enabled, except debug
@@ -535,4 +668,217 @@ void __printf(3, 4) qdf_snprintf(char *str_buffer, unsigned int size,
 
 #endif /* CONFIG_MCL */
 
+#define ERROR_CODE                      -1
+#define QDF_MAX_NAME_SIZE               32
+#define MAX_PRINT_CONFIG_SUPPORTED      32
+
+#define MAX_SUPPORTED_CATEGORY QDF_MODULE_ID_MAX
+
+/*
+ * Shared print control index
+ * for converged debug framework
+ */
+#define QDF_PRINT_IDX_SHARED -1
+
+/**
+ * QDF_PRINT_INFO() - Generic wrapper API for logging
+ * @idx : Index of print control object
+ * @module : Module identifier. A member of QDF_MODULE_ID enumeration that
+ *           identifies the module issuing the trace message
+ * @level : Trace level. A member of QDF_TRACE_LEVEL enumeration indicating
+ *          the severity of the condition causing the trace message to be
+ *          issued.
+ * @str_format : Format string that contains the message to be logged.
+ *
+ *
+ * This wrapper will be used for any generic logging messages. Wrapper will
+ * compile a call to converged QDF trace message API.
+ *
+ * Return : Nothing
+ *
+ */
+void QDF_PRINT_INFO(unsigned int idx, QDF_MODULE_ID module,
+		    QDF_TRACE_LEVEL level,
+		    char *str_format, ...);
+
+/**
+ * struct category_info  : Category information structure
+ * @category_verbose_mask: Embeds information about category's verbose level
+ */
+struct category_info {
+	uint16_t category_verbose_mask;
+};
+
+/**
+ * struct category_name_info  : Category name information structure
+ * @category_name_str: Embeds information about category name
+ */
+struct category_name_info {
+	unsigned char category_name_str[QDF_MAX_NAME_SIZE];
+};
+
+/**
+ * qdf_trace_msg_cmn()- Converged logging API
+ * @idx: Index of print control object assigned to the module
+ * @category: Category identifier. A member of the QDF_MODULE_ID enumeration
+ *            that identifies the category issuing the trace message.
+ * @verbose: Verbose level. A member of the QDF_TRACE_LEVEL enumeration
+ *           indicating the severity of the condition causing the trace
+ *           message to be issued. More severe conditions are more likely
+ *           to be logged.
+ * @str_format: Format string. The message to be logged. This format string
+ *              contains printf-like replacement parameters, which follow this
+ *              parameter in the variable argument list.
+ * @val: Variable argument list part of the log message
+ *
+ * Return: nothing
+ *
+ */
+void qdf_trace_msg_cmn(unsigned int idx,
+			QDF_MODULE_ID category,
+			QDF_TRACE_LEVEL verbose,
+			const char *str_format,
+			va_list val);
+
+/**
+ * struct qdf_print_ctrl: QDF Print Control structure
+ *                        Statically allocated objects of print control
+ *                        structure are declared that will support maximum of
+ *                        32 print control objects. Any module that needs to
+ *                        register to the print control framework needs to
+ *                        obtain a print control object using
+ *                        qdf_print_ctrl_register API. It will have to pass
+ *                        pointer to category info structure, name and
+ *                        custom print function to be used if required.
+ * @name                : Optional name for the control object
+ * @cat_info            : Array of category_info struct
+ * @custom_print        : Custom print handler
+ * @custom_ctxt         : Custom print context
+ * @dbglvlmac_on        : Flag to enable/disable MAC level filtering
+ * @in_use              : Boolean to indicate if control object is in use
+ */
+struct qdf_print_ctrl {
+	char name[QDF_MAX_NAME_SIZE];
+	struct category_info cat_info[MAX_SUPPORTED_CATEGORY];
+	void (*custom_print)(void *ctxt, const char *fmt, va_list args);
+	void *custom_ctxt;
+#ifdef DBG_LVL_MAC_FILTERING
+	unsigned char dbglvlmac_on;
+#endif
+	bool in_use;
+};
+
+/**
+ * qdf_print_ctrl_register() - Allocate QDF print control object, assign
+ *                             pointer to category info or print control
+ *                             structure and return the index to the callee
+ * @cinfo                 : Pointer to array of category info structure
+ * @custom_print_handler  : Pointer to custom print handler
+ * @custom_ctx            : Pointer to custom context
+ * @pctrl_name            : Pointer to print control object name
+ *
+ * Return                 : Index of qdf_print_ctrl structure
+ *
+ */
+int qdf_print_ctrl_register(const struct category_info *cinfo,
+			    void *custom_print_handler,
+			    void *custom_ctx,
+			    const char *pctrl_name);
+
+/**
+ * qdf_print_setup() - Setup default values to all the print control objects
+ *
+ * Register new print control object for the callee
+ *
+ * Return :             QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE
+ *                      on failure
+ */
+QDF_STATUS qdf_print_setup(void);
+
+/**
+ * qdf_print_ctrl_cleanup() - Clean up a print control object
+ *
+ * Cleanup the print control object for the callee
+ *
+ * @pctrl : Index of print control object
+ *
+ * Return : QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE on failure
+ */
+QDF_STATUS qdf_print_ctrl_cleanup(unsigned int idx);
+
+/**
+ * qdf_print_set_category_verbose() - Enable/Disable category for a
+ *                                    print control object with
+ *                                    user provided verbose level
+ *
+ * @idx : Index of the print control object assigned to callee
+ * @category : Category information
+ * @verbose: Verbose information
+ * @is_set: Flag indicating if verbose level needs to be enabled or disabled
+ *
+ * Return : QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS qdf_print_set_category_verbose(unsigned int idx,
+					  QDF_MODULE_ID category,
+					  QDF_TRACE_LEVEL verbose,
+					  bool is_set);
+
+/**
+ * qdf_print_is_category_enabled() - Get category information for the
+ *                                   print control object
+ *
+ * @idx : Index of print control object
+ * @category : Category information
+ *
+ * Return : Verbose enabled(true) or disabled(false) or invalid input (false)
+ */
+bool qdf_print_is_category_enabled(unsigned int idx,
+				   QDF_MODULE_ID category);
+
+/**
+ * qdf_print_is_verbose_enabled() - Get verbose information of a category for
+ *                                  the print control object
+ *
+ * @idx : Index of print control object
+ * @category : Category information
+ * @verbose : Verbose information
+ *
+ * Return : Verbose enabled(true) or disabled(false) or invalid input (false)
+ */
+bool qdf_print_is_verbose_enabled(unsigned int idx,
+				  QDF_MODULE_ID category,
+				  QDF_TRACE_LEVEL verbose);
+
+/**
+ * qdf_print_clean_node_flag() - Clean up node flag for print control object
+ *
+ * @idx : Index of print control object
+ *
+ * Return : None
+ */
+void qdf_print_clean_node_flag(unsigned int idx);
+
+#ifdef DBG_LVL_MAC_FILTERING
+
+/**
+ * qdf_print_set_node_flag() - Set flag to enable MAC level filtering
+ *
+ * @idx : Index of print control object
+ * @enable : Enable/Disable bit sent by callee
+ *
+ * Return : QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE on Failure
+ */
+QDF_STATUS qdf_print_set_node_flag(unsigned int idx,
+				   uint8_t enable);
+
+/**
+ * qdf_print_get_node_flag() - Get flag that controls MAC level filtering
+ *
+ * @idx : Index of print control object
+ *
+ * Return : Flag that indicates enable(1) or disable(0) or invalid(-1)
+ */
+bool qdf_print_get_node_flag(unsigned int idx);
+
+#endif
 #endif /* __QDF_TRACE_H */

+ 0 - 70
qdf/inc/qdf_types.h

@@ -215,76 +215,6 @@ typedef void (*qdf_timer_func_t)(void *);
 
 #define qdf_offsetof(type, field) offsetof(type, field)
 
-/**
- * typedef QDF_MODULE_ID - QDF Module IDs
- * @QDF_MODULE_ID_TLSHIM: TLSHIM module ID
- * @QDF_MODULE_ID_WMI: WMI module ID
- * @QDF_MODULE_ID_HTT: HTT module ID
- * @QDF_MODULE_ID_RSV4: Reserved
- * @QDF_MODULE_ID_HDD: HDD module ID
- * @QDF_MODULE_ID_SME: SME module ID
- * @QDF_MODULE_ID_PE: PE module ID
- * @QDF_MODULE_ID_WMA: WMA module ID
- * @QDF_MODULE_ID_SYS: SYS module ID
- * @QDF_MODULE_ID_QDF: QDF module ID
- * @QDF_MODULE_ID_SAP: SAP module ID
- * @QDF_MODULE_ID_HDD_SOFTAP: HDD SAP module ID
- * @QDF_MODULE_ID_HDD_DATA: HDD DATA module ID
- * @QDF_MODULE_ID_HDD_SAP_DATA: HDD SAP DATA module ID
- * @QDF_MODULE_ID_HIF: HIF module ID
- * @QDF_MODULE_ID_HTC: HTC module ID
- * @QDF_MODULE_ID_TXRX: TXRX module ID
- * @QDF_MODULE_ID_QDF_DEVICE: QDF DEVICE module ID
- * @QDF_MODULE_ID_CFG: CFG module ID
- * @QDF_MODULE_ID_BMI: BMI module ID
- * @QDF_MODULE_ID_EPPING: EPPING module ID
- * @QDF_MODULE_ID_QVIT: QVIT module ID
- * @QDF_MODULE_ID_DP: Data path module ID
- * @QDF_MODULE_ID_SOC: SOC module ID
- * @QDF_MODULE_ID_OS_IF: Scheduler OS interface queue module ID
- * @QDF_MODULE_ID_TARGET_IF: Scheduler target interface queue module ID
- * @QDF_MODULE_ID_SCHEDULER: Scheduler's module ID
- * @QDF_MODULE_ID_MGMT_TXRX: MGMT_TXRX module ID
- * @QDF_MODULE_ID_ANY: Generic module ID
- * @QDF_MODULE_ID_MAX: Max place holder module ID
- *
- * These are generic IDs that identify the various modules in the software
- * system
- * 0 & 4 are unused for historical purposes
- */
-typedef enum {
-	QDF_MODULE_ID_TLSHIM = 1,
-	QDF_MODULE_ID_WMI = 2,
-	QDF_MODULE_ID_HTT = 3,
-	QDF_MODULE_ID_RSV4 = 4,
-	QDF_MODULE_ID_HDD = 5,
-	QDF_MODULE_ID_SME = 6,
-	QDF_MODULE_ID_PE = 7,
-	QDF_MODULE_ID_WMA = 8,
-	QDF_MODULE_ID_SYS = 9,
-	QDF_MODULE_ID_QDF = 10,
-	QDF_MODULE_ID_SAP = 11,
-	QDF_MODULE_ID_HDD_SOFTAP = 12,
-	QDF_MODULE_ID_HDD_DATA = 14,
-	QDF_MODULE_ID_HDD_SAP_DATA = 15,
-	QDF_MODULE_ID_HIF = 16,
-	QDF_MODULE_ID_HTC = 17,
-	QDF_MODULE_ID_TXRX = 18,
-	QDF_MODULE_ID_QDF_DEVICE = 19,
-	QDF_MODULE_ID_CFG = 20,
-	QDF_MODULE_ID_BMI = 21,
-	QDF_MODULE_ID_EPPING = 22,
-	QDF_MODULE_ID_QVIT = 23,
-	QDF_MODULE_ID_DP = 24,
-	QDF_MODULE_ID_SOC = 25,
-	QDF_MODULE_ID_OS_IF = 26,
-	QDF_MODULE_ID_TARGET_IF = 27,
-	QDF_MODULE_ID_SCHEDULER = 28,
-	QDF_MODULE_ID_MGMT_TXRX = 29,
-	QDF_MODULE_ID_ANY = 30,
-	QDF_MODULE_ID_MAX
-} QDF_MODULE_ID;
-
 /**
  * enum tQDF_ADAPTER_MODE - Concurrency role.
  * @QDF_STA_MODE: STA mode

+ 462 - 9
qdf/linux/src/qdf_trace.c

@@ -35,6 +35,9 @@
 #include <qdf_trace.h>
 #include <linux/export.h>
 
+/* macro to map qdf trace levels into the bitmask */
+#define QDF_TRACE_LEVEL_TO_MODULE_BITMASK(_level) ((1 << (_level)))
+
 #ifdef CONFIG_MCL
 
 #include <wlan_logging_sock_svc.h>
@@ -42,13 +45,8 @@
 #include "qdf_mc_timer.h"
 /* Preprocessor definitions and constants */
 
-#define QDF_TRACE_BUFFER_SIZE (512)
-
 enum qdf_timestamp_unit qdf_log_timestamp_type = QDF_LOG_TIMESTAMP_UNIT;
 
-/* macro to map qdf trace levels into the bitmask */
-#define QDF_TRACE_LEVEL_TO_MODULE_BITMASK(_level) ((1 << (_level)))
-
 /**
  * typedef struct module_trace_info - Trace level for a module, as a bitmask.
  * The bits in this mask are ordered by QDF_TRACE_LEVEL.  For example,
@@ -64,9 +62,6 @@ typedef struct {
 	unsigned char module_name_str[4];
 } module_trace_info;
 
-#define QDF_DEFAULT_TRACE_LEVEL	\
-	((1 << QDF_TRACE_LEVEL_FATAL) | (1 << QDF_TRACE_LEVEL_ERROR))
-
 /* Array of static data that contains all of the per module trace
  * information.  This includes the trace level for the module and
  * the 3 character 'name' of the module for marking the trace logs
@@ -310,7 +305,8 @@ void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
 	int n;
 
 	/* Print the trace message when the desired level bit is set in
-	   the module tracel level mask */
+	 * the module tracel level mask
+	 */
 	if (g_qdf_trace_info[module].module_trace_level &
 	    QDF_TRACE_LEVEL_TO_MODULE_BITMASK(level)) {
 		/* the trace level strings in an array.  these are ordered in
@@ -1721,10 +1717,467 @@ void qdf_dp_trace_dump_all(uint32_t count)
 	}
 }
 EXPORT_SYMBOL(qdf_dp_trace_dump_all);
+
 #endif
 
 #endif /* CONFIG_MCL */
 
+struct qdf_print_ctrl print_ctrl_obj[MAX_PRINT_CONFIG_SUPPORTED];
+
+struct category_name_info g_qdf_category_name[MAX_SUPPORTED_CATEGORY] = {
+	[QDF_MODULE_ID_TDLS] = {"tdls"},
+	[QDF_MODULE_ID_ACS] = {"ACS"},
+	[QDF_MODULE_ID_SCAN_SM] = {"scan state machine"},
+	[QDF_MODULE_ID_SCANENTRY] = {"scan entry"},
+	[QDF_MODULE_ID_WDS] = {"WDS"},
+	[QDF_MODULE_ID_ACTION] = {"action"},
+	[QDF_MODULE_ID_ROAM] = {"STA roaming"},
+	[QDF_MODULE_ID_INACT] = {"inactivity"},
+	[QDF_MODULE_ID_DOTH] = {"11h"},
+	[QDF_MODULE_ID_IQUE] = {"IQUE"},
+	[QDF_MODULE_ID_WME] = {"WME"},
+	[QDF_MODULE_ID_ACL] = {"ACL"},
+	[QDF_MODULE_ID_WPA] = {"WPA/RSN"},
+	[QDF_MODULE_ID_RADKEYS] = {"dump 802.1x keys"},
+	[QDF_MODULE_ID_RADDUMP] = {"dump radius packet"},
+	[QDF_MODULE_ID_RADIUS] = {"802.1x radius client"},
+	[QDF_MODULE_ID_DOT1XSM] = {"802.1x state machine"},
+	[QDF_MODULE_ID_DOT1X] = {"802.1x authenticator"},
+	[QDF_MODULE_ID_POWER] = {"power save"},
+	[QDF_MODULE_ID_STATE] = {"state"},
+	[QDF_MODULE_ID_OUTPUT] = {"output"},
+	[QDF_MODULE_ID_SCAN] = {"scan"},
+	[QDF_MODULE_ID_AUTH] = {"authentication"},
+	[QDF_MODULE_ID_ASSOC] = {"association"},
+	[QDF_MODULE_ID_NODE] = {"node"},
+	[QDF_MODULE_ID_ELEMID] = {"element ID"},
+	[QDF_MODULE_ID_XRATE] = {"rate"},
+	[QDF_MODULE_ID_INPUT] = {"input"},
+	[QDF_MODULE_ID_CRYPTO] = {"crypto"},
+	[QDF_MODULE_ID_DUMPPKTS] = {"dump packet"},
+	[QDF_MODULE_ID_DEBUG] = {"debug"},
+	[QDF_MODULE_ID_MLME] = {"mlme"},
+	[QDF_MODULE_ID_RRM] = {"rrm"},
+	[QDF_MODULE_ID_WNM] = {"wnm"},
+	[QDF_MODULE_ID_P2P_PROT] = {"p2p_prot"},
+	[QDF_MODULE_ID_PROXYARP] = {"proxyarp"},
+	[QDF_MODULE_ID_L2TIF] = {"l2tif"},
+	[QDF_MODULE_ID_WIFIPOS] = {"wifipos"},
+	[QDF_MODULE_ID_WRAP] = {"wrap"},
+	[QDF_MODULE_ID_DFS] = {"dfs"},
+	[QDF_MODULE_ID_ATF] = {"atf"},
+	[QDF_MODULE_ID_SPLITMAC] = {"splitmac"},
+	[QDF_MODULE_ID_IOCTL] = {"ioctl"},
+	[QDF_MODULE_ID_NAC] = {"nac"},
+	[QDF_MODULE_ID_MESH] = {"mesh"},
+	[QDF_MODULE_ID_MBO] = {"mbo"},
+	[QDF_MODULE_ID_EXTIOCTL_CHANSWITCH] = {"extchanswitch"},
+	[QDF_MODULE_ID_EXTIOCTL_CHANSSCAN] = {"extchanscan"},
+	[QDF_MODULE_ID_TLSHIM] = {"tlshim"},
+	[QDF_MODULE_ID_WMI] = {"WMI"},
+	[QDF_MODULE_ID_HTT] = {"HTT"},
+	[QDF_MODULE_ID_HDD] = {"HDD"},
+	[QDF_MODULE_ID_SME] = {"SME"},
+	[QDF_MODULE_ID_PE] = {"PE"},
+	[QDF_MODULE_ID_WMA] = {"WMA"},
+	[QDF_MODULE_ID_SYS] = {"SYS"},
+	[QDF_MODULE_ID_QDF] = {"QDF"},
+	[QDF_MODULE_ID_SAP] = {"SAP"},
+	[QDF_MODULE_ID_HDD_SOFTAP] = {"HDD_SAP"},
+	[QDF_MODULE_ID_HDD_DATA] = {"DATA"},
+	[QDF_MODULE_ID_HDD_SAP_DATA] = {"SAP_DATA"},
+	[QDF_MODULE_ID_HIF] = {"HIF"},
+	[QDF_MODULE_ID_HTC] = {"HTC"},
+	[QDF_MODULE_ID_TXRX] = {"TXRX"},
+	[QDF_MODULE_ID_QDF_DEVICE] = {"QDF_DEV"},
+	[QDF_MODULE_ID_CFG] = {"CFG"},
+	[QDF_MODULE_ID_BMI] = {"BMI"},
+	[QDF_MODULE_ID_EPPING] = {"EPPING"},
+	[QDF_MODULE_ID_QVIT] = {"QVIT"},
+	[QDF_MODULE_ID_ANY] = {"ANY"},
+};
+
+void qdf_trace_msg_cmn(unsigned int idx,
+			QDF_MODULE_ID category,
+			QDF_TRACE_LEVEL verbose,
+			const char *str_format, va_list val)
+{
+	char str_buffer[QDF_TRACE_BUFFER_SIZE];
+	int n;
+
+	/* Check if index passed is valid */
+	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
+		pr_info("%s: Invalid index - %d\n", __func__, idx);
+		return;
+	}
+
+	/* Check if print control object is in use */
+	if (!print_ctrl_obj[idx].in_use) {
+		pr_info("%s: Invalid print control object\n", __func__);
+		return;
+	}
+
+	/* Check if category passed is valid */
+	if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
+		pr_info("%s: Invalid category: %d\n", __func__, category);
+		return;
+	}
+
+	/* Check if verbose mask is valid */
+	if (verbose < 0 || verbose >= QDF_TRACE_LEVEL_MAX) {
+		pr_info("%s: Invalid verbose level %d\n", __func__, verbose);
+		return;
+	}
+
+	/*
+	 * Print the trace message when the desired verbose level is set in
+	 * the desired category for the print control object
+	 */
+	if (print_ctrl_obj[idx].cat_info[category].category_verbose_mask &
+	    QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) {
+		/*
+		 * The verbose strings are in an array. These are ordered in
+		 * the same order as the verbose levels are defined in the enum
+		 * (see QDF_TRACE_LEVEL) so we can index into this array with
+		 * the level and get the right string. The qdf verbose
+		 * are... Off, Fatal, Error, Warning, Info, Info_high,
+		 * Info_med, Info_low, Debug
+		 */
+		static const char * const VERBOSE_STR[] = { "  ", "F", "E", "W",
+							"I", "IH", "IM", "IL",
+							"D" };
+
+		/* print the prefix string into the string buffer... */
+		n = scnprintf(str_buffer, QDF_TRACE_BUFFER_SIZE,
+			     "wlan: [%d:%2s:%s] ",
+			     in_interrupt() ? 0 : current->pid,
+			     VERBOSE_STR[verbose],
+			     g_qdf_category_name[category].category_name_str);
+
+		/* print the formatted log message after the prefix string */
+		vscnprintf(str_buffer + n, QDF_TRACE_BUFFER_SIZE - n,
+			   str_format, val);
+#if defined(WLAN_LOGGING_SOCK_SVC_ENABLE)
+		wlan_log_to_user(verbose, (char *)str_buffer,
+				 strlen(str_buffer));
+#else
+		pr_err("%s\n", str_buffer);
+#endif
+		va_end(val);
+	}
+}
+EXPORT_SYMBOL(qdf_trace_msg_cmn);
+
+QDF_STATUS qdf_print_setup(void)
+{
+	int i;
+
+	/* Loop through all print ctrl objects */
+	for (i = 0; i < MAX_PRINT_CONFIG_SUPPORTED; i++) {
+		if (qdf_print_ctrl_cleanup(i))
+			return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(qdf_print_setup);
+
+QDF_STATUS qdf_print_ctrl_cleanup(unsigned int idx)
+{
+	int i = 0;
+
+	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
+		pr_info("%s: Invalid index - %d\n", __func__, idx);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Clean up the print control object corresponding to that index
+	 * If success, callee to change print control index to -1
+	 */
+
+	for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
+		print_ctrl_obj[idx].cat_info[i].category_verbose_mask =
+							QDF_TRACE_LEVEL_NONE;
+	}
+	print_ctrl_obj[idx].custom_print = NULL;
+	print_ctrl_obj[idx].custom_ctxt = NULL;
+	qdf_print_clean_node_flag(idx);
+	print_ctrl_obj[idx].in_use = false;
+
+	pr_info("%s: Print control object %d cleaned up\n", __func__, idx);
+
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(qdf_print_ctrl_cleanup);
+
+int qdf_print_ctrl_register(const struct category_info *cinfo,
+			    void *custom_print_handler,
+			    void *custom_ctx,
+			    const char *pctrl_name)
+{
+	int idx = -1;
+	int i = 0;
+
+	for (i = 0; i < MAX_PRINT_CONFIG_SUPPORTED; i++) {
+		if (!print_ctrl_obj[i].in_use) {
+			idx = i;
+			break;
+		}
+	}
+
+	/* Callee to handle idx -1 appropriately */
+	if (idx == -1) {
+		pr_info("%s: Allocation failed! No print control object free\n",
+			__func__);
+		return idx;
+	}
+
+	print_ctrl_obj[idx].in_use = true;
+
+	/*
+	 * In case callee does not pass category info,
+	 * custom print handler, custom context and print control name,
+	 * we do not set any value here. Clean up for the print control
+	 * getting allocated would have taken care of initializing
+	 * default values.
+	 *
+	 * We need to only set in_use to 1 in such a case
+	 */
+
+	if (pctrl_name) {
+		qdf_str_lcopy(print_ctrl_obj[idx].name, pctrl_name,
+			      qdf_str_len(pctrl_name) + 1);
+	}
+
+	if (custom_print_handler)
+		print_ctrl_obj[idx].custom_print = custom_print_handler;
+
+	if (custom_ctx)
+		print_ctrl_obj[idx].custom_ctxt = custom_ctx;
+
+	if (cinfo) {
+		for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
+			if (cinfo[i].category_verbose_mask ==
+			    QDF_TRACE_LEVEL_ALL) {
+				print_ctrl_obj[idx].cat_info[i]
+				.category_verbose_mask = 0xFFFF;
+			} else {
+				print_ctrl_obj[idx].cat_info[i]
+				.category_verbose_mask =
+				cinfo[i].category_verbose_mask;
+			}
+		}
+	}
+
+	pr_info("%s: Allocated print control object %d\n",
+		__func__, idx);
+	return idx;
+}
+EXPORT_SYMBOL(qdf_print_ctrl_register);
+
+QDF_STATUS qdf_print_set_category_verbose(unsigned int idx,
+						QDF_MODULE_ID category,
+						QDF_TRACE_LEVEL verbose,
+						bool is_set)
+{
+	/* Check if index passed is valid */
+	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
+		pr_info("%s: Invalid index - %d\n", __func__, idx);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Check if print control object is in use */
+	if (!print_ctrl_obj[idx].in_use) {
+		pr_info("%s: Invalid print control object\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Check if category passed is valid */
+	if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
+		pr_info("%s: Invalid category: %d\n", __func__, category);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Check if verbose mask is valid */
+	if (verbose < 0 || verbose >= QDF_TRACE_LEVEL_MAX) {
+		pr_info("%s: Invalid verbose level %d\n", __func__, verbose);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (verbose == QDF_TRACE_LEVEL_ALL) {
+		print_ctrl_obj[idx].cat_info[category].category_verbose_mask =
+				0xFFFF;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (verbose == QDF_TRACE_LEVEL_NONE) {
+		print_ctrl_obj[idx].cat_info[category].category_verbose_mask =
+				QDF_TRACE_LEVEL_NONE;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (!is_set) {
+		if (print_ctrl_obj[idx].cat_info[category].category_verbose_mask
+		    & QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) {
+			print_ctrl_obj[idx].cat_info[category]
+				.category_verbose_mask &=
+				~QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose);
+		}
+	} else {
+		print_ctrl_obj[idx].cat_info[category].category_verbose_mask |=
+				QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose);
+	}
+
+	pr_info("%s: Print control object %d, Category %d, Verbose level %d\n",
+		__func__,
+		idx,
+		category,
+		print_ctrl_obj[idx].cat_info[category].category_verbose_mask);
+
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(qdf_print_set_category_verbose);
+
+bool qdf_print_is_category_enabled(unsigned int idx, QDF_MODULE_ID category)
+{
+	QDF_TRACE_LEVEL verbose_mask;
+
+	/* Check if index passed is valid */
+	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
+		pr_info("%s: Invalid index - %d\n", __func__, idx);
+		return false;
+	}
+
+	/* Check if print control object is in use */
+	if (!print_ctrl_obj[idx].in_use) {
+		pr_info("%s: Invalid print control object\n", __func__);
+		return false;
+	}
+
+	/* Check if category passed is valid */
+	if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
+		pr_info("%s: Invalid category: %d\n", __func__, category);
+		return false;
+	}
+
+	verbose_mask =
+		print_ctrl_obj[idx].cat_info[category].category_verbose_mask;
+
+	if (verbose_mask == QDF_TRACE_LEVEL_NONE)
+		return false;
+	else
+		return true;
+}
+EXPORT_SYMBOL(qdf_print_is_category_enabled);
+
+bool qdf_print_is_verbose_enabled(unsigned int idx, QDF_MODULE_ID category,
+				  QDF_TRACE_LEVEL verbose)
+{
+	bool verbose_enabled = false;
+
+	/* Check if index passed is valid */
+	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
+		pr_info("%s: Invalid index - %d\n", __func__, idx);
+		return verbose_enabled;
+	}
+
+	/* Check if print control object is in use */
+	if (!print_ctrl_obj[idx].in_use) {
+		pr_info("%s: Invalid print control object\n", __func__);
+		return verbose_enabled;
+	}
+
+	/* Check if category passed is valid */
+	if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
+		pr_info("%s: Invalid category: %d\n", __func__, category);
+		return verbose_enabled;
+	}
+
+	if ((verbose == QDF_TRACE_LEVEL_NONE) ||
+	    (verbose >= QDF_TRACE_LEVEL_MAX)) {
+		verbose_enabled = false;
+	} else if (verbose == QDF_TRACE_LEVEL_ALL) {
+		if (print_ctrl_obj[idx].cat_info[category]
+					.category_verbose_mask == 0xFFFF)
+			verbose_enabled = true;
+	} else {
+		verbose_enabled =
+		(print_ctrl_obj[idx].cat_info[category].category_verbose_mask &
+		 QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) ? true : false;
+	}
+
+	return verbose_enabled;
+}
+EXPORT_SYMBOL(qdf_print_is_verbose_enabled);
+
+#ifdef DBG_LVL_MAC_FILTERING
+
+QDF_STATUS qdf_print_set_node_flag(unsigned int idx, uint8_t enable)
+{
+	/* Check if index passed is valid */
+	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
+		pr_info("%s: Invalid index - %d\n", __func__, idx);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Check if print control object is in use */
+	if (!print_ctrl_obj[idx].in_use) {
+		pr_info("%s: Invalid print control object\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (enable > 1) {
+		pr_info("%s: Incorrect input: Use 1 or 0 to enable or disable\n",
+			__func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	print_ctrl_obj[idx].dbglvlmac_on = enable;
+	pr_info("%s: DbgLVLmac feature %s\n",
+		__func__,
+		((enable) ? "enabled" : "disabled"));
+
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(qdf_print_set_node_flag);
+
+bool qdf_print_get_node_flag(unsigned int idx)
+{
+	bool node_flag = false;
+
+	/* Check if index passed is valid */
+	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
+		pr_info("%s: Invalid index - %d\n", __func__, idx);
+		return node_flag;
+	}
+
+	/* Check if print control object is in use */
+	if (!print_ctrl_obj[idx].in_use) {
+		pr_info("%s: Invalid print control object\n", __func__);
+		return node_flag;
+	}
+
+	if (print_ctrl_obj[idx].dbglvlmac_on)
+		node_flag = true;
+
+	return node_flag;
+}
+EXPORT_SYMBOL(qdf_print_get_node_flag);
+
+void qdf_print_clean_node_flag(unsigned int idx)
+{
+	/* Disable dbglvlmac_on during cleanup */
+	print_ctrl_obj[idx].dbglvlmac_on = 0;
+}
+
+#else
+
+void qdf_print_clean_node_flag(unsigned int idx)
+{
+	/* No operation in case of no support for DBG_LVL_MAC_FILTERING */
+	return;
+}
+#endif
+
 void QDF_PRINT_INFO(unsigned int idx, QDF_MODULE_ID module,
 		    QDF_TRACE_LEVEL level,
 		    char *str_format, ...)