68 #define LE_TICK_SHIFT 14 75 #define LE_MODE_LOOP 4 81 #define SRAM_SIZE (128*1024) 130 static uint64_t le_read_16bit(
struct le_data *d,
int addr)
144 static void le_write_16bit(
struct le_data *d,
int addr, uint16_t x)
158 static void le_chip_init(
struct le_data *d)
162 fatal(
"[ le: WARNING! initialization block address " 163 "not word aligned? ]\n");
182 debug(
"[ le: DEBUG: mode %04x ]\n", d->
mode);
183 debug(
"[ le: DEBUG: padr %016llx ]\n", (
long long)d->
padr);
184 debug(
"[ le: DEBUG: ladrf %016llx ]\n", (
long long)d->
ladrf);
185 debug(
"[ le: DEBUG: rdra %06llx ]\n", d->
rdra);
186 debug(
"[ le: DEBUG: rlen %3i ]\n", d->
rlen);
187 debug(
"[ le: DEBUG: tdra %06llx ]\n", d->
tdra);
188 debug(
"[ le: DEBUG: tlen %3i ]\n", d->
tlen);
233 int start_txp = d->
txp;
234 uint16_t tx_descr[4];
235 int stp, enp, cur_packet_offset;
237 uint32_t bufaddr, buflen;
244 tx_descr[0] = le_read_16bit(d, d->
tdra + d->
txp*8 + 0);
245 tx_descr[1] = le_read_16bit(d, d->
tdra + d->
txp*8 + 2);
246 tx_descr[2] = le_read_16bit(d, d->
tdra + d->
txp*8 + 4);
247 tx_descr[3] = le_read_16bit(d, d->
tdra + d->
txp*8 + 6);
249 bufaddr = tx_descr[0] + ((tx_descr[1] & 0xff) << 16);
250 stp = tx_descr[1] &
LE_STP? 1 : 0;
251 enp = tx_descr[1] &
LE_ENP? 1 : 0;
252 buflen = 4096 - (tx_descr[2] & 0xfff);
259 if (!(tx_descr[1] &
LE_OWN))
261 if ((tx_descr[2] & 0xf000) != 0xf000)
263 if (buflen < 12 || buflen > 1900) {
264 fatal(
"[ le_tx(): buflen = %i ]\n", buflen);
268 debug(
"[ le_tx(): descr %3i DUMP: 0x%04x 0x%04x 0x%04x 0x%04x " 269 "=> addr=0x%06x, len=%i bytes, STP=%i ENP=%i ]\n", d->
txp,
270 tx_descr[0], tx_descr[1], tx_descr[2], tx_descr[3],
271 bufaddr, buflen, stp, enp);
274 fatal(
"[ le_tx(): !stp but tx_packet == NULL ]\n");
279 fatal(
"[ le_tx(): stp but tx_packet != NULL ]\n");
299 for (i=0; i<buflen; i++) {
302 d->
tx_packet[cur_packet_offset + i] = ch;
321 tx_descr[1] &= ~LE_OWN;
324 le_write_16bit(d, d->
tdra + d->
txp*8 + 2, tx_descr[1]);
325 le_write_16bit(d, d->
tdra + d->
txp*8 + 4, tx_descr[2]);
326 le_write_16bit(d, d->
tdra + d->
txp*8 + 6, tx_descr[3]);
332 }
while (d->
txp != start_txp);
335 fatal(
"[ le_tx(): all TX descriptors used up? ]\n");
344 static void le_rx(
struct net *net,
struct le_data *d)
346 int start_rxp = d->
rxp;
348 uint16_t rx_descr[4];
349 uint32_t bufaddr, buflen;
356 rx_descr[0] = le_read_16bit(d, d->
rdra + d->
rxp*8 + 0);
357 rx_descr[1] = le_read_16bit(d, d->
rdra + d->
rxp*8 + 2);
358 rx_descr[2] = le_read_16bit(d, d->
rdra + d->
rxp*8 + 4);
359 rx_descr[3] = le_read_16bit(d, d->
rdra + d->
rxp*8 + 6);
361 bufaddr = rx_descr[0] + ((rx_descr[1] & 0xff) << 16);
362 buflen = 4096 - (rx_descr[2] & 0xfff);
369 if (!(rx_descr[1] &
LE_OWN))
371 if ((rx_descr[2] & 0xf000) != 0xf000)
373 if (buflen < 12 || buflen > 1900) {
374 fatal(
"[ le_rx(): buflen = %i ]\n", buflen);
378 debug(
"[ le_rx(): descr %3i DUMP: 0x%04x 0x%04x 0x%04x 0x%04x " 379 "=> addr=0x%06x, len=%i bytes ]\n", d->
rxp,
380 rx_descr[0], rx_descr[1], rx_descr[2], rx_descr[3],
384 for (i=0; i<buflen; i++) {
408 rx_descr[3] &= ~0xfff;
430 rx_descr[1] &= ~LE_OWN;
433 le_write_16bit(d, d->
rdra + d->
rxp*8 + 2, rx_descr[1]);
434 le_write_16bit(d, d->
rdra + d->
rxp*8 + 4, rx_descr[2]);
435 le_write_16bit(d, d->
rdra + d->
rxp*8 + 6, rx_descr[3]);
441 }
while (d->
rxp != start_rxp);
444 fatal(
"[ le_rx(): all RX descriptors used up? ]\n");
451 static void le_register_fix(
struct net *net,
struct le_data *d)
460 if (x != d->
reg[0]) {
461 debug(
"[ le reg[0] = 0x%04x ]\n", d->
reg[0]);
553 d->
reg[r] &= ~LE_BABL;
555 d->
reg[r] &= ~LE_CERR;
557 d->
reg[r] &= ~LE_MISS;
559 d->
reg[r] &= ~LE_MERR;
561 d->
reg[r] &= ~LE_RINT;
563 d->
reg[r] &= ~LE_TINT;
565 d->
reg[r] &= ~LE_IDON;
576 fatal(
"[ le: attempt to INIT before" 579 d->
reg[r] &= ~LE_STOP;
607 fatal(
"[ le_sram: write to addr 0x%06x: ", (
int)relative_addr);
608 for (i=0; i<
len; i++)
619 debug(
"[ le: read from SRAM offset 0x%05x:",
621 for (i=0; i<
len; i++)
629 debug(
"[ le: write to SRAM offset 0x%05x:",
631 for (i=0; i<
len; i++)
647 uint64_t idata = 0, odata = 0;
656 fatal(
"[ le: write to addr 0x%06x: ", (
int)relative_addr);
657 for (i=0; i<
len; i++)
664 if (relative_addr >= 0xc0000 && relative_addr <= 0xfffff) {
666 int j = (relative_addr & 0xff) / 4;
670 odata = (a << 24) + (a << 16) + (a << 8) + a;
672 fatal(
"[ le: WRITE to ethernet addr (%08lx):",
673 (
long)relative_addr);
674 for (i=0; i<
len; i++)
684 switch (relative_addr) {
691 debug(
"[ le: read from register 0x%02x: 0x" 701 debug(
"[ le: write to register 0x%02x: 0x" 718 debug(
"[ le: read from register select: " 719 "0x%02x ]\n", (
int)odata);
722 debug(
"[ le: write to register select: " 723 "0x%02x ]\n", (
int)idata);
726 fatal(
"[ le: WARNING! register select %i " 733 fatal(
"[ le: read from UNIMPLEMENTED addr 0x%06x ]\n",
736 fatal(
"[ le: write to UNIMPLEMENTED addr 0x%06x: " 737 "0x%08x ]\n", (
int)relative_addr, (
int)idata);
745 fatal(
"[ le: read from addr 0x%06x: 0x%08x ]\n",
746 relative_addr, odata);
750 dev_le_tick(
cpu, extra);
767 memset(d, 0,
sizeof(
struct le_data));
797 d->
rom[24] = d->
rom[28] = 0xff;
798 d->
rom[25] = d->
rom[29] = 0x00;
799 d->
rom[26] = d->
rom[30] = 0x55;
800 d->
rom[27] = d->
rom[31] = 0xaa;
803 SRAM_SIZE, dev_le_sram_access, (
void *)d,
808 snprintf(name2, nlen,
"le [%02x:%02x:%02x:%02x:%02x:%02x]",
809 d->rom[0], d->rom[1], d->rom[2], d->rom[3], d->rom[4], d->rom[5]);
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
void net_ethernet_tx(struct net *net, void *extra, unsigned char *packet, int len)
void fatal(const char *fmt,...)
int dev_le_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, unsigned char *data, size_t len, int writeflag, void *)
void le_register_write(struct le_data *d, int r, uint32_t x)
void dev_le_init(struct machine *machine, struct memory *mem, uint64_t baseaddr, uint64_t buf_start, uint64_t buf_end, const char *irq_path, int len)
int net_ethernet_rx(struct net *net, void *extra, unsigned char **packetp, int *lenp)
#define CHECK_ALLOCATION(ptr)
void net_add_nic(struct net *net, void *extra, unsigned char *macaddr)
#define DM_READS_HAVE_NO_SIDE_EFFECTS
#define INTERRUPT_ASSERT(istruct)
#define DM_DYNTRANS_WRITE_OK
void net_generate_unique_mac(struct machine *, unsigned char *macbuf)
unsigned char * tx_packet
int net_ethernet_rx_avail(struct net *net, void *extra)
#define INTERRUPT_CONNECT(name, istruct)
unsigned char * rx_packet
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
void machine_add_tickfunction(struct machine *machine, void(*func)(struct cpu *, void *), void *extra, int clockshift)
#define INTERRUPT_DEASSERT(istruct)
uint16_t reg[N_REGISTERS]