cs89x0.c File Reference

#include <errno.h>
#include <gpxe/ethernet.h>
#include "etherboot.h"
#include "nic.h"
#include <gpxe/isa.h>
#include "console.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]

Definition at line 110 of file cs89x0.c.

References ADD_PORT, DATA_PORT, eth_nic_base, inw, and outw.

Referenced by cs89x0_poll(), cs89x0_probe(), cs89x0_reset(), cs89x0_transmit(), detect_tp(), get_eeprom_data(), send_test_pkt(), and wait_eeprom_ready().

00111 {
00112         outw(portno, eth_nic_base + ADD_PORT);
00113         return inw(eth_nic_base + DATA_PORT);
00114 }

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

Definition at line 116 of file cs89x0.c.

References ADD_PORT, DATA_PORT, eth_nic_base, and outw.

Referenced by control_dc_dc(), cs89x0_probe(), cs89x0_reset(), detect_aui(), detect_bnc(), detect_tp(), get_eeprom_data(), and send_test_pkt().

00117 {
00118         outw(portno, eth_nic_base + ADD_PORT);
00119         outw(value, eth_nic_base + DATA_PORT);
00120         return;
00121 }

static int wait_eeprom_ready ( void   )  [static]

Definition at line 127 of file cs89x0.c.

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

Referenced by get_eeprom_data().

00128 {
00129         unsigned long tmo = currticks() + 4*TICKS_PER_SEC;
00130 
00131         /* check to see if the EEPROM is ready, a timeout is used -
00132            just in case EEPROM is ready when SI_BUSY in the
00133            PP_SelfST is clear */
00134         while(readreg(PP_SelfST) & SI_BUSY) {
00135                 if (currticks() >= tmo)
00136                         return -1; }
00137         return 0;
00138 }

static int get_eeprom_data ( int  off,
int  len,
unsigned short *  buffer 
) [static]

Definition at line 140 of file cs89x0.c.

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

Referenced by cs89x0_probe().

00141 {
00142         int i;
00143 
00144 #ifdef  EDEBUG
00145         printf("\ncs: EEPROM data from %hX for %hX:",off,len);
00146 #endif
00147         for (i = 0; i < len; i++) {
00148                 if (wait_eeprom_ready() < 0)
00149                         return -1;
00150                 /* Now send the EEPROM read command and EEPROM location
00151                    to read */
00152                 writereg(PP_EECMD, (off + i) | EEPROM_READ_CMD);
00153                 if (wait_eeprom_ready() < 0)
00154                         return -1;
00155                 buffer[i] = readreg(PP_EEData);
00156 #ifdef  EDEBUG
00157                 if (!(i%10))
00158                         printf("\ncs: ");
00159                 printf("%hX ", buffer[i]);
00160 #endif
00161         }
00162 #ifdef  EDEBUG
00163         putchar('\n');
00164 #endif
00165 
00166         return(0);
00167 }

static int get_eeprom_chksum ( int off  __unused,
int  len,
unsigned short *  buffer 
) [static]

Definition at line 169 of file cs89x0.c.

Referenced by cs89x0_probe().

00170 {
00171         int  i, cksum;
00172 
00173         cksum = 0;
00174         for (i = 0; i < len; i++)
00175                 cksum += buffer[i];
00176         cksum &= 0xffff;
00177         if (cksum == 0)
00178                 return 0;
00179         return -1;
00180 }

static void clrline ( void   )  [static]

Definition at line 186 of file cs89x0.c.

References printf(), and putchar().

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

00187 {
00188         int i;
00189 
00190         putchar('\r');
00191         for (i = 79; i--; ) putchar(' ');
00192         printf("\rcs: ");
00193         return;
00194 }

static void control_dc_dc ( int  on_not_off  )  [static]

Definition at line 196 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().

