18e99ea8dSJohannes Berg // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
28e99ea8dSJohannes Berg /*
3*634c7b1bSJohannes Berg  * Copyright (C) 2005-2011, 2021-2022 Intel Corporation
48e99ea8dSJohannes Berg  */
5e705c121SKalle Valo #include <linux/device.h>
6e705c121SKalle Valo #include <linux/interrupt.h>
7e705c121SKalle Valo #include <linux/export.h>
8e705c121SKalle Valo #include "iwl-drv.h"
9e705c121SKalle Valo #include "iwl-debug.h"
10e705c121SKalle Valo #include "iwl-devtrace.h"
11e705c121SKalle Valo 
12e705c121SKalle Valo #define __iwl_fn(fn)						\
13e705c121SKalle Valo void __iwl_ ##fn(struct device *dev, const char *fmt, ...)	\
14e705c121SKalle Valo {								\
15e705c121SKalle Valo 	struct va_format vaf = {				\
16e705c121SKalle Valo 		.fmt = fmt,					\
17e705c121SKalle Valo 	};							\
18e705c121SKalle Valo 	va_list args;						\
19e705c121SKalle Valo 								\
20e705c121SKalle Valo 	va_start(args, fmt);					\
21e705c121SKalle Valo 	vaf.va = &args;						\
22e705c121SKalle Valo 	dev_ ##fn(dev, "%pV", &vaf);				\
23e705c121SKalle Valo 	trace_iwlwifi_ ##fn(&vaf);				\
24e705c121SKalle Valo 	va_end(args);						\
25e705c121SKalle Valo }
26e705c121SKalle Valo 
27e705c121SKalle Valo __iwl_fn(warn)
28e705c121SKalle Valo IWL_EXPORT_SYMBOL(__iwl_warn);
29e705c121SKalle Valo __iwl_fn(info)
30e705c121SKalle Valo IWL_EXPORT_SYMBOL(__iwl_info);
31e705c121SKalle Valo __iwl_fn(crit)
32e705c121SKalle Valo IWL_EXPORT_SYMBOL(__iwl_crit);
33e705c121SKalle Valo 
__iwl_err(struct device * dev,enum iwl_err_mode mode,const char * fmt,...)34e5f1cc98SJohannes Berg void __iwl_err(struct device *dev, enum iwl_err_mode mode, const char *fmt, ...)
35e705c121SKalle Valo {
36e705c121SKalle Valo 	struct va_format vaf = {
37e705c121SKalle Valo 		.fmt = fmt,
38e705c121SKalle Valo 	};
39e5f1cc98SJohannes Berg 	va_list args, args2;
40e705c121SKalle Valo 
41e705c121SKalle Valo 	va_start(args, fmt);
42e5f1cc98SJohannes Berg 	switch (mode) {
43e5f1cc98SJohannes Berg 	case IWL_ERR_MODE_RATELIMIT:
44e5f1cc98SJohannes Berg 		if (net_ratelimit())
45e5f1cc98SJohannes Berg 			break;
46e5f1cc98SJohannes Berg 		fallthrough;
47e5f1cc98SJohannes Berg 	case IWL_ERR_MODE_REGULAR:
48e5f1cc98SJohannes Berg 	case IWL_ERR_MODE_RFKILL:
49e5f1cc98SJohannes Berg 		va_copy(args2, args);
50e5f1cc98SJohannes Berg 		vaf.va = &args2;
51e5f1cc98SJohannes Berg 		if (mode == IWL_ERR_MODE_RFKILL)
52e705c121SKalle Valo 			dev_err(dev, "(RFKILL) %pV", &vaf);
53e705c121SKalle Valo 		else
54e705c121SKalle Valo 			dev_err(dev, "%pV", &vaf);
55e5f1cc98SJohannes Berg 		va_end(args2);
56e5f1cc98SJohannes Berg 		break;
57e5f1cc98SJohannes Berg 	default:
58e5f1cc98SJohannes Berg 		break;
59e705c121SKalle Valo 	}
60*634c7b1bSJohannes Berg 	vaf.va = &args;
61e705c121SKalle Valo 	trace_iwlwifi_err(&vaf);
62e705c121SKalle Valo 	va_end(args);
63e705c121SKalle Valo }
64e705c121SKalle Valo IWL_EXPORT_SYMBOL(__iwl_err);
65e705c121SKalle Valo 
66e705c121SKalle Valo #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
__iwl_dbg(struct device * dev,u32 level,bool limit,const char * function,const char * fmt,...)67e705c121SKalle Valo void __iwl_dbg(struct device *dev,
68e705c121SKalle Valo 	       u32 level, bool limit, const char *function,
69e705c121SKalle Valo 	       const char *fmt, ...)
70e705c121SKalle Valo {
71e705c121SKalle Valo 	struct va_format vaf = {
72e705c121SKalle Valo 		.fmt = fmt,
73e705c121SKalle Valo 	};
74e705c121SKalle Valo 	va_list args;
75e705c121SKalle Valo 
76e705c121SKalle Valo 	va_start(args, fmt);
77e705c121SKalle Valo 	vaf.va = &args;
78e705c121SKalle Valo #ifdef CONFIG_IWLWIFI_DEBUG
79e705c121SKalle Valo 	if (iwl_have_debug_level(level) &&
80e705c121SKalle Valo 	    (!limit || net_ratelimit()))
81e4ff7d6bSSebastian Andrzej Siewior 		dev_printk(KERN_DEBUG, dev, "%s %pV", function, &vaf);
82e705c121SKalle Valo #endif
83bd63bca5SSebastian Andrzej Siewior 	trace_iwlwifi_dbg(level, function, &vaf);
84e705c121SKalle Valo 	va_end(args);
85e705c121SKalle Valo }
86e705c121SKalle Valo IWL_EXPORT_SYMBOL(__iwl_dbg);
87e705c121SKalle Valo #endif
88