Files

78 lines
1.8 KiB
HolyC

// Warning: terrible code ahead. this still needs a lot of work
// In the future we'll probably have 2 FIFOs (pending frames & empty buffers)
// TODO: check if FIFO implementation is suitable for high throughput
#define NET_FIFO_DEPTH 1024
#define ETHERNET_FRAME_SIZE 1548
#define ETHERTYPE_IPV4 0x0800
#define ETHERTYPE_ARP 0x0806
class CNetFifoEntry {
I64 length;
U8 frame[ETHERNET_FRAME_SIZE];
};
static CFifoI64 *netfifo;
static CNetFifoEntry *entries;
static I64 next_entry = 0;
CTask *netfifo_handler_task = NULL;
// TODO: asm optimization? or perhaps use EndianU*?
// These don't belong here in the first place,
// but it's convenient for Ethernet drivers
// We'll probably split it off along with ETHERTYPE_* constants
U16 htons(U16 h) { return ((h >> 8) | (h << 8)) & 0xffff; }
U16 ntohs(U16 h) { return ((h >> 8) | (h << 8)) & 0xffff; }
U32 htonl(U32 h) {
return ((h >> 24) | ((h & 0x00ff0000) >> 8) | ((h & 0x0000ff00) << 8) |
(h << 24)) &
0xffffffff;
}
U32 ntohl(U32 h) {
return ((h >> 24) | ((h & 0x00ff0000) >> 8) | ((h & 0x0000ff00) << 8) |
(h << 24)) &
0xffffffff;
}
CNetFifoEntry *NetFifoPull() {
CNetFifoEntry *entry;
if (FifoI64Rem(netfifo, &entry))
return entry;
else
return NULL;
}
I64 NetFifoPushCopy(U8 *data, I64 length) {
CNetFifoEntry *entry = &entries[next_entry];
next_entry = (next_entry + 1) & (NET_FIFO_DEPTH - 1);
entry->length = length;
MemCpy(entry->frame, data, length);
if (!FifoI64Ins(netfifo, entry))
return -1;
// Wake up Handler Task
if (netfifo_handler_task)
LBtr(&netfifo_handler_task->task_flags, TASKf_IDLE);
return 0;
}
U0 NetFifoInit() {
netfifo = FifoI64New(NET_FIFO_DEPTH);
entries = MAlloc(NET_FIFO_DEPTH * sizeof(CNetFifoEntry));
}
NetFifoInit;