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

1.1     ! root        1: /**************************************************************************
        !             2: *
        !             3: *    dmfe.c -- Etherboot device driver for the Davicom 
        !             4: *      DM9102/DM9102A/DM9102A+DM9801/DM9102A+DM9802 NIC fast ethernet card
        !             5: *
        !             6: *    Written 2003-2003 by Timothy Legge <[email protected]>
        !             7: *
        !             8: *    This program is free software; you can redistribute it and/or modify
        !             9: *    it under the terms of the GNU General Public License as published by
        !            10: *    the Free Software Foundation; either version 2 of the License, or
        !            11: *    (at your option) any later version.
        !            12: *
        !            13: *    This program is distributed in the hope that it will be useful,
        !            14: *    but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            15: *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            16: *    GNU General Public License for more details.
        !            17: *
        !            18: *    You should have received a copy of the GNU General Public License
        !            19: *    along with this program; if not, write to the Free Software
        !            20: *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            21: *
        !            22: *    Portions of this code based on:
        !            23: *
        !            24: *       dmfe.c:     A Davicom DM9102/DM9102A/DM9102A+DM9801/DM9102A+DM9802 
        !            25: *              NIC fast ethernet driver for Linux.
        !            26: *       Copyright (C) 1997  Sten Wang
        !            27: *       (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
        !            28: *
        !            29: *
        !            30: *    REVISION HISTORY:
        !            31: *    ================
        !            32: *    v1.0       10-02-2004      timlegge        Boots ltsp needs cleanup 
        !            33: *
        !            34: *    Indent Options: indent -kr -i8
        !            35: *
        !            36: *
        !            37: ***************************************************************************/
        !            38: 
        !            39: FILE_LICENCE ( GPL2_OR_LATER );
        !            40: 
        !            41: /* to get some global routines like printf */
        !            42: #include "etherboot.h"
        !            43: /* to get the interface to the body of the program */
        !            44: #include "nic.h"
        !            45: /* to get the PCI support functions, if this is a PCI NIC */
        !            46: #include <ipxe/pci.h>
        !            47: #include <ipxe/ethernet.h>
        !            48: 
        !            49: /* #define EDEBUG 1 */
        !            50: #ifdef EDEBUG
        !            51: #define dprintf(x) printf x
        !            52: #else
        !            53: #define dprintf(x)
        !            54: #endif
        !            55: 
        !            56: /* Condensed operations for readability. */
        !            57: #define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
        !            58: #define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
        !            59: 
        !            60: /* Board/System/Debug information/definition ---------------- */
        !            61: #define PCI_DM9132_ID   0x91321282     /* Davicom DM9132 ID */
        !            62: #define PCI_DM9102_ID   0x91021282     /* Davicom DM9102 ID */
        !            63: #define PCI_DM9100_ID   0x91001282     /* Davicom DM9100 ID */
        !            64: #define PCI_DM9009_ID   0x90091282     /* Davicom DM9009 ID */
        !            65: 
        !            66: #define DM9102_IO_SIZE  0x80
        !            67: #define DM9102A_IO_SIZE 0x100
        !            68: #define TX_MAX_SEND_CNT 0x1    /* Maximum tx packet per time */
        !            69: #define TX_DESC_CNT     0x10   /* Allocated Tx descriptors */
        !            70: #define RX_DESC_CNT     0x20   /* Allocated Rx descriptors */
        !            71: #define TX_FREE_DESC_CNT (TX_DESC_CNT - 2)     /* Max TX packet count */
        !            72: #define TX_WAKE_DESC_CNT (TX_DESC_CNT - 3)     /* TX wakeup count */
        !            73: #define DESC_ALL_CNT    (TX_DESC_CNT + RX_DESC_CNT)
        !            74: #define TX_BUF_ALLOC    0x600
        !            75: #define RX_ALLOC_SIZE   0x620
        !            76: #define DM910X_RESET    1
        !            77: #define CR0_DEFAULT     0x00E00000     /* TX & RX burst mode */
        !            78: #define CR6_DEFAULT     0x00080000     /* HD */
        !            79: #define CR7_DEFAULT     0x180c1
        !            80: #define CR15_DEFAULT    0x06   /* TxJabber RxWatchdog */
        !            81: #define TDES0_ERR_MASK  0x4302 /* TXJT, LC, EC, FUE */
        !            82: #define MAX_PACKET_SIZE 1514
        !            83: #define DMFE_MAX_MULTICAST 14
        !            84: #define RX_COPY_SIZE   100
        !            85: #define MAX_CHECK_PACKET 0x8000
        !            86: #define DM9801_NOISE_FLOOR 8
        !            87: #define DM9802_NOISE_FLOOR 5
        !            88: 
        !            89: #define DMFE_10MHF      0
        !            90: #define DMFE_100MHF     1
        !            91: #define DMFE_10MFD      4
        !            92: #define DMFE_100MFD     5
        !            93: #define DMFE_AUTO       8
        !            94: #define DMFE_1M_HPNA    0x10
        !            95: 
        !            96: #define DMFE_TXTH_72   0x400000        /* TX TH 72 byte */
        !            97: #define DMFE_TXTH_96   0x404000        /* TX TH 96 byte */
        !            98: #define DMFE_TXTH_128  0x0000  /* TX TH 128 byte */
        !            99: #define DMFE_TXTH_256  0x4000  /* TX TH 256 byte */
        !           100: #define DMFE_TXTH_512  0x8000  /* TX TH 512 byte */
        !           101: #define DMFE_TXTH_1K   0xC000  /* TX TH 1K  byte */
        !           102: 
        !           103: #define DMFE_TIMER_WUT  (jiffies + HZ * 1)     /* timer wakeup time : 1 second */
        !           104: #define DMFE_TX_TIMEOUT ((3*HZ)/2)     /* tx packet time-out time 1.5 s" */
        !           105: #define DMFE_TX_KICK   (HZ/2)  /* tx packet Kick-out time 0.5 s" */
        !           106: 
        !           107: #define DMFE_DBUG(dbug_now, msg, value) if (dmfe_debug || (dbug_now)) printk(KERN_ERR DRV_NAME ": %s %lx\n", (msg), (long) (value))
        !           108: 
        !           109: #define SHOW_MEDIA_TYPE(mode) printk(KERN_ERR DRV_NAME ": Change Speed to %sMhz %s duplex\n",mode & 1 ?"100":"10", mode & 4 ? "full":"half");
        !           110: 
        !           111: 
        !           112: /* CR9 definition: SROM/MII */
        !           113: #define CR9_SROM_READ   0x4800
        !           114: #define CR9_SRCS        0x1
        !           115: #define CR9_SRCLK       0x2
        !           116: #define CR9_CRDOUT      0x8
        !           117: #define SROM_DATA_0     0x0
        !           118: #define SROM_DATA_1     0x4
        !           119: #define PHY_DATA_1      0x20000
        !           120: #define PHY_DATA_0      0x00000
        !           121: #define MDCLKH          0x10000
        !           122: 
        !           123: #define PHY_POWER_DOWN 0x800
        !           124: 
        !           125: #define SROM_V41_CODE   0x14
        !           126: 
        !           127: #define SROM_CLK_WRITE(data, ioaddr) outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);udelay(5);outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr);udelay(5);outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);udelay(5);
        !           128: 
        !           129: #define __CHK_IO_SIZE(pci_id, dev_rev) ( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x02000030) ) ? DM9102A_IO_SIZE: DM9102_IO_SIZE
        !           130: #define CHK_IO_SIZE(pci_dev, dev_rev) __CHK_IO_SIZE(((pci_dev)->device << 16) | (pci_dev)->vendor, dev_rev)
        !           131: 
        !           132: /* Sten Check */
        !           133: #define DEVICE net_device
        !           134: 
        !           135: /* Structure/enum declaration ------------------------------- */
        !           136: struct tx_desc {
        !           137:        u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */
        !           138:        void * tx_buf_ptr;              /* Data for us */
        !           139:        struct tx_desc * next_tx_desc;
        !           140: } __attribute__ ((aligned(32)));
        !           141: 
        !           142: struct rx_desc {
        !           143:        u32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */
        !           144:        void * rx_skb_ptr;              /* Data for us */
        !           145:        struct rx_desc * next_rx_desc;
        !           146: } __attribute__ ((aligned(32)));
        !           147: 
        !           148: static struct dmfe_private {
        !           149:        u32 chip_id;            /* Chip vendor/Device ID */
        !           150:        u32 chip_revision;      /* Chip revision */
        !           151:        u32 cr0_data;
        !           152: //     u32 cr5_data;
        !           153:        u32 cr6_data;
        !           154:        u32 cr7_data;
        !           155:        u32 cr15_data;
        !           156: 
        !           157:        u16 HPNA_command;       /* For HPNA register 16 */
        !           158:        u16 HPNA_timer;         /* For HPNA remote device check */
        !           159:        u16 NIC_capability;     /* NIC media capability */
        !           160:        u16 PHY_reg4;           /* Saved Phyxcer register 4 value */
        !           161: 
        !           162:        u8 HPNA_present;        /* 0:none, 1:DM9801, 2:DM9802 */
        !           163:        u8 chip_type;           /* Keep DM9102A chip type */
        !           164:        u8 media_mode;          /* user specify media mode */
        !           165:        u8 op_mode;             /* real work media mode */
        !           166:        u8 phy_addr;
        !           167:        u8 dm910x_chk_mode;     /* Operating mode check */
        !           168: 
        !           169:        /* NIC SROM data */
        !           170:        unsigned char srom[128];
        !           171:        /* Etherboot Only */
        !           172:        u8 cur_tx;
        !           173:        u8 cur_rx;
        !           174: } dfx;
        !           175: 
        !           176: static struct dmfe_private *db;
        !           177: 
        !           178: enum dmfe_offsets {
        !           179:        DCR0 = 0x00, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20,
        !           180:        DCR5 = 0x28, DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48,
        !           181:        DCR10 = 0x50, DCR11 = 0x58, DCR12 = 0x60, DCR13 = 0x68, DCR14 =
        !           182:            0x70,
        !           183:        DCR15 = 0x78
        !           184: };
        !           185: 
        !           186: enum dmfe_CR6_bits {
        !           187:        CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80,
        !           188:        CR6_FDM = 0x200, CR6_TXSC = 0x2000, CR6_STI = 0x100000,
        !           189:        CR6_SFT = 0x200000, CR6_RXA = 0x40000000, CR6_NO_PURGE = 0x20000000
        !           190: };
        !           191: 
        !           192: /* Global variable declaration ----------------------------- */
        !           193: static struct nic_operations dmfe_operations;
        !           194: 
        !           195: static unsigned char dmfe_media_mode = DMFE_AUTO;
        !           196: static u32 dmfe_cr6_user_set;
        !           197: 
        !           198: /* For module input parameter */
        !           199: static u8 chkmode = 1;
        !           200: static u8 HPNA_mode;           /* Default: Low Power/High Speed */
        !           201: static u8 HPNA_rx_cmd;         /* Default: Disable Rx remote command */
        !           202: static u8 HPNA_tx_cmd;         /* Default: Don't issue remote command */
        !           203: static u8 HPNA_NoiseFloor;     /* Default: HPNA NoiseFloor */
        !           204: static u8 SF_mode;             /* Special Function: 1:VLAN, 2:RX Flow Control
        !           205:                                   4: TX pause packet */
        !           206: 
        !           207: 
        !           208: /**********************************************
        !           209: * Descriptor Ring and Buffer defination
        !           210: ***********************************************/
        !           211: struct {
        !           212:        struct tx_desc txd[TX_DESC_CNT] __attribute__ ((aligned(32)));
        !           213:        unsigned char txb[TX_BUF_ALLOC * TX_DESC_CNT]
        !           214:        __attribute__ ((aligned(32)));
        !           215:        struct rx_desc rxd[RX_DESC_CNT] __attribute__ ((aligned(32)));
        !           216:        unsigned char rxb[RX_ALLOC_SIZE * RX_DESC_CNT]
        !           217:        __attribute__ ((aligned(32)));
        !           218: } dmfe_bufs __shared;
        !           219: #define txd dmfe_bufs.txd
        !           220: #define txb dmfe_bufs.txb
        !           221: #define rxd dmfe_bufs.rxd
        !           222: #define rxb dmfe_bufs.rxb
        !           223: 
        !           224: /* NIC specific static variables go here */
        !           225: static long int BASE;
        !           226: 
        !           227: static u16 read_srom_word(long ioaddr, int offset);
        !           228: static void dmfe_init_dm910x(struct nic *nic);
        !           229: static void dmfe_descriptor_init(struct nic *, unsigned long ioaddr);
        !           230: static void update_cr6(u32, unsigned long);
        !           231: static void send_filter_frame(struct nic *nic);
        !           232: static void dm9132_id_table(struct nic *nic);
        !           233: 
        !           234: static u16 phy_read(unsigned long, u8, u8, u32);
        !           235: static void phy_write(unsigned long, u8, u8, u16, u32);
        !           236: static void phy_write_1bit(unsigned long, u32);
        !           237: static u16 phy_read_1bit(unsigned long);
        !           238: static void dmfe_set_phyxcer(struct nic *nic);
        !           239: 
        !           240: static void dmfe_parse_srom(struct nic *nic);
        !           241: static void dmfe_program_DM9801(struct nic *nic, int);
        !           242: static void dmfe_program_DM9802(struct nic *nic);
        !           243: 
        !           244: static void dmfe_reset(struct nic *nic)
        !           245: {
        !           246:        /* system variable init */
        !           247:        db->cr6_data = CR6_DEFAULT | dmfe_cr6_user_set;
        !           248: 
        !           249:        db->NIC_capability = 0xf;       /* All capability */
        !           250:        db->PHY_reg4 = 0x1e0;
        !           251: 
        !           252:        /* CR6 operation mode decision */
        !           253:        if (!chkmode || (db->chip_id == PCI_DM9132_ID) ||
        !           254:            (db->chip_revision >= 0x02000030)) {
        !           255:                db->cr6_data |= DMFE_TXTH_256;
        !           256:                db->cr0_data = CR0_DEFAULT;
        !           257:                db->dm910x_chk_mode = 4;        /* Enter the normal mode */
        !           258:        } else {
        !           259:                db->cr6_data |= CR6_SFT;        /* Store & Forward mode */
        !           260:                db->cr0_data = 0;
        !           261:                db->dm910x_chk_mode = 1;        /* Enter the check mode */
        !           262:        }
        !           263:        /* Initilize DM910X board */
        !           264:        dmfe_init_dm910x(nic);
        !           265: 
        !           266:        return;
        !           267: }
        !           268: 
        !           269: /*     Initilize DM910X board
        !           270:  *     Reset DM910X board
        !           271:  *     Initilize TX/Rx descriptor chain structure
        !           272:  *     Send the set-up frame
        !           273:  *     Enable Tx/Rx machine
        !           274:  */
        !           275: 
        !           276: static void dmfe_init_dm910x(struct nic *nic)
        !           277: {
        !           278:        unsigned long ioaddr = BASE;
        !           279: 
        !           280:        /* Reset DM910x MAC controller */
        !           281:        outl(DM910X_RESET, ioaddr + DCR0);      /* RESET MAC */
        !           282:        udelay(100);
        !           283:        outl(db->cr0_data, ioaddr + DCR0);
        !           284:        udelay(5);
        !           285: 
        !           286:        /* Phy addr : DM910(A)2/DM9132/9801, phy address = 1 */
        !           287:        db->phy_addr = 1;
        !           288: 
        !           289:        /* Parser SROM and media mode */
        !           290:        dmfe_parse_srom(nic);
        !           291:        db->media_mode = dmfe_media_mode;
        !           292: 
        !           293:        /* RESET Phyxcer Chip by GPR port bit 7 */
        !           294:        outl(0x180, ioaddr + DCR12);    /* Let bit 7 output port */
        !           295:        if (db->chip_id == PCI_DM9009_ID) {
        !           296:                outl(0x80, ioaddr + DCR12);     /* Issue RESET signal */
        !           297:                mdelay(300);    /* Delay 300 ms */
        !           298:        }
        !           299:        outl(0x0, ioaddr + DCR12);      /* Clear RESET signal */
        !           300: 
        !           301:        /* Process Phyxcer Media Mode */
        !           302:        if (!(db->media_mode & 0x10))   /* Force 1M mode */
        !           303:                dmfe_set_phyxcer(nic);
        !           304: 
        !           305:        /* Media Mode Process */
        !           306:        if (!(db->media_mode & DMFE_AUTO))
        !           307:                db->op_mode = db->media_mode;   /* Force Mode */
        !           308: 
        !           309:        /* Initiliaze Transmit/Receive decriptor and CR3/4 */
        !           310:        dmfe_descriptor_init(nic, ioaddr);
        !           311: 
        !           312:        /* tx descriptor start pointer */
        !           313:        outl(virt_to_le32desc(&txd[0]), ioaddr + DCR4); /* TX DESC address */
        !           314: 
        !           315:        /* rx descriptor start pointer */
        !           316:        outl(virt_to_le32desc(&rxd[0]), ioaddr + DCR3); /* RX DESC address */
        !           317: 
        !           318:        /* Init CR6 to program DM910x operation */
        !           319:        update_cr6(db->cr6_data, ioaddr);
        !           320: 
        !           321:        /* Send setup frame */
        !           322:        if (db->chip_id == PCI_DM9132_ID) {
        !           323:                dm9132_id_table(nic);   /* DM9132 */
        !           324:        } else {
        !           325:                send_filter_frame(nic); /* DM9102/DM9102A */
        !           326:        }
        !           327: 
        !           328:        /* Init CR7, interrupt active bit */
        !           329:        db->cr7_data = CR7_DEFAULT;
        !           330:        outl(db->cr7_data, ioaddr + DCR7);
        !           331:        /* Init CR15, Tx jabber and Rx watchdog timer */
        !           332:        outl(db->cr15_data, ioaddr + DCR15);
        !           333:        /* Enable DM910X Tx/Rx function */
        !           334:        db->cr6_data |= CR6_RXSC | CR6_TXSC | 0x40000;
        !           335:        update_cr6(db->cr6_data, ioaddr);
        !           336: }
        !           337: #ifdef EDEBUG
        !           338: void hex_dump(const char *data, const unsigned int len);
        !           339: #endif
        !           340: /**************************************************************************
        !           341: POLL - Wait for a frame
        !           342: ***************************************************************************/
        !           343: static int dmfe_poll(struct nic *nic, int retrieve)
        !           344: {
        !           345:        u32 rdes0;
        !           346:        int entry = db->cur_rx % RX_DESC_CNT;
        !           347:        int rxlen;
        !           348:        rdes0 = le32_to_cpu(rxd[entry].rdes0);
        !           349:        if (rdes0 & 0x80000000)
        !           350:                return 0;
        !           351: 
        !           352:        if (!retrieve)
        !           353:                return 1;
        !           354: 
        !           355:        if ((rdes0 & 0x300) != 0x300) {
        !           356:                /* A packet without First/Last flag */
        !           357:                printf("strange Packet\n");
        !           358:                rxd[entry].rdes0 = cpu_to_le32(0x80000000);
        !           359:                return 0;
        !           360:        } else {
        !           361:                /* A packet with First/Last flag */
        !           362:                rxlen = ((rdes0 >> 16) & 0x3fff) - 4;
        !           363:                /* error summary bit check */
        !           364:                if (rdes0 & 0x8000) {
        !           365:                        printf("Error\n");
        !           366:                        return 0;
        !           367:                }
        !           368:                if (!(rdes0 & 0x8000) ||
        !           369:                    ((db->cr6_data & CR6_PM) && (rxlen > 6))) {
        !           370:                        if (db->dm910x_chk_mode & 1)
        !           371:                                printf("Silly check mode\n");
        !           372: 
        !           373:                        nic->packetlen = rxlen;
        !           374:                        memcpy(nic->packet, rxb + (entry * RX_ALLOC_SIZE),
        !           375:                               nic->packetlen);
        !           376:                }
        !           377:        }
        !           378:        rxd[entry].rdes0 = cpu_to_le32(0x80000000);
        !           379:        db->cur_rx++;
        !           380:        return 1;
        !           381: }
        !           382: 
        !           383: static void dmfe_irq(struct nic *nic __unused, irq_action_t action __unused)
        !           384: {
        !           385:        switch ( action ) {
        !           386:                case DISABLE :
        !           387:                        break;
        !           388:                case ENABLE :
        !           389:                        break;
        !           390:                case FORCE :
        !           391:                        break;
        !           392:        }
        !           393: }
        !           394: 
        !           395: /**************************************************************************
        !           396: TRANSMIT - Transmit a frame
        !           397: ***************************************************************************/
        !           398: static void dmfe_transmit(struct nic *nic, 
        !           399:        const char *dest,       /* Destination */
        !           400:        unsigned int type,      /* Type */
        !           401:        unsigned int size,      /* size */
        !           402:        const char *packet)     /* Packet */
        !           403: {      
        !           404:        u16 nstype;
        !           405:        u8 *ptxb;
        !           406: 
        !           407:        ptxb = &txb[db->cur_tx];
        !           408: 
        !           409:        /* Stop Tx */
        !           410:        outl(0, BASE + DCR7);
        !           411:        memcpy(ptxb, dest, ETH_ALEN);
        !           412:        memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN);
        !           413:        nstype = htons((u16) type);
        !           414:        memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2);
        !           415:        memcpy(ptxb + ETH_HLEN, packet, size);
        !           416: 
        !           417:        size += ETH_HLEN;
        !           418:        while (size < ETH_ZLEN)
        !           419:                ptxb[size++] = '\0';
        !           420: 
        !           421:        /* setup the transmit descriptor */
        !           422:        txd[db->cur_tx].tdes1 = cpu_to_le32(0xe1000000 | size);
        !           423:        txd[db->cur_tx].tdes0 = cpu_to_le32(0x80000000);        /* give ownership to device */
        !           424: 
        !           425:        /* immediate transmit demand */
        !           426:        outl(0x1, BASE + DCR1);
        !           427:        outl(db->cr7_data, BASE + DCR7);
        !           428: 
        !           429:        /* Point to next TX descriptor */
        !           430:        db->cur_tx++;
        !           431:        db->cur_tx = db->cur_tx % TX_DESC_CNT;
        !           432: }
        !           433: 
        !           434: /**************************************************************************
        !           435: DISABLE - Turn off ethernet interface
        !           436: ***************************************************************************/
        !           437: static void dmfe_disable ( struct nic *nic __unused ) {
        !           438:        /* Reset & stop DM910X board */
        !           439:        outl(DM910X_RESET, BASE + DCR0);
        !           440:        udelay(5);
        !           441:        phy_write(BASE, db->phy_addr, 0, 0x8000, db->chip_id);
        !           442: 
        !           443: }
        !           444: 
        !           445: /**************************************************************************
        !           446: PROBE - Look for an adapter, this routine's visible to the outside
        !           447: ***************************************************************************/
        !           448: 
        !           449: #define board_found 1
        !           450: #define valid_link 0
        !           451: static int dmfe_probe ( struct nic *nic, struct pci_device *pci ) {
        !           452: 
        !           453:        uint32_t dev_rev, pci_pmr;
        !           454:        int i;
        !           455: 
        !           456:        if (pci->ioaddr == 0)
        !           457:                return 0;
        !           458: 
        !           459:        BASE = pci->ioaddr;
        !           460:        printf("dmfe.c: Found %s Vendor=0x%hX Device=0x%hX\n",
        !           461:               pci->id->name, pci->vendor, pci->device);
        !           462: 
        !           463:        /* Read Chip revision */
        !           464:        pci_read_config_dword(pci, PCI_REVISION_ID, &dev_rev);
        !           465:        dprintf(("Revision %lX\n", dev_rev));
        !           466: 
        !           467:        /* point to private storage */
        !           468:        db = &dfx;
        !           469: 
        !           470:        db->chip_id = ((u32) pci->device << 16) | pci->vendor;
        !           471:        BASE = pci_bar_start(pci, PCI_BASE_ADDRESS_0);
        !           472:        db->chip_revision = dev_rev;
        !           473: 
        !           474:        pci_read_config_dword(pci, 0x50, &pci_pmr);
        !           475:        pci_pmr &= 0x70000;
        !           476:        if ((pci_pmr == 0x10000) && (dev_rev == 0x02000031))
        !           477:                db->chip_type = 1;      /* DM9102A E3 */
        !           478:        else
        !           479:                db->chip_type = 0;
        !           480: 
        !           481:        dprintf(("Chip type : %d\n", db->chip_type));
        !           482: 
        !           483:        /* read 64 word srom data */
        !           484:        for (i = 0; i < 64; i++)
        !           485:                ((u16 *) db->srom)[i] = cpu_to_le16(read_srom_word(BASE, i));
        !           486: 
        !           487:        /* Set Node address */
        !           488:        for (i = 0; i < 6; i++)
        !           489:                nic->node_addr[i] = db->srom[20 + i];
        !           490: 
        !           491:        /* Print out some hardware info */
        !           492:        DBG ( "%s: %s at ioaddr %4.4lx\n",
        !           493:              pci->id->name, eth_ntoa ( nic->node_addr ), BASE );
        !           494: 
        !           495:        /* Set the card as PCI Bus Master */
        !           496:        adjust_pci_device(pci);
        !           497: 
        !           498:        dmfe_reset(nic);
        !           499: 
        !           500:        nic->irqno  = 0;
        !           501:        nic->ioaddr = pci->ioaddr;
        !           502: 
        !           503:        /* point to NIC specific routines */
        !           504:        nic->nic_op     = &dmfe_operations;
        !           505: 
        !           506:        return 1;
        !           507: }
        !           508: 
        !           509: /*
        !           510:  *     Initialize transmit/Receive descriptor
        !           511:  *     Using Chain structure, and allocate Tx/Rx buffer
        !           512:  */
        !           513: 
        !           514: static void dmfe_descriptor_init(struct nic *nic __unused, unsigned long ioaddr)
        !           515: {
        !           516:        int i;
        !           517:        db->cur_tx = 0;
        !           518:        db->cur_rx = 0;
        !           519: 
        !           520:        /* tx descriptor start pointer */
        !           521:        outl(virt_to_le32desc(&txd[0]), ioaddr + DCR4); /* TX DESC address */
        !           522: 
        !           523:        /* rx descriptor start pointer */
        !           524:        outl(virt_to_le32desc(&rxd[0]), ioaddr + DCR3); /* RX DESC address */
        !           525: 
        !           526:        /* Init Transmit chain */
        !           527:        for (i = 0; i < TX_DESC_CNT; i++) {
        !           528:                txd[i].tx_buf_ptr = &txb[i];
        !           529:                txd[i].tdes0 = cpu_to_le32(0);
        !           530:                txd[i].tdes1 = cpu_to_le32(0x81000000); /* IC, chain */
        !           531:                txd[i].tdes2 = cpu_to_le32(virt_to_bus(&txb[i]));
        !           532:                txd[i].tdes3 = cpu_to_le32(virt_to_bus(&txd[i + 1]));
        !           533:                txd[i].next_tx_desc = &txd[i + 1];
        !           534:        }
        !           535:        /* Mark the last entry as wrapping the ring */
        !           536:        txd[i - 1].tdes3 = virt_to_le32desc(&txd[0]);
        !           537:        txd[i - 1].next_tx_desc = &txd[0];
        !           538: 
        !           539:        /* receive descriptor chain */
        !           540:        for (i = 0; i < RX_DESC_CNT; i++) {
        !           541:                rxd[i].rx_skb_ptr = &rxb[i * RX_ALLOC_SIZE];
        !           542:                rxd[i].rdes0 = cpu_to_le32(0x80000000);
        !           543:                rxd[i].rdes1 = cpu_to_le32(0x01000600);
        !           544:                rxd[i].rdes2 =
        !           545:                    cpu_to_le32(virt_to_bus(&rxb[i * RX_ALLOC_SIZE]));
        !           546:                rxd[i].rdes3 = cpu_to_le32(virt_to_bus(&rxd[i + 1]));
        !           547:                rxd[i].next_rx_desc = &rxd[i + 1];
        !           548:        }
        !           549:        /* Mark the last entry as wrapping the ring */
        !           550:        rxd[i - 1].rdes3 = cpu_to_le32(virt_to_bus(&rxd[0]));
        !           551:        rxd[i - 1].next_rx_desc = &rxd[0];
        !           552: 
        !           553: }
        !           554: 
        !           555: /*
        !           556:  *     Update CR6 value
        !           557:  *     Firstly stop DM910X , then written value and start
        !           558:  */
        !           559: 
        !           560: static void update_cr6(u32 cr6_data, unsigned long ioaddr)
        !           561: {
        !           562:        u32 cr6_tmp;
        !           563: 
        !           564:        cr6_tmp = cr6_data & ~0x2002;   /* stop Tx/Rx */
        !           565:        outl(cr6_tmp, ioaddr + DCR6);
        !           566:        udelay(5);
        !           567:        outl(cr6_data, ioaddr + DCR6);
        !           568:        udelay(5);
        !           569: }
        !           570: 
        !           571: 
        !           572: /*
        !           573:  *     Send a setup frame for DM9132
        !           574:  *     This setup frame initilize DM910X addres filter mode
        !           575: */
        !           576: 
        !           577: static void dm9132_id_table(struct nic *nic __unused)
        !           578: {
        !           579: #ifdef LINUX
        !           580:        u16 *addrptr;
        !           581:        u8 dmi_addr[8];
        !           582:        unsigned long ioaddr = BASE + 0xc0;     /* ID Table */
        !           583:        u32 hash_val;
        !           584:        u16 i, hash_table[4];
        !           585: #endif
        !           586:        dprintf(("dm9132_id_table\n"));
        !           587: 
        !           588:        printf("FIXME: This function is broken.  If you have this card contact "
        !           589:                "Timothy Legge at the etherboot-user list\n");
        !           590: 
        !           591: #ifdef LINUX
        !           592:        //DMFE_DBUG(0, "dm9132_id_table()", 0);
        !           593: 
        !           594:        /* Node address */
        !           595:        addrptr = (u16 *) nic->node_addr;
        !           596:        outw(addrptr[0], ioaddr);
        !           597:        ioaddr += 4;
        !           598:        outw(addrptr[1], ioaddr);
        !           599:        ioaddr += 4;
        !           600:        outw(addrptr[2], ioaddr);
        !           601:        ioaddr += 4;
        !           602: 
        !           603:        /* Clear Hash Table */
        !           604:        for (i = 0; i < 4; i++)
        !           605:                hash_table[i] = 0x0;
        !           606: 
        !           607:        /* broadcast address */
        !           608:        hash_table[3] = 0x8000;
        !           609: 
        !           610:        /* the multicast address in Hash Table : 64 bits */
        !           611:        for (mcptr = mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
        !           612:                hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f;
        !           613:                hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
        !           614:        }
        !           615: 
        !           616:        /* Write the hash table to MAC MD table */
        !           617:        for (i = 0; i < 4; i++, ioaddr += 4)
        !           618:                outw(hash_table[i], ioaddr);
        !           619: #endif
        !           620: }
        !           621: 
        !           622: 
        !           623: /*
        !           624:  *     Send a setup frame for DM9102/DM9102A
        !           625:  *     This setup frame initilize DM910X addres filter mode
        !           626:  */
        !           627: 
        !           628: static void send_filter_frame(struct nic *nic)
        !           629: {
        !           630: 
        !           631:        u8 *ptxb;
        !           632:        int i;
        !           633: 
        !           634:        dprintf(("send_filter_frame\n"));
        !           635:        /* point to the current txb incase multiple tx_rings are used */
        !           636:        ptxb = &txb[db->cur_tx];
        !           637: 
        !           638:        /* construct perfect filter frame with mac address as first match
        !           639:           and broadcast address for all others */
        !           640:        for (i = 0; i < 192; i++)
        !           641:                ptxb[i] = 0xFF;
        !           642:        ptxb[0] = nic->node_addr[0];
        !           643:        ptxb[1] = nic->node_addr[1];
        !           644:        ptxb[4] = nic->node_addr[2];
        !           645:        ptxb[5] = nic->node_addr[3];
        !           646:        ptxb[8] = nic->node_addr[4];
        !           647:        ptxb[9] = nic->node_addr[5];
        !           648: 
        !           649:        /* prepare the setup frame */
        !           650:        txd[db->cur_tx].tdes1 = cpu_to_le32(0x890000c0);
        !           651:        txd[db->cur_tx].tdes0 = cpu_to_le32(0x80000000);
        !           652:        update_cr6(db->cr6_data | 0x2000, BASE);
        !           653:        outl(0x1, BASE + DCR1); /* Issue Tx polling */
        !           654:        update_cr6(db->cr6_data, BASE);
        !           655:        db->cur_tx++;
        !           656: }
        !           657: 
        !           658: /*
        !           659:  *     Read one word data from the serial ROM
        !           660:  */
        !           661: 
        !           662: static u16 read_srom_word(long ioaddr, int offset)
        !           663: {
        !           664:        int i;
        !           665:        u16 srom_data = 0;
        !           666:        long cr9_ioaddr = ioaddr + DCR9;
        !           667: 
        !           668:        outl(CR9_SROM_READ, cr9_ioaddr);
        !           669:        outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
        !           670: 
        !           671:        /* Send the Read Command 110b */
        !           672:        SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
        !           673:        SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
        !           674:        SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr);
        !           675: 
        !           676:        /* Send the offset */
        !           677:        for (i = 5; i >= 0; i--) {
        !           678:                srom_data =
        !           679:                    (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0;
        !           680:                SROM_CLK_WRITE(srom_data, cr9_ioaddr);
        !           681:        }
        !           682: 
        !           683:        outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
        !           684: 
        !           685:        for (i = 16; i > 0; i--) {
        !           686:                outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr);
        !           687:                udelay(5);
        !           688:                srom_data =
        !           689:                    (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1
        !           690:                                        : 0);
        !           691:                outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
        !           692:                udelay(5);
        !           693:        }
        !           694: 
        !           695:        outl(CR9_SROM_READ, cr9_ioaddr);
        !           696:        return srom_data;
        !           697: }
        !           698: 
        !           699: 
        !           700: /*
        !           701:  *     Auto sense the media mode
        !           702:  */
        !           703: 
        !           704: #if 0 /* not used */
        !           705: static u8 dmfe_sense_speed(struct nic *nic __unused)
        !           706: {
        !           707:        u8 ErrFlag = 0;
        !           708:        u16 phy_mode;
        !           709: 
        !           710:        /* CR6 bit18=0, select 10/100M */
        !           711:        update_cr6((db->cr6_data & ~0x40000), BASE);
        !           712: 
        !           713:        phy_mode = phy_read(BASE, db->phy_addr, 1, db->chip_id);
        !           714:        phy_mode = phy_read(BASE, db->phy_addr, 1, db->chip_id);
        !           715: 
        !           716:        if ((phy_mode & 0x24) == 0x24) {
        !           717:                if (db->chip_id == PCI_DM9132_ID)       /* DM9132 */
        !           718:                        phy_mode =
        !           719:                            phy_read(BASE, db->phy_addr, 7,
        !           720:                                     db->chip_id) & 0xf000;
        !           721:                else            /* DM9102/DM9102A */
        !           722:                        phy_mode =
        !           723:                            phy_read(BASE, db->phy_addr, 17,
        !           724:                                     db->chip_id) & 0xf000;
        !           725:                /* printk(DRV_NAME ": Phy_mode %x ",phy_mode); */
        !           726:                switch (phy_mode) {
        !           727:                case 0x1000:
        !           728:                        db->op_mode = DMFE_10MHF;
        !           729:                        break;
        !           730:                case 0x2000:
        !           731:                        db->op_mode = DMFE_10MFD;
        !           732:                        break;
        !           733:                case 0x4000:
        !           734:                        db->op_mode = DMFE_100MHF;
        !           735:                        break;
        !           736:                case 0x8000:
        !           737:                        db->op_mode = DMFE_100MFD;
        !           738:                        break;
        !           739:                default:
        !           740:                        db->op_mode = DMFE_10MHF;
        !           741:                        ErrFlag = 1;
        !           742:                        break;
        !           743:                }
        !           744:        } else {
        !           745:                db->op_mode = DMFE_10MHF;
        !           746:                //DMFE_DBUG(0, "Link Failed :", phy_mode);
        !           747:                ErrFlag = 1;
        !           748:        }
        !           749: 
        !           750:        return ErrFlag;
        !           751: }
        !           752: #endif
        !           753: 
        !           754: /*
        !           755:  *     Set 10/100 phyxcer capability
        !           756:  *     AUTO mode : phyxcer register4 is NIC capability
        !           757:  *     Force mode: phyxcer register4 is the force media
        !           758:  */
        !           759: 
        !           760: static void dmfe_set_phyxcer(struct nic *nic __unused)
        !           761: {
        !           762:        u16 phy_reg;
        !           763: 
        !           764:        /* Select 10/100M phyxcer */
        !           765:        db->cr6_data &= ~0x40000;
        !           766:        update_cr6(db->cr6_data, BASE);
        !           767: 
        !           768:        /* DM9009 Chip: Phyxcer reg18 bit12=0 */
        !           769:        if (db->chip_id == PCI_DM9009_ID) {
        !           770:                phy_reg =
        !           771:                    phy_read(BASE, db->phy_addr, 18,
        !           772:                             db->chip_id) & ~0x1000;
        !           773:                phy_write(BASE, db->phy_addr, 18, phy_reg, db->chip_id);
        !           774:        }
        !           775: 
        !           776:        /* Phyxcer capability setting */
        !           777:        phy_reg = phy_read(BASE, db->phy_addr, 4, db->chip_id) & ~0x01e0;
        !           778: 
        !           779:        if (db->media_mode & DMFE_AUTO) {
        !           780:                /* AUTO Mode */
        !           781:                phy_reg |= db->PHY_reg4;
        !           782:        } else {
        !           783:                /* Force Mode */
        !           784:                switch (db->media_mode) {
        !           785:                case DMFE_10MHF:
        !           786:                        phy_reg |= 0x20;
        !           787:                        break;
        !           788:                case DMFE_10MFD:
        !           789:                        phy_reg |= 0x40;
        !           790:                        break;
        !           791:                case DMFE_100MHF:
        !           792:                        phy_reg |= 0x80;
        !           793:                        break;
        !           794:                case DMFE_100MFD:
        !           795:                        phy_reg |= 0x100;
        !           796:                        break;
        !           797:                }
        !           798:                if (db->chip_id == PCI_DM9009_ID)
        !           799:                        phy_reg &= 0x61;
        !           800:        }
        !           801: 
        !           802:        /* Write new capability to Phyxcer Reg4 */
        !           803:        if (!(phy_reg & 0x01e0)) {
        !           804:                phy_reg |= db->PHY_reg4;
        !           805:                db->media_mode |= DMFE_AUTO;
        !           806:        }
        !           807:        phy_write(BASE, db->phy_addr, 4, phy_reg, db->chip_id);
        !           808: 
        !           809:        /* Restart Auto-Negotiation */
        !           810:        if (db->chip_type && (db->chip_id == PCI_DM9102_ID))
        !           811:                phy_write(BASE, db->phy_addr, 0, 0x1800, db->chip_id);
        !           812:        if (!db->chip_type)
        !           813:                phy_write(BASE, db->phy_addr, 0, 0x1200, db->chip_id);
        !           814: }
        !           815: 
        !           816: 
        !           817: /*
        !           818:  *     Process op-mode
        !           819:  *     AUTO mode : PHY controller in Auto-negotiation Mode
        !           820:  *     Force mode: PHY controller in force mode with HUB
        !           821:  *                     N-way force capability with SWITCH
        !           822:  */
        !           823: 
        !           824: #if 0 /* not used */
        !           825: static void dmfe_process_mode(struct nic *nic __unused)
        !           826: {
        !           827:        u16 phy_reg;
        !           828: 
        !           829:        /* Full Duplex Mode Check */
        !           830:        if (db->op_mode & 0x4)
        !           831:                db->cr6_data |= CR6_FDM;        /* Set Full Duplex Bit */
        !           832:        else
        !           833:                db->cr6_data &= ~CR6_FDM;       /* Clear Full Duplex Bit */
        !           834: 
        !           835:        /* Transciver Selection */
        !           836:        if (db->op_mode & 0x10) /* 1M HomePNA */
        !           837:                db->cr6_data |= 0x40000;        /* External MII select */
        !           838:        else
        !           839:                db->cr6_data &= ~0x40000;       /* Internal 10/100 transciver */
        !           840: 
        !           841:        update_cr6(db->cr6_data, BASE);
        !           842: 
        !           843:        /* 10/100M phyxcer force mode need */
        !           844:        if (!(db->media_mode & 0x18)) {
        !           845:                /* Forece Mode */
        !           846:                phy_reg = phy_read(BASE, db->phy_addr, 6, db->chip_id);
        !           847:                if (!(phy_reg & 0x1)) {
        !           848:                        /* parter without N-Way capability */
        !           849:                        phy_reg = 0x0;
        !           850:                        switch (db->op_mode) {
        !           851:                        case DMFE_10MHF:
        !           852:                                phy_reg = 0x0;
        !           853:                                break;
        !           854:                        case DMFE_10MFD:
        !           855:                                phy_reg = 0x100;
        !           856:                                break;
        !           857:                        case DMFE_100MHF:
        !           858:                                phy_reg = 0x2000;
        !           859:                                break;
        !           860:                        case DMFE_100MFD:
        !           861:                                phy_reg = 0x2100;
        !           862:                                break;
        !           863:                        }
        !           864:                        phy_write(BASE, db->phy_addr, 0, phy_reg,
        !           865:                                  db->chip_id);
        !           866:                        if (db->chip_type
        !           867:                            && (db->chip_id == PCI_DM9102_ID))
        !           868:                                mdelay(20);
        !           869:                        phy_write(BASE, db->phy_addr, 0, phy_reg,
        !           870:                                  db->chip_id);
        !           871:                }
        !           872:        }
        !           873: }
        !           874: #endif
        !           875: 
        !           876: /*
        !           877:  *     Write a word to Phy register
        !           878:  */
        !           879: 
        !           880: static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset,
        !           881:                      u16 phy_data, u32 chip_id)
        !           882: {
        !           883:        u16 i;
        !           884:        unsigned long ioaddr;
        !           885: 
        !           886:        if (chip_id == PCI_DM9132_ID) {
        !           887:                ioaddr = iobase + 0x80 + offset * 4;
        !           888:                outw(phy_data, ioaddr);
        !           889:        } else {
        !           890:                /* DM9102/DM9102A Chip */
        !           891:                ioaddr = iobase + DCR9;
        !           892: 
        !           893:                /* Send 33 synchronization clock to Phy controller */
        !           894:                for (i = 0; i < 35; i++)
        !           895:                        phy_write_1bit(ioaddr, PHY_DATA_1);
        !           896: 
        !           897:                /* Send start command(01) to Phy */
        !           898:                phy_write_1bit(ioaddr, PHY_DATA_0);
        !           899:                phy_write_1bit(ioaddr, PHY_DATA_1);
        !           900: 
        !           901:                /* Send write command(01) to Phy */
        !           902:                phy_write_1bit(ioaddr, PHY_DATA_0);
        !           903:                phy_write_1bit(ioaddr, PHY_DATA_1);
        !           904: 
        !           905:                /* Send Phy addres */
        !           906:                for (i = 0x10; i > 0; i = i >> 1)
        !           907:                        phy_write_1bit(ioaddr,
        !           908:                                       phy_addr & i ? PHY_DATA_1 :
        !           909:                                       PHY_DATA_0);
        !           910: 
        !           911:                /* Send register addres */
        !           912:                for (i = 0x10; i > 0; i = i >> 1)
        !           913:                        phy_write_1bit(ioaddr,
        !           914:                                       offset & i ? PHY_DATA_1 :
        !           915:                                       PHY_DATA_0);
        !           916: 
        !           917:                /* written trasnition */
        !           918:                phy_write_1bit(ioaddr, PHY_DATA_1);
        !           919:                phy_write_1bit(ioaddr, PHY_DATA_0);
        !           920: 
        !           921:                /* Write a word data to PHY controller */
        !           922:                for (i = 0x8000; i > 0; i >>= 1)
        !           923:                        phy_write_1bit(ioaddr,
        !           924:                                       phy_data & i ? PHY_DATA_1 :
        !           925:                                       PHY_DATA_0);
        !           926:        }
        !           927: }
        !           928: 
        !           929: 
        !           930: /*
        !           931:  *     Read a word data from phy register
        !           932:  */
        !           933: 
        !           934: static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset,
        !           935:                    u32 chip_id)
        !           936: {
        !           937:        int i;
        !           938:        u16 phy_data;
        !           939:        unsigned long ioaddr;
        !           940: 
        !           941:        if (chip_id == PCI_DM9132_ID) {
        !           942:                /* DM9132 Chip */
        !           943:                ioaddr = iobase + 0x80 + offset * 4;
        !           944:                phy_data = inw(ioaddr);
        !           945:        } else {
        !           946:                /* DM9102/DM9102A Chip */
        !           947:                ioaddr = iobase + DCR9;
        !           948: 
        !           949:                /* Send 33 synchronization clock to Phy controller */
        !           950:                for (i = 0; i < 35; i++)
        !           951:                        phy_write_1bit(ioaddr, PHY_DATA_1);
        !           952: 
        !           953:                /* Send start command(01) to Phy */
        !           954:                phy_write_1bit(ioaddr, PHY_DATA_0);
        !           955:                phy_write_1bit(ioaddr, PHY_DATA_1);
        !           956: 
        !           957:                /* Send read command(10) to Phy */
        !           958:                phy_write_1bit(ioaddr, PHY_DATA_1);
        !           959:                phy_write_1bit(ioaddr, PHY_DATA_0);
        !           960: 
        !           961:                /* Send Phy addres */
        !           962:                for (i = 0x10; i > 0; i = i >> 1)
        !           963:                        phy_write_1bit(ioaddr,
        !           964:                                       phy_addr & i ? PHY_DATA_1 :
        !           965:                                       PHY_DATA_0);
        !           966: 
        !           967:                /* Send register addres */
        !           968:                for (i = 0x10; i > 0; i = i >> 1)
        !           969:                        phy_write_1bit(ioaddr,
        !           970:                                       offset & i ? PHY_DATA_1 :
        !           971:                                       PHY_DATA_0);
        !           972: 
        !           973:                /* Skip transition state */
        !           974:                phy_read_1bit(ioaddr);
        !           975: 
        !           976:                /* read 16bit data */
        !           977:                for (phy_data = 0, i = 0; i < 16; i++) {
        !           978:                        phy_data <<= 1;
        !           979:                        phy_data |= phy_read_1bit(ioaddr);
        !           980:                }
        !           981:        }
        !           982: 
        !           983:        return phy_data;
        !           984: }
        !           985: 
        !           986: 
        !           987: /*
        !           988:  *     Write one bit data to Phy Controller
        !           989:  */
        !           990: 
        !           991: static void phy_write_1bit(unsigned long ioaddr, u32 phy_data)
        !           992: {
        !           993:        outl(phy_data, ioaddr); /* MII Clock Low */
        !           994:        udelay(1);
        !           995:        outl(phy_data | MDCLKH, ioaddr);        /* MII Clock High */
        !           996:        udelay(1);
        !           997:        outl(phy_data, ioaddr); /* MII Clock Low */
        !           998:        udelay(1);
        !           999: }
        !          1000: 
        !          1001: 
        !          1002: /*
        !          1003:  *     Read one bit phy data from PHY controller
        !          1004:  */
        !          1005: 
        !          1006: static u16 phy_read_1bit(unsigned long ioaddr)
        !          1007: {
        !          1008:        u16 phy_data;
        !          1009: 
        !          1010:        outl(0x50000, ioaddr);
        !          1011:        udelay(1);
        !          1012:        phy_data = (inl(ioaddr) >> 19) & 0x1;
        !          1013:        outl(0x40000, ioaddr);
        !          1014:        udelay(1);
        !          1015: 
        !          1016:        return phy_data;
        !          1017: }
        !          1018: 
        !          1019: 
        !          1020: /*
        !          1021:  *     Parser SROM and media mode
        !          1022:  */
        !          1023: 
        !          1024: static void dmfe_parse_srom(struct nic *nic)
        !          1025: {
        !          1026:        unsigned char *srom = db->srom;
        !          1027:        int dmfe_mode, tmp_reg;
        !          1028: 
        !          1029:        /* Init CR15 */
        !          1030:        db->cr15_data = CR15_DEFAULT;
        !          1031: 
        !          1032:        /* Check SROM Version */
        !          1033:        if (((int) srom[18] & 0xff) == SROM_V41_CODE) {
        !          1034:                /* SROM V4.01 */
        !          1035:                /* Get NIC support media mode */
        !          1036:                db->NIC_capability = *(u16 *) (srom + 34);
        !          1037:                db->PHY_reg4 = 0;
        !          1038:                for (tmp_reg = 1; tmp_reg < 0x10; tmp_reg <<= 1) {
        !          1039:                        switch (db->NIC_capability & tmp_reg) {
        !          1040:                        case 0x1:
        !          1041:                                db->PHY_reg4 |= 0x0020;
        !          1042:                                break;
        !          1043:                        case 0x2:
        !          1044:                                db->PHY_reg4 |= 0x0040;
        !          1045:                                break;
        !          1046:                        case 0x4:
        !          1047:                                db->PHY_reg4 |= 0x0080;
        !          1048:                                break;
        !          1049:                        case 0x8:
        !          1050:                                db->PHY_reg4 |= 0x0100;
        !          1051:                                break;
        !          1052:                        }
        !          1053:                }
        !          1054: 
        !          1055:                /* Media Mode Force or not check */
        !          1056:                dmfe_mode = *((int *) srom + 34) & *((int *) srom + 36);
        !          1057:                switch (dmfe_mode) {
        !          1058:                case 0x4:
        !          1059:                        dmfe_media_mode = DMFE_100MHF;
        !          1060:                        break;  /* 100MHF */
        !          1061:                case 0x2:
        !          1062:                        dmfe_media_mode = DMFE_10MFD;
        !          1063:                        break;  /* 10MFD */
        !          1064:                case 0x8:
        !          1065:                        dmfe_media_mode = DMFE_100MFD;
        !          1066:                        break;  /* 100MFD */
        !          1067:                case 0x100:
        !          1068:                case 0x200:
        !          1069:                        dmfe_media_mode = DMFE_1M_HPNA;
        !          1070:                        break;  /* HomePNA */
        !          1071:                }
        !          1072: 
        !          1073:                /* Special Function setting */
        !          1074:                /* VLAN function */
        !          1075:                if ((SF_mode & 0x1) || (srom[43] & 0x80))
        !          1076:                        db->cr15_data |= 0x40;
        !          1077: 
        !          1078:                /* Flow Control */
        !          1079:                if ((SF_mode & 0x2) || (srom[40] & 0x1))
        !          1080:                        db->cr15_data |= 0x400;
        !          1081: 
        !          1082:                /* TX pause packet */
        !          1083:                if ((SF_mode & 0x4) || (srom[40] & 0xe))
        !          1084:                        db->cr15_data |= 0x9800;
        !          1085:        }
        !          1086: 
        !          1087:        /* Parse HPNA parameter */
        !          1088:        db->HPNA_command = 1;
        !          1089: 
        !          1090:        /* Accept remote command or not */
        !          1091:        if (HPNA_rx_cmd == 0)
        !          1092:                db->HPNA_command |= 0x8000;
        !          1093: 
        !          1094:        /* Issue remote command & operation mode */
        !          1095:        if (HPNA_tx_cmd == 1)
        !          1096:                switch (HPNA_mode) {    /* Issue Remote Command */
        !          1097:                case 0:
        !          1098:                        db->HPNA_command |= 0x0904;
        !          1099:                        break;
        !          1100:                case 1:
        !          1101:                        db->HPNA_command |= 0x0a00;
        !          1102:                        break;
        !          1103:                case 2:
        !          1104:                        db->HPNA_command |= 0x0506;
        !          1105:                        break;
        !          1106:                case 3:
        !          1107:                        db->HPNA_command |= 0x0602;
        !          1108:                        break;
        !          1109:        } else
        !          1110:                switch (HPNA_mode) {    /* Don't Issue */
        !          1111:                case 0:
        !          1112:                        db->HPNA_command |= 0x0004;
        !          1113:                        break;
        !          1114:                case 1:
        !          1115:                        db->HPNA_command |= 0x0000;
        !          1116:                        break;
        !          1117:                case 2:
        !          1118:                        db->HPNA_command |= 0x0006;
        !          1119:                        break;
        !          1120:                case 3:
        !          1121:                        db->HPNA_command |= 0x0002;
        !          1122:                        break;
        !          1123:                }
        !          1124: 
        !          1125:        /* Check DM9801 or DM9802 present or not */
        !          1126:        db->HPNA_present = 0;
        !          1127:        update_cr6(db->cr6_data | 0x40000, BASE);
        !          1128:        tmp_reg = phy_read(BASE, db->phy_addr, 3, db->chip_id);
        !          1129:        if ((tmp_reg & 0xfff0) == 0xb900) {
        !          1130:                /* DM9801 or DM9802 present */
        !          1131:                db->HPNA_timer = 8;
        !          1132:                if (phy_read(BASE, db->phy_addr, 31, db->chip_id) ==
        !          1133:                    0x4404) {
        !          1134:                        /* DM9801 HomeRun */
        !          1135:                        db->HPNA_present = 1;
        !          1136:                        dmfe_program_DM9801(nic, tmp_reg);
        !          1137:                } else {
        !          1138:                        /* DM9802 LongRun */
        !          1139:                        db->HPNA_present = 2;
        !          1140:                        dmfe_program_DM9802(nic);
        !          1141:                }
        !          1142:        }
        !          1143: 
        !          1144: }
        !          1145: 
        !          1146: /*
        !          1147:  *     Init HomeRun DM9801
        !          1148:  */
        !          1149: 
        !          1150: static void dmfe_program_DM9801(struct nic *nic __unused, int HPNA_rev)
        !          1151: {
        !          1152:        u32 reg17, reg25;
        !          1153: 
        !          1154:        if (!HPNA_NoiseFloor)
        !          1155:                HPNA_NoiseFloor = DM9801_NOISE_FLOOR;
        !          1156:        switch (HPNA_rev) {
        !          1157:        case 0xb900:            /* DM9801 E3 */
        !          1158:                db->HPNA_command |= 0x1000;
        !          1159:                reg25 = phy_read(BASE, db->phy_addr, 24, db->chip_id);
        !          1160:                reg25 = ((reg25 + HPNA_NoiseFloor) & 0xff) | 0xf000;
        !          1161:                reg17 = phy_read(BASE, db->phy_addr, 17, db->chip_id);
        !          1162:                break;
        !          1163:        case 0xb901:            /* DM9801 E4 */
        !          1164:                reg25 = phy_read(BASE, db->phy_addr, 25, db->chip_id);
        !          1165:                reg25 = (reg25 & 0xff00) + HPNA_NoiseFloor;
        !          1166:                reg17 = phy_read(BASE, db->phy_addr, 17, db->chip_id);
        !          1167:                reg17 = (reg17 & 0xfff0) + HPNA_NoiseFloor + 3;
        !          1168:                break;
        !          1169:        case 0xb902:            /* DM9801 E5 */
        !          1170:        case 0xb903:            /* DM9801 E6 */
        !          1171:        default:
        !          1172:                db->HPNA_command |= 0x1000;
        !          1173:                reg25 = phy_read(BASE, db->phy_addr, 25, db->chip_id);
        !          1174:                reg25 = (reg25 & 0xff00) + HPNA_NoiseFloor - 5;
        !          1175:                reg17 = phy_read(BASE, db->phy_addr, 17, db->chip_id);
        !          1176:                reg17 = (reg17 & 0xfff0) + HPNA_NoiseFloor;
        !          1177:                break;
        !          1178:        }
        !          1179:        phy_write(BASE, db->phy_addr, 16, db->HPNA_command, db->chip_id);
        !          1180:        phy_write(BASE, db->phy_addr, 17, reg17, db->chip_id);
        !          1181:        phy_write(BASE, db->phy_addr, 25, reg25, db->chip_id);
        !          1182: }
        !          1183: 
        !          1184: 
        !          1185: /*
        !          1186:  *     Init HomeRun DM9802
        !          1187:  */
        !          1188: 
        !          1189: static void dmfe_program_DM9802(struct nic *nic __unused)
        !          1190: {
        !          1191:        u32 phy_reg;
        !          1192: 
        !          1193:        if (!HPNA_NoiseFloor)
        !          1194:                HPNA_NoiseFloor = DM9802_NOISE_FLOOR;
        !          1195:        phy_write(BASE, db->phy_addr, 16, db->HPNA_command, db->chip_id);
        !          1196:        phy_reg = phy_read(BASE, db->phy_addr, 25, db->chip_id);
        !          1197:        phy_reg = (phy_reg & 0xff00) + HPNA_NoiseFloor;
        !          1198:        phy_write(BASE, db->phy_addr, 25, phy_reg, db->chip_id);
        !          1199: }
        !          1200: 
        !          1201: static struct nic_operations dmfe_operations = {
        !          1202:        .connect        = dummy_connect,
        !          1203:        .poll           = dmfe_poll,
        !          1204:        .transmit       = dmfe_transmit,
        !          1205:        .irq            = dmfe_irq,
        !          1206: 
        !          1207: };
        !          1208: 
        !          1209: static struct pci_device_id dmfe_nics[] = {
        !          1210:        PCI_ROM(0x1282, 0x9100, "dmfe9100", "Davicom 9100", 0),
        !          1211:        PCI_ROM(0x1282, 0x9102, "dmfe9102", "Davicom 9102", 0),
        !          1212:        PCI_ROM(0x1282, 0x9009, "dmfe9009", "Davicom 9009", 0),
        !          1213:        PCI_ROM(0x1282, 0x9132, "dmfe9132", "Davicom 9132", 0), /* Needs probably some fixing */
        !          1214: };
        !          1215: 
        !          1216: PCI_DRIVER ( dmfe_driver, dmfe_nics, PCI_NO_CLASS );
        !          1217: 
        !          1218: DRIVER ( "DMFE/PCI", nic_driver, pci_driver, dmfe_driver,
        !          1219:         dmfe_probe, dmfe_disable );
        !          1220: 
        !          1221: /*
        !          1222:  * Local variables:
        !          1223:  *  c-basic-offset: 8
        !          1224:  *  c-indent-level: 8
        !          1225:  *  tab-width: 8
        !          1226:  * End:
        !          1227:  */

unix.superglobalmegacorp.com

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