From 32c8037055f5fdaba9c9f401fd532c02571b66d7 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 25 Oct 2005 01:56:48 -0400 Subject: Initial import of ethtool version 3 + a few patches. --- realtek.c | 517 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 517 insertions(+) create mode 100644 realtek.c (limited to 'realtek.c') diff --git a/realtek.c b/realtek.c new file mode 100644 index 0000000..64ab7f8 --- /dev/null +++ b/realtek.c @@ -0,0 +1,517 @@ +/* Copyright 2001 Sun Microsystems (thockin@sun.com) */ +#include +#include +#include "ethtool-util.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \ + (b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22) + +enum chip_type { + RTLNONE, + RTL8139, + RTL8139_K, + RTL8139A, + RTL8139A_G, + RTL8139B, + RTL8130, + RTL8139C, + RTL8100, + RTL8100B_8139D, + RTL8139Cp, + RTL8101, + RTL8169, + RTL8169s, + RTL8110 +}; + +enum { + chip_type_mask = HW_REVID(1, 1, 1, 1, 1, 1, 1) +}; + +static struct chip_info { + const char *name; + u32 id_mask; +} rtl_info_tbl[] = { + { "RTL-8139", HW_REVID(1, 0, 0, 0, 0, 0, 0) }, + { "RTL-8139-K", HW_REVID(1, 1, 0, 0, 0, 0, 0) }, + { "RTL-8139A", HW_REVID(1, 1, 1, 0, 0, 0, 0) }, + { "RTL-8139A-G", HW_REVID(1, 1, 1, 0, 0, 1, 0) }, + { "RTL-8139B", HW_REVID(1, 1, 1, 1, 0, 0, 0) }, + { "RTL-8130", HW_REVID(1, 1, 1, 1, 1, 0, 0) }, + { "RTL-8139C", HW_REVID(1, 1, 1, 0, 1, 0, 0) }, + { "RTL-8100", HW_REVID(1, 1, 1, 1, 0, 1, 0) }, + { "RTL-8100B/8139D", HW_REVID(1, 1, 1, 0, 1, 0, 1) }, + { "RTL-8139C+", HW_REVID(1, 1, 1, 0, 1, 1, 0) }, + { "RTL-8101", HW_REVID(1, 1, 1, 0, 1, 1, 1) }, + { "RTL-8169", HW_REVID(0, 0, 0, 0, 0, 0, 0) }, + { "RTL-8169s", HW_REVID(0, 0, 0, 0, 1, 0, 0) }, + { "RTL-8110", HW_REVID(0, 0, 1, 0, 0, 0, 0) }, + { } +}; + +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 = RTLNONE, i; + + v = data[0x40 >> 2] & chip_type_mask; + + ci = &rtl_info_tbl[0]; + while (ci->name) { + if (v == ci->id_mask) + break; + ci++; + } + if (v != ci->id_mask) { + fprintf(stderr, "unknown RealTek chip\n"); + return 91; + } + for (i = 0; i < ARRAY_SIZE(rtl_info_tbl); i++) { + if (ci == &rtl_info_tbl[i]) + board_type = i + 1; + } + if (board_type == RTLNONE) + abort(); + + fprintf(stdout, + "RealTek %s registers:\n" + "------------------------------\n", + ci->name); + + 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 || + board_type == RTL8169s || + board_type == RTL8110) { + 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 == RTL8169 || + board_type == RTL8169s || + board_type == RTL8110) { + 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 && + board_type != RTL8169s && + board_type != RTL8110) { + 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 || + board_type == RTL8169s || + board_type == RTL8110) { + 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 || + board_type == RTL8169s || + board_type == RTL8110) { + fprintf(stdout, + "0x60: PHY access 0x%08x\n" + "0x64: TBI control and status 0x%08x\n", + data[0x60 >> 2], + 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 || + board_type == RTL8169s || + board_type == RTL8110) { + 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]); + } + } + + return 0; +} -- cgit v1.2.1