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

Comparing BasiliskII/src/Unix/ether_unix.cpp (file contents):
Revision 1.2 by cebix, 2001-07-12T19:48:27Z vs.
Revision 1.7 by cebix, 2002-02-07T16:10:55Z

# Line 1 | Line 1
1   /*
2   *  ether_unix.cpp - Ethernet device driver, Unix specific stuff (Linux and FreeBSD)
3   *
4 < *  Basilisk II (C) 1997-2001 Christian Bauer
4 > *  Basilisk II (C) 1997-2002 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 22 | Line 22
22  
23   #include <sys/ioctl.h>
24   #include <sys/poll.h>
25 + #include <sys/socket.h>
26 + #include <netinet/in.h>
27   #include <pthread.h>
28   #include <semaphore.h>
29   #include <errno.h>
30   #include <stdio.h>
31 + #include <map>
32  
33 < #include <netinet/in.h>
31 < #include <sys/socket.h>
32 <
33 < #if defined(__FreeBSD__)
33 > #if defined(__FreeBSD__) || defined(sgi)
34   #include <net/if.h>
35   #endif
36  
# Line 42 | Line 42
42   #include "ether.h"
43   #include "ether_defs.h"
44  
45 + #ifndef NO_STD_NAMESPACE
46 + using std::map;
47 + #endif
48 +
49   #define DEBUG 0
50   #include "debug.h"
51  
52   #define MONITOR 0
53  
54  
51 // List of attached protocols
52 struct NetProtocol {
53        NetProtocol *next;
54        uint16 type;
55        uint32 handler;
56 };
57
58 static NetProtocol *prot_list = NULL;
59
60
55   // Global variables
56   static int fd = -1;                                                     // fd of sheep_net device
57   static pthread_t ether_thread;                          // Packet reception thread
# Line 67 | Line 61 | static sem_t int_ack;                                          // Interrupt
61   static bool is_ethertap;                                        // Flag: Ethernet device is ethertap
62   static bool udp_tunnel;                                         // Flag: UDP tunnelling active, fd is the socket descriptor
63  
64 + // Attached network protocols, maps protocol type to MacOS handler address
65 + static map<uint16, uint32> net_protocols;
66 +
67   // Prototypes
68   static void *receive_func(void *arg);
69  
70  
71   /*
75 *  Find protocol in list
76 */
77
78 static NetProtocol *find_protocol(uint16 type)
79 {
80        // All 802.2 types are the same
81        if (type <= 1500)
82                type = 0;
83
84        // Search list (we could use hashing here but there are usually only three
85        // handlers installed: 0x0000 for AppleTalk and 0x0800/0x0806 for TCP/IP)
86        NetProtocol *p = prot_list;
87        while (p) {
88                if (p->type == type)
89                        return p;
90                p = p->next;
91        }
92        return NULL;
93 }
94
95
96 /*
97 *  Remove all protocols
98 */
99
100 static void remove_all_protocols(void)
101 {
102        NetProtocol *p = prot_list;
103        while (p) {
104                NetProtocol *next = p->next;
105                delete p;
106                p = next;
107        }
108        prot_list = NULL;
109 }
110
111
112 /*
72   *  Start packet reception thread
73   */
74  
# Line 120 | Line 79 | static bool start_thread(void)
79                  return false;
80          }
81  
82 <        pthread_attr_init(&ether_thread_attr);
124 < #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
125 <        if (geteuid() == 0) {
126 <                pthread_attr_setinheritsched(&ether_thread_attr, PTHREAD_EXPLICIT_SCHED);
127 <                pthread_attr_setschedpolicy(&ether_thread_attr, SCHED_FIFO);
128 <                struct sched_param fifo_param;
129 <                fifo_param.sched_priority = (sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2 + 1;
130 <                pthread_attr_setschedparam(&ether_thread_attr, &fifo_param);
131 <        }
132 < #endif
133 <
82 >        Set_pthread_attr(&ether_thread_attr, 1);
83          thread_active = (pthread_create(&ether_thread, &ether_thread_attr, receive_func, NULL) == 0);
84          if (!thread_active) {
85                  printf("WARNING: Cannot start Ethernet thread");
# Line 246 | Line 195 | void ether_exit(void)
195          // Close sheep_net device
196          if (fd > 0)
197                  close(fd);
249
250        // Remove all protocols
251        remove_all_protocols();
198   }
199  
200  
# Line 256 | Line 202 | void ether_exit(void)
202   *  Reset
203   */
204  
205 < void EtherReset(void)
205 > void ether_reset(void)
206   {
207 <        remove_all_protocols();
207 >        net_protocols.clear();
208   }
209  
210  
# Line 299 | Line 245 | int16 ether_del_multicast(uint32 pb)
245  
246   int16 ether_attach_ph(uint16 type, uint32 handler)
247   {
248 <        // Already attached?
303 <        NetProtocol *p = find_protocol(type);
304 <        if (p != NULL)
248 >        if (net_protocols.find(type) != net_protocols.end())
249                  return lapProtErr;
250 <        else {
251 <                // No, create and attach
308 <                p = new NetProtocol;
309 <                p->next = prot_list;
310 <                p->type = type;
311 <                p->handler = handler;
312 <                prot_list = p;
313 <                return noErr;
314 <        }
250 >        net_protocols[type] = handler;
251 >        return noErr;
252   }
253  
254  
# Line 321 | Line 258 | int16 ether_attach_ph(uint16 type, uint3
258  
259   int16 ether_detach_ph(uint16 type)
260   {
261 <        NetProtocol *p = find_protocol(type);
325 <        if (p != NULL) {
326 <                NetProtocol *q = prot_list;
327 <                if (p == q) {
328 <                        prot_list = p->next;
329 <                        delete p;
330 <                        return noErr;
331 <                }
332 <                while (q) {
333 <                        if (q->next == p) {
334 <                                q->next = p->next;
335 <                                delete p;
336 <                                return noErr;
337 <                        }
338 <                        q = q->next;
339 <                }
340 <                return lapProtErr;
341 <        } else
261 >        if (net_protocols.erase(type) == 0)
262                  return lapProtErr;
263 +        return noErr;
264   }
265  
266  
# Line 349 | Line 270 | int16 ether_detach_ph(uint16 type)
270  
271   int16 ether_write(uint32 wds)
272   {
352        // Set source address
353        uint32 hdr = ReadMacInt32(wds + 2);
354        Host2Mac_memcpy(hdr + 6, ether_addr, 6);
355
273          // Copy packet to buffer
274          uint8 packet[1516], *p = packet;
275          int len = 0;
# Line 486 | Line 403 | void EtherInterrupt(void)
403                          uint16 type = (p[12] << 8) | p[13];
404  
405                          // Look for protocol
406 <                        NetProtocol *prot = find_protocol(type);
407 <                        if (prot == NULL)
406 >                        uint16 search_type = (type <= 1500 ? 0 : type);
407 >                        if (net_protocols.find(search_type) == net_protocols.end())
408                                  continue;
409 +                        uint32 handler = net_protocols[search_type];
410  
411                          // No default handler
412 <                        if (prot->handler == 0)
412 >                        if (handler == 0)
413                                  continue;
414  
415                          // Copy header to RHA
# Line 505 | Line 423 | void EtherInterrupt(void)
423                          r.a[0] = (uint32)p + 14;                                                // Pointer to packet (host address, for ReadPacket)
424                          r.a[3] = ether_data + ed_RHA + 14;                              // Pointer behind header in RHA
425                          r.a[4] = ether_data + ed_ReadPacket;                    // Pointer to ReadPacket/ReadRest routines
426 <                        D(bug(" calling protocol handler %08x, type %08x, length %08x, data %08x, rha %08x, read_packet %08x\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
427 <                        Execute68k(prot->handler, &r);
426 >                        D(bug(" calling protocol handler %08x, type %08x, length %08x, data %08x, rha %08x, read_packet %08x\n", handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
427 >                        Execute68k(handler, &r);
428                  }
429          }
430  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines