Annotation of qemu/roms/ipxe/src/drivers/net/tlan.c, revision 1.1

1.1     ! root        1: /**************************************************************************
        !             2: *
        !             3: *    tlan.c -- Etherboot device driver for the Texas Instruments ThunderLAN
        !             4: *    Written 2003-2003 by Timothy Legge <[email protected]>
        !             5: *
        !             6: *    This program is free software; you can redistribute it and/or modify
        !             7: *    it under the terms of the GNU General Public License as published by
        !             8: *    the Free Software Foundation; either version 2 of the License, or
        !             9: *    (at your option) any later version.
        !            10: *
        !            11: *    This program is distributed in the hope that it will be useful,
        !            12: *    but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: *    GNU General Public License for more details.
        !            15: *
        !            16: *    You should have received a copy of the GNU General Public License
        !            17: *    along with this program; if not, write to the Free Software
        !            18: *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            19: *
        !            20: *    Portions of this code based on:
        !            21: *      lan.c: Linux ThunderLan Driver:
        !            22: *
        !            23: *      by James Banks
        !            24: *
        !            25: *      (C) 1997-1998 Caldera, Inc.
        !            26: *      (C) 1998 James Banks
        !            27: *      (C) 1999-2001 Torben Mathiasen
        !            28: *      (C) 2002 Samuel Chessman
        !            29: *
        !            30: *    REVISION HISTORY:
        !            31: *    ================
        !            32: *    v1.0      07-08-2003      timlegge        Initial not quite working version
        !            33: *    v1.1      07-27-2003      timlegge        Sync 5.0 and 5.1 versions
        !            34: *    v1.2      08-19-2003      timlegge        Implement Multicast Support
        !            35: *    v1.3      08-23-2003      timlegge        Fix the transmit Function
        !            36: *    v1.4      01-17-2004      timlegge        Initial driver output cleanup    
        !            37: *    
        !            38: *    Indent Options: indent -kr -i8
        !            39: ***************************************************************************/
        !            40: 
        !            41: FILE_LICENCE ( GPL2_OR_LATER );
        !            42: 
        !            43: #include "etherboot.h"
        !            44: #include "nic.h"
        !            45: #include <ipxe/pci.h>
        !            46: #include <ipxe/ethernet.h>
        !            47: #include <mii.h>
        !            48: #include "tlan.h"
        !            49: 
        !            50: #define drv_version "v1.4"
        !            51: #define drv_date "01-17-2004"
        !            52: 
        !            53: /* NIC specific static variables go here */
        !            54: #define HZ 100
        !            55: #define TX_TIME_OUT      (6*HZ)
        !            56: 
        !            57: /* Condensed operations for readability. */
        !            58: #define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
        !            59: #define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
        !            60: 
        !            61: static void TLan_ResetLists(struct nic *nic __unused);
        !            62: static void TLan_ResetAdapter(struct nic *nic __unused);
        !            63: static void TLan_FinishReset(struct nic *nic __unused);
        !            64: 
        !            65: static void TLan_EeSendStart(u16);
        !            66: static int TLan_EeSendByte(u16, u8, int);
        !            67: static void TLan_EeReceiveByte(u16, u8 *, int);
        !            68: static int TLan_EeReadByte(u16 io_base, u8, u8 *);
        !            69: 
        !            70: static void TLan_PhyDetect(struct nic *nic);
        !            71: static void TLan_PhyPowerDown(struct nic *nic);
        !            72: static void TLan_PhyPowerUp(struct nic *nic);
        !            73: 
        !            74: 
        !            75: static void TLan_SetMac(struct nic *nic __unused, int areg, unsigned char *mac);
        !            76: 
        !            77: static void TLan_PhyReset(struct nic *nic);
        !            78: static void TLan_PhyStartLink(struct nic *nic);
        !            79: static void TLan_PhyFinishAutoNeg(struct nic *nic);
        !            80: 
        !            81: #ifdef MONITOR
        !            82: static void TLan_PhyMonitor(struct nic *nic);
        !            83: #endif
        !            84: 
        !            85: 
        !            86: static void refill_rx(struct nic *nic __unused);
        !            87: 
        !            88: static int TLan_MiiReadReg(struct nic *nic __unused, u16, u16, u16 *);
        !            89: static void TLan_MiiSendData(u16, u32, unsigned);
        !            90: static void TLan_MiiSync(u16);
        !            91: static void TLan_MiiWriteReg(struct nic *nic __unused, u16, u16, u16);
        !            92: 
        !            93: 
        !            94: static const char *media[] = {
        !            95:        "10BaseT-HD ", "10BaseT-FD ", "100baseTx-HD ",
        !            96:        "100baseTx-FD", "100baseT4", 0
        !            97: };
        !            98: 
        !            99: /* This much match tlan_pci_tbl[]!  */
        !           100: enum tlan_nics {
        !           101:        NETEL10 = 0, NETEL100 = 1, NETFLEX3I = 2, THUNDER = 3, NETFLEX3B =
        !           102:            4, NETEL100PI = 5,
        !           103:        NETEL100D = 6, NETEL100I = 7, OC2183 = 8, OC2325 = 9, OC2326 =
        !           104:            10, NETELLIGENT_10_100_WS_5100 = 11,
        !           105:        NETELLIGENT_10_T2 = 12
        !           106: };
        !           107: 
        !           108: struct pci_id_info {
        !           109:        const char *name;
        !           110:        int nic_id;
        !           111:        struct match_info {
        !           112:                u32 pci, pci_mask, subsystem, subsystem_mask;
        !           113:                u32 revision, revision_mask;    /* Only 8 bits. */
        !           114:        } id;
        !           115:        u32 flags;
        !           116:        u16 addrOfs;            /* Address Offset */
        !           117: };
        !           118: 
        !           119: static const struct pci_id_info tlan_pci_tbl[] = {
        !           120:        {"Compaq Netelligent 10 T PCI UTP", NETEL10,
        !           121:         {0xae340e11, 0xffffffff, 0, 0, 0, 0},
        !           122:         TLAN_ADAPTER_ACTIVITY_LED, 0x83},
        !           123:        {"Compaq Netelligent 10/100 TX PCI UTP", NETEL100,
        !           124:         {0xae320e11, 0xffffffff, 0, 0, 0, 0},
        !           125:         TLAN_ADAPTER_ACTIVITY_LED, 0x83},
        !           126:        {"Compaq Integrated NetFlex-3/P", NETFLEX3I,
        !           127:         {0xae350e11, 0xffffffff, 0, 0, 0, 0},
        !           128:         TLAN_ADAPTER_NONE, 0x83},
        !           129:        {"Compaq NetFlex-3/P", THUNDER,
        !           130:         {0xf1300e11, 0xffffffff, 0, 0, 0, 0},
        !           131:         TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83},
        !           132:        {"Compaq NetFlex-3/P", NETFLEX3B,
        !           133:         {0xf1500e11, 0xffffffff, 0, 0, 0, 0},
        !           134:         TLAN_ADAPTER_NONE, 0x83},
        !           135:        {"Compaq Netelligent Integrated 10/100 TX UTP", NETEL100PI,
        !           136:         {0xae430e11, 0xffffffff, 0, 0, 0, 0},
        !           137:         TLAN_ADAPTER_ACTIVITY_LED, 0x83},
        !           138:        {"Compaq Netelligent Dual 10/100 TX PCI UTP", NETEL100D,
        !           139:         {0xae400e11, 0xffffffff, 0, 0, 0, 0},
        !           140:         TLAN_ADAPTER_NONE, 0x83},
        !           141:        {"Compaq Netelligent 10/100 TX Embedded UTP", NETEL100I,
        !           142:         {0xb0110e11, 0xffffffff, 0, 0, 0, 0},
        !           143:         TLAN_ADAPTER_NONE, 0x83},
        !           144:        {"Olicom OC-2183/2185", OC2183,
        !           145:         {0x0013108d, 0xffffffff, 0, 0, 0, 0},
        !           146:         TLAN_ADAPTER_USE_INTERN_10, 0x83},
        !           147:        {"Olicom OC-2325", OC2325,
        !           148:         {0x0012108d, 0xffffffff, 0, 0, 0, 0},
        !           149:         TLAN_ADAPTER_UNMANAGED_PHY, 0xF8},
        !           150:        {"Olicom OC-2326", OC2326,
        !           151:         {0x0014108d, 0xffffffff, 0, 0, 0, 0},
        !           152:         TLAN_ADAPTER_USE_INTERN_10, 0xF8},
        !           153:        {"Compaq Netelligent 10/100 TX UTP", NETELLIGENT_10_100_WS_5100,
        !           154:         {0xb0300e11, 0xffffffff, 0, 0, 0, 0},
        !           155:         TLAN_ADAPTER_ACTIVITY_LED, 0x83},
        !           156:        {"Compaq Netelligent 10 T/2 PCI UTP/Coax", NETELLIGENT_10_T2,
        !           157:         {0xb0120e11, 0xffffffff, 0, 0, 0, 0},
        !           158:         TLAN_ADAPTER_NONE, 0x83},
        !           159:        {"Compaq NetFlex-3/E", 0,       /* EISA card */
        !           160:         {0, 0, 0, 0, 0, 0},
        !           161:         TLAN_ADAPTER_ACTIVITY_LED | TLAN_ADAPTER_UNMANAGED_PHY |
        !           162:         TLAN_ADAPTER_BIT_RATE_PHY, 0x83},
        !           163:        {"Compaq NetFlex-3/E", 0,       /* EISA card */
        !           164:         {0, 0, 0, 0, 0, 0},
        !           165:         TLAN_ADAPTER_ACTIVITY_LED, 0x83},
        !           166:        {0, 0,
        !           167:         {0, 0, 0, 0, 0, 0},
        !           168:         0, 0},
        !           169: };
        !           170: 
        !           171: struct TLanList {
        !           172:        u32 forward;
        !           173:        u16 cStat;
        !           174:        u16 frameSize;
        !           175:        struct {
        !           176:                u32 count;
        !           177:                u32 address;
        !           178:        } buffer[TLAN_BUFFERS_PER_LIST];
        !           179: };
        !           180: 
        !           181: struct {
        !           182:        struct TLanList tx_ring[TLAN_NUM_TX_LISTS];
        !           183:        unsigned char txb[TLAN_MAX_FRAME_SIZE * TLAN_NUM_TX_LISTS];
        !           184:        struct TLanList rx_ring[TLAN_NUM_RX_LISTS];
        !           185:        unsigned char rxb[TLAN_MAX_FRAME_SIZE * TLAN_NUM_RX_LISTS];
        !           186: } tlan_buffers __shared;
        !           187: #define tx_ring tlan_buffers.tx_ring
        !           188: #define txb tlan_buffers.txb
        !           189: #define rx_ring tlan_buffers.rx_ring
        !           190: #define rxb tlan_buffers.rxb
        !           191: 
        !           192: typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE];
        !           193: 
        !           194: static int chip_idx;
        !           195: 
        !           196: /*****************************************************************
        !           197: * TLAN Private Information Structure
        !           198: *
        !           199: ****************************************************************/
        !           200: static struct tlan_private {
        !           201:        unsigned short vendor_id;       /* PCI Vendor code */
        !           202:        unsigned short dev_id;  /* PCI Device code */
        !           203:        const char *nic_name;
        !           204:        unsigned int cur_rx, dirty_rx;  /* Producer/consumer ring indicies */
        !           205:        unsigned rx_buf_sz;     /* Based on mtu + Slack */
        !           206:        struct TLanList *txList;
        !           207:        u32 txHead;
        !           208:        u32 txInProgress;
        !           209:        u32 txTail;
        !           210:        int eoc;
        !           211:        u32 phyOnline;
        !           212:        u32 aui;
        !           213:        u32 duplex;
        !           214:        u32 phy[2];
        !           215:        u32 phyNum;
        !           216:        u32 speed;
        !           217:        u8 tlanRev;
        !           218:        u8 tlanFullDuplex;
        !           219:        u8 link;
        !           220:        u8 neg_be_verbose;
        !           221: } TLanPrivateInfo;
        !           222: 
        !           223: static struct tlan_private *priv;
        !           224: 
        !           225: static u32 BASE;
        !           226: 
        !           227: /***************************************************************
        !           228: *      TLan_ResetLists
        !           229: *
        !           230: *      Returns:
        !           231: *              Nothing
        !           232: *      Parms:
        !           233: *              dev     The device structure with the list
        !           234: *                      stuctures to be reset.
        !           235: *
        !           236: *      This routine sets the variables associated with managing
        !           237: *      the TLAN lists to their initial values.
        !           238: *
        !           239: **************************************************************/
        !           240: 
        !           241: static void TLan_ResetLists(struct nic *nic __unused)
        !           242: {
        !           243: 
        !           244:        int i;
        !           245:        struct TLanList *list;
        !           246:        priv->txHead = 0;
        !           247:        priv->txTail = 0;
        !           248: 
        !           249:        for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
        !           250:                list = &tx_ring[i];
        !           251:                list->cStat = TLAN_CSTAT_UNUSED;
        !           252:                list->buffer[0].address = virt_to_bus(txb + 
        !           253:                                (i * TLAN_MAX_FRAME_SIZE)); 
        !           254:                list->buffer[2].count = 0;
        !           255:                list->buffer[2].address = 0;
        !           256:                list->buffer[9].address = 0;
        !           257:        }
        !           258: 
        !           259:        priv->cur_rx = 0;
        !           260:        priv->rx_buf_sz = (TLAN_MAX_FRAME_SIZE);
        !           261: //     priv->rx_head_desc = &rx_ring[0];
        !           262: 
        !           263:        /* Initialize all the Rx descriptors */
        !           264:        for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
        !           265:                rx_ring[i].forward = virt_to_le32desc(&rx_ring[i + 1]);
        !           266:                rx_ring[i].cStat = TLAN_CSTAT_READY;
        !           267:                rx_ring[i].frameSize = TLAN_MAX_FRAME_SIZE;
        !           268:                rx_ring[i].buffer[0].count =
        !           269:                    TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
        !           270:                rx_ring[i].buffer[0].address =
        !           271:                    virt_to_le32desc(&rxb[i * TLAN_MAX_FRAME_SIZE]);
        !           272:                rx_ring[i].buffer[1].count = 0;
        !           273:                rx_ring[i].buffer[1].address = 0;
        !           274:        }
        !           275: 
        !           276:        /* Mark the last entry as wrapping the ring */
        !           277:        rx_ring[i - 1].forward = virt_to_le32desc(&rx_ring[0]);
        !           278:        priv->dirty_rx = (unsigned int) (i - TLAN_NUM_RX_LISTS);
        !           279: 
        !           280: } /* TLan_ResetLists */
        !           281: 
        !           282: /***************************************************************
        !           283: *      TLan_Reset
        !           284: *
        !           285: *      Returns:
        !           286: *              0
        !           287: *      Parms:
        !           288: *              dev     Pointer to device structure of adapter
        !           289: *                      to be reset.
        !           290: *
        !           291: *      This function resets the adapter and it's physical
        !           292: *      device.  See Chap. 3, pp. 9-10 of the "ThunderLAN
        !           293: *      Programmer's Guide" for details.  The routine tries to
        !           294: *      implement what is detailed there, though adjustments
        !           295: *      have been made.
        !           296: *
        !           297: **************************************************************/
        !           298: 
        !           299: void TLan_ResetAdapter(struct nic *nic __unused)
        !           300: {
        !           301:        int i;
        !           302:        u32 addr;
        !           303:        u32 data;
        !           304:        u8 data8;
        !           305: 
        !           306:        priv->tlanFullDuplex = FALSE;
        !           307:        priv->phyOnline = 0;
        !           308: /*  1. Assert reset bit. */
        !           309: 
        !           310:        data = inl(BASE + TLAN_HOST_CMD);
        !           311:        data |= TLAN_HC_AD_RST;
        !           312:        outl(data, BASE + TLAN_HOST_CMD);
        !           313: 
        !           314:        udelay(1000);
        !           315: 
        !           316: /*  2. Turn off interrupts. ( Probably isn't necessary ) */
        !           317: 
        !           318:        data = inl(BASE + TLAN_HOST_CMD);
        !           319:        data |= TLAN_HC_INT_OFF;
        !           320:        outl(data, BASE + TLAN_HOST_CMD);
        !           321: /*  3. Clear AREGs and HASHs. */
        !           322: 
        !           323:        for (i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4) {
        !           324:                TLan_DioWrite32(BASE, (u16) i, 0);
        !           325:        }
        !           326: 
        !           327: /*  4. Setup NetConfig register. */
        !           328: 
        !           329:        data =
        !           330:            TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
        !           331:        TLan_DioWrite16(BASE, TLAN_NET_CONFIG, (u16) data);
        !           332: 
        !           333: /*  5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
        !           334: 
        !           335:        outl(TLAN_HC_LD_TMR | 0x3f, BASE + TLAN_HOST_CMD);
        !           336:        outl(TLAN_HC_LD_THR | 0x0, BASE + TLAN_HOST_CMD);
        !           337: 
        !           338: /*  6. Unreset the MII by setting NMRST (in NetSio) to 1. */
        !           339: 
        !           340:        outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR);
        !           341:        addr = BASE + TLAN_DIO_DATA + TLAN_NET_SIO;
        !           342:        TLan_SetBit(TLAN_NET_SIO_NMRST, addr);
        !           343: 
        !           344: /*  7. Setup the remaining registers. */
        !           345: 
        !           346:        if (priv->tlanRev >= 0x30) {
        !           347:                data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
        !           348:                TLan_DioWrite8(BASE, TLAN_INT_DIS, data8);
        !           349:        }
        !           350:        TLan_PhyDetect(nic);
        !           351:        data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
        !           352: 
        !           353:        if (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_BIT_RATE_PHY) {
        !           354:                data |= TLAN_NET_CFG_BIT;
        !           355:                if (priv->aui == 1) {
        !           356:                        TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x0a);
        !           357:                } else if (priv->duplex == TLAN_DUPLEX_FULL) {
        !           358:                        TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x00);
        !           359:                        priv->tlanFullDuplex = TRUE;
        !           360:                } else {
        !           361:                        TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x08);
        !           362:                }
        !           363:        }
        !           364: 
        !           365:        if (priv->phyNum == 0) {
        !           366:                data |= TLAN_NET_CFG_PHY_EN;
        !           367:        }
        !           368:        TLan_DioWrite16(BASE, TLAN_NET_CONFIG, (u16) data);
        !           369: 
        !           370:        if (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_UNMANAGED_PHY) {
        !           371:                TLan_FinishReset(nic);
        !           372:        } else {
        !           373:                TLan_PhyPowerDown(nic);
        !           374:        }
        !           375: 
        !           376: }      /* TLan_ResetAdapter */
        !           377: 
        !           378: void TLan_FinishReset(struct nic *nic)
        !           379: {
        !           380: 
        !           381:        u8 data;
        !           382:        u32 phy;
        !           383:        u8 sio;
        !           384:        u16 status;
        !           385:        u16 partner;
        !           386:        u16 tlphy_ctl;
        !           387:        u16 tlphy_par;
        !           388:        u16 tlphy_id1, tlphy_id2;
        !           389:        int i;
        !           390: 
        !           391:        phy = priv->phy[priv->phyNum];
        !           392: 
        !           393:        data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
        !           394:        if (priv->tlanFullDuplex) {
        !           395:                data |= TLAN_NET_CMD_DUPLEX;
        !           396:        }
        !           397:        TLan_DioWrite8(BASE, TLAN_NET_CMD, data);
        !           398:        data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
        !           399:        if (priv->phyNum == 0) {
        !           400:                data |= TLAN_NET_MASK_MASK7;
        !           401:        }
        !           402:        TLan_DioWrite8(BASE, TLAN_NET_MASK, data);
        !           403:        TLan_DioWrite16(BASE, TLAN_MAX_RX, ((1536) + 7) & ~7);
        !           404:        TLan_MiiReadReg(nic, phy, MII_PHYSID1, &tlphy_id1);
        !           405:        TLan_MiiReadReg(nic, phy, MII_PHYSID2, &tlphy_id2);
        !           406: 
        !           407:        if ((tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_UNMANAGED_PHY)
        !           408:            || (priv->aui)) {
        !           409:                status = BMSR_LSTATUS;
        !           410:                DBG ( "TLAN:  %s: Link forced.\n", priv->nic_name );
        !           411:        } else {
        !           412:                TLan_MiiReadReg(nic, phy, MII_BMSR, &status);
        !           413:                udelay(1000);
        !           414:                TLan_MiiReadReg(nic, phy, MII_BMSR, &status);
        !           415:                if ((status & BMSR_LSTATUS) &&  /* We only support link info on Nat.Sem. PHY's */
        !           416:                    (tlphy_id1 == NAT_SEM_ID1)
        !           417:                    && (tlphy_id2 == NAT_SEM_ID2)) {
        !           418:                        TLan_MiiReadReg(nic, phy, MII_LPA, &partner);
        !           419:                        TLan_MiiReadReg(nic, phy, TLAN_TLPHY_PAR,
        !           420:                                        &tlphy_par);
        !           421: 
        !           422:                        DBG ( "TLAN: %s: Link active with ",
        !           423:                               priv->nic_name );
        !           424:                        if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) {
        !           425:                                DBG ( "forced 10%sMbps %s-Duplex\n",
        !           426:                                       tlphy_par & TLAN_PHY_SPEED_100 ? ""
        !           427:                                       : "0",
        !           428:                                       tlphy_par & TLAN_PHY_DUPLEX_FULL ?
        !           429:                                       "Full" : "Half" );
        !           430:                        } else {
        !           431:                                DBG 
        !           432:                                    ( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n",
        !           433:                                     tlphy_par & TLAN_PHY_SPEED_100 ? "" :
        !           434:                                     "0",
        !           435:                                     tlphy_par & TLAN_PHY_DUPLEX_FULL ?
        !           436:                                     "Full" : "Half" );
        !           437:                                DBG ( "TLAN: Partner capability: " );
        !           438:                                for (i = 5; i <= 10; i++)
        !           439:                                        if (partner & (1 << i)) {
        !           440:                                                DBG ( "%s", media[i - 5] );
        !           441:                                        }
        !           442:                                DBG ( "\n" );
        !           443:                        }
        !           444: 
        !           445:                        TLan_DioWrite8(BASE, TLAN_LED_REG, TLAN_LED_LINK);
        !           446: #ifdef MONITOR
        !           447:                        /* We have link beat..for now anyway */
        !           448:                        priv->link = 1;
        !           449:                        /*Enabling link beat monitoring */
        !           450:                        /* TLan_SetTimer( nic, (10*HZ), TLAN_TIMER_LINK_BEAT ); */
        !           451:                        mdelay(10000);
        !           452:                        TLan_PhyMonitor(nic);
        !           453: #endif
        !           454:                } else if (status & BMSR_LSTATUS) {
        !           455:                        DBG ( "TLAN: %s: Link active\n", priv->nic_name );
        !           456:                        TLan_DioWrite8(BASE, TLAN_LED_REG, TLAN_LED_LINK);
        !           457:                }
        !           458:        }
        !           459: 
        !           460:        if (priv->phyNum == 0) {
        !           461:                TLan_MiiReadReg(nic, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
        !           462:                tlphy_ctl |= TLAN_TC_INTEN;
        !           463:                TLan_MiiWriteReg(nic, phy, TLAN_TLPHY_CTL, tlphy_ctl);
        !           464:                sio = TLan_DioRead8(BASE, TLAN_NET_SIO);
        !           465:                sio |= TLAN_NET_SIO_MINTEN;
        !           466:                TLan_DioWrite8(BASE, TLAN_NET_SIO, sio);
        !           467:        }
        !           468: 
        !           469:        if (status & BMSR_LSTATUS) {
        !           470:                TLan_SetMac(nic, 0, nic->node_addr);
        !           471:                priv->phyOnline = 1;
        !           472:                outb((TLAN_HC_INT_ON >> 8), BASE + TLAN_HOST_CMD + 1);
        !           473:                outl(virt_to_bus(&rx_ring), BASE + TLAN_CH_PARM);
        !           474:                outl(TLAN_HC_GO | TLAN_HC_RT, BASE + TLAN_HOST_CMD);
        !           475:        } else {
        !           476:                DBG 
        !           477:                    ( "TLAN: %s: Link inactive, will retry in 10 secs...\n",
        !           478:                     priv->nic_name );
        !           479:                /* TLan_SetTimer( nic, (10*HZ), TLAN_TIMER_FINISH_RESET ); */
        !           480:                mdelay(10000);
        !           481:                TLan_FinishReset(nic);
        !           482:                return;
        !           483: 
        !           484:        }
        !           485: 
        !           486: }      /* TLan_FinishReset */
        !           487: 
        !           488: /**************************************************************************
        !           489: POLL - Wait for a frame
        !           490: ***************************************************************************/
        !           491: static int tlan_poll(struct nic *nic, int retrieve)
        !           492: {
        !           493:        /* return true if there's an ethernet packet ready to read */
        !           494:        /* nic->packet should contain data on return */
        !           495:        /* nic->packetlen should contain length of data */
        !           496:        u32 framesize;
        !           497:        u32 host_cmd = 0;
        !           498:        u32 ack = 1;
        !           499:        int eoc = 0;
        !           500:        int entry = priv->cur_rx % TLAN_NUM_RX_LISTS;
        !           501:        u16 tmpCStat = le32_to_cpu(rx_ring[entry].cStat);
        !           502:        u16 host_int = inw(BASE + TLAN_HOST_INT);
        !           503: 
        !           504:        if ((tmpCStat & TLAN_CSTAT_FRM_CMP) && !retrieve)
        !           505:          return 1;
        !           506: 
        !           507:        outw(host_int, BASE + TLAN_HOST_INT);
        !           508: 
        !           509:        if (!(tmpCStat & TLAN_CSTAT_FRM_CMP))
        !           510:                return 0;
        !           511: 
        !           512:        /* printf("PI-1: 0x%hX\n", host_int); */
        !           513:        if (tmpCStat & TLAN_CSTAT_EOC)
        !           514:                eoc = 1;
        !           515: 
        !           516:        framesize = rx_ring[entry].frameSize;
        !           517: 
        !           518:        nic->packetlen = framesize;
        !           519: 
        !           520:        DBG ( ".%d.", (unsigned int) framesize ); 
        !           521:      
        !           522:        memcpy(nic->packet, rxb +
        !           523:               (priv->cur_rx * TLAN_MAX_FRAME_SIZE), nic->packetlen);
        !           524: 
        !           525:        rx_ring[entry].cStat = 0;
        !           526: 
        !           527:        DBG ( "%d", entry );  
        !           528: 
        !           529:        entry = (entry + 1) % TLAN_NUM_RX_LISTS;
        !           530:        priv->cur_rx = entry;
        !           531:        if (eoc) {
        !           532:                if ((rx_ring[entry].cStat & TLAN_CSTAT_READY) ==
        !           533:                    TLAN_CSTAT_READY) {
        !           534:                        ack |= TLAN_HC_GO | TLAN_HC_RT;
        !           535:                        host_cmd = TLAN_HC_ACK | ack | 0x001C0000;
        !           536:                        outl(host_cmd, BASE + TLAN_HOST_CMD);
        !           537:                }
        !           538:        } else {
        !           539:                host_cmd = TLAN_HC_ACK | ack | (0x000C0000);
        !           540:                outl(host_cmd, BASE + TLAN_HOST_CMD);
        !           541:                
        !           542:                DBG ( "AC: 0x%hX\n", inw(BASE + TLAN_CH_PARM) ); 
        !           543:                DBG ( "PI-2: 0x%hX\n", inw(BASE + TLAN_HOST_INT) );
        !           544:        }
        !           545:        refill_rx(nic);
        !           546:        return (1);             /* initially as this is called to flush the input */
        !           547: }
        !           548: 
        !           549: static void refill_rx(struct nic *nic __unused)
        !           550: {
        !           551:        int entry = 0;
        !           552: 
        !           553:        for (;
        !           554:             (priv->cur_rx - priv->dirty_rx +
        !           555:              TLAN_NUM_RX_LISTS) % TLAN_NUM_RX_LISTS > 0;
        !           556:             priv->dirty_rx = (priv->dirty_rx + 1) % TLAN_NUM_RX_LISTS) {
        !           557:                entry = priv->dirty_rx % TLAN_NUM_TX_LISTS;
        !           558:                rx_ring[entry].frameSize = TLAN_MAX_FRAME_SIZE;
        !           559:                rx_ring[entry].cStat = TLAN_CSTAT_READY;
        !           560:        }
        !           561: 
        !           562: }
        !           563: 
        !           564: /**************************************************************************
        !           565: TRANSMIT - Transmit a frame
        !           566: ***************************************************************************/
        !           567: static void tlan_transmit(struct nic *nic, const char *d,      /* Destination */
        !           568:                          unsigned int t,       /* Type */
        !           569:                          unsigned int s,       /* size */
        !           570:                          const char *p)
        !           571: {                              /* Packet */
        !           572:        u16 nstype;
        !           573:        u32 to;
        !           574:        struct TLanList *tail_list;
        !           575:        struct TLanList *head_list;
        !           576:        u8 *tail_buffer;
        !           577:        u32 ack = 0;
        !           578:        u32 host_cmd;
        !           579:        int eoc = 0;
        !           580:        u16 tmpCStat;
        !           581:        u16 host_int = inw(BASE + TLAN_HOST_INT);
        !           582: 
        !           583:        int entry = 0;
        !           584: 
        !           585:        DBG ( "INT0-0x%hX\n", host_int );
        !           586: 
        !           587:        if (!priv->phyOnline) {
        !           588:                printf("TRANSMIT:  %s PHY is not ready\n", priv->nic_name);
        !           589:                return;
        !           590:        }
        !           591: 
        !           592:        tail_list = priv->txList + priv->txTail;
        !           593: 
        !           594:        if (tail_list->cStat != TLAN_CSTAT_UNUSED) {
        !           595:                printf("TRANSMIT: %s is busy (Head=%p Tail=%x)\n",
        !           596:                       priv->nic_name, priv->txList, (unsigned int) priv->txTail);
        !           597:                tx_ring[entry].cStat = TLAN_CSTAT_UNUSED;
        !           598: //             priv->txBusyCount++;
        !           599:                return;
        !           600:        }
        !           601: 
        !           602:        tail_list->forward = 0;
        !           603: 
        !           604:        tail_buffer = txb + (priv->txTail * TLAN_MAX_FRAME_SIZE);
        !           605: 
        !           606:        /* send the packet to destination */
        !           607:        memcpy(tail_buffer, d, ETH_ALEN);
        !           608:        memcpy(tail_buffer + ETH_ALEN, nic->node_addr, ETH_ALEN);
        !           609:        nstype = htons((u16) t);
        !           610:        memcpy(tail_buffer + 2 * ETH_ALEN, (u8 *) & nstype, 2);
        !           611:        memcpy(tail_buffer + ETH_HLEN, p, s);
        !           612: 
        !           613:        s += ETH_HLEN;
        !           614:        s &= 0x0FFF;
        !           615:        while (s < ETH_ZLEN)
        !           616:                tail_buffer[s++] = '\0';
        !           617: 
        !           618:        /*=====================================================*/
        !           619:        /* Receive
        !           620:         * 0000 0000 0001 1100
        !           621:         * 0000 0000 0000 1100
        !           622:         * 0000 0000 0000 0011 = 0x0003
        !           623:         *
        !           624:         * 0000 0000 0000 0000 0000 0000 0000 0011
        !           625:         * 0000 0000 0000 1100 0000 0000 0000 0000 = 0x000C0000
        !           626:         *
        !           627:         * Transmit
        !           628:         * 0000 0000 0001 1100
        !           629:         * 0000 0000 0000 0100
        !           630:         * 0000 0000 0000 0001 = 0x0001
        !           631:         *
        !           632:         * 0000 0000 0000 0000 0000 0000 0000 0001
        !           633:         * 0000 0000 0000 0100 0000 0000 0000 0000 = 0x00040000
        !           634:         * */
        !           635: 
        !           636:        /* Setup the transmit descriptor */
        !           637:        tail_list->frameSize = (u16) s;
        !           638:        tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) s;
        !           639:        tail_list->buffer[1].count = 0;
        !           640:        tail_list->buffer[1].address = 0;
        !           641: 
        !           642:        tail_list->cStat = TLAN_CSTAT_READY;
        !           643: 
        !           644:        DBG ( "INT1-0x%hX\n", inw(BASE + TLAN_HOST_INT) );
        !           645: 
        !           646:        if (!priv->txInProgress) {
        !           647:                priv->txInProgress = 1;
        !           648:                outl(virt_to_le32desc(tail_list), BASE + TLAN_CH_PARM);
        !           649:                outl(TLAN_HC_GO, BASE + TLAN_HOST_CMD);
        !           650:        } else {
        !           651:                if (priv->txTail == 0) {
        !           652:                        DBG ( "Out buffer\n" );
        !           653:                        (priv->txList + (TLAN_NUM_TX_LISTS - 1))->forward =
        !           654:                            virt_to_le32desc(tail_list);
        !           655:                } else {
        !           656:                        DBG ( "Fix this \n" );
        !           657:                        (priv->txList + (priv->txTail - 1))->forward =
        !           658:                            virt_to_le32desc(tail_list);
        !           659:                }
        !           660:        }
        !           661:        
        !           662:        CIRC_INC(priv->txTail, TLAN_NUM_TX_LISTS);
        !           663: 
        !           664:        DBG ( "INT2-0x%hX\n", inw(BASE + TLAN_HOST_INT) );
        !           665: 
        !           666:        to = currticks() + TX_TIME_OUT;
        !           667:        while ((tail_list->cStat == TLAN_CSTAT_READY) && currticks() < to);
        !           668: 
        !           669:        head_list = priv->txList + priv->txHead;
        !           670:        while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) 
        !           671:                        && (ack < 255)) {
        !           672:                ack++;
        !           673:                if(tmpCStat & TLAN_CSTAT_EOC)
        !           674:                        eoc =1;
        !           675:                head_list->cStat = TLAN_CSTAT_UNUSED;
        !           676:                CIRC_INC(priv->txHead, TLAN_NUM_TX_LISTS);
        !           677:                head_list = priv->txList + priv->txHead;
        !           678:                
        !           679:        }
        !           680:        if(!ack)
        !           681:                printf("Incomplete TX Frame\n");
        !           682: 
        !           683:        if(eoc) {
        !           684:                head_list = priv->txList + priv->txHead;
        !           685:                if ((head_list->cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) {
        !           686:                        outl(virt_to_le32desc(head_list), BASE + TLAN_CH_PARM);
        !           687:                        ack |= TLAN_HC_GO;
        !           688:                } else {
        !           689:                        priv->txInProgress = 0;
        !           690:                }
        !           691:        }
        !           692:        if(ack) {
        !           693:                host_cmd = TLAN_HC_ACK | ack;
        !           694:                outl(host_cmd, BASE + TLAN_HOST_CMD);
        !           695:        }
        !           696:        
        !           697:        if(priv->tlanRev < 0x30 ) {
        !           698:                ack = 1;
        !           699:                head_list = priv->txList + priv->txHead;
        !           700:                if ((head_list->cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) {
        !           701:                        outl(virt_to_le32desc(head_list), BASE + TLAN_CH_PARM);
        !           702:                        ack |= TLAN_HC_GO;
        !           703:                } else {
        !           704:                        priv->txInProgress = 0;
        !           705:                }
        !           706:                host_cmd = TLAN_HC_ACK | ack | 0x00140000;
        !           707:                outl(host_cmd, BASE + TLAN_HOST_CMD);
        !           708:                
        !           709:        }
        !           710:                        
        !           711:        if (currticks() >= to) {
        !           712:                printf("TX Time Out");
        !           713:        }
        !           714: }
        !           715: 
        !           716: /**************************************************************************
        !           717: DISABLE - Turn off ethernet interface
        !           718: ***************************************************************************/
        !           719: static void tlan_disable ( struct nic *nic __unused ) {
        !           720:        /* put the card in its initial state */
        !           721:        /* This function serves 3 purposes.
        !           722:         * This disables DMA and interrupts so we don't receive
        !           723:         *  unexpected packets or interrupts from the card after
        !           724:         *  etherboot has finished.
        !           725:         * This frees resources so etherboot may use
        !           726:         *  this driver on another interface
        !           727:         * This allows etherboot to reinitialize the interface
        !           728:         *  if something is something goes wrong.
        !           729:         *
        !           730:         */
        !           731:        outl(TLAN_HC_AD_RST, BASE + TLAN_HOST_CMD);
        !           732: }
        !           733: 
        !           734: /**************************************************************************
        !           735: IRQ - Enable, Disable, or Force interrupts
        !           736: ***************************************************************************/
        !           737: static void tlan_irq(struct nic *nic __unused, irq_action_t action __unused)
        !           738: {
        !           739:   switch ( action ) {
        !           740:   case DISABLE :
        !           741:     break;
        !           742:   case ENABLE :
        !           743:     break;
        !           744:   case FORCE :
        !           745:     break;
        !           746:   }
        !           747: }
        !           748: 
        !           749: static struct nic_operations tlan_operations = {
        !           750:        .connect        = dummy_connect,
        !           751:        .poll           = tlan_poll,
        !           752:        .transmit       = tlan_transmit,
        !           753:        .irq            = tlan_irq,
        !           754: 
        !           755: };
        !           756: 
        !           757: static void TLan_SetMulticastList(struct nic *nic) {
        !           758:        int i;
        !           759:        u8 tmp;
        !           760: 
        !           761:        /* !IFF_PROMISC */
        !           762:        tmp = TLan_DioRead8(BASE, TLAN_NET_CMD);
        !           763:        TLan_DioWrite8(BASE, TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF);
        !           764: 
        !           765:        /* IFF_ALLMULTI */
        !           766:        for(i = 0; i< 3; i++)
        !           767:                TLan_SetMac(nic, i + 1, NULL);
        !           768:        TLan_DioWrite32(BASE, TLAN_HASH_1, 0xFFFFFFFF);
        !           769:        TLan_DioWrite32(BASE, TLAN_HASH_2, 0xFFFFFFFF);
        !           770: 
        !           771:        
        !           772: }
        !           773: /**************************************************************************
        !           774: PROBE - Look for an adapter, this routine's visible to the outside
        !           775: ***************************************************************************/
        !           776: 
        !           777: #define board_found 1
        !           778: #define valid_link 0
        !           779: static int tlan_probe ( struct nic *nic, struct pci_device *pci ) {
        !           780: 
        !           781:        u16 data = 0;
        !           782:        int err;
        !           783:        int i;
        !           784: 
        !           785:        if (pci->ioaddr == 0)
        !           786:                return 0;
        !           787: 
        !           788:        nic->irqno  = 0;
        !           789:        nic->ioaddr = pci->ioaddr;
        !           790: 
        !           791:        BASE = pci->ioaddr;
        !           792: 
        !           793:        /* Set nic as PCI bus master */
        !           794:        adjust_pci_device(pci);
        !           795:        
        !           796:        /* Point to private storage */
        !           797:        priv = &TLanPrivateInfo;
        !           798: 
        !           799:        /* Figure out which chip we're dealing with */
        !           800:        i = 0;
        !           801:        chip_idx = -1;
        !           802:        while (tlan_pci_tbl[i].name) {
        !           803:                if ((((u32) pci->device << 16) | pci->vendor) ==
        !           804:                    (tlan_pci_tbl[i].id.pci & 0xffffffff)) {
        !           805:                        chip_idx = i;
        !           806:                        break;
        !           807:                }
        !           808:                i++;
        !           809:        }
        !           810: 
        !           811:        priv->vendor_id = pci->vendor;
        !           812:        priv->dev_id = pci->device;
        !           813:        priv->nic_name = pci->id->name;
        !           814:        priv->eoc = 0;
        !           815: 
        !           816:        err = 0;
        !           817:        for (i = 0; i < 6; i++)
        !           818:                err |= TLan_EeReadByte(BASE,
        !           819:                                       (u8) tlan_pci_tbl[chip_idx].
        !           820:                                       addrOfs + i,
        !           821:                                       (u8 *) & nic->node_addr[i]);
        !           822:        if (err) {
        !           823:            printf ( "TLAN: %s: Error reading MAC from eeprom: %d\n",
        !           824:                    pci->id->name, err);
        !           825:        } else {
        !           826:            DBG ( "%s: %s at ioaddr %#lX, ", 
        !           827:                  pci->id->name, eth_ntoa ( nic->node_addr ), pci->ioaddr );
        !           828:        }
        !           829: 
        !           830:        priv->tlanRev = TLan_DioRead8(BASE, TLAN_DEF_REVISION);
        !           831:        printf("revision: 0x%hX\n", priv->tlanRev);
        !           832: 
        !           833:        TLan_ResetLists(nic);
        !           834:        TLan_ResetAdapter(nic);
        !           835: 
        !           836:        data = inl(BASE + TLAN_HOST_CMD);
        !           837:        data |= TLAN_HC_INT_OFF;
        !           838:        outw(data, BASE + TLAN_HOST_CMD);
        !           839: 
        !           840:        TLan_SetMulticastList(nic);
        !           841:        udelay(100); 
        !           842:        priv->txList = tx_ring;
        !           843: 
        !           844: /*     if (board_found && valid_link)
        !           845:        {*/
        !           846:        /* point to NIC specific routines */
        !           847:        nic->nic_op     = &tlan_operations;
        !           848:        return 1;
        !           849: }
        !           850: 
        !           851: 
        !           852: /*****************************************************************************
        !           853: ******************************************************************************
        !           854: 
        !           855:        ThunderLAN Driver Eeprom routines
        !           856: 
        !           857:        The Compaq Netelligent 10 and 10/100 cards use a Microchip 24C02A
        !           858:        EEPROM.  These functions are based on information in Microchip's
        !           859:        data sheet.  I don't know how well this functions will work with
        !           860:        other EEPROMs.
        !           861: 
        !           862: ******************************************************************************
        !           863: *****************************************************************************/
        !           864: 
        !           865: 
        !           866: /***************************************************************
        !           867: *      TLan_EeSendStart
        !           868: *
        !           869: *      Returns:
        !           870: *              Nothing
        !           871: *      Parms:
        !           872: *              io_base         The IO port base address for the
        !           873: *                              TLAN device with the EEPROM to
        !           874: *                              use.
        !           875: *
        !           876: *      This function sends a start cycle to an EEPROM attached
        !           877: *      to a TLAN chip.
        !           878: *
        !           879: **************************************************************/
        !           880: 
        !           881: void TLan_EeSendStart(u16 io_base)
        !           882: {
        !           883:        u16 sio;
        !           884: 
        !           885:        outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
        !           886:        sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
        !           887: 
        !           888:        TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
        !           889:        TLan_SetBit(TLAN_NET_SIO_EDATA, sio);
        !           890:        TLan_SetBit(TLAN_NET_SIO_ETXEN, sio);
        !           891:        TLan_ClearBit(TLAN_NET_SIO_EDATA, sio);
        !           892:        TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);
        !           893: 
        !           894: }      /* TLan_EeSendStart */
        !           895: 
        !           896: /***************************************************************
        !           897: *      TLan_EeSendByte
        !           898: *
        !           899: *      Returns:
        !           900: *              If the correct ack was received, 0, otherwise 1
        !           901: *      Parms:  io_base         The IO port base address for the
        !           902: *                              TLAN device with the EEPROM to
        !           903: *                              use.
        !           904: *              data            The 8 bits of information to
        !           905: *                              send to the EEPROM.
        !           906: *              stop            If TLAN_EEPROM_STOP is passed, a
        !           907: *                              stop cycle is sent after the
        !           908: *                              byte is sent after the ack is
        !           909: *                              read.
        !           910: *
        !           911: *      This function sends a byte on the serial EEPROM line,
        !           912: *      driving the clock to send each bit. The function then
        !           913: *      reverses transmission direction and reads an acknowledge
        !           914: *      bit.
        !           915: *
        !           916: **************************************************************/
        !           917: 
        !           918: int TLan_EeSendByte(u16 io_base, u8 data, int stop)
        !           919: {
        !           920:        int err;
        !           921:        u8 place;
        !           922:        u16 sio;
        !           923: 
        !           924:        outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
        !           925:        sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
        !           926: 
        !           927:        /* Assume clock is low, tx is enabled; */
        !           928:        for (place = 0x80; place != 0; place >>= 1) {
        !           929:                if (place & data)
        !           930:                        TLan_SetBit(TLAN_NET_SIO_EDATA, sio);
        !           931:                else
        !           932:                        TLan_ClearBit(TLAN_NET_SIO_EDATA, sio);
        !           933:                TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
        !           934:                TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);
        !           935:        }
        !           936:        TLan_ClearBit(TLAN_NET_SIO_ETXEN, sio);
        !           937:        TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
        !           938:        err = TLan_GetBit(TLAN_NET_SIO_EDATA, sio);
        !           939:        TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);
        !           940:        TLan_SetBit(TLAN_NET_SIO_ETXEN, sio);
        !           941: 
        !           942:        if ((!err) && stop) {
        !           943:                TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); /* STOP, raise data while clock is high */
        !           944:                TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
        !           945:                TLan_SetBit(TLAN_NET_SIO_EDATA, sio);
        !           946:        }
        !           947: 
        !           948:        return (err);
        !           949: 
        !           950: }      /* TLan_EeSendByte */
        !           951: 
        !           952: /***************************************************************
        !           953: *      TLan_EeReceiveByte
        !           954: *
        !           955: *      Returns:
        !           956: *              Nothing
        !           957: *      Parms:
        !           958: *              io_base         The IO port base address for the
        !           959: *                              TLAN device with the EEPROM to
        !           960: *                              use.
        !           961: *              data            An address to a char to hold the
        !           962: *                              data sent from the EEPROM.
        !           963: *              stop            If TLAN_EEPROM_STOP is passed, a
        !           964: *                              stop cycle is sent after the
        !           965: *                              byte is received, and no ack is
        !           966: *                              sent.
        !           967: *
        !           968: *      This function receives 8 bits of data from the EEPROM
        !           969: *      over the serial link.  It then sends and ack bit, or no
        !           970: *      ack and a stop bit.  This function is used to retrieve
        !           971: *      data after the address of a byte in the EEPROM has been
        !           972: *      sent.
        !           973: *
        !           974: **************************************************************/
        !           975: 
        !           976: void TLan_EeReceiveByte(u16 io_base, u8 * data, int stop)
        !           977: {
        !           978:        u8 place;
        !           979:        u16 sio;
        !           980: 
        !           981:        outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
        !           982:        sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
        !           983:        *data = 0;
        !           984: 
        !           985:        /* Assume clock is low, tx is enabled; */
        !           986:        TLan_ClearBit(TLAN_NET_SIO_ETXEN, sio);
        !           987:        for (place = 0x80; place; place >>= 1) {
        !           988:                TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
        !           989:                if (TLan_GetBit(TLAN_NET_SIO_EDATA, sio))
        !           990:                        *data |= place;
        !           991:                TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);
        !           992:        }
        !           993: 
        !           994:        TLan_SetBit(TLAN_NET_SIO_ETXEN, sio);
        !           995:        if (!stop) {
        !           996:                TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); /* Ack = 0 */
        !           997:                TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
        !           998:                TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);
        !           999:        } else {
        !          1000:                TLan_SetBit(TLAN_NET_SIO_EDATA, sio);   /* No ack = 1 (?) */
        !          1001:                TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
        !          1002:                TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);
        !          1003:                TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); /* STOP, raise data while clock is high */
        !          1004:                TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
        !          1005:                TLan_SetBit(TLAN_NET_SIO_EDATA, sio);
        !          1006:        }
        !          1007: 
        !          1008: }      /* TLan_EeReceiveByte */
        !          1009: 
        !          1010: /***************************************************************
        !          1011: *      TLan_EeReadByte
        !          1012: *
        !          1013: *      Returns:
        !          1014: *              No error = 0, else, the stage at which the error
        !          1015: *              occurred.
        !          1016: *      Parms:
        !          1017: *              io_base         The IO port base address for the
        !          1018: *                              TLAN device with the EEPROM to
        !          1019: *                              use.
        !          1020: *              ee_addr         The address of the byte in the
        !          1021: *                              EEPROM whose contents are to be
        !          1022: *                              retrieved.
        !          1023: *              data            An address to a char to hold the
        !          1024: *                              data obtained from the EEPROM.
        !          1025: *
        !          1026: *      This function reads a byte of information from an byte
        !          1027: *      cell in the EEPROM.
        !          1028: *
        !          1029: **************************************************************/
        !          1030: 
        !          1031: int TLan_EeReadByte(u16 io_base, u8 ee_addr, u8 * data)
        !          1032: {
        !          1033:        int err;
        !          1034:        int ret = 0;
        !          1035: 
        !          1036: 
        !          1037:        TLan_EeSendStart(io_base);
        !          1038:        err = TLan_EeSendByte(io_base, 0xA0, TLAN_EEPROM_ACK);
        !          1039:        if (err) {
        !          1040:                ret = 1;
        !          1041:                goto fail;
        !          1042:        }
        !          1043:        err = TLan_EeSendByte(io_base, ee_addr, TLAN_EEPROM_ACK);
        !          1044:        if (err) {
        !          1045:                ret = 2;
        !          1046:                goto fail;
        !          1047:        }
        !          1048:        TLan_EeSendStart(io_base);
        !          1049:        err = TLan_EeSendByte(io_base, 0xA1, TLAN_EEPROM_ACK);
        !          1050:        if (err) {
        !          1051:                ret = 3;
        !          1052:                goto fail;
        !          1053:        }
        !          1054:        TLan_EeReceiveByte(io_base, data, TLAN_EEPROM_STOP);
        !          1055:       fail:
        !          1056: 
        !          1057:        return ret;
        !          1058: 
        !          1059: }      /* TLan_EeReadByte */
        !          1060: 
        !          1061: 
        !          1062: /*****************************************************************************
        !          1063: ******************************************************************************
        !          1064: 
        !          1065: ThunderLAN Driver MII Routines
        !          1066: 
        !          1067: These routines are based on the information in Chap. 2 of the
        !          1068: "ThunderLAN Programmer's Guide", pp. 15-24.
        !          1069: 
        !          1070: ******************************************************************************
        !          1071: *****************************************************************************/
        !          1072: 
        !          1073: 
        !          1074: /***************************************************************
        !          1075: *      TLan_MiiReadReg
        !          1076: *
        !          1077: *      Returns:
        !          1078: *              0       if ack received ok
        !          1079: *              1       otherwise.
        !          1080: *
        !          1081: *      Parms:
        !          1082: *              dev             The device structure containing
        !          1083: *                              The io address and interrupt count
        !          1084: *                              for this device.
        !          1085: *              phy             The address of the PHY to be queried.
        !          1086: *              reg             The register whose contents are to be
        !          1087: *                              retreived.
        !          1088: *              val             A pointer to a variable to store the
        !          1089: *                              retrieved value.
        !          1090: *
        !          1091: *      This function uses the TLAN's MII bus to retreive the contents
        !          1092: *      of a given register on a PHY.  It sends the appropriate info
        !          1093: *      and then reads the 16-bit register value from the MII bus via
        !          1094: *      the TLAN SIO register.
        !          1095: *
        !          1096: **************************************************************/
        !          1097: 
        !          1098: int TLan_MiiReadReg(struct nic *nic __unused, u16 phy, u16 reg, u16 * val)
        !          1099: {
        !          1100:        u8 nack;
        !          1101:        u16 sio, tmp;
        !          1102:        u32 i;
        !          1103:        int err;
        !          1104:        int minten;
        !          1105: 
        !          1106:        err = FALSE;
        !          1107:        outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR);
        !          1108:        sio = BASE + TLAN_DIO_DATA + TLAN_NET_SIO;
        !          1109: 
        !          1110:        TLan_MiiSync(BASE);
        !          1111: 
        !          1112:        minten = TLan_GetBit(TLAN_NET_SIO_MINTEN, sio);
        !          1113:        if (minten)
        !          1114:                TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio);
        !          1115: 
        !          1116:        TLan_MiiSendData(BASE, 0x1, 2); /* Start ( 01b ) */
        !          1117:        TLan_MiiSendData(BASE, 0x2, 2); /* Read  ( 10b ) */
        !          1118:        TLan_MiiSendData(BASE, phy, 5); /* Device #      */
        !          1119:        TLan_MiiSendData(BASE, reg, 5); /* Register #    */
        !          1120: 
        !          1121: 
        !          1122:        TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio); /* Change direction */
        !          1123: 
        !          1124:        TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);  /* Clock Idle bit */
        !          1125:        TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
        !          1126:        TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);  /* Wait 300ns */
        !          1127: 
        !          1128:        nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio);    /* Check for ACK */
        !          1129:        TLan_SetBit(TLAN_NET_SIO_MCLK, sio);    /* Finish ACK */
        !          1130:        if (nack) {             /* No ACK, so fake it */
        !          1131:                for (i = 0; i < 16; i++) {
        !          1132:                        TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
        !          1133:                        TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
        !          1134:                }
        !          1135:                tmp = 0xffff;
        !          1136:                err = TRUE;
        !          1137:        } else {                /* ACK, so read data */
        !          1138:                for (tmp = 0, i = 0x8000; i; i >>= 1) {
        !          1139:                        TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
        !          1140:                        if (TLan_GetBit(TLAN_NET_SIO_MDATA, sio))
        !          1141:                                tmp |= i;
        !          1142:                        TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
        !          1143:                }
        !          1144:        }
        !          1145: 
        !          1146: 
        !          1147:        TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);  /* Idle cycle */
        !          1148:        TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
        !          1149: 
        !          1150:        if (minten)
        !          1151:                TLan_SetBit(TLAN_NET_SIO_MINTEN, sio);
        !          1152: 
        !          1153:        *val = tmp;
        !          1154: 
        !          1155:        return err;
        !          1156: 
        !          1157: }                              /* TLan_MiiReadReg */
        !          1158: 
        !          1159: /***************************************************************
        !          1160: *      TLan_MiiSendData
        !          1161: *
        !          1162: *      Returns:
        !          1163: *              Nothing
        !          1164: *      Parms:
        !          1165: *              base_port       The base IO port of the adapter in
        !          1166: *                              question.
        !          1167: *              dev             The address of the PHY to be queried.
        !          1168: *              data            The value to be placed on the MII bus.
        !          1169: *              num_bits        The number of bits in data that are to
        !          1170: *                              be placed on the MII bus.
        !          1171: *
        !          1172: *      This function sends on sequence of bits on the MII
        !          1173: *      configuration bus.
        !          1174: *
        !          1175: **************************************************************/
        !          1176: 
        !          1177: void TLan_MiiSendData(u16 base_port, u32 data, unsigned num_bits)
        !          1178: {
        !          1179:        u16 sio;
        !          1180:        u32 i;
        !          1181: 
        !          1182:        if (num_bits == 0)
        !          1183:                return;
        !          1184: 
        !          1185:        outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
        !          1186:        sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
        !          1187:        TLan_SetBit(TLAN_NET_SIO_MTXEN, sio);
        !          1188: 
        !          1189:        for (i = (0x1 << (num_bits - 1)); i; i >>= 1) {
        !          1190:                TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
        !          1191:                (void) TLan_GetBit(TLAN_NET_SIO_MCLK, sio);
        !          1192:                if (data & i)
        !          1193:                        TLan_SetBit(TLAN_NET_SIO_MDATA, sio);
        !          1194:                else
        !          1195:                        TLan_ClearBit(TLAN_NET_SIO_MDATA, sio);
        !          1196:                TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
        !          1197:                (void) TLan_GetBit(TLAN_NET_SIO_MCLK, sio);
        !          1198:        }
        !          1199: 
        !          1200: }                              /* TLan_MiiSendData */
        !          1201: 
        !          1202: /***************************************************************
        !          1203: *      TLan_MiiSync
        !          1204: *
        !          1205: *      Returns:
        !          1206: *              Nothing
        !          1207: *      Parms:
        !          1208: *              base_port       The base IO port of the adapter in
        !          1209: *                              question.
        !          1210: *
        !          1211: *      This functions syncs all PHYs in terms of the MII configuration
        !          1212: *      bus.
        !          1213: *
        !          1214: **************************************************************/
        !          1215: 
        !          1216: void TLan_MiiSync(u16 base_port)
        !          1217: {
        !          1218:        int i;
        !          1219:        u16 sio;
        !          1220: 
        !          1221:        outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
        !          1222:        sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
        !          1223: 
        !          1224:        TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio);
        !          1225:        for (i = 0; i < 32; i++) {
        !          1226:                TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
        !          1227:                TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
        !          1228:        }
        !          1229: 
        !          1230: }                              /* TLan_MiiSync */
        !          1231: 
        !          1232: /***************************************************************
        !          1233: *      TLan_MiiWriteReg
        !          1234: *
        !          1235: *      Returns:
        !          1236: *              Nothing
        !          1237: *      Parms:
        !          1238: *              dev             The device structure for the device
        !          1239: *                              to write to.
        !          1240: *              phy             The address of the PHY to be written to.
        !          1241: *              reg             The register whose contents are to be
        !          1242: *                              written.
        !          1243: *              val             The value to be written to the register.
        !          1244: *
        !          1245: *      This function uses the TLAN's MII bus to write the contents of a
        !          1246: *      given register on a PHY.  It sends the appropriate info and then
        !          1247: *      writes the 16-bit register value from the MII configuration bus
        !          1248: *      via the TLAN SIO register.
        !          1249: *
        !          1250: **************************************************************/
        !          1251: 
        !          1252: void TLan_MiiWriteReg(struct nic *nic __unused, u16 phy, u16 reg, u16 val)
        !          1253: {
        !          1254:        u16 sio;
        !          1255:        int minten;
        !          1256: 
        !          1257:        outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR);
        !          1258:        sio = BASE + TLAN_DIO_DATA + TLAN_NET_SIO;
        !          1259: 
        !          1260:        TLan_MiiSync(BASE);
        !          1261: 
        !          1262:        minten = TLan_GetBit(TLAN_NET_SIO_MINTEN, sio);
        !          1263:        if (minten)
        !          1264:                TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio);
        !          1265: 
        !          1266:        TLan_MiiSendData(BASE, 0x1, 2); /* Start ( 01b ) */
        !          1267:        TLan_MiiSendData(BASE, 0x1, 2); /* Write ( 01b ) */
        !          1268:        TLan_MiiSendData(BASE, phy, 5); /* Device #      */
        !          1269:        TLan_MiiSendData(BASE, reg, 5); /* Register #    */
        !          1270: 
        !          1271:        TLan_MiiSendData(BASE, 0x2, 2); /* Send ACK */
        !          1272:        TLan_MiiSendData(BASE, val, 16);        /* Send Data */
        !          1273: 
        !          1274:        TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);  /* Idle cycle */
        !          1275:        TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
        !          1276: 
        !          1277:        if (minten)
        !          1278:                TLan_SetBit(TLAN_NET_SIO_MINTEN, sio);
        !          1279: 
        !          1280: 
        !          1281: }                              /* TLan_MiiWriteReg */
        !          1282: 
        !          1283: /***************************************************************
        !          1284: *      TLan_SetMac
        !          1285: *
        !          1286: *      Returns:
        !          1287: *              Nothing
        !          1288: *      Parms:
        !          1289: *              dev     Pointer to device structure of adapter
        !          1290: *                      on which to change the AREG.
        !          1291: *              areg    The AREG to set the address in (0 - 3).
        !          1292: *              mac     A pointer to an array of chars.  Each
        !          1293: *                      element stores one byte of the address.
        !          1294: *                      IE, it isn't in ascii.
        !          1295: *
        !          1296: *      This function transfers a MAC address to one of the
        !          1297: *      TLAN AREGs (address registers).  The TLAN chip locks
        !          1298: *      the register on writing to offset 0 and unlocks the
        !          1299: *      register after writing to offset 5.  If NULL is passed
        !          1300: *      in mac, then the AREG is filled with 0's.
        !          1301: *
        !          1302: **************************************************************/
        !          1303: 
        !          1304: void TLan_SetMac(struct nic *nic __unused, int areg, unsigned char *mac)
        !          1305: {
        !          1306:        int i;
        !          1307: 
        !          1308:        areg *= 6;
        !          1309: 
        !          1310:        if (mac != NULL) {
        !          1311:                for (i = 0; i < 6; i++)
        !          1312:                        TLan_DioWrite8(BASE, TLAN_AREG_0 + areg + i,
        !          1313:                                       mac[i]);
        !          1314:        } else {
        !          1315:                for (i = 0; i < 6; i++)
        !          1316:                        TLan_DioWrite8(BASE, TLAN_AREG_0 + areg + i, 0);
        !          1317:        }
        !          1318: 
        !          1319: }                              /* TLan_SetMac */
        !          1320: 
        !          1321: /*********************************************************************
        !          1322: *      TLan_PhyDetect
        !          1323: *
        !          1324: *      Returns:
        !          1325: *              Nothing
        !          1326: *      Parms:
        !          1327: *              dev     A pointer to the device structure of the adapter
        !          1328: *                      for which the PHY needs determined.
        !          1329: *
        !          1330: *      So far I've found that adapters which have external PHYs
        !          1331: *      may also use the internal PHY for part of the functionality.
        !          1332: *      (eg, AUI/Thinnet).  This function finds out if this TLAN
        !          1333: *      chip has an internal PHY, and then finds the first external
        !          1334: *      PHY (starting from address 0) if it exists).
        !          1335: *
        !          1336: ********************************************************************/
        !          1337: 
        !          1338: void TLan_PhyDetect(struct nic *nic)
        !          1339: {
        !          1340:        u16 control;
        !          1341:        u16 hi;
        !          1342:        u16 lo;
        !          1343:        u32 phy;
        !          1344: 
        !          1345:        if (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_UNMANAGED_PHY) {
        !          1346:                priv->phyNum = 0xFFFF;
        !          1347:                return;
        !          1348:        }
        !          1349: 
        !          1350:        TLan_MiiReadReg(nic, TLAN_PHY_MAX_ADDR, MII_PHYSID1, &hi);
        !          1351: 
        !          1352:        if (hi != 0xFFFF) {
        !          1353:                priv->phy[0] = TLAN_PHY_MAX_ADDR;
        !          1354:        } else {
        !          1355:                priv->phy[0] = TLAN_PHY_NONE;
        !          1356:        }
        !          1357: 
        !          1358:        priv->phy[1] = TLAN_PHY_NONE;
        !          1359:        for (phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++) {
        !          1360:                TLan_MiiReadReg(nic, phy, MII_BMCR, &control);
        !          1361:                TLan_MiiReadReg(nic, phy, MII_PHYSID1, &hi);
        !          1362:                TLan_MiiReadReg(nic, phy, MII_PHYSID2, &lo);
        !          1363:                if ((control != 0xFFFF) || (hi != 0xFFFF)
        !          1364:                    || (lo != 0xFFFF)) {
        !          1365:                        printf("PHY found at %hX %hX %hX %hX\n", 
        !          1366:                               (unsigned int) phy, control, hi, lo);
        !          1367:                        if ((priv->phy[1] == TLAN_PHY_NONE)
        !          1368:                            && (phy != TLAN_PHY_MAX_ADDR)) {
        !          1369:                                priv->phy[1] = phy;
        !          1370:                        }
        !          1371:                }
        !          1372:        }
        !          1373: 
        !          1374:        if (priv->phy[1] != TLAN_PHY_NONE) {
        !          1375:                priv->phyNum = 1;
        !          1376:        } else if (priv->phy[0] != TLAN_PHY_NONE) {
        !          1377:                priv->phyNum = 0;
        !          1378:        } else {
        !          1379:                printf
        !          1380:                    ("TLAN:  Cannot initialize device, no PHY was found!\n");
        !          1381:        }
        !          1382: 
        !          1383: }                              /* TLan_PhyDetect */
        !          1384: 
        !          1385: void TLan_PhyPowerDown(struct nic *nic)
        !          1386: {
        !          1387: 
        !          1388:        u16 value;
        !          1389:        DBG ( "%s: Powering down PHY(s).\n", priv->nic_name );
        !          1390:        value = BMCR_PDOWN | BMCR_LOOPBACK | BMCR_ISOLATE;
        !          1391:        TLan_MiiSync(BASE);
        !          1392:        TLan_MiiWriteReg(nic, priv->phy[priv->phyNum], MII_BMCR, value);
        !          1393:        if ((priv->phyNum == 0) && (priv->phy[1] != TLAN_PHY_NONE)
        !          1394:            &&
        !          1395:            (!(tlan_pci_tbl[chip_idx].
        !          1396:               flags & TLAN_ADAPTER_USE_INTERN_10))) {
        !          1397:                TLan_MiiSync(BASE);
        !          1398:                TLan_MiiWriteReg(nic, priv->phy[1], MII_BMCR, value);
        !          1399:        }
        !          1400: 
        !          1401:        /* Wait for 50 ms and powerup
        !          1402:         * This is abitrary.  It is intended to make sure the
        !          1403:         * tranceiver settles.
        !          1404:         */
        !          1405:        /* TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP ); */
        !          1406:        mdelay(50);
        !          1407:        TLan_PhyPowerUp(nic);
        !          1408: 
        !          1409: }                              /* TLan_PhyPowerDown */
        !          1410: 
        !          1411: 
        !          1412: void TLan_PhyPowerUp(struct nic *nic)
        !          1413: {
        !          1414:        u16 value;
        !          1415: 
        !          1416:        DBG ( "%s: Powering up PHY.\n", priv->nic_name );
        !          1417:        TLan_MiiSync(BASE);
        !          1418:        value = BMCR_LOOPBACK;
        !          1419:        TLan_MiiWriteReg(nic, priv->phy[priv->phyNum], MII_BMCR, value);
        !          1420:        TLan_MiiSync(BASE);
        !          1421:        /* Wait for 500 ms and reset the
        !          1422:         * tranceiver.  The TLAN docs say both 50 ms and
        !          1423:         * 500 ms, so do the longer, just in case.
        !          1424:         */
        !          1425:        mdelay(500);
        !          1426:        TLan_PhyReset(nic);
        !          1427:        /* TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET ); */
        !          1428: 
        !          1429: }                              /* TLan_PhyPowerUp */
        !          1430: 
        !          1431: void TLan_PhyReset(struct nic *nic)
        !          1432: {
        !          1433:        u16 phy;
        !          1434:        u16 value;
        !          1435: 
        !          1436:        phy = priv->phy[priv->phyNum];
        !          1437: 
        !          1438:        DBG ( "%s: Reseting PHY.\n", priv->nic_name );
        !          1439:        TLan_MiiSync(BASE);
        !          1440:        value = BMCR_LOOPBACK | BMCR_RESET;
        !          1441:        TLan_MiiWriteReg(nic, phy, MII_BMCR, value);
        !          1442:        TLan_MiiReadReg(nic, phy, MII_BMCR, &value);
        !          1443:        while (value & BMCR_RESET) {
        !          1444:                TLan_MiiReadReg(nic, phy, MII_BMCR, &value);
        !          1445:        }
        !          1446: 
        !          1447:        /* Wait for 500 ms and initialize.
        !          1448:         * I don't remember why I wait this long.
        !          1449:         * I've changed this to 50ms, as it seems long enough.
        !          1450:         */
        !          1451:        /* TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_START_LINK ); */
        !          1452:        mdelay(50);
        !          1453:        TLan_PhyStartLink(nic);
        !          1454: 
        !          1455: }                              /* TLan_PhyReset */
        !          1456: 
        !          1457: 
        !          1458: void TLan_PhyStartLink(struct nic *nic)
        !          1459: {
        !          1460: 
        !          1461:        u16 ability;
        !          1462:        u16 control;
        !          1463:        u16 data;
        !          1464:        u16 phy;
        !          1465:        u16 status;
        !          1466:        u16 tctl;
        !          1467: 
        !          1468:        phy = priv->phy[priv->phyNum];
        !          1469:        DBG ( "%s: Trying to activate link.\n", priv->nic_name );
        !          1470:        TLan_MiiReadReg(nic, phy, MII_BMSR, &status);
        !          1471:        TLan_MiiReadReg(nic, phy, MII_BMSR, &ability);
        !          1472: 
        !          1473:        if ((status & BMSR_ANEGCAPABLE) && (!priv->aui)) {
        !          1474:                ability = status >> 11;
        !          1475:                if (priv->speed == TLAN_SPEED_10 &&
        !          1476:                    priv->duplex == TLAN_DUPLEX_HALF) {
        !          1477:                        TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x0000);
        !          1478:                } else if (priv->speed == TLAN_SPEED_10 &&
        !          1479:                           priv->duplex == TLAN_DUPLEX_FULL) {
        !          1480:                        priv->tlanFullDuplex = TRUE;
        !          1481:                        TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x0100);
        !          1482:                } else if (priv->speed == TLAN_SPEED_100 &&
        !          1483:                           priv->duplex == TLAN_DUPLEX_HALF) {
        !          1484:                        TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x2000);
        !          1485:                } else if (priv->speed == TLAN_SPEED_100 &&
        !          1486:                           priv->duplex == TLAN_DUPLEX_FULL) {
        !          1487:                        priv->tlanFullDuplex = TRUE;
        !          1488:                        TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x2100);
        !          1489:                } else {
        !          1490: 
        !          1491:                        /* Set Auto-Neg advertisement */
        !          1492:                        TLan_MiiWriteReg(nic, phy, MII_ADVERTISE,
        !          1493:                                         (ability << 5) | 1);
        !          1494:                        /* Enablee Auto-Neg */
        !          1495:                        TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x1000);
        !          1496:                        /* Restart Auto-Neg */
        !          1497:                        TLan_MiiWriteReg(nic, phy, MII_BMCR, 0x1200);
        !          1498:                        /* Wait for 4 sec for autonegotiation
        !          1499:                         * to complete.  The max spec time is less than this
        !          1500:                         * but the card need additional time to start AN.
        !          1501:                         * .5 sec should be plenty extra.
        !          1502:                         */
        !          1503:                        DBG ( "TLAN: %s: Starting autonegotiation.\n",
        !          1504:                               priv->nic_name );
        !          1505:                        mdelay(4000);
        !          1506:                        TLan_PhyFinishAutoNeg(nic);
        !          1507:                        /* TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN ); */
        !          1508:                        return;
        !          1509:                }
        !          1510: 
        !          1511:        }
        !          1512: 
        !          1513:        if ((priv->aui) && (priv->phyNum != 0)) {
        !          1514:                priv->phyNum = 0;
        !          1515:                data =
        !          1516:                    TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN |
        !          1517:                    TLAN_NET_CFG_PHY_EN;
        !          1518:                TLan_DioWrite16(BASE, TLAN_NET_CONFIG, data);
        !          1519:                mdelay(50);
        !          1520:                /* TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN ); */
        !          1521:                TLan_PhyPowerDown(nic);
        !          1522:                return;
        !          1523:        } else if (priv->phyNum == 0) {
        !          1524:                control = 0;
        !          1525:                TLan_MiiReadReg(nic, phy, TLAN_TLPHY_CTL, &tctl);
        !          1526:                if (priv->aui) {
        !          1527:                        tctl |= TLAN_TC_AUISEL;
        !          1528:                } else {
        !          1529:                        tctl &= ~TLAN_TC_AUISEL;
        !          1530:                        if (priv->duplex == TLAN_DUPLEX_FULL) {
        !          1531:                                control |= BMCR_FULLDPLX;
        !          1532:                                priv->tlanFullDuplex = TRUE;
        !          1533:                        }
        !          1534:                        if (priv->speed == TLAN_SPEED_100) {
        !          1535:                                control |= BMCR_SPEED100;
        !          1536:                        }
        !          1537:                }
        !          1538:                TLan_MiiWriteReg(nic, phy, MII_BMCR, control);
        !          1539:                TLan_MiiWriteReg(nic, phy, TLAN_TLPHY_CTL, tctl);
        !          1540:        }
        !          1541: 
        !          1542:        /* Wait for 2 sec to give the tranceiver time
        !          1543:         * to establish link.
        !          1544:         */
        !          1545:        /* TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET ); */
        !          1546:        mdelay(2000);
        !          1547:        TLan_FinishReset(nic);
        !          1548: 
        !          1549: }                              /* TLan_PhyStartLink */
        !          1550: 
        !          1551: void TLan_PhyFinishAutoNeg(struct nic *nic)
        !          1552: {
        !          1553: 
        !          1554:        u16 an_adv;
        !          1555:        u16 an_lpa;
        !          1556:        u16 data;
        !          1557:        u16 mode;
        !          1558:        u16 phy;
        !          1559:        u16 status;
        !          1560: 
        !          1561:        phy = priv->phy[priv->phyNum];
        !          1562: 
        !          1563:        TLan_MiiReadReg(nic, phy, MII_BMSR, &status);
        !          1564:        udelay(1000);
        !          1565:        TLan_MiiReadReg(nic, phy, MII_BMSR, &status);
        !          1566: 
        !          1567:        if (!(status & BMSR_ANEGCOMPLETE)) {
        !          1568:                /* Wait for 8 sec to give the process
        !          1569:                 * more time.  Perhaps we should fail after a while.
        !          1570:                 */
        !          1571:                if (!priv->neg_be_verbose++) {
        !          1572:                        printf
        !          1573:                            ("TLAN:  Giving autonegotiation more time.\n");
        !          1574:                        printf
        !          1575:                            ("TLAN:  Please check that your adapter has\n");
        !          1576:                        printf
        !          1577:                            ("TLAN:  been properly connected to a HUB or Switch.\n");
        !          1578:                        printf
        !          1579:                            ("TLAN:  Trying to establish link in the background...\n");
        !          1580:                }
        !          1581:                mdelay(8000);
        !          1582:                TLan_PhyFinishAutoNeg(nic);
        !          1583:                /* TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN ); */
        !          1584:                return;
        !          1585:        }
        !          1586: 
        !          1587:        DBG ( "TLAN: %s: Autonegotiation complete.\n", priv->nic_name );
        !          1588:        TLan_MiiReadReg(nic, phy, MII_ADVERTISE, &an_adv);
        !          1589:        TLan_MiiReadReg(nic, phy, MII_LPA, &an_lpa);
        !          1590:        mode = an_adv & an_lpa & 0x03E0;
        !          1591:        if (mode & 0x0100) {
        !          1592:                printf("Full Duplex\n");
        !          1593:                priv->tlanFullDuplex = TRUE;
        !          1594:        } else if (!(mode & 0x0080) && (mode & 0x0040)) {
        !          1595:                priv->tlanFullDuplex = TRUE;
        !          1596:                printf("Full Duplex\n");
        !          1597:        }
        !          1598: 
        !          1599:        if ((!(mode & 0x0180))
        !          1600:            && (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_USE_INTERN_10)
        !          1601:            && (priv->phyNum != 0)) {
        !          1602:                priv->phyNum = 0;
        !          1603:                data =
        !          1604:                    TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN |
        !          1605:                    TLAN_NET_CFG_PHY_EN;
        !          1606:                TLan_DioWrite16(BASE, TLAN_NET_CONFIG, data);
        !          1607:                /* TLan_SetTimer( nic, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN ); */
        !          1608:                mdelay(400);
        !          1609:                TLan_PhyPowerDown(nic);
        !          1610:                return;
        !          1611:        }
        !          1612: 
        !          1613:        if (priv->phyNum == 0) {
        !          1614:                if ((priv->duplex == TLAN_DUPLEX_FULL)
        !          1615:                    || (an_adv & an_lpa & 0x0040)) {
        !          1616:                        TLan_MiiWriteReg(nic, phy, MII_BMCR,
        !          1617:                                         BMCR_ANENABLE | BMCR_FULLDPLX);
        !          1618:                        DBG 
        !          1619:                            ( "TLAN:  Starting internal PHY with FULL-DUPLEX\n" );
        !          1620:                } else {
        !          1621:                        TLan_MiiWriteReg(nic, phy, MII_BMCR,
        !          1622:                                         BMCR_ANENABLE);
        !          1623:                        DBG 
        !          1624:                            ( "TLAN:  Starting internal PHY with HALF-DUPLEX\n" );
        !          1625:                }
        !          1626:        }
        !          1627: 
        !          1628:        /* Wait for 100 ms.  No reason in partiticular.
        !          1629:         */
        !          1630:        /* TLan_SetTimer( dev, (HZ/10), TLAN_TIMER_FINISH_RESET ); */
        !          1631:        mdelay(100);
        !          1632:        TLan_FinishReset(nic);
        !          1633: 
        !          1634: }                              /* TLan_PhyFinishAutoNeg */
        !          1635: 
        !          1636: #ifdef MONITOR
        !          1637: 
        !          1638: /*********************************************************************
        !          1639: *
        !          1640: *      TLan_phyMonitor
        !          1641: *
        !          1642: *      Returns:
        !          1643: *              None
        !          1644: *
        !          1645: *      Params:
        !          1646: *              dev             The device structure of this device.
        !          1647: *
        !          1648: *
        !          1649: *      This function monitors PHY condition by reading the status
        !          1650: *      register via the MII bus. This can be used to give info
        !          1651: *      about link changes (up/down), and possible switch to alternate
        !          1652: *      media.
        !          1653: *
        !          1654: ********************************************************************/
        !          1655: 
        !          1656: void TLan_PhyMonitor(struct net_device *dev)
        !          1657: {
        !          1658:        TLanPrivateInfo *priv = dev->priv;
        !          1659:        u16 phy;
        !          1660:        u16 phy_status;
        !          1661: 
        !          1662:        phy = priv->phy[priv->phyNum];
        !          1663: 
        !          1664:        /* Get PHY status register */
        !          1665:        TLan_MiiReadReg(nic, phy, MII_BMSR, &phy_status);
        !          1666: 
        !          1667:        /* Check if link has been lost */
        !          1668:        if (!(phy_status & BMSR_LSTATUS)) {
        !          1669:                if (priv->link) {
        !          1670:                        priv->link = 0;
        !          1671:                        printf("TLAN: %s has lost link\n", priv->nic_name);
        !          1672:                        priv->flags &= ~IFF_RUNNING;
        !          1673:                        mdelay(2000);
        !          1674:                        TLan_PhyMonitor(nic);
        !          1675:                        /* TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); */
        !          1676:                        return;
        !          1677:                }
        !          1678:        }
        !          1679: 
        !          1680:        /* Link restablished? */
        !          1681:        if ((phy_status & BMSR_LSTATUS) && !priv->link) {
        !          1682:                priv->link = 1;
        !          1683:                printf("TLAN: %s has reestablished link\n",
        !          1684:                       priv->nic_name);
        !          1685:                priv->flags |= IFF_RUNNING;
        !          1686:        }
        !          1687: 
        !          1688:        /* Setup a new monitor */
        !          1689:        /* TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); */
        !          1690:        mdelay(2000);
        !          1691:        TLan_PhyMonitor(nic);
        !          1692: }
        !          1693: 
        !          1694: #endif                         /* MONITOR */
        !          1695: 
        !          1696: static struct pci_device_id tlan_nics[] = {
        !          1697:        PCI_ROM(0x0e11, 0xae34, "netel10", "Compaq Netelligent 10 T PCI UTP", 0),
        !          1698:        PCI_ROM(0x0e11, 0xae32, "netel100","Compaq Netelligent 10/100 TX PCI UTP", 0),
        !          1699:        PCI_ROM(0x0e11, 0xae35, "netflex3i", "Compaq Integrated NetFlex-3/P", 0),
        !          1700:        PCI_ROM(0x0e11, 0xf130, "thunder", "Compaq NetFlex-3/P", 0),
        !          1701:        PCI_ROM(0x0e11, 0xf150, "netflex3b", "Compaq NetFlex-3/P", 0),
        !          1702:        PCI_ROM(0x0e11, 0xae43, "netel100pi", "Compaq Netelligent Integrated 10/100 TX UTP", 0),
        !          1703:        PCI_ROM(0x0e11, 0xae40, "netel100d", "Compaq Netelligent Dual 10/100 TX PCI UTP", 0),
        !          1704:        PCI_ROM(0x0e11, 0xb011, "netel100i", "Compaq Netelligent 10/100 TX Embedded UTP", 0),
        !          1705:        PCI_ROM(0x108d, 0x0013, "oc2183", "Olicom OC-2183/2185", 0),
        !          1706:        PCI_ROM(0x108d, 0x0012, "oc2325", "Olicom OC-2325", 0),
        !          1707:        PCI_ROM(0x108d, 0x0014, "oc2326", "Olicom OC-2326", 0),
        !          1708:        PCI_ROM(0x0e11, 0xb030, "netelligent_10_100_ws_5100", "Compaq Netelligent 10/100 TX UTP", 0),
        !          1709:        PCI_ROM(0x0e11, 0xb012, "netelligent_10_t2", "Compaq Netelligent 10 T/2 PCI UTP/Coax", 0),
        !          1710: };
        !          1711: 
        !          1712: PCI_DRIVER ( tlan_driver, tlan_nics, PCI_NO_CLASS );
        !          1713: 
        !          1714: DRIVER ( "TLAN/PCI", nic_driver, pci_driver, tlan_driver,
        !          1715:         tlan_probe, tlan_disable );
        !          1716: 
        !          1717: /*
        !          1718:  * Local variables:
        !          1719:  *  c-basic-offset: 8
        !          1720:  *  c-indent-level: 8
        !          1721:  *  tab-width: 8
        !          1722:  * End:
        !          1723:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.