1*c7fd2ed0Sgs150176 /* 2*c7fd2ed0Sgs150176 * CDDL HEADER START 3*c7fd2ed0Sgs150176 * 4*c7fd2ed0Sgs150176 * The contents of this file are subject to the terms of the 5*c7fd2ed0Sgs150176 * Common Development and Distribution License, Version 1.0 only 6*c7fd2ed0Sgs150176 * (the "License"). You may not use this file except in compliance 7*c7fd2ed0Sgs150176 * with the License. 8*c7fd2ed0Sgs150176 * 9*c7fd2ed0Sgs150176 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*c7fd2ed0Sgs150176 * or http://www.opensolaris.org/os/licensing. 11*c7fd2ed0Sgs150176 * See the License for the specific language governing permissions 12*c7fd2ed0Sgs150176 * and limitations under the License. 13*c7fd2ed0Sgs150176 * 14*c7fd2ed0Sgs150176 * When distributing Covered Code, include this CDDL HEADER in each 15*c7fd2ed0Sgs150176 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*c7fd2ed0Sgs150176 * If applicable, add the following below this CDDL HEADER, with the 17*c7fd2ed0Sgs150176 * fields enclosed by brackets "[]" replaced with your own identifying 18*c7fd2ed0Sgs150176 * information: Portions Copyright [yyyy] [name of copyright owner] 19*c7fd2ed0Sgs150176 * 20*c7fd2ed0Sgs150176 * CDDL HEADER END 21*c7fd2ed0Sgs150176 */ 22*c7fd2ed0Sgs150176 /* 23*c7fd2ed0Sgs150176 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*c7fd2ed0Sgs150176 * Use is subject to license terms. 25*c7fd2ed0Sgs150176 */ 26*c7fd2ed0Sgs150176 27*c7fd2ed0Sgs150176 #pragma ident "%Z%%M% %I% %E% SMI" 28*c7fd2ed0Sgs150176 29*c7fd2ed0Sgs150176 #include "rge.h" 30*c7fd2ed0Sgs150176 31*c7fd2ed0Sgs150176 32*c7fd2ed0Sgs150176 /* 33*c7fd2ed0Sgs150176 * Global variable for default debug flags 34*c7fd2ed0Sgs150176 */ 35*c7fd2ed0Sgs150176 uint32_t rge_debug; 36*c7fd2ed0Sgs150176 37*c7fd2ed0Sgs150176 /* 38*c7fd2ed0Sgs150176 * Global mutex used by logging routines below 39*c7fd2ed0Sgs150176 */ 40*c7fd2ed0Sgs150176 kmutex_t rge_log_mutex[1]; 41*c7fd2ed0Sgs150176 42*c7fd2ed0Sgs150176 /* 43*c7fd2ed0Sgs150176 * Static data used by logging routines; protected by <rge_log_mutex> 44*c7fd2ed0Sgs150176 */ 45*c7fd2ed0Sgs150176 static struct { 46*c7fd2ed0Sgs150176 const char *who; 47*c7fd2ed0Sgs150176 const char *fmt; 48*c7fd2ed0Sgs150176 int level; 49*c7fd2ed0Sgs150176 } rge_log_data; 50*c7fd2ed0Sgs150176 51*c7fd2ed0Sgs150176 52*c7fd2ed0Sgs150176 /* 53*c7fd2ed0Sgs150176 * Backend print routine for all the routines below 54*c7fd2ed0Sgs150176 */ 55*c7fd2ed0Sgs150176 static void 56*c7fd2ed0Sgs150176 rge_vprt(const char *fmt, va_list args) 57*c7fd2ed0Sgs150176 { 58*c7fd2ed0Sgs150176 char buf[128]; 59*c7fd2ed0Sgs150176 60*c7fd2ed0Sgs150176 ASSERT(mutex_owned(rge_log_mutex)); 61*c7fd2ed0Sgs150176 62*c7fd2ed0Sgs150176 (void) vsnprintf(buf, sizeof (buf), fmt, args); 63*c7fd2ed0Sgs150176 cmn_err(rge_log_data.level, rge_log_data.fmt, rge_log_data.who, buf); 64*c7fd2ed0Sgs150176 } 65*c7fd2ed0Sgs150176 66*c7fd2ed0Sgs150176 /* 67*c7fd2ed0Sgs150176 * Report a run-time event (CE_NOTE, to console & log) 68*c7fd2ed0Sgs150176 */ 69*c7fd2ed0Sgs150176 void 70*c7fd2ed0Sgs150176 rge_notice(rge_t *rgep, const char *fmt, ...) 71*c7fd2ed0Sgs150176 { 72*c7fd2ed0Sgs150176 va_list args; 73*c7fd2ed0Sgs150176 74*c7fd2ed0Sgs150176 mutex_enter(rge_log_mutex); 75*c7fd2ed0Sgs150176 rge_log_data.who = rgep->ifname; 76*c7fd2ed0Sgs150176 rge_log_data.fmt = "%s: %s"; 77*c7fd2ed0Sgs150176 rge_log_data.level = CE_NOTE; 78*c7fd2ed0Sgs150176 79*c7fd2ed0Sgs150176 va_start(args, fmt); 80*c7fd2ed0Sgs150176 rge_vprt(fmt, args); 81*c7fd2ed0Sgs150176 va_end(args); 82*c7fd2ed0Sgs150176 83*c7fd2ed0Sgs150176 mutex_exit(rge_log_mutex); 84*c7fd2ed0Sgs150176 } 85*c7fd2ed0Sgs150176 86*c7fd2ed0Sgs150176 /* 87*c7fd2ed0Sgs150176 * Log a run-time event (CE_NOTE, log only) 88*c7fd2ed0Sgs150176 */ 89*c7fd2ed0Sgs150176 void 90*c7fd2ed0Sgs150176 rge_log(rge_t *rgep, const char *fmt, ...) 91*c7fd2ed0Sgs150176 { 92*c7fd2ed0Sgs150176 va_list args; 93*c7fd2ed0Sgs150176 94*c7fd2ed0Sgs150176 mutex_enter(rge_log_mutex); 95*c7fd2ed0Sgs150176 rge_log_data.who = rgep->ifname; 96*c7fd2ed0Sgs150176 rge_log_data.fmt = "!%s: %s"; 97*c7fd2ed0Sgs150176 rge_log_data.level = CE_NOTE; 98*c7fd2ed0Sgs150176 99*c7fd2ed0Sgs150176 va_start(args, fmt); 100*c7fd2ed0Sgs150176 rge_vprt(fmt, args); 101*c7fd2ed0Sgs150176 va_end(args); 102*c7fd2ed0Sgs150176 103*c7fd2ed0Sgs150176 mutex_exit(rge_log_mutex); 104*c7fd2ed0Sgs150176 } 105*c7fd2ed0Sgs150176 106*c7fd2ed0Sgs150176 /* 107*c7fd2ed0Sgs150176 * Log a run-time problem (CE_WARN, log only) 108*c7fd2ed0Sgs150176 */ 109*c7fd2ed0Sgs150176 void 110*c7fd2ed0Sgs150176 rge_problem(rge_t *rgep, const char *fmt, ...) 111*c7fd2ed0Sgs150176 { 112*c7fd2ed0Sgs150176 va_list args; 113*c7fd2ed0Sgs150176 114*c7fd2ed0Sgs150176 mutex_enter(rge_log_mutex); 115*c7fd2ed0Sgs150176 rge_log_data.who = rgep->ifname; 116*c7fd2ed0Sgs150176 rge_log_data.fmt = "!%s: %s"; 117*c7fd2ed0Sgs150176 rge_log_data.level = CE_WARN; 118*c7fd2ed0Sgs150176 119*c7fd2ed0Sgs150176 va_start(args, fmt); 120*c7fd2ed0Sgs150176 rge_vprt(fmt, args); 121*c7fd2ed0Sgs150176 va_end(args); 122*c7fd2ed0Sgs150176 123*c7fd2ed0Sgs150176 mutex_exit(rge_log_mutex); 124*c7fd2ed0Sgs150176 } 125*c7fd2ed0Sgs150176 126*c7fd2ed0Sgs150176 /* 127*c7fd2ed0Sgs150176 * Log a programming error (CE_WARN, log only) 128*c7fd2ed0Sgs150176 */ 129*c7fd2ed0Sgs150176 void 130*c7fd2ed0Sgs150176 rge_error(rge_t *rgep, const char *fmt, ...) 131*c7fd2ed0Sgs150176 { 132*c7fd2ed0Sgs150176 va_list args; 133*c7fd2ed0Sgs150176 134*c7fd2ed0Sgs150176 mutex_enter(rge_log_mutex); 135*c7fd2ed0Sgs150176 rge_log_data.who = rgep->ifname; 136*c7fd2ed0Sgs150176 rge_log_data.fmt = "!%s: %s"; 137*c7fd2ed0Sgs150176 rge_log_data.level = CE_WARN; 138*c7fd2ed0Sgs150176 139*c7fd2ed0Sgs150176 va_start(args, fmt); 140*c7fd2ed0Sgs150176 rge_vprt(fmt, args); 141*c7fd2ed0Sgs150176 va_end(args); 142*c7fd2ed0Sgs150176 143*c7fd2ed0Sgs150176 mutex_exit(rge_log_mutex); 144*c7fd2ed0Sgs150176 } 145*c7fd2ed0Sgs150176 146*c7fd2ed0Sgs150176 #if RGE_DEBUGGING 147*c7fd2ed0Sgs150176 148*c7fd2ed0Sgs150176 static void 149*c7fd2ed0Sgs150176 rge_prt(const char *fmt, ...) 150*c7fd2ed0Sgs150176 { 151*c7fd2ed0Sgs150176 va_list args; 152*c7fd2ed0Sgs150176 153*c7fd2ed0Sgs150176 ASSERT(mutex_owned(rge_log_mutex)); 154*c7fd2ed0Sgs150176 155*c7fd2ed0Sgs150176 va_start(args, fmt); 156*c7fd2ed0Sgs150176 rge_vprt(fmt, args); 157*c7fd2ed0Sgs150176 va_end(args); 158*c7fd2ed0Sgs150176 159*c7fd2ed0Sgs150176 mutex_exit(rge_log_mutex); 160*c7fd2ed0Sgs150176 } 161*c7fd2ed0Sgs150176 162*c7fd2ed0Sgs150176 void 163*c7fd2ed0Sgs150176 (*rge_gdb(void))(const char *fmt, ...) 164*c7fd2ed0Sgs150176 { 165*c7fd2ed0Sgs150176 mutex_enter(rge_log_mutex); 166*c7fd2ed0Sgs150176 rge_log_data.who = "rge"; 167*c7fd2ed0Sgs150176 rge_log_data.fmt = "?%s: %s\n"; 168*c7fd2ed0Sgs150176 rge_log_data.level = CE_CONT; 169*c7fd2ed0Sgs150176 170*c7fd2ed0Sgs150176 return (rge_prt); 171*c7fd2ed0Sgs150176 } 172*c7fd2ed0Sgs150176 173*c7fd2ed0Sgs150176 void 174*c7fd2ed0Sgs150176 (*rge_db(rge_t *rgep))(const char *fmt, ...) 175*c7fd2ed0Sgs150176 { 176*c7fd2ed0Sgs150176 mutex_enter(rge_log_mutex); 177*c7fd2ed0Sgs150176 rge_log_data.who = rgep->ifname; 178*c7fd2ed0Sgs150176 rge_log_data.fmt = "?%s: %s\n"; 179*c7fd2ed0Sgs150176 rge_log_data.level = CE_CONT; 180*c7fd2ed0Sgs150176 181*c7fd2ed0Sgs150176 return (rge_prt); 182*c7fd2ed0Sgs150176 } 183*c7fd2ed0Sgs150176 184*c7fd2ed0Sgs150176 /* 185*c7fd2ed0Sgs150176 * Dump a chunk of memory, 16 bytes at a time 186*c7fd2ed0Sgs150176 */ 187*c7fd2ed0Sgs150176 static void 188*c7fd2ed0Sgs150176 minidump(rge_t *rgep, const char *caption, void *dp, uint_t len) 189*c7fd2ed0Sgs150176 { 190*c7fd2ed0Sgs150176 uint32_t buf[4]; 191*c7fd2ed0Sgs150176 uint32_t nbytes; 192*c7fd2ed0Sgs150176 193*c7fd2ed0Sgs150176 rge_log(rgep, "%d bytes of %s at address %p:-", len, caption, dp); 194*c7fd2ed0Sgs150176 195*c7fd2ed0Sgs150176 for (len = MIN(len, rgep->rxbuf_size); len != 0; len -= nbytes) { 196*c7fd2ed0Sgs150176 nbytes = MIN(len, sizeof (buf)); 197*c7fd2ed0Sgs150176 bzero(buf, sizeof (buf)); 198*c7fd2ed0Sgs150176 bcopy(dp, buf, nbytes); 199*c7fd2ed0Sgs150176 rge_log(rgep, "%08x %08x %08x %08x", 200*c7fd2ed0Sgs150176 buf[0], buf[1], buf[2], buf[3]); 201*c7fd2ed0Sgs150176 dp = (caddr_t)dp + nbytes; 202*c7fd2ed0Sgs150176 } 203*c7fd2ed0Sgs150176 } 204*c7fd2ed0Sgs150176 205*c7fd2ed0Sgs150176 void 206*c7fd2ed0Sgs150176 rge_pkt_dump(rge_t *rgep, rge_bd_t *hrbdp, sw_rbd_t *srbdp, const char *msg) 207*c7fd2ed0Sgs150176 { 208*c7fd2ed0Sgs150176 rge_problem(rgep, "driver-detected hardware error: %s", msg); 209*c7fd2ed0Sgs150176 210*c7fd2ed0Sgs150176 minidump(rgep, "hardware descriptor", hrbdp, sizeof (*hrbdp)); 211*c7fd2ed0Sgs150176 212*c7fd2ed0Sgs150176 rge_log(rgep, "PCI address %lx flags_len 0x%x" 213*c7fd2ed0Sgs150176 "vlan_tag 0x%x", 214*c7fd2ed0Sgs150176 hrbdp->host_buf_addr, 215*c7fd2ed0Sgs150176 hrbdp->flags_len, 216*c7fd2ed0Sgs150176 hrbdp->vlan_tag); 217*c7fd2ed0Sgs150176 218*c7fd2ed0Sgs150176 if (srbdp != NULL) { 219*c7fd2ed0Sgs150176 minidump(rgep, "software descriptor", srbdp, sizeof (*srbdp)); 220*c7fd2ed0Sgs150176 221*c7fd2ed0Sgs150176 rge_log(rgep, "PCI address %llx buffer len 0x%x token 0x%x", 222*c7fd2ed0Sgs150176 srbdp->rx_buf->pbuf.cookie.dmac_laddress, 223*c7fd2ed0Sgs150176 srbdp->rx_buf->pbuf.alength, 224*c7fd2ed0Sgs150176 srbdp->rx_buf->pbuf.token); 225*c7fd2ed0Sgs150176 226*c7fd2ed0Sgs150176 minidump(rgep, "packet data", srbdp->rx_buf->pbuf.mem_va, 227*c7fd2ed0Sgs150176 hrbdp->flags_len & RBD_LEN_MASK); 228*c7fd2ed0Sgs150176 } 229*c7fd2ed0Sgs150176 } 230*c7fd2ed0Sgs150176 231*c7fd2ed0Sgs150176 void 232*c7fd2ed0Sgs150176 rge_dbg_enter(rge_t *rgep, const char *s) 233*c7fd2ed0Sgs150176 { 234*c7fd2ed0Sgs150176 uint32_t debug; 235*c7fd2ed0Sgs150176 236*c7fd2ed0Sgs150176 debug = rgep != NULL ? rgep->debug : rge_debug; 237*c7fd2ed0Sgs150176 if (debug & RGE_DBG_STOP) { 238*c7fd2ed0Sgs150176 cmn_err(CE_CONT, "rge_dbg_enter(%p): %s\n", (void *)rgep, s); 239*c7fd2ed0Sgs150176 debug_enter(""); 240*c7fd2ed0Sgs150176 } 241*c7fd2ed0Sgs150176 } 242*c7fd2ed0Sgs150176 243*c7fd2ed0Sgs150176 #endif /* RGE_DEBUGGING */ 244