176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/************************************************************************** 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* mtd80x.c: Etherboot device driver for the mtd80x Ethernet chip. 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* Written 2004-2004 by Erdem Güven <zuencap@yahoo.com> 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* This program is free software; you can redistribute it and/or modify 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* it under the terms of the GNU General Public License as published by 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* the Free Software Foundation; either version 2 of the License, or 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* (at your option) any later version. 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* This program is distributed in the hope that it will be useful, 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* but WITHOUT ANY WARRANTY; without even the implied warranty of 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* GNU General Public License for more details. 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* You should have received a copy of the GNU General Public License 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* along with this program; if not, write to the Free Software 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* Portions of this code based on: 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* fealnx.c: A Linux device driver for the mtd80x Ethernet chip 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* Written 1998-2000 by Donald Becker 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman* 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman***************************************************************************/ 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2676d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL2_OR_LATER ); 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* to get some global routines like printf */ 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "etherboot.h" 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* to get the interface to the body of the program */ 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "nic.h" 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* to get the PCI support functions, if this is a PCI NIC */ 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/pci.h> 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/ethernet.h> 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <mii.h> 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Condensed operations for readability. */ 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define get_unaligned(ptr) (*(ptr)) 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Operational parameters that are set at compile time. */ 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Keep the ring sizes a power of two for compile efficiency. */ 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* The compiler will convert <unsigned>'%'<2^N> into a bit mask. */ 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Making the Tx ring too large decreases the effectiveness of channel */ 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* bonding and packet priority. */ 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* There are no ill effects from too-large receive rings. */ 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TX_RING_SIZE 2 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */ 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define RX_RING_SIZE 4 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Operational parameters that usually are not changed. */ 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Time in jiffies before concluding the transmitter is hung. */ 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define HZ 100 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TX_TIME_OUT (6*HZ) 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Allocation size of Rx buffers with normal sized Ethernet frames. 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Do not change this value without good reason. This is not a limit, 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman but a way to keep a consistent allocation size among drivers. 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PKT_BUF_SZ 1536 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* for different PHY */ 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum phy_type_flags { 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman MysonPHY = 1, 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman AhdocPHY = 2, 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman SeeqPHY = 3, 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman MarvellPHY = 4, 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Myson981 = 5, 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LevelOnePHY = 6, 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman OtherPHY = 10, 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* A chip capabilities table*/ 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum chip_capability_flags { 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman HAS_MII_XCVR, 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman HAS_CHIP_XCVR, 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if 0 /* not used */ 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct chip_info 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 dev_id; 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int flag; 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanmtd80x_chips[] = { 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x0800, HAS_MII_XCVR}, 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x0803, HAS_CHIP_XCVR}, 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman {0x0891, HAS_MII_XCVR} 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman }; 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int chip_cnt = sizeof( mtd80x_chips ) / sizeof( struct chip_info ); 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Offsets to the Command and Status Registers. */ 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum mtd_offsets { 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PAR0 = 0x0, /* physical address 0-3 */ 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PAR1 = 0x04, /* physical address 4-5 */ 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman MAR0 = 0x08, /* multicast address 0-3 */ 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman MAR1 = 0x0C, /* multicast address 4-7 */ 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman FAR0 = 0x10, /* flow-control address 0-3 */ 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman FAR1 = 0x14, /* flow-control address 4-5 */ 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TCRRCR = 0x18, /* receive & transmit configuration */ 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman BCR = 0x1C, /* bus command */ 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TXPDR = 0x20, /* transmit polling demand */ 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RXPDR = 0x24, /* receive polling demand */ 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RXCWP = 0x28, /* receive current word pointer */ 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TXLBA = 0x2C, /* transmit list base address */ 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RXLBA = 0x30, /* receive list base address */ 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ISR = 0x34, /* interrupt status */ 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman IMR = 0x38, /* interrupt mask */ 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman FTH = 0x3C, /* flow control high/low threshold */ 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman MANAGEMENT = 0x40, /* bootrom/eeprom and mii management */ 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TALLY = 0x44, /* tally counters for crc and mpa */ 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TSR = 0x48, /* tally counter for transmit status */ 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman BMCRSR = 0x4c, /* basic mode control and status */ 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PHYIDENTIFIER = 0x50, /* phy identifier */ 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ANARANLPAR = 0x54, /* auto-negotiation advertisement and link 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman partner ability */ 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ANEROCR = 0x58, /* auto-negotiation expansion and pci conf. */ 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman BPREMRPSR = 0x5c, /* bypass & receive error mask and phy status */ 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Bits in the interrupt status/enable registers. */ 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* The bits in the Intr Status/Enable registers, mostly interrupt sources. */ 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum intr_status_bits { 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RFCON = 0x00020000, /* receive flow control xon packet */ 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RFCOFF = 0x00010000, /* receive flow control xoff packet */ 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LSCStatus = 0x00008000, /* link status change */ 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ANCStatus = 0x00004000, /* autonegotiation completed */ 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman FBE = 0x00002000, /* fatal bus error */ 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman FBEMask = 0x00001800, /* mask bit12-11 */ 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ParityErr = 0x00000000, /* parity error */ 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TargetErr = 0x00001000, /* target abort */ 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman MasterErr = 0x00000800, /* master error */ 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TUNF = 0x00000400, /* transmit underflow */ 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ROVF = 0x00000200, /* receive overflow */ 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ETI = 0x00000100, /* transmit early int */ 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ERI = 0x00000080, /* receive early int */ 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman CNTOVF = 0x00000040, /* counter overflow */ 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RBU = 0x00000020, /* receive buffer unavailable */ 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TBU = 0x00000010, /* transmit buffer unavilable */ 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TI = 0x00000008, /* transmit interrupt */ 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RI = 0x00000004, /* receive interrupt */ 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RxErr = 0x00000002, /* receive error */ 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Bits in the NetworkConfig register. */ 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum rx_mode_bits { 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RxModeMask = 0xe0, 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman AcceptAllPhys = 0x80, /* promiscuous mode */ 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman AcceptBroadcast = 0x40, /* accept broadcast */ 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman AcceptMulticast = 0x20, /* accept mutlicast */ 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman AcceptRunt = 0x08, /* receive runt pkt */ 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ALP = 0x04, /* receive long pkt */ 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman AcceptErr = 0x02, /* receive error pkt */ 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman AcceptMyPhys = 0x00000000, 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RxEnable = 0x00000001, 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RxFlowCtrl = 0x00002000, 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TxEnable = 0x00040000, 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TxModeFDX = 0x00100000, 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TxThreshold = 0x00e00000, 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PS1000 = 0x00010000, 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PS10 = 0x00080000, 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman FD = 0x00100000, 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Bits in network_desc.status */ 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum rx_desc_status_bits { 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RXOWN = 0x80000000, /* own bit */ 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman FLNGMASK = 0x0fff0000, /* frame length */ 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman FLNGShift = 16, 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman MARSTATUS = 0x00004000, /* multicast address received */ 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman BARSTATUS = 0x00002000, /* broadcast address received */ 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PHYSTATUS = 0x00001000, /* physical address received */ 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RXFSD = 0x00000800, /* first descriptor */ 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RXLSD = 0x00000400, /* last descriptor */ 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ErrorSummary = 0x80, /* error summary */ 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RUNT = 0x40, /* runt packet received */ 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LONG = 0x20, /* long packet received */ 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman FAE = 0x10, /* frame align error */ 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman CRC = 0x08, /* crc error */ 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RXER = 0x04, /* receive error */ 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum rx_desc_control_bits { 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RXIC = 0x00800000, /* interrupt control */ 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RBSShift = 0, 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum tx_desc_status_bits { 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TXOWN = 0x80000000, /* own bit */ 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman JABTO = 0x00004000, /* jabber timeout */ 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman CSL = 0x00002000, /* carrier sense lost */ 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman LC = 0x00001000, /* late collision */ 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman EC = 0x00000800, /* excessive collision */ 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman UDF = 0x00000400, /* fifo underflow */ 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DFR = 0x00000200, /* deferred */ 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman HF = 0x00000100, /* heartbeat fail */ 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman NCRMask = 0x000000ff, /* collision retry count */ 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman NCRShift = 0, 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanenum tx_desc_control_bits { 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TXIC = 0x80000000, /* interrupt control */ 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ETIControl = 0x40000000, /* early transmit interrupt */ 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TXLD = 0x20000000, /* last descriptor */ 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TXFD = 0x10000000, /* first descriptor */ 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman CRCEnable = 0x08000000, /* crc control */ 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PADEnable = 0x04000000, /* padding control */ 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman RetryTxLC = 0x02000000, /* retry late collision */ 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PKTSMask = 0x3ff800, /* packet size bit21-11 */ 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PKTSShift = 11, 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TBSMask = 0x000007ff, /* transmit buffer bit 10-0 */ 21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TBSShift = 0, 22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* BootROM/EEPROM/MII Management Register */ 22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MASK_MIIR_MII_READ 0x00000000 22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MASK_MIIR_MII_WRITE 0x00000008 22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MASK_MIIR_MII_MDO 0x00000004 22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MASK_MIIR_MII_MDI 0x00000002 22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MASK_MIIR_MII_MDC 0x00000001 22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* ST+OP+PHYAD+REGAD+TA */ 23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define OP_READ 0x6000 /* ST:01+OP:10+PHYAD+REGAD+TA:Z0 */ 23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define OP_WRITE 0x5002 /* ST:01+OP:01+PHYAD+REGAD+TA:10 */ 23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* ------------------------------------------------------------------------- */ 23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Constants for Myson PHY */ 23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* ------------------------------------------------------------------------- */ 23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MysonPHYID 0xd0000302 23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 89-7-27 add, (begin) */ 23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MysonPHYID0 0x0302 23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define StatusRegister 18 24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define SPEED100 0x0400 // bit10 24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FULLMODE 0x0800 // bit11 24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 89-7-27 add, (end) */ 24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* ------------------------------------------------------------------------- */ 24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Constants for Seeq 80225 PHY */ 24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* ------------------------------------------------------------------------- */ 24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define SeeqPHYID0 0x0016 24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MIIRegister18 18 25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define SPD_DET_100 0x80 25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define DPLX_DET_FULL 0x40 25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* ------------------------------------------------------------------------- */ 25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Constants for Ahdoc 101 PHY */ 25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* ------------------------------------------------------------------------- */ 25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define AhdocPHYID0 0x0022 25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define DiagnosticReg 18 25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define DPLX_FULL 0x0800 26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define Speed_100 0x0400 26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 89/6/13 add, */ 26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* -------------------------------------------------------------------------- */ 26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Constants */ 26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* -------------------------------------------------------------------------- */ 26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MarvellPHYID0 0x0141 26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LevelOnePHYID0 0x0013 26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MII1000BaseTControlReg 9 27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MII1000BaseTStatusReg 10 27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define SpecificReg 17 27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* for 1000BaseT Control Register */ 27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PHYAbletoPerform1000FullDuplex 0x0200 27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PHYAbletoPerform1000HalfDuplex 0x0100 27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PHY1000AbilityMask 0x300 27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman// for phy specific status register, marvell phy. 27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define SpeedMask 0x0c000 28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define Speed_1000M 0x08000 28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define Speed_100M 0x4000 28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define Speed_10M 0 28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define Full_Duplex 0x2000 28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman// 89/12/29 add, for phy specific status register, levelone phy, (begin) 28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LXT1000_100M 0x08000 28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LXT1000_1000M 0x0c000 28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LXT1000_Full 0x200 28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman// 89/12/29 add, for phy specific status register, levelone phy, (end) 29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if 0 29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* for 3-in-1 case */ 29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PS10 0x00080000 29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define FD 0x00100000 29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PS1000 0x00010000 29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* for PHY */ 29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LinkIsUp 0x0004 30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LinkIsUp2 0x00040000 30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Create a static buffer of size PKT_BUF_SZ for each 30376d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanRX and TX Descriptor. All descriptors point to a 30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpart of this buffer */ 30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct { 30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u8 txb[PKT_BUF_SZ * TX_RING_SIZE] __attribute__ ((aligned(8))); 30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u8 rxb[PKT_BUF_SZ * RX_RING_SIZE] __attribute__ ((aligned(8))); 30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} mtd80x_bufs __shared; 30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define txb mtd80x_bufs.txb 31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define rxb mtd80x_bufs.rxb 31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* The Tulip Rx and Tx buffer descriptors. */ 31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct mtd_desc 31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s32 status; 31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s32 control; 31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 buffer; 31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 next_desc; 31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct mtd_desc *next_desc_logical; 32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u8* skbuff; 32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 reserved1; 32276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 reserved2; 32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct mtd_private 32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct mtd_desc rx_ring[RX_RING_SIZE]; 32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct mtd_desc tx_ring[TX_RING_SIZE]; 32976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 33076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Frequently used values: keep some adjacent for cache effect. */ 33176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int flags; 33276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct pci_dev *pci_dev; 33376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned long crvalue; 33476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned long bcrvalue; 33576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /*unsigned long imrvalue;*/ 33676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct mtd_desc *cur_rx; 33776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct mtd_desc *lack_rxbuf; 33876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int really_rx_count; 33976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct mtd_desc *cur_tx; 34076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct mtd_desc *cur_tx_copy; 34176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int really_tx_count; 34276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int free_tx_count; 34376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int rx_buf_sz; /* Based on MTU+slack. */ 34476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 34576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* These values are keep track of the transceiver/media in use. */ 34676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int linkok; 34776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int line_speed; 34876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int duplexmode; 34976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int default_port: 35076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4; /* Last dev->if_port value. */ 35176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int PHYType; 35276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 35376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* MII transceiver section. */ 35476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int mii_cnt; /* MII device addresses. */ 35576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned char phys[1]; /* MII device addresses. */ 35676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 35776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /*other*/ 35876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char *nic_name; 35976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int ioaddr; 36076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u16 dev_id; 36176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 36276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 36376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct mtd_private mtdx; 36476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 36576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int mdio_read(struct nic * , int phy_id, int location); 36676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void getlinktype(struct nic * ); 36776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void getlinkstatus(struct nic * ); 36876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void set_rx_mode(struct nic *); 36976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 37076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/************************************************************************** 37176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * init_ring - setup the tx and rx descriptors 37276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *************************************************************************/ 37376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void init_ring(struct nic *nic __unused) 37476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 37576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i; 37676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 37776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.cur_rx = &mtdx.rx_ring[0]; 37876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 37976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.rx_buf_sz = PKT_BUF_SZ; 38076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /*mtdx.rx_head_desc = &mtdx.rx_ring[0];*/ 38176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 38276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Initialize all Rx descriptors. */ 38376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Fill in the Rx buffers. Handle allocation failure gracefully. */ 38476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < RX_RING_SIZE; i++) 38576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 38676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.rx_ring[i].status = RXOWN; 38776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.rx_ring[i].control = mtdx.rx_buf_sz << RBSShift; 38876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.rx_ring[i].next_desc = virt_to_le32desc(&mtdx.rx_ring[i+1]); 38976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.rx_ring[i].next_desc_logical = &mtdx.rx_ring[i+1]; 39076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.rx_ring[i].buffer = virt_to_le32desc(&rxb[i * PKT_BUF_SZ]); 39176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.rx_ring[i].skbuff = &rxb[i * PKT_BUF_SZ]; 39276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 39376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Mark the last entry as wrapping the ring. */ 39476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.rx_ring[i-1].next_desc = virt_to_le32desc(&mtdx.rx_ring[0]); 39576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.rx_ring[i-1].next_desc_logical = &mtdx.rx_ring[0]; 39676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 39776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* We only use one transmit buffer, but two 39876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * descriptors so transmit engines have somewhere 39976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * to point should they feel the need */ 40076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.tx_ring[0].status = 0x00000000; 40176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.tx_ring[0].buffer = virt_to_bus(&txb[0]); 40276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.tx_ring[0].next_desc = virt_to_le32desc(&mtdx.tx_ring[1]); 40376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 40476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* This descriptor is never used */ 40576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.tx_ring[1].status = 0x00000000; 40676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.tx_ring[1].buffer = 0; /*virt_to_bus(&txb[1]); */ 40776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.tx_ring[1].next_desc = virt_to_le32desc(&mtdx.tx_ring[0]); 40876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 40976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 41076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 41176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 41276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/************************************************************************** 41376d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanRESET - Reset Adapter 41476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman***************************************************************************/ 41576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void mtd_reset( struct nic *nic ) 41676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 41776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Reset the chip to erase previous misconfiguration. */ 41876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(0x00000001, mtdx.ioaddr + BCR); 41976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 42076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman init_ring(nic); 42176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 42276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(virt_to_bus(mtdx.rx_ring), mtdx.ioaddr + RXLBA); 42376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(virt_to_bus(mtdx.tx_ring), mtdx.ioaddr + TXLBA); 42476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 42576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Initialize other registers. */ 42676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Configure the PCI bus bursts and FIFO thresholds. */ 42776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.bcrvalue = 0x10; /* little-endian, 8 burst length */ 42876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.crvalue = 0xa00; /* rx 128 burst length */ 42976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 43076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( mtdx.dev_id == 0x891 ) { 43176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.bcrvalue |= 0x200; /* set PROG bit */ 43276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.crvalue |= 0x02000000; /* set enhanced bit */ 43376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 43476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 43576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl( mtdx.bcrvalue, mtdx.ioaddr + BCR); 43676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 43776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Restart Rx engine if stopped. */ 43876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(0, mtdx.ioaddr + RXPDR); 43976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 44076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman getlinkstatus(nic); 44176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mtdx.linkok) 44276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 44376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman static const char* texts[]={"half","full","10","100","1000"}; 44476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman getlinktype(nic); 44576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "Link is OK : %s %s\n", texts[mtdx.duplexmode-1], texts[mtdx.line_speed+1] ); 44676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else 44776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 44876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "No link!!!\n" ); 44976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 45076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 45176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.crvalue |= /*TxEnable |*/ RxEnable | TxThreshold; 45276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman set_rx_mode(nic); 45376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 45476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Clear interrupts by setting the interrupt mask. */ 45576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(FBE | TUNF | CNTOVF | RBU | TI | RI, mtdx.ioaddr + ISR); 45676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl( 0, mtdx.ioaddr + IMR); 45776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 45876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 45976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/************************************************************************** 46076d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanPOLL - Wait for a frame 46176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman***************************************************************************/ 46276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int mtd_poll(struct nic *nic, __unused int retrieve) 46376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 46476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman s32 rx_status = mtdx.cur_rx->status; 46576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int retval = 0; 46676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 46776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if( ( rx_status & RXOWN ) != 0 ) 46876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 46976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 47076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 47176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 47276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (rx_status & ErrorSummary) 47376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { /* there was a fatal error */ 47476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf( "%s: Receive error, Rx status %8.8x, Error(s) %s%s%s\n", 47576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.nic_name, (unsigned int) rx_status, 47676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (rx_status & (LONG | RUNT)) ? "length_error ":"", 47776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (rx_status & RXER) ? "frame_error ":"", 47876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (rx_status & CRC) ? "crc_error ":"" ); 47976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman retval = 0; 48076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if( !((rx_status & RXFSD) && (rx_status & RXLSD)) ) 48176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 48276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* this pkt is too long, over one rx buffer */ 48376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf("Pkt is too long, over one rx buffer.\n"); 48476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman retval = 0; 48576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else 48676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { /* this received pkt is ok */ 48776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Omit the four octet CRC from the length. */ 48876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman short pkt_len = ((rx_status & FLNGMASK) >> FLNGShift) - 4; 48976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 49076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( " netdev_rx() normal Rx pkt length %d" 49176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman " status %x.\n", pkt_len, (unsigned int) rx_status ); 49276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 49376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nic->packetlen = pkt_len; 49476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy(nic->packet, mtdx.cur_rx->skbuff, pkt_len); 49576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 49676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman retval = 1; 49776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 49876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 49976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while( ( mtdx.cur_rx->status & RXOWN ) == 0 ) 50076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 50176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.cur_rx->status = RXOWN; 50276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.cur_rx = mtdx.cur_rx->next_desc_logical; 50376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 50476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 50576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Restart Rx engine if stopped. */ 50676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(0, mtdx.ioaddr + RXPDR); 50776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 50876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return retval; 50976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 51076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 51176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/************************************************************************** 51276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanTRANSMIT - Transmit a frame 51376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman***************************************************************************/ 51476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void mtd_transmit( 51576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct nic *nic, 51676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char *dest, /* Destination */ 51776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int type, /* Type */ 51876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int size, /* size */ 51976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman const char *data) /* Packet */ 52076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 52176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 to; 52276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 tx_status; 52376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int nstype = htons ( type ); 52476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 52576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy( txb, dest, ETH_ALEN ); 52676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy( txb + ETH_ALEN, nic->node_addr, ETH_ALEN ); 52776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy( txb + 2 * ETH_ALEN, &nstype, 2 ); 52876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy( txb + ETH_HLEN, data, size ); 52976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 53076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size += ETH_HLEN; 53176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size &= 0x0FFF; 53276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while( size < ETH_ZLEN ) 53376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 53476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman txb[size++] = '\0'; 53576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 53676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 53776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.tx_ring[0].control = TXLD | TXFD | CRCEnable | PADEnable; 53876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.tx_ring[0].control |= (size << PKTSShift); /* pkt size */ 53976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.tx_ring[0].control |= (size << TBSShift); /* buffer size */ 54076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.tx_ring[0].status = TXOWN; 54176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 54276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Point to transmit descriptor */ 54376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(virt_to_bus(mtdx.tx_ring), mtdx.ioaddr + TXLBA); 54476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Enable Tx */ 54576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl( mtdx.crvalue | TxEnable, mtdx.ioaddr + TCRRCR); 54676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Wake the potentially-idle transmit channel. */ 54776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(0, mtdx.ioaddr + TXPDR); 54876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 54976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman to = currticks() + TX_TIME_OUT; 55076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while(( mtdx.tx_ring[0].status & TXOWN) && (currticks() < to)); 55176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 55276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Disable Tx */ 55376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl( mtdx.crvalue & (~TxEnable), mtdx.ioaddr + TCRRCR); 55476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 55576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_status = mtdx.tx_ring[0].status; 55676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (currticks() >= to){ 55776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "TX Time Out" ); 55876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if( tx_status & (CSL | LC | EC | UDF | HF)){ 55976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf( "Transmit error: %8.8x %s %s %s %s %s\n", 56076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (unsigned int) tx_status, 56176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_status & EC ? "abort" : "", 56276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_status & CSL ? "carrier" : "", 56376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_status & LC ? "late" : "", 56476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_status & UDF ? "fifo" : "", 56576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tx_status & HF ? "heartbeat" : "" ); 56676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 56776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 56876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /*hex_dump( txb, size );*/ 56976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /*pause();*/ 57076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 57176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "TRANSMIT\n" ); 57276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 57376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 57476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/************************************************************************** 57576d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanDISABLE - Turn off ethernet interface 57676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman***************************************************************************/ 57776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void mtd_disable ( struct nic *nic ) { 57876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 57976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Disable Tx Rx*/ 58076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl( mtdx.crvalue & (~TxEnable) & (~RxEnable), mtdx.ioaddr + TCRRCR ); 58176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 58276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Reset the chip to erase previous misconfiguration. */ 58376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtd_reset(nic); 58476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 58576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "DISABLE\n" ); 58676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 58776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 58876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct nic_operations mtd_operations = { 58976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .connect = dummy_connect, 59076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .poll = mtd_poll, 59176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .transmit = mtd_transmit, 59276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .irq = dummy_irq, 59376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 59476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 59576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 59676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic struct pci_device_id mtd80x_nics[] = { 59776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x1516, 0x0800, "MTD800", "Myson MTD800", 0), 59876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x1516, 0x0803, "MTD803", "Surecom EP-320X", 0), 59976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman PCI_ROM(0x1516, 0x0891, "MTD891", "Myson MTD891", 0), 60076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 60176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 60276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanPCI_DRIVER ( mtd80x_driver, mtd80x_nics, PCI_NO_CLASS ); 60376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 60476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/************************************************************************** 60576d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanPROBE - Look for an adapter, this routine's visible to the outside 60676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman***************************************************************************/ 60776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 60876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int mtd_probe ( struct nic *nic, struct pci_device *pci ) { 60976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 61076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i; 61176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 61276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (pci->ioaddr == 0) 61376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 61476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 61576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman adjust_pci_device(pci); 61676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 61776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nic->ioaddr = pci->ioaddr; 61876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nic->irqno = 0; 61976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 62076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.nic_name = pci->driver_name; 62176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.dev_id = pci->device; 62276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.ioaddr = nic->ioaddr; 62376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 62476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* read ethernet id */ 62576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < 6; ++i) 62676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 62776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nic->node_addr[i] = inb(mtdx.ioaddr + PAR0 + i); 62876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 62976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 63076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (memcmp(nic->node_addr, "\0\0\0\0\0\0", 6) == 0) 63176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 63276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 63376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 63476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 63576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "%s: ioaddr %4.4x MAC %s\n", mtdx.nic_name, mtdx.ioaddr, eth_ntoa ( nic->node_addr ) ); 63676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 63776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Reset the chip to erase previous misconfiguration. */ 63876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(0x00000001, mtdx.ioaddr + BCR); 63976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 64076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* find the connected MII xcvrs */ 64176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 64276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if( mtdx.dev_id != 0x803 ) 64376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 64476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int phy, phy_idx = 0; 64576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 64676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (phy = 1; phy < 32 && phy_idx < 1; phy++) { 64776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int mii_status = mdio_read(nic, phy, 1); 64876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 64976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mii_status != 0xffff && mii_status != 0x0000) { 65076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.phys[phy_idx] = phy; 65176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 65276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "%s: MII PHY found at address %d, status " 65376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "0x%4.4x.\n", mtdx.nic_name, phy, mii_status ); 65476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* get phy type */ 65576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 65676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int data; 65776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 65876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman data = mdio_read(nic, mtdx.phys[phy_idx], 2); 65976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (data == SeeqPHYID0) 66076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.PHYType = SeeqPHY; 66176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (data == AhdocPHYID0) 66276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.PHYType = AhdocPHY; 66376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (data == MarvellPHYID0) 66476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.PHYType = MarvellPHY; 66576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (data == MysonPHYID0) 66676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.PHYType = Myson981; 66776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (data == LevelOnePHYID0) 66876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.PHYType = LevelOnePHY; 66976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 67076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.PHYType = OtherPHY; 67176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 67276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman phy_idx++; 67376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 67476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 67576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 67676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.mii_cnt = phy_idx; 67776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (phy_idx == 0) { 67876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf("%s: MII PHY not found -- this device may " 67976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "not operate correctly.\n", mtdx.nic_name); 68076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 68176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 68276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.phys[0] = 32; 68376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* get phy type */ 68476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (inl(mtdx.ioaddr + PHYIDENTIFIER) == MysonPHYID ) { 68576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.PHYType = MysonPHY; 68676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "MysonPHY\n" ); 68776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 68876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.PHYType = OtherPHY; 68976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman DBG ( "OtherPHY\n" ); 69076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 69176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 69276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 69376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman getlinkstatus(nic); 69476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if( !mtdx.linkok ) 69576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 69676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf("No link!!!\n"); 69776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 69876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 69976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 70076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtd_reset( nic ); 70176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 70276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* point to NIC specific routines */ 70376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman nic->nic_op = &mtd_operations; 70476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 70576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 70676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 70776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 70876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**************************************************************************/ 70976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void set_rx_mode(struct nic *nic __unused) 71076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 71176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 mc_filter[2]; /* Multicast hash filter */ 71276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 rx_mode; 71376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 71476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Too many to match, or accept all multicasts. */ 71576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mc_filter[1] = mc_filter[0] = ~0; 71676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; 71776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 71876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(mc_filter[0], mtdx.ioaddr + MAR0); 71976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(mc_filter[1], mtdx.ioaddr + MAR1); 72076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 72176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.crvalue = ( mtdx.crvalue & ~RxModeMask ) | rx_mode; 72276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outb( mtdx.crvalue, mtdx.ioaddr + TCRRCR); 72376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 72476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/**************************************************************************/ 72576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic unsigned int m80x_read_tick(void) 72676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* function: Reads the Timer tick count register which decrements by 2 from */ 72776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 65536 to 0 every 1/36.414 of a second. Each 2 decrements of the */ 72876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* count represents 838 nsec's. */ 72976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* input : none. */ 73076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* output : none. */ 73176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 73276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned char tmp; 73376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int value; 73476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 73576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outb((char) 0x06, 0x43); // Command 8254 to latch T0's count 73676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 73776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman // now read the count. 73876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tmp = (unsigned char) inb(0x40); 73976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman value = ((int) tmp) << 8; 74076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman tmp = (unsigned char) inb(0x40); 74176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman value |= (((int) tmp) & 0xff); 74276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return (value); 74376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 74476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 74576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void m80x_delay(unsigned int interval) 74676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* function: to wait for a specified time. */ 74776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* input : interval ... the specified time. */ 74876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* output : none. */ 74976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 75076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int interval1, interval2, i = 0; 75176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 75276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman interval1 = m80x_read_tick(); // get initial value 75376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman do 75476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 75576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman interval2 = m80x_read_tick(); 75676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (interval1 < interval2) 75776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman interval1 += 65536; 75876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ++i; 75976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } while (((interval1 - interval2) < (u16) interval) && (i < 65535)); 76076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 76176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 76276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 76376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic u32 m80x_send_cmd_to_phy(long miiport, int opcode, int phyad, int regad) 76476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 76576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 miir; 76676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int i; 76776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int mask, data; 76876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 76976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* enable MII output */ 77076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir = (u32) inl(miiport); 77176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir &= 0xfffffff0; 77276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 77376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir |= MASK_MIIR_MII_WRITE + MASK_MIIR_MII_MDO; 77476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 77576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* send 32 1's preamble */ 77676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < 32; i++) { 77776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* low MDC; MDO is already high (miir) */ 77876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir &= ~MASK_MIIR_MII_MDC; 77976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(miir, miiport); 78076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 78176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* high MDC */ 78276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir |= MASK_MIIR_MII_MDC; 78376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(miir, miiport); 78476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 78576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 78676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* calculate ST+OP+PHYAD+REGAD+TA */ 78776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman data = opcode | (phyad << 7) | (regad << 2); 78876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 78976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* sent out */ 79076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mask = 0x8000; 79176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while (mask) { 79276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* low MDC, prepare MDO */ 79376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO); 79476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mask & data) 79576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir |= MASK_MIIR_MII_MDO; 79676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 79776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(miir, miiport); 79876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* high MDC */ 79976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir |= MASK_MIIR_MII_MDC; 80076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(miir, miiport); 80176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m80x_delay(30); 80276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 80376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* next */ 80476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mask >>= 1; 80576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mask == 0x2 && opcode == OP_READ) 80676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir &= ~MASK_MIIR_MII_WRITE; 80776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 80876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return miir; 80976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 81076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 81176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int mdio_read(struct nic *nic __unused, int phyad, int regad) 81276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 81376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman long miiport = mtdx.ioaddr + MANAGEMENT; 81476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 miir; 81576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int mask, data; 81676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 81776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir = m80x_send_cmd_to_phy(miiport, OP_READ, phyad, regad); 81876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 81976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* read data */ 82076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mask = 0x8000; 82176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman data = 0; 82276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while (mask) 82376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 82476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* low MDC */ 82576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir &= ~MASK_MIIR_MII_MDC; 82676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(miir, miiport); 82776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 82876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* read MDI */ 82976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir = inl(miiport); 83076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (miir & MASK_MIIR_MII_MDI) 83176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman data |= mask; 83276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 83376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* high MDC, and wait */ 83476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir |= MASK_MIIR_MII_MDC; 83576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(miir, miiport); 83676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m80x_delay((int) 30); 83776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 83876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* next */ 83976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mask >>= 1; 84076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 84176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 84276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* low MDC */ 84376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir &= ~MASK_MIIR_MII_MDC; 84476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(miir, miiport); 84576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 84676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return data & 0xffff; 84776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 84876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 84976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if 0 /* not used */ 85076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void mdio_write(struct nic *nic __unused, int phyad, int regad, 85176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int data) 85276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 85376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman long miiport = mtdx.ioaddr + MANAGEMENT; 85476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman u32 miir; 85576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int mask; 85676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 85776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir = m80x_send_cmd_to_phy(miiport, OP_WRITE, phyad, regad); 85876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 85976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* write data */ 86076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mask = 0x8000; 86176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman while (mask) 86276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 86376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* low MDC, prepare MDO */ 86476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO); 86576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mask & data) 86676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir |= MASK_MIIR_MII_MDO; 86776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(miir, miiport); 86876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 86976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* high MDC */ 87076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir |= MASK_MIIR_MII_MDC; 87176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(miir, miiport); 87276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 87376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* next */ 87476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mask >>= 1; 87576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 87676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 87776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* low MDC */ 87876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman miir &= ~MASK_MIIR_MII_MDC; 87976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman outl(miir, miiport); 88076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 88176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 88276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 88376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 88476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 88576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void getlinkstatus(struct nic *nic) 88676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* function: Routine will read MII Status Register to get link status. */ 88776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* input : dev... pointer to the adapter block. */ 88876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* output : none. */ 88976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 89076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i, DelayTime = 0x1000; 89176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 89276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.linkok = 0; 89376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 89476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mtdx.PHYType == MysonPHY) 89576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 89676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < DelayTime; ++i) { 89776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (inl(mtdx.ioaddr + BMCRSR) & LinkIsUp2) { 89876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.linkok = 1; 89976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 90076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 90176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman // delay 90276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m80x_delay(100); 90376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 90476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else 90576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 90676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < DelayTime; ++i) { 90776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mdio_read(nic, mtdx.phys[0], MII_BMSR) & BMSR_LSTATUS) { 90876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.linkok = 1; 90976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return; 91076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 91176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman // delay 91276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman m80x_delay(100); 91376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 91476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 91576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 91676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 91776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 91876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic void getlinktype(struct nic *dev) 91976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 92076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mtdx.PHYType == MysonPHY) 92176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { /* 3-in-1 case */ 92276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (inl(mtdx.ioaddr + TCRRCR) & FD) 92376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.duplexmode = 2; /* full duplex */ 92476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 92576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.duplexmode = 1; /* half duplex */ 92676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (inl(mtdx.ioaddr + TCRRCR) & PS10) 92776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 1; /* 10M */ 92876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 92976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 2; /* 100M */ 93076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else 93176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman { 93276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mtdx.PHYType == SeeqPHY) { /* this PHY is SEEQ 80225 */ 93376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int data; 93476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 93576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman data = mdio_read(dev, mtdx.phys[0], MIIRegister18); 93676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (data & SPD_DET_100) 93776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 2; /* 100M */ 93876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 93976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 1; /* 10M */ 94076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (data & DPLX_DET_FULL) 94176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.duplexmode = 2; /* full duplex mode */ 94276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 94376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.duplexmode = 1; /* half duplex mode */ 94476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else if (mtdx.PHYType == AhdocPHY) { 94576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int data; 94676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 94776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman data = mdio_read(dev, mtdx.phys[0], DiagnosticReg); 94876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (data & Speed_100) 94976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 2; /* 100M */ 95076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 95176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 1; /* 10M */ 95276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (data & DPLX_FULL) 95376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.duplexmode = 2; /* full duplex mode */ 95476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 95576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.duplexmode = 1; /* half duplex mode */ 95676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 95776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 89/6/13 add, (begin) */ 95876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (mtdx.PHYType == MarvellPHY) { 95976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int data; 96076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 96176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman data = mdio_read(dev, mtdx.phys[0], SpecificReg); 96276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (data & Full_Duplex) 96376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.duplexmode = 2; /* full duplex mode */ 96476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 96576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.duplexmode = 1; /* half duplex mode */ 96676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman data &= SpeedMask; 96776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (data == Speed_1000M) 96876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 3; /* 1000M */ 96976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (data == Speed_100M) 97076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 2; /* 100M */ 97176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 97276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 1; /* 10M */ 97376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 97476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 89/6/13 add, (end) */ 97576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 89/7/27 add, (begin) */ 97676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (mtdx.PHYType == Myson981) { 97776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int data; 97876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 97976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman data = mdio_read(dev, mtdx.phys[0], StatusRegister); 98076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 98176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (data & SPEED100) 98276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 2; 98376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 98476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 1; 98576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 98676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (data & FULLMODE) 98776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.duplexmode = 2; 98876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 98976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.duplexmode = 1; 99076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 99176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 89/7/27 add, (end) */ 99276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 89/12/29 add */ 99376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (mtdx.PHYType == LevelOnePHY) { 99476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int data; 99576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 99676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman data = mdio_read(dev, mtdx.phys[0], SpecificReg); 99776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (data & LXT1000_Full) 99876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.duplexmode = 2; /* full duplex mode */ 99976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 100076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.duplexmode = 1; /* half duplex mode */ 100176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman data &= SpeedMask; 100276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (data == LXT1000_1000M) 100376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 3; /* 1000M */ 100476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (data == LXT1000_100M) 100576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 2; /* 100M */ 100676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else 100776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.line_speed = 1; /* 10M */ 100876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 100976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman // chage crvalue 101076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman // mtdx.crvalue&=(~PS10)&(~FD); 101176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.crvalue &= (~PS10) & (~FD) & (~PS1000); 101276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mtdx.line_speed == 1) 101376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.crvalue |= PS10; 101476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman else if (mtdx.line_speed == 3) 101576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.crvalue |= PS1000; 101676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (mtdx.duplexmode == 2) 101776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtdx.crvalue |= FD; 101876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 101976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 102076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 102176d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanDRIVER ( "MTD80X", nic_driver, pci_driver, mtd80x_driver, 102276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mtd_probe, mtd_disable ); 1023