xref: /freebsd/sys/contrib/dev/iwlwifi/iwl-debug.c (revision 266f97b5)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /*
3  * Copyright (C) 2005-2011, 2021 Intel Corporation
4  */
5 #include <linux/device.h>
6 #include <linux/interrupt.h>
7 #include <linux/export.h>
8 #if defined(CONFIG_IWLWIFI_DEBUG)
9 #include <linux/net.h>
10 #endif
11 #include "iwl-drv.h"
12 #include "iwl-debug.h"
13 #include "iwl-modparams.h"
14 #include "iwl-devtrace.h"
15 
16 #if defined(__FreeBSD__)
17 #if defined(CONFIG_IWLWIFI_DEBUG)
18 #include <sys/systm.h>		/* hexdump(9) */
19 #include <linux/preempt.h>
20 #endif
21 #endif
22 
23 #if defined(__linux__)
24 #define __iwl_fn(fn)						\
25 void __iwl_ ##fn(struct device *dev, const char *fmt, ...)	\
26 {								\
27 	struct va_format vaf = {				\
28 		.fmt = fmt,					\
29 	};							\
30 	va_list args;						\
31 								\
32 	va_start(args, fmt);					\
33 	vaf.va = &args;						\
34 	dev_ ##fn(dev, "%pV", &vaf);				\
35 	trace_iwlwifi_ ##fn(&vaf);				\
36 	va_end(args);						\
37 }
38 #elif defined(__FreeBSD__)
39 #define __iwl_fn(fn)						\
40 void __iwl_ ##fn(struct device *dev, const char *fmt, ...)	\
41 {								\
42 	struct va_format vaf = {				\
43 		.fmt = fmt,					\
44 	};							\
45 	va_list args;						\
46 	char *str;						\
47 								\
48 	va_start(args, fmt);					\
49 	vaf.va = &args;						\
50 	vasprintf(&str, M_KMALLOC, fmt, args);			\
51 	dev_ ##fn(dev, "%s", str);				\
52 	trace_iwlwifi_ ##fn(&vaf);				\
53 	free(str, M_KMALLOC);					\
54 	va_end(args);						\
55 }
56 #endif
57 
58 __iwl_fn(warn)
59 IWL_EXPORT_SYMBOL(__iwl_warn);
60 __iwl_fn(info)
61 IWL_EXPORT_SYMBOL(__iwl_info);
62 __iwl_fn(crit)
63 IWL_EXPORT_SYMBOL(__iwl_crit);
64 
65 void __iwl_err(struct device *dev, enum iwl_err_mode mode, const char *fmt, ...)
66 {
67 	struct va_format vaf = {
68 		.fmt = fmt,
69 	};
70 	va_list args, args2;
71 
72 	va_start(args, fmt);
73 	switch (mode) {
74 	case IWL_ERR_MODE_RATELIMIT:
75 		if (net_ratelimit())
76 			break;
77 		fallthrough;
78 	case IWL_ERR_MODE_REGULAR:
79 	case IWL_ERR_MODE_RFKILL:
80 		va_copy(args2, args);
81 		vaf.va = &args2;
82 #if defined(__linux_)
83 		if (mode == IWL_ERR_MODE_RFKILL)
84 			dev_err(dev, "(RFKILL) %pV", &vaf);
85 		else
86 			dev_err(dev, "%pV", &vaf);
87 #elif defined(__FreeBSD__)
88 		char *str;
89 		vasprintf(&str, M_KMALLOC, fmt, args2);
90 		dev_err(dev, "%s%s", (mode == IWL_ERR_MODE_RFKILL) ? "(RFKILL)" : "", str);
91 		free(str, M_KMALLOC);
92 #endif
93 		va_end(args2);
94 		break;
95 	default:
96 		break;
97 	}
98 	trace_iwlwifi_err(&vaf);
99 	va_end(args);
100 }
101 IWL_EXPORT_SYMBOL(__iwl_err);
102 
103 #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
104 
105 #ifdef CONFIG_IWLWIFI_DEBUG
106 bool
107 iwl_have_debug_level(enum iwl_dl level)
108 {
109 
110 	return (iwlwifi_mod_params.debug_level & level || level == IWL_DL_ANY);
111 }
112 
113 /* Passing the iwl_drv * in seems pointless. */
114 void
115 iwl_print_hex_dump(void *drv __unused, enum iwl_dl level,
116     const char *prefix, uint8_t *data, size_t len)
117 {
118 
119 	/* Given we have a level, check for it. */
120 	if (!iwl_have_debug_level(level))
121 		return;
122 
123 #if defined(__linux_)
124 	/* XXX I am cluseless in my editor. pcie/trans.c to the rescue. */
125 	print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET,
126 	    32, 4, data, len, 0);
127 #elif defined(__FreeBSD__)
128 	hexdump(data, len, prefix, 0);
129 #endif
130 }
131 #endif
132 
133 void __iwl_dbg(struct device *dev,
134 	       u32 level, bool limit, const char *function,
135 	       const char *fmt, ...)
136 {
137 	struct va_format vaf = {
138 		.fmt = fmt,
139 	};
140 	va_list args;
141 
142 	va_start(args, fmt);
143 	vaf.va = &args;
144 #if defined(CONFIG_IWLWIFI_DEBUG)
145 	if (iwl_have_debug_level(level) &&
146 	    (!limit || net_ratelimit())) {
147 #if defined(__linux_)
148 		dev_printk(KERN_DEBUG, dev, "%s %pV", function, &vaf);
149 #elif defined(__FreeBSD__)
150 		char *str;
151 		vasprintf(&str, M_KMALLOC, fmt, args);
152 		dev_printk(KERN_DEBUG, dev, "%d %u %s %s",
153 		    curthread->td_tid, (unsigned int)ticks, function, str);
154 		free(str, M_KMALLOC);
155 #endif
156 	}
157 
158 #endif
159 	trace_iwlwifi_dbg(level, function, &vaf);
160 	va_end(args);
161 }
162 IWL_EXPORT_SYMBOL(__iwl_dbg);
163 #endif
164