1 |
/* |
/* |
2 |
* Copyright (C) 2003-2005 Anders Gavare. All rights reserved. |
* Copyright (C) 2003-2006 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_le.c,v 1.46 2005/11/13 00:14:09 debug Exp $ |
* $Id: dev_le.c,v 1.49 2006/01/01 13:17:16 debug Exp $ |
29 |
* |
* |
30 |
* LANCE ethernet, as used in DECstations. |
* LANCE ethernet, as used in DECstations. |
31 |
* |
* |
47 |
* |
* |
48 |
* TODO: Error conditions (such as when there are not enough receive |
* TODO: Error conditions (such as when there are not enough receive |
49 |
* buffers) are not emulated yet. |
* buffers) are not emulated yet. |
50 |
|
* |
51 |
|
* (Old bug, but probably still valid: "UDP packets that are too |
52 |
|
* large are not handled well by the Lance device.") |
53 |
*/ |
*/ |
54 |
|
|
55 |
#include <stdio.h> |
#include <stdio.h> |
233 |
{ |
{ |
234 |
int start_txp = d->txp; |
int start_txp = d->txp; |
235 |
uint16_t tx_descr[4]; |
uint16_t tx_descr[4]; |
236 |
int stp, enp, i, cur_packet_offset; |
int stp, enp, cur_packet_offset; |
237 |
|
size_t i; |
238 |
uint32_t bufaddr, buflen; |
uint32_t bufaddr, buflen; |
239 |
|
|
240 |
/* TODO: This is just a guess: */ |
/* TODO: This is just a guess: */ |
353 |
*/ |
*/ |
354 |
static void le_rx(struct net *net, struct le_data *d) |
static void le_rx(struct net *net, struct le_data *d) |
355 |
{ |
{ |
356 |
int i, start_rxp = d->rxp; |
int start_rxp = d->rxp; |
357 |
|
size_t i; |
358 |
uint16_t rx_descr[4]; |
uint16_t rx_descr[4]; |
359 |
uint32_t bufaddr, buflen; |
uint32_t bufaddr, buflen; |
360 |
|
|
392 |
|
|
393 |
/* Copy data from the packet into SRAM: */ |
/* Copy data from the packet into SRAM: */ |
394 |
for (i=0; i<buflen; i++) { |
for (i=0; i<buflen; i++) { |
395 |
if (d->rx_packet_offset + i >= d->rx_packet_len) |
if (d->rx_packet_offset+(ssize_t)i >= d->rx_packet_len) |
396 |
break; |
break; |
397 |
d->sram[(bufaddr + i) & (SRAM_SIZE-1)] = |
d->sram[(bufaddr + i) & (SRAM_SIZE-1)] = |
398 |
d->rx_packet[d->rx_packet_offset + i]; |
d->rx_packet[d->rx_packet_offset + i]; |
607 |
/* |
/* |
608 |
* dev_le_sram_access(): |
* dev_le_sram_access(): |
609 |
*/ |
*/ |
610 |
int dev_le_sram_access(struct cpu *cpu, struct memory *mem, |
DEVICE_ACCESS(le_sram) |
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
611 |
{ |
{ |
612 |
int i, retval; |
size_t i; |
613 |
|
int retval; |
614 |
struct le_data *d = extra; |
struct le_data *d = extra; |
615 |
|
|
616 |
#ifdef LE_DEBUG |
#ifdef LE_DEBUG |
655 |
/* |
/* |
656 |
* dev_le_access(): |
* dev_le_access(): |
657 |
*/ |
*/ |
658 |
int dev_le_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, |
DEVICE_ACCESS(le) |
|
unsigned char *data, size_t len, int writeflag, void *extra) |
|
659 |
{ |
{ |
660 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
661 |
int i, retval = 1; |
size_t i; |
662 |
|
int retval = 1; |
663 |
struct le_data *d = extra; |
struct le_data *d = extra; |
664 |
|
|
665 |
if (writeflag == MEM_WRITE) |
if (writeflag == MEM_WRITE) |
676 |
|
|
677 |
/* Read from station's ROM (ethernet address): */ |
/* Read from station's ROM (ethernet address): */ |
678 |
if (relative_addr >= 0xc0000 && relative_addr <= 0xfffff) { |
if (relative_addr >= 0xc0000 && relative_addr <= 0xfffff) { |
679 |
i = (relative_addr & 0xff) / 4; |
uint32_t a; |
680 |
i = d->rom[i & (ROM_SIZE-1)]; |
int j = (relative_addr & 0xff) / 4; |
681 |
|
a = d->rom[j & (ROM_SIZE-1)]; |
682 |
|
|
683 |
if (writeflag == MEM_READ) { |
if (writeflag == MEM_READ) { |
684 |
odata = (i << 24) + (i << 16) + (i << 8) + i; |
odata = (a << 24) + (a << 16) + (a << 8) + a; |
685 |
} else { |
} else { |
686 |
fatal("[ le: WRITE to ethernet addr (%08lx):", |
fatal("[ le: WRITE to ethernet addr (%08lx):", |
687 |
(long)relative_addr); |
(long)relative_addr); |