//------------------------------------------------------------------- // nicstats2.c (Revisied version of 'nicstats.c') // // This module creates a pseudo-file (named '/proc/nicstats') // that displays the values of Pro/1000 statistical counters. // // NOTE: Written and tested for Linux kernel version 2.6.22.5 // // programmer: ALLAN CRUSE // written on: 03 FEB 2008 //------------------------------------------------------------------- #include // for init_module() #include // for create_proc_info_entry() #include // for pci_get_device() #define VENDOR_ID 0x8086 // Intel Corporation #define DEVICE_ID 0x109A // 82573L controller //#define DEVICE_ID 0x10B9 // 82572EI controller //#define DEVICE_ID 0x107C // 82541PI controller enum { E1000_CRCERRS = 0x4000, // CRC Error Count E1000_RA = 0x5400, // Receive-filter Array }; char modname[] = "nicstats"; struct pci_dev *devp; unsigned char mac[6]; unsigned int mmio_base; unsigned int mmio_size; void *io, *kmem; char *stat[ 80 ] = { "CRCERRS", "AIGNERRC", "SYMERRS", "RXERRC", "MPC", "SCC", "ECOL", "MCC", "LATECOL", " ", "COLC", " ", "DC", "TNC-S", "SEC", " ", "RLEC", " ", "XONRXC", "XONTXC", "XOFFRXC", "XOFFTXC", "FCRUC", "PRC64", "PRC127", "PRC255", "PRC511", "PRC1023", "PRC1522", "GPRC", "BPRC", "MPRC", "GPTC", " ", "GORCL", "GORCH", "GOTCL", "GOTCH", " ", " ", "RNBC", "RUC", "RFC", "ROC", "RJC", "MPRC", "MPDC", "MPTC", "TORL", "TORH", "TOTL", "TOTH", "TPR", "TPT", "PTC64", "PTC127", "PTC255", "PTC511", "PTC1023", "PTC1522", "MPTC", "BPTC", "TSCTC", "TSCTFC", "IAC", "ICRXPTC", "ICRXATC", "ICTXPCT", "ICTXATC", " ", "ICTXQEC", "ICXDLTC", "ICRXDMTX", "ICRXOC", " ", " " }; int my_get_info( char *buf, char **start, off_t off, int count ) { int i, *ip = (int*)kmem, len = 0; len += sprintf( buf+len, "\n Intel Pro1000 Statistical Counters \n" ); for (i = 0; i < 74; i++) { if ( ( i % 4 ) == 0 ) len += sprintf( buf+len, "\n 0x%04X", 0x4000 + 4*i ); ip[i] += ioread32( io + E1000_CRCERRS + 4*i ); len += sprintf( buf+len, " %8s:", stat[i] ); if ( ip[i] ) len += sprintf( buf+len, "%08X", ip[i] ); else len += sprintf( buf+len, "--------" ); } len += sprintf( buf+len, "\n\n" ); return len; } static int __init my_init( void ) { int i; printk( "<1>\nInstalling \'%s\' module\n", modname ); devp = pci_get_device( VENDOR_ID, DEVICE_ID, NULL ); if ( !devp) return -ENODEV; mmio_base = pci_resource_start( devp, 0 ); mmio_size = pci_resource_len( devp, 0 ); io = ioremap_nocache( mmio_base, mmio_size ); if ( !io ) return -ENOSPC; memcpy( mac, io + E1000_RA, 6 ); printk( " Intel Pro1000 Gigabit Ethernet Controller " ); for (i=0; i < 6; i++) printk( "%02X%c", mac[i], (i<5) ? ':' : ' ' ); printk( "\n" ); kmem = kzalloc( 0x2000, GFP_KERNEL ); if ( !kmem ) { iounmap( io ); return -ENOMEM; } create_proc_info_entry( modname, 0, NULL, my_get_info ); return 0; //SUCCESS } static void __exit my_exit(void ) { remove_proc_entry( modname, NULL ); kfree( kmem ); iounmap( io ); printk( "<1>Removing \'%s\' module\n", modname ); } module_init( my_init ); module_exit( my_exit ); MODULE_LICENSE("GPL");