Annotation of qemu/roms/ipxe/src/drivers/net/via-rhine.c, revision 1.1

1.1     ! root        1: /* rhine.c:Fast Ethernet driver for Linux. */
        !             2: /*
        !             3:        Adapted 09-jan-2000 by Paolo Marini ([email protected])
        !             4: 
        !             5:         originally written by Donald Becker.
        !             6: 
        !             7:        This software may be used and distributed according to the terms
        !             8:        of the GNU Public License (GPL), incorporated herein by reference.
        !             9:        Drivers derived from this code also fall under the GPL and must retain
        !            10:        this authorship and copyright notice.
        !            11: 
        !            12:        Under no circumstances are the authors responsible for
        !            13:        the proper functioning of this software, nor do the authors assume any
        !            14:        responsibility for damages incurred with its use.
        !            15: 
        !            16:        This driver is designed for the VIA VT86C100A Rhine-II PCI Fast Ethernet
        !            17:        controller.
        !            18: 
        !            19: */
        !            20: 
        !            21: static const char *version = "rhine.c v1.0.2 2004-10-29\n";
        !            22: 
        !            23: /* A few user-configurable values. */
        !            24: 
        !            25: // max time out delay time
        !            26: #define W_MAX_TIMEOUT  0x0FFFU
        !            27: 
        !            28: /* Size of the in-memory receive ring. */
        !            29: #define RX_BUF_LEN_IDX 3       /* 0==8K, 1==16K, 2==32K, 3==64K */
        !            30: #define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
        !            31: 
        !            32: /* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */
        !            33: #define TX_BUF_SIZE    1536
        !            34: #define RX_BUF_SIZE    1536
        !            35: 
        !            36: /* PCI Tuning Parameters
        !            37:    Threshold is bytes transferred to chip before transmission starts. */
        !            38: #define TX_FIFO_THRESH 256     /* In bytes, rounded down to 32 byte units. */
        !            39: 
        !            40: /* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024. */
        !            41: #define RX_FIFO_THRESH 4       /* Rx buffer level before first PCI xfer.  */
        !            42: #define RX_DMA_BURST   4       /* Maximum PCI burst, '4' is 256 bytes */
        !            43: #define TX_DMA_BURST   4
        !            44: 
        !            45: /* Operational parameters that usually are not changed. */
        !            46: /* Time in jiffies before concluding the transmitter is hung. */
        !            47: #define TX_TIMEOUT  ((2000*HZ)/1000)
        !            48: 
        !            49: #include "etherboot.h"
        !            50: #include "nic.h"
        !            51: #include <ipxe/pci.h>
        !            52: #include <ipxe/ethernet.h>
        !            53: 
        !            54: /* define all ioaddr */
        !            55: 
        !            56: #define byPAR0                         ioaddr
        !            57: #define byRCR                          ioaddr + 6
        !            58: #define byTCR                          ioaddr + 7
        !            59: #define byCR0                          ioaddr + 8
        !            60: #define byCR1                          ioaddr + 9
        !            61: #define byISR0                         ioaddr + 0x0c
        !            62: #define byISR1                         ioaddr + 0x0d
        !            63: #define byIMR0                         ioaddr + 0x0e
        !            64: #define byIMR1                         ioaddr + 0x0f
        !            65: #define byMAR0                         ioaddr + 0x10
        !            66: #define byMAR1                         ioaddr + 0x11
        !            67: #define byMAR2                         ioaddr + 0x12
        !            68: #define byMAR3                         ioaddr + 0x13
        !            69: #define byMAR4                         ioaddr + 0x14
        !            70: #define byMAR5                         ioaddr + 0x15
        !            71: #define byMAR6                         ioaddr + 0x16
        !            72: #define byMAR7                         ioaddr + 0x17
        !            73: #define dwCurrentRxDescAddr            ioaddr + 0x18
        !            74: #define dwCurrentTxDescAddr            ioaddr + 0x1c
        !            75: #define dwCurrentRDSE0                 ioaddr + 0x20
        !            76: #define dwCurrentRDSE1                 ioaddr + 0x24
        !            77: #define dwCurrentRDSE2                 ioaddr + 0x28
        !            78: #define dwCurrentRDSE3                 ioaddr + 0x2c
        !            79: #define dwNextRDSE0                    ioaddr + 0x30
        !            80: #define dwNextRDSE1                    ioaddr + 0x34
        !            81: #define dwNextRDSE2                    ioaddr + 0x38
        !            82: #define dwNextRDSE3                    ioaddr + 0x3c
        !            83: #define dwCurrentTDSE0                 ioaddr + 0x40
        !            84: #define dwCurrentTDSE1                 ioaddr + 0x44
        !            85: #define dwCurrentTDSE2                 ioaddr + 0x48
        !            86: #define dwCurrentTDSE3                 ioaddr + 0x4c
        !            87: #define dwNextTDSE0                    ioaddr + 0x50
        !            88: #define dwNextTDSE1                    ioaddr + 0x54
        !            89: #define dwNextTDSE2                    ioaddr + 0x58
        !            90: #define dwNextTDSE3                    ioaddr + 0x5c
        !            91: #define dwCurrRxDMAPtr                 ioaddr + 0x60
        !            92: #define dwCurrTxDMAPtr                 ioaddr + 0x64
        !            93: #define byMPHY                         ioaddr + 0x6c
        !            94: #define byMIISR                                ioaddr + 0x6d
        !            95: #define byBCR0                         ioaddr + 0x6e
        !            96: #define byBCR1                         ioaddr + 0x6f
        !            97: #define byMIICR                                ioaddr + 0x70
        !            98: #define byMIIAD                                ioaddr + 0x71
        !            99: #define wMIIDATA                       ioaddr + 0x72
        !           100: #define byEECSR                                ioaddr + 0x74
        !           101: #define byTEST                         ioaddr + 0x75
        !           102: #define byGPIO                         ioaddr + 0x76
        !           103: #define byCFGA                         ioaddr + 0x78
        !           104: #define byCFGB                         ioaddr + 0x79
        !           105: #define byCFGC                         ioaddr + 0x7a
        !           106: #define byCFGD                         ioaddr + 0x7b
        !           107: #define wTallyCntMPA                   ioaddr + 0x7c
        !           108: #define wTallyCntCRC                   ioaddr + 0x7d
        !           109: #define bySTICKHW                      ioaddr + 0x83
        !           110: #define byWOLcrClr                     ioaddr + 0xA4
        !           111: #define byWOLcgClr                     ioaddr + 0xA7
        !           112: #define byPwrcsrClr                    ioaddr + 0xAC
        !           113: 
        !           114: /*---------------------  Exioaddr Definitions -------------------------*/
        !           115: 
        !           116: /*
        !           117:  * Bits in the RCR register
        !           118:  */
        !           119: 
        !           120: #define RCR_RRFT2              0x80
        !           121: #define RCR_RRFT1              0x40
        !           122: #define RCR_RRFT0              0x20
        !           123: #define RCR_PROM               0x10
        !           124: #define RCR_AB                 0x08
        !           125: #define RCR_AM                 0x04
        !           126: #define RCR_AR                 0x02
        !           127: #define RCR_SEP                        0x01
        !           128: 
        !           129: /*
        !           130:  * Bits in the TCR register
        !           131:  */
        !           132: 
        !           133: #define TCR_RTSF               0x80
        !           134: #define TCR_RTFT1              0x40
        !           135: #define TCR_RTFT0              0x20
        !           136: #define TCR_OFSET              0x08
        !           137: #define TCR_LB1                        0x04    /* loopback[1] */
        !           138: #define TCR_LB0                        0x02    /* loopback[0] */
        !           139: 
        !           140: /*
        !           141:  * Bits in the CR0 register
        !           142:  */
        !           143: 
        !           144: #define CR0_RDMD               0x40    /* rx descriptor polling demand */
        !           145: #define CR0_TDMD               0x20    /* tx descriptor polling demand */
        !           146: #define CR0_TXON               0x10
        !           147: #define CR0_RXON               0x08
        !           148: #define CR0_STOP               0x04    /* stop NIC, default = 1 */
        !           149: #define CR0_STRT               0x02    /* start NIC */
        !           150: #define CR0_INIT               0x01    /* start init process */
        !           151: 
        !           152: 
        !           153: /*
        !           154:  * Bits in the CR1 register
        !           155:  */
        !           156: 
        !           157: #define CR1_SFRST              0x80    /* software reset */
        !           158: #define CR1_RDMD1              0x40    /* RDMD1 */
        !           159: #define CR1_TDMD1              0x20    /* TDMD1 */
        !           160: #define CR1_KEYPAG             0x10    /* turn on par/key */
        !           161: #define CR1_DPOLL              0x08    /* disable rx/tx auto polling */
        !           162: #define CR1_FDX                        0x04    /* full duplex mode */
        !           163: #define CR1_ETEN               0x02    /* early tx mode */
        !           164: #define CR1_EREN               0x01    /* early rx mode */
        !           165: 
        !           166: /*
        !           167:  * Bits in the CR register
        !           168:  */
        !           169: 
        !           170: #define CR_RDMD                        0x0040  /* rx descriptor polling demand */
        !           171: #define CR_TDMD                        0x0020  /* tx descriptor polling demand */
        !           172: #define CR_TXON                        0x0010
        !           173: #define CR_RXON                        0x0008
        !           174: #define CR_STOP                        0x0004  /* stop NIC, default = 1 */
        !           175: #define CR_STRT                        0x0002  /* start NIC */
        !           176: #define CR_INIT                        0x0001  /* start init process */
        !           177: #define CR_SFRST               0x8000  /* software reset */
        !           178: #define CR_RDMD1               0x4000  /* RDMD1 */
        !           179: #define CR_TDMD1               0x2000  /* TDMD1 */
        !           180: #define CR_KEYPAG              0x1000  /* turn on par/key */
        !           181: #define CR_DPOLL               0x0800  /* disable rx/tx auto polling */
        !           182: #define CR_FDX                 0x0400  /* full duplex mode */
        !           183: #define CR_ETEN                        0x0200  /* early tx mode */
        !           184: #define CR_EREN                        0x0100  /* early rx mode */
        !           185: 
        !           186: /*
        !           187:  * Bits in the IMR0 register
        !           188:  */
        !           189: 
        !           190: #define IMR0_CNTM              0x80
        !           191: #define IMR0_BEM               0x40
        !           192: #define IMR0_RUM               0x20
        !           193: #define IMR0_TUM               0x10
        !           194: #define IMR0_TXEM              0x08
        !           195: #define IMR0_RXEM              0x04
        !           196: #define IMR0_PTXM              0x02
        !           197: #define IMR0_PRXM              0x01
        !           198: 
        !           199: /* define imrshadow */
        !           200: 
        !           201: #define IMRShadow              0x5AFF
        !           202: 
        !           203: /*
        !           204:  * Bits in the IMR1 register
        !           205:  */
        !           206: 
        !           207: #define IMR1_INITM             0x80
        !           208: #define IMR1_SRCM              0x40
        !           209: #define IMR1_NBFM              0x10
        !           210: #define IMR1_PRAIM             0x08
        !           211: #define IMR1_RES0M             0x04
        !           212: #define IMR1_ETM               0x02
        !           213: #define IMR1_ERM               0x01
        !           214: 
        !           215: /*
        !           216:  * Bits in the ISR register
        !           217:  */
        !           218: 
        !           219: #define ISR_INITI              0x8000
        !           220: #define ISR_SRCI               0x4000
        !           221: #define ISR_ABTI               0x2000
        !           222: #define ISR_NORBF              0x1000
        !           223: #define ISR_PKTRA              0x0800
        !           224: #define ISR_RES0               0x0400
        !           225: #define ISR_ETI                        0x0200
        !           226: #define ISR_ERI                        0x0100
        !           227: #define ISR_CNT                        0x0080
        !           228: #define ISR_BE                 0x0040
        !           229: #define ISR_RU                 0x0020
        !           230: #define ISR_TU                 0x0010
        !           231: #define ISR_TXE                        0x0008
        !           232: #define ISR_RXE                        0x0004
        !           233: #define ISR_PTX                        0x0002
        !           234: #define ISR_PRX                        0x0001
        !           235: 
        !           236: /*
        !           237:  * Bits in the ISR0 register
        !           238:  */
        !           239: 
        !           240: #define ISR0_CNT               0x80
        !           241: #define ISR0_BE                        0x40
        !           242: #define ISR0_RU                        0x20
        !           243: #define ISR0_TU                        0x10
        !           244: #define ISR0_TXE               0x08
        !           245: #define ISR0_RXE               0x04
        !           246: #define ISR0_PTX               0x02
        !           247: #define ISR0_PRX               0x01
        !           248: 
        !           249: /*
        !           250:  * Bits in the ISR1 register
        !           251:  */
        !           252: 
        !           253: #define ISR1_INITI             0x80
        !           254: #define ISR1_SRCI              0x40
        !           255: #define ISR1_NORBF             0x10
        !           256: #define ISR1_PKTRA             0x08
        !           257: #define ISR1_ETI               0x02
        !           258: #define ISR1_ERI               0x01
        !           259: 
        !           260: /* ISR ABNORMAL CONDITION */
        !           261: 
        !           262: #define ISR_ABNORMAL ISR_BE+ISR_RU+ISR_TU+ISR_CNT+ISR_NORBF+ISR_PKTRA
        !           263: 
        !           264: /*
        !           265:  * Bits in the MIISR register
        !           266:  */
        !           267: 
        !           268: #define MIISR_MIIERR           0x08
        !           269: #define MIISR_MRERR            0x04
        !           270: #define MIISR_LNKFL            0x02
        !           271: #define MIISR_SPEED            0x01
        !           272: 
        !           273: /*
        !           274:  * Bits in the MIICR register
        !           275:  */
        !           276: 
        !           277: #define MIICR_MAUTO            0x80
        !           278: #define MIICR_RCMD             0x40
        !           279: #define MIICR_WCMD             0x20
        !           280: #define MIICR_MDPM             0x10
        !           281: #define MIICR_MOUT             0x08
        !           282: #define MIICR_MDO              0x04
        !           283: #define MIICR_MDI              0x02
        !           284: #define MIICR_MDC              0x01
        !           285: 
        !           286: /*
        !           287:  * Bits in the EECSR register
        !           288:  */
        !           289: 
        !           290: #define EECSR_EEPR             0x80    /* eeprom programed status, 73h means programed */
        !           291: #define EECSR_EMBP             0x40    /* eeprom embeded programming */
        !           292: #define EECSR_AUTOLD           0x20    /* eeprom content reload */
        !           293: #define EECSR_DPM              0x10    /* eeprom direct programming */
        !           294: #define EECSR_CS               0x08    /* eeprom CS pin */
        !           295: #define EECSR_SK               0x04    /* eeprom SK pin */
        !           296: #define EECSR_DI               0x02    /* eeprom DI pin */
        !           297: #define EECSR_DO               0x01    /* eeprom DO pin */
        !           298: 
        !           299: /*
        !           300:  * Bits in the BCR0 register
        !           301:  */
        !           302: 
        !           303: #define BCR0_CRFT2             0x20
        !           304: #define BCR0_CRFT1             0x10
        !           305: #define BCR0_CRFT0             0x08
        !           306: #define BCR0_DMAL2             0x04
        !           307: #define BCR0_DMAL1             0x02
        !           308: #define BCR0_DMAL0             0x01
        !           309: 
        !           310: /*
        !           311:  * Bits in the BCR1 register
        !           312:  */
        !           313: 
        !           314: #define BCR1_CTSF              0x20
        !           315: #define BCR1_CTFT1             0x10
        !           316: #define BCR1_CTFT0             0x08
        !           317: #define BCR1_POT2              0x04
        !           318: #define BCR1_POT1              0x02
        !           319: #define BCR1_POT0              0x01
        !           320: 
        !           321: /*
        !           322:  * Bits in the CFGA register
        !           323:  */
        !           324: 
        !           325: #define CFGA_EELOAD            0x80    /* enable eeprom embeded and direct programming */
        !           326: #define CFGA_JUMPER            0x40
        !           327: #define CFGA_MTGPIO            0x08
        !           328: #define CFGA_T10EN             0x02
        !           329: #define CFGA_AUTO              0x01
        !           330: 
        !           331: /*
        !           332:  * Bits in the CFGB register
        !           333:  */
        !           334: 
        !           335: #define CFGB_PD                        0x80
        !           336: #define CFGB_POLEN             0x02
        !           337: #define CFGB_LNKEN             0x01
        !           338: 
        !           339: /*
        !           340:  * Bits in the CFGC register
        !           341:  */
        !           342: 
        !           343: #define CFGC_M10TIO            0x80
        !           344: #define CFGC_M10POL            0x40
        !           345: #define CFGC_PHY1              0x20
        !           346: #define CFGC_PHY0              0x10
        !           347: #define CFGC_BTSEL             0x08
        !           348: #define CFGC_BPS2              0x04    /* bootrom select[2] */
        !           349: #define CFGC_BPS1              0x02    /* bootrom select[1] */
        !           350: #define CFGC_BPS0              0x01    /* bootrom select[0] */
        !           351: 
        !           352: /*
        !           353:  * Bits in the CFGD register
        !           354:  */
        !           355: 
        !           356: #define CFGD_GPIOEN            0x80
        !           357: #define CFGD_DIAG              0x40
        !           358: #define CFGD_MAGIC             0x10
        !           359: #define CFGD_RANDOM            0x08
        !           360: #define CFGD_CFDX              0x04
        !           361: #define CFGD_CEREN             0x02
        !           362: #define CFGD_CETEN             0x01
        !           363: 
        !           364: /* Bits in RSR */
        !           365: #define RSR_RERR               0x00000001
        !           366: #define RSR_CRC                        0x00000002
        !           367: #define RSR_FAE                        0x00000004
        !           368: #define RSR_FOV                        0x00000008
        !           369: #define RSR_LONG               0x00000010
        !           370: #define RSR_RUNT               0x00000020
        !           371: #define RSR_SERR               0x00000040
        !           372: #define RSR_BUFF               0x00000080
        !           373: #define RSR_EDP                        0x00000100
        !           374: #define RSR_STP                        0x00000200
        !           375: #define RSR_CHN                        0x00000400
        !           376: #define RSR_PHY                        0x00000800
        !           377: #define RSR_BAR                        0x00001000
        !           378: #define RSR_MAR                        0x00002000
        !           379: #define RSR_RXOK               0x00008000
        !           380: #define RSR_ABNORMAL           RSR_RERR+RSR_LONG+RSR_RUNT
        !           381: 
        !           382: /* Bits in TSR */
        !           383: #define TSR_NCR0               0x00000001
        !           384: #define TSR_NCR1               0x00000002
        !           385: #define TSR_NCR2               0x00000004
        !           386: #define TSR_NCR3               0x00000008
        !           387: #define TSR_COLS               0x00000010
        !           388: #define TSR_CDH                        0x00000080
        !           389: #define TSR_ABT                        0x00000100
        !           390: #define TSR_OWC                        0x00000200
        !           391: #define TSR_CRS                        0x00000400
        !           392: #define TSR_UDF                        0x00000800
        !           393: #define TSR_TBUFF              0x00001000
        !           394: #define TSR_SERR               0x00002000
        !           395: #define TSR_JAB                        0x00004000
        !           396: #define TSR_TERR               0x00008000
        !           397: #define TSR_ABNORMAL           TSR_TERR+TSR_OWC+TSR_ABT+TSR_JAB+TSR_CRS
        !           398: #define TSR_OWN_BIT            0x80000000
        !           399: 
        !           400: #define CB_DELAY_LOOP_WAIT     10      /* 10ms */
        !           401: /* enabled mask value of irq */
        !           402: 
        !           403: #define W_IMR_MASK_VALUE       0x1BFF  /* initial value of IMR */
        !           404: 
        !           405: /* Ethernet address filter type */
        !           406: #define PKT_TYPE_DIRECTED      0x0001  /* obsolete, directed address is always accepted */
        !           407: #define PKT_TYPE_MULTICAST     0x0002
        !           408: #define PKT_TYPE_ALL_MULTICAST 0x0004
        !           409: #define PKT_TYPE_BROADCAST     0x0008
        !           410: #define PKT_TYPE_PROMISCUOUS   0x0020
        !           411: #define PKT_TYPE_LONG          0x2000
        !           412: #define PKT_TYPE_RUNT          0x4000
        !           413: #define PKT_TYPE_ERROR         0x8000  /* accept error packets, e.g. CRC error */
        !           414: 
        !           415: /* Loopback mode */
        !           416: 
        !           417: #define NIC_LB_NONE            0x00
        !           418: #define NIC_LB_INTERNAL                0x01
        !           419: #define NIC_LB_PHY             0x02    /* MII or Internal-10BaseT loopback */
        !           420: 
        !           421: #define TX_RING_SIZE           2
        !           422: #define RX_RING_SIZE           2
        !           423: #define PKT_BUF_SZ             1536    /* Size of each temporary Rx buffer. */
        !           424: 
        !           425: #define PCI_REG_MODE3          0x53
        !           426: #define MODE3_MIION            0x04    /* in PCI_REG_MOD3 OF PCI space */
        !           427: 
        !           428: enum rhine_revs {
        !           429:     VT86C100A       = 0x00,
        !           430:     VTunknown0      = 0x20,
        !           431:     VT6102          = 0x40,
        !           432:     VT8231          = 0x50, /* Integrated MAC */
        !           433:     VT8233          = 0x60, /* Integrated MAC */
        !           434:     VT8235          = 0x74, /* Integrated MAC */
        !           435:     VT8237          = 0x78, /* Integrated MAC */
        !           436:     VTunknown1      = 0x7C,
        !           437:     VT6105          = 0x80,
        !           438:     VT6105_B0       = 0x83,
        !           439:     VT6105L        = 0x8A,
        !           440:     VT6107          = 0x8C,
        !           441:     VTunknown2      = 0x8E,
        !           442:     VT6105M         = 0x90,
        !           443: };
        !           444: 
        !           445: /* Transmit and receive descriptors definition */
        !           446: 
        !           447: struct rhine_tx_desc
        !           448: {
        !           449:     union VTC_tx_status_tag
        !           450:     {
        !           451:        struct
        !           452:        {
        !           453:            unsigned long ncro:1;
        !           454:            unsigned long ncr1:1;
        !           455:            unsigned long ncr2:1;
        !           456:            unsigned long ncr3:1;
        !           457:            unsigned long cols:1;
        !           458:            unsigned long reserve_1:2;
        !           459:            unsigned long cdh:1;
        !           460:            unsigned long abt:1;
        !           461:            unsigned long owc:1;
        !           462:            unsigned long crs:1;
        !           463:            unsigned long udf:1;
        !           464:            unsigned long tbuff:1;
        !           465:            unsigned long serr:1;
        !           466:            unsigned long jab:1;
        !           467:            unsigned long terr:1;
        !           468:            unsigned long reserve_2:15;
        !           469:            unsigned long own_bit:1;
        !           470:        }
        !           471:        bits;
        !           472:        unsigned long lw;
        !           473:     }
        !           474:     tx_status;
        !           475: 
        !           476:     union VTC_tx_ctrl_tag
        !           477:     {
        !           478:        struct
        !           479:        {
        !           480:            unsigned long tx_buf_size:11;
        !           481:            unsigned long extend_tx_buf_size:4;
        !           482:            unsigned long chn:1;
        !           483:            unsigned long crc:1;
        !           484:            unsigned long reserve_1:4;
        !           485:            unsigned long stp:1;
        !           486:            unsigned long edp:1;
        !           487:            unsigned long ic:1;
        !           488:            unsigned long reserve_2:8;
        !           489:        }
        !           490:        bits;
        !           491:        unsigned long lw;
        !           492:     }
        !           493:     tx_ctrl;
        !           494: 
        !           495:     unsigned long buf_addr_1:32;
        !           496:     unsigned long buf_addr_2:32;
        !           497: 
        !           498: };
        !           499: 
        !           500: struct rhine_rx_desc
        !           501: {
        !           502:     union VTC_rx_status_tag
        !           503:     {
        !           504:        struct
        !           505:        {
        !           506:            unsigned long rerr:1;
        !           507:            unsigned long crc_error:1;
        !           508:            unsigned long fae:1;
        !           509:            unsigned long fov:1;
        !           510:            unsigned long toolong:1;
        !           511:            unsigned long runt:1;
        !           512:            unsigned long serr:1;
        !           513:            unsigned long buff:1;
        !           514:            unsigned long edp:1;
        !           515:            unsigned long stp:1;
        !           516:            unsigned long chn:1;
        !           517:            unsigned long phy:1;
        !           518:            unsigned long bar:1;
        !           519:            unsigned long mar:1;
        !           520:            unsigned long reserve_1:1;
        !           521:            unsigned long rxok:1;
        !           522:            unsigned long frame_length:11;
        !           523:            unsigned long reverve_2:4;
        !           524:            unsigned long own_bit:1;
        !           525:        }
        !           526:        bits;
        !           527:        unsigned long lw;
        !           528:     }
        !           529:     rx_status;
        !           530: 
        !           531:     union VTC_rx_ctrl_tag
        !           532:     {
        !           533:        struct
        !           534:        {
        !           535:            unsigned long rx_buf_size:11;
        !           536:            unsigned long extend_rx_buf_size:4;
        !           537:            unsigned long reserved_1:17;
        !           538:        }
        !           539:        bits;
        !           540:        unsigned long lw;
        !           541:     }
        !           542:     rx_ctrl;
        !           543: 
        !           544:     unsigned long buf_addr_1:32;
        !           545:     unsigned long buf_addr_2:32;
        !           546: 
        !           547: };
        !           548: 
        !           549: struct {
        !           550:        char txbuf[TX_RING_SIZE * PKT_BUF_SZ + 32];
        !           551:        char rxbuf[RX_RING_SIZE * PKT_BUF_SZ + 32];
        !           552:        char txdesc[TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32];
        !           553:        char rxdesc[RX_RING_SIZE * sizeof (struct rhine_rx_desc) + 32];
        !           554: } rhine_buffers __shared;
        !           555: 
        !           556: /* The I/O extent. */
        !           557: #define rhine_TOTAL_SIZE 0x80
        !           558: 
        !           559: #ifdef HAVE_DEVLIST
        !           560: struct netdev_entry rhine_drv =
        !           561:     { "rhine", rhine_probe, rhine_TOTAL_SIZE, NULL };
        !           562: #endif
        !           563: 
        !           564: static int rhine_debug = 1;
        !           565: 
        !           566: /*
        !           567:                                Theory of Operation
        !           568: 
        !           569: I. Board Compatibility
        !           570: 
        !           571: This driver is designed for the VIA 86c100A Rhine-II PCI Fast Ethernet
        !           572: controller.
        !           573: 
        !           574: II. Board-specific settings
        !           575: 
        !           576: Boards with this chip are functional only in a bus-master PCI slot.
        !           577: 
        !           578: Many operational settings are loaded from the EEPROM to the Config word at
        !           579: offset 0x78.  This driver assumes that they are correct.
        !           580: If this driver is compiled to use PCI memory space operations the EEPROM
        !           581: must be configured to enable memory ops.
        !           582: 
        !           583: III. Driver operation
        !           584: 
        !           585: IIIa. Ring buffers
        !           586: 
        !           587: This driver uses two statically allocated fixed-size descriptor lists
        !           588: formed into rings by a branch from the final descriptor to the beginning of
        !           589: the list.  The ring sizes are set at compile time by RX/TX_RING_SIZE.
        !           590: 
        !           591: IIIb/c. Transmit/Receive Structure
        !           592: 
        !           593: This driver attempts to use a zero-copy receive and transmit scheme.
        !           594: 
        !           595: Alas, all data buffers are required to start on a 32 bit boundary, so
        !           596: the driver must often copy transmit packets into bounce buffers.
        !           597: 
        !           598: The driver allocates full frame size skbuffs for the Rx ring buffers at
        !           599: open() time and passes the skb->data field to the chip as receive data
        !           600: buffers.  When an incoming frame is less than RX_COPYBREAK bytes long,
        !           601: a fresh skbuff is allocated and the frame is copied to the new skbuff.
        !           602: When the incoming frame is larger, the skbuff is passed directly up the
        !           603: protocol stack.  Buffers consumed this way are replaced by newly allocated
        !           604: skbuffs in the last phase of netdev_rx().
        !           605: 
        !           606: The RX_COPYBREAK value is chosen to trade-off the memory wasted by
        !           607: using a full-sized skbuff for small frames vs. the copying costs of larger
        !           608: frames.  New boards are typically used in generously configured machines
        !           609: and the underfilled buffers have negligible impact compared to the benefit of
        !           610: a single allocation size, so the default value of zero results in never
        !           611: copying packets.  When copying is done, the cost is usually mitigated by using
        !           612: a combined copy/checksum routine.  Copying also preloads the cache, which is
        !           613: most useful with small frames.
        !           614: 
        !           615: Since the VIA chips are only able to transfer data to buffers on 32 bit
        !           616: boundaries, the the IP header at offset 14 in an ethernet frame isn't
        !           617: longword aligned for further processing.  Copying these unaligned buffers
        !           618: has the beneficial effect of 16-byte aligning the IP header.
        !           619: 
        !           620: IIId. Synchronization
        !           621: 
        !           622: The driver runs as two independent, single-threaded flows of control.  One
        !           623: is the send-packet routine, which enforces single-threaded use by the
        !           624: dev->tbusy flag.  The other thread is the interrupt handler, which is single
        !           625: threaded by the hardware and interrupt handling software.
        !           626: 
        !           627: The send packet thread has partial control over the Tx ring and 'dev->tbusy'
        !           628: flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
        !           629: queue slot is empty, it clears the tbusy flag when finished otherwise it sets
        !           630: the 'lp->tx_full' flag.
        !           631: 
        !           632: The interrupt handler has exclusive control over the Rx ring and records stats
        !           633: from the Tx ring.  After reaping the stats, it marks the Tx queue entry as
        !           634: empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it
        !           635: clears both the tx_full and tbusy flags.
        !           636: 
        !           637: IV. Notes
        !           638: 
        !           639: IVb. References
        !           640: 
        !           641: Preliminary VT86C100A manual from http://www.via.com.tw/
        !           642: http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
        !           643: http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
        !           644: 
        !           645: IVc. Errata
        !           646: 
        !           647: The VT86C100A manual is not reliable information.
        !           648: The chip does not handle unaligned transmit or receive buffers, resulting
        !           649: in significant performance degradation for bounce buffer copies on transmit
        !           650: and unaligned IP headers on receive.
        !           651: The chip does not pad to minimum transmit length.
        !           652: 
        !           653: */
        !           654: 
        !           655: /* The rest of these values should never change. */
        !           656: #define NUM_TX_DESC    2       /* Number of Tx descriptor registers. */
        !           657: 
        !           658: static struct rhine_private
        !           659: {
        !           660:     char devname[8];           /* Used only for kernel debugging. */
        !           661:     const char *product_name;
        !           662:     struct rhine_rx_desc *rx_ring;
        !           663:     struct rhine_tx_desc *tx_ring;
        !           664:     char *rx_buffs[RX_RING_SIZE];
        !           665:     char *tx_buffs[TX_RING_SIZE];
        !           666: 
        !           667:     /* temporary Rx buffers. */
        !           668: 
        !           669:     int chip_id;
        !           670:     int chip_revision;
        !           671:     unsigned short ioaddr;
        !           672:     unsigned int cur_rx, cur_tx;       /* The next free and used entries */
        !           673:     unsigned int dirty_rx, dirty_tx;
        !           674:     /* The saved address of a sent-in-place packet/buffer, for skfree(). */
        !           675:     struct sk_buff *tx_skbuff[TX_RING_SIZE];
        !           676:     unsigned char mc_filter[8];        /* Current multicast filter. */
        !           677:     char phys[4];              /* MII device addresses. */
        !           678:     unsigned int tx_full:1;    /* The Tx queue is full. */
        !           679:     unsigned int full_duplex:1;        /* Full-duplex operation requested. */
        !           680:     unsigned int default_port:4;       /* Last dev->if_port value. */
        !           681:     unsigned int media2:4;     /* Secondary monitored media port. */
        !           682:     unsigned int medialock:1;  /* Don't sense media type. */
        !           683:     unsigned int mediasense:1; /* Media sensing in progress. */
        !           684: }
        !           685: rhine;
        !           686: 
        !           687: static void rhine_probe1 (struct nic *nic, struct pci_device *pci, int ioaddr,
        !           688:                                 int chip_id, int options);
        !           689: static int QueryAuto (int);
        !           690: static int ReadMII (int byMIIIndex, int);
        !           691: static void WriteMII (char, char, char, int);
        !           692: static void MIIDelay (void);
        !           693: static void rhine_init_ring (struct nic *dev);
        !           694: static void rhine_disable (struct nic *nic);
        !           695: static void rhine_reset (struct nic *nic);
        !           696: static int rhine_poll (struct nic *nic, int retreive);
        !           697: static void rhine_transmit (struct nic *nic, const char *d, unsigned int t,
        !           698:                            unsigned int s, const char *p);
        !           699: static void reload_eeprom(int ioaddr);
        !           700: 
        !           701: 
        !           702: static void reload_eeprom(int ioaddr)
        !           703: {
        !           704:        int i;
        !           705:        outb(0x20, byEECSR);
        !           706:        /* Typically 2 cycles to reload. */
        !           707:        for (i = 0; i < 150; i++)
        !           708:                if (! (inb(byEECSR) & 0x20))
        !           709:                        break;
        !           710: }
        !           711: /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
        !           712: static void
        !           713: rhine_init_ring (struct nic *nic)
        !           714: {
        !           715:     struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
        !           716:     int i;
        !           717: 
        !           718:     tp->tx_full = 0;
        !           719:     tp->cur_rx = tp->cur_tx = 0;
        !           720:     tp->dirty_rx = tp->dirty_tx = 0;
        !           721: 
        !           722:     for (i = 0; i < RX_RING_SIZE; i++)
        !           723:     {
        !           724: 
        !           725:        tp->rx_ring[i].rx_status.bits.own_bit = 1;
        !           726:        tp->rx_ring[i].rx_ctrl.bits.rx_buf_size = 1536;
        !           727: 
        !           728:        tp->rx_ring[i].buf_addr_1 = virt_to_bus (tp->rx_buffs[i]);
        !           729:        tp->rx_ring[i].buf_addr_2 = virt_to_bus (&tp->rx_ring[i + 1]);
        !           730:        /* printf("[%d]buf1=%hX,buf2=%hX",i,tp->rx_ring[i].buf_addr_1,tp->rx_ring[i].buf_addr_2); */
        !           731:     }
        !           732:     /* Mark the last entry as wrapping the ring. */
        !           733:     /* tp->rx_ring[i-1].rx_ctrl.bits.rx_buf_size =1518; */
        !           734:     tp->rx_ring[i - 1].buf_addr_2 = virt_to_bus (&tp->rx_ring[0]);
        !           735:     /*printf("[%d]buf1=%hX,buf2=%hX",i-1,tp->rx_ring[i-1].buf_addr_1,tp->rx_ring[i-1].buf_addr_2); */
        !           736: 
        !           737:     /* The Tx buffer descriptor is filled in as needed, but we
        !           738:        do need to clear the ownership bit. */
        !           739: 
        !           740:     for (i = 0; i < TX_RING_SIZE; i++)
        !           741:     {
        !           742: 
        !           743:        tp->tx_ring[i].tx_status.lw = 0;
        !           744:        tp->tx_ring[i].tx_ctrl.lw = 0x00e08000;
        !           745:        tp->tx_ring[i].buf_addr_1 = virt_to_bus (tp->tx_buffs[i]);
        !           746:        tp->tx_ring[i].buf_addr_2 = virt_to_bus (&tp->tx_ring[i + 1]);
        !           747:        /* printf("[%d]buf1=%hX,buf2=%hX",i,tp->tx_ring[i].buf_addr_1,tp->tx_ring[i].buf_addr_2); */
        !           748:     }
        !           749: 
        !           750:     tp->tx_ring[i - 1].buf_addr_2 = virt_to_bus (&tp->tx_ring[0]);
        !           751:     /* printf("[%d]buf1=%hX,buf2=%hX",i,tp->tx_ring[i-1].buf_addr_1,tp->tx_ring[i-1].buf_addr_2); */
        !           752: }
        !           753: 
        !           754: int
        !           755: QueryAuto (int ioaddr)
        !           756: {
        !           757:     int byMIIIndex;
        !           758:     int MIIReturn;
        !           759: 
        !           760:        int advertising,mii_reg5;
        !           761:        int negociated;
        !           762: 
        !           763:     byMIIIndex = 0x04;
        !           764:     MIIReturn = ReadMII (byMIIIndex, ioaddr);
        !           765:        advertising=MIIReturn;
        !           766: 
        !           767:     byMIIIndex = 0x05;
        !           768:     MIIReturn = ReadMII (byMIIIndex, ioaddr);
        !           769:        mii_reg5=MIIReturn;
        !           770: 
        !           771:        negociated=mii_reg5 & advertising;
        !           772: 
        !           773:        if ( (negociated & 0x100) || (negociated & 0x1C0) == 0x40 )
        !           774:                return 1;
        !           775:        else
        !           776:                return 0;
        !           777: 
        !           778: }
        !           779: 
        !           780: int
        !           781: ReadMII (int byMIIIndex, int ioaddr)
        !           782: {
        !           783:     int ReturnMII;
        !           784:     char byMIIAdrbak;
        !           785:     char byMIICRbak;
        !           786:     char byMIItemp;
        !           787:     unsigned long ct;
        !           788: 
        !           789:     byMIIAdrbak = inb (byMIIAD);
        !           790:     byMIICRbak = inb (byMIICR);
        !           791:     outb (byMIICRbak & 0x7f, byMIICR);
        !           792:     MIIDelay ();
        !           793: 
        !           794:     outb (byMIIIndex, byMIIAD);
        !           795:     MIIDelay ();
        !           796: 
        !           797:     outb (inb (byMIICR) | 0x40, byMIICR);
        !           798: 
        !           799:     byMIItemp = inb (byMIICR);
        !           800:     byMIItemp = byMIItemp & 0x40;
        !           801: 
        !           802:     ct = currticks();
        !           803:     while (byMIItemp != 0 && ct + 2*1000 < currticks())
        !           804:     {
        !           805:        byMIItemp = inb (byMIICR);
        !           806:        byMIItemp = byMIItemp & 0x40;
        !           807:     }
        !           808:     MIIDelay ();
        !           809: 
        !           810:     ReturnMII = inw (wMIIDATA);
        !           811: 
        !           812:     outb (byMIIAdrbak, byMIIAD);
        !           813:     outb (byMIICRbak, byMIICR);
        !           814:     MIIDelay ();
        !           815: 
        !           816:     return (ReturnMII);
        !           817: 
        !           818: }
        !           819: 
        !           820: void
        !           821: WriteMII (char byMIISetByte, char byMIISetBit, char byMIIOP, int ioaddr)
        !           822: {
        !           823:     int ReadMIItmp;
        !           824:     int MIIMask;
        !           825:     char byMIIAdrbak;
        !           826:     char byMIICRbak;
        !           827:     char byMIItemp;
        !           828:     unsigned long ct;
        !           829: 
        !           830: 
        !           831:     byMIIAdrbak = inb (byMIIAD);
        !           832: 
        !           833:     byMIICRbak = inb (byMIICR);
        !           834:     outb (byMIICRbak & 0x7f, byMIICR);
        !           835:     MIIDelay ();
        !           836:     outb (byMIISetByte, byMIIAD);
        !           837:     MIIDelay ();
        !           838: 
        !           839:     outb (inb (byMIICR) | 0x40, byMIICR);
        !           840: 
        !           841:     byMIItemp = inb (byMIICR);
        !           842:     byMIItemp = byMIItemp & 0x40;
        !           843: 
        !           844:     ct = currticks();
        !           845:     while (byMIItemp != 0 && ct + 2*1000 < currticks())
        !           846:     {
        !           847:        byMIItemp = inb (byMIICR);
        !           848:        byMIItemp = byMIItemp & 0x40;
        !           849:     }
        !           850:     MIIDelay ();
        !           851: 
        !           852:     ReadMIItmp = inw (wMIIDATA);
        !           853:     MIIMask = 0x0001;
        !           854:     MIIMask = MIIMask << byMIISetBit;
        !           855: 
        !           856: 
        !           857:     if (byMIIOP == 0)
        !           858:     {
        !           859:        MIIMask = ~MIIMask;
        !           860:        ReadMIItmp = ReadMIItmp & MIIMask;
        !           861:     }
        !           862:     else
        !           863:     {
        !           864:        ReadMIItmp = ReadMIItmp | MIIMask;
        !           865: 
        !           866:     }
        !           867:     outw (ReadMIItmp, wMIIDATA);
        !           868:     MIIDelay ();
        !           869: 
        !           870:     outb (inb (byMIICR) | 0x20, byMIICR);
        !           871:     byMIItemp = inb (byMIICR);
        !           872:     byMIItemp = byMIItemp & 0x20;
        !           873: 
        !           874:     ct = currticks();
        !           875:     while (byMIItemp != 0 && ct + 2*1000 < currticks())
        !           876:     {
        !           877:        byMIItemp = inb (byMIICR);
        !           878:        byMIItemp = byMIItemp & 0x20;
        !           879:     }
        !           880:     MIIDelay ();
        !           881: 
        !           882:     outb (byMIIAdrbak & 0x7f, byMIIAD);
        !           883:     outb (byMIICRbak, byMIICR);
        !           884:     MIIDelay ();
        !           885: 
        !           886: }
        !           887: 
        !           888: void
        !           889: MIIDelay (void)
        !           890: {
        !           891:     int i;
        !           892:     for (i = 0; i < 0x7fff; i++)
        !           893:     {
        !           894:         ( void ) inb (0x61);
        !           895:         ( void ) inb (0x61);
        !           896:         ( void ) inb (0x61);
        !           897:         ( void ) inb (0x61);
        !           898:     }
        !           899: }
        !           900: 
        !           901: /* Offsets to the device registers. */
        !           902: enum register_offsets {
        !           903:         StationAddr=0x00, RxConfig=0x06, TxConfig=0x07, ChipCmd=0x08,
        !           904:         IntrStatus=0x0C, IntrEnable=0x0E,
        !           905:         MulticastFilter0=0x10, MulticastFilter1=0x14,
        !           906:         RxRingPtr=0x18, TxRingPtr=0x1C, GFIFOTest=0x54,
        !           907:         MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIBusConfig=0x6E,
        !           908:         MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74,
        !           909:         ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B,
        !           910:         RxMissed=0x7C, RxCRCErrs=0x7E, MiscCmd=0x81,
        !           911:         StickyHW=0x83, IntrStatus2=0x84, WOLcrClr=0xA4, WOLcgClr=0xA7,
        !           912:         PwrcsrClr=0xAC,
        !           913: };
        !           914: 
        !           915: /* Bits in the interrupt status/mask registers. */
        !           916: enum intr_status_bits {
        !           917:         IntrRxDone=0x0001, IntrRxErr=0x0004, IntrRxEmpty=0x0020,
        !           918:         IntrTxDone=0x0002, IntrTxError=0x0008, IntrTxUnderrun=0x0210,
        !           919:         IntrPCIErr=0x0040,
        !           920:         IntrStatsMax=0x0080, IntrRxEarly=0x0100,
        !           921:         IntrRxOverflow=0x0400, IntrRxDropped=0x0800, IntrRxNoBuf=0x1000,
        !           922:         IntrTxAborted=0x2000, IntrLinkChange=0x4000,
        !           923:         IntrRxWakeUp=0x8000,
        !           924:         IntrNormalSummary=0x0003, IntrAbnormalSummary=0xC260,
        !           925:         IntrTxDescRace=0x080000,        /* mapped from IntrStatus2 */
        !           926:         IntrTxErrSummary=0x082218,
        !           927: };
        !           928: #define DEFAULT_INTR (IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | \
        !           929:                    IntrRxDropped | IntrRxNoBuf) 
        !           930: 
        !           931: /***************************************************************************
        !           932:  IRQ - PXE IRQ Handler
        !           933: ***************************************************************************/
        !           934: void rhine_irq ( struct nic *nic, irq_action_t action ) {
        !           935:     struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
        !           936:     /* Enable interrupts by setting the interrupt mask. */
        !           937:     unsigned int intr_status;
        !           938: 
        !           939:     switch ( action ) {
        !           940:         case DISABLE :
        !           941:         case ENABLE :
        !           942:             intr_status = inw(nic->ioaddr + IntrStatus);
        !           943:             /* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */
        !           944: 
        !           945:             /* added comment by guard */
        !           946:             /* For supporting VT6107, please use revision id to recognize different chips in driver */
        !           947:             // if (tp->chip_id == 0x3065)
        !           948:             if( tp->chip_revision < 0x80 && tp->chip_revision >=0x40 )
        !           949:                 intr_status |= inb(nic->ioaddr + IntrStatus2) << 16;
        !           950:                 intr_status = (intr_status & ~DEFAULT_INTR);
        !           951:                 if ( action == ENABLE ) 
        !           952:                     intr_status = intr_status | DEFAULT_INTR;
        !           953:                     outw(intr_status, nic->ioaddr + IntrEnable);
        !           954:                 break;
        !           955:         case FORCE :
        !           956:             outw(0x0010, nic->ioaddr + 0x84);
        !           957:            break;
        !           958:         }
        !           959: }
        !           960: 
        !           961: static struct nic_operations rhine_operations;
        !           962: 
        !           963: static int
        !           964: rhine_probe ( struct nic *nic, struct pci_device *pci ) {
        !           965: 
        !           966:     struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
        !           967: 
        !           968:     if (!pci->ioaddr)
        !           969:        return 0;
        !           970: 
        !           971:     rhine_probe1 (nic, pci, pci->ioaddr, pci->device, -1);
        !           972: 
        !           973:     adjust_pci_device ( pci );
        !           974: 
        !           975:     rhine_reset (nic);
        !           976: 
        !           977:     nic->nic_op        = &rhine_operations;
        !           978: 
        !           979:     nic->irqno   = pci->irq;
        !           980:     nic->ioaddr   = tp->ioaddr;
        !           981: 
        !           982:     return 1;
        !           983: }
        !           984: 
        !           985: static void set_rx_mode(struct nic *nic __unused) {
        !           986:        struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
        !           987:        unsigned char rx_mode;
        !           988:        int ioaddr = tp->ioaddr;
        !           989: 
        !           990:        /* ! IFF_PROMISC */
        !           991:        outl(0xffffffff, byMAR0);
        !           992:        outl(0xffffffff, byMAR4);
        !           993:        rx_mode = 0x0C;
        !           994: 
        !           995:        outb(0x60 /* thresh */ | rx_mode, byRCR );
        !           996: }
        !           997: 
        !           998: static void
        !           999: rhine_probe1 (struct nic *nic, struct pci_device *pci, int ioaddr, int chip_id, int options)
        !          1000: {
        !          1001:     struct rhine_private *tp;
        !          1002:     static int did_version = 0;        /* Already printed version info. */
        !          1003:     unsigned int i, ww;
        !          1004:     unsigned int timeout;
        !          1005:     int FDXFlag;
        !          1006:     int byMIIvalue, LineSpeed, MIICRbak;
        !          1007:     uint8_t revision_id;    
        !          1008:     unsigned char mode3_reg;
        !          1009: 
        !          1010:     if (rhine_debug > 0 && did_version++ == 0)
        !          1011:        printf ("%s",version);
        !          1012: 
        !          1013:     // get revision id.
        !          1014:     pci_read_config_byte(pci, PCI_REVISION, &revision_id);
        !          1015: 
        !          1016:     /* D-Link provided reset code (with comment additions) */
        !          1017:     if (revision_id >= 0x40) {
        !          1018:        unsigned char byOrgValue;
        !          1019:        
        !          1020:        if(rhine_debug > 0)
        !          1021:                printf("Enabling Sticky Bit Workaround for Chip_id: 0x%hX\n"
        !          1022:                                , chip_id);
        !          1023:        /* clear sticky bit before reset & read ethernet address */
        !          1024:        byOrgValue = inb(bySTICKHW);
        !          1025:        byOrgValue = byOrgValue & 0xFC;
        !          1026:        outb(byOrgValue, bySTICKHW);
        !          1027: 
        !          1028:        /* (bits written are cleared?) */
        !          1029:        /* disable force PME-enable */
        !          1030:        outb(0x80, byWOLcgClr);
        !          1031:        /* disable power-event config bit */
        !          1032:        outb(0xFF, byWOLcrClr);
        !          1033:        /* clear power status (undocumented in vt6102 docs?) */
        !          1034:        outb(0xFF, byPwrcsrClr);
        !          1035:        
        !          1036:     }
        !          1037: 
        !          1038:     /* Reset the chip to erase previous misconfiguration. */
        !          1039:     outw(CR_SFRST, byCR0);
        !          1040:     // if vt3043 delay after reset
        !          1041:     if (revision_id <0x40) {
        !          1042:        udelay(10000);
        !          1043:     }
        !          1044:     // polling till software reset complete
        !          1045:     // W_MAX_TIMEOUT is the timeout period
        !          1046:     for(ww = 0; ww < W_MAX_TIMEOUT; ww++) {
        !          1047:         if ((inw(byCR0) & CR_SFRST) == 0)
        !          1048:                break;
        !          1049:         }
        !          1050: 
        !          1051:     // issue AUTOLoad in EECSR to reload eeprom
        !          1052:     outb(0x20, byEECSR );
        !          1053: 
        !          1054:     // if vt3065 delay after reset
        !          1055:     if (revision_id >=0x40) {
        !          1056:        // delay 8ms to let MAC stable
        !          1057:        mdelay(8);
        !          1058:         /*
        !          1059:          * for 3065D, EEPROM reloaded will cause bit 0 in MAC_REG_CFGA
        !          1060:          * turned on.  it makes MAC receive magic packet
        !          1061:          * automatically. So, we turn it off. (D-Link)
        !          1062:          */
        !          1063:          outb(inb(byCFGA) & 0xFE, byCFGA);
        !          1064:     }
        !          1065: 
        !          1066:     /* turn on bit2 in PCI configuration register 0x53 , only for 3065*/
        !          1067:     if (revision_id >= 0x40) {
        !          1068:         pci_read_config_byte(pci, PCI_REG_MODE3, &mode3_reg);
        !          1069:         pci_write_config_byte(pci, PCI_REG_MODE3, mode3_reg|MODE3_MIION);
        !          1070:     }
        !          1071: 
        !          1072: 
        !          1073:     /* back off algorithm ,disable the right-most 4-bit off CFGD*/
        !          1074:     outb(inb(byCFGD) & (~(CFGD_RANDOM | CFGD_CFDX | CFGD_CEREN | CFGD_CETEN)), byCFGD);
        !          1075: 
        !          1076:     /* reload eeprom */
        !          1077:     reload_eeprom(ioaddr);
        !          1078: 
        !          1079:     /* Perhaps this should be read from the EEPROM? */
        !          1080:     for (i = 0; i < ETH_ALEN; i++)
        !          1081:        nic->node_addr[i] = inb (byPAR0 + i);
        !          1082: 
        !          1083:     DBG ( "IO address %#hX Ethernet Address: %s\n", ioaddr, eth_ntoa ( nic->node_addr ) );
        !          1084: 
        !          1085:     /* restart MII auto-negotiation */
        !          1086:     WriteMII (0, 9, 1, ioaddr);
        !          1087:     printf ("Analyzing Media type,this may take several seconds... ");
        !          1088:     for (i = 0; i < 5; i++)
        !          1089:     {
        !          1090:        /* need to wait 1 millisecond - we will round it up to 50-100ms */
        !          1091:        timeout = currticks() + 2;
        !          1092:        for (timeout = currticks() + 2; currticks() < timeout;)
        !          1093:            /* nothing */;
        !          1094:        if (ReadMII (1, ioaddr) & 0x0020)
        !          1095:            break;
        !          1096:     }
        !          1097:     printf ("OK.\n");
        !          1098: 
        !          1099: #if 0
        !          1100:        /* JJM : for Debug */
        !          1101:        printf("MII : Address %hhX ",inb(ioaddr+0x6c));
        !          1102:        {
        !          1103:         unsigned char st1,st2,adv1,adv2,l1,l2;
        !          1104:        
        !          1105:         st1=ReadMII(1,ioaddr)>>8;
        !          1106:         st2=ReadMII(1,ioaddr)&0xFF;
        !          1107:         adv1=ReadMII(4,ioaddr)>>8;
        !          1108:         adv2=ReadMII(4,ioaddr)&0xFF;
        !          1109:         l1=ReadMII(5,ioaddr)>>8;
        !          1110:         l2=ReadMII(5,ioaddr)&0xFF;
        !          1111:         printf(" status 0x%hhX%hhX, advertising 0x%hhX%hhX, link 0x%hhX%hhX\n", st1,st2,adv1,adv2,l1,l2);
        !          1112:        }
        !          1113: #endif
        !          1114: 
        !          1115:     
        !          1116:     /* query MII to know LineSpeed,duplex mode */
        !          1117:     byMIIvalue = inb (ioaddr + 0x6d);
        !          1118:     LineSpeed = byMIIvalue & MIISR_SPEED;
        !          1119:     if (LineSpeed != 0)                                                //JJM
        !          1120:     {
        !          1121:        printf ("Linespeed=10Mbs");
        !          1122:     }
        !          1123:     else
        !          1124:     {
        !          1125:        printf ("Linespeed=100Mbs");
        !          1126:     }
        !          1127:        
        !          1128:     FDXFlag = QueryAuto (ioaddr);
        !          1129:     if (FDXFlag == 1)
        !          1130:     {
        !          1131:        printf (" Fullduplex\n");
        !          1132:        outw (CR_FDX, byCR0);
        !          1133:     }
        !          1134:     else
        !          1135:     {
        !          1136:        printf (" Halfduplex\n");
        !          1137:     }
        !          1138: 
        !          1139: 
        !          1140:     /* set MII 10 FULL ON, only apply in vt3043 */
        !          1141:     if(chip_id == 0x3043)
        !          1142:         WriteMII (0x17, 1, 1, ioaddr);
        !          1143: 
        !          1144:     /* turn on MII link change */
        !          1145:     MIICRbak = inb (byMIICR);
        !          1146:     outb (MIICRbak & 0x7F, byMIICR);
        !          1147:     MIIDelay ();
        !          1148:     outb (0x41, byMIIAD);
        !          1149:     MIIDelay ();
        !          1150: 
        !          1151:     /* while((inb(byMIIAD)&0x20)==0) ; */
        !          1152:     outb (MIICRbak | 0x80, byMIICR);
        !          1153: 
        !          1154:     nic->priv_data = &rhine;
        !          1155:     tp = &rhine;
        !          1156:     tp->chip_id = chip_id;
        !          1157:     tp->ioaddr = ioaddr;
        !          1158:     tp->phys[0] = -1;
        !          1159:     tp->chip_revision = revision_id;
        !          1160: 
        !          1161:     /* The lower four bits are the media type. */
        !          1162:     if (options > 0)
        !          1163:     {
        !          1164:        tp->full_duplex = (options & 16) ? 1 : 0;
        !          1165:        tp->default_port = options & 15;
        !          1166:        if (tp->default_port)
        !          1167:            tp->medialock = 1;
        !          1168:     }
        !          1169:     return;
        !          1170: }
        !          1171: 
        !          1172: static void 
        !          1173: rhine_disable ( struct nic *nic ) {
        !          1174: 
        !          1175:     struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
        !          1176:     int ioaddr = tp->ioaddr;
        !          1177: 
        !          1178:     rhine_reset(nic);
        !          1179: 
        !          1180:     printf ("rhine disable\n");
        !          1181:     /* Switch to loopback mode to avoid hardware races. */
        !          1182:     outb(0x60 | 0x01, byTCR);
        !          1183:     /* Stop the chip's Tx and Rx processes. */
        !          1184:     outw(CR_STOP, byCR0);
        !          1185: }
        !          1186: 
        !          1187: /**************************************************************************
        !          1188: ETH_RESET - Reset adapter
        !          1189: ***************************************************************************/
        !          1190: static void
        !          1191: rhine_reset (struct nic *nic)
        !          1192: {
        !          1193:     struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
        !          1194:     int ioaddr = tp->ioaddr;
        !          1195:     int i, j;
        !          1196:     int FDXFlag, CRbak;
        !          1197:     void *rx_ring_tmp;
        !          1198:     void *tx_ring_tmp;
        !          1199:     void *rx_bufs_tmp;
        !          1200:     void *tx_bufs_tmp;
        !          1201:     unsigned long rx_ring_tmp1;
        !          1202:     unsigned long tx_ring_tmp1;
        !          1203:     unsigned long rx_bufs_tmp1;
        !          1204:     unsigned long tx_bufs_tmp1;
        !          1205: 
        !          1206:     /* printf ("rhine_reset\n"); */
        !          1207:     /* Soft reset the chip. */
        !          1208:     /*outb(CmdReset, ioaddr + ChipCmd); */
        !          1209: 
        !          1210:     tx_bufs_tmp = rhine_buffers.txbuf;
        !          1211:     tx_ring_tmp = rhine_buffers.txdesc;
        !          1212:     rx_bufs_tmp = rhine_buffers.rxbuf;
        !          1213:     rx_ring_tmp = rhine_buffers.rxdesc;
        !          1214: 
        !          1215:     /* tune RD TD 32 byte alignment */
        !          1216:     rx_ring_tmp1 = virt_to_bus ( rx_ring_tmp );
        !          1217:     j = (rx_ring_tmp1 + 32) & (~0x1f);
        !          1218:     /* printf ("txring[%d]", j); */
        !          1219:     tp->rx_ring = (struct rhine_rx_desc *) bus_to_virt (j);
        !          1220: 
        !          1221:     tx_ring_tmp1 = virt_to_bus ( tx_ring_tmp );
        !          1222:     j = (tx_ring_tmp1 + 32) & (~0x1f);
        !          1223:     tp->tx_ring = (struct rhine_tx_desc *) bus_to_virt (j);
        !          1224:     /* printf ("rxring[%X]", j); */
        !          1225: 
        !          1226: 
        !          1227:     tx_bufs_tmp1 = virt_to_bus ( tx_bufs_tmp );
        !          1228:     j = (int) (tx_bufs_tmp1 + 32) & (~0x1f);
        !          1229:     tx_bufs_tmp = bus_to_virt (j);
        !          1230:     /* printf ("txb[%X]", j); */
        !          1231: 
        !          1232:     rx_bufs_tmp1 = virt_to_bus ( rx_bufs_tmp );
        !          1233:     j = (int) (rx_bufs_tmp1 + 32) & (~0x1f);
        !          1234:     rx_bufs_tmp = bus_to_virt (j);
        !          1235:     /* printf ("rxb[%X][%X]", rx_bufs_tmp1, j); */
        !          1236: 
        !          1237:     for (i = 0; i < RX_RING_SIZE; i++)
        !          1238:     {
        !          1239:        tp->rx_buffs[i] = (char *) rx_bufs_tmp;
        !          1240:        /* printf("r[%X]",tp->rx_buffs[i]); */
        !          1241:        rx_bufs_tmp += 1536;
        !          1242:     }
        !          1243: 
        !          1244:     for (i = 0; i < TX_RING_SIZE; i++)
        !          1245:     {
        !          1246:        tp->tx_buffs[i] = (char *) tx_bufs_tmp;
        !          1247:        /* printf("t[%X]",tp->tx_buffs[i]);  */
        !          1248:        tx_bufs_tmp += 1536;
        !          1249:     }
        !          1250: 
        !          1251:     /* software reset */
        !          1252:     outb (CR1_SFRST, byCR1);
        !          1253:     MIIDelay ();
        !          1254: 
        !          1255:     /* printf ("init ring"); */
        !          1256:     rhine_init_ring (nic);
        !          1257:     /*write TD RD Descriptor to MAC */
        !          1258:     outl (virt_to_bus (tp->rx_ring), dwCurrentRxDescAddr);
        !          1259:     outl (virt_to_bus (tp->tx_ring), dwCurrentTxDescAddr);
        !          1260: 
        !          1261:     /* Setup Multicast */      
        !          1262:     set_rx_mode(nic);
        !          1263: 
        !          1264:     /* set TCR RCR threshold to store and forward*/
        !          1265:     outb (0x3e, byBCR0);
        !          1266:     outb (0x38, byBCR1);
        !          1267:     outb (0x2c, byRCR);
        !          1268:     outb (0x60, byTCR);
        !          1269:     /* Set Fulldupex */
        !          1270:     FDXFlag = QueryAuto (ioaddr);
        !          1271:     if (FDXFlag == 1)
        !          1272:     {
        !          1273:        outb (CFGD_CFDX, byCFGD);
        !          1274:        outw (CR_FDX, byCR0);
        !          1275:     }
        !          1276: 
        !          1277:     /* KICK NIC to WORK */
        !          1278:     CRbak = inw (byCR0);
        !          1279:     CRbak = CRbak & 0xFFFB;    /* not CR_STOP */
        !          1280:     outw ((CRbak | CR_STRT | CR_TXON | CR_RXON | CR_DPOLL), byCR0);
        !          1281: 
        !          1282:     /* disable all known interrupt */
        !          1283:     outw (0, byIMR0);
        !          1284: }
        !          1285: /* Beware of PCI posted writes */
        !          1286: #define IOSYNC  do { inb(nic->ioaddr + StationAddr); } while (0)
        !          1287: 
        !          1288: static int
        !          1289: rhine_poll (struct nic *nic, int retreive)
        !          1290: {
        !          1291:     struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
        !          1292:     int rxstatus, good = 0;;
        !          1293: 
        !          1294:     if (tp->rx_ring[tp->cur_rx].rx_status.bits.own_bit == 0)
        !          1295:     {
        !          1296:         unsigned int intr_status;
        !          1297:         /* There is a packet ready */
        !          1298:         if(!retreive)
        !          1299:             return 1;
        !          1300: 
        !          1301:         intr_status = inw(nic->ioaddr + IntrStatus);
        !          1302:         /* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */
        !          1303: #if 0
        !          1304:        if (tp->chip_id == 0x3065)
        !          1305:          intr_status |= inb(nic->ioaddr + IntrStatus2) << 16;
        !          1306: #endif
        !          1307:         /* Acknowledge all of the current interrupt sources ASAP. */
        !          1308:         if (intr_status & IntrTxDescRace)
        !          1309:            outb(0x08, nic->ioaddr + IntrStatus2);
        !          1310:         outw(intr_status & 0xffff, nic->ioaddr + IntrStatus);
        !          1311:        IOSYNC;
        !          1312: 
        !          1313:        rxstatus = tp->rx_ring[tp->cur_rx].rx_status.lw;
        !          1314:        if ((rxstatus & 0x0300) != 0x0300)
        !          1315:        {
        !          1316:            printf("rhine_poll: bad status\n");
        !          1317:        }
        !          1318:        else if (rxstatus & (RSR_ABNORMAL))
        !          1319:        {
        !          1320:            printf ("rxerr[%X]\n", rxstatus);
        !          1321:        }
        !          1322:        else
        !          1323:            good = 1;
        !          1324: 
        !          1325:        if (good)
        !          1326:        {
        !          1327:            nic->packetlen = tp->rx_ring[tp->cur_rx].rx_status.bits.frame_length;
        !          1328:            memcpy (nic->packet, tp->rx_buffs[tp->cur_rx], nic->packetlen);
        !          1329:            /* printf ("Packet RXed\n"); */
        !          1330:        }
        !          1331:        tp->rx_ring[tp->cur_rx].rx_status.bits.own_bit = 1;
        !          1332:        tp->cur_rx++;
        !          1333:        tp->cur_rx = tp->cur_rx % RX_RING_SIZE;
        !          1334:     }
        !          1335:         /* Acknowledge all of the current interrupt sources ASAP. */
        !          1336:         outw(DEFAULT_INTR & ~IntrRxDone, nic->ioaddr + IntrStatus);
        !          1337: 
        !          1338:         IOSYNC;
        !          1339: 
        !          1340:     return good;
        !          1341: }
        !          1342: 
        !          1343: static void
        !          1344: rhine_transmit (struct nic *nic,
        !          1345:                const char *d, unsigned int t, unsigned int s, const char *p)
        !          1346: {
        !          1347:     struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
        !          1348:     int ioaddr = tp->ioaddr;
        !          1349:     int entry;
        !          1350:     unsigned char CR1bak;
        !          1351:     unsigned char CR0bak;
        !          1352:     unsigned int nstype;
        !          1353:     unsigned long ct;
        !          1354: 
        !          1355: 
        !          1356:     /*printf ("rhine_transmit\n"); */
        !          1357:     /* setup ethernet header */
        !          1358: 
        !          1359: 
        !          1360:     /* Calculate the next Tx descriptor entry. */
        !          1361:     entry = tp->cur_tx % TX_RING_SIZE;
        !          1362: 
        !          1363:     memcpy (tp->tx_buffs[entry], d, ETH_ALEN); /* dst */
        !          1364:     memcpy (tp->tx_buffs[entry] + ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
        !          1365:     
        !          1366:     nstype=htons(t);
        !          1367:     memcpy(tp->tx_buffs[entry] + 2 * ETH_ALEN, (char*)&nstype, 2);
        !          1368: 
        !          1369:     memcpy (tp->tx_buffs[entry] + ETH_HLEN, p, s);
        !          1370:     s += ETH_HLEN;
        !          1371:     while (s < ETH_ZLEN)
        !          1372:        *((char *) tp->tx_buffs[entry] + (s++)) = 0;
        !          1373: 
        !          1374:     tp->tx_ring[entry].tx_ctrl.bits.tx_buf_size = s;
        !          1375: 
        !          1376:     tp->tx_ring[entry].tx_status.bits.own_bit = 1;
        !          1377: 
        !          1378: 
        !          1379:     CR1bak = inb (byCR1);
        !          1380: 
        !          1381:     CR1bak = CR1bak | CR1_TDMD1;
        !          1382:     /*printf("tdsw=[%X]",tp->tx_ring[entry].tx_status.lw); */
        !          1383:     /*printf("tdcw=[%X]",tp->tx_ring[entry].tx_ctrl.lw); */
        !          1384:     /*printf("tdbuf1=[%X]",tp->tx_ring[entry].buf_addr_1); */
        !          1385:     /*printf("tdbuf2=[%X]",tp->tx_ring[entry].buf_addr_2); */
        !          1386:     /*printf("td1=[%X]",inl(dwCurrentTDSE0)); */
        !          1387:     /*printf("td2=[%X]",inl(dwCurrentTDSE1)); */
        !          1388:     /*printf("td3=[%X]",inl(dwCurrentTDSE2)); */
        !          1389:     /*printf("td4=[%X]",inl(dwCurrentTDSE3)); */
        !          1390: 
        !          1391:     outb (CR1bak, byCR1);
        !          1392:     do
        !          1393:     {
        !          1394:        ct = currticks();
        !          1395:         /* Wait until transmit is finished or timeout*/
        !          1396:         while((tp->tx_ring[entry].tx_status.bits.own_bit !=0) &&
        !          1397:                ct + 10*1000 < currticks())
        !          1398:         ;
        !          1399: 
        !          1400:         if(tp->tx_ring[entry].tx_status.bits.terr == 0)
        !          1401:             break;
        !          1402: 
        !          1403:         if(tp->tx_ring[entry].tx_status.bits.abt == 1)
        !          1404:         {
        !          1405:             // turn on TX
        !          1406:             CR0bak = inb(byCR0);
        !          1407:             CR0bak = CR0bak|CR_TXON;
        !          1408:             outb(CR0bak,byCR0);
        !          1409:         }
        !          1410:     }while(0);
        !          1411:     tp->cur_tx++;
        !          1412: 
        !          1413:     /*outw(IMRShadow,byIMR0); */
        !          1414:     /*dev_kfree_skb(tp->tx_skbuff[entry], FREE_WRITE); */
        !          1415:     /*tp->tx_skbuff[entry] = 0; */
        !          1416: }
        !          1417: 
        !          1418: static struct nic_operations rhine_operations = {
        !          1419:        .connect        = dummy_connect,
        !          1420:        .poll           = rhine_poll,
        !          1421:        .transmit       = rhine_transmit,
        !          1422:        .irq            = rhine_irq,
        !          1423: 
        !          1424: };
        !          1425: 
        !          1426: static struct pci_device_id rhine_nics[] = {
        !          1427: PCI_ROM(0x1106, 0x3065, "dlink-530tx",     "VIA 6102", 0),
        !          1428: PCI_ROM(0x1106, 0x3106, "via-rhine-6105",  "VIA 6105", 0),
        !          1429: PCI_ROM(0x1106, 0x3043, "dlink-530tx-old", "VIA 3043", 0),             /* Rhine-I 86c100a */
        !          1430: PCI_ROM(0x1106, 0x3053, "via6105m",        "VIA 6105M", 0),
        !          1431: PCI_ROM(0x1106, 0x6100, "via-rhine-old",   "VIA 86C100A", 0),  /* Rhine-II */
        !          1432: };
        !          1433: 
        !          1434: PCI_DRIVER ( rhine_driver, rhine_nics, PCI_NO_CLASS );
        !          1435: 
        !          1436: DRIVER ( "VIA 86C100", nic_driver, pci_driver, rhine_driver,
        !          1437:         rhine_probe, rhine_disable );
        !          1438: 
        !          1439: /* EOF via-rhine.c */
        !          1440: 
        !          1441: /*
        !          1442:  * Local variables:
        !          1443:  *  c-basic-offset: 8
        !          1444:  *  c-indent-level: 8
        !          1445:  *  tab-width: 8
        !          1446:  * End:
        !          1447:  */

unix.superglobalmegacorp.com

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