mirror of
https://github.com/minexew/Shrine.git
synced 2026-05-26 16:36:09 +00:00
80 lines
1.9 KiB
HolyC
80 lines
1.9 KiB
HolyC
// vim: set ft=c:
|
|
|
|
// 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;
|