/******************************************************************************* NAME $RCSfile: nic82576Diag.c,v $ SUMMARY Intel 82576 Ethernet Controller diagnostics VERSION $Revision: 1.6 $ UPDATE DATE $Date: 2010/02/23 04:16:50 $ PROGRAMMER $Author: jim $ Copyright 2009 LSI Corporation. All Rights Reserved. DESCRIPTION: REFERENCE: *******************************************************************************/ #include #include //#include "../igb/src/nic82576DiagDrv.h" #undef FALSE #undef TRUE #include "commPciChip.h" #include #include extern int igbMdiTest(const char *name); extern int igbLinkTest(const char *name); extern int igbRegTest(const char *name); extern int igbEepromTest(const char *name); extern int igbIntrTest(const char *name); extern int igbLoopbackTest(const char *name, LOOPBACK_TYPE type); extern int igbCrossLoopbackTest(const char *name1, const char *name2, LOOPBACK_TYPE type); extern int igbGetStatistics(const char *name, struct e1000_hw_stats *buffer); #define IS_VALID_NAME_ON_PP(name) \ do { \ if (strcmp(name, "eth1") && strcmp(name, "eth2")) { \ printk("Invalid eth interface (%s) for nic 82576\n", name); \ return (-EINVAL); \ } \ } while(0) int nic82576PciReadTest(void) { return (pciRegTest(NIC_INTEL_82576, pciReadTest)); } int nic82576PciAddrLineTest(void) { return (pciRegTest(NIC_INTEL_82576, pciAddressLineTest)); } int nic82576PciDataLineTest(void) { return (pciRegTest(NIC_INTEL_82576, pciDataLineTest)); } int nic82576MdiTest(const char *name) { int ret; uint16_t component = 0; IS_VALID_NAME_ON_PP(name); if (!strcmp(name, "eth1")) component = MEC_NIC82576_0; else if (!strcmp(name, "eth2")) component = MEC_NIC82576_1; ret = igbMdiTest(name); if (ret) commReportError(component, NIC82576_ITEM_MDI, NIC82576_CODE_MDI, NIC82576_MSG_EMDI, 0, 0, 0, DG_FORMAT_NONE); return (ret); } int nic82576LinkTest(const char *name) { int ret; uint16_t component = 0; IS_VALID_NAME_ON_PP(name); if (!strcmp(name, "eth1")) component = MEC_NIC82576_0; else if (!strcmp(name, "eth2")) component = MEC_NIC82576_1; ret = igbLinkTest(name); if (ret) commReportError(component, NIC82576_ITEM_LINK, NIC82576_CODE_LINK, NIC82576_MSG_ELINK, 0, 0, 0, DG_FORMAT_NONE); return (ret); } int nic82576RegTest(const char *name) { int ret; uint16_t component = 0; IS_VALID_NAME_ON_PP(name); if (!strcmp(name, "eth1")) component = MEC_NIC82576_0; else if (!strcmp(name, "eth2")) component = MEC_NIC82576_1; ret = igbRegTest(name); if (ret) commReportError(component, NIC82576_ITEM_REG, NIC82576_CODE_REG, NIC82576_MSG_EREG, 0, 0, 0, DG_FORMAT_NONE); return (ret); } int nic82576EepromTest(const char *name) { int ret; uint16_t component = 0; IS_VALID_NAME_ON_PP(name); if (!strcmp(name, "eth1")) component = MEC_NIC82576_0; else if (!strcmp(name, "eth2")) component = MEC_NIC82576_1; ret = igbEepromTest(name); if (ret) commReportError(component, NIC82576_ITEM_EEPROM, NIC82576_CODE_EEPROM, NIC82576_MSG_EEEPROM, 0, 0, 0, DG_FORMAT_NONE); return (ret); } int nic82576IntrTest(const char *name) { int ret; uint16_t component = 0; IS_VALID_NAME_ON_PP(name); if (!strcmp(name, "eth1")) component = MEC_NIC82576_0; else if (!strcmp(name, "eth2")) component = MEC_NIC82576_1; ret = igbIntrTest(name); if (ret) commReportError(component, NIC82576_ITEM_INTR, NIC82576_CODE_INTR, NIC82576_MSG_EINTR, 0, 0, 0, DG_FORMAT_NONE); return (ret); } int nic82576LoopbackTest(const char *name, LOOPBACK_TYPE type) { int ret; uint16_t component = 0; char msg[64]; IS_VALID_NAME_ON_PP(name); if (!strcmp(name, "eth1")) component = MEC_NIC82576_0; else if (!strcmp(name, "eth2")) component = MEC_NIC82576_1; ret = igbLoopbackTest(name, type); if (ret) { switch (type) { case PHY_LOOPBACK_10M: strcpy(msg, NIC82576_MSG_ELP_PHY10); break; case PHY_LOOPBACK_100M: strcpy(msg, NIC82576_MSG_ELP_PHY100); break; case PHY_LOOPBACK_1000M: strcpy(msg, NIC82576_MSG_ELP_PHY1000); break; case EXTERNAL_LOOPBACK_10M: strcpy(msg, NIC82576_MSG_ELP_EXT10); break; case EXTERNAL_LOOPBACK_100M: strcpy(msg, NIC82576_MSG_ELP_EXT100); break; case EXTERNAL_LOOPBACK_1000M: strcpy(msg, NIC82576_MSG_ELP_EXT1000); break; default: printk("Unsupport Loopback Test type(%d)\n", type); } commReportError(component, NIC82576_ITEM_LOOPBACK, NIC82576_CODE_LOOPBACK, msg, 0, 0, 0, DG_FORMAT_NONE); } return (ret); } int nic82576CrossLoopbackTest(const char *name1, const char *name2, LOOPBACK_TYPE type) { int ret=1; char msg[64]; IS_VALID_NAME_ON_PP(name1); IS_VALID_NAME_ON_PP(name2); ret = igbCrossLoopbackTest(name1, name2, type); if (ret) { switch (type) { case CROSS_LOOPBACK_10M: strcpy(msg, NIC82576_MSG_ELP_CROSS10); break; case CROSS_LOOPBACK_100M: strcpy(msg, NIC82576_MSG_ELP_CROSS100); break; case CROSS_LOOPBACK_1000M: strcpy(msg, NIC82576_MSG_ELP_CROSS1000); break; default: printk("CrossLooback Unsupported Test type(%d)\n", type); } commReportError(MEC_NIC82576_0, NIC82576_ITEM_CLOOPBACK, NIC82576_CODE_CLOOPBACK, msg, 0, 0, 0, DG_FORMAT_NONE); } return (ret); } int nic82576GetStatistics(const char *name) { struct e1000_hw_stats stats; int ret; int result = 0; IS_VALID_NAME_ON_PP(name); ret = igbGetStatistics(name, &stats); if (ret) { printk("%s failed to get statistics\n", name); return (ret); } printk("<%s> Tx bytes: %llu\n", name, stats.gotc); printk("<%s> Rx bytes: %llu\n", name, stats.gorc); printk("--------------------------------------------\n\n"); printk("<%s> CRC error count: %llu\n", name, stats.crcerrs); printk("<%s> Alignment error count: %llu\n", name, stats.algnerrc); printk("<%s> Symbol error count: %llu\n", name, stats.symerrs); printk("<%s> Rx error count: %llu\n", name, stats.rxerrc); printk("<%s> Missed packets count: %llu\n", name, stats.mpc); printk("<%s> Collision count: %llu\n", name, stats.colc); printk("<%s> Defer count: %llu\n", name, stats.dc); printk("<%s> Tx - No CRS: %llu\n", name, stats.tncrs); printk("<%s> Sequence error count: %llu\n", name, stats.sec); printk("<%s> Carrier ext error count: %llu\n", name, stats.cexterr); printk("<%s> Rx length error count: %llu\n", name, stats.rlec); if(stats.crcerrs > 0) { result++; } if(stats.algnerrc > 0) { result++; } if(stats.symerrs > 0) { result++; } if(stats.rxerrc > 0) { result++; } if(stats.mpc > 0) { result++; } if(stats.colc > 0) { result++; } if(stats.dc > 0) { result++; } if(stats.tncrs > 0) { result++; } if(stats.sec > 0) { result++; } if(stats.cexterr > 0) { result++; } if(stats.rlec > 0) { result++; } if(result > 0) { printk(" \n"); printk("## ## ## ##### ## ## #### ## ## ##### \n"); printk("## ## ## ## ## ### ## ## ### ## ## ## \n"); printk("## ## ## ####### ## # ## ## ## # ## ## \n"); printk("## ## ## ## ## ## ### ## ## ### ## ### \n"); printk(" ## ## ## ## ## ## #### ## ## #### # \n"); printk(" \n"); printk("[NIC_BS] NIC82576 has error count \n"); printk(" \n"); /* commReportError(MODEL_CODE_TEMP, NIC82576_ITEM_STRESS, NIC82576_CODE_STRESS, NIC82576_MSG_STRESS, 0, 0, 0, DG_FORMAT_NONE); */ } return (0); } MODULE_AUTHOR( "merck.hung@netapp.com" ); MODULE_DESCRIPTION( "NetApp NIC 82576 Diag Code" ); MODULE_LICENSE( "GPL" ); MODULE_VERSION( "0.1" );