25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_ether.c,v 1.17 2006/12/30 13:30:57 debug Exp $ |
* $Id: dev_ether.c,v 1.19 2007/06/15 19:11:15 debug Exp $ |
29 |
|
* |
30 |
|
* COMMENT: A simple ethernet controller, for the test machines |
31 |
* |
* |
32 |
* Basic "ethernet" network device. This is a simple test device which can |
* Basic "ethernet" network device. This is a simple test device which can |
33 |
* be used to send and receive packets to/from a simulated ethernet network. |
* be used to send and receive packets to/from a simulated ethernet network. |
63 |
|
|
64 |
DEVICE_TICK(ether) |
DEVICE_TICK(ether) |
65 |
{ |
{ |
66 |
struct ether_data *d = (struct ether_data *) extra; |
struct ether_data *d = extra; |
67 |
int r = 0; |
int r = 0; |
68 |
|
|
69 |
d->status &= ~DEV_ETHER_STATUS_MORE_PACKETS_AVAILABLE; |
d->status &= ~DEV_ETHER_STATUS_MORE_PACKETS_AVAILABLE; |
81 |
|
|
82 |
DEVICE_ACCESS(ether_buf) |
DEVICE_ACCESS(ether_buf) |
83 |
{ |
{ |
84 |
struct ether_data *d = (struct ether_data *) extra; |
struct ether_data *d = extra; |
85 |
|
|
86 |
if (writeflag == MEM_WRITE) |
if (writeflag == MEM_WRITE) |
87 |
memcpy(d->buf + relative_addr, data, len); |
memcpy(d->buf + relative_addr, data, len); |
88 |
else |
else |
89 |
memcpy(data, d->buf + relative_addr, len); |
memcpy(data, d->buf + relative_addr, len); |
90 |
|
|
91 |
return 1; |
return 1; |
92 |
} |
} |
93 |
|
|
94 |
|
|
95 |
DEVICE_ACCESS(ether) |
DEVICE_ACCESS(ether) |
96 |
{ |
{ |
97 |
struct ether_data *d = (struct ether_data *) extra; |
struct ether_data *d = extra; |
98 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
99 |
unsigned char *incoming_ptr; |
unsigned char *incoming_ptr; |
100 |
int incoming_len; |
int incoming_len; |
200 |
|
|
201 |
DEVINIT(ether) |
DEVINIT(ether) |
202 |
{ |
{ |
203 |
struct ether_data *d = malloc(sizeof(struct ether_data)); |
struct ether_data *d; |
204 |
size_t nlen; |
size_t nlen; |
205 |
char *n1, *n2; |
char *n1, *n2; |
206 |
char tmp[50]; |
char tmp[50]; |
207 |
|
|
208 |
nlen = strlen(devinit->name) + 80; |
CHECK_ALLOCATION(d = malloc(sizeof(struct ether_data))); |
|
n1 = malloc(nlen); |
|
|
n2 = malloc(nlen); |
|
|
|
|
|
if (d == NULL || n1 == NULL || n2 == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
209 |
memset(d, 0, sizeof(struct ether_data)); |
memset(d, 0, sizeof(struct ether_data)); |
210 |
|
|
211 |
|
nlen = strlen(devinit->name) + 80; |
212 |
|
CHECK_ALLOCATION(n1 = malloc(nlen)); |
213 |
|
CHECK_ALLOCATION(n2 = malloc(nlen)); |
214 |
|
|
215 |
INTERRUPT_CONNECT(devinit->interrupt_path, d->irq); |
INTERRUPT_CONNECT(devinit->interrupt_path, d->irq); |
216 |
|
|
217 |
net_generate_unique_mac(devinit->machine, d->mac); |
net_generate_unique_mac(devinit->machine, d->mac); |
233 |
net_add_nic(devinit->machine->emul->net, d, d->mac); |
net_add_nic(devinit->machine->emul->net, d, d->mac); |
234 |
|
|
235 |
machine_add_tickfunction(devinit->machine, |
machine_add_tickfunction(devinit->machine, |
236 |
dev_ether_tick, d, DEV_ETHER_TICK_SHIFT, 0.0); |
dev_ether_tick, d, DEV_ETHER_TICK_SHIFT); |
237 |
|
|
238 |
return 1; |
return 1; |
239 |
} |
} |