/******************************************************************************* NAME $RCSfile: commPciChip.c,v $ SUMMARY Generic APIs for PCI configuration register diagnostics VERSION $Revision: 1.18 $ UPDATE DATE $Date: 2009/11/23 08:04:01 $ PROGRAMMER $Author: luap $ Copyright 2009 NetApp Corporation. All Rights Reserved. DESCRIPTION: REFERENCE: *******************************************************************************/ #include #include "commPciChip.h" #include #include #include "pchDiag.h" #ifdef DBG #define DPRINTK printk #else #define DPRINTK(fmt...) do { } while (0) #endif extern int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn, int reg, int len, u32 val); EXPORT_SYMBOL(pciDataLineTest); EXPORT_SYMBOL(pciRegTest); EXPORT_SYMBOL(pciReadTest); EXPORT_SYMBOL(pciAddressLineTest); /* PLX PEX8648 PCI-E Switch */ const REG_STRUCT pex8648_cfg_type1_reg_tbl[] = { /* offset #rsv ctrl intval defmask rmask wmask pattern */ /*VID*/ {0x00, 0x00, REG_CT, 0xB5, 0x00, 0x00, 0x00, 0x00}, {0x01, 0x00, REG_CT, 0x10, 0x00, 0x00, 0x00, 0x00}, /*DID*/ {0x02, 0x00, REG_CT, 0x48, 0x01, 0x00, 0x00, 0x00}, {0x03, 0x00, REG_CT, 0x86, 0x00, 0x00, 0x00, 0x00}, /*PCICMD*/ {0x04, 0x00, REG_RW, 0x00, 0x47, 0x00, 0xb8, 0x00}, {0x05, 0x00, REG_RW, 0x00, 0x05, 0x00, 0xFA, 0x00}, ///*PCISTS*/ {0x06, 0x00, REG_RO, 0x10, 0x00, 0x00, 0x00, 0x00}, //3A03B {0x07, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, /*RID*/ {0x08, 0x00, REG_RO, 0xBB, 0xFF, 0x00, 0x00, 0x00}, /*CCODE*/ {0x09, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x0A, 0x00, REG_RO, 0x04, 0x00, 0x00, 0x00, 0x00}, {0x0B, 0x00, REG_RO, 0x06, 0x00, 0x00, 0x00, 0x00}, /*CLS*/ {0x0C, 0x00, REG_RW+REG_AD, 0x00, 0xFF, 0x00, 0x00, 0x55}, /*PLTIMER*/ {0x0D, 0x00, REG_RS, 0x00, 0x00, 0x00, 0x00, 0x00}, /*HDR*/ {0x0E, 0x00, REG_RO, 0x01, 0x00, 0x00, 0x00, 0x00}, /*BIST*/ {0x0F, 0x00, REG_RS, 0x00, 0x00, 0x00, 0x00, 0x00}, /*BAR0*/ {0x10, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x11, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x12, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x13, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*BAR1*/ {0x14, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x15, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x16, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x17, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*PBUSN*/ {0x18, 0x00, REG_RW+REG_AD, 0x00, 0xFF, 0x00, 0x00, 0xAA}, /*SBUSN*/ {0x19, 0x00, REG_RW+REG_AD, 0x00, 0xFF, 0x00, 0x00, 0xFF}, /*SUBUSN*/ {0x1A, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*SLTIMER*/ {0x1B, 0x00, REG_RS, 0x00, 0x00, 0x00, 0x00, 0x00}, /*IOBASE*/ {0x1C, 0x00, REG_RW, 0x01, 0xF0, 0x0F, 0x0F, 0x00}, /*IOLIMIT*/ {0x1D, 0x00, REG_RW, 0x01, 0xF0, 0x0F, 0x0F, 0x00}, /*SECSTS*/ {0x1E, 0x00, REG_RS, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x1F, 0x00, REG_RWC, 0x00, 0x00, 0x00, 0x00, 0x00}, /*MBASE*/ {0x20, 0x00, REG_RW+REG_AD, 0xF0, 0xF0, 0x00, 0x0F, 0x55}, {0x21, 0x00, REG_RW+REG_AD, 0xFF, 0xFF, 0x00, 0x00, 0xAA}, /*MLIMIT*/ {0x22, 0x00, REG_RW+REG_AD, 0x00, 0xF0, 0x00, 0x0F, 0xFF}, {0x23, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*PMBASE*/ {0x24, 0x00, REG_RW, 0x01, 0xF0, 0x0F, 0x0F, 0x00}, {0x25, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*PMLIMI*/ {0x26, 0x00, REG_RW, 0x01, 0xF0, 0x0F, 0x0F, 0x00}, {0x27, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*PMBASEU*/ {0x28, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x29, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x2A, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x2B, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*PMLIMITU*/{0x2C, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x2D, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x2E, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x2F, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*IOBASEU*/ {0x30, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x31, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*IOLIMITU*/{0x32, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x33, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*CAPPTR*/ {0x34, 0x00, REG_RO, 0x40, 0x00, 0x00, 0x00, 0x00}, /*EROMBASE*/{0x38, 0x04, REG_RS, 0x00, 0x00, 0x00, 0x00, 0x00}, /*INTRLINE*/{0x3C, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*INTRPIN*/ {0x3D, 0x00, REG_RO, 0x01, 0x00, 0x00, 0x00, 0x00}, }; /* PLX PEX8648 PCI-E Switch */ const REG_STRUCT pex8648_cfg_type0_reg_tbl[] = { /* offset #rsv ctrl intval defmask rmask wmask pattern */ /*VID*/ {0x00, 0x00, REG_CT, 0xB5, 0x00, 0x00, 0x00, 0x00}, {0x01, 0x00, REG_CT, 0x10, 0x00, 0x00, 0x00, 0x00}, /*DID*/ {0x02, 0x00, REG_CT, 0x48, 0x01, 0x00, 0x00, 0x00}, {0x03, 0x00, REG_CT, 0x86, 0x00, 0x00, 0x00, 0x00}, /*PCICMD*/ {0x04, 0x00, REG_RW, 0x00, 0x47, 0x00, 0xB8, 0x00}, {0x05, 0x00, REG_RW, 0x00, 0x05, 0x00, 0xFA, 0x00}, ///*PCISTS*/ {0x06, 0x00, REG_RO, 0x10, 0x00, 0x00, 0x00, 0x00}, //3A03B {0x07, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, /*RID*/ {0x08, 0x00, REG_RO, 0xBB, 0xFF, 0x00, 0x00, 0x00}, /*CCODE*/ {0x09, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x0A, 0x00, REG_RO, 0x80, 0x00, 0x00, 0x00, 0x00}, {0x0B, 0x00, REG_RO+REG_IG, 0x06, 0x00, 0x00, 0x00, 0x00}, /*CLS*/ {0x0C, 0x00, REG_RW+REG_AD, 0x00, 0xFF, 0x00, 0x00, 0x55}, /*PLTIMER*/ {0x0D, 0x00, REG_RS, 0x00, 0x00, 0x00, 0x00, 0x00}, /*HDR*/ {0x0E, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, /*BIST*/ {0x0F, 0x00, REG_RS, 0x00, 0x00, 0x00, 0x00, 0x00}, /*BAR0*/ {0x10, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x11, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x12, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x13, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*BAR1*/ {0x14, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x15, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x16, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x17, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*BAR2*/ {0x18, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x19, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x1A, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x1B, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*BAR3*/ {0x1C, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x1D, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x1E, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x1F, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*BAR4*/ {0x20, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x21, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x22, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x23, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*BAR5*/ {0x24, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x25, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x26, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x27, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*RSV*/ {0x28, 0x04, REG_RS, 0x00, 0x00, 0x00, 0x00, 0x00}, /*SVID*/ {0x2C, 0x00, REG_CT+REG_IG, 0xB5, 0x00, 0x00, 0x00, 0x00}, {0x2D, 0x00, REG_CT+REG_IG, 0x10, 0x00, 0x00, 0x00, 0x00}, /*SSID*/ {0x2E, 0x00, REG_CT+REG_IG, 0x49, 0x01, 0x00, 0x00, 0x00}, {0x2F, 0x00, REG_CT+REG_IG, 0x86, 0x00, 0x00, 0x00, 0x00}, /*EROMBASE*/{0x30, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x31, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x32, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, {0x33, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*CAPPTR*/ {0x34, 0x00, REG_RO, 0x40, 0x00, 0x00, 0x00, 0x00}, /*RSV*/ {0x38, 0x04, REG_RS, 0x00, 0x00, 0x00, 0x00, 0x00}, /*INTRLINE*/{0x3C, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0x00}, /*INTRPIN*/ {0x3D, 0x00, REG_RO, 0x01, 0x00, 0x00, 0x00, 0x00}, }; /* Intel 82576 ethernet */ const REG_STRUCT nic82576_cfg_reg_tbl[] = { /* offset #rsv ctrl intval defmask rmask wmask pattern */ /* VID0 */ { 0x00, 0x00, REG_CT+REG_AD, 0x86, 0x00, 0x00, 0x00, 0xAA }, /* VID1 */ { 0x01, 0x00, REG_CT+REG_AD, 0x80, 0x00, 0x00, 0x00, 0xAA }, /* DID2 */ { 0x02, 0x00, REG_CT+REG_AD, 0xC9, 0x00, 0x00, 0x00, 0xAA }, /* DID3 */ { 0x03, 0x00, REG_CT, 0x10, 0x00, 0x00, 0x00, 0xAA }, /* CMD1 */ { 0x04, 0x00, REG_RO+REG_AD, 0x00, 0x47, 0x47, 0x00, 0xAA }, /* CMD2 */ { 0x05, 0x00, REG_RO+REG_AD, 0x00, 0x05, 0x05, 0x00, 0xAA }, /* STAT2 */ { 0x06, 0x00, REG_RO, 0x10, 0x00, 0x00, 0x00, 0xAA }, /* STAT3 */ { 0x07, 0x00, REG_RWC, 0x00, 0x00, 0x00, 0x00, 0x33 }, /* CLAS1 */ { 0x09, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* CLAS2 */ { 0x0A, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* CLAS3 */ { 0x0B, 0x00, REG_RO, 0x02, 0x00, 0x00, 0x00, 0xAA }, /* HDRT2 */ { 0x0E, 0x00, REG_CT+REG_AD, 0x80, 0x00, 0x00, 0x00, 0xAA }, /* BIST3 */ { 0x0F, 0x00, REG_RS, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* CAP0 */ { 0x34, 0x00, REG_CT+REG_AD, 0x40, 0x00, 0x00, 0x00, 0x00 }, /* RSVD */ { 0x35, 0x07, REG_RS, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* INTP1 */ { 0x3D, 0x00, REG_RO, 0x00, 0x07, 0x00, 0x00, 0xAA }, /* MGNT2 */ { 0x3E, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* MLAT3 */ { 0x3F, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* CAPI0 */ { 0x40, 0x00, REG_CT+REG_AD, 0x01, 0x00, 0x00, 0x00, 0xAA }, /* NEXT1 */ { 0x41, 0x00, REG_CT, 0x50, 0x00, 0x00, 0x00, 0xAA }, /* PMC2 */ { 0x42, 0x00, REG_RO, 0x23, 0x00, 0x00, 0x00, 0xAA }, /* PMC3 */ { 0x43, 0x00, REG_RO, 0x48, 0x00, 0x00, 0x00, 0xAA }, /* M-CID */ { 0x50, 0x00, REG_CT, 0x05, 0x00, 0x00, 0x00, 0xAA }, /* M-NCap */ { 0x51, 0x00, REG_CT, 0x70, 0x00, 0x00, 0x00, 0xAA }, /* M-MCtl1*/ { 0x52, 0x00, REG_RO, 0x80, 0x00, 0x00, 0x00, 0xAA }, /* M-MCtl2*/ { 0x53, 0x00, REG_RO, 0x01, 0x00, 0x00, 0x00, 0xAA }, /* M-Add1 */ { 0x54, 0x00, REG_RW, 0x00, 0x03, 0x03, 0x03, 0xAA }, /* M-Add2 */ { 0x55, 0x00, REG_RW, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* M-Add3 */ { 0x56, 0x00, REG_RW, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* M-Add4 */ { 0x57, 0x00, REG_RW, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* M-UAdd1 */ { 0x58, 0x00, REG_RW, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* M-UAdd2 */ { 0x59, 0x00, REG_RW, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* M-UAdd3 */ { 0x5A, 0x00, REG_RW, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* M-UAdd4 */ { 0x5B, 0x00, REG_RW, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* M-Data1 */ { 0x5C, 0x00, REG_RW, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* M-Data2 */ { 0x5D, 0x00, REG_RW, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* MX-CAP */ { 0x70, 0x00, REG_CT, 0x11, 0x00, 0x00, 0x00, 0xAA }, /* MX-NCP */ { 0x71, 0x00, REG_CT, 0xA0, 0x00, 0x00, 0x00, 0xAA }, /* MX-CMD0 */ { 0x72, 0x00, REG_RO, 0x09, 0x00, 0x00, 0x00, 0xAA }, /* MX-CMD1 */ { 0x73, 0x00, REG_RO, 0x80, 0x00, 0x00, 0x00, 0xAA }, }; /* Patsburg 82579 ethernet */ const REG_STRUCT nic82579_cfg_reg_tbl[] = { /* offset #rsv ctrl intval defmask rmask wmask pattern */ // /* VID0 */ { 0x00, 0x00, REG_CT+REG_AD, 0x86, 0x00, 0x00, 0x00, 0xAA }, // /* VID1 */ { 0x01, 0x00, REG_CT+REG_AD, 0x80, 0x00, 0x00, 0x00, 0xAA }, // /* DID2 */ { 0x02, 0x00, REG_CT+REG_AD, 0x02, 0x00, 0x00, 0x00, 0xAA }, // /* DID3 */ { 0x03, 0x00, REG_CT, 0x15, 0x00, 0x00, 0x00, 0xAA }, /* CMD1 */ { 0x04, 0x00, REG_RO+REG_AD, 0x07, 0x47, 0x47, 0x00, 0xAA }, /* CMD2 */ { 0x05, 0x00, REG_RO+REG_AD, 0x04, 0x05, 0x05, 0x00, 0xAA }, /* STAT2 */ { 0x06, 0x00, REG_RO, 0x10, 0x00, 0x00, 0x00, 0xAA }, /* STAT3 */ { 0x07, 0x00, REG_RWC, 0x00, 0x00, 0x00, 0x00, 0x33 }, /* CLAS1 */ { 0x09, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* CLAS2 */ { 0x0A, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* CLAS3 */ { 0x0B, 0x00, REG_RO, 0x02, 0x00, 0x00, 0x00, 0xAA }, /* HDRT2 */ { 0x0E, 0x00, REG_CT+REG_AD, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* BIST3 */ { 0x0F, 0x00, REG_RS, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* CAP0 */ { 0x34, 0x00, REG_CT+REG_AD, 0xC8, 0x00, 0x00, 0x00, 0x00 }, /* RSVD */ { 0x35, 0x07, REG_RS, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* INTP1 */ { 0x3D, 0x00, REG_RO, 0x01, 0x07, 0x00, 0x00, 0xAA }, /* MGNT2 */ { 0x3E, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* MLAT3 */ { 0x3F, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* CAPI0 */ { 0xC8, 0x00, REG_CT+REG_AD, 0x01, 0x00, 0x00, 0x00, 0xAA }, /* NEXT1 */ { 0xC9, 0x00, REG_CT, 0xD0, 0x00, 0x00, 0x00, 0xAA }, /* PMC2 */ { 0xCA, 0x00, REG_RO, 0x22, 0x00, 0x00, 0x00, 0xAA }, /* PMC3 */ { 0xCB, 0x00, REG_RO, 0xC8, 0x00, 0x00, 0x00, 0xAA }, /* M-CID */ { 0xD0, 0x00, REG_CT, 0x05, 0x00, 0x00, 0x00, 0xAA }, /* M-NCap */ { 0xD1, 0x00, REG_CT, 0xE0, 0x00, 0x00, 0x00, 0xAA }, /* M-MCtl1*/ { 0xD2, 0x00, REG_RO, 0x81, 0x00, 0x00, 0x00, 0xAA }, /* M-MCtl2*/ { 0xD3, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0xAA }, /* M-Add1 */ { 0xD4, 0x00, REG_RW+REG_AD, 0x00, 0xFF, 0x0F, 0x0F, 0xAA }, /* M-Add2 */ { 0xD5, 0x00, REG_RW+REG_AD, 0x00, 0xFF, 0x00, 0x00, 0xAA }, /* M-Add3 */ { 0xD6, 0x00, REG_RW+REG_AD, 0xE0, 0xFF, 0x00, 0x00, 0xAA }, /* M-Add4 */ { 0xD7, 0x00, REG_RW+REG_AD, 0xFE, 0xFF, 0x00, 0x00, 0xAA }, /* M-UAdd1 */ { 0xD8, 0x00, REG_RW+REG_AD, 0x00, 0xFF, 0x00, 0x00, 0xAA }, /* M-UAdd2 */ { 0xD9, 0x00, REG_RW+REG_AD, 0x00, 0xFF, 0x00, 0x00, 0xAA }, /* M-UAdd3 */ { 0xDA, 0x00, REG_RW+REG_AD, 0x00, 0xFF, 0x00, 0x00, 0xAA }, /* M-UAdd4 */ { 0xDB, 0x00, REG_RW+REG_AD, 0x55, 0xFF, 0x00, 0x00, 0xAA }, /* M-Data1 */ { 0xDC, 0x00, REG_RW, 0x40, 0xFF, 0x00, 0x00, 0xAA }, /* M-Data2 */ { 0xDD, 0x00, REG_RW, 0x00, 0xFF, 0x00, 0x00, 0xAA }, { 0xE0, 0x00, REG_CT, 0x13, 0x00, 0x00, 0x00, 0xAA }, { 0xE1, 0x00, REG_CT, 0x00, 0x00, 0x00, 0x00, 0xAA }, { 0xE2, 0x00, REG_RO, 0x06, 0x00, 0x00, 0x00, 0xAA }, { 0xE3, 0x00, REG_RO, 0x03, 0x00, 0x00, 0x00, 0xAA }, }; const REG_STRUCT lsi2308_cfg_reg_tbl[] = { /* offset #rsv ctrl intval defmask rmask wmask pattern */ /* VID */ {0x00, 0x00, REG_CT+REG_AD, 0x00, 0x00, 0x00, 0x00, 0xaa}, /* VID */ {0x01, 0x00, REG_CT+REG_AD, 0x10, 0x00, 0x00, 0x00, 0xaa}, /* CMD1 */ {0x04, 0x00, REG_RW+REG_IG, 0x47, 0x07, 0xB8, 0xB8, 0xaa}, /* CMD2 */ {0x05, 0x00, REG_RW+REG_IG, 0x05, 0x00, 0xFA, 0xFA, 0xaa}, /* STAT */ {0x06, 0x00, REG_RWC, 0x10, 0x00, 0xC7, 0xC7, 0x00}, /* STAT */ {0x07, 0x00, REG_RWC+REG_AD, 0x00, 0x00, 0x02, 0x02, 0xFF}, /* CCD */ {0x09, 0x00, REG_CT, 0x00, 0x00, 0x00, 0x00, 0x00}, /* CCD */ {0x0a, 0x00, REG_CT+REG_IG, 0x07, 0x00, 0x00, 0x00, 0x00}, /* CCD */ {0x0b, 0x00, REG_CT, 0x01, 0x00, 0x00, 0x00, 0x00}, /* CLSZ */ {0x0c, 0x00, REG_RW+REG_IG, 0x08, 0x00, 0x07, 0x07, 0x00}, /* LTMR */ {0x0d, 0x00, REG_RW, 0x00, 0x00, 0xFF, 0xFF, 0x00}, /* HTP */ {0x0e, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR1 */ {0x10, 0x00, REG_RW+REG_AD+REG_IG, 0x01, 0x00, 0xFF, 0xFF, 0x00}, /* BAR1 */ {0x11, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR1 */ {0x12, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR1 */ {0x13, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR2 */ {0x14, 0x00, REG_RW+REG_IG, 0x04, 0x00, 0xFF, 0xFF, 0x00}, /* BAR2 */ {0x15, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0xFF, 0xFF, 0x00}, /* BAR2 */ {0x16, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR2 */ {0x17, 0x00, REG_RW+REG_IG, 0x80, 0x00, 0x00, 0x00, 0x00}, /* BAR2 */ {0x18, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR2 */ {0x19, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR2 */ {0x1A, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR2 */ {0x1B, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR3 */ {0x1C, 0x00, REG_RW+REG_IG, 0x04, 0x00, 0xFF, 0xFF, 0x00}, /* BAR3 */ {0x1D, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0xFF, 0x00, 0x00}, /* BAR3 */ {0x1E, 0x00, REG_IG, 0x98, 0x00, 0x0F, 0x00, 0x00}, /* BAR3 */ {0x1F, 0x00, REG_IG, 0xff, 0x00, 0x00, 0x00, 0x00}, /* BAR3 */ {0x20, 0x00, REG_AD+REG_IG, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR3 */ {0x21, 0x00, REG_IG, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR3 */ {0x22, 0x00, REG_IG, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR3 */ {0x23, 0x00, REG_IG, 0x00, 0x00, 0x00, 0x00, 0x00}, /* CAP */ {0x34, 0x00, REG_RO, 0x50, 0x00, 0x00, 0x00, 0x00}, /* IPN */ {0x3d, 0x00, REG_RO, 0x01, 0x00, 0x00, 0x00, 0x00}, }; const REG_STRUCT lsifpga_cfg_reg_tbl[] = { /* offset #rsv ctrl intval defmask rmask wmask pattern */ // /* VID */ {0x00, 0x00, REG_RO+REG_AD, 0x75, 0x00, 0x00, 0x00, 0xAA}, // /* VID */ {0x01, 0x00, REG_RO+REG_AD, 0x12, 0x00, 0x00, 0x00, 0xAA}, // /* DID */ {0x02, 0x00, REG_RO+REG_AD, 0x10, 0x00, 0x00, 0x00, 0xAA}, // /* DID */ {0x03, 0x00, REG_RO, 0x71, 0x00, 0x00, 0x00, 0xAA}, /* CMD1 */ {0x04, 0x00, REG_CT, 0x02, 0xFF, 0x00, 0x00, 0xAA}, /* CMD2 */ {0x05, 0x00, REG_CT, 0x00, 0xFF, 0x00, 0x00, 0xAA}, /* STAT */ {0x06, 0x00, REG_RWC, 0x10, 0x00, 0xC7, 0xC7, 0x00}, /* STAT */ {0x07, 0x00, REG_RWC, 0x02, 0x00, 0x02, 0x02, 0xFF}, /* REV */ {0x08, 0x00, REG_RO+REG_AD, 0x01, 0xFF, 0xFF, 0xFF, 0x00}, /* CCD */ {0x09, 0x00, REG_CT, 0x00, 0x02, 0x00, 0x00, 0x00}, /* CCD */ {0x0A, 0x00, REG_CT+REG_IG, 0x80, 0x00, 0x00, 0x00, 0x00}, /* CCD */ {0x0B, 0x00, REG_CT, 0x08, 0x00, 0x00, 0x00, 0x00}, /* HTP */ {0x0E, 0x00, REG_RO, 0x80, 0x00, 0x00, 0x00, 0x00}, /* BAR1 */ {0x10, 0x00, REG_RW+REG_IG+REG_AD, 0x00, 0x00, 0xFF, 0xFF, 0x00}, /* BAR1 */ {0x11, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0xFF, 0xFF, 0x00}, /* BAR1 */ {0x12, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0xFF, 0xFF, 0x00}, /* BAR1 */ {0x13, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0xFF, 0xFF, 0x00}, /* BAR2 */ {0x14, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0xFF, 0xFF, 0x00}, /* BAR2 */ {0x15, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0xFF, 0xFF, 0x00}, /* BAR2 */ {0x16, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0xFF, 0xFF, 0x00}, /* BAR2 */ {0x17, 0x00, REG_RW+REG_IG, 0x00, 0x00, 0xFF, 0xFF, 0x00}, /* BAR3 */ {0x18, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR3 */ {0x19, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR3 */ {0x1A, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR3 */ {0x1B, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR4 */ {0x1C, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR4 */ {0x1D, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR4 */ {0x1E, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, /* BAR4 */ {0x1F, 0x00, REG_RO, 0x00, 0x00, 0x00, 0x00, 0x00}, /* IPN */ {0x3C, 0x00, REG_RO, 0x00, 0xFF, 0x00, 0x00, 0x00}, /* IPP */ {0x3D, 0x00, REG_RO, 0x03, 0x03, 0x00, 0x00, 0x00}, }; #define MAX_PEX8648_TYPE1_CFG_SPACE \ (sizeof(pex8648_cfg_type1_reg_tbl)/sizeof(pex8648_cfg_type1_reg_tbl[0])) #define MAX_PEX8648_TYPE0_CFG_SPACE \ (sizeof(pex8648_cfg_type0_reg_tbl)/sizeof(pex8648_cfg_type0_reg_tbl[0])) #define MAX_LSI2308_CFG_SPACE sizeof(lsi2308_cfg_reg_tbl)/sizeof(lsi2308_cfg_reg_tbl[0]) #define MAX_NIC82576_CFG_SPACE sizeof(nic82576_cfg_reg_tbl)/sizeof(nic82576_cfg_reg_tbl[0]); #define MAX_NIC82579_CFG_SPACE sizeof(nic82579_cfg_reg_tbl)/sizeof(nic82579_cfg_reg_tbl[0]); #define MAX_NETAPPFPGA_CFG_SPACE sizeof(lsifpga_cfg_reg_tbl)/sizeof(lsifpga_cfg_reg_tbl[0]) #define REG_READ_ONLY (REG_RO+REG_CT) #define REG_ADDRESS_TEST REG_AD #define MAX_PATTERN 6 static uint32_t test_pattern [MAX_PATTERN] = { 0xAAAAAAAA, 0x55555555, 0x33333333, 0xC3C3C3C3, 0x99669966, 0xEEEE1111 }; int pciReadTest (REG_STRUCT *reg, struct pci_dev* pdev, int maxReg) { int err = 0; uint8_t obs_val; int i, j; for (i=0; i< maxReg; i++) { if (reg->number_of_reserves == 0) { pci_read_config_byte(pdev, reg->offset, &obs_val); DPRINTK("Reg: 0x%04x, Obs: 0x%02x, Masked: 0x%02x, Exp: 0x%02x\n", reg->offset, obs_val, obs_val & ~reg->drmask, reg->reset_value & ~reg->drmask); if ( !(reg->control & REG_IG) && ((obs_val & ~reg->drmask) != (reg->reset_value & ~reg->drmask)) ) { /* Indicate a wrong initial value */ DPRINTK("[PCI_READ_TEST] Reg: 0x%04x, Obs: 0x%02x, Masked: 0x%02x, Exp: 0x%02x\n", reg->offset, obs_val, obs_val & ~reg->drmask, reg->reset_value & ~reg->drmask); err++; printk("[PCI_READ_TEST] Reg: 0x%04x, Obs: 0x%02x, Masked: 0x%02x, Exp: 0x%02x\n", reg->offset, obs_val, obs_val & ~reg->drmask, reg->reset_value & ~reg->drmask); commReportError(MEC_GEN_BUS_ERROR, PCI_READ_TEST, PCI_ERROR_CODE_1, PCI_ERROR_MSG_1, reg->offset, reg->reset_value & ~reg->drmask, obs_val & ~reg->drmask, DG_MEMORY_BYTE_FORMAT); } } else { for (j=0; j < (reg->number_of_reserves); j++) { pci_read_config_byte(pdev, (reg->offset + j), &obs_val); DPRINTK("Reg: 0x%04x, Obs: 0x%02x, Masked: 0x%02x, Exp: 0 (RS)\n", reg->offset + j, obs_val, obs_val & ~reg->drmask); if (obs_val != 0) { /* Indicate a wrong reserve value */ DPRINTK("[PCI_READ_TEST] Reg: 0x%04x, Obs: 0x%02x, Masked: 0x%02x, Exp: 0 (RS)\n", reg->offset + j, obs_val, obs_val & ~reg->drmask); err++; printk("[PCI_READ_TEST] Reg: 0x%04x, Obs: 0x%02x, Masked: 0x%02x, Exp: 0 (RS)\n", reg->offset + j, obs_val, obs_val & ~reg->drmask); commReportError(MEC_GEN_BUS_ERROR, PCI_READ_TEST, PCI_ERROR_CODE_2, PCI_ERROR_MSG_2, reg->offset + j, 0, obs_val, DG_MEMORY_BYTE_FORMAT); } } } reg++; } return (err); } int pciAddressLineTest (REG_STRUCT *reg, struct pci_dev* pdev, int maxReg) { int i; int err = 0; uint8_t obs_val; uint8_t pattern; REG_STRUCT *start_reg; uint8_t saved_reg_val[maxReg]; start_reg = reg; for (i = 0; i < maxReg; i++) { if (reg->control & REG_ADDRESS_TEST) { /* save original register's value */ pci_read_config_byte(pdev, reg->offset, &saved_reg_val[i]); DPRINTK("Save Reg: 0x%04x, Val: 0x%02x, Wr Ptrn: 0x%02x\n", reg->offset, saved_reg_val[i], reg->pattern & ~reg->wmask); /* write pattern to register */ pci_write_config_byte(pdev, reg->offset, (reg->pattern & ~reg->wmask)); } reg++; } reg = start_reg; for (i = 0; i < maxReg; i++) { pci_read_config_byte(pdev, reg->offset, &obs_val); if (reg->control & REG_ADDRESS_TEST) { DPRINTK("Reg: 0x%04x, Obs: 0x%02x", reg->offset, obs_val); if (reg->control & REG_READ_ONLY) { DPRINTK(", Masked 0x%02x, Exp: 0x%02x (RO)", (obs_val & ~reg->rmask), (reg->reset_value & ~reg->rmask)); if ((obs_val & ~reg->rmask) != (reg->reset_value & ~reg->rmask)) { DPRINTK("\nError, Masked 0x%02x, Exp: 0x%02x (RO)\n", (obs_val & ~reg->rmask), (reg->reset_value & ~reg->rmask)); err++; printk("\nError, Masked 0x%02x, Exp: 0x%02x (RO)\n", (obs_val & ~reg->rmask), (reg->reset_value & ~reg->rmask)); commReportError(MEC_GEN_BUS_ERROR, PCI_ADDR_LINE_TEST, PCI_ERROR_CODE_3, PCI_ERROR_MSG_3, reg->offset, reg->reset_value & ~reg->rmask, obs_val & ~reg->rmask, DG_MEMORY_BYTE_FORMAT); } } else if (reg->control & REG_RWC) { pattern = ~reg->pattern & ~reg->wmask; DPRINTK(", Masked 0x%02x, Exp: 0x%02x (RWC)", (obs_val & ~reg->rmask), (pattern & ~reg->rmask)); if((obs_val & ~reg->rmask) != (pattern & ~reg->rmask)) { DPRINTK("\nError, Masked 0x%02x, Exp: 0x%02x (RWC)\n", (obs_val & ~reg->rmask), (pattern & ~reg->rmask)); err++; printk("\nError, Masked 0x%02x, Exp: 0x%02x (RWC)\n", (obs_val & ~reg->rmask), (pattern & ~reg->rmask)); commReportError(MEC_GEN_BUS_ERROR, PCI_ADDR_LINE_TEST, PCI_ERROR_CODE_4, PCI_ERROR_MSG_4, reg->offset, pattern & ~reg->rmask, obs_val & ~reg->rmask, DG_MEMORY_BYTE_FORMAT); } } else { pattern = reg->pattern & ~reg->wmask; DPRINTK(", Masked 0x%02x, Exp: 0x%02x (RW)", (obs_val & ~reg->rmask), (pattern & ~reg->rmask)); if((obs_val & ~reg->rmask) != (pattern & ~reg->rmask)) { DPRINTK("\nError, Masked 0x%02x, Exp: 0x%02x (RW)\n", (obs_val & ~reg->rmask), (pattern & ~reg->rmask)); err++; printk("\nError, Masked 0x%02x, Exp: 0x%02x (RW)\n", (obs_val & ~reg->rmask), (pattern & ~reg->rmask)); commReportError(MEC_GEN_BUS_ERROR, PCI_ADDR_LINE_TEST, PCI_ERROR_CODE_5, PCI_ERROR_MSG_5, reg->offset, pattern & ~reg->rmask, obs_val & ~reg->rmask, DG_MEMORY_BYTE_FORMAT); } } DPRINTK(" *Restored*\n"); /* restore original register's value after previous write */ pci_write_config_byte(pdev, reg->offset, saved_reg_val[i]); } reg++; } return (err); } int pciDataLineTest(REG_STRUCT *reg, struct pci_dev* pdev, int maxReg) { int i,j; int err = 0; uint8_t obs_val; uint8_t d_pattern; uint8_t preserve_val; uint8_t saved_reg_val = 0x00; /* initialize to remove compiler's warnings */ for (i = 0; i < maxReg; i++) { if (reg->control & REG_RW) { DPRINTK("Reg: 0x%04x", reg->offset); /* save original register's value */ pci_read_config_byte(pdev, reg->offset, &saved_reg_val); DPRINTK(", Saved Val: 0x%02x\n", saved_reg_val); for (j=0; j < MAX_PATTERN; j++) { d_pattern = test_pattern[j] & ~reg->wmask; d_pattern &= 0xff; pci_read_config_byte(pdev, reg->offset, &preserve_val); pci_write_config_byte(pdev, reg->offset, d_pattern); pci_read_config_byte(pdev, reg->offset, &obs_val); DPRINTK("Wr Ptrn: 0x%02x, Obs: 0x%02x, Masked: 0x%02x, EXP: 0x%02x\n", d_pattern, obs_val, obs_val & ~reg->rmask, d_pattern & ~reg->rmask); if (!(reg->control & REG_RWC)) { pci_write_config_byte(pdev, reg->offset, preserve_val); } if ((obs_val & ~reg->rmask) != (d_pattern & ~reg->rmask)) { DPRINTK("Error: Wr Ptrn: 0x%02x, Obs: 0x%02x, Masked: 0x%02x, EXP: 0x%02x\n", d_pattern, obs_val, obs_val & ~reg->rmask, d_pattern & ~reg->rmask); err++; printk("Error(%x): Wr Ptrn: 0x%02x, Obs: 0x%02x, Masked: 0x%02x, EXP: 0x%02x\n", reg->offset, d_pattern, obs_val, obs_val & ~reg->rmask, d_pattern & ~reg->rmask); commReportError(MEC_GEN_BUS_ERROR, PCI_DATA_LINE_TEST, PCI_ERROR_CODE_6, PCI_ERROR_MSG_6, reg->offset, d_pattern & ~reg->rmask, obs_val & ~reg->rmask, DG_MEMORY_BYTE_FORMAT); } } /* restore original register's value after previous write */ pci_write_config_byte(pdev, reg->offset, saved_reg_val); } reg++; } return (err); } int pciRegTest(PCI_COMPONENT component, int (*performTest) (REG_STRUCT*, struct pci_dev*, int)) { REG_STRUCT *chipStruct = NULL; struct pci_dev *pdev = NULL; int maxReg; int func = 0, err = 0; //uint8_t find = 0; switch (component) { case PCIE_PLX_PEX8648: while ((pdev = pci_get_device( 0x10b5, PCI_ANY_ID, pdev))) { if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { chipStruct = (REG_STRUCT*) pex8648_cfg_type1_reg_tbl; maxReg = MAX_PEX8648_TYPE1_CFG_SPACE; } else { chipStruct = (REG_STRUCT*) pex8648_cfg_type0_reg_tbl; maxReg = MAX_PEX8648_TYPE0_CFG_SPACE; } DPRINTK("--------> Find device @%p\n", pdev); err = (*performTest) (chipStruct, pdev, maxReg); func++; /* XXX make sure we go through all functions */ } if (func == 0) { commReportError(MEC_GEN_BUS_ERROR, PCI_REGISTER_TEST, PCI_ERROR_CODE_7, PCI_ERROR_MSG_7, 0, 0, 0, DG_FORMAT_NONE); err = -ENODEV; } break; case NIC_INTEL_82576: while ((pdev = pci_get_device(0x8086, 0x10c9, pdev))) { chipStruct = (REG_STRUCT*) nic82576_cfg_reg_tbl; maxReg = MAX_NIC82576_CFG_SPACE; DPRINTK("--------> Find device @%p\n", pdev); err = (*performTest) (chipStruct, pdev, maxReg); func++; /* XXX make sure we go through all functions */ } if (func != 2) { commReportError(MEC_GEN_BUS_ERROR, PCI_REGISTER_TEST, PCI_ERROR_CODE_7, PCI_ERROR_MSG_7, 0, 0, 0, DG_FORMAT_NONE); err = -ENODEV; } break; case NIC_INTEL_82579: // INTEL_PATSBURG_NIC_82579_DEVICE_ID: SOYUZ // INTEL_IBX_NIC_82577_DEVICE_ID: PIKESPEAK while ((pdev = pci_get_device( PCI_VENDOR_ID_INTEL, INTEL_PATSBURG_NIC_82579_DEVICE_ID, pdev))) { chipStruct = (REG_STRUCT*) nic82579_cfg_reg_tbl; maxReg = MAX_NIC82579_CFG_SPACE; DPRINTK("--------> Find device @%p\n", pdev); err = (*performTest) (chipStruct, pdev, maxReg); func++; /* XXX make sure we go through all functions */ } while ((pdev = pci_get_device( PCI_VENDOR_ID_INTEL, INTEL_IBX_NIC_82577_DEVICE_ID, pdev))) { chipStruct = (REG_STRUCT*) nic82579_cfg_reg_tbl; maxReg = MAX_NIC82579_CFG_SPACE; DPRINTK("--------> Find device @%p\n", pdev); err = (*performTest) (chipStruct, pdev, maxReg); func++; /* XXX make sure we go through all functions */ } if (func != 1) { commReportError(MEC_GEN_BUS_ERROR, PCI_REGISTER_TEST, PCI_ERROR_CODE_7, PCI_ERROR_MSG_7, 0, 0, 0, DG_FORMAT_NONE); err = -ENODEV; } break; case LSI_SAS_2308_IOC0: // Get SAS 2308 Device pdev = pci_get_device( 0x1000, 0x0087, pdev ); if( pdev ) { chipStruct = (REG_STRUCT*) lsi2308_cfg_reg_tbl; maxReg = MAX_LSI2308_CFG_SPACE; DPRINTK("RunRegTest Device @ 0x%p\n", pdev); err = (*performTest) (chipStruct, pdev, maxReg); break; } printk( "LSI SAS2308 device not found (Looking for PCI 0x1000:0x0087).\n" ); printk( "Try to program three SAS EEPROMs, reboot, and test again.\n" ); commReportError(MEC_GEN_BUS_ERROR, PCI_REGISTER_TEST, PCI_ERROR_CODE_7, PCI_ERROR_MSG_7, 0, 0, 0, DG_FORMAT_NONE); err = -ENODEV; break; case NETAPP_ROCKET_FPGA: pdev = pci_get_device( 0x1275, 0x7110, pdev ); // Soyuz if( !pdev ) { pdev = pci_get_device( 0x1000, 0x7110, pdev ); // Pikespeak } if( pdev ) { chipStruct = (REG_STRUCT*) lsifpga_cfg_reg_tbl; maxReg = MAX_NETAPPFPGA_CFG_SPACE; DPRINTK("RunRegTest Device @ 0x%p\n", pdev); err = (*performTest)( chipStruct, pdev, maxReg ); break; } printk( "NetApp FPGA device not found!!!\n" ); commReportError(MEC_GEN_BUS_ERROR, PCI_REGISTER_TEST, PCI_ERROR_CODE_7, PCI_ERROR_MSG_7, 0, 0, 0, DG_FORMAT_NONE); err = -ENODEV; break; default: break; } return err; } /************************************************************/ /* APIs to access PCI configuration space ************************************************************/ //ret = raw_pci_read(0, bus, devfn, offset, len, &data); //ret = raw_pci_write(0, bus, devfn, offset, len, value); static DEFINE_SPINLOCK(pci_lock); #define PCI_OP_READ(size, type, len) \ int pciConfigRead##size \ (uint16_t bus, uint8_t dev, uint8_t func, uint16_t offset, type *value) \ { \ int ret; \ uint8_t devfn; \ uint32_t data = 0; \ unsigned long flags; \ devfn = (dev << 3) | func; \ spin_lock_irqsave(&pci_lock, flags); \ printk("[Luap] raw_pci_read is stub!!\n"); \ ret = -1; \ spin_unlock_irqrestore(&pci_lock, flags); \ *value = (type) data; \ return ret; \ } #define PCI_OP_WRITE(size, type, len) \ int pciConfigWrite##size \ (uint16_t bus, uint8_t dev, uint8_t func, uint16_t offset, type value) \ { \ int ret; \ uint8_t devfn; \ unsigned long flags; \ devfn = (dev << 3) | func; \ spin_lock_irqsave(&pci_lock, flags); \ printk("[Luap] raw_pci_write is stub!!\n"); \ ret = -1; \ spin_unlock_irqrestore(&pci_lock, flags); \ return ret; \ } PCI_OP_READ(Byte, uint8_t, 1) PCI_OP_READ(Word, uint16_t, 2) PCI_OP_READ(DWord, uint32_t, 4) PCI_OP_WRITE(Byte, uint8_t, 1) PCI_OP_WRITE(Word, uint16_t, 2) PCI_OP_WRITE(DWord, uint32_t, 4) #define PCI_OP_SHOW(size, type, len) \ int pciConfigShow##size \ (uint16_t bus, uint8_t dev, uint8_t func, uint16_t offset) \ { \ int ret; \ type value; \ ret = pciConfigRead##size(bus, dev, func, offset, &value); \ switch (len) \ { \ case 1: \ printk("%02x:%02x.%02x: (%04xH) = %02x\n", bus, dev, func, offset, value); \ break; \ case 2: \ printk("%02x:%02x.%02x: (%04xH) = %04x\n", bus, dev, func, offset, value); \ break; \ case 4: \ printk("%02x:%02x.%02x: (%04xH) = %08x\n", bus, dev, func, offset, value); \ break; \ default: \ break; \ } \ return ret; \ } PCI_OP_SHOW(Byte, uint8_t, 1) PCI_OP_SHOW(Word, uint16_t, 2) PCI_OP_SHOW(DWord, uint32_t, 4) /***************************************** * FIXME: An workaround function to set upstream bridge * prefetch window to Mellanox. * The non-transparent path between two controllers * requires another prefetch settings. Those settings are * achieved by plxNTBSetup. * Users can not diagnose NTB and Mellanox at the same time. *****************************************/ void pciSetBridgePrefetchToMellanox(void) { #if 0 uint32_t bl, bu, barSize; unsigned long long membase = 0, pLimit; struct pci_dev *pdev = NULL; pdev = pci_get_device(0x15b3, 0x673c, pdev); if (!pdev) { printk("No mellanox IB device ???\n"); return; } pci_read_config_dword(pdev, 0x18, &bl); if (!(bl & PCI_BASE_ADDRESS_MEM_PREFETCH)) { printk("Mellanox IB device prefetch not enabled\n"); return; } if (bl & 0x4) { /* 64-bit address */ pci_read_config_dword(pdev, 0x1c, &bu); membase = bu; membase = membase << 32; } membase += (bl & 0xfff00000); barSize = pci_resource_len(pdev, 2); pLimit = membase + (barSize - 1); /* PLX upstream bridge */ pciConfigWriteDWord(1, 0, 0, 0x24, (((uint32_t) pLimit) & 0xfff00000) | ((uint32_t) (membase >> 16) & 0x0000fff0) | 0x00010001); pciConfigWriteDWord(1, 0, 0, 0x28, ((uint32_t) (membase >> 32))); pciConfigWriteDWord(1, 0, 0, 0x2c, ((uint32_t) (pLimit >> 32))); /* Jasper Forest PCIe root */ pciConfigWriteDWord(0, 3, 0, 0x24, (((uint32_t) pLimit) & 0xfff00000) | ((uint32_t) (membase >> 16) & 0x0000fff0) | 0x00010001); pciConfigWriteDWord(0, 3, 0, 0x28, ((uint32_t) (membase >> 32))); pciConfigWriteDWord(0, 3, 0, 0x2c, ((uint32_t) (pLimit >> 32))); #endif } MODULE_AUTHOR( "merck.hung@netapp.com" ); MODULE_DESCRIPTION( "Common PCI Code" ); MODULE_LICENSE( "GPL" );