1 |
|
/* |
2 |
|
* ether.cpp - SheepShaver Ethernet Device Driver (DLPI) |
3 |
|
* |
4 |
< |
* SheepShaver (C) 1997-2004 Marc Hellwig and Christian Bauer |
4 |
> |
* SheepShaver (C) 1997-2005 Marc Hellwig and Christian Bauer |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
27 |
|
#include <string.h> |
28 |
|
|
29 |
|
#include "sysdeps.h" |
30 |
+ |
#include "cpu_emulation.h" |
31 |
|
#include "ether.h" |
32 |
|
#include "ether_defs.h" |
33 |
|
#include "macos_util.h" |
33 |
– |
#include "cpu_emulation.h" |
34 |
|
#include "emul_op.h" |
35 |
|
#include "main.h" |
36 |
|
|
37 |
|
#define DEBUG 0 |
38 |
|
#include "debug.h" |
39 |
|
|
40 |
+ |
#if DIRECT_ADDRESSING |
41 |
+ |
#warning "This code is not direct addressing clean" |
42 |
+ |
#endif |
43 |
|
|
44 |
|
// Packet types |
45 |
|
enum { |
89 |
|
|
90 |
|
void AddMulticast(uint8 *addr) |
91 |
|
{ |
92 |
< |
multicast_node *n = (multicast_node *)Mac_sysalloc(sizeof(multicast_node)); |
92 |
> |
multicast_node *n = (multicast_node *)Mac2HostAddr(Mac_sysalloc(sizeof(multicast_node))); |
93 |
|
memcpy(n->addr, addr, kEnetPhysicalAddressLength); |
94 |
|
n->next = multicast_list; |
95 |
|
multicast_list = n; |
109 |
|
while (q) { |
110 |
|
if (q->next == p) { |
111 |
|
q->next = p->next; |
112 |
< |
Mac_sysfree(p); |
112 |
> |
Mac_sysfree(Host2MacAddr((uint8 *)p)); |
113 |
|
return; |
114 |
|
} |
115 |
|
q = q->next; |
321 |
|
ether_driver_opened = false; |
322 |
|
|
323 |
|
// Import functions from OTKernelLib |
324 |
< |
allocb_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\006allocb"); |
324 |
> |
allocb_tvect = FindLibSymbol("\013OTKernelLib", "\006allocb"); |
325 |
|
D(bug("allocb TVECT at %08lx\n", allocb_tvect)); |
326 |
|
if (allocb_tvect == 0) |
327 |
|
return false; |
328 |
< |
freeb_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\005freeb"); |
328 |
> |
freeb_tvect = FindLibSymbol("\013OTKernelLib", "\005freeb"); |
329 |
|
D(bug("freeb TVECT at %08lx\n", freeb_tvect)); |
330 |
|
if (freeb_tvect == 0) |
331 |
|
return false; |
332 |
< |
freemsg_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\007freemsg"); |
332 |
> |
freemsg_tvect = FindLibSymbol("\013OTKernelLib", "\007freemsg"); |
333 |
|
D(bug("freemsg TVECT at %08lx\n", freemsg_tvect)); |
334 |
|
if (freemsg_tvect == 0) |
335 |
|
return false; |
336 |
< |
copyb_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\005copyb"); |
336 |
> |
copyb_tvect = FindLibSymbol("\013OTKernelLib", "\005copyb"); |
337 |
|
D(bug("copyb TVECT at %08lx\n", copyb_tvect)); |
338 |
|
if (copyb_tvect == 0) |
339 |
|
return false; |
340 |
< |
dupmsg_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\006dupmsg"); |
340 |
> |
dupmsg_tvect = FindLibSymbol("\013OTKernelLib", "\006dupmsg"); |
341 |
|
D(bug("dupmsg TVECT at %08lx\n", dupmsg_tvect)); |
342 |
|
if (dupmsg_tvect == 0) |
343 |
|
return false; |
344 |
< |
getq_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\004getq"); |
344 |
> |
getq_tvect = FindLibSymbol("\013OTKernelLib", "\004getq"); |
345 |
|
D(bug("getq TVECT at %08lx\n", getq_tvect)); |
346 |
|
if (getq_tvect == 0) |
347 |
|
return false; |
348 |
< |
putq_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\004putq"); |
348 |
> |
putq_tvect = FindLibSymbol("\013OTKernelLib", "\004putq"); |
349 |
|
D(bug("putq TVECT at %08lx\n", putq_tvect)); |
350 |
|
if (putq_tvect == 0) |
351 |
|
return false; |
352 |
< |
putnext_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\007putnext"); |
352 |
> |
putnext_tvect = FindLibSymbol("\013OTKernelLib", "\007putnext"); |
353 |
|
D(bug("putnext TVECT at %08lx\n", putnext_tvect)); |
354 |
|
if (putnext_tvect == 0) |
355 |
|
return false; |
356 |
< |
putnextctl1_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\013putnextctl1"); |
356 |
> |
putnextctl1_tvect = FindLibSymbol("\013OTKernelLib", "\013putnextctl1"); |
357 |
|
D(bug("putnextctl1 TVECT at %08lx\n", putnextctl1_tvect)); |
358 |
|
if (putnextctl1_tvect == 0) |
359 |
|
return false; |
360 |
< |
canputnext_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\012canputnext"); |
360 |
> |
canputnext_tvect = FindLibSymbol("\013OTKernelLib", "\012canputnext"); |
361 |
|
D(bug("canputnext TVECT at %08lx\n", canputnext_tvect)); |
362 |
|
if (canputnext_tvect == 0) |
363 |
|
return false; |
364 |
< |
qreply_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\006qreply"); |
364 |
> |
qreply_tvect = FindLibSymbol("\013OTKernelLib", "\006qreply"); |
365 |
|
D(bug("qreply TVECT at %08lx\n", qreply_tvect)); |
366 |
|
if (qreply_tvect == 0) |
367 |
|
return false; |
368 |
< |
flushq_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\006flushq"); |
368 |
> |
flushq_tvect = FindLibSymbol("\013OTKernelLib", "\006flushq"); |
369 |
|
D(bug("flushq TVECT at %08lx\n", flushq_tvect)); |
370 |
|
if (flushq_tvect == 0) |
371 |
|
return false; |
372 |
< |
msgdsize_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\010msgdsize"); |
372 |
> |
msgdsize_tvect = FindLibSymbol("\013OTKernelLib", "\010msgdsize"); |
373 |
|
D(bug("msgdsize TVECT at %08lx\n", msgdsize_tvect)); |
374 |
|
if (msgdsize_tvect == 0) |
375 |
|
return false; |
376 |
< |
otenterint_tvect = (uint32)FindLibSymbol("\017OTKernelUtilLib", "\020OTEnterInterrupt"); |
376 |
> |
otenterint_tvect = FindLibSymbol("\017OTKernelUtilLib", "\020OTEnterInterrupt"); |
377 |
|
D(bug("OTEnterInterrupt TVECT at %08lx\n", otenterint_tvect)); |
378 |
|
if (otenterint_tvect == 0) |
379 |
|
return false; |
380 |
< |
otleaveint_tvect = (uint32)FindLibSymbol("\017OTKernelUtilLib", "\020OTLeaveInterrupt"); |
380 |
> |
otleaveint_tvect = FindLibSymbol("\017OTKernelUtilLib", "\020OTLeaveInterrupt"); |
381 |
|
D(bug("OTLeaveInterrupt TVECT at %08lx\n", otleaveint_tvect)); |
382 |
|
if (otleaveint_tvect == 0) |
383 |
|
return false; |
384 |
< |
mi_open_comm_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\014mi_open_comm"); |
384 |
> |
mi_open_comm_tvect = FindLibSymbol("\013OTKernelLib", "\014mi_open_comm"); |
385 |
|
D(bug("mi_open_comm TVECT at %08lx\n", mi_open_comm_tvect)); |
386 |
|
if (mi_open_comm_tvect == 0) |
387 |
|
return false; |
388 |
< |
mi_close_comm_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\015mi_close_comm"); |
388 |
> |
mi_close_comm_tvect = FindLibSymbol("\013OTKernelLib", "\015mi_close_comm"); |
389 |
|
D(bug("mi_close_comm TVECT at %08lx\n", mi_close_comm_tvect)); |
390 |
|
if (mi_close_comm_tvect == 0) |
391 |
|
return false; |
392 |
< |
mi_next_ptr_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\013mi_next_ptr"); |
392 |
> |
mi_next_ptr_tvect = FindLibSymbol("\013OTKernelLib", "\013mi_next_ptr"); |
393 |
|
D(bug("mi_next_ptr TVECT at %08lx\n", mi_next_ptr_tvect)); |
394 |
|
if (mi_next_ptr_tvect == 0) |
395 |
|
return false; |
398 |
|
dlpi_stream_list = NULL; |
399 |
|
|
400 |
|
// Ask add-on for ethernet hardware address |
401 |
< |
AO_get_ethernet_address(hardware_address); |
401 |
> |
AO_get_ethernet_address(Host2MacAddr(hardware_address)); |
402 |
|
|
403 |
|
// Yes, we're open |
404 |
|
ether_driver_opened = true; |
479 |
|
|
480 |
|
// Disable all registered multicast addresses |
481 |
|
while (the_stream->multicast_list) { |
482 |
< |
AO_disable_multicast(the_stream->multicast_list->addr); |
482 |
> |
AO_disable_multicast(Host2MacAddr(the_stream->multicast_list->addr)); |
483 |
|
the_stream->RemoveMulticast(the_stream->multicast_list->addr); |
484 |
|
} |
485 |
|
the_stream->multicast_list = NULL; |
929 |
|
OTCopy48BitAddress(hardware_address, enetHeader->fSourceAddr); |
930 |
|
|
931 |
|
// Tell add-on to transmit packet |
932 |
< |
AO_transmit_packet(mp); |
932 |
> |
AO_transmit_packet(Host2MacAddr((uint8 *)mp)); |
933 |
|
freemsg(mp); |
934 |
|
} |
935 |
|
|
1101 |
|
} |
1102 |
|
} |
1103 |
|
|
1104 |
+ |
void ether_dispatch_packet(uint32 p, uint32 size) |
1105 |
+ |
{ |
1106 |
+ |
// Wrap packet in message block |
1107 |
+ |
num_rx_packets++; |
1108 |
+ |
mblk_t *mp; |
1109 |
+ |
if ((mp = allocb(size, 0)) != NULL) { |
1110 |
+ |
D(bug(" packet data at %p\n", (void *)mp->b_rptr)); |
1111 |
+ |
Mac2Host_memcpy(mp->b_rptr, p, size); |
1112 |
+ |
mp->b_wptr += size; |
1113 |
+ |
ether_packet_received(mp); |
1114 |
+ |
} else { |
1115 |
+ |
D(bug("WARNING: Cannot allocate mblk for received packet\n")); |
1116 |
+ |
num_rx_no_mem++; |
1117 |
+ |
} |
1118 |
+ |
} |
1119 |
+ |
|
1120 |
|
|
1121 |
|
/* |
1122 |
|
* Build and send an error acknowledge |
1558 |
|
} |
1559 |
|
|
1560 |
|
// Tell add-on to enable multicast address |
1561 |
< |
AO_enable_multicast(reqaddr); |
1561 |
> |
AO_enable_multicast(Host2MacAddr((uint8 *)reqaddr)); |
1562 |
|
|
1563 |
|
// Add new address to multicast list |
1564 |
< |
uint8 *addr = (uint8 *)Mac_sysalloc(kEnetPhysicalAddressLength); |
1564 |
> |
uint8 *addr = Mac2HostAddr(Mac_sysalloc(kEnetPhysicalAddressLength)); |
1565 |
|
OTCopy48BitAddress(reqaddr, addr); |
1566 |
|
the_stream->AddMulticast(addr); |
1567 |
|
|
1599 |
|
|
1600 |
|
// Found, then remove |
1601 |
|
the_stream->RemoveMulticast(addr); |
1602 |
< |
Mac_sysfree(addr); |
1602 |
> |
Mac_sysfree(Host2MacAddr(addr)); |
1603 |
|
|
1604 |
|
// Tell add-on to disable multicast address |
1605 |
< |
AO_disable_multicast(reqaddr); |
1605 |
> |
AO_disable_multicast(Host2MacAddr((uint8 *)reqaddr)); |
1606 |
|
|
1607 |
|
// No longer check multicast packets if no multicast addresses are registered |
1608 |
|
if (the_stream->multicast_list == NULL) |
1655 |
|
if ((mp = build_tx_packet_header(the_stream, mp, false)) != NULL) |
1656 |
|
transmit_packet(mp); |
1657 |
|
} |
1658 |
+ |
|
1659 |
+ |
|
1660 |
+ |
/* |
1661 |
+ |
* Ethernet packet allocator |
1662 |
+ |
*/ |
1663 |
+ |
|
1664 |
+ |
#if SIZEOF_VOID_P != 4 || REAL_ADDRESSING == 0 |
1665 |
+ |
static uint32 ether_packet = 0; // Ethernet packet (cached allocation) |
1666 |
+ |
static uint32 n_ether_packets = 0; // Number of ethernet packets allocated so far (should be at most 1) |
1667 |
+ |
|
1668 |
+ |
EthernetPacket::EthernetPacket() |
1669 |
+ |
{ |
1670 |
+ |
++n_ether_packets; |
1671 |
+ |
if (ether_packet && n_ether_packets == 1) |
1672 |
+ |
packet = ether_packet; |
1673 |
+ |
else { |
1674 |
+ |
packet = Mac_sysalloc(1516); |
1675 |
+ |
assert(packet != 0); |
1676 |
+ |
Mac_memset(packet, 0, 1516); |
1677 |
+ |
if (ether_packet == 0) |
1678 |
+ |
ether_packet = packet; |
1679 |
+ |
} |
1680 |
+ |
} |
1681 |
+ |
|
1682 |
+ |
EthernetPacket::~EthernetPacket() |
1683 |
+ |
{ |
1684 |
+ |
--n_ether_packets; |
1685 |
+ |
if (packet != ether_packet) |
1686 |
+ |
Mac_sysfree(packet); |
1687 |
+ |
if (n_ether_packets > 0) { |
1688 |
+ |
bug("WARNING: Nested allocation of ethernet packets!\n"); |
1689 |
+ |
} |
1690 |
+ |
} |
1691 |
+ |
#endif |