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.1 by gbeauche, 2004-12-06T23:31:03Z vs.
Revision 1.4 by gbeauche, 2005-11-27T22:18:29Z

# Line 1 | Line 1
1   /*
2   *  ether_windows.cpp - Ethernet device driver
3   *
4 < *  Basilisk II (C) 1997-2004 Christian Bauer
4 > *  Basilisk II (C) 1997-2005 Christian Bauer
5   *
6   *  Windows platform specific code copyright (C) Lauri Pesonen
7   *
# Line 58 | Line 58 | HANDLE ether_th;
58   unsigned int ether_tid;
59   HANDLE ether_th1;
60   HANDLE ether_th2;
61 + #ifdef SHEEPSHAVER
62 + static bool net_open = false;                           // Flag: initialization succeeded, network device open
63 + uint8 ether_addr[6];                                            // Our Ethernet address
64 + #endif
65  
66  
67   // Need to fake a NIC if there is none but the router module is activated.
# Line 66 | Line 70 | bool ether_fake = false;
70   // These are protected by queue_csection
71   // Controls transfer for read thread to feed thread
72   static CRITICAL_SECTION queue_csection;
73 < typedef struct _queue_t {
73 > typedef struct _win_queue_t {
74          uint8 *buf;
75          int sz;
76 < } queue_t;
76 > } win_queue_t;
77   #define MAX_QUEUE_ITEMS 1024
78 < static queue_t queue[MAX_QUEUE_ITEMS];
78 > static win_queue_t queue[MAX_QUEUE_ITEMS];
79   static int queue_head = 0;
80   static int queue_inx = 0;
81   static bool wait_request = true;
# Line 141 | Line 145 | static void final_queue(void);
145   static bool allocate_read_packets(void);
146   static void free_read_packets(void);
147   static void free_write_packets(void);
148 + static int16 ether_do_add_multicast(uint8 *addr);
149 + static int16 ether_do_del_multicast(uint8 *addr);
150 + static int16 ether_do_write(uint32 arg);
151 + static void ether_do_interrupt(void);
152  
153  
154   /*
# Line 446 | Line 454 | void ether_exit(void)
454  
455  
456   /*
457 + *  Glue around low-level implementation
458 + */
459 +
460 + #ifdef SHEEPSHAVER
461 + // Error codes
462 + enum {
463 +        eMultiErr               = -91,
464 +        eLenErr                 = -92,
465 +        lapProtErr              = -94,
466 +        excessCollsns   = -95
467 + };
468 +
469 + // Initialize ethernet
470 + void EtherInit(void)
471 + {
472 +        net_open = false;
473 +
474 +        // Do nothing if the user disabled the network
475 +        if (PrefsFindBool("nonet"))
476 +                return;
477 +
478 +        net_open = ether_init();
479 + }
480 +
481 + // Exit ethernet
482 + void EtherExit(void)
483 + {
484 +        ether_exit();
485 +        net_open = false;
486 + }
487 +
488 + // Get ethernet hardware address
489 + void AO_get_ethernet_address(uint32 arg)
490 + {
491 +        uint8 *addr = Mac2HostAddr(arg);
492 +        if (net_open)
493 +                OTCopy48BitAddress(ether_addr, addr);
494 +        else {
495 +                addr[0] = 0x12;
496 +                addr[1] = 0x34;
497 +                addr[2] = 0x56;
498 +                addr[3] = 0x78;
499 +                addr[4] = 0x9a;
500 +                addr[5] = 0xbc;
501 +        }
502 +        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]));
503 + }
504 +
505 + // Add multicast address
506 + void AO_enable_multicast(uint32 addr)
507 + {
508 +        if (net_open)
509 +                ether_do_add_multicast(Mac2HostAddr(addr));
510 + }
511 +
512 + // Disable multicast address
513 + void AO_disable_multicast(uint32 addr)
514 + {
515 +        if (net_open)
516 +                ether_do_del_multicast(Mac2HostAddr(addr));
517 + }
518 +
519 + // Transmit one packet
520 + void AO_transmit_packet(uint32 mp)
521 + {
522 +        if (net_open) {
523 +                switch (ether_do_write(mp)) {
524 +                case noErr:
525 +                        num_tx_packets++;
526 +                        break;
527 +                case excessCollsns:
528 +                        num_tx_buffer_full++;
529 +                        break;
530 +                }
531 +        }
532 + }
533 +
534 + // Copy packet data from message block to linear buffer
535 + static inline int ether_arg_to_buffer(uint32 mp, uint8 *p)
536 + {
537 +        return ether_msgb_to_buffer(mp, p);
538 + }
539 +
540 + // Ethernet interrupt
541 + void EtherIRQ(void)
542 + {
543 +        D(bug("EtherIRQ\n"));
544 +        num_ether_irq++;
545 +
546 +        OTEnterInterrupt();
547 +        ether_do_interrupt();
548 +        OTLeaveInterrupt();
549 +
550 +        // Acknowledge interrupt to reception thread
551 +        D(bug(" EtherIRQ done\r\n"));
552 +        ReleaseSemaphore(int_ack,1,NULL);
553 + }
554 + #else
555 + // Add multicast address
556 + int16 ether_add_multicast(uint32 pb)
557 + {
558 +        return ether_do_add_multicast(Mac2HostAddr(pb + eMultiAddr));
559 + }
560 +
561 + // Disable multicast address
562 + int16 ether_del_multicast(uint32 pb)
563 + {
564 +        return ether_do_del_multicast(Mac2HostAddr(pb + eMultiAddr));
565 + }
566 +
567 + // Transmit one packet
568 + int16 ether_write(uint32 wds)
569 + {
570 +        return ether_do_write(wds);
571 + }
572 +
573 + // Copy packet data from WDS to linear buffer
574 + static inline int ether_arg_to_buffer(uint32 wds, uint8 *p)
575 + {
576 +        return ether_wds_to_buffer(wds, p);
577 + }
578 +
579 + // Dispatch packet to protocol handler
580 + static void ether_dispatch_packet(uint32 packet, uint32 length)
581 + {
582 +        // Get packet type
583 +        uint16 type = ReadMacInt16(packet + 12);
584 +
585 +        // Look for protocol
586 +        NetProtocol *prot = find_protocol(type);
587 +        if (prot == NULL)
588 +                return;
589 +
590 +        // No default handler
591 +        if (prot->handler == 0)
592 +                return;
593 +
594 +        // Copy header to RHA
595 +        Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14);
596 +        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)));
597 +
598 +        // Call protocol handler
599 +        M68kRegisters r;
600 +        r.d[0] = type;                                                          // Packet type
601 +        r.d[1] = length - 14;                                           // Remaining packet length (without header, for ReadPacket)
602 +        r.a[0] = packet + 14;                                           // Pointer to packet (Mac address, for ReadPacket)
603 +        r.a[3] = ether_data + ed_RHA + 14;                      // Pointer behind header in RHA
604 +        r.a[4] = ether_data + ed_ReadPacket;            // Pointer to ReadPacket/ReadRest routines
605 +        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]));
606 +        Execute68k(prot->handler, &r);
607 + }
608 +
609 + // Ethernet interrupt
610 + void EtherInterrupt(void)
611 + {
612 +        D(bug("EtherIRQ\n"));
613 +        ether_do_interrupt();
614 +
615 +        // Acknowledge interrupt to reception thread
616 +        D(bug(" EtherIRQ done\r\n"));
617 +        ReleaseSemaphore(int_ack,1,NULL);
618 + }
619 + #endif
620 +
621 +
622 + /*
623   *  Reset
624   */
625  
# Line 468 | Line 642 | void ether_reset(void)
642   *  Add multicast address
643   */
644  
645 < int16 ether_add_multicast(uint32 pb)
645 > static int16 ether_do_add_multicast(uint8 *addr)
646   {
647          D(bug("ether_add_multicast\r\n"));
648  
649          // We wouldn't need to do this
650          // if(ether_multi_mode != ETHER_MULTICAST_MAC) return noErr;
651  
652 <        if (!ether_fake && !PacketAddMulticast( fd, Mac2HostAddr(pb + eMultiAddr))) {
652 >        if (!ether_fake && !PacketAddMulticast( fd, addr)) {
653                  D(bug("WARNING: couldn't enable multicast address\r\n"));
654                  return eMultiErr;
655          } else {
# Line 489 | Line 663 | int16 ether_add_multicast(uint32 pb)
663   *  Delete multicast address
664   */
665  
666 < int16 ether_del_multicast(uint32 pb)
666 > int16 ether_do_del_multicast(uint8 *addr)
667   {
668          D(bug("ether_del_multicast\r\n"));
669  
670          // We wouldn't need to do this
671          // if(ether_multi_mode != ETHER_MULTICAST_MAC) return noErr;
672  
673 <        if (!ether_fake && !PacketDelMulticast( fd, Mac2HostAddr(pb + eMultiAddr))) {
673 >        if (!ether_fake && !PacketDelMulticast( fd, addr)) {
674                  D(bug("WARNING: couldn't disable multicast address\r\n"));
675                  return eMultiErr;
676          } else
# Line 569 | Line 743 | static void dump_packet( uint8 *packet,
743          if(length > 256) length = 256;
744  
745          for (int i=0; i<length; i++) {
746 <                sprintf(sm,"%02x", (int)packet[i]);
746 >                sprintf(sm," %02x", (int)packet[i]);
747                  strcat( buf, sm );
748          }
749          strcat( buf, "\r\n" );
# Line 728 | Line 902 | static BOOL write_packet( uint8 *packet,
902          }
903   }
904  
905 < int16 ether_write(uint32 wds)
905 > static int16 ether_do_write(uint32 arg)
906   {
907          D(bug("ether_write\r\n"));
908  
735        // Set source address
736        uint32 hdr = ReadMacInt32(wds + 2);
737        memcpy(Mac2HostAddr(hdr + 6), ether_addr, 6);
738
909          // Copy packet to buffer
910          uint8 packet[1514], *p = packet;
911 <        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 <        }
911 >        int len = ether_arg_to_buffer(arg, p);
912  
913          if(len > 1514) {
914                  D(bug("illegal packet length: %d\r\n",len));
# Line 1034 | Line 1195 | static unsigned int ether_thread_feed_in
1195   *  Ethernet interrupt - activate deferred tasks to call IODone or protocol handlers
1196   */
1197  
1198 < void EtherInterrupt(void)
1198 > static void ether_do_interrupt(void)
1199   {
1039        int length;
1040        static uint8 packet[1514];
1041
1042        D(bug("EtherIRQ\r\n"));
1043
1200          // Call protocol handler for received packets
1201 <        while( (length = dequeue_packet(packet)) > 0 ) {
1201 >        EthernetPacket ether_packet;
1202 >        uint32 packet = ether_packet.addr();
1203 >        ssize_t length;
1204 >        for (;;) {
1205  
1206 +                // Read packet from Ethernet device
1207 +                length = dequeue_packet(Mac2HostAddr(packet));
1208                  if (length < 14)
1209 <                        continue;
1209 >                        break;
1210  
1211   #if MONITOR
1212                  bug("Receiving Ethernet packet (%d bytes):\n",(int)length);
1213 <                dump_packet( packet, length );
1213 >                dump_packet( Mac2HostAddr(packet), length );
1214   #endif
1215  
1216 <                // Get packet type
1217 <                uint16 type = ntohs(*(uint16 *)(packet + 12));
1057 <
1058 <                // Look for protocol
1059 <                NetProtocol *prot = find_protocol(type);
1060 <                if (prot == NULL)
1061 <                        continue;
1062 <                // break;
1063 <
1064 <                // No default handler
1065 <                if (prot->handler == 0)
1066 <                        continue;
1067 <                // break;
1068 <
1069 <                // Copy header to RHA
1070 <                memcpy(Mac2HostAddr(ether_data + ed_RHA), packet, 14);
1071 <                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)));
1072 <
1073 <                // Call protocol handler
1074 <                M68kRegisters r;
1075 <                r.d[0] = type;                  // Packet type
1076 <                r.d[1] = length - 14;             // Remaining packet length (without header, for ReadPacket)
1077 <
1078 <                r.a[0] = (uint32)packet + 14;         // Pointer to packet (host address, for ReadPacket)
1079 <                r.a[3] = ether_data + ed_RHA + 14;        // Pointer behind header in RHA
1080 <                r.a[4] = ether_data + ed_ReadPacket;      // Pointer to ReadPacket/ReadRest routines
1081 <                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]));
1082 <                Execute68k(prot->handler, &r);
1216 >                // Dispatch packet
1217 >                ether_dispatch_packet(packet, length);
1218          }
1084
1085        // Acknowledge interrupt to reception thread
1086        D(bug(" EtherIRQ done\r\n"));
1087        ReleaseSemaphore(int_ack,1,NULL);
1219   }
1220  
1221   #if DEBUG

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines