1/* 2 * SiS 190/191 NIC Driver. 3 * Copyright (c) 2009 S.Zharski <imker@gmx.li> 4 * Distributed under the terms of the MIT license. 5 * 6 */ 7 8 9#include "Settings.h" 10 11#include <stdlib.h> 12#include <stdio.h> 13#include <string.h> 14 15#include <lock.h> // for mutex 16 17 18bool gTraceOn = false; 19bool gTruncateLogFile = false; 20bool gTraceFlow = false; 21bool gAddTimeStamp = true; 22static char *gLogFilePath = NULL; 23 24mutex gLogLock; 25 26 27// 28// Logging, tracing and settings 29// 30 31static 32void create_log() 33{ 34 if (gLogFilePath == NULL) 35 return; 36 37 int flags = O_WRONLY | O_CREAT | ((gTruncateLogFile) ? O_TRUNC : 0); 38 int fd = open(gLogFilePath, flags, 0666); 39 if (fd >= 0) 40 close(fd); 41 42 mutex_init(&gLogLock, DRIVER_NAME"-logging"); 43} 44 45 46void load_settings() 47{ 48 void *handle = load_driver_settings(DRIVER_NAME); 49 if (handle == 0) 50 return; 51 52 gTraceOn = get_driver_boolean_parameter( 53 handle, "trace", gTraceOn, true); 54 55 gTruncateLogFile = get_driver_boolean_parameter( 56 handle, "truncate_logfile", gTruncateLogFile, true); 57 58 gTraceFlow = get_driver_boolean_parameter( 59 handle, "trace_flow", gTraceFlow, true); 60 61 gAddTimeStamp = get_driver_boolean_parameter( 62 handle, "add_timestamp", gAddTimeStamp, true); 63 64 const char * logFilePath = get_driver_parameter( 65 handle, "logfile", NULL, "/var/log/"DRIVER_NAME".log"); 66 if (logFilePath != NULL) { 67 gLogFilePath = strdup(logFilePath); 68 } 69 70 unload_driver_settings(handle); 71 72 create_log(); 73} 74 75 76void release_settings() 77{ 78 if (gLogFilePath != NULL) { 79 mutex_destroy(&gLogLock); 80 free(gLogFilePath); 81 } 82} 83 84 85void SiS19X_trace(bool force, const char* func, const char *fmt, ...) 86{ 87 if (!(force || gTraceOn)) { 88 return; 89 } 90 91 va_list arg_list; 92 static const char *prefix = DRIVER_NAME":"; 93 static char buffer[1024]; 94 char *buf_ptr = buffer; 95 if (gLogFilePath == NULL) { 96 strlcpy(buffer, prefix, sizeof(buffer)); 97 buf_ptr += strlen(prefix); 98 } 99 100 if (gAddTimeStamp) { 101 bigtime_t time = system_time(); 102 uint32 msec = time / 1000; 103 uint32 sec = msec / 1000; 104 sprintf(buf_ptr, "%02" B_PRId32 ".%02" B_PRId32 ".%03" B_PRId32 ":", 105 sec / 60, sec % 60, msec % 1000); 106 buf_ptr += strlen(buf_ptr); 107 } 108 109 if (func != NULL) { 110 sprintf(buf_ptr, "%s::", func); 111 buf_ptr += strlen(buf_ptr); 112 } 113 114 va_start(arg_list, fmt); 115 vsprintf(buf_ptr, fmt, arg_list); 116 va_end(arg_list); 117 118 if (gLogFilePath == NULL) { 119 dprintf(buffer); 120 return; 121 } 122 123 mutex_lock(&gLogLock); 124 int fd = open(gLogFilePath, O_WRONLY | O_APPEND); 125 if (fd >= 0) { 126 write(fd, buffer, strlen(buffer)); 127 close(fd); 128 } 129 mutex_unlock(&gLogLock); 130} 131 132 133// 134// Rx/Tx traffic statistic harvesting 135// 136 137Statistics::Statistics() 138{ 139 memset(this, 0, sizeof(Statistics)); 140} 141 142 143void 144Statistics::PutStatus(uint32 status) 145{ 146 fInterrupts++; 147 if (status & (INT_TXDONE /*| INT_TXIDLE*/)) fTxInterrupts++; 148 if (status & (INT_RXDONE /*| INT_RXIDLE*/)) fRxInterrupts++; 149 150 if (status & INT_TXHALT) fTxHalt++; 151 if (status & INT_RXHALT) fRxHalt++; 152 if (status & INT_TXDONE) fTxDone++; 153 if (status & INT_TXIDLE) fTxIdle++; 154 if (status & INT_RXDONE) fRxDone++; 155 if (status & INT_RXIDLE) fRxIdle++; 156 if (status & INT_LINK) fLink++; 157 if (status & INT_WAKEF) fWakeUp++; 158 if (status & INT_MAGICP) fMagic++; 159 if (status & INT_PAUSEF) fPause++; 160 if (status & INT_TIMER) fTimer++; 161 if (status & INT_SOFT) fSoft++; 162} 163 164 165void 166Statistics::PutTxStatus(uint32 status, uint32 size) 167{ 168 if (status & TDS_CRS) fCarrier++; 169 if (status & TDS_FIFO) fFIFO++; 170 if (status & TDS_ABT) fTxAbort++; 171 if (status & TDS_OWC) fWindow++; 172 if ((status & txErrorStatusBits) == 0) { 173 fCollisions += (status & TDS_COLLS) - 1; 174 fTransmitted += (size & TxDescriptorSize); 175 } 176} 177 178 179void 180Statistics::PutRxStatus(uint32 status) 181{ 182 if (!(status & RDS_CRCOK)) fCRC++; 183 if (status & RDS_COLON) fColon++; 184 if (status & RDS_NIBON) fNibon++; 185 if (status & RDS_OVRUN) fOverrun++; 186 if (status & RDS_MIIER) fMIIError++; 187 if (status & RDS_LIMIT) fLimit++; 188 if (status & RDS_SHORT) fShort++; 189 if (status & RDS_ABORT) fRxAbort++; 190 if ((status & rxErrorStatusBits) == 0) { 191 fReceived += (status & RDS_SIZE) - 4; // exclude CRC? 192 } 193} 194 195 196void Statistics::Trace() 197{ 198 TRACE("Ints:%d;Lnk:%d;WkUps:%d;Mgic:%d;Pause:%d;Tmr:%d;Sft:%d\n", 199 fInterrupts, fLink, fWakeUp, fMagic, fPause, fTimer, fSoft); 200 201 TRACE("TX:Ints:%d;Bts:%llu;Drop:%d;Hlts:%d;Done:%d;Idle:%d;" 202 "Colls:%d;Carr:%d;FIFO:%d;Abrt:%d;Wndw:%d;\n", 203 fTxInterrupts, fTransmitted, fDropped, fTxHalt, fTxDone, 204 fTxIdle, fCollisions, fCarrier, fFIFO, fTxAbort, fWindow); 205 206 TRACE("RX:Ints:%d;Bts:%llu;Hlts:%d;Done:%d;Idle:%d;CRC:%d;Cln:%d;" 207 "Nibon:%d;Ovrrn:%d;MIIErr:%d;Lmt:%d;Shrt:%d;Abrt:%d\n", 208 fRxInterrupts, fReceived, fRxHalt, fRxDone, fRxIdle, fCRC, fColon, 209 fNibon, fOverrun, fMIIError, fLimit, fShort, fRxAbort); 210} 211 212