75 |
static unsigned short eth_auto_neg_cnf; |
static unsigned short eth_auto_neg_cnf; |
76 |
static unsigned short eth_adapter_cnf; |
static unsigned short eth_adapter_cnf; |
77 |
static unsigned short eth_linectl; |
static unsigned short eth_linectl; |
|
static unsigned char eth_vendor; |
|
78 |
|
|
79 |
/************************************************************************* |
/************************************************************************* |
80 |
CS89x0 - specific routines |
CS89x0 - specific routines |
115 |
int i; |
int i; |
116 |
|
|
117 |
#ifdef EDEBUG |
#ifdef EDEBUG |
118 |
printf("\ncs: EEPROM data from %x for %x:",off,len); |
printf("\ncs: EEPROM data from %hX for %hX:",off,len); |
119 |
#endif |
#endif |
120 |
for (i = 0; i < len; i++) { |
for (i = 0; i < len; i++) { |
121 |
if (wait_eeprom_ready() < 0) |
if (wait_eeprom_ready() < 0) |
129 |
#ifdef EDEBUG |
#ifdef EDEBUG |
130 |
if (!(i%10)) |
if (!(i%10)) |
131 |
printf("\ncs: "); |
printf("\ncs: "); |
132 |
printf("%x ", buffer[i]); |
printf("%hX ", buffer[i]); |
133 |
#endif |
#endif |
134 |
} |
} |
135 |
#ifdef EDEBUG |
#ifdef EDEBUG |
234 |
/* send a test packet - return true if carrier bits are ok */ |
/* send a test packet - return true if carrier bits are ok */ |
235 |
static int send_test_pkt(struct nic *nic) |
static int send_test_pkt(struct nic *nic) |
236 |
{ |
{ |
237 |
static char testpacket[] = { 0,0,0,0,0,0, 0,0,0,0,0,0, |
static unsigned char testpacket[] = { 0,0,0,0,0,0, 0,0,0,0,0,0, |
238 |
0, 46, /*A 46 in network order */ |
0, 46, /*A 46 in network order */ |
239 |
0, 0, /*DSAP=0 & SSAP=0 fields */ |
0, 0, /*DSAP=0 & SSAP=0 fields */ |
240 |
0xf3,0 /*Control (Test Req+P bit set)*/ }; |
0xf3,0 /*Control (Test Req+P bit set)*/ }; |
242 |
|
|
243 |
writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_TX_ON); |
writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_TX_ON); |
244 |
|
|
245 |
memcpy(testpacket, nic->node_addr, ETHER_ADDR_SIZE); |
memcpy(testpacket, nic->node_addr, ETH_ALEN); |
246 |
memcpy(testpacket+ETHER_ADDR_SIZE, nic->node_addr, ETHER_ADDR_SIZE); |
memcpy(testpacket+ETH_ALEN, nic->node_addr, ETH_ALEN); |
247 |
|
|
248 |
outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT); |
outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT); |
249 |
outw(ETH_MIN_PACKET, eth_nic_base + TX_LEN_PORT); |
outw(ETH_ZLEN, eth_nic_base + TX_LEN_PORT); |
250 |
|
|
251 |
/* Test to see if the chip has allocated memory for the packet */ |
/* Test to see if the chip has allocated memory for the packet */ |
252 |
for (tmo = currticks() + 2; |
for (tmo = currticks() + 2; |
256 |
|
|
257 |
/* Write the contents of the packet */ |
/* Write the contents of the packet */ |
258 |
outsw(eth_nic_base + TX_FRAME_PORT, testpacket, |
outsw(eth_nic_base + TX_FRAME_PORT, testpacket, |
259 |
(ETH_MIN_PACKET+1)>>1); |
(ETH_ZLEN+1)>>1); |
260 |
|
|
261 |
printf(" sending test packet "); |
printf(" sending test packet "); |
262 |
/* wait a couple of timer ticks for packet to be received */ |
/* wait a couple of timer ticks for packet to be received */ |
306 |
int i; |
int i; |
307 |
unsigned long reset_tmo; |
unsigned long reset_tmo; |
308 |
|
|
|
if(eth_vendor!=VENDOR_CS89x0) |
|
|
return; |
|
|
|
|
309 |
writereg(PP_SelfCTL, readreg(PP_SelfCTL) | POWER_ON_RESET); |
writereg(PP_SelfCTL, readreg(PP_SelfCTL) | POWER_ON_RESET); |
310 |
|
|
311 |
/* wait for two ticks; that is 2*55ms */ |
/* wait for two ticks; that is 2*55ms */ |
333 |
writereg(PP_BusCTL, 0); |
writereg(PP_BusCTL, 0); |
334 |
|
|
335 |
/* set the ethernet address */ |
/* set the ethernet address */ |
336 |
for (i=0; i < ETHER_ADDR_SIZE/2; i++) |
for (i=0; i < ETH_ALEN/2; i++) |
337 |
writereg(PP_IA+i*2, |
writereg(PP_IA+i*2, |
338 |
nic->node_addr[i*2] | |
nic->node_addr[i*2] | |
339 |
(nic->node_addr[i*2+1] << 8)); |
(nic->node_addr[i*2+1] << 8)); |
370 |
unsigned long tmo; |
unsigned long tmo; |
371 |
int sr; |
int sr; |
372 |
|
|
|
if(eth_vendor!=VENDOR_CS89x0) |
|
|
return; |
|
|
|
|
373 |
/* does this size have to be rounded??? please, |
/* does this size have to be rounded??? please, |
374 |
somebody have a look in the specs */ |
somebody have a look in the specs */ |
375 |
if ((sr = ((s + ETHER_HDR_SIZE + 1)&~1)) < ETH_MIN_PACKET) |
if ((sr = ((s + ETH_HLEN + 1)&~1)) < ETH_ZLEN) |
376 |
sr = ETH_MIN_PACKET; |
sr = ETH_ZLEN; |
377 |
|
|
378 |
retry: |
retry: |
379 |
/* initiate a transmit sequence */ |
/* initiate a transmit sequence */ |
389 |
goto retry; } |
goto retry; } |
390 |
|
|
391 |
/* Write the contents of the packet */ |
/* Write the contents of the packet */ |
392 |
outsw(eth_nic_base + TX_FRAME_PORT, d, ETHER_ADDR_SIZE/2); |
outsw(eth_nic_base + TX_FRAME_PORT, d, ETH_ALEN/2); |
393 |
outsw(eth_nic_base + TX_FRAME_PORT, nic->node_addr, |
outsw(eth_nic_base + TX_FRAME_PORT, nic->node_addr, |
394 |
ETHER_ADDR_SIZE/2); |
ETH_ALEN/2); |
395 |
outw(((t >> 8)&0xFF)|(t << 8), eth_nic_base + TX_FRAME_PORT); |
outw(((t >> 8)&0xFF)|(t << 8), eth_nic_base + TX_FRAME_PORT); |
396 |
outsw(eth_nic_base + TX_FRAME_PORT, p, (s+1)/2); |
outsw(eth_nic_base + TX_FRAME_PORT, p, (s+1)/2); |
397 |
for (sr = sr/2 - (s+1)/2 - ETHER_ADDR_SIZE - 1; sr-- > 0; |
for (sr = sr/2 - (s+1)/2 - ETH_ALEN - 1; sr-- > 0; |
398 |
outw(0, eth_nic_base + TX_FRAME_PORT)); |
outw(0, eth_nic_base + TX_FRAME_PORT)); |
399 |
|
|
400 |
/* wait for transfer to succeed */ |
/* wait for transfer to succeed */ |
402 |
(s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() < tmo;) |
(s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() < tmo;) |
403 |
/* nothing */ ; |
/* nothing */ ; |
404 |
if ((s & TX_SEND_OK_BITS) != TX_OK) { |
if ((s & TX_SEND_OK_BITS) != TX_OK) { |
405 |
printf("\ntransmission error 0x%x\n", s); |
printf("\ntransmission error %#hX\n", s); |
406 |
} |
} |
407 |
|
|
408 |
return; |
return; |
416 |
{ |
{ |
417 |
int status; |
int status; |
418 |
|
|
|
if(eth_vendor!=VENDOR_CS89x0) |
|
|
return 0; |
|
|
|
|
419 |
status = readreg(PP_RxEvent); |
status = readreg(PP_RxEvent); |
420 |
|
|
421 |
if ((status & RX_OK) == 0) |
if ((status & RX_OK) == 0) |
431 |
|
|
432 |
static void cs89x0_disable(struct nic *nic) |
static void cs89x0_disable(struct nic *nic) |
433 |
{ |
{ |
434 |
|
cs89x0_reset(nic); |
435 |
} |
} |
436 |
|
|
437 |
/************************************************************************** |
/************************************************************************** |
457 |
unsigned short eeprom_buff[CHKSUM_LEN]; |
unsigned short eeprom_buff[CHKSUM_LEN]; |
458 |
|
|
459 |
|
|
460 |
for (eth_vendor = VENDOR_NONE, ioidx = 0; |
for (ioidx = 0; (ioaddr=netcard_portlist[ioidx++]) != 0; ) { |
|
eth_vendor == VENDOR_NONE && |
|
|
(ioaddr=netcard_portlist[ioidx++]) != 0;) { |
|
461 |
/* if they give us an odd I/O address, then do ONE write to |
/* if they give us an odd I/O address, then do ONE write to |
462 |
the address port, to get it back to address zero, where we |
the address port, to get it back to address zero, where we |
463 |
expect to find the EISA signature word. */ |
expect to find the EISA signature word. */ |
477 |
eth_cs_type = rev_type &~ REVISON_BITS; |
eth_cs_type = rev_type &~ REVISON_BITS; |
478 |
cs_revision = ((rev_type & REVISON_BITS) >> 8) + 'A'; |
cs_revision = ((rev_type & REVISON_BITS) >> 8) + 'A'; |
479 |
|
|
480 |
printf("\ncs: cs89%c0%s rev %c, base 0x%x", |
printf("\ncs: cs89%c0%s rev %c, base %#hX", |
481 |
eth_cs_type==CS8900?'0':'2', |
eth_cs_type==CS8900?'0':'2', |
482 |
eth_cs_type==CS8920M?"M":"", |
eth_cs_type==CS8920M?"M":"", |
483 |
cs_revision, |
cs_revision, |
537 |
eth_irq = i; } |
eth_irq = i; } |
538 |
|
|
539 |
/* Retrieve and print the ethernet address. */ |
/* Retrieve and print the ethernet address. */ |
540 |
for (i=0; i<ETHER_ADDR_SIZE; i++) { |
for (i=0; i<ETH_ALEN; i++) { |
541 |
printf("%b%s",(int)(nic->node_addr[i] = |
nic->node_addr[i] = ((unsigned char *)eeprom_buff)[i]; |
542 |
((unsigned char *)eeprom_buff)[i]), |
} |
543 |
i < ETHER_ADDR_SIZE-1 ? ":" : "\n"); } |
printf("%!\n", nic->node_addr); |
544 |
|
|
545 |
/* Set the LineCTL quintuplet based on adapter |
/* Set the LineCTL quintuplet based on adapter |
546 |
configuration read from EEPROM */ |
configuration read from EEPROM */ |
572 |
} |
} |
573 |
|
|
574 |
/* Initialize the card for probing of the attached media */ |
/* Initialize the card for probing of the attached media */ |
|
eth_vendor = VENDOR_CS89x0; |
|
575 |
cs89x0_reset(nic); |
cs89x0_reset(nic); |
|
eth_vendor = VENDOR_NONE; |
|
576 |
|
|
577 |
/* set the hardware to the configured choice */ |
/* set the hardware to the configured choice */ |
578 |
switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) { |
switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) { |
639 |
writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_RX_ON | |
writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_RX_ON | |
640 |
SERIAL_TX_ON); |
SERIAL_TX_ON); |
641 |
|
|
642 |
eth_vendor = VENDOR_CS89x0; |
break; |
643 |
} |
} |
644 |
|
|
645 |
|
if (ioaddr == 0) |
646 |
|
return (0); |
647 |
nic->reset = cs89x0_reset; |
nic->reset = cs89x0_reset; |
648 |
nic->poll = cs89x0_poll; |
nic->poll = cs89x0_poll; |
649 |
nic->transmit = cs89x0_transmit; |
nic->transmit = cs89x0_transmit; |
650 |
nic->disable = cs89x0_disable; |
nic->disable = cs89x0_disable; |
651 |
return nic; |
return (nic); |
652 |
} |
} |
653 |
|
|
654 |
/* |
/* |