5 |
#include "etherboot.h" |
#include "etherboot.h" |
6 |
#include "nic.h" |
#include "nic.h" |
7 |
#include "cards.h" |
#include "cards.h" |
8 |
|
#include "timer.h" |
9 |
#include "epic100.h" |
#include "epic100.h" |
10 |
|
|
11 |
#undef virt_to_bus |
#undef virt_to_bus |
16 |
|
|
17 |
#define PKT_BUF_SZ 1536 /* Size of each temporary Tx/Rx buffer.*/ |
#define PKT_BUF_SZ 1536 /* Size of each temporary Tx/Rx buffer.*/ |
18 |
|
|
|
#define TIME_OUT 1000000 |
|
|
|
|
19 |
/* |
/* |
20 |
#define DEBUG_RX |
#define DEBUG_RX |
21 |
#define DEBUG_TX |
#define DEBUG_TX |
82 |
static signed char phys[4]; /* MII device addresses. */ |
static signed char phys[4]; /* MII device addresses. */ |
83 |
static struct epic_rx_desc rx_ring[RX_RING_SIZE]; |
static struct epic_rx_desc rx_ring[RX_RING_SIZE]; |
84 |
static struct epic_tx_desc tx_ring[TX_RING_SIZE]; |
static struct epic_tx_desc tx_ring[TX_RING_SIZE]; |
85 |
#ifndef USE_INTERNAL_BUFFER |
#ifdef USE_LOWMEM_BUFFER |
86 |
#define rx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE) |
#define rx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE) |
87 |
#define tx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE - PKT_BUF_SZ * TX_RING_SIZE) |
#define tx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE - PKT_BUF_SZ * TX_RING_SIZE) |
88 |
#else |
#else |
169 |
#if (EPIC_DEBUG > 1) |
#if (EPIC_DEBUG > 1) |
170 |
printf("EEPROM contents\n"); |
printf("EEPROM contents\n"); |
171 |
for (i = 0; i < 64; i++) { |
for (i = 0; i < 64; i++) { |
172 |
printf(" %02x%s", eeprom[i], i % 16 == 15 ? "\n" : ""); |
printf(" %hhX%s", eeprom[i], i % 16 == 15 ? "\n" : ""); |
173 |
} |
} |
174 |
#endif |
#endif |
175 |
#endif |
#endif |
179 |
for (i = 0; i < 3; i++) |
for (i = 0; i < 3; i++) |
180 |
*ap++ = inw(lan0 + i*4); |
*ap++ = inw(lan0 + i*4); |
181 |
|
|
182 |
printf(" I/O %x ", ioaddr); |
printf(" I/O %#hX %! ", ioaddr, nic->node_addr); |
|
|
|
|
for (i = 0; i < 6; i++) |
|
|
printf ("%b%c", nic->node_addr[i] , i < 5 ?':':' '); |
|
183 |
|
|
184 |
/* Find the connected MII xcvrs. */ |
/* Find the connected MII xcvrs. */ |
185 |
for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(phys); phy++) { |
for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(phys); phy++) { |
211 |
} |
} |
212 |
|
|
213 |
static void |
static void |
214 |
epic100_open() |
epic100_open(void) |
215 |
{ |
{ |
216 |
int mii_reg5; |
int mii_reg5; |
217 |
int full_duplex = 0; |
int full_duplex = 0; |
249 |
|
|
250 |
/* Initialize the Rx and Tx rings. */ |
/* Initialize the Rx and Tx rings. */ |
251 |
static void |
static void |
252 |
epic100_init_ring() |
epic100_init_ring(void) |
253 |
{ |
{ |
254 |
int i; |
int i; |
255 |
char* p; |
char* p; |
296 |
unsigned int len, const char *data) |
unsigned int len, const char *data) |
297 |
{ |
{ |
298 |
unsigned short nstype; |
unsigned short nstype; |
|
unsigned short status; |
|
299 |
char* txp; |
char* txp; |
|
int to; |
|
300 |
int entry; |
int entry; |
301 |
|
|
302 |
/* Calculate the next Tx descriptor entry. */ |
/* Calculate the next Tx descriptor entry. */ |
303 |
entry = cur_tx % TX_RING_SIZE; |
entry = cur_tx % TX_RING_SIZE; |
304 |
|
|
305 |
if ((tx_ring[entry].status & TRING_OWN) == TRING_OWN) { |
if ((tx_ring[entry].status & TRING_OWN) == TRING_OWN) { |
306 |
printf("eth_transmit: Unable to transmit. status=%x. Resetting...\n", |
printf("eth_transmit: Unable to transmit. status=%hX. Resetting...\n", |
307 |
tx_ring[entry].status); |
tx_ring[entry].status); |
308 |
|
|
309 |
epic100_open(); |
epic100_open(); |
312 |
|
|
313 |
txp = (char*)tx_ring[entry].bufaddr; |
txp = (char*)tx_ring[entry].bufaddr; |
314 |
|
|
315 |
memcpy(txp, destaddr, ETHER_ADDR_SIZE); |
memcpy(txp, destaddr, ETH_ALEN); |
316 |
memcpy(txp + ETHER_ADDR_SIZE, nic->node_addr, ETHER_ADDR_SIZE); |
memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN); |
317 |
nstype = htons(type); |
nstype = htons(type); |
318 |
memcpy(txp + 12, (char*)&nstype, 2); |
memcpy(txp + 12, (char*)&nstype, 2); |
319 |
memcpy(txp + ETHER_HDR_SIZE, data, len); |
memcpy(txp + ETH_HLEN, data, len); |
320 |
|
|
321 |
len += ETHER_HDR_SIZE; |
len += ETH_HLEN; |
322 |
|
|
323 |
/* |
/* |
324 |
* Caution: the write order is important here, |
* Caution: the write order is important here, |
334 |
/* Trigger an immediate transmit demand. */ |
/* Trigger an immediate transmit demand. */ |
335 |
outl(CR_QUEUE_TX, command); |
outl(CR_QUEUE_TX, command); |
336 |
|
|
337 |
to = TIME_OUT; |
load_timer2(10*TICKS_PER_MS); /* timeout 10 ms for transmit */ |
338 |
status = tx_ring[entry].status; |
while ((tx_ring[entry].status & TRING_OWN) && timer2_running()) |
339 |
|
/* Wait */; |
340 |
while ( (status & TRING_OWN) && --to) { |
|
341 |
status = tx_ring[entry].status; |
if ((tx_ring[entry].status & TRING_OWN) != 0) |
342 |
} |
printf("Oops, transmitter timeout, status=%hX\n", |
343 |
|
tx_ring[entry].status); |
|
if ((status & TRING_OWN) == 0) { |
|
|
#ifdef DEBUG_TX |
|
|
printf("tx done after %d loop(s), status %x\n", |
|
|
TIME_OUT-to, tx_ring[entry].status ); |
|
|
#endif |
|
|
return; |
|
|
} |
|
|
|
|
|
if (to == 0) { |
|
|
printf("OOPS, Something wrong with transmitter. status=%x\n", |
|
|
tx_ring[entry].status); |
|
|
} |
|
344 |
} |
} |
345 |
|
|
346 |
/* function: epic100_poll / eth_poll |
/* function: epic100_poll / eth_poll |
358 |
static int |
static int |
359 |
epic100_poll(struct nic *nic) |
epic100_poll(struct nic *nic) |
360 |
{ |
{ |
|
int to; |
|
361 |
int entry; |
int entry; |
362 |
int status; |
int status; |
363 |
int retcode; |
int retcode; |
364 |
|
|
365 |
entry = cur_rx % RX_RING_SIZE; |
entry = cur_rx % RX_RING_SIZE; |
|
cur_rx++; |
|
|
to = TIME_OUT; |
|
366 |
|
|
367 |
status = rx_ring[entry].status; |
if ((status = rx_ring[entry].status & RRING_OWN) == RRING_OWN) |
368 |
while ( (status & RRING_OWN) == RRING_OWN && --to) { |
return (0); |
|
status = rx_ring[entry].status; |
|
|
} |
|
|
|
|
|
if (to == 0) { |
|
|
#ifdef DEBUG_RX |
|
|
printf("epic_poll: time out! status %x\n", status); |
|
|
#endif |
|
|
/* Restart Receiver */ |
|
|
outl(CR_START_RX | CR_QUEUE_RX, command); |
|
|
return 0; |
|
|
} |
|
369 |
|
|
370 |
/* We own the next entry, it's a new packet. Send it up. */ |
/* We own the next entry, it's a new packet. Send it up. */ |
371 |
|
|
372 |
#if (EPIC_DEBUG > 4) |
#if (EPIC_DEBUG > 4) |
373 |
printf("epic_poll: entry %d status %8x\n", entry, status); |
printf("epic_poll: entry %d status %hX\n", entry, status); |
374 |
#endif |
#endif |
375 |
|
|
376 |
|
cur_rx++; |
377 |
if (status & 0x2000) { |
if (status & 0x2000) { |
378 |
printf("epic_poll: Giant packet\n"); |
printf("epic_poll: Giant packet\n"); |
379 |
retcode = 0; |
retcode = 0; |