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

1.1     ! root        1: #ifdef ALLMULTI
        !             2: #error multicast support is not yet implemented
        !             3: #endif
        !             4: /**************************************************************************
        !             5: Etherboot -  BOOTP/TFTP Bootstrap Program
        !             6: Intel EEPRO/10 NIC driver for Etherboot
        !             7: Adapted from Linux eepro.c from kernel 2.2.17
        !             8: 
        !             9: This board accepts a 32 pin EEPROM (29C256), however a test with a
        !            10: 27C010 shows that this EPROM also works in the socket, but it's not clear
        !            11: how repeatably. The two top address pins appear to be held low, thus
        !            12: the bottom 32kB of the 27C010 is visible in the CPU's address space.
        !            13: To be sure you could put 4 copies of the code in the 27C010, then
        !            14: it doesn't matter whether the extra lines are held low or high, just
        !            15: hopefully not floating as CMOS chips don't like floating inputs.
        !            16: 
        !            17: Be careful with seating the EPROM as the socket on my board actually
        !            18: has 34 pins, the top row of 2 are not used.
        !            19: ***************************************************************************/
        !            20: 
        !            21: /*
        !            22: 
        !            23:  timlegge      2005-05-18      remove the relocation changes cards that 
        !            24:                                write directly to the hardware don't need it
        !            25: */
        !            26: 
        !            27: /*
        !            28:  * This program is free software; you can redistribute it and/or
        !            29:  * modify it under the terms of the GNU General Public License as
        !            30:  * published by the Free Software Foundation; either version 2, or (at
        !            31:  * your option) any later version.
        !            32:  */
        !            33: 
        !            34: FILE_LICENCE ( GPL2_OR_LATER );
        !            35: 
        !            36: #include "etherboot.h"
        !            37: #include <errno.h>
        !            38: #include "nic.h"
        !            39: #include <ipxe/isa.h>
        !            40: #include <ipxe/ethernet.h>
        !            41: 
        !            42: /* Different 82595 chips */
        !            43: #define LAN595         0
        !            44: #define LAN595TX       1
        !            45: #define LAN595FX       2
        !            46: #define LAN595FX_10ISA 3
        !            47: 
        !            48: #define        SLOW_DOWN       inb(0x80);
        !            49: 
        !            50: /* The station (ethernet) address prefix, used for IDing the board. */
        !            51: #define SA_ADDR0 0x00  /* Etherexpress Pro/10 */
        !            52: #define SA_ADDR1 0xaa
        !            53: #define SA_ADDR2 0x00
        !            54: 
        !            55: #define GetBit(x,y) ((x & (1<<y))>>y)
        !            56: 
        !            57: /* EEPROM Word 0: */
        !            58: #define ee_PnP       0  /* Plug 'n Play enable bit */
        !            59: #define ee_Word1     1  /* Word 1? */
        !            60: #define ee_BusWidth  2  /* 8/16 bit */
        !            61: #define ee_FlashAddr 3  /* Flash Address */
        !            62: #define ee_FlashMask 0x7   /* Mask */
        !            63: #define ee_AutoIO    6  /* */
        !            64: #define ee_reserved0 7  /* =0! */
        !            65: #define ee_Flash     8  /* Flash there? */
        !            66: #define ee_AutoNeg   9  /* Auto Negotiation enabled? */
        !            67: #define ee_IO0       10 /* IO Address LSB */
        !            68: #define ee_IO0Mask   0x /*...*/
        !            69: #define ee_IO1       15 /* IO MSB */
        !            70: 
        !            71: /* EEPROM Word 1: */
        !            72: #define ee_IntSel    0   /* Interrupt */
        !            73: #define ee_IntMask   0x7
        !            74: #define ee_LI        3   /* Link Integrity 0= enabled */
        !            75: #define ee_PC        4   /* Polarity Correction 0= enabled */
        !            76: #define ee_TPE_AUI   5   /* PortSelection 1=TPE */
        !            77: #define ee_Jabber    6   /* Jabber prevention 0= enabled */
        !            78: #define ee_AutoPort  7   /* Auto Port Selection 1= Disabled */
        !            79: #define ee_SMOUT     8   /* SMout Pin Control 0= Input */
        !            80: #define ee_PROM      9   /* Flash EPROM / PROM 0=Flash */
        !            81: #define ee_reserved1 10  /* .. 12 =0! */
        !            82: #define ee_AltReady  13  /* Alternate Ready, 0=normal */
        !            83: #define ee_reserved2 14  /* =0! */
        !            84: #define ee_Duplex    15
        !            85: 
        !            86: /* Word2,3,4: */
        !            87: #define ee_IA5       0 /*bit start for individual Addr Byte 5 */
        !            88: #define ee_IA4       8 /*bit start for individual Addr Byte 5 */
        !            89: #define ee_IA3       0 /*bit start for individual Addr Byte 5 */
        !            90: #define ee_IA2       8 /*bit start for individual Addr Byte 5 */
        !            91: #define ee_IA1       0 /*bit start for individual Addr Byte 5 */
        !            92: #define ee_IA0       8 /*bit start for individual Addr Byte 5 */
        !            93: 
        !            94: /* Word 5: */
        !            95: #define ee_BNC_TPE   0 /* 0=TPE */
        !            96: #define ee_BootType  1 /* 00=None, 01=IPX, 10=ODI, 11=NDIS */
        !            97: #define ee_BootTypeMask 0x3 
        !            98: #define ee_NumConn   3  /* Number of Connections 0= One or Two */
        !            99: #define ee_FlashSock 4  /* Presence of Flash Socket 0= Present */
        !           100: #define ee_PortTPE   5
        !           101: #define ee_PortBNC   6
        !           102: #define ee_PortAUI   7
        !           103: #define ee_PowerMgt  10 /* 0= disabled */
        !           104: #define ee_CP        13 /* Concurrent Processing */
        !           105: #define ee_CPMask    0x7
        !           106: 
        !           107: /* Word 6: */
        !           108: #define ee_Stepping  0 /* Stepping info */
        !           109: #define ee_StepMask  0x0F
        !           110: #define ee_BoardID   4 /* Manucaturer Board ID, reserved */
        !           111: #define ee_BoardMask 0x0FFF
        !           112: 
        !           113: /* Word 7: */
        !           114: #define ee_INT_TO_IRQ 0 /* int to IRQ Mapping  = 0x1EB8 for Pro/10+ */
        !           115: #define ee_FX_INT2IRQ 0x1EB8 /* the _only_ mapping allowed for FX chips */
        !           116: 
        !           117: /*..*/
        !           118: #define ee_SIZE 0x40 /* total EEprom Size */
        !           119: #define ee_Checksum 0xBABA /* initial and final value for adding checksum */
        !           120: 
        !           121: 
        !           122: /* Card identification via EEprom:   */
        !           123: #define ee_addr_vendor 0x10  /* Word offset for EISA Vendor ID */
        !           124: #define ee_addr_id 0x11      /* Word offset for Card ID */
        !           125: #define ee_addr_SN 0x12      /* Serial Number */
        !           126: #define ee_addr_CRC_8 0x14   /* CRC over last thee Bytes */
        !           127: 
        !           128: 
        !           129: #define ee_vendor_intel0 0x25  /* Vendor ID Intel */
        !           130: #define ee_vendor_intel1 0xD4
        !           131: #define ee_id_eepro10p0 0x10   /* ID for eepro/10+ */
        !           132: #define ee_id_eepro10p1 0x31
        !           133: 
        !           134: /* now this section could be used by both boards: the oldies and the ee10:
        !           135:  * ee10 uses tx buffer before of rx buffer and the oldies the inverse.
        !           136:  * (aris)
        !           137:  */
        !           138: #define        RAM_SIZE        0x8000
        !           139: 
        !           140: #define        RCV_HEADER      8
        !           141: #define RCV_DEFAULT_RAM        0x6000
        !           142: #define RCV_RAM        rcv_ram
        !           143: 
        !           144: static unsigned rcv_ram = RCV_DEFAULT_RAM;
        !           145: 
        !           146: #define XMT_HEADER     8
        !           147: #define XMT_RAM                (RAM_SIZE - RCV_RAM)
        !           148: 
        !           149: #define XMT_START      ((rcv_start + RCV_RAM) % RAM_SIZE)
        !           150: 
        !           151: #define RCV_LOWER_LIMIT        (rcv_start >> 8)
        !           152: #define RCV_UPPER_LIMIT        (((rcv_start + RCV_RAM) - 2) >> 8)
        !           153: #define XMT_LOWER_LIMIT        (XMT_START >> 8)
        !           154: #define XMT_UPPER_LIMIT        (((XMT_START + XMT_RAM) - 2) >> 8)
        !           155: 
        !           156: #define RCV_START_PRO  0x00
        !           157: #define RCV_START_10   XMT_RAM
        !           158:                                        /* by default the old driver */
        !           159: static unsigned rcv_start = RCV_START_PRO;
        !           160: 
        !           161: #define        RCV_DONE        0x0008
        !           162: #define        RX_OK           0x2000
        !           163: #define        RX_ERROR        0x0d81
        !           164: 
        !           165: #define        TX_DONE_BIT     0x0080
        !           166: #define        CHAIN_BIT       0x8000
        !           167: #define        XMT_STATUS      0x02
        !           168: #define        XMT_CHAIN       0x04
        !           169: #define        XMT_COUNT       0x06
        !           170: 
        !           171: #define        BANK0_SELECT    0x00            
        !           172: #define        BANK1_SELECT    0x40            
        !           173: #define        BANK2_SELECT    0x80            
        !           174: 
        !           175: /* Bank 0 registers */
        !           176: #define        COMMAND_REG     0x00    /* Register 0 */
        !           177: #define        MC_SETUP        0x03
        !           178: #define        XMT_CMD         0x04
        !           179: #define        DIAGNOSE_CMD    0x07
        !           180: #define        RCV_ENABLE_CMD  0x08
        !           181: #define        RCV_DISABLE_CMD 0x0a
        !           182: #define        STOP_RCV_CMD    0x0b
        !           183: #define        RESET_CMD       0x0e
        !           184: #define        POWER_DOWN_CMD  0x18
        !           185: #define        RESUME_XMT_CMD  0x1c
        !           186: #define        SEL_RESET_CMD   0x1e
        !           187: #define        STATUS_REG      0x01    /* Register 1 */
        !           188: #define        RX_INT          0x02
        !           189: #define        TX_INT          0x04
        !           190: #define        EXEC_STATUS     0x30
        !           191: #define        ID_REG          0x02    /* Register 2   */
        !           192: #define        R_ROBIN_BITS    0xc0    /* round robin counter */
        !           193: #define        ID_REG_MASK     0x2c
        !           194: #define        ID_REG_SIG      0x24
        !           195: #define        AUTO_ENABLE     0x10
        !           196: #define        INT_MASK_REG    0x03    /* Register 3   */
        !           197: #define        RX_STOP_MASK    0x01
        !           198: #define        RX_MASK         0x02
        !           199: #define        TX_MASK         0x04
        !           200: #define        EXEC_MASK       0x08
        !           201: #define        ALL_MASK        0x0f
        !           202: #define        IO_32_BIT       0x10
        !           203: #define        RCV_BAR         0x04    /* The following are word (16-bit) registers */
        !           204: #define        RCV_STOP        0x06
        !           205: 
        !           206: #define        XMT_BAR_PRO     0x0a
        !           207: #define        XMT_BAR_10      0x0b
        !           208: static unsigned xmt_bar = XMT_BAR_PRO;
        !           209: 
        !           210: #define        HOST_ADDRESS_REG        0x0c
        !           211: #define        IO_PORT         0x0e
        !           212: #define        IO_PORT_32_BIT  0x0c
        !           213: 
        !           214: /* Bank 1 registers */
        !           215: #define        REG1    0x01
        !           216: #define        WORD_WIDTH      0x02
        !           217: #define        INT_ENABLE      0x80
        !           218: #define INT_NO_REG     0x02
        !           219: #define        RCV_LOWER_LIMIT_REG     0x08
        !           220: #define        RCV_UPPER_LIMIT_REG     0x09
        !           221: 
        !           222: #define        XMT_LOWER_LIMIT_REG_PRO 0x0a
        !           223: #define        XMT_UPPER_LIMIT_REG_PRO 0x0b
        !           224: #define        XMT_LOWER_LIMIT_REG_10  0x0b
        !           225: #define        XMT_UPPER_LIMIT_REG_10  0x0a
        !           226: static unsigned xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
        !           227: static unsigned xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
        !           228: 
        !           229: /* Bank 2 registers */
        !           230: #define        XMT_Chain_Int   0x20    /* Interrupt at the end of the transmit chain */
        !           231: #define        XMT_Chain_ErrStop       0x40 /* Interrupt at the end of the chain even if there are errors */
        !           232: #define        RCV_Discard_BadFrame    0x80 /* Throw bad frames away, and continue to receive others */
        !           233: #define        REG2            0x02
        !           234: #define        PRMSC_Mode      0x01
        !           235: #define        Multi_IA        0x20
        !           236: #define        REG3            0x03
        !           237: #define        TPE_BIT         0x04
        !           238: #define        BNC_BIT         0x20
        !           239: #define        REG13           0x0d
        !           240: #define        FDX             0x00
        !           241: #define        A_N_ENABLE      0x02
        !           242:        
        !           243: #define        I_ADD_REG0      0x04
        !           244: #define        I_ADD_REG1      0x05
        !           245: #define        I_ADD_REG2      0x06
        !           246: #define        I_ADD_REG3      0x07
        !           247: #define        I_ADD_REG4      0x08
        !           248: #define        I_ADD_REG5      0x09
        !           249: 
        !           250: #define EEPROM_REG_PRO 0x0a
        !           251: #define EEPROM_REG_10  0x0b
        !           252: static unsigned eeprom_reg = EEPROM_REG_PRO;
        !           253: 
        !           254: #define EESK 0x01
        !           255: #define EECS 0x02
        !           256: #define EEDI 0x04
        !           257: #define EEDO 0x08
        !           258: 
        !           259: /* The horrible routine to read a word from the serial EEPROM. */
        !           260: /* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */
        !           261: 
        !           262: /* The delay between EEPROM clock transitions. */
        !           263: #define eeprom_delay() { udelay(40); }
        !           264: #define EE_READ_CMD (6 << 6)
        !           265: 
        !           266: /* do a full reset; data sheet asks for 250us delay */
        !           267: #define eepro_full_reset(ioaddr)       outb(RESET_CMD, ioaddr); udelay(255);
        !           268: 
        !           269: /* do a nice reset */
        !           270: #define eepro_sel_reset(ioaddr) \
        !           271:   do {  \
        !           272:     outb ( SEL_RESET_CMD, ioaddr ); \
        !           273:     (void) SLOW_DOWN; \
        !           274:     (void) SLOW_DOWN; \
        !           275:   } while (0)
        !           276: 
        !           277: /* clear all interrupts */
        !           278: #define        eepro_clear_int(ioaddr) outb(ALL_MASK, ioaddr + STATUS_REG)
        !           279: 
        !           280: /* enable rx */
        !           281: #define        eepro_en_rx(ioaddr)     outb(RCV_ENABLE_CMD, ioaddr)
        !           282: 
        !           283: /* disable rx */
        !           284: #define        eepro_dis_rx(ioaddr)    outb(RCV_DISABLE_CMD, ioaddr)
        !           285: 
        !           286: /* switch bank */
        !           287: #define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr)
        !           288: #define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr)
        !           289: #define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr)
        !           290: 
        !           291: static unsigned int    rx_start, tx_start;
        !           292: static int             tx_last;
        !           293: static unsigned        int     tx_end;
        !           294: static int             eepro = 0;
        !           295: static unsigned int    mem_start, mem_end = RCV_DEFAULT_RAM / 1024;
        !           296: 
        !           297: /**************************************************************************
        !           298: RESET - Reset adapter
        !           299: ***************************************************************************/
        !           300: static void eepro_reset(struct nic *nic)
        !           301: {
        !           302:        int             temp_reg, i;
        !           303: 
        !           304:        /* put the card in its initial state */
        !           305:        eepro_sw2bank2(nic->ioaddr);    /* be careful, bank2 now */
        !           306:        temp_reg = inb(nic->ioaddr + eeprom_reg);
        !           307:        DBG("Stepping %d\n", temp_reg >> 5);
        !           308:        if (temp_reg & 0x10)    /* check the TurnOff Enable bit */
        !           309:                outb(temp_reg & 0xEF, nic->ioaddr + eeprom_reg);
        !           310:        for (i = 0; i < ETH_ALEN; i++)  /* fill the MAC address */
        !           311:                outb(nic->node_addr[i], nic->ioaddr + I_ADD_REG0 + i);
        !           312:        temp_reg = inb(nic->ioaddr + REG1);
        !           313:        /* setup Transmit Chaining and discard bad RCV frames */
        !           314:        outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop
        !           315:                | RCV_Discard_BadFrame, nic->ioaddr + REG1);
        !           316:        temp_reg = inb(nic->ioaddr + REG2);             /* match broadcast */
        !           317:        outb(temp_reg | 0x14, nic->ioaddr + REG2);
        !           318:        temp_reg = inb(nic->ioaddr + REG3);
        !           319:        outb(temp_reg & 0x3F, nic->ioaddr + REG3);      /* clear test mode */
        !           320:        /* set the receiving mode */
        !           321:        eepro_sw2bank1(nic->ioaddr);    /* be careful, bank1 now */
        !           322:        /* initialise the RCV and XMT upper and lower limits */
        !           323:        outb(RCV_LOWER_LIMIT, nic->ioaddr + RCV_LOWER_LIMIT_REG);
        !           324:        outb(RCV_UPPER_LIMIT, nic->ioaddr + RCV_UPPER_LIMIT_REG);
        !           325:        outb(XMT_LOWER_LIMIT, nic->ioaddr + xmt_lower_limit_reg);
        !           326:        outb(XMT_UPPER_LIMIT, nic->ioaddr + xmt_upper_limit_reg);
        !           327:        eepro_sw2bank0(nic->ioaddr);    /* Switch back to bank 0 */
        !           328:        eepro_clear_int(nic->ioaddr);
        !           329:        /* Initialise RCV */
        !           330:        outw(rx_start = (RCV_LOWER_LIMIT << 8), nic->ioaddr + RCV_BAR);
        !           331:        outw(((RCV_UPPER_LIMIT << 8) | 0xFE), nic->ioaddr + RCV_STOP);
        !           332:        /* Make sure 1st poll won't find a valid packet header */
        !           333:        outw((RCV_LOWER_LIMIT << 8), nic->ioaddr + HOST_ADDRESS_REG);
        !           334:        outw(0,                      nic->ioaddr + IO_PORT);
        !           335:        /* Intialise XMT */
        !           336:        outw((XMT_LOWER_LIMIT << 8), nic->ioaddr + xmt_bar);
        !           337:        eepro_sel_reset(nic->ioaddr);
        !           338:        tx_start = tx_end = (unsigned int) (XMT_LOWER_LIMIT << 8);
        !           339:        tx_last = 0;
        !           340:        eepro_en_rx(nic->ioaddr);
        !           341: }
        !           342: 
        !           343: /**************************************************************************
        !           344: POLL - Wait for a frame
        !           345: ***************************************************************************/
        !           346: static int eepro_poll(struct nic *nic, int retrieve)
        !           347: {
        !           348:        unsigned int    rcv_car = rx_start;
        !           349:        unsigned int    rcv_event, rcv_status, rcv_next_frame, rcv_size;
        !           350: 
        !           351:        /* return true if there's an ethernet packet ready to read */
        !           352:        /* nic->packet should contain data on return */
        !           353:        /* nic->packetlen should contain length of data */
        !           354: #if    0
        !           355:        if ((inb(nic->ioaddr + STATUS_REG) & 0x40) == 0)
        !           356:                return (0);
        !           357:        outb(0x40, nic->ioaddr + STATUS_REG);
        !           358: #endif
        !           359:        outw(rcv_car, nic->ioaddr + HOST_ADDRESS_REG);
        !           360:        rcv_event = inw(nic->ioaddr + IO_PORT);
        !           361:        if (rcv_event != RCV_DONE)
        !           362:                return (0);
        !           363: 
        !           364:        /* FIXME: I'm guessing this might not work with this card, since
        !           365:           it looks like once a rcv_event is started it must be completed.
        !           366:           maybe there's another way. */
        !           367:        if ( ! retrieve ) return 1;
        !           368: 
        !           369:        rcv_status = inw(nic->ioaddr + IO_PORT);
        !           370:        rcv_next_frame = inw(nic->ioaddr + IO_PORT);
        !           371:        rcv_size = inw(nic->ioaddr + IO_PORT);
        !           372: #if    0
        !           373:        printf("%hX %hX %d %hhX\n", rcv_status, rcv_next_frame, rcv_size,
        !           374:                inb(nic->ioaddr + STATUS_REG));
        !           375: #endif
        !           376:        if ((rcv_status & (RX_OK|RX_ERROR)) != RX_OK) {
        !           377:                printf("Receive error %hX\n", rcv_status);
        !           378:                return (0);
        !           379:        }
        !           380:        rcv_size &= 0x3FFF;
        !           381:        insw(nic->ioaddr + IO_PORT, nic->packet, ((rcv_size + 3) >> 1));
        !           382: #if    0
        !           383: {
        !           384:        int i;
        !           385:        for (i = 0; i < 48; i++) {
        !           386:                printf("%hhX", nic->packet[i]);
        !           387:                putchar(i % 16 == 15 ? '\n' : ' ');
        !           388:        }
        !           389: }
        !           390: #endif
        !           391:        nic->packetlen = rcv_size;
        !           392:        rcv_car  = (rx_start + RCV_HEADER + rcv_size);
        !           393:        rx_start = rcv_next_frame;
        !           394: /* 
        !           395:        hex_dump(rcv_car, nic->packetlen); 
        !           396: */
        !           397: 
        !           398:        if (rcv_car == 0)
        !           399:                rcv_car = ((RCV_UPPER_LIMIT << 8) | 0xff);
        !           400:        outw(rcv_car - 1, nic->ioaddr + RCV_STOP);
        !           401:        return (1);
        !           402: }
        !           403: 
        !           404: /**************************************************************************
        !           405: TRANSMIT - Transmit a frame
        !           406: ***************************************************************************/
        !           407: static void eepro_transmit(
        !           408:        struct nic *nic,
        !           409:        const char *d,                  /* Destination */
        !           410:        unsigned int t,                 /* Type */
        !           411:        unsigned int s,                 /* size */
        !           412:        const char *p)                  /* Packet */
        !           413: {
        !           414:        unsigned int    status, tx_available, last, end, length;
        !           415:        unsigned short  type;
        !           416:        int             boguscount = 20;
        !           417: 
        !           418:        length = s + ETH_HLEN;
        !           419:        if (tx_end > tx_start)
        !           420:                tx_available = XMT_RAM - (tx_end - tx_start);
        !           421:        else if (tx_end < tx_start)
        !           422:                tx_available = tx_start - tx_end;
        !           423:        else
        !           424:                tx_available = XMT_RAM;
        !           425:        assert ( length <= tx_available );
        !           426:        last = tx_end;
        !           427:        end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
        !           428:        if (end >= (XMT_UPPER_LIMIT << 8)) {
        !           429:                last = (XMT_LOWER_LIMIT << 8);
        !           430:                end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
        !           431:        }
        !           432:        outw(last, nic->ioaddr + HOST_ADDRESS_REG);
        !           433:        outw(XMT_CMD, nic->ioaddr + IO_PORT);
        !           434:        outw(0, nic->ioaddr + IO_PORT);
        !           435:        outw(end, nic->ioaddr + IO_PORT);
        !           436:        outw(length, nic->ioaddr + IO_PORT);
        !           437:        outsw(nic->ioaddr + IO_PORT, d, ETH_ALEN / 2);
        !           438:        outsw(nic->ioaddr + IO_PORT, nic->node_addr, ETH_ALEN / 2);
        !           439:        type = htons(t);
        !           440:        outsw(nic->ioaddr + IO_PORT, &type, sizeof(type) / 2);
        !           441:        outsw(nic->ioaddr + IO_PORT, p, (s + 3) >> 1);
        !           442:        /* A dummy read to flush the DRAM write pipeline */
        !           443:        status = inw(nic->ioaddr + IO_PORT);
        !           444:        outw(last, nic->ioaddr + xmt_bar);
        !           445:        outb(XMT_CMD, nic->ioaddr);
        !           446:        tx_start = last;
        !           447:        tx_last = last;
        !           448:        tx_end = end;
        !           449: #if    0
        !           450:        printf("%d %d\n", tx_start, tx_end);
        !           451: #endif
        !           452:        while (boguscount > 0) {
        !           453:                if (((status = inw(nic->ioaddr + IO_PORT)) & TX_DONE_BIT) == 0) {
        !           454:                        udelay(40);
        !           455:                        boguscount--;
        !           456:                        continue;
        !           457:                }
        !           458:                if ((status & 0x2000) == 0) {
        !           459:                        DBG("Transmit status %hX\n", status);
        !           460:                }
        !           461:        }
        !           462: }
        !           463: 
        !           464: /**************************************************************************
        !           465: DISABLE - Turn off ethernet interface
        !           466: ***************************************************************************/
        !           467: static void eepro_disable ( struct nic *nic, struct isa_device *isa __unused ) {
        !           468:        eepro_sw2bank0(nic->ioaddr);    /* Switch to bank 0 */
        !           469:        /* Flush the Tx and disable Rx */
        !           470:        outb(STOP_RCV_CMD, nic->ioaddr);
        !           471:        tx_start = tx_end = (XMT_LOWER_LIMIT << 8);
        !           472:        tx_last = 0;
        !           473:        /* Reset the 82595 */
        !           474:        eepro_full_reset(nic->ioaddr);
        !           475: }
        !           476: 
        !           477: /**************************************************************************
        !           478: DISABLE - Enable, Disable, or Force interrupts
        !           479: ***************************************************************************/
        !           480: static void eepro_irq(struct nic *nic __unused, irq_action_t action __unused)
        !           481: {
        !           482:   switch ( action ) {
        !           483:   case DISABLE :
        !           484:     break;
        !           485:   case ENABLE :
        !           486:     break;
        !           487:   case FORCE :
        !           488:     break;
        !           489:   }
        !           490: }
        !           491: 
        !           492: static int read_eeprom(uint16_t ioaddr, int location)
        !           493: {
        !           494:        int             i;
        !           495:        unsigned short  retval = 0;
        !           496:        int             ee_addr = ioaddr + eeprom_reg;
        !           497:        int             read_cmd = location | EE_READ_CMD;
        !           498:        int             ctrl_val = EECS;
        !           499: 
        !           500:        if (eepro == LAN595FX_10ISA) {
        !           501:                eepro_sw2bank1(ioaddr);
        !           502:                outb(0x00, ioaddr + STATUS_REG);
        !           503:        }
        !           504:        eepro_sw2bank2(ioaddr);
        !           505:        outb(ctrl_val, ee_addr);
        !           506:        /* shift the read command bits out */
        !           507:        for (i = 8; i >= 0; i--) {
        !           508:                short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val;
        !           509:                outb(outval, ee_addr);
        !           510:                outb(outval | EESK, ee_addr);   /* EEPROM clock tick */
        !           511:                eeprom_delay();
        !           512:                outb(outval, ee_addr);          /* finish EEPROM clock tick */
        !           513:                eeprom_delay();
        !           514:        }
        !           515:        outb(ctrl_val, ee_addr);
        !           516:        for (i = 16; i > 0; i--) {
        !           517:                outb(ctrl_val | EESK, ee_addr);
        !           518:                eeprom_delay();
        !           519:                retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
        !           520:                outb(ctrl_val, ee_addr);
        !           521:                eeprom_delay();
        !           522:        }
        !           523:        /* terminate the EEPROM access */
        !           524:        ctrl_val &= ~EECS;
        !           525:        outb(ctrl_val | EESK, ee_addr);
        !           526:        eeprom_delay();
        !           527:        outb(ctrl_val, ee_addr);
        !           528:        eeprom_delay();
        !           529:        eepro_sw2bank0(ioaddr);
        !           530:        return (retval);
        !           531: }
        !           532: 
        !           533: static int eepro_probe1 ( isa_probe_addr_t ioaddr ) {
        !           534:        int             id, counter;
        !           535: 
        !           536:        id = inb(ioaddr + ID_REG);
        !           537:        if ((id & ID_REG_MASK) != ID_REG_SIG)
        !           538:                return (0);
        !           539:        counter = id & R_ROBIN_BITS;
        !           540:        if (((id = inb(ioaddr + ID_REG)) & R_ROBIN_BITS) != (counter + 0x40))
        !           541:                return (0);
        !           542:        /* yes the 82595 has been found */
        !           543:        return (1);
        !           544: }
        !           545: 
        !           546: static struct nic_operations eepro_operations = {
        !           547:        .connect        = dummy_connect,
        !           548:        .poll           = eepro_poll,
        !           549:        .transmit       = eepro_transmit,
        !           550:        .irq            = eepro_irq,
        !           551: 
        !           552: };
        !           553: 
        !           554: /**************************************************************************
        !           555: PROBE - Look for an adapter, this routine's visible to the outside
        !           556: ***************************************************************************/
        !           557: static int eepro_probe ( struct nic *nic, struct isa_device *isa ) {
        !           558: 
        !           559:        int             i, l_eepro = 0;
        !           560:        union {
        !           561:                unsigned char   caddr[ETH_ALEN];
        !           562:                unsigned short  saddr[ETH_ALEN/2];
        !           563:        } station_addr;
        !           564:        const char *name;
        !           565: 
        !           566:        nic->irqno  = 0;
        !           567:        nic->ioaddr = isa->ioaddr;
        !           568: 
        !           569:        station_addr.saddr[2] = read_eeprom(nic->ioaddr,2);
        !           570:        if ( ( station_addr.saddr[2] == 0x0000 ) ||
        !           571:             ( station_addr.saddr[2] == 0xFFFF ) ) {
        !           572:                l_eepro = 3;
        !           573:                eepro = LAN595FX_10ISA;
        !           574:                eeprom_reg= EEPROM_REG_10;
        !           575:                rcv_start = RCV_START_10;
        !           576:                xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
        !           577:                xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
        !           578:                station_addr.saddr[2] = read_eeprom(nic->ioaddr,2);
        !           579:        }
        !           580:        station_addr.saddr[1] = read_eeprom(nic->ioaddr,3);
        !           581:        station_addr.saddr[0] = read_eeprom(nic->ioaddr,4);
        !           582:        if (l_eepro)
        !           583:                name = "Intel EtherExpress 10 ISA";
        !           584:        else if (read_eeprom(nic->ioaddr,7) == ee_FX_INT2IRQ) {
        !           585:                name = "Intel EtherExpress Pro/10+ ISA";
        !           586:                l_eepro = 2;
        !           587:        } else if (station_addr.saddr[0] == SA_ADDR1) {
        !           588:                name = "Intel EtherExpress Pro/10 ISA";
        !           589:                l_eepro = 1;
        !           590:        } else {
        !           591:                l_eepro = 0;
        !           592:                name = "Intel 82595-based LAN card";
        !           593:        }
        !           594:        station_addr.saddr[0] = swap16(station_addr.saddr[0]);
        !           595:        station_addr.saddr[1] = swap16(station_addr.saddr[1]);
        !           596:        station_addr.saddr[2] = swap16(station_addr.saddr[2]);
        !           597:        for (i = 0; i < ETH_ALEN; i++) {
        !           598:                nic->node_addr[i] = station_addr.caddr[i];
        !           599:        }
        !           600: 
        !           601:        DBG ( "%s ioaddr %#hX, addr %s", name, nic->ioaddr, eth_ntoa ( nic->node_addr ) );
        !           602: 
        !           603:        mem_start = RCV_LOWER_LIMIT << 8;
        !           604:        if ((mem_end & 0x3F) < 3 || (mem_end & 0x3F) > 29)
        !           605:                mem_end = RCV_UPPER_LIMIT << 8;
        !           606:        else {
        !           607:                mem_end = mem_end * 1024 + (RCV_LOWER_LIMIT << 8);
        !           608:                rcv_ram = mem_end - (RCV_LOWER_LIMIT << 8);
        !           609:        }
        !           610:        printf(", Rx mem %dK, if %s\n", (mem_end - mem_start) >> 10,
        !           611:                GetBit(read_eeprom(nic->ioaddr,5), ee_BNC_TPE) ? "BNC" : "TP");
        !           612: 
        !           613:        eepro_reset(nic);
        !           614: 
        !           615:        /* point to NIC specific routines */
        !           616:        nic->nic_op     = &eepro_operations;
        !           617:        return 1;
        !           618: }
        !           619: 
        !           620: static isa_probe_addr_t eepro_probe_addrs[] = {
        !           621:        0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360,
        !           622: };
        !           623: 
        !           624: ISA_DRIVER ( eepro_driver, eepro_probe_addrs, eepro_probe1,
        !           625:                     GENERIC_ISAPNP_VENDOR, 0x828a );
        !           626: 
        !           627: DRIVER ( "eepro", nic_driver, isa_driver, eepro_driver,
        !           628:         eepro_probe, eepro_disable );
        !           629: 
        !           630: ISA_ROM ( "eepro", "Intel Etherexpress Pro/10" );
        !           631: 
        !           632: /*
        !           633:  * Local variables:
        !           634:  *  c-basic-offset: 8
        !           635:  *  c-indent-level: 8
        !           636:  *  tab-width: 8
        !           637:  * End:
        !           638:  */

unix.superglobalmegacorp.com

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