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; |
65 |
|
unsigned int ether_tid; |
66 |
|
HANDLE ether_th1; |
67 |
|
HANDLE ether_th2; |
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 |
|
|
66 |
– |
|
67 |
– |
// Need to fake a NIC if there is none but the router module is activated. |
68 |
– |
bool ether_fake = false; |
69 |
– |
|
74 |
|
// These are protected by queue_csection |
75 |
|
// Controls transfer for read thread to feed thread |
76 |
|
static CRITICAL_SECTION queue_csection; |
137 |
|
static HANDLE int_sig2 = 0; |
138 |
|
static HANDLE int_send_now = 0; |
139 |
|
|
136 |
– |
static char edevice[512]; |
137 |
– |
|
138 |
– |
|
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); |
182 |
|
{ |
183 |
|
char str[256]; |
184 |
|
|
184 |
– |
// Initialize NAT-Router |
185 |
– |
router_init(); |
186 |
– |
|
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; |
200 |
< |
} |
201 |
< |
} |
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"); |
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); |
305 |
|
|
306 |
|
ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, ðer_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; |
300 |
– |
#if 0 |
301 |
– |
SetThreadPriority( ether_th, threads[THREAD_ETHER].priority_running ); |
302 |
– |
SetThreadAffinityMask( ether_th, threads[THREAD_ETHER].affinity_mask ); |
303 |
– |
#endif |
312 |
|
|
313 |
|
unsigned int dummy; |
314 |
|
ether_th2 = (HANDLE)_beginthreadex( 0, 0, ether_thread_get_packets_nt, 0, 0, &dummy ); |
307 |
– |
#if 0 |
308 |
– |
SetThreadPriority( ether_th2, threads[THREAD_ETHER].priority_running ); |
309 |
– |
SetThreadAffinityMask( ether_th2, threads[THREAD_ETHER].affinity_mask ); |
310 |
– |
#endif |
311 |
– |
|
315 |
|
ether_th1 = (HANDLE)_beginthreadex( 0, 0, ether_thread_write_packets, 0, 0, &dummy ); |
313 |
– |
#if 0 |
314 |
– |
SetThreadPriority( ether_th1, threads[THREAD_ETHER].priority_running ); |
315 |
– |
SetThreadAffinityMask( ether_th1, threads[THREAD_ETHER].affinity_mask ); |
316 |
– |
#endif |
316 |
|
|
317 |
|
// Everything OK |
318 |
|
return true; |
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; |
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 |
|
|
358 |
– |
// _asm int 3 |
359 |
– |
|
360 |
– |
D(bug("Closing ethernet device %s\r\n",edevice)); |
361 |
– |
|
362 |
– |
if(!*edevice) return; |
363 |
– |
|
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 |
|
} |
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; |
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; |
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\r\n")); |
447 |
> |
D(bug("EtherExit done\n")); |
448 |
|
} |
449 |
|
|
450 |
|
|
543 |
|
OTLeaveInterrupt(); |
544 |
|
|
545 |
|
// Acknowledge interrupt to reception thread |
546 |
< |
D(bug(" EtherIRQ done\r\n")); |
546 |
> |
D(bug(" EtherIRQ done\n")); |
547 |
|
ReleaseSemaphore(int_ack,1,NULL); |
548 |
|
} |
549 |
|
#else |
588 |
|
|
589 |
|
// Copy header to RHA |
590 |
|
Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14); |
591 |
< |
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))); |
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; |
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\r\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4])); |
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 |
|
|
608 |
|
ether_do_interrupt(); |
609 |
|
|
610 |
|
// Acknowledge interrupt to reception thread |
611 |
< |
D(bug(" EtherIRQ done\r\n")); |
611 |
> |
D(bug(" EtherIRQ done\n")); |
612 |
|
ReleaseSemaphore(int_ack,1,NULL); |
613 |
|
} |
614 |
|
#endif |
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; |
639 |
|
|
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, addr)) { |
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 |
|
} |
663 |
|
|
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, addr)) { |
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 |
|
|
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 |
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 |
|
} |
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) { |
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 |
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 |
|
} |
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 |
|
|
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 |
|
|
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 |
|
|
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) { |
914 |
|
|
915 |
|
static int16 ether_do_write(uint32 arg) |
916 |
|
{ |
917 |
< |
D(bug("ether_write\r\n")); |
917 |
> |
D(bug("ether_write\n")); |
918 |
|
|
919 |
|
// Copy packet to buffer |
920 |
|
uint8 packet[1514], *p = packet; |
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 |
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 |
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; |
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. |
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 |
|
} |
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 |
|
} |
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, |
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 |
|
|
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(); |
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 |
|
|