#include "etherboot.h"#include "nic.h"#include <gpxe/ethernet.h>#include <gpxe/pci.h>Go to the source code of this file.
Data Structures | |
| struct | pci_id_info |
| struct | pci_id_info::match_info |
| struct | tulip_chip_table |
| struct | medialeaf |
| struct | mediatable |
| struct | mediainfo |
| struct | tulip_rx_desc |
| struct | tulip_tx_desc |
| struct | tulip_private |
| struct | fixups |
Defines | |
| #define | TX_TIME_OUT 2*TICKS_PER_SEC |
| #define | get_unaligned(ptr) (*(ptr)) |
| #define | put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) |
| #define | get_u16(ptr) (*(u16 *)(ptr)) |
| #define | virt_to_le32desc(addr) virt_to_bus(addr) |
| #define | TULIP_IOTYPE PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0 |
| #define | TULIP_SIZE 0x80 |
| #define | FULL_DUPLEX_MAGIC 0x6969 |
| #define | MEDIA_MASK 31 |
| #define | EEPROM_ADDRLEN 6 |
| #define | EEPROM_SIZE 128 |
| #define | EE_WRITE_CMD (5 << addr_len) |
| #define | EE_READ_CMD (6 << addr_len) |
| #define | EE_ERASE_CMD (7 << addr_len) |
| #define | EE_SHIFT_CLK 0x02 |
| #define | EE_CS 0x01 |
| #define | EE_DATA_WRITE 0x04 |
| #define | EE_WRITE_0 0x01 |
| #define | EE_WRITE_1 0x05 |
| #define | EE_DATA_READ 0x08 |
| #define | EE_ENB (0x4800 | EE_CS) |
| #define | eeprom_delay() inl(ee_addr) |
| #define | BUFLEN 1536 |
| #define | DESC_RING_WRAP 0x02000000 |
| #define | TX_RING_SIZE 2 |
| #define | RX_RING_SIZE 4 |
| #define | tx_ring tulip_bss.tx_ring |
| #define | txb tulip_bss.txb |
| #define | rx_ring tulip_bss.rx_ring |
| #define | rxb tulip_bss.rxb |
| #define | mdio_delay() inl(mdio_addr) |
| #define | MDIO_SHIFT_CLK 0x10000 |
| #define | MDIO_DATA_WRITE0 0x00000 |
| #define | MDIO_DATA_WRITE1 0x20000 |
| #define | MDIO_ENB 0x00000 |
| #define | MDIO_ENB_IN 0x40000 |
| #define | MDIO_DATA_READ 0x80000 |
Enumerations | |
| enum | tulip_chips { DC21040 = 0, DC21041 = 1, DC21140 = 2, DC21142 = 3, DC21143 = 3, LC82C168, MX98713, MX98715, MX98725, AX88141, AX88140, PNIC2, COMET, COMPEX9881, I21145, XIRCOM, SGThomson } |
| enum | pci_id_flags_bits { PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4, PCI_ADDR0 = 0 << 4, PCI_ADDR1 = 1 << 4, PCI_ADDR2, PCI_ADDR3 = 3 << 4, PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4, PCI_ADDR0 = 0<<4, PCI_ADDR1 = 1<<4, PCI_ADDR2 = 2<<4, PCI_ADDR3 = 3<<4, PCI_ADDR_64BITS = 0x100, PCI_NO_ACPI_WAKE = 0x200, PCI_NO_MIN_LATENCY = 0x400, PCI_UNUSED_IRQ = 0x800 } |
| enum | tbl_flag { HAS_MII = 1, HAS_MEDIA_TABLE = 2, CSR12_IN_SROM = 4, ALWAYS_CHECK_MII = 8, HAS_PWRDWN = 0x10, MC_HASH_ONLY = 0x20, HAS_PNICNWAY = 0x80, HAS_NWAY = 0x40, HAS_INTR_MITIGATION = 0x100, IS_ASIX = 0x200, HAS_8023X = 0x400 } |
| enum | MediaIs { MediaIsFD = 1, MediaAlwaysFD = 2, MediaIsMII = 4, MediaIsFx = 8, MediaIs100 = 16 } |
| enum | tulip_offsets { CSR0 = 0, CSR1 = 0x08, CSR2 = 0x10, CSR3 = 0x18, CSR4 = 0x20, CSR5 = 0x28, CSR6 = 0x30, CSR7 = 0x38, CSR8 = 0x40, CSR9 = 0x48, CSR10 = 0x50, CSR11 = 0x58, CSR12 = 0x60, CSR13 = 0x68, CSR14 = 0x70, CSR15 = 0x78, CSR16 = 0x80, CSR20 = 0xA0 } |
| enum | status_bits { TimerInt = 0x800, TPLnkFail = 0x1000, TPLnkPass = 0x10, NormalIntr = 0x10000, AbnormalIntr = 0x8000, RxJabber = 0x200, RxDied = 0x100, RxNoBuf = 0x80, RxIntr = 0x40, TxFIFOUnderflow = 0x20, TxJabber = 0x08, TxNoBuf = 0x04, TxDied = 0x02, TxIntr = 0x01 } |
| enum | csr6_mode_bits { TxOn = 0x2000, RxOn = 0x0002, FullDuplex = 0x0200, AcceptBroadcast = 0x0100, AcceptAllMulticast = 0x0080, AcceptAllPhys = 0x0040, AcceptRunt = 0x0008 } |
| enum | desc_status_bits { DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000, DescNoCRC = 0x10000000, DescPktOK = 0x08000000, RxTooLong = 0x00400000, DescOwn = 0x8000, DescEndPacket = 0x4000, DescEndRing = 0x2000, LastFrag = 0x80000000, DescIntrOnTx = 0x8000, DescIntrOnDMADone = 0x80000000, DisableAlign = 0x00000001, DescOwnded = 0x80000000, RxDescFatalErr = 0x8000, RxWholePkt = 0x0300, DescOwn = 0x80000000, DescEndRing = 0x02000000, DescUseLink = 0x01000000, DescWholePkt = 0x60000000, DescStartPkt = 0x20000000, DescEndPkt = 0x40000000, DescIntr = 0x80000000 } |
Functions | |
| FILE_LICENCE (GPL_ANY) | |
| static int | mdio_read (struct nic *nic, int phy_id, int location) |
| static void | mdio_write (struct nic *nic, int phy_id, int location, int value) |
| static int | read_eeprom (unsigned long ioaddr, int location, int addr_len) |
| static void | parse_eeprom (struct nic *nic) |
| static int | tulip_probe (struct nic *nic, struct pci_device *pci) |
| static void | tulip_init_ring (struct nic *nic) |
| static void | tulip_reset (struct nic *nic) |
| static void | tulip_transmit (struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p) |
| static int | tulip_poll (struct nic *nic, int retrieve) |
| static void | tulip_disable (struct nic *nic) |
| static void | nway_start (struct nic *nic) |
| static void | pnic_do_nway (struct nic *nic) |
| static void | select_media (struct nic *nic, int startup) |
| static void | init_media (struct nic *nic) |
| static void | start_link (struct nic *nic) |
| static int | tulip_check_duplex (struct nic *nic) |
| static void | tulip_wait (unsigned int nticks) |
| int | mdio_read (struct nic *nic __unused, int phy_id, int location) |
| void | mdio_write (struct nic *nic __unused, int phy_id, int location, int value) |
| static void | tulip_init_ring (struct nic *nic __unused) |
| static void | set_rx_mode (struct nic *nic __unused) |
| static void | tulip_irq (struct nic *nic __unused, irq_action_t action __unused) |
| static void | nway_start (struct nic *nic __unused) |
| static void | pnic_do_nway (struct nic *nic __unused) |
| PCI_DRIVER (tulip_driver, tulip_nics, PCI_NO_CLASS) | |
| DRIVER ("Tulip", nic_driver, pci_driver, tulip_driver, tulip_probe, tulip_disable) | |
Variables | |
| static const int | csr0 = 0x01A00000 | 0x8000 |
| static const char *const | medianame [32] |
| static struct pci_id_info | pci_id_tbl [] |
| static struct tulip_chip_table | tulip_tbl [] |
| static const char | media_cap [32] |
| static u8 | t21040_csr13 [] = {2,0x0C,8,4, 4,0,0,0, 0,0,0,0, 4,0,0,0} |
| static u16 | t21041_csr13 [] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, } |
| static u16 | t21041_csr14 [] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, } |
| static u16 | t21041_csr15 [] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, } |
| static u16 | t21142_csr14 [] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, } |
| static u32 | ioaddr |
| struct { | |
| struct tulip_tx_desc tx_ring [TX_RING_SIZE] | |
| unsigned char txb [BUFLEN] | |
| struct tulip_rx_desc rx_ring [RX_RING_SIZE] | |
| unsigned char rxb [RX_RING_SIZE *BUFLEN] | |
| struct tulip_private tpx | |
| } | __shared |
| static struct tulip_private * | tp |
| static struct fixups | eeprom_fixups [] |
| static const char * | block_name [] |
| static struct nic_operations | tulip_operations |
| static struct pci_device_id | tulip_nics [] |
| #define put_unaligned | ( | val, | |||
| ptr | ) | ((void)( *(ptr) = (val) )) |
| #define get_u16 | ( | ptr | ) | (*(u16 *)(ptr)) |
| #define TULIP_IOTYPE PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0 |
| #define FULL_DUPLEX_MAGIC 0x6969 |
| #define MEDIA_MASK 31 |
| #define DESC_RING_WRAP 0x02000000 |
| #define tx_ring tulip_bss.tx_ring |
| #define txb tulip_bss.txb |
| #define rx_ring tulip_bss.rx_ring |
| #define rxb tulip_bss.rxb |
| #define MDIO_SHIFT_CLK 0x10000 |
| #define MDIO_DATA_WRITE1 0x20000 |
| #define MDIO_ENB 0x00000 |
| #define MDIO_ENB_IN 0x40000 |
| #define MDIO_DATA_READ 0x80000 |
| enum tulip_chips |
| DC21040 | |
| DC21041 | |
| DC21140 | |
| DC21142 | |
| DC21143 | |
| LC82C168 | |
| MX98713 | |
| MX98715 | |
| MX98725 | |
| AX88141 | |
| AX88140 | |
| PNIC2 | |
| COMET | |
| COMPEX9881 | |
| I21145 | |
| XIRCOM | |
| SGThomson |
Definition at line 156 of file tulip.c.
00156 { 00157 DC21040=0, DC21041=1, DC21140=2, DC21142=3, DC21143=3, 00158 LC82C168, MX98713, MX98715, MX98725, AX88141, AX88140, PNIC2, COMET, 00159 COMPEX9881, I21145, XIRCOM, SGThomson, /*Ramesh Chander*/ 00160 };
| enum pci_id_flags_bits |
Definition at line 162 of file tulip.c.
00162 { 00163 /* Set PCI command register bits before calling probe1(). */ 00164 PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, 00165 /* Read and map the single following PCI BAR. */ 00166 PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4, 00167 PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400, 00168 PCI_UNUSED_IRQ=0x800, 00169 };
| enum tbl_flag |
| HAS_MII | |
| HAS_MEDIA_TABLE | |
| CSR12_IN_SROM | |
| ALWAYS_CHECK_MII | |
| HAS_PWRDWN | |
| MC_HASH_ONLY | |
| HAS_PNICNWAY | |
| HAS_NWAY | |
| HAS_INTR_MITIGATION | |
| IS_ASIX | |
| HAS_8023X |
Definition at line 240 of file tulip.c.
00240 { 00241 HAS_MII=1, HAS_MEDIA_TABLE=2, CSR12_IN_SROM=4, ALWAYS_CHECK_MII=8, 00242 HAS_PWRDWN=0x10, MC_HASH_ONLY=0x20, /* Hash-only multicast filter. */ 00243 HAS_PNICNWAY=0x80, HAS_NWAY=0x40, /* Uses internal NWay xcvr. */ 00244 HAS_INTR_MITIGATION=0x100, IS_ASIX=0x200, HAS_8023X=0x400, 00245 };
| enum MediaIs |
Definition at line 277 of file tulip.c.
00277 { 00278 MediaIsFD = 1, MediaAlwaysFD=2, MediaIsMII=4, MediaIsFx=8, 00279 MediaIs100=16};
| enum tulip_offsets |
| CSR0 | |
| CSR1 | |
| CSR2 | |
| CSR3 | |
| CSR4 | |
| CSR5 | |
| CSR6 | |
| CSR7 | |
| CSR8 | |
| CSR9 | |
| CSR10 | |
| CSR11 | |
| CSR12 | |
| CSR13 | |
| CSR14 | |
| CSR15 | |
| CSR16 | |
| CSR20 |
Definition at line 300 of file tulip.c.
00300 { 00301 CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28, 00302 CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58, 00303 CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0 00304 };
| enum status_bits |
| TimerInt | |
| TPLnkFail | |
| TPLnkPass | |
| NormalIntr | |
| AbnormalIntr | |
| RxJabber | |
| RxDied | |
| RxNoBuf | |
| RxIntr | |
| TxFIFOUnderflow | |
| TxJabber | |
| TxNoBuf | |
| TxDied | |
| TxIntr |
Definition at line 307 of file tulip.c.
00307 { 00308 TimerInt=0x800, TPLnkFail=0x1000, TPLnkPass=0x10, 00309 NormalIntr=0x10000, AbnormalIntr=0x8000, 00310 RxJabber=0x200, RxDied=0x100, RxNoBuf=0x80, RxIntr=0x40, 00311 TxFIFOUnderflow=0x20, TxJabber=0x08, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01, 00312 };
| enum csr6_mode_bits |
Definition at line 315 of file tulip.c.
00315 { 00316 TxOn=0x2000, RxOn=0x0002, FullDuplex=0x0200, 00317 AcceptBroadcast=0x0100, AcceptAllMulticast=0x0080, 00318 AcceptAllPhys=0x0040, AcceptRunt=0x0008, 00319 };
| enum desc_status_bits |
Definition at line 322 of file tulip.c.
00322 { 00323 DescOwnded=0x80000000, RxDescFatalErr=0x8000, RxWholePkt=0x0300, 00324 };
| FILE_LICENCE | ( | GPL_ANY | ) |
| static int mdio_read | ( | struct nic * | nic, | |
| int | phy_id, | |||
| int | location | |||
| ) | [static] |
| static void mdio_write | ( | struct nic * | nic, | |
| int | phy_id, | |||
| int | location, | |||
| int | value | |||
| ) | [static] |
| static int read_eeprom | ( | unsigned long | ioaddr, | |
| int | location, | |||
| int | addr_len | |||
| ) | [static] |
Definition at line 707 of file tulip.c.
References CSR9, EE_CS, EE_DATA_READ, EE_DATA_WRITE, EE_ENB, EE_READ_CMD, EE_SHIFT_CLK, eeprom_delay, inl, outl, and whereami().
00708 { 00709 int i; 00710 unsigned short retval = 0; 00711 long ee_addr = ioaddr + CSR9; 00712 int read_cmd = location | EE_READ_CMD; 00713 00714 #ifdef TULIP_DEBUG_WHERE 00715 whereami("read_eeprom\n"); 00716 #endif 00717 00718 outl(EE_ENB & ~EE_CS, ee_addr); 00719 outl(EE_ENB, ee_addr); 00720 00721 /* Shift the read command bits out. */ 00722 for (i = 4 + addr_len; i >= 0; i--) { 00723 short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; 00724 outl(EE_ENB | dataval, ee_addr); 00725 eeprom_delay(); 00726 outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); 00727 eeprom_delay(); 00728 } 00729 outl(EE_ENB, ee_addr); 00730 00731 for (i = 16; i > 0; i--) { 00732 outl(EE_ENB | EE_SHIFT_CLK, ee_addr); 00733 eeprom_delay(); 00734 retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0); 00735 outl(EE_ENB, ee_addr); 00736 eeprom_delay(); 00737 } 00738 00739 /* Terminate the EEPROM access. */ 00740 outl(EE_ENB & ~EE_CS, ee_addr); 00741 return retval; 00742 }
| static void parse_eeprom | ( | struct nic * | nic | ) | [static] |
Definition at line 748 of file tulip.c.
References fixups::addr0, fixups::addr1, fixups::addr2, tulip_private::chip_id, CSR12_IN_SROM, mediatable::csr12dir, mediatable::csr15dir, mediatable::csr15val, DC21041, mediatable::defaultmedia, ee_data, tulip_private::eeprom, eeprom_fixups, tulip_private::flags, get_u16, get_unaligned, mediatable::has_mii, mediatable::has_nonmii, mediatable::has_reset, mediatable::leafcount, medialeaf::leafdata, medialeaf::media, media, MEDIA_MASK, tulip_private::media_table_storage, medianame, memcpy, mediatable::mleaf, tulip_private::mtable, name, fixups::name, tulip_private::nic_name, nic::node_addr, NULL, printf(), tulip_private::sym_advertise, medialeaf::type, u16, u32, and whereami().
Referenced by tulip_probe().
00749 { 00750 unsigned char *p, *ee_data = tp->eeprom; 00751 int new_advertise = 0; 00752 int i; 00753 00754 #ifdef TULIP_DEBUG_WHERE 00755 whereami("parse_eeprom\n"); 00756 #endif 00757 00758 tp->mtable = 0; 00759 /* Detect an old-style (SA only) EEPROM layout: 00760 memcmp(ee_data, ee_data+16, 8). */ 00761 for (i = 0; i < 8; i ++) 00762 if (ee_data[i] != ee_data[16+i]) 00763 break; 00764 if (i >= 8) { 00765 /* Do a fix-up based on the vendor half of the station address. */ 00766 for (i = 0; eeprom_fixups[i].name; i++) { 00767 if (nic->node_addr[0] == eeprom_fixups[i].addr0 00768 && nic->node_addr[1] == eeprom_fixups[i].addr1 00769 && nic->node_addr[2] == eeprom_fixups[i].addr2) { 00770 if (nic->node_addr[2] == 0xE8 && ee_data[0x1a] == 0x55) 00771 i++; /* An Accton EN1207, not an outlaw Maxtech. */ 00772 memcpy(ee_data + 26, eeprom_fixups[i].newtable, 00773 sizeof(eeprom_fixups[i].newtable)); 00774 #ifdef TULIP_DEBUG 00775 printf("%s: Old format EEPROM on '%s' board.\n%s: Using substitute media control info.\n", 00776 tp->nic_name, eeprom_fixups[i].name, tp->nic_name); 00777 #endif 00778 break; 00779 } 00780 } 00781 if (eeprom_fixups[i].name == NULL) { /* No fixup found. */ 00782 #ifdef TULIP_DEBUG 00783 printf("%s: Old style EEPROM with no media selection information.\n", 00784 tp->nic_name); 00785 #endif 00786 return; 00787 } 00788 } 00789 00790 if (ee_data[19] > 1) { 00791 #ifdef TULIP_DEBUG 00792 printf("%s: Multiport cards (%d ports) may not work correctly.\n", 00793 tp->nic_name, ee_data[19]); 00794 #endif 00795 } 00796 00797 p = (void *)ee_data + ee_data[27]; 00798 00799 if (ee_data[27] == 0) { /* No valid media table. */ 00800 #ifdef TULIP_DEBUG 00801 if (tulip_debug > 1) { 00802 printf("%s: No Valid Media Table. ee_data[27] = %hhX\n", 00803 tp->nic_name, ee_data[27]); 00804 } 00805 #endif 00806 } else if (tp->chip_id == DC21041) { 00807 int media = get_u16(p); 00808 int count = p[2]; 00809 p += 3; 00810 00811 printf("%s: 21041 Media table, default media %hX (%s).\n", 00812 tp->nic_name, media, 00813 media & 0x0800 ? "Autosense" : medianame[media & 15]); 00814 for (i = 0; i < count; i++) { 00815 unsigned char media_block = *p++; 00816 int media_code = media_block & MEDIA_MASK; 00817 if (media_block & 0x40) 00818 p += 6; 00819 switch(media_code) { 00820 case 0: new_advertise |= 0x0020; break; 00821 case 4: new_advertise |= 0x0040; break; 00822 } 00823 printf("%s: 21041 media #%d, %s.\n", 00824 tp->nic_name, media_code, medianame[media_code]); 00825 } 00826 } else { 00827 unsigned char csr12dir = 0; 00828 int count; 00829 struct mediatable *mtable; 00830 u16 media = get_u16(p); 00831 00832 p += 2; 00833 if (tp->flags & CSR12_IN_SROM) 00834 csr12dir = *p++; 00835 count = *p++; 00836 00837 tp->mtable = mtable = (struct mediatable *)&tp->media_table_storage[0]; 00838 00839 mtable->defaultmedia = media; 00840 mtable->leafcount = count; 00841 mtable->csr12dir = csr12dir; 00842 mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0; 00843 mtable->csr15dir = mtable->csr15val = 0; 00844 00845 printf("%s: EEPROM default media type %s.\n", tp->nic_name, 00846 media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]); 00847 00848 for (i = 0; i < count; i++) { 00849 struct medialeaf *leaf = &mtable->mleaf[i]; 00850 00851 if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */ 00852 leaf->type = 0; 00853 leaf->media = p[0] & 0x3f; 00854 leaf->leafdata = p; 00855 if ((p[2] & 0x61) == 0x01) /* Bogus, but Znyx boards do it. */ 00856 mtable->has_mii = 1; 00857 p += 4; 00858 } else { 00859 switch(leaf->type = p[1]) { 00860 case 5: 00861 mtable->has_reset = i; 00862 leaf->media = p[2] & 0x0f; 00863 break; 00864 case 1: case 3: 00865 mtable->has_mii = 1; 00866 leaf->media = 11; 00867 break; 00868 case 2: 00869 if ((p[2] & 0x3f) == 0) { 00870 u32 base15 = (p[2] & 0x40) ? get_u16(p + 7) : 0x0008; 00871 u16 *p1 = (u16 *)(p + (p[2] & 0x40 ? 9 : 3)); 00872 mtable->csr15dir = (get_unaligned(p1 + 0)<<16) + base15; 00873 mtable->csr15val = (get_unaligned(p1 + 1)<<16) + base15; 00874 } 00875 /* Fall through. */ 00876 case 0: case 4: 00877 mtable->has_nonmii = 1; 00878 leaf->media = p[2] & MEDIA_MASK; 00879 switch (leaf->media) { 00880 case 0: new_advertise |= 0x0020; break; 00881 case 4: new_advertise |= 0x0040; break; 00882 case 3: new_advertise |= 0x0080; break; 00883 case 5: new_advertise |= 0x0100; break; 00884 case 6: new_advertise |= 0x0200; break; 00885 } 00886 break; 00887 default: 00888 leaf->media = 19; 00889 } 00890 leaf->leafdata = p + 2; 00891 p += (p[0] & 0x3f) + 1; 00892 } 00893 #ifdef TULIP_DEBUG 00894 if (tulip_debug > 1 && leaf->media == 11) { 00895 unsigned char *bp = leaf->leafdata; 00896 printf("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %hhX %hhX.\n", 00897 tp->nic_name, bp[0], bp[1], bp[2 + bp[1]*2], 00898 bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]); 00899 } 00900 #endif 00901 printf("%s: Index #%d - Media %s (#%d) described " 00902 "by a %s (%d) block.\n", 00903 tp->nic_name, i, medianame[leaf->media], leaf->media, 00904 leaf->type < 6 ? block_name[leaf->type] : "UNKNOWN", 00905 leaf->type); 00906 } 00907 if (new_advertise) 00908 tp->sym_advertise = new_advertise; 00909 } 00910 }
| static int tulip_probe | ( | struct nic * | nic, | |
| struct pci_device * | pci | |||
| ) | [static] |
Definition at line 1235 of file tulip.c.
References adjust_pci_device(), tulip_private::chip_id, chip_idx, tulip_chip_table::chip_name, COMET, csr0, tulip_private::csr0, CSR5, CSR6, CSR7, CSR8, CSR9, DBG, DC21040, DC21041, DC21143, tulip_private::default_port, tulip_private::dev_id, pci_device::device, pci_device::driver_name, pci_id_info::drv_flags, ee_data, tulip_private::eeprom, EEPROM_SIZE, ETH_ALEN, eth_ntoa(), tulip_chip_table::flags, tulip_private::flags, HAS_8023X, HAS_MEDIA_TABLE, HAS_PWRDWN, pci_id_info::id, tulip_private::if_port, inl, nic::ioaddr, ioaddr, pci_device::ioaddr, nic::irqno, IS_ASIX, LC82C168, le16_to_cpu, media_cap, MediaIsMII, memcpy, tulip_private::mii_advertise, pci_id_info::name, name, tulip_private::nic_name, nic::nic_op, nic::node_addr, outl, parse_eeprom(), pci_id_info::match_info::pci, tulip_private::pci_id_idx, pci_id_info::match_info::pci_mask, pci_read_config_byte(), PCI_REVISION, pci_write_config_dword(), printf(), put_unaligned, read_eeprom(), tulip_private::revision, start_link(), TICKS_PER_SEC, tulip_reset(), tulip_tbl, tulip_wait(), u16, u32, u8, pci_device::vendor, tulip_private::vendor_id, and whereami().
01235 { 01236 01237 u32 i; 01238 u8 chip_rev; 01239 u8 ee_data[EEPROM_SIZE]; 01240 unsigned short sum; 01241 int chip_idx; 01242 static unsigned char last_phys_addr[ETH_ALEN] = {0x00, 'L', 'i', 'n', 'u', 'x'}; 01243 01244 if (pci->ioaddr == 0) 01245 return 0; 01246 01247 ioaddr = pci->ioaddr; 01248 nic->ioaddr = pci->ioaddr & ~3; 01249 nic->irqno = 0; 01250 01251 /* point to private storage */ 01252 tp = &tulip_bss.tpx; 01253 01254 tp->vendor_id = pci->vendor; 01255 tp->dev_id = pci->device; 01256 tp->nic_name = pci->driver_name; 01257 01258 tp->if_port = 0; 01259 tp->default_port = 0; 01260 01261 adjust_pci_device(pci); 01262 01263 /* disable interrupts */ 01264 outl(0x00000000, ioaddr + CSR7); 01265 01266 /* Stop the chip's Tx and Rx processes. */ 01267 outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6); 01268 01269 /* Clear the missed-packet counter. */ 01270 inl(ioaddr + CSR8); 01271 01272 printf("\n"); /* so we start on a fresh line */ 01273 #ifdef TULIP_DEBUG_WHERE 01274 whereami("tulip_probe\n"); 01275 #endif 01276 01277 #ifdef TULIP_DEBUG 01278 if (tulip_debug > 1) 01279 printf ("%s: Looking for Tulip Chip: Vendor=%hX Device=%hX\n", tp->nic_name, 01280 tp->vendor, tp->dev_id); 01281 #endif 01282 01283 /* Figure out which chip we're dealing with */ 01284 i = 0; 01285 chip_idx = -1; 01286 01287 while (pci_id_tbl[i].name) { 01288 if ( (((u32) tp->dev_id << 16) | tp->vendor_id) == 01289 (pci_id_tbl[i].id.pci & pci_id_tbl[i].id.pci_mask) ) { 01290 chip_idx = pci_id_tbl[i].drv_flags; 01291 break; 01292 } 01293 i++; 01294 } 01295 01296 if (chip_idx == -1) { 01297 printf ("%s: Unknown Tulip Chip: Vendor=%hX Device=%hX\n", tp->nic_name, 01298 tp->vendor_id, tp->dev_id); 01299 return 0; 01300 } 01301 01302 tp->pci_id_idx = i; 01303 tp->flags = tulip_tbl[chip_idx].flags; 01304 01305 #ifdef TULIP_DEBUG 01306 if (tulip_debug > 1) { 01307 printf ("%s: tp->pci_id_idx == %d, name == %s\n", tp->nic_name, 01308 tp->pci_id_idx, pci_id_tbl[tp->pci_id_idx].name); 01309 printf ("%s: chip_idx == %d, name == %s\n", tp->nic_name, chip_idx, 01310 tulip_tbl[chip_idx].chip_name); 01311 } 01312 #endif 01313 01314 /* Bring the 21041/21143 out of sleep mode. 01315 Caution: Snooze mode does not work with some boards! */ 01316 if (tp->flags & HAS_PWRDWN) 01317 pci_write_config_dword(pci, 0x40, 0x00000000); 01318 01319 if (inl(ioaddr + CSR5) == 0xFFFFFFFF) { 01320 printf("%s: The Tulip chip at %X is not functioning.\n", 01321 tp->nic_name, (unsigned int) ioaddr); 01322 return 0; 01323 } 01324 01325 pci_read_config_byte(pci, PCI_REVISION, &chip_rev); 01326 01327 printf("%s: [chip: %s] rev %d at %hX\n", tp->nic_name, 01328 tulip_tbl[chip_idx].chip_name, chip_rev, (unsigned int) ioaddr); 01329 printf("%s: Vendor=%hX Device=%hX", tp->nic_name, tp->vendor_id, tp->dev_id); 01330 01331 if (chip_idx == DC21041 && inl(ioaddr + CSR9) & 0x8000) { 01332 printf(" 21040 compatible mode."); 01333 chip_idx = DC21040; 01334 } 01335 01336 printf("\n"); 01337 01338 /* The SROM/EEPROM interface varies dramatically. */ 01339 sum = 0; 01340 if (chip_idx == DC21040) { 01341 outl(0, ioaddr + CSR9); /* Reset the pointer with a dummy write. */ 01342 for (i = 0; i < ETH_ALEN; i++) { 01343 int value, boguscnt = 100000; 01344 do 01345 value = inl(ioaddr + CSR9); 01346 while (value < 0 && --boguscnt > 0); 01347 nic->node_addr[i] = value; 01348 sum += value & 0xff; 01349 } 01350 } else if (chip_idx == LC82C168) { 01351 for (i = 0; i < 3; i++) { 01352 int value, boguscnt = 100000; 01353 outl(0x600 | i, ioaddr + 0x98); 01354 do 01355 value = inl(ioaddr + CSR9); 01356 while (value < 0 && --boguscnt > 0); 01357 put_unaligned(le16_to_cpu(value), ((u16*)nic->node_addr) + i); 01358 sum += value & 0xffff; 01359 } 01360 } else if (chip_idx == COMET) { 01361 /* No need to read the EEPROM. */ 01362 put_unaligned(inl(ioaddr + 0xA4), (u32 *)nic->node_addr); 01363 put_unaligned(inl(ioaddr + 0xA8), (u16 *)(nic->node_addr + 4)); 01364 for (i = 0; i < ETH_ALEN; i ++) 01365 sum += nic->node_addr[i]; 01366 } else { 01367 /* A serial EEPROM interface, we read now and sort it out later. */ 01368 int sa_offset = 0; 01369 int ee_addr_size = read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6; 01370 01371 for (i = 0; i < sizeof(ee_data)/2; i++) 01372 ((u16 *)ee_data)[i] = 01373 le16_to_cpu(read_eeprom(ioaddr, i, ee_addr_size)); 01374 01375 /* DEC now has a specification (see Notes) but early board makers 01376 just put the address in the first EEPROM locations. */ 01377 /* This does memcmp(eedata, eedata+16, 8) */ 01378 for (i = 0; i < 8; i ++) 01379 if (ee_data[i] != ee_data[16+i]) 01380 sa_offset = 20; 01381 if (ee_data[0] == 0xff && ee_data[1] == 0xff && ee_data[2] == 0) { 01382 sa_offset = 2; /* Grrr, damn Matrox boards. */ 01383 } 01384 for (i = 0; i < ETH_ALEN; i ++) { 01385 nic->node_addr[i] = ee_data[i + sa_offset]; 01386 sum += ee_data[i + sa_offset]; 01387 } 01388 } 01389 /* Lite-On boards have the address byte-swapped. */ 01390 if ((nic->node_addr[0] == 0xA0 || nic->node_addr[0] == 0xC0) 01391 && nic->node_addr[1] == 0x00) 01392 for (i = 0; i < ETH_ALEN; i+=2) { 01393 char tmp = nic->node_addr[i]; 01394 nic->node_addr[i] = nic->node_addr[i+1]; 01395 nic->node_addr[i+1] = tmp; 01396 } 01397 01398 if (sum == 0 || sum == ETH_ALEN*0xff) { 01399 printf("%s: EEPROM not present!\n", tp->nic_name); 01400 for (i = 0; i < ETH_ALEN-1; i++) 01401 nic->node_addr[i] = last_phys_addr[i]; 01402 nic->node_addr[i] = last_phys_addr[i] + 1; 01403 } 01404 01405 for (i = 0; i < ETH_ALEN; i++) 01406 last_phys_addr[i] = nic->node_addr[i]; 01407 01408 DBG ( "%s: %s at ioaddr %hX\n", tp->nic_name, eth_ntoa ( nic->node_addr ), 01409 (unsigned int) ioaddr ); 01410 01411 tp->chip_id = chip_idx; 01412 tp->revision = chip_rev; 01413 tp->csr0 = csr0; 01414 01415 /* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles. 01416 And the ASIX must have a burst limit or horrible things happen. */ 01417 if (chip_idx == DC21143 && chip_rev == 65) 01418 tp->csr0 &= ~0x01000000; 01419 else if (tp->flags & IS_ASIX) 01420 tp->csr0 |= 0x2000; 01421 01422 if (media_cap[tp->default_port] & MediaIsMII) { 01423 static const u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 01424 0x80, 0x100, 0x200 }; 01425 tp->mii_advertise = media2advert[tp->default_port - 9]; 01426 tp->mii_advertise |= (tp->flags & HAS_8023X); /* Matching bits! */ 01427 } 01428 01429 /* This is logically part of the probe routine, but too complex 01430 to write inline. */ 01431 if (tp->flags & HAS_MEDIA_TABLE) { 01432 memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom)); 01433 parse_eeprom(nic); 01434 } 01435 01436 start_link(nic); 01437 01438 /* reset the device and make ready for tx and rx of packets */ 01439 tulip_reset(nic); 01440 nic->nic_op = &tulip_operations; 01441 01442 /* give the board a chance to reset before returning */ 01443 tulip_wait(4*TICKS_PER_SEC); 01444 01445 return 1; 01446 }
| static void tulip_init_ring | ( | struct nic * | nic | ) | [static] |
Referenced by tulip_reset().
| static void tulip_reset | ( | struct nic * | nic | ) | [static] |
Definition at line 972 of file tulip.c.
References tulip_private::chip_id, COMET, cpu_to_le32, tulip_private::csr0, CSR0, CSR1, CSR13, CSR14, CSR3, CSR4, tulip_private::csr6, CSR6, currticks(), tulip_private::flags, get_unaligned, mediatable::has_mii, init_media(), inl, ioaddr, IS_ASIX, LC82C168, MC_HASH_ONLY, tulip_private::mii_cnt, tulip_private::mtable, tulip_private::nic_name, nic::node_addr, outl, PNIC2, printf(), rx_ring, set_rx_mode(), tulip_check_duplex(), tulip_init_ring(), tulip_wait(), tx_ring, TX_TIME_OUT, txb, u16, u32, virt_to_le32desc, and whereami().
Referenced by tulip_disable(), and tulip_probe().
00973 { 00974 int i; 00975 unsigned long to; 00976 00977 #ifdef TULIP_DEBUG_WHERE 00978 whereami("tulip_reset\n"); 00979 #endif 00980 00981 /* Stop Tx and RX */ 00982 outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6); 00983 00984 /* On some chip revs we must set the MII/SYM port before the reset!? */ 00985 if (tp->mii_cnt || (tp->mtable && tp->mtable->has_mii)) { 00986 outl(0x814C0000, ioaddr + CSR6); 00987 } 00988 00989 /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */ 00990 outl(0x00000001, ioaddr + CSR0); 00991 tulip_wait(1); 00992 00993 /* turn off reset and set cache align=16lword, burst=unlimit */ 00994 outl(tp->csr0, ioaddr + CSR0); 00995 00996 /* Wait the specified 50 PCI cycles after a reset */ 00997 tulip_wait(1); 00998 00999 /* set up transmit and receive descriptors */ 01000 tulip_init_ring(nic); 01001 01002 if (tp->chip_id == PNIC2) { 01003 u32 addr_high = (nic->node_addr[1]<<8) + (nic->node_addr[0]<<0); 01004 /* This address setting does not appear to impact chip operation?? */ 01005 outl((nic->node_addr[5]<<8) + nic->node_addr[4] + 01006 (nic->node_addr[3]<<24) + (nic->node_addr[2]<<16), 01007 ioaddr + 0xB0); 01008 outl(addr_high + (addr_high<<16), ioaddr + 0xB8); 01009 } 01010 01011 /* MC_HASH_ONLY boards don't support setup packets */ 01012 if (tp->flags & MC_HASH_ONLY) { 01013 u32 addr_low = cpu_to_le32(get_unaligned((u32 *)nic->node_addr)); 01014 u32 addr_high = cpu_to_le32(get_unaligned((u16 *)(nic->node_addr+4))); 01015 01016 /* clear multicast hash filters and setup MAC address filters */ 01017 if (tp->flags & IS_ASIX) { 01018 outl(0, ioaddr + CSR13); 01019 outl(addr_low, ioaddr + CSR14); 01020 outl(1, ioaddr + CSR13); 01021 outl(addr_high, ioaddr + CSR14); 01022 outl(2, ioaddr + CSR13); 01023 outl(0, ioaddr + CSR14); 01024 outl(3, ioaddr + CSR13); 01025 outl(0, ioaddr + CSR14); 01026 } else if (tp->chip_id == COMET) { 01027 outl(addr_low, ioaddr + 0xA4); 01028 outl(addr_high, ioaddr + 0xA8); 01029 outl(0, ioaddr + 0xAC); 01030 outl(0, ioaddr + 0xB0); 01031 } 01032 } else { 01033 /* for other boards we send a setup packet to initialize 01034 the filters */ 01035 u32 tx_flags = 0x08000000 | 192; 01036 01037 /* construct perfect filter frame with mac address as first match 01038 and broadcast address for all others */ 01039 for (i=0; i<192; i++) 01040 txb[i] = 0xFF; 01041 txb[0] = nic->node_addr[0]; 01042 txb[1] = nic->node_addr[1]; 01043 txb[4] = nic->node_addr[2]; 01044 txb[5] = nic->node_addr[3]; 01045 txb[8] = nic->node_addr[4]; 01046 txb[9] = nic->node_addr[5]; 01047 01048 tx_ring[0].length = cpu_to_le32(tx_flags); 01049 tx_ring[0].buffer1 = virt_to_le32desc(&txb[0]); 01050 tx_ring[0].status = cpu_to_le32(0x80000000); 01051 } 01052 01053 /* Point to rx and tx descriptors */ 01054 outl(virt_to_le32desc(&rx_ring[0]), ioaddr + CSR3); 01055 outl(virt_to_le32desc(&tx_ring[0]), ioaddr + CSR4); 01056 01057 init_media(nic); 01058 01059 /* set the chip's operating mode (but don't turn on xmit and recv yet) */ 01060 outl((tp->csr6 & ~0x00002002), ioaddr + CSR6); 01061 01062 /* send setup packet for cards that support it */ 01063 if (!(tp->flags & MC_HASH_ONLY)) { 01064 /* enable transmit wait for completion */ 01065 outl(tp->csr6 | 0x00002000, ioaddr + CSR6); 01066 /* immediate transmit demand */ 01067 outl(0, ioaddr + CSR1); 01068 01069 to = currticks() + TX_TIME_OUT; 01070 while ((tx_ring[0].status & 0x80000000) && (currticks() < to)) 01071 /* wait */ ; 01072 01073 if (currticks() >= to) { 01074 printf ("%s: TX Setup Timeout.\n", tp->nic_name); 01075 } 01076 } 01077 01078 if (tp->chip_id == LC82C168) 01079 tulip_check_duplex(nic); 01080 01081 set_rx_mode(nic); 01082 01083 /* enable transmit and receive */ 01084 outl(tp->csr6 | 0x00002002, ioaddr + CSR6); 01085 }
| static void tulip_transmit | ( | struct nic * | nic, | |
| const char * | d, | |||
| unsigned int | t, | |||
| unsigned int | s, | |||
| const char * | p | |||
| ) | [static] |
Definition at line 1091 of file tulip.c.
References cpu_to_le32, CSR1, CSR4, CSR6, currticks(), ETH_ALEN, ETH_HLEN, ETH_ZLEN, htons, inl, ioaddr, memcpy, tulip_private::nic_name, nic::node_addr, outl, printf(), tx_ring, TX_TIME_OUT, txb, u16, u32, u8, virt_to_le32desc, and whereami().
01093 { 01094 u16 nstype; 01095 u32 to; 01096 u32 csr6 = inl(ioaddr + CSR6); 01097 01098 #ifdef TULIP_DEBUG_WHERE 01099 whereami("tulip_transmit\n"); 01100 #endif 01101 01102 /* Disable Tx */ 01103 outl(csr6 & ~0x00002000, ioaddr + CSR6); 01104 01105 memcpy(txb, d, ETH_ALEN); 01106 memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN); 01107 nstype = htons((u16) t); 01108 memcpy(txb + 2 * ETH_ALEN, (u8 *)&nstype, 2); 01109 memcpy(txb + ETH_HLEN, p, s); 01110 01111 s += ETH_HLEN; 01112 s &= 0x0FFF; 01113 01114 /* pad to minimum packet size */ 01115 while (s < ETH_ZLEN) 01116 txb[s++] = '\0'; 01117 01118 #ifdef TULIP_DEBUG 01119 if (tulip_debug > 1) 01120 printf("%s: sending %d bytes ethtype %hX\n", tp->nic_name, s, t); 01121 #endif 01122 01123 /* setup the transmit descriptor */ 01124 /* 0x60000000 = no interrupt on completion */ 01125 tx_ring[0].length = cpu_to_le32(0x60000000 | s); 01126 tx_ring[0].status = cpu_to_le32(0x80000000); 01127 01128 /* Point to transmit descriptor */ 01129 outl(virt_to_le32desc(&tx_ring[0]), ioaddr + CSR4); 01130 01131 /* Enable Tx */ 01132 outl(csr6 | 0x00002000, ioaddr + CSR6); 01133 /* immediate transmit demand */ 01134 outl(0, ioaddr + CSR1); 01135 01136 to = currticks() + TX_TIME_OUT; 01137 while ((tx_ring[0].status & 0x80000000) && (currticks() < to)) 01138 /* wait */ ; 01139 01140 if (currticks() >= to) { 01141 printf ("TX Timeout!\n"); 01142 } 01143 01144 /* Disable Tx */ 01145 outl(csr6 & ~0x00002000, ioaddr + CSR6); 01146 }
| static int tulip_poll | ( | struct nic * | nic, | |
| int | retrieve | |||
| ) | [static] |
Definition at line 1151 of file tulip.c.
References BUFLEN, tulip_private::cur_rx, memcpy, nic::packet, nic::packetlen, rx_ring, RX_RING_SIZE, rxb, and whereami().
01152 { 01153 01154 #ifdef TULIP_DEBUG_WHERE 01155 whereami("tulip_poll\n"); 01156 #endif 01157 01158 /* no packet waiting. packet still owned by NIC */ 01159 if (rx_ring[tp->cur_rx].status & 0x80000000) 01160 return 0; 01161 01162 if ( ! retrieve ) return 1; 01163 01164 #ifdef TULIP_DEBUG_WHERE 01165 whereami("tulip_poll got one\n"); 01166 #endif 01167 01168 nic->packetlen = (rx_ring[tp->cur_rx].status & 0x3FFF0000) >> 16; 01169 01170 /* if we get a corrupted packet. throw it away and move on */ 01171 if (rx_ring[tp->cur_rx].status & 0x00008000) { 01172 /* return the descriptor and buffer to receive ring */ 01173 rx_ring[tp->cur_rx].status = 0x80000000; 01174 tp->cur_rx = (++tp->cur_rx) % RX_RING_SIZE; 01175 return 0; 01176 } 01177 01178 /* copy packet to working buffer */ 01179 memcpy(nic->packet, rxb + tp->cur_rx * BUFLEN, nic->packetlen); 01180 01181 /* return the descriptor and buffer to receive ring */ 01182 rx_ring[tp->cur_rx].status = 0x80000000; 01183 tp->cur_rx = (++tp->cur_rx) % RX_RING_SIZE; 01184 01185 return 1; 01186 }
| static void tulip_disable | ( | struct nic * | nic | ) | [static] |
Definition at line 1191 of file tulip.c.
References CSR6, CSR7, CSR8, inl, ioaddr, outl, tulip_reset(), and whereami().
01191 { 01192 01193 #ifdef TULIP_DEBUG_WHERE 01194 whereami("tulip_disable\n"); 01195 #endif 01196 01197 tulip_reset(nic); 01198 01199 /* disable interrupts */ 01200 outl(0x00000000, ioaddr + CSR7); 01201 01202 /* Stop the chip's Tx and Rx processes. */ 01203 outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6); 01204 01205 /* Clear the missed-packet counter. */ 01206 inl(ioaddr + CSR8); 01207 }
| static void nway_start | ( | struct nic * | nic | ) | [static] |
Referenced by init_media(), and start_link().
| static void pnic_do_nway | ( | struct nic * | nic | ) | [static] |
Referenced by init_media().
| static void select_media | ( | struct nic * | nic, | |
| int | startup | |||
| ) | [static] |
Definition at line 1760 of file tulip.c.
References tulip_private::advertising, tulip_private::chip_id, CSR11, CSR12, mediatable::csr12dir, CSR13, CSR14, CSR15, tulip_private::csr6, tulip_private::cur_index, DC21040, DC21041, tulip_private::default_port, tulip_private::full_duplex, FULL_DUPLEX_MAGIC, get_u16, mediatable::has_reset, tulip_private::if_port, inl, ioaddr, LC82C168, medialeaf::leafdata, mdio_write(), media_cap, MediaAlwaysFD, MediaIsFx, MediaIsMII, tulip_private::medialock, medianame, tulip_private::mii_advertise, tulip_private::mii_cnt, mediatable::mleaf, tulip_private::mtable, tulip_private::nic_name, outl, tulip_private::phys, printf(), t21040_csr13, t21041_csr13, t21041_csr14, t21041_csr15, t21142_csr14, medialeaf::type, u16, u32, u8, and whereami().
Referenced by init_media(), and start_link().
01761 { 01762 struct mediatable *mtable = tp->mtable; 01763 u32 new_csr6; 01764 int i; 01765 01766 #ifdef TULIP_DEBUG_WHERE 01767 whereami("select_media\n"); 01768 #endif 01769 01770 if (mtable) { 01771 struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index]; 01772 unsigned char *p = mleaf->leafdata; 01773 switch (mleaf->type) { 01774 case 0: /* 21140 non-MII xcvr. */ 01775 #ifdef TULIP_DEBUG 01776 if (tulip_debug > 1) 01777 printf("%s: Using a 21140 non-MII transceiver" 01778 " with control setting %hhX.\n", 01779 tp->nic_name, p[1]); 01780 #endif 01781 tp->if_port = p[0]; 01782 if (startup) 01783 outl(mtable->csr12dir | 0x100, ioaddr + CSR12); 01784 outl(p[1], ioaddr + CSR12); 01785 new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18); 01786 break; 01787 case 2: case 4: { 01788 u16 setup[5]; 01789 u32 csr13val, csr14val, csr15dir, csr15val; 01790 for (i = 0; i < 5; i++) 01791 setup[i] = get_u16(&p[i*2 + 1]); 01792 01793 tp->if_port = p[0] & 15; 01794 if (media_cap[tp->if_port] & MediaAlwaysFD) 01795 tp->full_duplex = 1; 01796 01797 if (startup && mtable->has_reset) { 01798 struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset]; 01799 unsigned char *rst = rleaf->leafdata; 01800 #ifdef TULIP_DEBUG 01801 if (tulip_debug > 1) 01802 printf("%s: Resetting the transceiver.\n", 01803 tp->nic_name); 01804 #endif 01805 for (i = 0; i < rst[0]; i++) 01806 outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15); 01807 } 01808 #ifdef TULIP_DEBUG 01809 if (tulip_debug > 1) 01810 printf("%s: 21143 non-MII %s transceiver control " 01811 "%hX/%hX.\n", 01812 tp->nic_name, medianame[tp->if_port], setup[0], setup[1]); 01813 #endif 01814 if (p[0] & 0x40) { /* SIA (CSR13-15) setup values are provided. */ 01815 csr13val = setup[0]; 01816 csr14val = setup[1]; 01817 csr15dir = (setup[3]<<16) | setup[2]; 01818 csr15val = (setup[4]<<16) | setup[2]; 01819 outl(0, ioaddr + CSR13); 01820 outl(csr14val, ioaddr + CSR14); 01821 outl(csr15dir, ioaddr + CSR15); /* Direction */ 01822 outl(csr15val, ioaddr + CSR15); /* Data */ 01823 outl(csr13val, ioaddr + CSR13); 01824 } else { 01825 csr13val = 1; 01826 csr14val = 0x0003FF7F; 01827 csr15dir = (setup[0]<<16) | 0x0008; 01828 csr15val = (setup[1]<<16) | 0x0008; 01829 if (tp->if_port <= 4) 01830 csr14val = t21142_csr14[tp->if_port]; 01831 if (startup) { 01832 outl(0, ioaddr + CSR13); 01833 outl(csr14val, ioaddr + CSR14); 01834 } 01835 outl(csr15dir, ioaddr + CSR15); /* Direction */ 01836 outl(csr15val, ioaddr + CSR15); /* Data */ 01837 if (startup) outl(csr13val, ioaddr + CSR13); 01838 } 01839 #ifdef TULIP_DEBUG 01840 if (tulip_debug > 1) 01841 printf("%s: Setting CSR15 to %X/%X.\n", 01842 tp->nic_name, csr15dir, csr15val); 01843 #endif 01844 if (mleaf->type == 4) 01845 new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18); 01846 else 01847 new_csr6 = 0x82420000; 01848 break; 01849 } 01850 case 1: case 3: { 01851 int phy_num = p[0]; 01852 int init_length = p[1]; 01853 u16 *misc_info; 01854 01855 tp->if_port = 11; 01856 new_csr6 = 0x020E0000; 01857 if (mleaf->type == 3) { /* 21142 */ 01858 u16 *init_sequence = (u16*)(p+2); 01859 u16 *reset_sequence = &((u16*)(p+3))[init_length]; 01860 int reset_length = p[2 + init_length*2]; 01861 misc_info = reset_sequence + reset_length; 01862 if (startup) 01863 for (i = 0; i < reset_length; i++) 01864 outl(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); 01865 for (i = 0; i < init_length; i++) 01866 outl(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); 01867 } else { 01868 u8 *init_sequence = p + 2; 01869 u8 *reset_sequence = p + 3 + init_length; 01870 int reset_length = p[2 + init_length]; 01871 misc_info = (u16*)(reset_sequence + reset_length); 01872 if (startup) { 01873 outl(mtable->csr12dir | 0x100, ioaddr + CSR12); 01874 for (i = 0; i < reset_length; i++) 01875 outl(reset_sequence[i], ioaddr + CSR12); 01876 } 01877 for (i = 0; i < init_length; i++) 01878 outl(init_sequence[i], ioaddr + CSR12); 01879 } 01880 tp->advertising[phy_num] = get_u16(&misc_info[1]) | 1; 01881 if (startup < 2) { 01882 if (tp->mii_advertise == 0) 01883 tp->mii_advertise = tp->advertising[phy_num]; 01884 #ifdef TULIP_DEBUG 01885 if (tulip_debug > 1) 01886 printf("%s: Advertising %hX on MII %d.\n", 01887 tp->nic_name, tp->mii_advertise, tp->phys[phy_num]); 01888 #endif 01889 mdio_write(nic, tp->phys[phy_num], 4, tp->mii_advertise); 01890 } 01891 break; 01892 } 01893 default: 01894 printf("%s: Invalid media table selection %d.\n", 01895 tp->nic_name, mleaf->type); 01896 new_csr6 = 0x020E0000; 01897 } 01898 #ifdef TULIP_DEBUG 01899 if (tulip_debug > 1) 01900 printf("%s: Using media type %s, CSR12 is %hhX.\n", 01901 tp->nic_name, medianame[tp->if_port], 01902 inl(ioaddr + CSR12) & 0xff); 01903 #endif 01904 } else if (tp->chip_id == DC21041) { 01905 int port = tp->if_port <= 4 ? tp->if_port : 0; 01906 #ifdef TULIP_DEBUG 01907 if (tulip_debug > 1) 01908 printf("%s: 21041 using media %s, CSR12 is %hX.\n", 01909 tp->nic_name, medianame[port == 3 ? 12: port], 01910 inl(ioaddr + CSR12)); 01911 #endif 01912 outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */ 01913 outl(t21041_csr14[port], ioaddr + CSR14); 01914 outl(t21041_csr15[port], ioaddr + CSR15); 01915 outl(t21041_csr13[port], ioaddr + CSR13); 01916 new_csr6 = 0x80020000; 01917 } else if (tp->chip_id == LC82C168) { 01918 if (startup && ! tp->medialock) 01919 tp->if_port = tp->mii_cnt ? 11 : 0; 01920 #ifdef TULIP_DEBUG 01921 if (tulip_debug > 1) 01922 printf("%s: PNIC PHY status is %hX, media %s.\n", 01923 tp->nic_name, inl(ioaddr + 0xB8), medianame[tp->if_port]); 01924 #endif 01925 if (tp->mii_cnt) { 01926 new_csr6 = 0x810C0000; 01927 outl(0x0001, ioaddr + CSR15); 01928 outl(0x0201B07A, ioaddr + 0xB8); 01929 } else if (startup) { 01930 /* Start with 10mbps to do autonegotiation. */ 01931 outl(0x32, ioaddr + CSR12); 01932 new_csr6 = 0x00420000; 01933 outl(0x0001B078, ioaddr + 0xB8); 01934 outl(0x0201B078, ioaddr + 0xB8); 01935 } else if (tp->if_port == 3 || tp->if_port == 5) { 01936 outl(0x33, ioaddr + CSR12); 01937 new_csr6 = 0x01860000; 01938 /* Trigger autonegotiation. */ 01939 outl(startup ? 0x0201F868 : 0x0001F868, ioaddr + 0xB8); 01940 } else { 01941 outl(0x32, ioaddr + CSR12); 01942 new_csr6 = 0x00420000; 01943 outl(0x1F078, ioaddr + 0xB8); 01944 } 01945 } else if (tp->chip_id == DC21040) { /* 21040 */ 01946 /* Turn on the xcvr interface. */ 01947 #ifdef TULIP_DEBUG 01948 int csr12 = inl(ioaddr + CSR12); 01949 if (tulip_debug > 1) 01950 printf("%s: 21040 media type is %s, CSR12 is %hhX.\n", 01951 tp->nic_name, medianame[tp->if_port], csr12); 01952 #endif 01953 if (media_cap[tp->if_port] & MediaAlwaysFD) 01954 tp->full_duplex = 1; 01955 new_csr6 = 0x20000; 01956 /* Set the full duplux match frame. */ 01957 outl(FULL_DUPLEX_MAGIC, ioaddr + CSR11); 01958 outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */ 01959 if (t21040_csr13[tp->if_port] & 8) { 01960 outl(0x0705, ioaddr + CSR14); 01961 outl(0x0006, ioaddr + CSR15); 01962 } else { 01963 outl(0xffff, ioaddr + CSR14); 01964 outl(0x0000, ioaddr + CSR15); 01965 } 01966 outl(0x8f01 | t21040_csr13[tp->if_port], ioaddr + CSR13); 01967 } else { /* Unknown chip type with no media table. */ 01968 if (tp->default_port == 0) 01969 tp->if_port = tp->mii_cnt ? 11 : 3; 01970 if (media_cap[tp->if_port] & MediaIsMII) { 01971 new_csr6 = 0x020E0000; 01972 } else if (media_cap[tp->if_port] & MediaIsFx) { 01973 new_csr6 = 0x028600000; 01974 } else 01975 new_csr6 = 0x038600000; 01976 #ifdef TULIP_DEBUG 01977 if (tulip_debug > 1) 01978 printf("%s: No media description table, assuming " 01979 "%s transceiver, CSR12 %hhX.\n", 01980 tp->nic_name, medianame[tp->if_port], 01981 inl(ioaddr + CSR12)); 01982 #endif 01983 } 01984 01985 tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0); 01986 return; 01987 }
| static void init_media | ( | struct nic * | nic | ) | [static] |
Definition at line 1603 of file tulip.c.
References AX88140, AX88141, tulip_private::chip_id, COMET, COMPEX9881, CSR12, CSR13, CSR14, CSR15, CSR5, CSR6, tulip_private::csr6, tulip_private::cur_index, DC21041, DC21142, DC21143, tulip_private::default_port, mediatable::defaultmedia, tulip_private::full_duplex, tulip_private::if_port, inl, inw, ioaddr, LC82C168, mediatable::leafcount, mdio_read(), medialeaf::media, media_cap, MediaAlwaysFD, MediaIsMII, medianame, tulip_private::mii_cnt, mediatable::mleaf, tulip_private::mtable, MX98713, MX98715, MX98725, tulip_private::nic_name, NULL, nway_start(), tulip_private::nwayset, outl, tulip_private::phys, PNIC2, pnic_do_nway(), printf(), tulip_private::saved_if_port, select_media(), TPLnkPass, and whereami().
Referenced by tulip_reset().
01604 { 01605 int i; 01606 01607 #ifdef TULIP_DEBUG_WHERE 01608 whereami("init_media\n"); 01609 #endif 01610 01611 tp->saved_if_port = tp->if_port; 01612 if (tp->if_port == 0) 01613 tp->if_port = tp->default_port; 01614 01615 /* Allow selecting a default media. */ 01616 i = 0; 01617 if (tp->mtable == NULL) 01618 goto media_picked; 01619 if (tp->if_port) { 01620 int looking_for = media_cap[tp->if_port] & MediaIsMII ? 11 : 01621 (tp->if_port == 12 ? 0 : tp->if_port); 01622 for (i = 0; i < tp->mtable->leafcount; i++) 01623 if (tp->mtable->mleaf[i].media == looking_for) { 01624 printf("%s: Using user-specified media %s.\n", 01625 tp->nic_name, medianame[tp->if_port]); 01626 goto media_picked; 01627 } 01628 } 01629 if ((tp->mtable->defaultmedia & 0x0800) == 0) { 01630 int looking_for = tp->mtable->defaultmedia & 15; 01631 for (i = 0; i < tp->mtable->leafcount; i++) 01632 if (tp->mtable->mleaf[i].media == looking_for) { 01633 printf("%s: Using EEPROM-set media %s.\n", 01634 tp->nic_name, medianame[looking_for]); 01635 goto media_picked; 01636 } 01637 } 01638 /* Start sensing first non-full-duplex media. */ 01639 for (i = tp->mtable->leafcount - 1; 01640 (media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--) 01641 ; 01642 media_picked: 01643 01644 tp->csr6 = 0; 01645 tp->cur_index = i; 01646 tp->nwayset = 0; 01647 01648 if (tp->if_port) { 01649 if (tp->chip_id == DC21143 && media_cap[tp->if_port] & MediaIsMII) { 01650 /* We must reset the media CSRs when we force-select MII mode. */ 01651 outl(0x0000, ioaddr + CSR13); 01652 outl(0x0000, ioaddr + CSR14); 01653 outl(0x0008, ioaddr + CSR15); 01654 } 01655 select_media(nic, 1); 01656 return; 01657 } 01658 switch(tp->chip_id) { 01659 case DC21041: 01660 /* tp->nway = 1;*/ 01661 nway_start(nic); 01662 break; 01663 case DC21142: 01664 if (tp->mii_cnt) { 01665 select_media(nic, 1); 01666 #ifdef TULIP_DEBUG 01667 if (tulip_debug > 1) 01668 printf("%s: Using MII transceiver %d, status %hX.\n", 01669 tp->nic_name, tp->phys[0], mdio_read(nic, tp->phys[0], 1)); 01670 #endif 01671 outl(0x82020000, ioaddr + CSR6); 01672 tp->csr6 = 0x820E0000; 01673 tp->if_port = 11; 01674 outl(0x0000, ioaddr + CSR13); 01675 outl(0x0000, ioaddr + CSR14); 01676 } else 01677 nway_start(nic); 01678 break; 01679 case PNIC2: 01680 nway_start(nic); 01681 break; 01682 case LC82C168: 01683 if (tp->mii_cnt) { 01684 tp->if_port = 11; 01685 tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0); 01686 outl(0x0001, ioaddr + CSR15); 01687 } else if (inl(ioaddr + CSR5) & TPLnkPass) 01688 pnic_do_nway(nic); 01689 else { 01690 /* Start with 10mbps to do autonegotiation. */ 01691 outl(0x32, ioaddr + CSR12); 01692 tp->csr6 = 0x00420000; 01693 outl(0x0001B078, ioaddr + 0xB8); 01694 outl(0x0201B078, ioaddr + 0xB8); 01695 } 01696 break; 01697 case MX98713: case COMPEX9881: 01698 tp->if_port = 0; 01699 tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0); 01700 outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); 01701 break; 01702 case MX98715: case MX98725: 01703 /* Provided by BOLO, Macronix - 12/10/1998. */ 01704 tp->if_port = 0; 01705 tp->csr6 = 0x01a80200; 01706 outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); 01707 outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0); 01708 break; 01709 case COMET: 01710 /* Enable automatic Tx underrun recovery */ 01711 outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88); 01712 tp->if_port = 0; 01713 tp->csr6 = 0x00040000; 01714 break; 01715 case AX88140: case AX88141: 01716 tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100; 01717 break; 01718 default: 01719 select_media(nic, 1); 01720 } 01721 }
| static void start_link | ( | struct nic * | nic | ) | [static] |
Definition at line 1448 of file tulip.c.
References tulip_private::advertising, ALWAYS_CHECK_MII, tulip_private::chip_id, COMET, COMPEX9881, CSR12, mediatable::csr12dir, CSR13, CSR14, CSR15, CSR6, tulip_private::cur_index, DC21040, DC21041, DC21140, DC21142, tulip_private::default_port, tulip_private::flags, tulip_private::full_duplex, HAS_MII, mediatable::has_mii, tulip_private::if_port, inl, ioaddr, LC82C168, mediatable::leafcount, mdio_read(), mdio_write(), medialeaf::media, media_cap, MediaIs100, MediaIsMII, tulip_private::mii_advertise, tulip_private::mii_cnt, mediatable::mleaf, tulip_private::mtable, MX98713, MX98715, MX98725, tulip_private::nic_name, tulip_private::nway, nway_start(), tulip_private::nwayset, outl, tulip_private::phys, PNIC2, printf(), tulip_private::saved_if_port, select_media(), tulip_private::sym_advertise, and whereami().
Referenced by tulip_probe().
01449 { 01450 int i; 01451 01452 #ifdef TULIP_DEBUG_WHERE 01453 whereami("start_link\n"); 01454 #endif 01455 01456 if ((tp->flags & ALWAYS_CHECK_MII) || 01457 (tp->mtable && tp->mtable->has_mii) || 01458 ( ! tp->mtable && (tp->flags & HAS_MII))) { 01459 unsigned int phy, phy_idx; 01460 if (tp->mtable && tp->mtable->has_mii) { 01461 for (i = 0; i < tp->mtable->leafcount; i++) 01462 if (tp->mtable->mleaf[i].media == 11) { 01463 tp->cur_index = i; 01464 tp->saved_if_port = tp->if_port; 01465 select_media(nic, 2); 01466 tp->if_port = tp->saved_if_port; 01467 break; 01468 } 01469 } 01470 01471 /* Find the connected MII xcvrs. */ 01472 for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys); 01473 phy++) { 01474 int mii_status = mdio_read(nic, phy, 1); 01475 if ((mii_status & 0x8301) == 0x8001 || 01476 ((mii_status & 0x8000) == 0 && (mii_status & 0x7800) != 0)) { 01477 int mii_reg0 = mdio_read(nic, phy, 0); 01478 int mii_advert = mdio_read(nic, phy, 4); 01479 int to_advert; 01480 01481 if (tp->mii_advertise) 01482 to_advert = tp->mii_advertise; 01483 else if (tp->advertising[phy_idx]) 01484 to_advert = tp->advertising[phy_idx]; 01485 else /* Leave unchanged. */ 01486 tp->mii_advertise = to_advert = mii_advert; 01487 01488 tp->phys[phy_idx++] = phy; 01489 printf("%s: MII transceiver %d config %hX status %hX advertising %hX.\n", 01490 tp->nic_name, phy, mii_reg0, mii_status, mii_advert); 01491 /* Fixup for DLink with miswired PHY. */ 01492 if (mii_advert != to_advert) { 01493 printf("%s: Advertising %hX on PHY %d previously advertising %hX.\n", 01494 tp->nic_name, to_advert, phy, mii_advert); 01495 mdio_write(nic, phy, 4, to_advert); 01496 } 01497 /* Enable autonegotiation: some boards default to off. */ 01498 mdio_write(nic, phy, 0, mii_reg0 | 01499 (tp->full_duplex ? 0x1100 : 0x1000) | 01500 (media_cap[tp->default_port]&MediaIs100 ? 0x2000:0)); 01501 } 01502 } 01503 tp->mii_cnt = phy_idx; 01504 if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) { 01505 printf("%s: ***WARNING***: No MII transceiver found!\n", 01506 tp->nic_name); 01507 tp->phys[0] = 1; 01508 } 01509 } 01510 01511 /* Reset the xcvr interface and turn on heartbeat. */ 01512 switch (tp->chip_id) { 01513 case DC21040: 01514 outl(0x00000000, ioaddr + CSR13); 01515 outl(0x00000004, ioaddr + CSR13); 01516 break; 01517 case DC21041: 01518 /* This is nway_start(). */ 01519 if (tp->sym_advertise == 0) 01520 tp->sym_advertise = 0x0061; 01521 outl(0x00000000, ioaddr + CSR13); 01522 outl(0xFFFFFFFF, ioaddr + CSR14); 01523 outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ 01524 outl(inl(ioaddr + CSR6) | 0x0200, ioaddr + CSR6); 01525 outl(0x0000EF01, ioaddr + CSR13); 01526 break; 01527 case DC21140: default: 01528 if (tp->mtable) 01529 outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12); 01530 break; 01531 case DC21142: 01532 case PNIC2: 01533 if (tp->mii_cnt || media_cap[tp->if_port] & MediaIsMII) { 01534 outl(0x82020000, ioaddr + CSR6); 01535 outl(0x0000, ioaddr + CSR13); 01536 outl(0x0000, ioaddr + CSR14); 01537 outl(0x820E0000, ioaddr + CSR6); 01538 } else 01539 nway_start(nic); 01540 break; 01541 case LC82C168: 01542 if ( ! tp->mii_cnt) { 01543 tp->nway = 1; 01544 tp->nwayset = 0; 01545 outl(0x00420000, ioaddr + CSR6); 01546 outl(0x30, ioaddr + CSR12); 01547 outl(0x0001F078, ioaddr + 0xB8); 01548 outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */ 01549 } 01550 break; 01551 case MX98713: case COMPEX9881: 01552 outl(0x00000000, ioaddr + CSR6); 01553 outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */ 01554 outl(0x00000001, ioaddr + CSR13); 01555 break; 01556 case MX98715: case MX98725: 01557 outl(0x01a80000, ioaddr + CSR6); 01558 outl(0xFFFFFFFF, ioaddr + CSR14); 01559 outl(0x00001000, ioaddr + CSR12); 01560 break; 01561 case COMET: 01562 /* No initialization necessary. */ 01563 break; 01564 } 01565 }
| static int tulip_check_duplex | ( | struct nic * | nic | ) | [static] |
Definition at line 1995 of file tulip.c.
References tulip_private::advertising, tulip_private::csr6, tulip_private::full_duplex, mdio_read(), tulip_private::nic_name, tulip_private::phys, and printf().
Referenced by tulip_reset().
01996 { 01997 unsigned int bmsr, lpa, negotiated, new_csr6; 01998 01999 bmsr = mdio_read(nic, tp->phys[0], 1); 02000 lpa = mdio_read(nic, tp->phys[0], 5); 02001 02002 #ifdef TULIP_DEBUG 02003 if (tulip_debug > 1) 02004 printf("%s: MII status %#x, Link partner report " 02005 "%#x.\n", tp->nic_name, bmsr, lpa); 02006 #endif 02007 02008 if (bmsr == 0xffff) 02009 return -2; 02010 if ((bmsr & 4) == 0) { 02011 int new_bmsr = mdio_read(nic, tp->phys[0], 1); 02012 if ((new_bmsr & 4) == 0) { 02013 #ifdef TULIP_DEBUG 02014 if (tulip_debug > 1) 02015 printf("%s: No link beat on the MII interface," 02016 " status %#x.\n", tp->nic_name, 02017 new_bmsr); 02018 #endif 02019 return -1; 02020 } 02021 } 02022 tp->full_duplex = lpa & 0x140; 02023 02024 new_csr6 = tp->csr6; 02025 negotiated = lpa & tp->advertising[0]; 02026 02027 if(negotiated & 0x380) new_csr6 &= ~0x400000; 02028 else new_csr6 |= 0x400000; 02029 if (tp->full_duplex) new_csr6 |= 0x200; 02030 else new_csr6 &= ~0x200; 02031 02032 if (new_csr6 != tp->csr6) { 02033 tp->csr6 = new_csr6; 02034 02035 #ifdef TULIP_DEBUG 02036 if (tulip_debug > 0) 02037 printf("%s: Setting %s-duplex based on MII" 02038 "#%d link partner capability of %#x.\n", 02039 tp->nic_name, 02040 tp->full_duplex ? "full" : "half", 02041 tp->phys[0], lpa); 02042 #endif 02043 return 1; 02044 } 02045 02046 return 0; 02047 }
| static void tulip_wait | ( | unsigned int | nticks | ) | [static] |
Definition at line 545 of file tulip.c.
References currticks().
Referenced by tulip_probe(), and tulip_reset().
00546 { 00547 unsigned int to = currticks() + nticks; 00548 while (currticks() < to) 00549 /* wait */ ; 00550 }
Definition at line 582 of file tulip.c.
References pcnet32_private::a, tulip_private::chip_id, COMET, CSR9, inl, ioaddr, LC82C168, MDIO_DATA_READ, MDIO_DATA_WRITE1, mdio_delay, MDIO_ENB, MDIO_ENB_IN, MDIO_SHIFT_CLK, pcnet32_private::mii, outl, pcnet32_access::read_bcr, u16, whereami(), and pcnet32_access::write_bcr.
00583 { 00584 int i; 00585 int read_cmd = (0xf6 << 10) | (phy_id << 5) | location; 00586 int retval = 0; 00587 long mdio_addr = ioaddr + CSR9; 00588 00589 #ifdef TULIP_DEBUG_WHERE 00590 whereami("mdio_read\n"); 00591 #endif 00592 00593 if (tp->chip_id == LC82C168) { 00594 int i = 1000; 00595 outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0); 00596 inl(ioaddr + 0xA0); 00597 inl(ioaddr + 0xA0); 00598 while (--i > 0) 00599 if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000)) 00600 return retval & 0xffff; 00601 return 0xffff; 00602 } 00603 00604 if (tp->chip_id == COMET) { 00605 if (phy_id == 1) { 00606 if (location < 7) 00607 return inl(ioaddr + 0xB4 + (location<<2)); 00608 else if (location == 17) 00609 return inl(ioaddr + 0xD0); 00610 else if (location >= 29 && location <= 31) 00611 return inl(ioaddr + 0xD4 + ((location-29)<<2)); 00612 } 00613 return 0xffff; 00614 } 00615 00616 /* Establish sync by sending at least 32 logic ones. */ 00617 for (i = 32; i >= 0; i--) { 00618 outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr); 00619 mdio_delay(); 00620 outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr); 00621 mdio_delay(); 00622 } 00623 /* Shift the read command bits out. */ 00624 for (i = 15; i >= 0; i--) { 00625 int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0; 00626 00627 outl(MDIO_ENB | dataval, mdio_addr); 00628 mdio_delay(); 00629 outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr); 00630 mdio_delay(); 00631 } 00632 /* Read the two transition, 16 data, and wire-idle bits. */ 00633 for (i = 19; i > 0; i--) { 00634 outl(MDIO_ENB_IN, mdio_addr); 00635 mdio_delay(); 00636 retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0); 00637 outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); 00638 mdio_delay(); 00639 } 00640 return (retval>>1) & 0xffff; 00641 }
Definition at line 643 of file tulip.c.
References tulip_private::chip_id, COMET, CSR9, inl, ioaddr, LC82C168, MDIO_DATA_WRITE1, mdio_delay, MDIO_ENB, MDIO_ENB_IN, MDIO_SHIFT_CLK, outl, and whereami().
00644 { 00645 int i; 00646 int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value; 00647 long mdio_addr = ioaddr + CSR9; 00648 00649 #ifdef TULIP_DEBUG_WHERE 00650 whereami("mdio_write\n"); 00651 #endif 00652 00653 if (tp->chip_id == LC82C168) { 00654 int i = 1000; 00655 outl(cmd, ioaddr + 0xA0); 00656 do 00657 if ( ! (inl(ioaddr + 0xA0) & 0x80000000)) 00658 break; 00659 while (--i > 0); 00660 return; 00661 } 00662 00663 if (tp->chip_id == COMET) { 00664 if (phy_id != 1) 00665 return; 00666 if (location < 7) 00667 outl(value, ioaddr + 0xB4 + (location<<2)); 00668 else if (location == 17) 00669 outl(value, ioaddr + 0xD0); 00670 else if (location >= 29 && location <= 31) 00671 outl(value, ioaddr + 0xD4 + ((location-29)<<2)); 00672 return; 00673 } 00674 00675 /* Establish sync by sending 32 logic ones. */ 00676 for (i = 32; i >= 0; i--) { 00677 outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr); 00678 mdio_delay(); 00679 outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr); 00680 mdio_delay(); 00681 } 00682 /* Shift the command bits out. */ 00683 for (i = 31; i >= 0; i--) { 00684 int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0; 00685 outl(MDIO_ENB | dataval, mdio_addr); 00686 mdio_delay(); 00687 outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr); 00688 mdio_delay(); 00689 } 00690 /* Clear out extra bits. */ 00691 for (i = 2; i > 0; i--) { 00692 outl(MDIO_ENB_IN, mdio_addr); 00693 mdio_delay(); 00694 outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); 00695 mdio_delay(); 00696 } 00697 }
Definition at line 916 of file tulip.c.
References BUFLEN, cpu_to_le32, tulip_private::cur_rx, DESC_RING_WRAP, rx_ring, RX_RING_SIZE, rxb, tx_ring, txb, virt_to_le32desc, and whereami().
00917 { 00918 int i; 00919 00920 #ifdef TULIP_DEBUG_WHERE 00921 whereami("tulip_init_ring\n"); 00922 #endif 00923 00924 tp->cur_rx = 0; 00925 00926 for (i = 0; i < RX_RING_SIZE; i++) { 00927 rx_ring[i].status = cpu_to_le32(0x80000000); 00928 rx_ring[i].length = cpu_to_le32(BUFLEN); 00929 rx_ring[i].buffer1 = virt_to_le32desc(&rxb[i * BUFLEN]); 00930 rx_ring[i].buffer2 = virt_to_le32desc(&rx_ring[i+1]); 00931 } 00932 /* Mark the last entry as wrapping the ring. */ 00933 rx_ring[i-1].length = cpu_to_le32(DESC_RING_WRAP | BUFLEN); 00934 rx_ring[i-1].buffer2 = virt_to_le32desc(&rx_ring[0]); 00935 00936 /* We only use 1 transmit buffer, but we use 2 descriptors so 00937 transmit engines have somewhere to point to if they feel the need */ 00938 00939 tx_ring[0].status = 0x00000000; 00940 tx_ring[0].buffer1 = virt_to_le32desc(&txb[0]); 00941 tx_ring[0].buffer2 = virt_to_le32desc(&tx_ring[1]); 00942 00943 /* this descriptor should never get used, since it will never be owned 00944 by the machine (status will always == 0) */ 00945 tx_ring[1].status = 0x00000000; 00946 tx_ring[1].buffer1 = virt_to_le32desc(&txb[0]); 00947 tx_ring[1].buffer2 = virt_to_le32desc(&tx_ring[0]); 00948 00949 /* Mark the last entry as wrapping the ring, though this should never happen */ 00950 tx_ring[1].length = cpu_to_le32(DESC_RING_WRAP | BUFLEN); 00951 }
Definition at line 954 of file tulip.c.
References AcceptAllMulticast, tulip_private::csr6, CSR6, inl, ioaddr, and outl.
00954 { 00955 int csr6 = inl(ioaddr + CSR6) & ~0x00D5; 00956 00957 tp->csr6 &= ~0x00D5; 00958 00959 /* !IFF_PROMISC */ 00960 tp->csr6 |= AcceptAllMulticast; 00961 csr6 |= AcceptAllMulticast; 00962 00963 outl(csr6, ioaddr + CSR6); 00964 00965 00966 00967 }
| static void tulip_irq | ( | struct nic *nic | __unused, | |
| irq_action_t action | __unused | |||
| ) | [static] |
Definition at line 1567 of file tulip.c.
References tulip_private::chip_id, CSR12, CSR13, CSR14, CSR15, mediatable::csr15dir, mediatable::csr15val, CSR6, tulip_private::csr6, DC21041, tulip_private::if_port, ioaddr, tulip_private::lpar, tulip_private::mediasense, tulip_private::mtable, tulip_private::nic_name, tulip_private::nway, tulip_private::nwayset, outl, outw, PNIC2, printf(), tulip_private::sym_advertise, and whereami().
01568 { 01569 int csr14 = ((tp->sym_advertise & 0x0780) << 9) | 01570 ((tp->sym_advertise&0x0020)<<1) | 0xffbf; 01571 01572 #ifdef TULIP_DEBUG_WHERE 01573 whereami("nway_start\n"); 01574 #endif 01575 01576 tp->if_port = 0; 01577 tp->nway = tp->mediasense = 1; 01578 tp->nwayset = tp->lpar = 0; 01579 if (tp->chip_id == PNIC2) { 01580 tp->csr6 = 0x01000000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0); 01581 return; 01582 } 01583 #ifdef TULIP_DEBUG 01584 if (tulip_debug > 1) 01585 printf("%s: Restarting internal NWay autonegotiation, %X.\n", 01586 tp->nic_name, csr14); 01587 #endif 01588 outl(0x0001, ioaddr + CSR13); 01589 outl(csr14, ioaddr + CSR14); 01590 tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0); 01591 outl(tp->csr6, ioaddr + CSR6); 01592 if (tp->mtable && tp->mtable->csr15dir) { 01593 outl(tp->mtable->csr15dir, ioaddr + CSR15); 01594 outl(tp->mtable->csr15val, ioaddr + CSR15); 01595 } else if (tp->chip_id != PNIC2) 01596 outw(0x0008, ioaddr + CSR15); 01597 if (tp->chip_id == DC21041) /* Trigger NWAY. */ 01598 outl(0xEF01, ioaddr + CSR12); 01599 else 01600 outl(0x1301, ioaddr + CSR12); 01601 }
Definition at line 1723 of file tulip.c.
References CSR12, CSR6, tulip_private::csr6, tulip_private::full_duplex, tulip_private::if_port, inl, ioaddr, medianame, tulip_private::nic_name, tulip_private::nwayset, outl, printf(), u32, and whereami().
01724 { 01725 u32 phy_reg = inl(ioaddr + 0xB8); 01726 u32 new_csr6 = tp->csr6 & ~0x40C40200; 01727 01728 #ifdef TULIP_DEBUG_WHERE 01729 whereami("pnic_do_nway\n"); 01730 #endif 01731 01732 if (phy_reg & 0x78000000) { /* Ignore baseT4 */ 01733 if (phy_reg & 0x20000000) tp->if_port = 5; 01734 else if (phy_reg & 0x40000000) tp->if_port = 3; 01735 else if (phy_reg & 0x10000000) tp->if_port = 4; 01736 else if (phy_reg & 0x08000000) tp->if_port = 0; 01737 tp->nwayset = 1; 01738 new_csr6 = (tp->if_port & 1) ? 0x01860000 : 0x00420000; 01739 outl(0x32 | (tp->if_port & 1), ioaddr + CSR12); 01740 if (tp->if_port & 1) 01741 outl(0x1F868, ioaddr + 0xB8); 01742 if (phy_reg & 0x30000000) { 01743 tp->full_duplex = 1; 01744 new_csr6 |= 0x00000200; 01745 } 01746 #ifdef TULIP_DEBUG 01747 if (tulip_debug > 1) 01748 printf("%s: PNIC autonegotiated status %X, %s.\n", 01749 tp->nic_name, phy_reg, medianame[tp->if_port]); 01750 #endif 01751 if (tp->csr6 != new_csr6) { 01752 tp->csr6 = new_csr6; 01753 outl(tp->csr6 | 0x0002, ioaddr + CSR6); /* Restart Tx */ 01754 outl(tp->csr6 | 0x2002, ioaddr + CSR6); 01755 } 01756 } 01757 }
| PCI_DRIVER | ( | tulip_driver | , | |
| tulip_nics | , | |||
| PCI_NO_CLASS | ||||
| ) |
| DRIVER | ( | "Tulip" | , | |
| nic_driver | , | |||
| pci_driver | , | |||
| tulip_driver | , | |||
| tulip_probe | , | |||
| tulip_disable | ||||
| ) |
const int csr0 = 0x01A00000 | 0x8000 [static] |
const char* const medianame[32] [static] |
Initial value:
{
"10baseT", "10base2", "AUI", "100baseTx",
"10baseT-FDX", "100baseTx-FDX", "100baseT4", "100baseFx",
"100baseFx-FDX", "MII 10baseT", "MII 10baseT-FDX", "MII",
"10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FDX", "MII 100baseT4",
"MII 100baseFx-HDX", "MII 100baseFx-FDX", "Home-PNA 1Mbps", "Invalid-19",
}
Definition at line 147 of file tulip.c.
Referenced by init_media(), parse_eeprom(), pnic_do_nway(), and select_media().
struct pci_id_info pci_id_tbl[] [static] |
struct tulip_chip_table tulip_tbl[] [static] |
Referenced by tulip_probe().
const char media_cap[32] [static] |
Initial value:
{0,0,0,16, 3,19,16,24, 27,4,7,5, 0,20,23,20, 20,31,0,0, }
Definition at line 281 of file tulip.c.
Referenced by init_media(), select_media(), start_link(), and tulip_probe().
u8 t21040_csr13[] = {2,0x0C,8,4, 4,0,0,0, 0,0,0,0, 4,0,0,0} [static] |
u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, } [static] |
u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, } [static] |
u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, } [static] |
u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, } [static] |
| struct tulip_tx_desc tx_ring[TX_RING_SIZE] |
| struct tulip_rx_desc rx_ring[RX_RING_SIZE] |
| struct tulip_private tpx |
| struct { ... } __shared |
struct tulip_private* tp [static] |
Definition at line 447 of file tulip.c.
Referenced by __mdio_read(), __mdio_write(), rhine_disable(), rhine_init_ring(), rhine_irq(), rhine_poll(), rhine_probe(), rhine_probe1(), rhine_reset(), rhine_transmit(), rtl8169_close(), rtl8169_irq(), rtl8169_open(), rtl8169_poll(), rtl8169_probe(), rtl8169_process_rx_packets(), rtl8169_process_tx_packets(), rtl8169_remove(), rtl8169_set_speed(), rtl8169_set_speed_tbi(), rtl8169_set_speed_xmii(), rtl8169_transmit(), rtl_disable_clock_request(), rtl_hw_phy_config(), rtl_hw_start(), rtl_hw_start_8101(), rtl_hw_start_8168(), rtl_hw_start_8169(), rtl_set_rx_mode(), rtl_soft_reset(), rtl_tx_performance_tweak(), set_rx_mode(), sis190_down(), sis190_free(), sis190_get_mac_addr_from_apc(), sis190_get_mac_addr_from_eeprom(), sis190_hw_start(), sis190_init_board(), sis190_init_ring(), sis190_init_rxfilter(), sis190_irq(), sis190_mii_probe(), sis190_mii_remove(), sis190_open(), sis190_poll(), sis190_probe(), sis190_remove(), sis190_set_rx_mode(), sis190_set_speed_auto(), sis190_transmit(), sky2_ramset(), and tg3_poll().
struct fixups eeprom_fixups[] [static] |
Referenced by parse_eeprom().
const char* block_name[] [static] |
struct nic_operations tulip_operations [static] |
Initial value:
{
.connect = dummy_connect,
.poll = tulip_poll,
.transmit = tulip_transmit,
.irq = tulip_irq,
}
struct pci_device_id tulip_nics[] [static] |
1.5.7.1