00197 {
00198         unsigned int selfcontrol;
00199         unsigned long tmo = currticks() + TICKS_PER_SEC;
00200 
00201         /* control the DC to DC convertor in the SelfControl register.  */
00202         selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */
00203         if (((eth_adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)
00204                 selfcontrol |= HCB1;
00205         else
00206                 selfcontrol &= ~HCB1;
00207         writereg(PP_SelfCTL, selfcontrol);
00208 
00209         /* Wait for the DC/DC converter to power up - 1000ms */
00210         while (currticks() < tmo);
00211 
00212         return;
00213 }

static int detect_tp ( void   )  [static]

Definition at line 215 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().

00216 {
00217         unsigned long tmo;
00218 
00219         /* Turn on the chip auto detection of 10BT/ AUI */
00220 
00221         clrline(); printf("attempting %s:","TP");
00222 
00223         /* If connected to another full duplex capable 10-Base-T card
00224            the link pulses seem to be lost when the auto detect bit in
00225            the LineCTL is set.  To overcome this the auto detect bit
00226            will be cleared whilst testing the 10-Base-T interface.
00227            This would not be necessary for the sparrow chip but is
00228            simpler to do it anyway. */
00229         writereg(PP_LineCTL, eth_linectl &~ AUI_ONLY);
00230         control_dc_dc(0);
00231 
00232         /* Delay for the hardware to work out if the TP cable is
00233            present - 150ms */
00234         for (tmo = currticks() + 4; currticks() < tmo; );
00235 
00236         if ((readreg(PP_LineST) & LINK_OK) == 0)
00237                 return 0;
00238 
00239         if (eth_cs_type != CS8900) {
00240 
00241                 writereg(PP_AutoNegCTL, eth_auto_neg_cnf & AUTO_NEG_MASK);
00242 
00243                 if ((eth_auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {
00244                         printf(" negotiating duplex... ");
00245                         while (readreg(PP_AutoNegST) & AUTO_NEG_BUSY) {
00246                                 if (currticks() - tmo > 40*TICKS_PER_SEC) {
00247                                         printf("time out ");
00248                                         break;
00249                                 }
00250                         }
00251                 }
00252                 if (readreg(PP_AutoNegST) & FDX_ACTIVE)
00253                         printf("using full duplex");
00254                 else
00255                         printf("using half duplex");
00256         }
00257 
00258         return A_CNF_MEDIA_10B_T;
00259 }

static int send_test_pkt ( struct nic nic  )  [static]

Definition at line 262 of file cs89x0.c.

References currticks(), ETH_ALEN, eth_nic_base, ETH_ZLEN, memcpy, nic::node_addr, 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().

00263 {
00264         static unsigned char testpacket[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
00265                                      0, 46, /*A 46 in network order       */
00266                                      0, 0,  /*DSAP=0 & SSAP=0 fields      */
00267                                      0xf3,0 /*Control (Test Req+P bit set)*/ };
00268         unsigned long tmo;
00269 
00270         writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_TX_ON);
00271 
00272         memcpy(testpacket, nic->node_addr, ETH_ALEN);
00273         memcpy(testpacket+ETH_ALEN, nic->node_addr, ETH_ALEN);
00274 
00275         outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
00276         outw(ETH_ZLEN, eth_nic_base + TX_LEN_PORT);
00277 
00278         /* Test to see if the chip has allocated memory for the packet */
00279         for (tmo = currticks() + 2;
00280              (readreg(PP_BusST) & READY_FOR_TX_NOW) == 0; )
00281                 if (currticks() >= tmo)
00282                         return(0);
00283 
00284         /* Write the contents of the packet */
00285         outsw(eth_nic_base + TX_FRAME_PORT, testpacket,
00286               (ETH_ZLEN+1)>>1);
00287 
00288         printf(" sending test packet ");
00289         /* wait a couple of timer ticks for packet to be received */
00290         for (tmo = currticks() + 2; currticks() < tmo; );
00291 
00292         if ((readreg(PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
00293                         printf("succeeded");
00294                         return 1;
00295         }
00296         printf("failed");
00297         return 0;
00298 }

static int detect_aui ( struct nic nic  )  [static]

Definition at line 301 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().

00302 {
00303         clrline(); printf("attempting %s:","AUI");
00304         control_dc_dc(0);
00305 
00306         writereg(PP_LineCTL, (eth_linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
00307 
00308         if (send_test_pkt(nic)) {
00309                 return A_CNF_MEDIA_AUI; }
00310         else
00311                 return 0;
00312 }

static int detect_bnc ( struct nic nic  )  [static]

Definition at line 314 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().

00315 {
00316         clrline(); printf("attempting %s:","BNC");
00317         control_dc_dc(1);
00318 
00319         writereg(PP_LineCTL, (eth_linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
00320 
00321         if (send_test_pkt(nic)) {
00322                 return A_CNF_MEDIA_10B_2; }
00323         else
00324                 return 0;
00325 }

static void cs89x0_reset ( struct nic nic  )  [static]

Definition at line 331 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, nic::node_addr, 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().

00332 {
00333         int  i;
00334         unsigned long reset_tmo;
00335 
00336         writereg(PP_SelfCTL, readreg(PP_SelfCTL) | POWER_ON_RESET);
00337 
00338         /* wait for two ticks; that is 2*55ms */
00339         for (reset_tmo = currticks() + 2; currticks() < reset_tmo; );
00340 
00341         if (eth_cs_type != CS8900) {
00342                 /* Hardware problem requires PNP registers to be reconfigured
00343                    after a reset */
00344                 if (eth_irqno != 0xFFFF) {
00345                         outw(PP_CS8920_ISAINT, eth_nic_base + ADD_PORT);
00346                         outb(eth_irqno, eth_nic_base + DATA_PORT);
00347                         outb(0, eth_nic_base + DATA_PORT + 1); }
00348 
00349                 if (eth_mem_start) {
00350                         outw(PP_CS8920_ISAMemB, eth_nic_base + ADD_PORT);
00351                         outb((eth_mem_start >> 8) & 0xff, eth_nic_base + DATA_PORT);
00352                         outb((eth_mem_start >> 24) & 0xff, eth_nic_base + DATA_PORT + 1); } }
00353 
00354         /* Wait until the chip is reset */
00355         for (reset_tmo = currticks() + 2;
00356              (readreg(PP_SelfST) & INIT_DONE) == 0 &&
00357                      currticks() < reset_tmo; );
00358 
00359         /* disable interrupts and memory accesses */
00360         writereg(PP_BusCTL, 0);
00361 
00362         /* set the ethernet address */
00363         for (i=0; i < ETH_ALEN/2; i++)
00364                 writereg(PP_IA+i*2,
00365                          nic->node_addr[i*2] |
00366                          (nic->node_addr[i*2+1] << 8));
00367 
00368         /* receive only error free packets addressed to this card */
00369         writereg(PP_RxCTL, DEF_RX_ACCEPT);
00370 
00371         /* do not generate any interrupts on receive operations */
00372         writereg(PP_RxCFG, 0);
00373 
00374         /* do not generate any interrupts on transmit operations */
00375         writereg(PP_TxCFG, 0);
00376 
00377         /* do not generate any interrupts on buffer operations */
00378         writereg(PP_BufCFG, 0);
00379 
00380         /* reset address port, so that autoprobing will keep working */
00381         outw(PP_ChipID, eth_nic_base + ADD_PORT);
00382 
00383         return;
00384 }

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

Definition at line 390 of file cs89x0.c.

References cs89x0_reset(), currticks(), ETH_ALEN, ETH_HLEN, eth_nic_base, ETH_ZLEN, nic::node_addr, 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.

00396 {
00397         unsigned long tmo;
00398         int           sr;
00399 
00400         /* does this size have to be rounded??? please,
00401            somebody have a look in the specs */
00402         if ((sr = ((s + ETH_HLEN + 1)&~1)) < ETH_ZLEN)
00403                 sr = ETH_ZLEN;
00404 
00405 retry:
00406         /* initiate a transmit sequence */
00407         outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
00408         outw(sr, eth_nic_base + TX_LEN_PORT);
00409 
00410         /* Test to see if the chip has allocated memory for the packet */
00411         if ((readreg(PP_BusST) & READY_FOR_TX_NOW) == 0) {
00412                 /* Oops... this should not happen! */
00413                 printf("cs: unable to send packet; retrying...\n");
00414                 for (tmo = currticks() + 5*TICKS_PER_SEC; currticks() < tmo; );
00415                 cs89x0_reset(nic);
00416                 goto retry; }
00417 
00418         /* Write the contents of the packet */
00419         outsw(eth_nic_base + TX_FRAME_PORT, d, ETH_ALEN/2);
00420         outsw(eth_nic_base + TX_FRAME_PORT, nic->node_addr,
00421               ETH_ALEN/2);
00422         outw(((t >> 8)&0xFF)|(t << 8), eth_nic_base + TX_FRAME_PORT);
00423         outsw(eth_nic_base + TX_FRAME_PORT, p, (s+1)/2);
00424         for (sr = sr/2 - (s+1)/2 - ETH_ALEN - 1; sr > 0; sr--)
00425                 outw(0, eth_nic_base + TX_FRAME_PORT);
00426 
00427         /* wait for transfer to succeed */
00428         for (tmo = currticks()+5*TICKS_PER_SEC;
00429              (s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() < tmo;)
00430                 /* nothing */ ;
00431         if ((s & TX_SEND_OK_BITS) != TX_OK) {
00432                 printf("\ntransmission error %#hX\n", s);
00433         }
00434 
00435         return;
00436 }

static int cs89x0_poll ( struct nic nic,
int  retrieve 
) [static]

Definition at line 442 of file cs89x0.c.

References eth_nic_base, insw, inw, nic::packet, nic::packetlen, PP_RxEvent, readreg(), RX_FRAME_PORT, and RX_OK.

00443 {
00444         int status;
00445 
00446         status = readreg(PP_RxEvent);
00447 
00448         if ((status & RX_OK) == 0)
00449                 return(0);
00450 
00451         if ( ! retrieve ) return 1;
00452 
00453         status = inw(eth_nic_base + RX_FRAME_PORT);
00454         nic->packetlen = inw(eth_nic_base + RX_FRAME_PORT);
00455         insw(eth_nic_base + RX_FRAME_PORT, nic->packet, nic->packetlen >> 1);
00456         if (nic->packetlen & 1)
00457                 nic->packet[nic->packetlen-1] = inw(eth_nic_base + RX_FRAME_PORT);
00458         return 1;
00459 }

static void cs89x0_irq ( struct nic *nic  __unused,
irq_action_t action  __unused 
) [static]

Definition at line 461 of file cs89x0.c.

References DISABLE, ENABLE, and FORCE.

00462 {
00463   switch ( action ) {
00464   case DISABLE :
00465     break;
00466   case ENABLE :
00467     break;
00468   case FORCE :
00469     break;
00470   }
00471 }

static int cs89x0_probe_addr ( isa_probe_addr_t  ioaddr  )  [static]

Definition at line 484 of file cs89x0.c.

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

00484                                                          {
00485         /* if they give us an odd I/O address, then do ONE write to
00486            the address port, to get it back to address zero, where we
00487            expect to find the EISA signature word. */
00488         if (ioaddr & 1) {
00489                 ioaddr &= ~1;
00490                 if ((inw(ioaddr + ADD_PORT) & ADD_MASK) != ADD_SIG)
00491                         return 0;
00492                 outw(PP_ChipID, ioaddr + ADD_PORT);
00493         }
00494         
00495         if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG)
00496                 return 0;
00497 
00498         return 1;
00499 }

static int cs89x0_probe ( struct nic nic,
struct isa_device *isa  __unused 
) [static]

Definition at line 501 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_reset(), DBG, detect_aui(), detect_bnc(), detect_tp(), EE_AUTO_NEG_ENABLE, EEPROM_PRESENT, 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, nic::ioaddr, nic::irqno, ISA_CNF_OFFSET, LOW_RX_SQUELCH, memcpy, nic::nic_op, nic::node_addr, 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().

00501                                                                              {
00502         int      i, result = -1;
00503         unsigned rev_type = 0, isa_cnf, cs_revision;
00504         unsigned short eeprom_buff[CHKSUM_LEN];
00505 
00506         nic->ioaddr &= ~1; /* LSB = 1 indicates a more aggressive probe */
00507         eth_nic_base = nic->ioaddr;
00508 
00509         /* get the chip type */
00510         rev_type = readreg(PRODUCT_ID_ADD);
00511         eth_cs_type = rev_type &~ REVISON_BITS;
00512         cs_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
00513         
00514         printf("\ncs: cs89%c0%s rev %c, base %#hX",
00515                eth_cs_type==CS8900?'0':'2',
00516                eth_cs_type==CS8920M?"M":"",
00517                cs_revision,
00518                eth_nic_base);
00519 #ifndef EMBEDDED 
00520         /* First check to see if an EEPROM is attached*/
00521         if ((readreg(PP_SelfST) & EEPROM_PRESENT) == 0) {
00522                 printf("\ncs: no EEPROM...\n");
00523                 outw(PP_ChipID, eth_nic_base + ADD_PORT);
00524                 return 0;
00525         } else if (get_eeprom_data(START_EEPROM_DATA,CHKSUM_LEN,
00526                                    eeprom_buff) < 0) {
00527                 printf("\ncs: EEPROM read failed...\n");
00528                 outw(PP_ChipID, eth_nic_base + ADD_PORT);
00529                 return 0;
00530         } else if (get_eeprom_chksum(START_EEPROM_DATA,CHKSUM_LEN,
00531                                      eeprom_buff) < 0) {
00532                 printf("\ncs: EEPROM checksum bad...\n");
00533                 outw(PP_ChipID, eth_nic_base + ADD_PORT);
00534                 return 0;
00535         }
00536 
00537         /* get transmission control word but keep the
00538            autonegotiation bits */
00539         eth_auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];
00540         /* Store adapter configuration */
00541         eth_adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];
00542         /* Store ISA configuration */
00543         isa_cnf = eeprom_buff[ISA_CNF_OFFSET/2];
00544         
00545         /* store the initial memory base address */
00546         eth_mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] << 8;
00547         
00548         printf("%s%s%s, addr ",
00549                (eth_adapter_cnf & A_CNF_10B_T)?", RJ-45":"",
00550                (eth_adapter_cnf & A_CNF_AUI)?", AUI":"",
00551                (eth_adapter_cnf & A_CNF_10B_2)?", BNC":"");
00552         
00553         /* If this is a CS8900 then no pnp soft */
00554         if (eth_cs_type != CS8900 &&
00555             /* Check if the ISA IRQ has been set  */
00556             (i = readreg(PP_CS8920_ISAINT) & 0xff,
00557              (i != 0 && i < CS8920_NO_INTS)))
00558                 eth_irqno = i;
00559         else {
00560                 i = isa_cnf & INT_NO_MASK;
00561                 if (eth_cs_type == CS8900) {
00562                         /* the table that follows is dependent
00563                            upon how you wired up your cs8900
00564                            in your system.  The table is the
00565                            same as the cs8900 engineering demo
00566                            board.  irq_map also depends on the
00567                            contents of the table.  Also see
00568                            write_irq, which is the reverse
00569                            mapping of the table below. */
00570                         if (i < 4) i = "\012\013\014\005"[i];
00571                         else printf("\ncs: BUG: isa_config is %d\n", i); }
00572                 eth_irqno = i; }
00573         
00574         nic->irqno = eth_irqno;
00575 
00576         /* Retrieve and print the ethernet address. */
00577         for (i=0; i<ETH_ALEN; i++) {
00578                 nic->node_addr[i] = ((unsigned char *)eeprom_buff)[i];
00579         }
00580 
00581         DBG ( "%s\n", eth_ntoa ( nic->node_addr ) );
00582 
00583 #endif
00584 #ifdef EMBEDDED
00585         /* Retrieve and print the ethernet address. */
00586         {
00587                 unsigned char MAC_HW_ADDR[6]={MAC_HW_ADDR_DRV};
00588                 memcpy(nic->node_addr, MAC_HW_ADDR, 6);
00589         }
00590 
00591         DBG ( "%s\n", eth_ntoa ( nic->node_addr ) );
00592         
00593         eth_adapter_cnf = A_CNF_10B_T | A_CNF_MEDIA_10B_T;
00594         eth_auto_neg_cnf = EE_AUTO_NEG_ENABLE | IMM_BIT;
00595 #endif
00596 #ifndef EMBEDDED 
00597         /* Set the LineCTL quintuplet based on adapter
00598            configuration read from EEPROM */
00599         if ((eth_adapter_cnf & A_CNF_EXTND_10B_2) &&
00600             (eth_adapter_cnf & A_CNF_LOW_RX_SQUELCH))
00601                 eth_linectl = LOW_RX_SQUELCH;
00602         else
00603                 eth_linectl = 0;
00604         
00605         /* check to make sure that they have the "right"
00606            hardware available */
00607         switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {
00608         case A_CNF_MEDIA_10B_T: result = eth_adapter_cnf & A_CNF_10B_T;
00609                 break;
00610         case A_CNF_MEDIA_AUI:   result = eth_adapter_cnf & A_CNF_AUI;
00611                 break;
00612         case A_CNF_MEDIA_10B_2: result = eth_adapter_cnf & A_CNF_10B_2;
00613                 break;
00614         default: result = eth_adapter_cnf & (A_CNF_10B_T | A_CNF_AUI |
00615                                              A_CNF_10B_2);
00616         }
00617         if (!result) {
00618                 printf("cs: EEPROM is configured for unavailable media\n");
00619         error:
00620                 writereg(PP_LineCTL, readreg(PP_LineCTL) &
00621                          ~(SERIAL_TX_ON | SERIAL_RX_ON));
00622                 outw(PP_ChipID, eth_nic_base + ADD_PORT);
00623                 return 0;
00624         }
00625 #endif
00626         /* Initialize the card for probing of the attached media */
00627         cs89x0_reset(nic);
00628         
00629         /* set the hardware to the configured choice */
00630         switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {
00631         case A_CNF_MEDIA_10B_T:
00632                 result = detect_tp();
00633                 if (!result) {
00634                         clrline();
00635                         printf("10Base-T (RJ-45%s",
00636                                ") has no cable\n"); }
00637                 /* check "ignore missing media" bit */
00638                 if (eth_auto_neg_cnf & IMM_BIT)
00639                         /* Yes! I don't care if I see a link pulse */
00640                         result = A_CNF_MEDIA_10B_T;
00641                 break;
00642         case A_CNF_MEDIA_AUI:
00643                 result = detect_aui(nic);
00644                 if (!result) {
00645                         clrline();
00646                         printf("10Base-5 (AUI%s",
00647                                ") has no cable\n"); }
00648                 /* check "ignore missing media" bit */
00649                 if (eth_auto_neg_cnf & IMM_BIT)
00650                         /* Yes! I don't care if I see a carrrier */
00651                         result = A_CNF_MEDIA_AUI;
00652                 break;
00653         case A_CNF_MEDIA_10B_2:
00654                 result = detect_bnc(nic);
00655                 if (!result) {
00656                         clrline();
00657                         printf("10Base-2 (BNC%s",
00658                                ") has no cable\n"); }
00659                 /* check "ignore missing media" bit */
00660                 if (eth_auto_neg_cnf & IMM_BIT)
00661                         /* Yes! I don't care if I can xmit a packet */
00662                         result = A_CNF_MEDIA_10B_2;
00663                 break;
00664         case A_CNF_MEDIA_AUTO:
00665                 writereg(PP_LineCTL, eth_linectl | AUTO_AUI_10BASET);
00666                 if (eth_adapter_cnf & A_CNF_10B_T)
00667                         if ((result = detect_tp()) != 0)
00668                                 break;
00669                 if (eth_adapter_cnf & A_CNF_AUI)
00670                         if ((result = detect_aui(nic)) != 0)
00671                                 break;
00672                 if (eth_adapter_cnf & A_CNF_10B_2)
00673                         if ((result = detect_bnc(nic)) != 0)
00674                                 break;
00675                 clrline(); printf("no media detected\n");
00676                 goto error;
00677         }
00678         clrline();
00679         switch(result) {
00680         case 0:                 printf("no network cable attached to configured media\n");
00681                 goto error;
00682         case A_CNF_MEDIA_10B_T: printf("using 10Base-T (RJ-45)\n");
00683                 break;
00684         case A_CNF_MEDIA_AUI:   printf("using 10Base-5 (AUI)\n");
00685                 break;
00686         case A_CNF_MEDIA_10B_2: printf("using 10Base-2 (BNC)\n");
00687                 break;
00688         }
00689         
00690         /* Turn on both receive and transmit operations */
00691         writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_RX_ON |
00692                  SERIAL_TX_ON);
00693         
00694         return 0;
00695 #ifdef EMBEDDED
00696  error:
00697         writereg(PP_LineCTL, readreg(PP_LineCTL) &
00698                  ~(SERIAL_TX_ON | SERIAL_RX_ON));
00699         outw(PP_ChipID, eth_nic_base + ADD_PORT);
00700         return 0;
00701 #endif
00702 
00703         nic->nic_op   = &cs89x0_operations;
00704         return 1;
00705 }

static void cs89x0_disable ( struct nic nic,
struct isa_device *isa  __unused 
) [static]

Definition at line 707 of file cs89x0.c.

References cs89x0_reset().

00708                                                                {
00709         cs89x0_reset(nic);
00710 }

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]

Definition at line 98 of file cs89x0.c.

unsigned long eth_mem_start [static]

Definition at line 99 of file cs89x0.c.

Referenced by cs89x0_probe(), and cs89x0_reset().

unsigned short eth_irqno [static]

Definition at line 100 of file cs89x0.c.

Referenced by cs89x0_probe(), and cs89x0_reset().

unsigned short eth_cs_type [static]

Definition at line 101 of file cs89x0.c.

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

unsigned short eth_auto_neg_cnf [static]

Definition at line 102 of file cs89x0.c.

Referenced by cs89x0_probe(), and detect_tp().

unsigned short eth_adapter_cnf [static]

Definition at line 103 of file cs89x0.c.

Referenced by control_dc_dc(), and cs89x0_probe().

unsigned short eth_linectl [static]

Definition at line 104 of file cs89x0.c.

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

Initial value:

 {
        .connect        = dummy_connect,
        .poll           = cs89x0_poll,
        .transmit       = cs89x0_transmit,
        .irq            = cs89x0_irq,
}

Definition at line 473 of file cs89x0.c.

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 712 of file cs89x0.c.


Generated on Tue Apr 6 20:01:23 2010 for gPXE by  doxygen 1.5.7.1