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