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

Comparing BasiliskII/src/Windows/ether_windows.cpp (file contents):
Revision 1.3 by gbeauche, 2005-03-19T17:43:03Z vs.
Revision 1.5 by gbeauche, 2006-04-23T15:36:51Z

# Line 49 | Line 49
49   #include "debug.h"
50  
51  
52 + // Ethernet device types
53 + enum {
54 +        NET_IF_B2ETHER,
55 +        NET_IF_ROUTER,
56 +        NET_IF_FAKE,
57 + };
58 +
59   // Options
60   bool ether_use_permanent = true;
61   static int16 ether_multi_mode = ETHER_MULTICAST_MAC;
# Line 58 | Line 65 | HANDLE ether_th;
65   unsigned int ether_tid;
66   HANDLE ether_th1;
67   HANDLE ether_th2;
68 <
69 <
70 < // Need to fake a NIC if there is none but the router module is activated.
71 < bool ether_fake = false;
68 > static int net_if_type = -1;                            // Ethernet device type
69 > #ifdef SHEEPSHAVER
70 > static bool net_open = false;                           // Flag: initialization succeeded, network device open
71 > uint8 ether_addr[6];                                            // Our Ethernet address
72 > #endif
73  
74   // These are protected by queue_csection
75   // Controls transfer for read thread to feed thread
76   static CRITICAL_SECTION queue_csection;
77 < typedef struct _queue_t {
77 > typedef struct _win_queue_t {
78          uint8 *buf;
79          int sz;
80 < } queue_t;
80 > } win_queue_t;
81   #define MAX_QUEUE_ITEMS 1024
82 < static queue_t queue[MAX_QUEUE_ITEMS];
82 > static win_queue_t queue[MAX_QUEUE_ITEMS];
83   static int queue_head = 0;
84   static int queue_inx = 0;
85   static bool wait_request = true;
# Line 129 | Line 137 | static HANDLE int_sig = 0;
137   static HANDLE int_sig2 = 0;
138   static HANDLE int_send_now = 0;
139  
132 static char edevice[512];
133
134
140   // Prototypes
141   static WINAPI unsigned int ether_thread_feed_int(void *arg);
142   static WINAPI unsigned int ether_thread_get_packets_nt(void *arg);
# Line 141 | Line 146 | static void final_queue(void);
146   static bool allocate_read_packets(void);
147   static void free_read_packets(void);
148   static void free_write_packets(void);
149 + static int16 ether_do_add_multicast(uint8 *addr);
150 + static int16 ether_do_del_multicast(uint8 *addr);
151 + static int16 ether_do_write(uint32 arg);
152 + static void ether_do_interrupt(void);
153  
154  
155   /*
# Line 173 | Line 182 | bool ether_init(void)
182   {
183          char str[256];
184  
176        // Initialize NAT-Router
177        router_init();
178
185          // Do nothing if no Ethernet device specified
186          const char *name = PrefsFindString("ether");
187 <        if (name)
188 <                strcpy(edevice, name);
187 >        if (name == NULL)
188 >                return false;
189  
190 <        bool there_is_a_router = PrefsFindBool("routerenabled");
190 >        ether_multi_mode = PrefsFindInt32("ethermulticastmode");
191 >        ether_use_permanent = PrefsFindBool("etherpermanentaddress");
192  
193 <        if (!name || !*name) {
194 <                if( there_is_a_router ) {
195 <                        strcpy( edevice, "None" );
196 <                        ether_fake = true;
197 <                } else {
198 <                        return false;
192 <                }
193 <        }
193 >        // Determine Ethernet device type
194 >        net_if_type = -1;
195 >        if (strcmp(name, "router") == 0)
196 >                net_if_type = NET_IF_ROUTER;
197 >        else
198 >                net_if_type = NET_IF_B2ETHER;
199  
200 <        ether_use_permanent = PrefsFindBool("etherpermanentaddress");
201 <        ether_multi_mode = PrefsFindInt32("ethermulticastmode");
200 >        // Initialize NAT-Router
201 >        if (net_if_type == NET_IF_ROUTER) {
202 >                if (!router_init())
203 >                        net_if_type = NET_IF_FAKE;
204 >        }
205  
206          // Open ethernet device
207 <        if(ether_fake) {
208 <                memcpy( ether_addr, router_mac_addr, 6 );
209 <                D(bug("Fake ethernet address (same as router) %02x %02x %02x %02x %02x %02x\r\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
210 <        } else {
211 <                fd = PacketOpenAdapter( name, ether_multi_mode );
207 >        const char *dev_name;
208 >        switch (net_if_type) {
209 >        case NET_IF_B2ETHER:
210 >                dev_name = PrefsFindString("etherguid");
211 >                break;
212 >        }
213 >        if (net_if_type == NET_IF_B2ETHER) {
214 >                if (dev_name == NULL) {
215 >                        WarningAlert("No ethernet device GUID specified. Ethernet is not available.");
216 >                        goto open_error;
217 >                }
218 >
219 >                fd = PacketOpenAdapter( dev_name, ether_multi_mode );
220                  if (!fd) {
221 <                        sprintf(str, "Could not open ethernet adapter %s.", name);
221 >                        sprintf(str, "Could not open ethernet adapter %s.", dev_name);
222                          WarningAlert(str);
223                          goto open_error;
224                  }
225  
226                  // Get Ethernet address
227                  if(!PacketGetMAC(fd,ether_addr,ether_use_permanent)) {
228 <                        sprintf(str, "Could not get hardware address of device %s. Ethernet is not available.", name);
228 >                        sprintf(str, "Could not get hardware address of device %s. Ethernet is not available.", dev_name);
229                          WarningAlert(str);
230                          goto open_error;
231                  }
232 <                D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\r\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
232 >                D(bug("Real ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
233  
234                  const char *ether_fake_address;
235                  ether_fake_address = PrefsFindString("etherfakeaddress");
# Line 225 | Line 241 | bool ether_init(void)
241                                  sm[3] = ether_fake_address[i*2+1];
242                                  ether_addr[i] = (uint8)strtoul(sm,0,0);
243                          }
244 <                        D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\r\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
244 >                        D(bug("Fake ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
245                  }
246          }
247 +        else {
248 +                memcpy( ether_addr, router_mac_addr, 6 );
249 +                D(bug("Fake ethernet address (same as router) %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
250 +        }
251  
252          // Start packet reception thread
253          int_ack = CreateSemaphore( 0, 0, 1, NULL);
# Line 285 | Line 305 | bool ether_init(void)
305  
306          ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, &ether_tid );
307          if (!ether_th) {
308 <                D(bug("Failed to create ethernet thread\r\n"));
308 >                D(bug("Failed to create ethernet thread\n"));
309                  goto open_error;
310          }
311          thread_active = true;
292 #if 0
293        SetThreadPriority( ether_th, threads[THREAD_ETHER].priority_running );
294        SetThreadAffinityMask( ether_th, threads[THREAD_ETHER].affinity_mask );
295 #endif
312  
313          unsigned int dummy;
314          ether_th2 = (HANDLE)_beginthreadex( 0, 0, ether_thread_get_packets_nt, 0, 0, &dummy );
299 #if 0
300        SetThreadPriority( ether_th2, threads[THREAD_ETHER].priority_running );
301        SetThreadAffinityMask( ether_th2, threads[THREAD_ETHER].affinity_mask );
302 #endif
303
315          ether_th1 = (HANDLE)_beginthreadex( 0, 0, ether_thread_write_packets, 0, 0, &dummy );
305 #if 0
306        SetThreadPriority( ether_th1, threads[THREAD_ETHER].priority_running );
307        SetThreadAffinityMask( ether_th1, threads[THREAD_ETHER].affinity_mask );
308 #endif
316  
317          // Everything OK
318          return true;
# Line 328 | Line 335 | bool ether_init(void)
335                  int_send_now = 0;
336                  thread_active = false;
337          }
338 <        if(!ether_fake) {
338 >        if(net_if_type == NET_IF_B2ETHER) {
339                  PacketCloseAdapter(fd);
340          }
341          fd = 0;
# Line 342 | Line 349 | bool ether_init(void)
349  
350   void ether_exit(void)
351   {
352 <        D(bug("EtherExit\r\n"));
352 >        D(bug("EtherExit\n"));
353  
354 <        // Take them down in a controlled way.
354 >        // Stop reception thread
355          thread_active = false;
356  
350        // _asm int 3
351
352        D(bug("Closing ethernet device %s\r\n",edevice));
353
354        if(!*edevice) return;
355
357          if(int_ack) ReleaseSemaphore(int_ack,1,NULL);
358          if(int_sig) ReleaseSemaphore(int_sig,1,NULL);
359          if(int_sig2) ReleaseSemaphore(int_sig2,1,NULL);
360          if(int_send_now) ReleaseSemaphore(int_send_now,1,NULL);
361  
362 <        D(bug("CancelIO if needed\r\n"));
362 >        D(bug("CancelIO if needed\n"));
363          if (fd && fd->hFile && pfnCancelIo)
364                  pfnCancelIo(fd->hFile);
365  
366          // Wait max 2 secs to shut down pending io. After that, kill them.
367 <        D(bug("Wait delay\r\n"));
367 >        D(bug("Wait delay\n"));
368          for( int i=0; i<10; i++ ) {
369                  if(!thread_active_1 && !thread_active_2 && !thread_active_3) break;
370                  Sleep(200);
371          }
372  
373          if(thread_active_1) {
374 <                D(bug("Ether killing ether_th1\r\n"));
374 >                D(bug("Ether killing ether_th1\n"));
375                  if(ether_th1) TerminateThread(ether_th1,0);
376                  thread_active_1 = false;
377          }
378          if(thread_active_2) {
379 <                D(bug("Ether killing ether_th2\r\n"));
379 >                D(bug("Ether killing ether_th2\n"));
380                  if(ether_th2) TerminateThread(ether_th2,0);
381                  thread_active_2 = false;
382          }
383          if(thread_active_3) {
384 <                D(bug("Ether killing thread\r\n"));
384 >                D(bug("Ether killing thread\n"));
385                  if(ether_th) TerminateThread(ether_th,0);
386                  thread_active_3 = false;
387          }
# Line 389 | Line 390 | void ether_exit(void)
390          ether_th2 = 0;
391          ether_th = 0;
392  
393 <        D(bug("Closing semaphores\r\n"));
393 >        D(bug("Closing semaphores\n"));
394          if(int_ack) {
395                  CloseHandle(int_ack);
396                  int_ack = 0;
# Line 414 | Line 415 | void ether_exit(void)
415          }
416  
417          // Remove all protocols
418 <        D(bug("Removing protocols\r\n"));
418 >        D(bug("Removing protocols\n"));
419          NetProtocol *p = prot_list;
420          while (p) {
421                  NetProtocol *next = p->next;
# Line 423 | Line 424 | void ether_exit(void)
424          }
425          prot_list = 0;
426  
427 <        D(bug("Deleting sections\r\n"));
427 >        D(bug("Deleting sections\n"));
428          DeleteCriticalSection( &fetch_csection );
429          DeleteCriticalSection( &queue_csection );
430          DeleteCriticalSection( &send_csection );
431          DeleteCriticalSection( &wpool_csection );
432  
433 <        D(bug("Freeing read packets\r\n"));
433 >        D(bug("Freeing read packets\n"));
434          free_read_packets();
435  
436 <        D(bug("Freeing write packets\r\n"));
436 >        D(bug("Freeing write packets\n"));
437          free_write_packets();
438  
439 <        D(bug("Finalizing queue\r\n"));
439 >        D(bug("Finalizing queue\n"));
440          final_queue();
441  
442 <        D(bug("Stopping router\r\n"));
443 <        router_final();
442 >        if (net_if_type == NET_IF_ROUTER) {
443 >                D(bug("Stopping router\n"));
444 >                router_final();
445 >        }
446 >
447 >        D(bug("EtherExit done\n"));
448 > }
449 >
450 >
451 > /*
452 > *  Glue around low-level implementation
453 > */
454 >
455 > #ifdef SHEEPSHAVER
456 > // Error codes
457 > enum {
458 >        eMultiErr               = -91,
459 >        eLenErr                 = -92,
460 >        lapProtErr              = -94,
461 >        excessCollsns   = -95
462 > };
463 >
464 > // Initialize ethernet
465 > void EtherInit(void)
466 > {
467 >        net_open = false;
468 >
469 >        // Do nothing if the user disabled the network
470 >        if (PrefsFindBool("nonet"))
471 >                return;
472 >
473 >        net_open = ether_init();
474 > }
475 >
476 > // Exit ethernet
477 > void EtherExit(void)
478 > {
479 >        ether_exit();
480 >        net_open = false;
481 > }
482 >
483 > // Get ethernet hardware address
484 > void AO_get_ethernet_address(uint32 arg)
485 > {
486 >        uint8 *addr = Mac2HostAddr(arg);
487 >        if (net_open)
488 >                OTCopy48BitAddress(ether_addr, addr);
489 >        else {
490 >                addr[0] = 0x12;
491 >                addr[1] = 0x34;
492 >                addr[2] = 0x56;
493 >                addr[3] = 0x78;
494 >                addr[4] = 0x9a;
495 >                addr[5] = 0xbc;
496 >        }
497 >        D(bug("AO_get_ethernet_address: got address %02x%02x%02x%02x%02x%02x\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]));
498 > }
499 >
500 > // Add multicast address
501 > void AO_enable_multicast(uint32 addr)
502 > {
503 >        if (net_open)
504 >                ether_do_add_multicast(Mac2HostAddr(addr));
505 > }
506 >
507 > // Disable multicast address
508 > void AO_disable_multicast(uint32 addr)
509 > {
510 >        if (net_open)
511 >                ether_do_del_multicast(Mac2HostAddr(addr));
512 > }
513 >
514 > // Transmit one packet
515 > void AO_transmit_packet(uint32 mp)
516 > {
517 >        if (net_open) {
518 >                switch (ether_do_write(mp)) {
519 >                case noErr:
520 >                        num_tx_packets++;
521 >                        break;
522 >                case excessCollsns:
523 >                        num_tx_buffer_full++;
524 >                        break;
525 >                }
526 >        }
527 > }
528 >
529 > // Copy packet data from message block to linear buffer
530 > static inline int ether_arg_to_buffer(uint32 mp, uint8 *p)
531 > {
532 >        return ether_msgb_to_buffer(mp, p);
533 > }
534 >
535 > // Ethernet interrupt
536 > void EtherIRQ(void)
537 > {
538 >        D(bug("EtherIRQ\n"));
539 >        num_ether_irq++;
540 >
541 >        OTEnterInterrupt();
542 >        ether_do_interrupt();
543 >        OTLeaveInterrupt();
544 >
545 >        // Acknowledge interrupt to reception thread
546 >        D(bug(" EtherIRQ done\n"));
547 >        ReleaseSemaphore(int_ack,1,NULL);
548 > }
549 > #else
550 > // Add multicast address
551 > int16 ether_add_multicast(uint32 pb)
552 > {
553 >        return ether_do_add_multicast(Mac2HostAddr(pb + eMultiAddr));
554 > }
555 >
556 > // Disable multicast address
557 > int16 ether_del_multicast(uint32 pb)
558 > {
559 >        return ether_do_del_multicast(Mac2HostAddr(pb + eMultiAddr));
560 > }
561 >
562 > // Transmit one packet
563 > int16 ether_write(uint32 wds)
564 > {
565 >        return ether_do_write(wds);
566 > }
567 >
568 > // Copy packet data from WDS to linear buffer
569 > static inline int ether_arg_to_buffer(uint32 wds, uint8 *p)
570 > {
571 >        return ether_wds_to_buffer(wds, p);
572 > }
573 >
574 > // Dispatch packet to protocol handler
575 > static void ether_dispatch_packet(uint32 packet, uint32 length)
576 > {
577 >        // Get packet type
578 >        uint16 type = ReadMacInt16(packet + 12);
579 >
580 >        // Look for protocol
581 >        NetProtocol *prot = find_protocol(type);
582 >        if (prot == NULL)
583 >                return;
584 >
585 >        // No default handler
586 >        if (prot->handler == 0)
587 >                return;
588 >
589 >        // Copy header to RHA
590 >        Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14);
591 >        D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12)));
592 >
593 >        // Call protocol handler
594 >        M68kRegisters r;
595 >        r.d[0] = type;                                                          // Packet type
596 >        r.d[1] = length - 14;                                           // Remaining packet length (without header, for ReadPacket)
597 >        r.a[0] = packet + 14;                                           // Pointer to packet (Mac address, for ReadPacket)
598 >        r.a[3] = ether_data + ed_RHA + 14;                      // Pointer behind header in RHA
599 >        r.a[4] = ether_data + ed_ReadPacket;            // Pointer to ReadPacket/ReadRest routines
600 >        D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
601 >        Execute68k(prot->handler, &r);
602 > }
603 >
604 > // Ethernet interrupt
605 > void EtherInterrupt(void)
606 > {
607 >        D(bug("EtherIRQ\n"));
608 >        ether_do_interrupt();
609  
610 <        D(bug("EtherExit done\r\n"));
610 >        // Acknowledge interrupt to reception thread
611 >        D(bug(" EtherIRQ done\n"));
612 >        ReleaseSemaphore(int_ack,1,NULL);
613   }
614 + #endif
615  
616  
617   /*
# Line 451 | Line 620 | void ether_exit(void)
620  
621   void ether_reset(void)
622   {
623 <        D(bug("EtherReset\r\n"));
623 >        D(bug("EtherReset\n"));
624  
625          // Remove all protocols
626          NetProtocol *p = prot_list;
# Line 468 | Line 637 | void ether_reset(void)
637   *  Add multicast address
638   */
639  
640 < int16 ether_add_multicast(uint32 pb)
640 > static int16 ether_do_add_multicast(uint8 *addr)
641   {
642 <        D(bug("ether_add_multicast\r\n"));
642 >        D(bug("ether_add_multicast\n"));
643  
644          // We wouldn't need to do this
645          // if(ether_multi_mode != ETHER_MULTICAST_MAC) return noErr;
646  
647 <        if (!ether_fake && !PacketAddMulticast( fd, Mac2HostAddr(pb + eMultiAddr))) {
648 <                D(bug("WARNING: couldn't enable multicast address\r\n"));
649 <                return eMultiErr;
650 <        } else {
651 <                D(bug("ether_add_multicast: noErr\r\n"));
647 >        switch (net_if_type) {
648 >        case NET_IF_B2ETHER:
649 >                if (!PacketAddMulticast( fd, addr)) {
650 >                        D(bug("WARNING: couldn't enable multicast address\n"));
651 >                        return eMultiErr;
652 >                }
653 >        default:
654 >                D(bug("ether_add_multicast: noErr\n"));
655                  return noErr;
656          }
657   }
# Line 489 | Line 661 | int16 ether_add_multicast(uint32 pb)
661   *  Delete multicast address
662   */
663  
664 < int16 ether_del_multicast(uint32 pb)
664 > int16 ether_do_del_multicast(uint8 *addr)
665   {
666 <        D(bug("ether_del_multicast\r\n"));
666 >        D(bug("ether_del_multicast\n"));
667  
668          // We wouldn't need to do this
669          // if(ether_multi_mode != ETHER_MULTICAST_MAC) return noErr;
670  
671 <        if (!ether_fake && !PacketDelMulticast( fd, Mac2HostAddr(pb + eMultiAddr))) {
672 <                D(bug("WARNING: couldn't disable multicast address\r\n"));
673 <                return eMultiErr;
674 <        } else
671 >        switch (net_if_type) {
672 >        case NET_IF_B2ETHER:
673 >                if (!PacketDelMulticast( fd, addr)) {
674 >                        D(bug("WARNING: couldn't disable multicast address\n"));
675 >                        return eMultiErr;
676 >                }
677 >        default:
678                  return noErr;
679 +        }
680   }
681  
682  
# Line 510 | Line 686 | int16 ether_del_multicast(uint32 pb)
686  
687   int16 ether_attach_ph(uint16 type, uint32 handler)
688   {
689 <        D(bug("ether_attach_ph type=0x%x, handler=0x%x\r\n",(int)type,handler));
689 >        D(bug("ether_attach_ph type=0x%x, handler=0x%x\n",(int)type,handler));
690  
691          // Already attached?
692          NetProtocol *p = find_protocol(type);
693          if (p != NULL) {
694 <                D(bug("ether_attach_ph: lapProtErr\r\n"));
694 >                D(bug("ether_attach_ph: lapProtErr\n"));
695                  return lapProtErr;
696          } else {
697                  // No, create and attach
# Line 524 | Line 700 | int16 ether_attach_ph(uint16 type, uint3
700                  p->type = type;
701                  p->handler = handler;
702                  prot_list = p;
703 <                D(bug("ether_attach_ph: noErr\r\n"));
703 >                D(bug("ether_attach_ph: noErr\n"));
704                  return noErr;
705          }
706   }
# Line 536 | Line 712 | int16 ether_attach_ph(uint16 type, uint3
712  
713   int16 ether_detach_ph(uint16 type)
714   {
715 <        D(bug("ether_detach_ph type=%08lx\r\n",(int)type));
715 >        D(bug("ether_detach_ph type=%08lx\n",(int)type));
716  
717          NetProtocol *p = find_protocol(type);
718          if (p != NULL) {
# Line 569 | Line 745 | static void dump_packet( uint8 *packet,
745          if(length > 256) length = 256;
746  
747          for (int i=0; i<length; i++) {
748 <                sprintf(sm,"%02x", (int)packet[i]);
748 >                sprintf(sm," %02x", (int)packet[i]);
749                  strcat( buf, sm );
750          }
751 <        strcat( buf, "\r\n" );
751 >        strcat( buf, "\n" );
752          bug(buf);
753   }
754   #endif
# Line 629 | Line 805 | static void free_write_packets( void )
805          int i = 0;
806          while(write_packet_pool) {
807                  next = write_packet_pool->next;
808 <                D(bug("Freeing write packet %ld\r\n",++i));
808 >                D(bug("Freeing write packet %ld\n",++i));
809                  PacketFreePacket(write_packet_pool);
810                  write_packet_pool = next;
811          }
# Line 640 | Line 816 | void recycle_write_packet( LPPACKET Pack
816          EnterCriticalSection( &wpool_csection );
817          Packet->next = write_packet_pool;
818          write_packet_pool = Packet;
819 <        D(bug("Pool size after recycling = %ld\r\n",get_write_packet_pool_sz()));
819 >        D(bug("Pool size after recycling = %ld\n",get_write_packet_pool_sz()));
820          LeaveCriticalSection( &wpool_csection );
821   }
822  
# Line 665 | Line 841 | static LPPACKET get_write_packet( UINT l
841                  Packet = PacketAllocatePacket(fd,len);
842          }
843  
844 <        D(bug("Pool size after get wr packet = %ld\r\n",get_write_packet_pool_sz()));
844 >        D(bug("Pool size after get wr packet = %ld\n",get_write_packet_pool_sz()));
845  
846          LeaveCriticalSection( &wpool_csection );
847  
# Line 678 | Line 854 | static unsigned int ether_thread_write_p
854  
855          thread_active_1 = true;
856  
857 <        D(bug("ether_thread_write_packets start\r\n"));
857 >        D(bug("ether_thread_write_packets start\n"));
858  
859          while(thread_active) {
860                  // must be alertable, otherwise write completion is never called
861                  WaitForSingleObjectEx(int_send_now,INFINITE,TRUE);
862                  while( thread_active && (Packet = get_send_head()) != 0 ) {
863 <                        if(m_router_enabled && router_write_packet((uint8 *)Packet->Buffer, Packet->Length)) {
864 <                                Packet->bIoComplete = TRUE;
865 <                                recycle_write_packet(Packet);
866 <                        } else if(ether_fake) {
863 >                        switch (net_if_type) {
864 >                        case NET_IF_ROUTER:
865 >                                if(router_write_packet((uint8 *)Packet->Buffer, Packet->Length)) {
866 >                                        Packet->bIoComplete = TRUE;
867 >                                        recycle_write_packet(Packet);
868 >                                }
869 >                                break;
870 >                        case NET_IF_FAKE:
871                                  Packet->bIoComplete = TRUE;
872                                  recycle_write_packet(Packet);
873 <                        } else if(!PacketSendPacket( fd, Packet, FALSE, TRUE )) {
874 <                                // already recycled if async
873 >                                break;
874 >                        case NET_IF_B2ETHER:
875 >                                if(!PacketSendPacket( fd, Packet, FALSE, TRUE )) {
876 >                                        // already recycled if async
877 >                                }
878 >                                break;
879                          }
880                  }
881          }
882  
883 <        D(bug("ether_thread_write_packets exit\r\n"));
883 >        D(bug("ether_thread_write_packets exit\n"));
884  
885          thread_active_1 = false;
886  
# Line 707 | Line 891 | static BOOL write_packet( uint8 *packet,
891   {
892          LPPACKET Packet;
893  
894 <        D(bug("write_packet\r\n"));
894 >        D(bug("write_packet\n"));
895  
896          Packet = get_write_packet(len);
897          if(Packet) {
# Line 728 | Line 912 | static BOOL write_packet( uint8 *packet,
912          }
913   }
914  
915 < int16 ether_write(uint32 wds)
915 > static int16 ether_do_write(uint32 arg)
916   {
917 <        D(bug("ether_write\r\n"));
734 <
735 <        // Set source address
736 <        uint32 hdr = ReadMacInt32(wds + 2);
737 <        memcpy(Mac2HostAddr(hdr + 6), ether_addr, 6);
917 >        D(bug("ether_write\n"));
918  
919          // Copy packet to buffer
920          uint8 packet[1514], *p = packet;
921 <        int len = 0;
742 <        for (;;) {
743 <                uint16 w = (uint16)ReadMacInt16(wds);
744 <                if (w == 0)
745 <                        break;
746 <                memcpy(p, Mac2HostAddr(ReadMacInt32(wds + 2)), w);
747 <                len += w;
748 <                p += w;
749 <                wds += 6;
750 <        }
921 >        int len = ether_arg_to_buffer(arg, p);
922  
923          if(len > 1514) {
924 <                D(bug("illegal packet length: %d\r\n",len));
924 >                D(bug("illegal packet length: %d\n",len));
925                  return eLenErr;
926          } else {
927   #if MONITOR
# Line 761 | Line 932 | int16 ether_write(uint32 wds)
932  
933          // Transmit packet
934          if (!write_packet(packet, len)) {
935 <                D(bug("WARNING: couldn't transmit packet\r\n"));
935 >                D(bug("WARNING: couldn't transmit packet\n"));
936                  return excessCollsns;
937          } else {
938                  // It's up to the protocol drivers to do the error checking. Even if the
# Line 795 | Line 966 | void enqueue_packet( uint8 *buf, int sz
966   {
967          EnterCriticalSection( &queue_csection );
968          if(queue[queue_inx].sz > 0) {
969 <                D(bug("ethernet queue full, packet dropped\r\n"));
969 >                D(bug("ethernet queue full, packet dropped\n"));
970          } else {
971                  if(sz > 1514) sz = 1514;
972                  queue[queue_inx].sz = sz;
# Line 832 | Line 1003 | static void trigger_queue(void)
1003   {
1004          EnterCriticalSection( &queue_csection );
1005          if( queue[queue_head].sz > 0 ) {
1006 <                D(bug(" packet received, triggering Ethernet interrupt\r\n"));
1006 >                D(bug(" packet received, triggering Ethernet interrupt\n"));
1007                  SetInterruptFlag(INTFLAG_ETHER);
1008                  TriggerInterrupt();
1009                  // of course can't wait here.
# Line 881 | Line 1052 | VOID CALLBACK packet_read_completion(
1052                                  if(count == pending_packet_sz[j] &&
1053                                     memcmp(pending_packet[j],lpPacket->Buffer,count) == 0)
1054                                  {
1055 <                                        D(bug("packet_read_completion discarding own packet.\r\n"));
1055 >                                        D(bug("packet_read_completion discarding own packet.\n"));
1056                                          dwNumberOfBytesTransfered = 0;
1057  
1058                                          j = (j+1) & (~(MAX_ECHO-1));
1059                                          if(j != echo_count) {
1060 <                                                D(bug("Wow, this fix made some good after all...\r\n"));
1060 >                                                D(bug("Wow, this fix made some good after all...\n"));
1061                                          }
1062  
1063                                          break;
1064                                  }
1065                          }
1066                          if(dwNumberOfBytesTransfered) {
1067 <                                if(!m_router_enabled || !router_read_packet((uint8 *)lpPacket->Buffer, dwNumberOfBytesTransfered)) {
1067 >                                if(net_if_type != NET_IF_ROUTER || !router_read_packet((uint8 *)lpPacket->Buffer, dwNumberOfBytesTransfered)) {
1068                                          enqueue_packet( (LPBYTE)lpPacket->Buffer, dwNumberOfBytesTransfered );
1069                                  }
1070                          }
# Line 937 | Line 1108 | static bool allocate_read_packets(void)
1108          for( int i=0; i<PACKET_POOL_COUNT; i++ ) {
1109                  packets[i] = PacketAllocatePacket(fd,1514);
1110                  if(!packets[i]) {
1111 <                        D(bug("allocate_read_packets: out of memory\r\n"));
1111 >                        D(bug("allocate_read_packets: out of memory\n"));
1112                          return(false);
1113                  }
1114          }
# Line 958 | Line 1129 | static unsigned int ether_thread_get_pac
1129  
1130          thread_active_2 = true;
1131  
1132 <        D(bug("ether_thread_get_packets_nt start\r\n"));
1132 >        D(bug("ether_thread_get_packets_nt start\n"));
1133  
1134          // Wait for packets to arrive.
1135          // Obey the golden rules; keep the reads pending.
1136          while(thread_active) {
1137  
1138 <                if(!ether_fake) {
1139 <                        D(bug("Pending reads\r\n"));
1138 >                if(net_if_type == NET_IF_B2ETHER) {
1139 >                        D(bug("Pending reads\n"));
1140                          for( i=0; thread_active && i<PACKET_POOL_COUNT; i++ ) {
1141                                  if(packets[i]->free) {
1142                                          packets[i]->free = FALSE;
1143                                          if(PacketReceivePacket(fd,packets[i],FALSE)) {
1144                                                  if(packets[i]->bIoComplete) {
1145 <                                                        D(bug("Early io completion...\r\n"));
1145 >                                                        D(bug("Early io completion...\n"));
1146                                                          packet_read_completion(
1147                                                                  ERROR_SUCCESS,
1148                                                                  packets[i]->BytesReceived,
# Line 986 | Line 1157 | static unsigned int ether_thread_get_pac
1157                  }
1158  
1159                  if(thread_active && has_no_completed_io()) {
1160 <                        D(bug("Waiting for int_sig2\r\n"));
1160 >                        D(bug("Waiting for int_sig2\n"));
1161                          // "problem": awakens twice in a row. Fix if you increase the pool size.
1162                          WaitForSingleObjectEx(int_sig2,INFINITE,TRUE);
1163                  }
1164          }
1165  
1166 <        D(bug("ether_thread_get_packets_nt exit\r\n"));
1166 >        D(bug("ether_thread_get_packets_nt exit\n"));
1167  
1168          thread_active_2 = false;
1169  
# Line 1005 | Line 1176 | static unsigned int ether_thread_feed_in
1176  
1177          thread_active_3 = true;
1178  
1179 <        D(bug("ether_thread_feed_int start\r\n"));
1179 >        D(bug("ether_thread_feed_int start\n"));
1180  
1181          while(thread_active) {
1182 <                D(bug("Waiting for int_sig\r\n"));
1182 >                D(bug("Waiting for int_sig\n"));
1183                  WaitForSingleObject(int_sig,INFINITE);
1184                  // Looping this way to avoid a race condition.
1185 <                D(bug("Triggering\r\n"));
1185 >                D(bug("Triggering\n"));
1186                  looping = true;
1187                  while(thread_active && looping) {
1188                          trigger_queue();
# Line 1019 | Line 1190 | static unsigned int ether_thread_feed_in
1190                          WaitForSingleObject(int_ack,INFINITE);
1191                          if(thread_active) looping = set_wait_request();
1192                  }
1193 <                D(bug("Queue empty.\r\n"));
1193 >                D(bug("Queue empty.\n"));
1194          }
1195  
1196 <        D(bug("ether_thread_feed_int exit\r\n"));
1196 >        D(bug("ether_thread_feed_int exit\n"));
1197  
1198          thread_active_3 = false;
1199  
# Line 1034 | Line 1205 | static unsigned int ether_thread_feed_in
1205   *  Ethernet interrupt - activate deferred tasks to call IODone or protocol handlers
1206   */
1207  
1208 < void EtherInterrupt(void)
1208 > static void ether_do_interrupt(void)
1209   {
1210 <        int length;
1210 >        // Call protocol handler for received packets
1211          EthernetPacket ether_packet;
1212          uint32 packet = ether_packet.addr();
1213 +        ssize_t length;
1214 +        for (;;) {
1215  
1216 <        D(bug("EtherIRQ\r\n"));
1217 <
1045 <        // Call protocol handler for received packets
1046 <        while( (length = dequeue_packet(Mac2HostAddr(packet))) > 0 ) {
1047 <
1216 >                // Read packet from Ethernet device
1217 >                length = dequeue_packet(Mac2HostAddr(packet));
1218                  if (length < 14)
1219 <                        continue;
1219 >                        break;
1220  
1221   #if MONITOR
1222                  bug("Receiving Ethernet packet (%d bytes):\n",(int)length);
1223                  dump_packet( Mac2HostAddr(packet), length );
1224   #endif
1225  
1226 <                // Get packet type
1227 <                uint16 type = ReadMacInt16(packet + 12);
1058 <
1059 <                // Look for protocol
1060 <                NetProtocol *prot = find_protocol(type);
1061 <                if (prot == NULL)
1062 <                        continue;
1063 <                // break;
1064 <
1065 <                // No default handler
1066 <                if (prot->handler == 0)
1067 <                        continue;
1068 <                // break;
1069 <
1070 <                // Copy header to RHA
1071 <                Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14);
1072 <                D(bug(" header %08lx%04lx %08lx%04lx %04lx\r\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12)));
1073 <
1074 <                // Call protocol handler
1075 <                M68kRegisters r;
1076 <                r.d[0] = type;                  // Packet type
1077 <                r.d[1] = length - 14;             // Remaining packet length (without header, for ReadPacket)
1078 <
1079 <                r.a[0] = packet + 14;                     // Pointer to packet (Mac address, for ReadPacket)
1080 <                r.a[3] = ether_data + ed_RHA + 14;        // Pointer behind header in RHA
1081 <                r.a[4] = ether_data + ed_ReadPacket;      // Pointer to ReadPacket/ReadRest routines
1082 <                D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\r\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
1083 <                Execute68k(prot->handler, &r);
1226 >                // Dispatch packet
1227 >                ether_dispatch_packet(packet, length);
1228          }
1085
1086        // Acknowledge interrupt to reception thread
1087        D(bug(" EtherIRQ done\r\n"));
1088        ReleaseSemaphore(int_ack,1,NULL);
1229   }
1230  
1231   #if DEBUG

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines