/* Copyright 2001 Sun Microsystems (thockin@sun.com) */ #include #include #include "internal.h" #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) enum chip_type { RTL8139 = 1, RTL8139_K, RTL8139A, RTL8139A_G, RTL8139B, RTL8130, RTL8139C, RTL8100, RTL8100B_8139D, RTL8139Cp, RTL8101, /* chips not handled by 8139too/8139cp module */ RTL8169, RTL8169S, RTL8110S, RTL8169_8110SB, RTL8169_8110SCd, RTL8169_8110SCe, RTL8168_8111Bb, RTL8168_8111Bef, RTL8101Ebc, RTL8100E1, RTL8100E2, }; static const char * const chip_names[] = { [RTL8139] = "8139", [RTL8139_K] = "8139-K", [RTL8139A] = "8139A", [RTL8139A_G] = "8139A-G", [RTL8139B] = "8139B", [RTL8130] = "8130", [RTL8139C] = "8139C", [RTL8100] = "8100", [RTL8100B_8139D] = "8100B/8139D", [RTL8139Cp] = "8139C+", [RTL8101] = "8101", /* chips not handled by 8139too/8139cp module */ [RTL8169] = "8169", [RTL8169S] = "8169S", [RTL8110S] = "8110S", [RTL8169_8110SB] = "8169/8110SB", [RTL8169_8110SCd] = "8169/8110SCd", [RTL8169_8110SCe] = "8169/8110SCe", [RTL8168_8111Bb] = "8168/8111Bb", [RTL8168_8111Bef] = "8168/8111Bef", [RTL8101Ebc] = "8101Ebc", [RTL8100E1] = "8100E(1)", [RTL8100E2] = "8100E(2)", }; static struct chip_info { u32 id_mask; u32 id_val; int mac_version; } rtl_info_tbl[] = { { 0xfcc00000, 0x40000000, RTL8139 }, { 0xfcc00000, 0x60000000, RTL8139_K }, { 0xfcc00000, 0x70000000, RTL8139A }, { 0xfcc00000, 0x70800000, RTL8139A_G }, { 0xfcc00000, 0x78000000, RTL8139B }, { 0xfcc00000, 0x7c000000, RTL8130 }, { 0xfcc00000, 0x74000000, RTL8139C }, { 0xfcc00000, 0x78800000, RTL8100 }, { 0xfcc00000, 0x74400000, RTL8100B_8139D }, { 0xfcc00000, 0x74800000, RTL8139Cp }, { 0xfcc00000, 0x74c00000, RTL8101 }, /* chips not handled by 8139too/8139cp module */ { 0xfcc00000, 0x00000000, RTL8169 }, { 0xfcc00000, 0x00800000, RTL8169S }, { 0xfcc00000, 0x04000000, RTL8110S }, { 0xfcc00000, 0x10000000, RTL8169_8110SB }, { 0xfcc00000, 0x18000000, RTL8169_8110SCd }, { 0xfcc00000, 0x98000000, RTL8169_8110SCe }, { 0xfcc00000, 0x30000000, RTL8168_8111Bb }, { 0xfcc00000, 0x38000000, RTL8168_8111Bef }, { 0xfcc00000, 0x34000000, RTL8101Ebc }, { 0xfcc00000, 0x30800000, RTL8100E1 }, { 0xfcc00000, 0x38800000, RTL8100E2 }, { } }; static void print_intr_bits(u16 mask) { fprintf(stdout, " %s%s%s%s%s%s%s%s%s%s%s\n", mask & (1 << 15) ? "SERR " : "", mask & (1 << 14) ? "TimeOut " : "", mask & (1 << 8) ? "SWInt " : "", mask & (1 << 7) ? "TxNoBuf " : "", mask & (1 << 6) ? "RxFIFO " : "", mask & (1 << 5) ? "LinkChg " : "", mask & (1 << 4) ? "RxNoBuf " : "", mask & (1 << 3) ? "TxErr " : "", mask & (1 << 2) ? "TxOK " : "", mask & (1 << 1) ? "RxErr " : "", mask & (1 << 0) ? "RxOK " : ""); } int realtek_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs) { u32 *data = (u32 *) regs->data; u8 *data8 = (u8 *) regs->data; u32 v; struct chip_info *ci; unsigned int board_type; v = data[0x40 >> 2]; /* TxConfig */ ci = &rtl_info_tbl[0]; while (ci->mac_version) { if ((v & ci->id_mask) == ci->id_val) break; ci++; } board_type = ci->mac_version; if (!board_type) { fprintf(stderr, "Unknown RealTek chip (TxConfig: 0x%08x)\n", v); return 91; } fprintf(stdout, "RealTek RTL%s registers:\n" "--------------------------------------------------------\n", chip_names[board_type]); fprintf(stdout, "0x00: MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", data8[0x00], data8[0x01], data8[0x02], data8[0x03], data8[0x04], data8[0x05]); fprintf(stdout, "0x08: Multicast Address Filter 0x%08x 0x%08x\n", data[0x08 >> 2], data[0x0c >> 2]); if (board_type == RTL8139Cp || board_type >= RTL8169) { fprintf(stdout, "0x10: Dump Tally Counter Command 0x%08x 0x%08x\n", data[0x10 >> 2], data[0x14 >> 2]); fprintf(stdout, "0x20: Tx Normal Priority Ring Addr 0x%08x 0x%08x\n", data[0x20 >> 2], data[0x24 >> 2]); fprintf(stdout, "0x28: Tx High Priority Ring Addr 0x%08x 0x%08x\n", data[0x28 >> 2], data[0x2C >> 2]); } else { fprintf(stdout, "0x10: Transmit Status Desc 0 0x%08x\n" "0x14: Transmit Status Desc 1 0x%08x\n" "0x18: Transmit Status Desc 2 0x%08x\n" "0x1C: Transmit Status Desc 3 0x%08x\n", data[0x10 >> 2], data[0x14 >> 2], data[0x18 >> 2], data[0x1C >> 2]); fprintf(stdout, "0x20: Transmit Start Addr 0 0x%08x\n" "0x24: Transmit Start Addr 1 0x%08x\n" "0x28: Transmit Start Addr 2 0x%08x\n" "0x2C: Transmit Start Addr 3 0x%08x\n", data[0x20 >> 2], data[0x24 >> 2], data[0x28 >> 2], data[0x2C >> 2]); } if (board_type != RTL8168_8111Bb && board_type != RTL8168_8111Bef) { if (board_type >= RTL8169) { fprintf(stdout, "0x30: Flash memory read/write 0x%08x\n", data[0x30 >> 2]); } else { fprintf(stdout, "0x30: Rx buffer addr (C mode) 0x%08x\n", data[0x30 >> 2]); } } v = data8[0x36]; fprintf(stdout, "0x34: Early Rx Byte Count %8u\n" "0x36: Early Rx Status 0x%02x\n", data[0x34 >> 2] & 0xffff, v); if (v & 0xf) { fprintf(stdout, " %s%s%s%s\n", v & (1 << 3) ? "ERxGood " : "", v & (1 << 2) ? "ERxBad " : "", v & (1 << 1) ? "ERxOverWrite " : "", v & (1 << 0) ? "ERxOK " : ""); } v = data8[0x37]; fprintf(stdout, "0x37: Command 0x%02x\n" " Rx %s, Tx %s%s\n", data8[0x37], v & (1 << 3) ? "on" : "off", v & (1 << 2) ? "on" : "off", v & (1 << 4) ? ", RESET" : ""); if (board_type < RTL8169) { fprintf(stdout, "0x38: Current Address of Packet Read (C mode) 0x%04x\n" "0x3A: Current Rx buffer address (C mode) 0x%04x\n", data[0x38 >> 2] & 0xffff, data[0x38 >> 2] >> 16); } fprintf(stdout, "0x3C: Interrupt Mask 0x%04x\n", data[0x3c >> 2] & 0xffff); print_intr_bits(data[0x3c >> 2] & 0xffff); fprintf(stdout, "0x3E: Interrupt Status 0x%04x\n", data[0x3c >> 2] >> 16); print_intr_bits(data[0x3c >> 2] >> 16); fprintf(stdout, "0x40: Tx Configuration 0x%08x\n" "0x44: Rx Configuration 0x%08x\n" "0x48: Timer count 0x%08x\n" "0x4C: Missed packet counter 0x%06x\n", data[0x40 >> 2], data[0x44 >> 2], data[0x48 >> 2], data[0x4C >> 2] & 0xffffff); fprintf(stdout, "0x50: EEPROM Command 0x%02x\n" "0x51: Config 0 0x%02x\n" "0x52: Config 1 0x%02x\n", data8[0x50], data8[0x51], data8[0x52]); if (board_type >= RTL8169) { fprintf(stdout, "0x53: Config 2 0x%02x\n" "0x54: Config 3 0x%02x\n" "0x55: Config 4 0x%02x\n" "0x56: Config 5 0x%02x\n", data8[0x53], data8[0x54], data8[0x55], data8[0x56]); fprintf(stdout, "0x58: Timer interrupt 0x%08x\n", data[0x58 >> 2]); } else { if (board_type >= RTL8139A) { fprintf(stdout, "0x54: Timer interrupt 0x%08x\n", data[0x54 >> 2]); } fprintf(stdout, "0x58: Media status 0x%02x\n", data8[0x58]); if (board_type >= RTL8139A) { fprintf(stdout, "0x59: Config 3 0x%02x\n", data8[0x59]); } if (board_type >= RTL8139B) { fprintf(stdout, "0x5A: Config 4 0x%02x\n", data8[0x5A]); } } fprintf(stdout, "0x5C: Multiple Interrupt Select 0x%04x\n", data[0x5c >> 2] & 0xffff); if (board_type >= RTL8169) { fprintf(stdout, "0x60: PHY access 0x%08x\n", data[0x60 >> 2]); if (board_type != RTL8168_8111Bb && board_type != RTL8168_8111Bef) { fprintf(stdout, "0x64: TBI control and status 0x%08x\n", data[0x64 >> 2]); fprintf(stdout, "0x68: TBI Autonegotiation advertisement (ANAR) 0x%04x\n" "0x6A: TBI Link partner ability (LPAR) 0x%04x\n", data[0x68 >> 2] & 0xffff, data[0x68 >> 2] >> 16); } fprintf(stdout, "0x6C: PHY status 0x%02x\n", data8[0x6C]); fprintf(stdout, "0x84: PM wakeup frame 0 0x%08x 0x%08x\n" "0x8C: PM wakeup frame 1 0x%08x 0x%08x\n", data[0x84 >> 2], data[0x88 >> 2], data[0x8C >> 2], data[0x90 >> 2]); fprintf(stdout, "0x94: PM wakeup frame 2 (low) 0x%08x 0x%08x\n" "0x9C: PM wakeup frame 2 (high) 0x%08x 0x%08x\n", data[0x94 >> 2], data[0x98 >> 2], data[0x9C >> 2], data[0xA0 >> 2]); fprintf(stdout, "0xA4: PM wakeup frame 3 (low) 0x%08x 0x%08x\n" "0xAC: PM wakeup frame 3 (high) 0x%08x 0x%08x\n", data[0xA4 >> 2], data[0xA8 >> 2], data[0xAC >> 2], data[0xB0 >> 2]); fprintf(stdout, "0xB4: PM wakeup frame 4 (low) 0x%08x 0x%08x\n" "0xBC: PM wakeup frame 4 (high) 0x%08x 0x%08x\n", data[0xB4 >> 2], data[0xB8 >> 2], data[0xBC >> 2], data[0xC0 >> 2]); fprintf(stdout, "0xC4: Wakeup frame 0 CRC 0x%04x\n" "0xC6: Wakeup frame 1 CRC 0x%04x\n" "0xC8: Wakeup frame 2 CRC 0x%04x\n" "0xCA: Wakeup frame 3 CRC 0x%04x\n" "0xCC: Wakeup frame 4 CRC 0x%04x\n", data[0xC4 >> 2] & 0xffff, data[0xC4 >> 2] >> 16, data[0xC8 >> 2] & 0xffff, data[0xC8 >> 2] >> 16, data[0xCC >> 2] & 0xffff); fprintf(stdout, "0xDA: RX packet maximum size 0x%04x\n", data[0xD8 >> 2] >> 16); } else { fprintf(stdout, "0x5E: PCI revision id 0x%02x\n", data8[0x5e]); fprintf(stdout, "0x60: Transmit Status of All Desc (C mode) 0x%04x\n" "0x62: MII Basic Mode Control Register 0x%04x\n", data[0x60 >> 2] & 0xffff, data[0x60 >> 2] >> 16); fprintf(stdout, "0x64: MII Basic Mode Status Register 0x%04x\n" "0x66: MII Autonegotiation Advertising 0x%04x\n", data[0x64 >> 2] & 0xffff, data[0x64 >> 2] >> 16); fprintf(stdout, "0x68: MII Link Partner Ability 0x%04x\n" "0x6A: MII Expansion 0x%04x\n", data[0x68 >> 2] & 0xffff, data[0x68 >> 2] >> 16); fprintf(stdout, "0x6C: MII Disconnect counter 0x%04x\n" "0x6E: MII False carrier sense counter 0x%04x\n", data[0x6C >> 2] & 0xffff, data[0x6C >> 2] >> 16); fprintf(stdout, "0x70: MII Nway test 0x%04x\n" "0x72: MII RX_ER counter 0x%04x\n", data[0x70 >> 2] & 0xffff, data[0x70 >> 2] >> 16); fprintf(stdout, "0x74: MII CS configuration 0x%04x\n", data[0x74 >> 2] & 0xffff); if (board_type >= RTL8139_K) { fprintf(stdout, "0x78: PHY parameter 1 0x%08x\n" "0x7C: Twister parameter 0x%08x\n", data[0x78 >> 2], data[0x7C >> 2]); if (board_type >= RTL8139A) { fprintf(stdout, "0x80: PHY parameter 2 0x%02x\n", data8[0x80]); } } if (board_type == RTL8139Cp) { fprintf(stdout, "0x82: Low addr of a Tx Desc w/ Tx DMA OK 0x%04x\n", data[0x80 >> 2] >> 16); } else if (board_type == RTL8130) { fprintf(stdout, "0x82: MII register 0x%02x\n", data8[0x82]); } if (board_type >= RTL8139A) { fprintf(stdout, "0x84: PM CRC for wakeup frame 0 0x%02x\n" "0x85: PM CRC for wakeup frame 1 0x%02x\n" "0x86: PM CRC for wakeup frame 2 0x%02x\n" "0x87: PM CRC for wakeup frame 3 0x%02x\n" "0x88: PM CRC for wakeup frame 4 0x%02x\n" "0x89: PM CRC for wakeup frame 5 0x%02x\n" "0x8A: PM CRC for wakeup frame 6 0x%02x\n" "0x8B: PM CRC for wakeup frame 7 0x%02x\n", data8[0x84], data8[0x85], data8[0x86], data8[0x87], data8[0x88], data8[0x89], data8[0x8A], data8[0x8B]); fprintf(stdout, "0x8C: PM wakeup frame 0 0x%08x 0x%08x\n" "0x94: PM wakeup frame 1 0x%08x 0x%08x\n" "0x9C: PM wakeup frame 2 0x%08x 0x%08x\n" "0xA4: PM wakeup frame 3 0x%08x 0x%08x\n" "0xAC: PM wakeup frame 4 0x%08x 0x%08x\n" "0xB4: PM wakeup frame 5 0x%08x 0x%08x\n" "0xBC: PM wakeup frame 6 0x%08x 0x%08x\n" "0xC4: PM wakeup frame 7 0x%08x 0x%08x\n", data[0x8C >> 2], data[0x90 >> 2], data[0x94 >> 2], data[0x98 >> 2], data[0x9C >> 2], data[0xA0 >> 2], data[0xA4 >> 2], data[0xA8 >> 2], data[0xAC >> 2], data[0xB0 >> 2], data[0xB4 >> 2], data[0xB8 >> 2], data[0xBC >> 2], data[0xC0 >> 2], data[0xC4 >> 2], data[0xC8 >> 2]); fprintf(stdout, "0xCC: PM LSB CRC for wakeup frame 0 0x%02x\n" "0xCD: PM LSB CRC for wakeup frame 1 0x%02x\n" "0xCE: PM LSB CRC for wakeup frame 2 0x%02x\n" "0xCF: PM LSB CRC for wakeup frame 3 0x%02x\n" "0xD0: PM LSB CRC for wakeup frame 4 0x%02x\n" "0xD1: PM LSB CRC for wakeup frame 5 0x%02x\n" "0xD2: PM LSB CRC for wakeup frame 6 0x%02x\n" "0xD3: PM LSB CRC for wakeup frame 7 0x%02x\n", data8[0xCC], data8[0xCD], data8[0xCE], data8[0xCF], data8[0xD0], data8[0xD1], data8[0xD2], data8[0xD3]); } if (board_type >= RTL8139B) { if (board_type != RTL8100 && board_type != RTL8100B_8139D && board_type != RTL8101) fprintf(stdout, "0xD4: Flash memory read/write 0x%08x\n", data[0xD4 >> 2]); if (board_type != RTL8130) fprintf(stdout, "0xD8: Config 5 0x%02x\n", data8[0xD8]); } } if (board_type == RTL8139Cp || board_type >= RTL8169) { v = data[0xE0 >> 2] & 0xffff; fprintf(stdout, "0xE0: C+ Command 0x%04x\n", v); if (v & (1 << 9)) fprintf(stdout, " Big-endian mode\n"); if (v & (1 << 8)) fprintf(stdout, " Home LAN enable\n"); if (v & (1 << 6)) fprintf(stdout, " VLAN de-tagging\n"); if (v & (1 << 5)) fprintf(stdout, " RX checksumming\n"); if (v & (1 << 4)) fprintf(stdout, " PCI 64-bit DAC\n"); if (v & (1 << 3)) fprintf(stdout, " PCI Multiple RW\n"); v = data[0xe0 >> 2] >> 16; fprintf(stdout, "0xE2: Interrupt Mitigation 0x%04x\n" " TxTimer: %u\n" " TxPackets: %u\n" " RxTimer: %u\n" " RxPackets: %u\n", v, v >> 12, (v >> 8) & 0xf, (v >> 4) & 0xf, v & 0xf); fprintf(stdout, "0xE4: Rx Ring Addr 0x%08x 0x%08x\n", data[0xE4 >> 2], data[0xE8 >> 2]); fprintf(stdout, "0xEC: Early Tx threshold 0x%02x\n", data8[0xEC]); if (board_type == RTL8139Cp) { fprintf(stdout, "0xFC: External MII register 0x%08x\n", data[0xFC >> 2]); } else if (board_type >= RTL8169 && board_type != RTL8168_8111Bb && board_type != RTL8168_8111Bef) { fprintf(stdout, "0xF0: Func Event 0x%08x\n" "0xF4: Func Event Mask 0x%08x\n" "0xF8: Func Preset State 0x%08x\n" "0xFC: Func Force Event 0x%08x\n", data[0xF0 >> 2], data[0xF4 >> 2], data[0xF8 >> 2], data[0xFC >> 2]); } } return 0; }