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