iPXE
Functions | Variables
cs89x0.c File Reference
#include <errno.h>
#include <ipxe/ethernet.h>
#include "etherboot.h"
#include "nic.h"
#include <ipxe/isa.h>
#include "cs89x0.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_ONLY)
 Per an email message from Russ Nelson <nelson@crynwr.com> on 18 March 2008 this file is now licensed under GPL Version 2.
static int readreg (int portno)
static void writereg (int portno, int value)
static int wait_eeprom_ready (void)
static int get_eeprom_data (int off, int len, unsigned short *buffer)
static int get_eeprom_chksum (int off __unused, int len, unsigned short *buffer)
static void clrline (void)
static void control_dc_dc (int on_not_off)
static int detect_tp (void)
static int send_test_pkt (struct nic *nic)
static int detect_aui (struct nic *nic)
static int detect_bnc (struct nic *nic)
static void cs89x0_reset (struct nic *nic)
static void cs89x0_transmit (struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
static int cs89x0_poll (struct nic *nic, int retrieve)
static void cs89x0_irq (struct nic *nic __unused, irq_action_t action __unused)
static int cs89x0_probe_addr (isa_probe_addr_t ioaddr)
static int cs89x0_probe (struct nic *nic, struct isa_device *isa __unused)
static void cs89x0_disable (struct nic *nic, struct isa_device *isa __unused)
 ISA_DRIVER (cs89x0_driver, cs89x0_probe_addrs, cs89x0_probe_addr, ISAPNP_VENDOR('C','S','C'), 0x0007)
 DRIVER ("cs89x0", nic_driver, isa_driver, cs89x0_driver, cs89x0_probe, cs89x0_disable)
 ISA_ROM ("cs89x0","Crystal Semiconductor CS89x0")

Variables

static unsigned short eth_nic_base
static unsigned long eth_mem_start
static unsigned short eth_irqno
static unsigned short eth_cs_type
static unsigned short eth_auto_neg_cnf
static unsigned short eth_adapter_cnf
static unsigned short eth_linectl
static struct nic_operations cs89x0_operations
static isa_probe_addr_t cs89x0_probe_addrs []

Function Documentation

FILE_LICENCE ( GPL2_ONLY  )

Per an email message from Russ Nelson <nelson@crynwr.com> on 18 March 2008 this file is now licensed under GPL Version 2.

From: Russ Nelson <nelson@crynwr.com> Date: Tue, 18 Mar 2008 12:42:00 -0400 Subject: Re: [Etherboot-developers] cs89x0 driver in etherboot -- quote from email As copyright holder, if I say it doesn't conflict with the GPL, then it doesn't conflict with the GPL.

However, there's no point in causing people's brains to overheat, so yes, I grant permission for the code to be relicensed under the GPLv2. Please make sure that this change in licensing makes its way upstream. -russ -- quote from email

static int readreg ( int  portno) [inline, static]
static void writereg ( int  portno,
int  value 
) [inline, static]
static int wait_eeprom_ready ( void  ) [static]

Definition at line 126 of file cs89x0.c.

References currticks(), PP_SelfST, readreg(), SI_BUSY, and TICKS_PER_SEC.

Referenced by get_eeprom_data().

{
        unsigned long tmo = currticks() + 4*TICKS_PER_SEC;

        /* check to see if the EEPROM is ready, a timeout is used -
           just in case EEPROM is ready when SI_BUSY in the
           PP_SelfST is clear */
        while(readreg(PP_SelfST) & SI_BUSY) {
                if (currticks() >= tmo)
                        return -1; }
        return 0;
}
static int get_eeprom_data ( int  off,
int  len,
unsigned short *  buffer 
) [static]

Definition at line 139 of file cs89x0.c.

References EEPROM_READ_CMD, len, PP_EECMD, PP_EEData, printf(), putchar(), readreg(), wait_eeprom_ready(), and writereg().

Referenced by cs89x0_probe().

{
        int i;

#ifdef  EDEBUG
        printf("\ncs: EEPROM data from %hX for %hX:",off,len);
#endif
        for (i = 0; i < len; i++) {
                if (wait_eeprom_ready() < 0)
                        return -1;
                /* Now send the EEPROM read command and EEPROM location
                   to read */
                writereg(PP_EECMD, (off + i) | EEPROM_READ_CMD);
                if (wait_eeprom_ready() < 0)
                        return -1;
                buffer[i] = readreg(PP_EEData);
#ifdef  EDEBUG
                if (!(i%10))
                        printf("\ncs: ");
                printf("%hX ", buffer[i]);
#endif
        }
#ifdef  EDEBUG
        putchar('\n');
#endif

        return(0);
}
static int get_eeprom_chksum ( int off  __unused,
int  len,
unsigned short *  buffer 
) [static]

Definition at line 168 of file cs89x0.c.

References len.

Referenced by cs89x0_probe().

{
        int  i, cksum;

        cksum = 0;
        for (i = 0; i < len; i++)
                cksum += buffer[i];
        cksum &= 0xffff;
        if (cksum == 0)
                return 0;
        return -1;
}
static void clrline ( void  ) [static]

Definition at line 185 of file cs89x0.c.

References printf(), and putchar().

Referenced by cs89x0_probe(), detect_aui(), detect_bnc(), and detect_tp().

{
        int i;

        putchar('\r');
        for (i = 79; i--; ) putchar(' ');
        printf("\rcs: ");
        return;
}
static void control_dc_dc ( int  on_not_off) [static]

Definition at line 195 of file cs89x0.c.

References A_CNF_DC_DC_POLARITY, currticks(), eth_adapter_cnf, HCB1, HCB1_ENBL, PP_SelfCTL, TICKS_PER_SEC, and writereg().

Referenced by detect_aui(), detect_bnc(), and detect_tp().

{
        unsigned int selfcontrol;
        unsigned long tmo = currticks() + TICKS_PER_SEC;

        /* control the DC to DC convertor in the SelfControl register.  */
        selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */
        if (((eth_adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)
                selfcontrol |= HCB1;
        else
                selfcontrol &= ~HCB1;
        writereg(PP_SelfCTL, selfcontrol);

        /* Wait for the DC/DC converter to power up - 1000ms */
        while (currticks() < tmo);

        return;
}
static int detect_tp ( void  ) [static]

Definition at line 214 of file cs89x0.c.

References A_CNF_MEDIA_10B_T, AUI_ONLY, AUTO_NEG_BITS, AUTO_NEG_BUSY, AUTO_NEG_ENABLE, AUTO_NEG_MASK, clrline(), control_dc_dc(), CS8900, currticks(), eth_auto_neg_cnf, eth_cs_type, eth_linectl, FDX_ACTIVE, LINK_OK, PP_AutoNegCTL, PP_AutoNegST, PP_LineCTL, PP_LineST, printf(), readreg(), TICKS_PER_SEC, and writereg().

Referenced by cs89x0_probe().

{
        unsigned long tmo;

        /* Turn on the chip auto detection of 10BT/ AUI */

        clrline(); printf("attempting %s:","TP");

        /* If connected to another full duplex capable 10-Base-T card
           the link pulses seem to be lost when the auto detect bit in
           the LineCTL is set.  To overcome this the auto detect bit
           will be cleared whilst testing the 10-Base-T interface.
           This would not be necessary for the sparrow chip but is
           simpler to do it anyway. */
        writereg(PP_LineCTL, eth_linectl &~ AUI_ONLY);
        control_dc_dc(0);

        /* Delay for the hardware to work out if the TP cable is
           present - 150ms */
        for (tmo = currticks() + 4; currticks() < tmo; );

        if ((readreg(PP_LineST) & LINK_OK) == 0)
                return 0;

        if (eth_cs_type != CS8900) {

                writereg(PP_AutoNegCTL, eth_auto_neg_cnf & AUTO_NEG_MASK);

                if ((eth_auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {
                        printf(" negotiating duplex... ");
                        while (readreg(PP_AutoNegST) & AUTO_NEG_BUSY) {
                                if (currticks() - tmo > 40*TICKS_PER_SEC) {
                                        printf("time out ");
                                        break;
                                }
                        }
                }
                if (readreg(PP_AutoNegST) & FDX_ACTIVE)
                        printf("using full duplex");
                else
                        printf("using half duplex");
        }

        return A_CNF_MEDIA_10B_T;
}
static int send_test_pkt ( struct nic nic) [static]

Definition at line 261 of file cs89x0.c.

References currticks(), ETH_ALEN, eth_nic_base, ETH_ZLEN, memcpy(), outsw(), outw(), PP_BusST, PP_LineCTL, PP_TxEvent, printf(), readreg(), READY_FOR_TX_NOW, SERIAL_TX_ON, TX_AFTER_ALL, TX_CMD_PORT, TX_FRAME_PORT, TX_LEN_PORT, TX_OK, TX_SEND_OK_BITS, and writereg().

Referenced by detect_aui(), and detect_bnc().

{
        static unsigned char testpacket[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
                                     0, 46, /*A 46 in network order       */
                                     0, 0,  /*DSAP=0 & SSAP=0 fields      */
                                     0xf3,0 /*Control (Test Req+P bit set)*/ };
        unsigned long tmo;

        writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_TX_ON);

        memcpy(testpacket, nic->node_addr, ETH_ALEN);
        memcpy(testpacket+ETH_ALEN, nic->node_addr, ETH_ALEN);

        outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
        outw(ETH_ZLEN, eth_nic_base + TX_LEN_PORT);

        /* Test to see if the chip has allocated memory for the packet */
        for (tmo = currticks() + 2;
             (readreg(PP_BusST) & READY_FOR_TX_NOW) == 0; )
                if (currticks() >= tmo)
                        return(0);

        /* Write the contents of the packet */
        outsw(eth_nic_base + TX_FRAME_PORT, testpacket,
              (ETH_ZLEN+1)>>1);

        printf(" sending test packet ");
        /* wait a couple of timer ticks for packet to be received */
        for (tmo = currticks() + 2; currticks() < tmo; );

        if ((readreg(PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
                        printf("succeeded");
                        return 1;
        }
        printf("failed");
        return 0;
}
static int detect_aui ( struct nic nic) [static]

Definition at line 300 of file cs89x0.c.

References A_CNF_MEDIA_AUI, AUI_ONLY, AUTO_AUI_10BASET, clrline(), control_dc_dc(), eth_linectl, PP_LineCTL, printf(), send_test_pkt(), and writereg().

Referenced by cs89x0_probe().

{
        clrline(); printf("attempting %s:","AUI");
        control_dc_dc(0);

        writereg(PP_LineCTL, (eth_linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);

        if (send_test_pkt(nic)) {
                return A_CNF_MEDIA_AUI; }
        else
                return 0;
}
static int detect_bnc ( struct nic nic) [static]

Definition at line 313 of file cs89x0.c.

References A_CNF_MEDIA_10B_2, AUI_ONLY, AUTO_AUI_10BASET, clrline(), control_dc_dc(), eth_linectl, PP_LineCTL, printf(), send_test_pkt(), and writereg().

Referenced by cs89x0_probe().

{
        clrline(); printf("attempting %s:","BNC");
        control_dc_dc(1);

        writereg(PP_LineCTL, (eth_linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);

        if (send_test_pkt(nic)) {
                return A_CNF_MEDIA_10B_2; }
        else
                return 0;
}
static void cs89x0_reset ( struct nic nic) [static]

Definition at line 330 of file cs89x0.c.

References ADD_PORT, CS8900, currticks(), DATA_PORT, DEF_RX_ACCEPT, ETH_ALEN, eth_cs_type, eth_irqno, eth_mem_start, eth_nic_base, INIT_DONE, outb(), outw(), POWER_ON_RESET, PP_BufCFG, PP_BusCTL, PP_ChipID, PP_CS8920_ISAINT, PP_CS8920_ISAMemB, PP_IA, PP_RxCFG, PP_RxCTL, PP_SelfCTL, PP_SelfST, PP_TxCFG, readreg(), and writereg().

Referenced by cs89x0_disable(), cs89x0_probe(), and cs89x0_transmit().

{
        int  i;
        unsigned long reset_tmo;

        writereg(PP_SelfCTL, readreg(PP_SelfCTL) | POWER_ON_RESET);

        /* wait for two ticks; that is 2*55ms */
        for (reset_tmo = currticks() + 2; currticks() < reset_tmo; );

        if (eth_cs_type != CS8900) {
                /* Hardware problem requires PNP registers to be reconfigured
                   after a reset */
                if (eth_irqno != 0xFFFF) {
                        outw(PP_CS8920_ISAINT, eth_nic_base + ADD_PORT);
                        outb(eth_irqno, eth_nic_base + DATA_PORT);
                        outb(0, eth_nic_base + DATA_PORT + 1); }

                if (eth_mem_start) {
                        outw(PP_CS8920_ISAMemB, eth_nic_base + ADD_PORT);
                        outb((eth_mem_start >> 8) & 0xff, eth_nic_base + DATA_PORT);
                        outb((eth_mem_start >> 24) & 0xff, eth_nic_base + DATA_PORT + 1); } }

        /* Wait until the chip is reset */
        for (reset_tmo = currticks() + 2;
             (readreg(PP_SelfST) & INIT_DONE) == 0 &&
                     currticks() < reset_tmo; );

        /* disable interrupts and memory accesses */
        writereg(PP_BusCTL, 0);

        /* set the ethernet address */
        for (i=0; i < ETH_ALEN/2; i++)
                writereg(PP_IA+i*2,
                         nic->node_addr[i*2] |
                         (nic->node_addr[i*2+1] << 8));

        /* receive only error free packets addressed to this card */
        writereg(PP_RxCTL, DEF_RX_ACCEPT);

        /* do not generate any interrupts on receive operations */
        writereg(PP_RxCFG, 0);

        /* do not generate any interrupts on transmit operations */
        writereg(PP_TxCFG, 0);

        /* do not generate any interrupts on buffer operations */
        writereg(PP_BufCFG, 0);

        /* reset address port, so that autoprobing will keep working */
        outw(PP_ChipID, eth_nic_base + ADD_PORT);

        return;
}
static void cs89x0_transmit ( struct nic nic,
const char *  d,
unsigned int  t,
unsigned int  s,
const char *  p 
) [static]

Definition at line 389 of file cs89x0.c.

References cs89x0_reset(), currticks(), ETH_ALEN, ETH_HLEN, eth_nic_base, ETH_ZLEN, outsw(), outw(), PP_BusST, PP_TxEvent, printf(), readreg(), READY_FOR_TX_NOW, TICKS_PER_SEC, TX_AFTER_ALL, TX_CMD_PORT, TX_FRAME_PORT, TX_LEN_PORT, TX_OK, and TX_SEND_OK_BITS.

{
        unsigned long tmo;
        int           sr;

        /* does this size have to be rounded??? please,
           somebody have a look in the specs */
        if ((sr = ((s + ETH_HLEN + 1)&~1)) < ETH_ZLEN)
                sr = ETH_ZLEN;

retry:
        /* initiate a transmit sequence */
        outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
        outw(sr, eth_nic_base + TX_LEN_PORT);

        /* Test to see if the chip has allocated memory for the packet */
        if ((readreg(PP_BusST) & READY_FOR_TX_NOW) == 0) {
                /* Oops... this should not happen! */
                printf("cs: unable to send packet; retrying...\n");
                for (tmo = currticks() + 5*TICKS_PER_SEC; currticks() < tmo; );
                cs89x0_reset(nic);
                goto retry; }

        /* Write the contents of the packet */
        outsw(eth_nic_base + TX_FRAME_PORT, d, ETH_ALEN/2);
        outsw(eth_nic_base + TX_FRAME_PORT, nic->node_addr,
              ETH_ALEN/2);
        outw(((t >> 8)&0xFF)|(t << 8), eth_nic_base + TX_FRAME_PORT);
        outsw(eth_nic_base + TX_FRAME_PORT, p, (s+1)/2);
        for (sr = sr/2 - (s+1)/2 - ETH_ALEN - 1; sr > 0; sr--)
                outw(0, eth_nic_base + TX_FRAME_PORT);

        /* wait for transfer to succeed */
        for (tmo = currticks()+5*TICKS_PER_SEC;
             (s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() < tmo;)
                /* nothing */ ;
        if ((s & TX_SEND_OK_BITS) != TX_OK) {
                printf("\ntransmission error %#hX\n", s);
        }

        return;
}
static int cs89x0_poll ( struct nic nic,
int  retrieve 
) [static]

Definition at line 441 of file cs89x0.c.

References eth_nic_base, insw(), inw(), PP_RxEvent, readreg(), RX_FRAME_PORT, RX_OK, and status.

{
        int status;

        status = readreg(PP_RxEvent);

        if ((status & RX_OK) == 0)
                return(0);

        if ( ! retrieve ) return 1;

        status = inw(eth_nic_base + RX_FRAME_PORT);
        nic->packetlen = inw(eth_nic_base + RX_FRAME_PORT);
        insw(eth_nic_base + RX_FRAME_PORT, nic->packet, nic->packetlen >> 1);
        if (nic->packetlen & 1)
                nic->packet[nic->packetlen-1] = inw(eth_nic_base + RX_FRAME_PORT);
        return 1;
}
static void cs89x0_irq ( struct nic *nic  __unused,
irq_action_t action  __unused 
) [static]

Definition at line 460 of file cs89x0.c.

{
  switch ( action ) {
  case DISABLE :
    break;
  case ENABLE :
    break;
  case FORCE :
    break;
  }
}
static int cs89x0_probe_addr ( isa_probe_addr_t  ioaddr) [static]

Definition at line 483 of file cs89x0.c.

References ADD_MASK, ADD_PORT, ADD_SIG, CHIP_EISA_ID_SIG, DATA_PORT, inw(), outw(), and PP_ChipID.

                                                         {
        /* if they give us an odd I/O address, then do ONE write to
           the address port, to get it back to address zero, where we
           expect to find the EISA signature word. */
        if (ioaddr & 1) {
                ioaddr &= ~1;
                if ((inw(ioaddr + ADD_PORT) & ADD_MASK) != ADD_SIG)
                        return 0;
                outw(PP_ChipID, ioaddr + ADD_PORT);
        }
        
        if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG)
                return 0;

        return 1;
}
static int cs89x0_probe ( struct nic nic,
struct isa_device *isa  __unused 
) [static]

Definition at line 500 of file cs89x0.c.

References A_CNF_10B_2, A_CNF_10B_T, A_CNF_AUI, A_CNF_EXTND_10B_2, A_CNF_LOW_RX_SQUELCH, A_CNF_MEDIA_10B_2, A_CNF_MEDIA_10B_T, A_CNF_MEDIA_AUI, A_CNF_MEDIA_AUTO, A_CNF_MEDIA_TYPE, ADAPTER_CNF_OFFSET, ADD_PORT, AUTO_AUI_10BASET, AUTO_NEG_CNF_OFFSET, CHKSUM_LEN, clrline(), CS8900, CS8920_NO_INTS, CS8920M, cs89x0_operations, cs89x0_reset(), DBG, detect_aui(), detect_bnc(), detect_tp(), EE_AUTO_NEG_ENABLE, EEPROM_PRESENT, error, eth_adapter_cnf, ETH_ALEN, eth_auto_neg_cnf, eth_cs_type, eth_irqno, eth_linectl, eth_mem_start, eth_nic_base, eth_ntoa(), get_eeprom_chksum(), get_eeprom_data(), IMM_BIT, INT_NO_MASK, ISA_CNF_OFFSET, LOW_RX_SQUELCH, memcpy(), outw(), PACKET_PAGE_OFFSET, PP_ChipID, PP_CS8920_ISAINT, PP_LineCTL, PP_SelfST, printf(), PRODUCT_ID_ADD, readreg(), REVISON_BITS, SERIAL_RX_ON, SERIAL_TX_ON, START_EEPROM_DATA, and writereg().

                                                                             {
        int      i, result = -1;
        unsigned rev_type = 0, isa_cnf, cs_revision;
        unsigned short eeprom_buff[CHKSUM_LEN];

        nic->ioaddr &= ~1; /* LSB = 1 indicates a more aggressive probe */
        eth_nic_base = nic->ioaddr;

        /* get the chip type */
        rev_type = readreg(PRODUCT_ID_ADD);
        eth_cs_type = rev_type &~ REVISON_BITS;
        cs_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
        
        printf("\ncs: cs89%c0%s rev %c, base %#hX",
               eth_cs_type==CS8900?'0':'2',
               eth_cs_type==CS8920M?"M":"",
               cs_revision,
               eth_nic_base);
#ifndef EMBEDDED 
        /* First check to see if an EEPROM is attached*/
        if ((readreg(PP_SelfST) & EEPROM_PRESENT) == 0) {
                printf("\ncs: no EEPROM...\n");
                outw(PP_ChipID, eth_nic_base + ADD_PORT);
                return 0;
        } else if (get_eeprom_data(START_EEPROM_DATA,CHKSUM_LEN,
                                   eeprom_buff) < 0) {
                printf("\ncs: EEPROM read failed...\n");
                outw(PP_ChipID, eth_nic_base + ADD_PORT);
                return 0;
        } else if (get_eeprom_chksum(START_EEPROM_DATA,CHKSUM_LEN,
                                     eeprom_buff) < 0) {
                printf("\ncs: EEPROM checksum bad...\n");
                outw(PP_ChipID, eth_nic_base + ADD_PORT);
                return 0;
        }

        /* get transmission control word but keep the
           autonegotiation bits */
        eth_auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];
        /* Store adapter configuration */
        eth_adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];
        /* Store ISA configuration */
        isa_cnf = eeprom_buff[ISA_CNF_OFFSET/2];
        
        /* store the initial memory base address */
        eth_mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] << 8;
        
        printf("%s%s%s, addr ",
               (eth_adapter_cnf & A_CNF_10B_T)?", RJ-45":"",
               (eth_adapter_cnf & A_CNF_AUI)?", AUI":"",
               (eth_adapter_cnf & A_CNF_10B_2)?", BNC":"");
        
        /* If this is a CS8900 then no pnp soft */
        if (eth_cs_type != CS8900 &&
            /* Check if the ISA IRQ has been set  */
            (i = readreg(PP_CS8920_ISAINT) & 0xff,
             (i != 0 && i < CS8920_NO_INTS)))
                eth_irqno = i;
        else {
                i = isa_cnf & INT_NO_MASK;
                if (eth_cs_type == CS8900) {
                        /* the table that follows is dependent
                           upon how you wired up your cs8900
                           in your system.  The table is the
                           same as the cs8900 engineering demo
                           board.  irq_map also depends on the
                           contents of the table.  Also see
                           write_irq, which is the reverse
                           mapping of the table below. */
                        if (i < 4) i = "\012\013\014\005"[i];
                        else printf("\ncs: BUG: isa_config is %d\n", i); }
                eth_irqno = i; }
        
        nic->irqno = eth_irqno;

        /* Retrieve and print the ethernet address. */
        for (i=0; i<ETH_ALEN; i++) {
                nic->node_addr[i] = ((unsigned char *)eeprom_buff)[i];
        }

        DBG ( "%s\n", eth_ntoa ( nic->node_addr ) );

#endif
#ifdef EMBEDDED
        /* Retrieve and print the ethernet address. */
        {
                unsigned char MAC_HW_ADDR[6]={MAC_HW_ADDR_DRV};
                memcpy(nic->node_addr, MAC_HW_ADDR, 6);
        }

        DBG ( "%s\n", eth_ntoa ( nic->node_addr ) );
        
        eth_adapter_cnf = A_CNF_10B_T | A_CNF_MEDIA_10B_T;
        eth_auto_neg_cnf = EE_AUTO_NEG_ENABLE | IMM_BIT;
#endif
#ifndef EMBEDDED 
        /* Set the LineCTL quintuplet based on adapter
           configuration read from EEPROM */
        if ((eth_adapter_cnf & A_CNF_EXTND_10B_2) &&
            (eth_adapter_cnf & A_CNF_LOW_RX_SQUELCH))
                eth_linectl = LOW_RX_SQUELCH;
        else
                eth_linectl = 0;
        
        /* check to make sure that they have the "right"
           hardware available */
        switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {
        case A_CNF_MEDIA_10B_T: result = eth_adapter_cnf & A_CNF_10B_T;
                break;
        case A_CNF_MEDIA_AUI:   result = eth_adapter_cnf & A_CNF_AUI;
                break;
        case A_CNF_MEDIA_10B_2: result = eth_adapter_cnf & A_CNF_10B_2;
                break;
        default: result = eth_adapter_cnf & (A_CNF_10B_T | A_CNF_AUI |
                                             A_CNF_10B_2);
        }
        if (!result) {
                printf("cs: EEPROM is configured for unavailable media\n");
        error:
                writereg(PP_LineCTL, readreg(PP_LineCTL) &
                         ~(SERIAL_TX_ON | SERIAL_RX_ON));
                outw(PP_ChipID, eth_nic_base + ADD_PORT);
                return 0;
        }
#endif
        /* Initialize the card for probing of the attached media */
        cs89x0_reset(nic);
        
        /* set the hardware to the configured choice */
        switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {
        case A_CNF_MEDIA_10B_T:
                result = detect_tp();
                if (!result) {
                        clrline();
                        printf("10Base-T (RJ-45%s",
                               ") has no cable\n"); }
                /* check "ignore missing media" bit */
                if (eth_auto_neg_cnf & IMM_BIT)
                        /* Yes! I don't care if I see a link pulse */
                        result = A_CNF_MEDIA_10B_T;
                break;
        case A_CNF_MEDIA_AUI:
                result = detect_aui(nic);
                if (!result) {
                        clrline();
                        printf("10Base-5 (AUI%s",
                               ") has no cable\n"); }
                /* check "ignore missing media" bit */
                if (eth_auto_neg_cnf & IMM_BIT)
                        /* Yes! I don't care if I see a carrrier */
                        result = A_CNF_MEDIA_AUI;
                break;
        case A_CNF_MEDIA_10B_2:
                result = detect_bnc(nic);
                if (!result) {
                        clrline();
                        printf("10Base-2 (BNC%s",
                               ") has no cable\n"); }
                /* check "ignore missing media" bit */
                if (eth_auto_neg_cnf & IMM_BIT)
                        /* Yes! I don't care if I can xmit a packet */
                        result = A_CNF_MEDIA_10B_2;
                break;
        case A_CNF_MEDIA_AUTO:
                writereg(PP_LineCTL, eth_linectl | AUTO_AUI_10BASET);
                if (eth_adapter_cnf & A_CNF_10B_T)
                        if ((result = detect_tp()) != 0)
                                break;
                if (eth_adapter_cnf & A_CNF_AUI)
                        if ((result = detect_aui(nic)) != 0)
                                break;
                if (eth_adapter_cnf & A_CNF_10B_2)
                        if ((result = detect_bnc(nic)) != 0)
                                break;
                clrline(); printf("no media detected\n");
                goto error;
        }
        clrline();
        switch(result) {
        case 0:                 printf("no network cable attached to configured media\n");
                goto error;
        case A_CNF_MEDIA_10B_T: printf("using 10Base-T (RJ-45)\n");
                break;
        case A_CNF_MEDIA_AUI:   printf("using 10Base-5 (AUI)\n");
                break;
        case A_CNF_MEDIA_10B_2: printf("using 10Base-2 (BNC)\n");
                break;
        }
        
        /* Turn on both receive and transmit operations */
        writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_RX_ON |
                 SERIAL_TX_ON);
        
        return 0;
#ifdef EMBEDDED
 error:
        writereg(PP_LineCTL, readreg(PP_LineCTL) &
                 ~(SERIAL_TX_ON | SERIAL_RX_ON));
        outw(PP_ChipID, eth_nic_base + ADD_PORT);
        return 0;
#endif

        nic->nic_op   = &cs89x0_operations;
        return 1;
}
static void cs89x0_disable ( struct nic nic,
struct isa_device *isa  __unused 
) [static]

Definition at line 706 of file cs89x0.c.

References cs89x0_reset().

ISA_DRIVER ( cs89x0_driver  ,
cs89x0_probe_addrs  ,
cs89x0_probe_addr  ,
ISAPNP_VENDOR('C','S','C')  ,
0x0007   
)
DRIVER ( "cs89x0"  ,
nic_driver  ,
isa_driver  ,
cs89x0_driver  ,
cs89x0_probe  ,
cs89x0_disable   
)
ISA_ROM ( "cs89x0"  ,
"Crystal Semiconductor CS89x0"   
)

Variable Documentation

unsigned short eth_nic_base [static]
unsigned long eth_mem_start [static]

Definition at line 98 of file cs89x0.c.

Referenced by cs89x0_probe(), and cs89x0_reset().

unsigned short eth_irqno [static]

Definition at line 99 of file cs89x0.c.

Referenced by cs89x0_probe(), and cs89x0_reset().

unsigned short eth_cs_type [static]

Definition at line 100 of file cs89x0.c.

Referenced by cs89x0_probe(), cs89x0_reset(), and detect_tp().

unsigned short eth_auto_neg_cnf [static]

Definition at line 101 of file cs89x0.c.

Referenced by cs89x0_probe(), and detect_tp().

unsigned short eth_adapter_cnf [static]

Definition at line 102 of file cs89x0.c.

Referenced by control_dc_dc(), and cs89x0_probe().

unsigned short eth_linectl [static]

Definition at line 103 of file cs89x0.c.

Referenced by cs89x0_probe(), detect_aui(), detect_bnc(), and detect_tp().

struct nic_operations cs89x0_operations [static]
Initial value:
 {
        .connect        = dummy_connect,
        .poll           = cs89x0_poll,
        .transmit       = cs89x0_transmit,
        .irq            = cs89x0_irq,
}

Definition at line 472 of file cs89x0.c.

Referenced by cs89x0_probe().

Initial value:
 { 

        
        0x300, 0x320, 0x340, 0x200, 0x220, 0x240,
        0x260, 0x280, 0x2a0, 0x2c0, 0x2e0,
        
        0x301, 0x321, 0x341, 0x201, 0x221, 0x241,
        0x261, 0x281, 0x2a1, 0x2c1, 0x2e1,



}

Definition at line 711 of file cs89x0.c.