| 154 |
#define LEDMA_MAXADDR (LEDMA_REGS * 4 - 1) |
#define LEDMA_MAXADDR (LEDMA_REGS * 4 - 1) |
| 155 |
|
|
| 156 |
typedef struct LANCEState { |
typedef struct LANCEState { |
| 157 |
NetDriverState *nd; |
VLANClientState *vc; |
| 158 |
|
uint8_t macaddr[6]; /* init mac address */ |
| 159 |
uint32_t leptr; |
uint32_t leptr; |
| 160 |
uint16_t addr; |
uint16_t addr; |
| 161 |
uint16_t regs[LE_NREGS]; |
uint16_t regs[LE_NREGS]; |
| 170 |
static void lance_reset(void *opaque) |
static void lance_reset(void *opaque) |
| 171 |
{ |
{ |
| 172 |
LANCEState *s = opaque; |
LANCEState *s = opaque; |
| 173 |
memcpy(s->phys, s->nd->macaddr, 6); |
memcpy(s->phys, s->macaddr, 6); |
| 174 |
s->rxptr = 0; |
s->rxptr = 0; |
| 175 |
s->txptr = 0; |
s->txptr = 0; |
| 176 |
memset(s->regs, 0, LE_NREGS * 2); |
memset(s->regs, 0, LE_NREGS * 2); |
| 281 |
}; |
}; |
| 282 |
|
|
| 283 |
|
|
|
/* return the max buffer size if the LANCE can receive more data */ |
|
|
static int lance_can_receive(void *opaque) |
|
|
{ |
|
|
LANCEState *s = opaque; |
|
|
uint32_t dmaptr = s->leptr + s->ledmaregs[3]; |
|
|
struct lance_init_block *ib; |
|
|
int i; |
|
|
uint8_t temp8; |
|
|
|
|
|
if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP) |
|
|
return 0; |
|
|
|
|
|
ib = (void *) iommu_translate(dmaptr); |
|
|
|
|
|
for (i = 0; i < RX_RING_SIZE; i++) { |
|
|
cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp8, 1); |
|
|
if (temp8 == (LE_R1_OWN)) { |
|
|
DPRINTF("can receive %d\n", RX_BUFF_SIZE); |
|
|
return RX_BUFF_SIZE; |
|
|
} |
|
|
} |
|
|
DPRINTF("cannot receive\n"); |
|
|
return 0; |
|
|
} |
|
|
|
|
| 284 |
#define MIN_BUF_SIZE 60 |
#define MIN_BUF_SIZE 60 |
| 285 |
|
|
| 286 |
static void lance_receive(void *opaque, const uint8_t *buf, int size) |
static void lance_receive(void *opaque, const uint8_t *buf, int size) |
| 344 |
temp16 = (~temp16) + 1; |
temp16 = (~temp16) + 1; |
| 345 |
cpu_physical_memory_read((uint32_t)&ib->tx_buf[i], pkt_buf, temp16); |
cpu_physical_memory_read((uint32_t)&ib->tx_buf[i], pkt_buf, temp16); |
| 346 |
DPRINTF("sending packet, len %d\n", temp16); |
DPRINTF("sending packet, len %d\n", temp16); |
| 347 |
qemu_send_packet(s->nd, pkt_buf, temp16); |
qemu_send_packet(s->vc, pkt_buf, temp16); |
| 348 |
temp8 = LE_T1_POK; |
temp8 = LE_T1_POK; |
| 349 |
cpu_physical_memory_write((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp8, 1); |
cpu_physical_memory_write((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp8, 1); |
| 350 |
s->txptr = (s->txptr + 1) & TX_RING_MOD_MASK; |
s->txptr = (s->txptr + 1) & TX_RING_MOD_MASK; |
| 419 |
return 0; |
return 0; |
| 420 |
} |
} |
| 421 |
|
|
| 422 |
void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr) |
void lance_init(NICInfo *nd, int irq, uint32_t leaddr, uint32_t ledaddr) |
| 423 |
{ |
{ |
| 424 |
LANCEState *s; |
LANCEState *s; |
| 425 |
int lance_io_memory, ledma_io_memory; |
int lance_io_memory, ledma_io_memory; |
| 428 |
if (!s) |
if (!s) |
| 429 |
return; |
return; |
| 430 |
|
|
|
s->nd = nd; |
|
| 431 |
s->irq = irq; |
s->irq = irq; |
| 432 |
|
|
| 433 |
lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, s); |
lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, s); |
| 436 |
ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, s); |
ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, s); |
| 437 |
cpu_register_physical_memory(ledaddr, 16, ledma_io_memory); |
cpu_register_physical_memory(ledaddr, 16, ledma_io_memory); |
| 438 |
|
|
| 439 |
|
memcpy(s->macaddr, nd->macaddr, 6); |
| 440 |
|
|
| 441 |
lance_reset(s); |
lance_reset(s); |
| 442 |
qemu_add_read_packet(nd, lance_can_receive, lance_receive, s); |
|
| 443 |
|
s->vc = qemu_new_vlan_client(nd->vlan, lance_receive, s); |
| 444 |
|
|
| 445 |
|
snprintf(s->vc->info_str, sizeof(s->vc->info_str), |
| 446 |
|
"lance macaddr=%02x:%02x:%02x:%02x:%02x:%02x", |
| 447 |
|
s->macaddr[0], |
| 448 |
|
s->macaddr[1], |
| 449 |
|
s->macaddr[2], |
| 450 |
|
s->macaddr[3], |
| 451 |
|
s->macaddr[4], |
| 452 |
|
s->macaddr[5]); |
| 453 |
|
|
| 454 |
register_savevm("lance", leaddr, 1, lance_save, lance_load, s); |
register_savevm("lance", leaddr, 1, lance_save, lance_load, s); |
| 455 |
qemu_register_reset(lance_reset, s); |
qemu_register_reset(lance_reset, s); |
| 456 |
} |
} |