ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/ether.cpp
(Generate patch)

Comparing SheepShaver/src/ether.cpp (file contents):
Revision 1.3 by gbeauche, 2004-05-10T12:05:43Z vs.
Revision 1.9 by gbeauche, 2005-07-03T22:02:01Z

# Line 1 | Line 1
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
# Line 27 | Line 27
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"
34  
35   #define DEBUG 0
36   #include "debug.h"
37  
40
38   // Packet types
39   enum {
40          kPktDIX                         = 0,
# Line 86 | Line 83 | struct DLPIStream {
83  
84          void AddMulticast(uint8 *addr)
85          {
86 <                multicast_node *n = new multicast_node;
86 >                multicast_node *n = (multicast_node *)Mac2HostAddr(Mac_sysalloc(sizeof(multicast_node)));
87                  memcpy(n->addr, addr, kEnetPhysicalAddressLength);
88                  n->next = multicast_list;
89                  multicast_list = n;
# Line 106 | Line 103 | struct DLPIStream {
103                  while (q) {
104                          if (q->next == p) {
105                                  q->next = p->next;
106 <                                delete p;
106 >                                Mac_sysfree(Host2MacAddr((uint8 *)p));
107                                  return;
108                          }
109                          q = q->next;
# Line 180 | Line 177 | typedef mblk_t *(*allocb_ptr)(size_t siz
177   static uint32 allocb_tvect = 0;
178   mblk_t *allocb(size_t arg1, int arg2)
179   {
180 <        return (mblk_t *)CallMacOS2(allocb_ptr, allocb_tvect, arg1, arg2);
180 >        return (mblk_t *)Mac2HostAddr((uint32)CallMacOS2(allocb_ptr, allocb_tvect, arg1, arg2));
181   }
182   typedef void (*freeb_ptr)(mblk_t *);
183   static uint32 freeb_tvect = 0;
# Line 198 | Line 195 | typedef mblk_t *(*copyb_ptr)(mblk_t *);
195   static uint32 copyb_tvect = 0;
196   static inline mblk_t *copyb(mblk_t *arg1)
197   {
198 <        return (mblk_t *)CallMacOS1(copyb_ptr, copyb_tvect, arg1);
198 >        return (mblk_t *)Mac2HostAddr((uint32)CallMacOS1(copyb_ptr, copyb_tvect, arg1));
199   }
200   typedef mblk_t *(*dupmsg_ptr)(mblk_t *);
201   static uint32 dupmsg_tvect = 0;
202   static inline mblk_t *dupmsg(mblk_t *arg1)
203   {
204 <        return (mblk_t *)CallMacOS1(dupmsg_ptr, dupmsg_tvect, arg1);
204 >        return (mblk_t *)Mac2HostAddr((uint32)CallMacOS1(dupmsg_ptr, dupmsg_tvect, arg1));
205   }
206   typedef mblk_t *(*getq_ptr)(queue_t *);
207   static uint32 getq_tvect = 0;
208   static inline mblk_t *getq(queue_t *arg1)
209   {
210 <        return (mblk_t *)CallMacOS1(getq_ptr, getq_tvect, arg1);
210 >        return (mblk_t *)Mac2HostAddr((uint32)CallMacOS1(getq_ptr, getq_tvect, arg1));
211   }
212   typedef int (*putq_ptr)(queue_t *, mblk_t *);
213   static uint32 putq_tvect = 0;
# Line 282 | Line 279 | typedef DLPIStream *(*mi_next_ptr_ptr)(D
279   static uint32 mi_next_ptr_tvect = 0;
280   static inline DLPIStream *mi_next_ptr(DLPIStream *arg1)
281   {
282 <        return (DLPIStream *)CallMacOS1(mi_next_ptr_ptr, mi_next_ptr_tvect, arg1);
282 >        return (DLPIStream *)Mac2HostAddr((uint32)CallMacOS1(mi_next_ptr_ptr, mi_next_ptr_tvect, arg1));
283   }
284 <
284 > #ifdef USE_ETHER_FULL_DRIVER
285 > typedef void (*ether_dispatch_packet_ptr)(uint32 p, uint32 size);
286 > static uint32 ether_dispatch_packet_tvect = 0;
287 > #endif
288  
289   // Prototypes
290   static void ether_ioctl(DLPIStream *the_stream, queue_t* q, mblk_t* mp);
# Line 308 | Line 308 | static void DLPI_unit_data(DLPIStream *t
308   *  Initialize ethernet stream module
309   */
310  
311 < uint8 InitStreamModule(void *theID)
311 > static uint8 InitStreamModuleImpl(void *theID)
312   {
313          D(bug("InitStreamModule\n"));
314  
# Line 318 | Line 318 | uint8 InitStreamModule(void *theID)
318          ether_driver_opened = false;
319  
320          // Import functions from OTKernelLib
321 <        allocb_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\006allocb");
321 >        allocb_tvect = FindLibSymbol("\013OTKernelLib", "\006allocb");
322          D(bug("allocb TVECT at %08lx\n", allocb_tvect));
323          if (allocb_tvect == 0)
324                  return false;
325 <        freeb_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\005freeb");
325 >        freeb_tvect = FindLibSymbol("\013OTKernelLib", "\005freeb");
326          D(bug("freeb TVECT at %08lx\n", freeb_tvect));
327          if (freeb_tvect == 0)
328                  return false;
329 <        freemsg_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\007freemsg");
329 >        freemsg_tvect = FindLibSymbol("\013OTKernelLib", "\007freemsg");
330          D(bug("freemsg TVECT at %08lx\n", freemsg_tvect));
331          if (freemsg_tvect == 0)
332                  return false;
333 <        copyb_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\005copyb");
333 >        copyb_tvect = FindLibSymbol("\013OTKernelLib", "\005copyb");
334          D(bug("copyb TVECT at %08lx\n", copyb_tvect));
335          if (copyb_tvect == 0)
336                  return false;
337 <        dupmsg_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\006dupmsg");
337 >        dupmsg_tvect = FindLibSymbol("\013OTKernelLib", "\006dupmsg");
338          D(bug("dupmsg TVECT at %08lx\n", dupmsg_tvect));
339          if (dupmsg_tvect == 0)
340                  return false;
341 <        getq_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\004getq");
341 >        getq_tvect = FindLibSymbol("\013OTKernelLib", "\004getq");
342          D(bug("getq TVECT at %08lx\n", getq_tvect));
343          if (getq_tvect == 0)
344                  return false;
345 <        putq_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\004putq");
345 >        putq_tvect = FindLibSymbol("\013OTKernelLib", "\004putq");
346          D(bug("putq TVECT at %08lx\n", putq_tvect));
347          if (putq_tvect == 0)
348                  return false;
349 <        putnext_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\007putnext");
349 >        putnext_tvect = FindLibSymbol("\013OTKernelLib", "\007putnext");
350          D(bug("putnext TVECT at %08lx\n", putnext_tvect));
351          if (putnext_tvect == 0)
352                  return false;
353 <        putnextctl1_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\013putnextctl1");
353 >        putnextctl1_tvect = FindLibSymbol("\013OTKernelLib", "\013putnextctl1");
354          D(bug("putnextctl1 TVECT at %08lx\n", putnextctl1_tvect));
355          if (putnextctl1_tvect == 0)
356                  return false;
357 <        canputnext_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\012canputnext");
357 >        canputnext_tvect = FindLibSymbol("\013OTKernelLib", "\012canputnext");
358          D(bug("canputnext TVECT at %08lx\n", canputnext_tvect));
359          if (canputnext_tvect == 0)
360                  return false;
361 <        qreply_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\006qreply");
361 >        qreply_tvect = FindLibSymbol("\013OTKernelLib", "\006qreply");
362          D(bug("qreply TVECT at %08lx\n", qreply_tvect));
363          if (qreply_tvect == 0)
364                  return false;
365 <        flushq_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\006flushq");
365 >        flushq_tvect = FindLibSymbol("\013OTKernelLib", "\006flushq");
366          D(bug("flushq TVECT at %08lx\n", flushq_tvect));
367          if (flushq_tvect == 0)
368                  return false;
369 <        msgdsize_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\010msgdsize");
369 >        msgdsize_tvect = FindLibSymbol("\013OTKernelLib", "\010msgdsize");
370          D(bug("msgdsize TVECT at %08lx\n", msgdsize_tvect));
371          if (msgdsize_tvect == 0)
372                  return false;
373 <        otenterint_tvect = (uint32)FindLibSymbol("\017OTKernelUtilLib", "\020OTEnterInterrupt");
373 >        otenterint_tvect = FindLibSymbol("\017OTKernelUtilLib", "\020OTEnterInterrupt");
374          D(bug("OTEnterInterrupt TVECT at %08lx\n", otenterint_tvect));
375          if (otenterint_tvect == 0)
376                  return false;
377 <        otleaveint_tvect = (uint32)FindLibSymbol("\017OTKernelUtilLib", "\020OTLeaveInterrupt");
377 >        otleaveint_tvect = FindLibSymbol("\017OTKernelUtilLib", "\020OTLeaveInterrupt");
378          D(bug("OTLeaveInterrupt TVECT at %08lx\n", otleaveint_tvect));
379          if (otleaveint_tvect == 0)
380                  return false;
381 <        mi_open_comm_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\014mi_open_comm");
381 >        mi_open_comm_tvect = FindLibSymbol("\013OTKernelLib", "\014mi_open_comm");
382          D(bug("mi_open_comm TVECT at %08lx\n", mi_open_comm_tvect));
383          if (mi_open_comm_tvect == 0)
384                  return false;
385 <        mi_close_comm_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\015mi_close_comm");
385 >        mi_close_comm_tvect = FindLibSymbol("\013OTKernelLib", "\015mi_close_comm");
386          D(bug("mi_close_comm TVECT at %08lx\n", mi_close_comm_tvect));
387          if (mi_close_comm_tvect == 0)
388                  return false;
389 <        mi_next_ptr_tvect = (uint32)FindLibSymbol("\013OTKernelLib", "\013mi_next_ptr");
389 >        mi_next_ptr_tvect = FindLibSymbol("\013OTKernelLib", "\013mi_next_ptr");
390          D(bug("mi_next_ptr TVECT at %08lx\n", mi_next_ptr_tvect));
391          if (mi_next_ptr_tvect == 0)
392                  return false;
393  
394 + #ifndef USE_ETHER_FULL_DRIVER
395          // Initialize stream list (which might be leftover)
396          dlpi_stream_list = NULL;
397  
398          // Ask add-on for ethernet hardware address
399 <        AO_get_ethernet_address(hardware_address);
399 >        AO_get_ethernet_address(Host2MacAddr(hardware_address));
400 > #endif
401  
402          // Yes, we're open
403          ether_driver_opened = true;
404          return true;
405   }
406  
407 + uint8 InitStreamModule(void *theID)
408 + {
409 +        // Common initialization code
410 +        bool net_open = InitStreamModuleImpl(theID);
411 +
412 +        // Call InitStreamModule() in native side
413 + #ifdef BUILD_ETHER_FULL_DRIVER
414 +        extern bool NativeInitStreamModule(void *);
415 +        if (!NativeInitStreamModule((void *)ether_dispatch_packet))
416 +                net_open = false;
417 + #endif
418 +
419 +        // Import functions from the Ethernet driver
420 + #ifdef USE_ETHER_FULL_DRIVER
421 +        ether_dispatch_packet_tvect = (uintptr)theID;
422 +        D(bug("ether_dispatch_packet TVECT at %08lx\n", ether_dispatch_packet_tvect));
423 +        if (ether_dispatch_packet_tvect == 0)
424 +                net_open = false;
425 + #endif
426 +
427 +        return net_open;
428 + }
429 +
430  
431   /*
432   *  Terminate ethernet stream module
433   */
434  
435 < void TerminateStreamModule(void)
435 > static void TerminateStreamModuleImpl(void)
436   {
437          D(bug("TerminateStreamModule\n"));
438  
439 + #ifndef USE_ETHER_FULL_DRIVER
440          // This happens sometimes. I don't know why.
441          if (dlpi_stream_list != NULL)
442                  printf("FATAL: TerminateStreamModule() called, but streams still open\n");
443 + #endif
444  
445          // Sorry, we're closed
446          ether_driver_opened = false;
447   }
448  
449 + void TerminateStreamModule(void)
450 + {
451 +        // Common termination code
452 +        TerminateStreamModuleImpl();
453 +
454 +        // Call TerminateStreamModule() in native side
455 + #ifdef BUILD_ETHER_FULL_DRIVER
456 +        extern void NativeTerminateStreamModule(void);
457 +        NativeTerminateStreamModule();
458 + #endif
459 + }
460 +
461  
462   /*
463   *  Open new stream
# Line 476 | Line 515 | int ether_close(queue_t *rdq, int flag,
515  
516          // Disable all registered multicast addresses
517          while (the_stream->multicast_list) {
518 <                AO_disable_multicast(the_stream->multicast_list->addr);
518 >                AO_disable_multicast(Host2MacAddr(the_stream->multicast_list->addr));
519                  the_stream->RemoveMulticast(the_stream->multicast_list->addr);
520          }
521          the_stream->multicast_list = NULL;
# Line 926 | Line 965 | static void transmit_packet(mblk_t *mp)
965          OTCopy48BitAddress(hardware_address, enetHeader->fSourceAddr);
966  
967          // Tell add-on to transmit packet
968 <        AO_transmit_packet(mp);
968 >        AO_transmit_packet(Host2MacAddr((uint8 *)mp));
969          freemsg(mp);
970   }
971  
# Line 1098 | Line 1137 | type_found:
1137          }
1138   }
1139  
1140 + void ether_dispatch_packet(uint32 p, uint32 size)
1141 + {
1142 + #ifdef USE_ETHER_FULL_DRIVER
1143 +        // Call handler from the Ethernet driver
1144 +        D(bug("ether_dispatch_packet\n"));
1145 +        D(bug(" packet data at %p, %d bytes\n", p, size));
1146 +        CallMacOS2(ether_dispatch_packet_ptr, ether_dispatch_packet_tvect, p, size);
1147 + #else
1148 +        // Wrap packet in message block
1149 +        num_rx_packets++;
1150 +        mblk_t *mp;
1151 +        if ((mp = allocb(size, 0)) != NULL) {
1152 +                D(bug(" packet data at %p\n", (void *)mp->b_rptr));
1153 +                Mac2Host_memcpy(mp->b_rptr, p, size);
1154 +                mp->b_wptr += size;
1155 +                ether_packet_received(mp);
1156 +        } else {
1157 +                D(bug("WARNING: Cannot allocate mblk for received packet\n"));
1158 +                num_rx_no_mem++;
1159 +        }
1160 + #endif
1161 + }
1162 +
1163  
1164   /*
1165   *  Build and send an error acknowledge
# Line 1539 | Line 1601 | static void DLPI_enable_multi(DLPIStream
1601          }
1602  
1603          // Tell add-on to enable multicast address
1604 <        AO_enable_multicast(reqaddr);
1604 >        AO_enable_multicast(Host2MacAddr((uint8 *)reqaddr));
1605  
1606          // Add new address to multicast list
1607 <        uint8 *addr = new uint8[kEnetPhysicalAddressLength];
1607 >        uint8 *addr = Mac2HostAddr(Mac_sysalloc(kEnetPhysicalAddressLength));
1608          OTCopy48BitAddress(reqaddr, addr);
1609          the_stream->AddMulticast(addr);
1610  
# Line 1580 | Line 1642 | static void DLPI_disable_multi(DLPIStrea
1642  
1643          // Found, then remove
1644          the_stream->RemoveMulticast(addr);
1645 <        delete addr;
1645 >        Mac_sysfree(Host2MacAddr(addr));
1646  
1647          // Tell add-on to disable multicast address
1648 <        AO_disable_multicast(reqaddr);
1648 >        AO_disable_multicast(Host2MacAddr((uint8 *)reqaddr));
1649          
1650          // No longer check multicast packets if no multicast addresses are registered
1651          if (the_stream->multicast_list == NULL)
# Line 1636 | Line 1698 | static void DLPI_unit_data(DLPIStream *t
1698          if ((mp = build_tx_packet_header(the_stream, mp, false)) != NULL)
1699                  transmit_packet(mp);
1700   }
1701 +
1702 +
1703 + /*
1704 + *  Ethernet packet allocator
1705 + */
1706 +
1707 + #if SIZEOF_VOID_P != 4 || REAL_ADDRESSING == 0
1708 + static uint32 ether_packet = 0;                 // Ethernet packet (cached allocation)
1709 + static uint32 n_ether_packets = 0;              // Number of ethernet packets allocated so far (should be at most 1)
1710 +
1711 + EthernetPacket::EthernetPacket()
1712 + {
1713 +        ++n_ether_packets;
1714 +        if (ether_packet && n_ether_packets == 1)
1715 +                packet = ether_packet;
1716 +        else {
1717 +                packet = Mac_sysalloc(1516);
1718 +                assert(packet != 0);
1719 +                Mac_memset(packet, 0, 1516);
1720 +                if (ether_packet == 0)
1721 +                        ether_packet = packet;
1722 +        }
1723 + }
1724 +
1725 + EthernetPacket::~EthernetPacket()
1726 + {
1727 +        --n_ether_packets;
1728 +        if (packet != ether_packet)
1729 +                Mac_sysfree(packet);
1730 +        if (n_ether_packets > 0) {
1731 +                bug("WARNING: Nested allocation of ethernet packets!\n");
1732 +        }
1733 + }
1734 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines