2
2
* ether.cpp - Ethernet device driver
4
* Basilisk II (C) 1997-2002 Christian Bauer
4
* Basilisk II (C) 1997-2005 Christian Bauer
6
6
* This program is free software; you can redistribute it and/or modify
7
7
* it under the terms of the GNU General Public License as published by
390
390
* Ethernet ReadPacket routine
393
void EtherReadPacket(uint8 **src, uint32 &dest, uint32 &len, uint32 &remaining)
393
void EtherReadPacket(uint32 &src, uint32 &dest, uint32 &len, uint32 &remaining)
395
D(bug("EtherReadPacket src %p, dest %08x, len %08x, remaining %08x\n", *src, dest, len, remaining));
395
D(bug("EtherReadPacket src %08x, dest %08x, len %08x, remaining %08x\n", src, dest, len, remaining));
396
396
uint32 todo = len > remaining ? remaining : len;
397
Host2Mac_memcpy(dest, *src, todo);
397
Mac2Mac_memcpy(dest, src, todo);
401
401
remaining -= todo;
407
407
* Read packet from UDP socket
410
void ether_udp_read(uint8 *packet, int length, struct sockaddr_in *from)
410
void ether_udp_read(uint32 packet, int length, struct sockaddr_in *from)
412
412
// Drop packets sent by us
413
if (memcmp(packet + 6, ether_addr, 6) == 0)
413
if (memcmp(Mac2HostAddr(packet) + 6, ether_addr, 6) == 0)
417
417
bug("Receiving Ethernet packet:\n");
418
418
for (int i=0; i<length; i++) {
419
bug("%02x ", packet[i]);
419
bug("%02x ", ReadMacInt8(packet + i));
424
424
// Get packet type
425
uint16 type = (packet[12] << 8) | packet[13];
425
uint16 type = ReadMacInt16(packet + 12);
427
427
// Look for protocol
428
428
uint16 search_type = (type <= 1500 ? 0 : type);
435
435
// Copy header to RHA
436
Host2Mac_memcpy(ether_data + ed_RHA, packet, 14);
436
Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14);
437
437
D(bug(" header %08x%04x %08x%04x %04x\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)));
439
439
// Call protocol handler
441
441
r.d[0] = type; // Packet type
442
442
r.d[1] = length - 14; // Remaining packet length (without header, for ReadPacket)
443
r.a[0] = (uint32)packet + 14; // Pointer to packet (host address, for ReadPacket)
443
r.a[0] = packet + 14; // Pointer to packet (Mac address, for ReadPacket)
444
444
r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA
445
445
r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines
446
446
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]));
447
447
Execute68k(handler, &r);
453
* Ethernet packet allocator
456
#if SIZEOF_VOID_P != 4 || REAL_ADDRESSING == 0
457
static uint32 ether_packet = 0; // Ethernet packet (cached allocation)
458
static uint32 n_ether_packets = 0; // Number of ethernet packets allocated so far (should be at most 1)
460
EthernetPacket::EthernetPacket()
463
if (ether_packet && n_ether_packets == 1)
464
packet = ether_packet;
468
Execute68kTrap(0xa71e, &r); // NewPtrSysClear()
471
if (ether_packet == 0)
472
ether_packet = packet;
476
EthernetPacket::~EthernetPacket()
479
if (packet != ether_packet) {
482
Execute68kTrap(0xa01f, &r); // DisposePtr
484
if (n_ether_packets > 0) {
485
bug("WARNING: Nested allocation of ethernet packets!\n");