net: don't duplicate struct layout in e1000 device object

This commit is contained in:
K. Lange 2021-06-18 15:20:22 +09:00
parent 45ff4e4404
commit d8dc85e507
5 changed files with 61 additions and 62 deletions

View File

@ -138,7 +138,7 @@ kernel/%.o: kernel/%.S
echo ${PATH} echo ${PATH}
${CC} -c $< -o $@ ${CC} -c $< -o $@
HEADERS = $(wildcard base/usr/include/kernel/*.h) HEADERS = $(wildcard base/usr/include/kernel/*.h) $(wildcard base/usr/include/kernel/*/*.h)
kernel/%.o: kernel/%.c ${HEADERS} kernel/%.o: kernel/%.c ${HEADERS}
${CC} ${KERNEL_CFLAGS} -nostdlib -g -Iinclude -c -o $@ $< ${CC} ${KERNEL_CFLAGS} -nostdlib -g -Iinclude -c -o $@ $<

View File

@ -9,6 +9,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/time.h> #include <sys/time.h>
#include <net/if.h>
struct ethernet_packet { struct ethernet_packet {
uint8_t destination[6]; uint8_t destination[6];
@ -261,7 +262,7 @@ static int configure_interface(const char * if_name) {
return 1; return 1;
} }
if (ioctl(netdev, 0x12340001, &mac_addr)) { if (ioctl(netdev, SIOCGIFHWADDR, &mac_addr)) {
fprintf(stderr, "%s: %s: could not get mac address\n", _argv_0, if_name); fprintf(stderr, "%s: %s: could not get mac address\n", _argv_0, if_name);
return 1; return 1;
} }
@ -353,7 +354,7 @@ static int configure_interface(const char * if_name) {
yiaddr = response->dhcp_header.yiaddr; yiaddr = response->dhcp_header.yiaddr;
char yiaddr_ip[16]; char yiaddr_ip[16];
ip_ntoa(ntohl(yiaddr), yiaddr_ip); ip_ntoa(ntohl(yiaddr), yiaddr_ip);
if (!ioctl(netdev, 0x12340012, &yiaddr)) { if (!ioctl(netdev, SIOCSIFADDR, &yiaddr)) {
printf("%s: %s: configured for %s\n", _argv_0, if_name, yiaddr_ip); printf("%s: %s: configured for %s\n", _argv_0, if_name, yiaddr_ip);
} else { } else {
perror(_argv_0); perror(_argv_0);
@ -371,7 +372,7 @@ static int configure_interface(const char * if_name) {
char addr[16]; char addr[16];
ip_ntoa(ntohl(ip_data), addr); ip_ntoa(ntohl(ip_data), addr);
printf("%s: %s: subnet mask %s\n", _argv_0, if_name, addr); printf("%s: %s: subnet mask %s\n", _argv_0, if_name, addr);
ioctl(netdev, 0x12340014, &ip_data); ioctl(netdev, SIOCSIFNETMASK, &ip_data);
} else if (opt_type == 3) { } else if (opt_type == 3) {
/* Gateway address - add this to a route table? */ /* Gateway address - add this to a route table? */
uint32_t ip_data; uint32_t ip_data;
@ -379,6 +380,7 @@ static int configure_interface(const char * if_name) {
char addr[16]; char addr[16];
ip_ntoa(ntohl(ip_data), addr); ip_ntoa(ntohl(ip_data), addr);
printf("%s: %s: gateway %s\n", _argv_0, if_name, addr); printf("%s: %s: gateway %s\n", _argv_0, if_name, addr);
ioctl(netdev, SIOCSIFGATEWAY, &ip_data);
} else if (opt_type == 6) { } else if (opt_type == 6) {
/* DNS server */ /* DNS server */
uint32_t ip_data; uint32_t ip_data;

View File

@ -21,6 +21,7 @@ struct EthernetDevice {
/* XXX: just to get things going */ /* XXX: just to get things going */
uint32_t ipv4_addr; uint32_t ipv4_addr;
uint32_t ipv4_subnet; uint32_t ipv4_subnet;
uint32_t ipv4_gateway;
uint8_t ipv6_addr[16]; uint8_t ipv6_addr[16];
/* TODO: Address lists? */ /* TODO: Address lists? */

View File

@ -17,6 +17,8 @@ _Begin_C_Header
#define SIOCSIFADDR6 0x12340013 /* Set IPv6 address */ #define SIOCSIFADDR6 0x12340013 /* Set IPv6 address */
#define SIOCGIFFLAGS 0x12340005 /* Get interface flags */ #define SIOCGIFFLAGS 0x12340005 /* Get interface flags */
#define SIOCGIFMTU 0x12340006 /* Get interface mtu */ #define SIOCGIFMTU 0x12340006 /* Get interface mtu */
#define SIOCGIFGATEWAY 0x12340007
#define SIOCSIFGATEWAY 0x12340017
/** /**
* Flags for interface status * Flags for interface status

View File

@ -32,20 +32,7 @@
#define INTS ((1 << 2) | (1 << 6) | (1 << 7) | (1 << 1) | (1 << 0)) #define INTS ((1 << 2) | (1 << 6) | (1 << 7) | (1 << 1) | (1 << 0))
struct e1000_nic { struct e1000_nic {
/* This should be generic netif struct stuff... */ struct EthernetDevice eth;
char if_name[32];
uint8_t mac[6];
size_t mtu;
/* XXX: just to get things going */
uint32_t ipv4_addr;
uint32_t ipv4_subnet;
uint8_t ipv6_addr[16];
/* TODO: Address lists? */
fs_node_t * device_node;
uint32_t pci_device; uint32_t pci_device;
uint16_t deviceid; uint16_t deviceid;
uintptr_t mmio_addr; uintptr_t mmio_addr;
@ -140,8 +127,8 @@ static uint16_t eeprom_read(struct e1000_nic * device, uint8_t addr) {
static void write_mac(struct e1000_nic * device) { static void write_mac(struct e1000_nic * device) {
uint32_t low, high; uint32_t low, high;
memcpy(&low, &device->mac[0], 4); memcpy(&low, &device->eth.mac[0], 4);
memcpy(&high,&device->mac[4], 2); memcpy(&high,&device->eth.mac[4], 2);
memset((uint8_t *)&high + 2, 0, 2); memset((uint8_t *)&high + 2, 0, 2);
high |= 0x80000000; high |= 0x80000000;
write_command(device, E1000_REG_RXADDR + 0, low); write_command(device, E1000_REG_RXADDR + 0, low);
@ -152,23 +139,23 @@ static void read_mac(struct e1000_nic * device) {
if (device->has_eeprom) { if (device->has_eeprom) {
uint32_t t; uint32_t t;
t = eeprom_read(device, 0); t = eeprom_read(device, 0);
device->mac[0] = t & 0xFF; device->eth.mac[0] = t & 0xFF;
device->mac[1] = t >> 8; device->eth.mac[1] = t >> 8;
t = eeprom_read(device, 1); t = eeprom_read(device, 1);
device->mac[2] = t & 0xFF; device->eth.mac[2] = t & 0xFF;
device->mac[3] = t >> 8; device->eth.mac[3] = t >> 8;
t = eeprom_read(device, 2); t = eeprom_read(device, 2);
device->mac[4] = t & 0xFF; device->eth.mac[4] = t & 0xFF;
device->mac[5] = t >> 8; device->eth.mac[5] = t >> 8;
} else { } else {
uint32_t mac_addr_low = *(uint32_t *)(device->mmio_addr + E1000_REG_RXADDR); uint32_t mac_addr_low = *(uint32_t *)(device->mmio_addr + E1000_REG_RXADDR);
uint32_t mac_addr_high = *(uint32_t *)(device->mmio_addr + E1000_REG_RXADDR + 4); uint32_t mac_addr_high = *(uint32_t *)(device->mmio_addr + E1000_REG_RXADDR + 4);
device->mac[0] = (mac_addr_low >> 0 ) & 0xFF; device->eth.mac[0] = (mac_addr_low >> 0 ) & 0xFF;
device->mac[1] = (mac_addr_low >> 8 ) & 0xFF; device->eth.mac[1] = (mac_addr_low >> 8 ) & 0xFF;
device->mac[2] = (mac_addr_low >> 16) & 0xFF; device->eth.mac[2] = (mac_addr_low >> 16) & 0xFF;
device->mac[3] = (mac_addr_low >> 24) & 0xFF; device->eth.mac[3] = (mac_addr_low >> 24) & 0xFF;
device->mac[4] = (mac_addr_high>> 0 ) & 0xFF; device->eth.mac[4] = (mac_addr_high>> 0 ) & 0xFF;
device->mac[5] = (mac_addr_high>> 8 ) & 0xFF; device->eth.mac[5] = (mac_addr_high>> 8 ) & 0xFF;
} }
} }
@ -179,7 +166,7 @@ static void e1000_alert_waiters(struct e1000_nic * nic) {
process_t * p = node->value; process_t * p = node->value;
free(node); free(node);
spin_unlock(nic->alert_lock); spin_unlock(nic->alert_lock);
process_alert_node(p, nic->device_node); process_alert_node(p, nic->eth.device_node);
spin_lock(nic->alert_lock); spin_lock(nic->alert_lock);
} }
spin_unlock(nic->alert_lock); spin_unlock(nic->alert_lock);
@ -302,28 +289,35 @@ static int ioctl_e1000(fs_node_t * node, unsigned long request, void * argp) {
switch (request) { switch (request) {
case SIOCGIFHWADDR: case SIOCGIFHWADDR:
/* fill argp with mac */ /* fill argp with mac */
memcpy(argp, nic->mac, 6); memcpy(argp, nic->eth.mac, 6);
return 0; return 0;
case SIOCGIFADDR: case SIOCGIFADDR:
if (nic->ipv4_addr == 0) return -ENOENT; if (nic->eth.ipv4_addr == 0) return -ENOENT;
memcpy(argp, &nic->ipv4_addr, sizeof(nic->ipv4_addr)); memcpy(argp, &nic->eth.ipv4_addr, sizeof(nic->eth.ipv4_addr));
return 0; return 0;
case SIOCSIFADDR: case SIOCSIFADDR:
memcpy(&nic->ipv4_addr, argp, sizeof(nic->ipv4_addr)); memcpy(&nic->eth.ipv4_addr, argp, sizeof(nic->eth.ipv4_addr));
return 0; return 0;
case SIOCGIFNETMASK: case SIOCGIFNETMASK:
if (nic->ipv4_subnet == 0) return -ENOENT; if (nic->eth.ipv4_subnet == 0) return -ENOENT;
memcpy(argp, &nic->ipv4_subnet, sizeof(nic->ipv4_subnet)); memcpy(argp, &nic->eth.ipv4_subnet, sizeof(nic->eth.ipv4_subnet));
return 0; return 0;
case SIOCSIFNETMASK: case SIOCSIFNETMASK:
memcpy(&nic->ipv4_subnet, argp, sizeof(nic->ipv4_subnet)); memcpy(&nic->eth.ipv4_subnet, argp, sizeof(nic->eth.ipv4_subnet));
return 0;
case SIOCGIFGATEWAY:
if (nic->eth.ipv4_subnet == 0) return -ENOENT;
memcpy(argp, &nic->eth.ipv4_gateway, sizeof(nic->eth.ipv4_gateway));
return 0;
case SIOCSIFGATEWAY:
memcpy(&nic->eth.ipv4_gateway, argp, sizeof(nic->eth.ipv4_gateway));
return 0; return 0;
case SIOCGIFADDR6: case SIOCGIFADDR6:
return -ENOENT; return -ENOENT;
case SIOCSIFADDR6: case SIOCSIFADDR6:
memcpy(&nic->ipv6_addr, argp, sizeof(nic->ipv6_addr)); memcpy(&nic->eth.ipv6_addr, argp, sizeof(nic->eth.ipv6_addr));
return 0; return 0;
case SIOCGIFFLAGS: { case SIOCGIFFLAGS: {
@ -338,7 +332,7 @@ static int ioctl_e1000(fs_node_t * node, unsigned long request, void * argp) {
case SIOCGIFMTU: { case SIOCGIFMTU: {
uint32_t * mtu = argp; uint32_t * mtu = argp;
*mtu = nic->mtu; *mtu = nic->eth.mtu;
return 0; return 0;
} }
@ -376,7 +370,7 @@ static int wait_e1000(fs_node_t *node, void * process) {
if (!list_find(nic->alert_wait, process)) { if (!list_find(nic->alert_wait, process)) {
list_insert(nic->alert_wait, process); list_insert(nic->alert_wait, process);
} }
list_insert(((process_t *)process)->node_waits, nic->device_node); list_insert(((process_t *)process)->node_waits, nic->eth.device_node);
spin_unlock(nic->alert_lock); spin_unlock(nic->alert_lock);
return 0; return 0;
} }
@ -387,7 +381,7 @@ static void e1000_init(void * data) {
nic->rx_phys = mmu_allocate_a_frame() << 12; nic->rx_phys = mmu_allocate_a_frame() << 12;
if (nic->rx_phys == 0) { if (nic->rx_phys == 0) {
printf("e1000[%s]: unable to allocate memory for buffers\n", nic->if_name); printf("e1000[%s]: unable to allocate memory for buffers\n", nic->eth.if_name);
switch_task(0); switch_task(0);
} }
nic->rx = mmu_map_from_physical(nic->rx_phys); //mmu_map_mmio_region(nic->rx_phys, 4096); nic->rx = mmu_map_from_physical(nic->rx_phys); //mmu_map_mmio_region(nic->rx_phys, 4096);
@ -401,7 +395,7 @@ static void e1000_init(void * data) {
for (int i = 0; i < E1000_NUM_RX_DESC; ++i) { for (int i = 0; i < E1000_NUM_RX_DESC; ++i) {
nic->rx[i].addr = mmu_allocate_n_frames(2) << 12; nic->rx[i].addr = mmu_allocate_n_frames(2) << 12;
if (nic->rx[i].addr == 0) { if (nic->rx[i].addr == 0) {
printf("e1000[%s]: unable to allocate memory for receive buffer\n", nic->if_name); printf("e1000[%s]: unable to allocate memory for receive buffer\n", nic->eth.if_name);
switch_task(0); switch_task(0);
} }
//nic->rx_virt[i] = mmu_map_from_physical(nic->rx[i].addr); //nic->rx_virt[i] = mmu_map_from_physical(nic->rx[i].addr);
@ -414,7 +408,7 @@ static void e1000_init(void * data) {
for (int i = 0; i < E1000_NUM_TX_DESC; ++i) { for (int i = 0; i < E1000_NUM_TX_DESC; ++i) {
nic->tx[i].addr = mmu_allocate_n_frames(2) << 12; nic->tx[i].addr = mmu_allocate_n_frames(2) << 12;
if (nic->tx[i].addr == 0) { if (nic->tx[i].addr == 0) {
printf("e1000[%s]: unable to allocate memory for receive buffer\n", nic->if_name); printf("e1000[%s]: unable to allocate memory for receive buffer\n", nic->eth.if_name);
switch_task(0); switch_task(0);
} }
//nic->tx_virt[i] = mmu_map_from_physical(nic->tx[i].addr); //nic->tx_virt[i] = mmu_map_from_physical(nic->tx[i].addr);
@ -487,7 +481,7 @@ static void e1000_init(void * data) {
nic->irq_number = pci_get_interrupt(e1000_device_pci); nic->irq_number = pci_get_interrupt(e1000_device_pci);
irq_install_handler(nic->irq_number, irq_handler, nic->if_name); irq_install_handler(nic->irq_number, irq_handler, nic->eth.if_name);
for (int i = 0; i < 128; ++i) { for (int i = 0; i < 128; ++i) {
write_command(nic, 0x5200 + i * 4, 0); write_command(nic, 0x5200 + i * 4, 0);
@ -508,25 +502,25 @@ static void e1000_init(void * data) {
nic->link_status = (read_command(nic, E1000_REG_STATUS) & (1 << 1)); nic->link_status = (read_command(nic, E1000_REG_STATUS) & (1 << 1));
nic->device_node = calloc(sizeof(fs_node_t),1); nic->eth.device_node = calloc(sizeof(fs_node_t),1);
snprintf(nic->device_node->name, 100, "%s", nic->if_name); snprintf(nic->eth.device_node->name, 100, "%s", nic->eth.if_name);
nic->device_node->flags = FS_BLOCKDEVICE; /* NETDEVICE? */ nic->eth.device_node->flags = FS_BLOCKDEVICE; /* NETDEVICE? */
nic->device_node->mask = 0666; /* temporary; shouldn't be doing this with these device files */ nic->eth.device_node->mask = 0666; /* temporary; shouldn't be doing this with these device files */
nic->device_node->ioctl = ioctl_e1000; nic->eth.device_node->ioctl = ioctl_e1000;
nic->device_node->write = write_e1000; nic->eth.device_node->write = write_e1000;
nic->device_node->read = read_e1000; nic->eth.device_node->read = read_e1000;
nic->device_node->selectcheck = check_e1000; nic->eth.device_node->selectcheck = check_e1000;
nic->device_node->selectwait = wait_e1000; nic->eth.device_node->selectwait = wait_e1000;
nic->device_node->device = nic; nic->eth.device_node->device = nic;
nic->mtu = 1500; /* guess */ nic->eth.mtu = 1500; /* guess */
net_add_interface(nic->if_name, nic->device_node); net_add_interface(nic->eth.if_name, nic->eth.device_node);
/* Now wait for packets */ /* Now wait for packets */
while (1) { while (1) {
struct ethernet_packet * packet = dequeue_packet(nic); struct ethernet_packet * packet = dequeue_packet(nic);
net_eth_handle(packet, nic->device_node); net_eth_handle(packet, nic->eth.device_node);
} }
} }
@ -538,13 +532,13 @@ static void find_e1000(uint32_t device, uint16_t vendorid, uint16_t deviceid, vo
nic->deviceid = deviceid; nic->deviceid = deviceid;
devices[device_count++] = nic; devices[device_count++] = nic;
snprintf(nic->if_name, 31, snprintf(nic->eth.if_name, 31,
"enp%ds%d", "enp%ds%d",
(int)pci_extract_bus(device), (int)pci_extract_bus(device),
(int)pci_extract_slot(device)); (int)pci_extract_slot(device));
char worker_name[34]; char worker_name[34];
snprintf(worker_name, 33, "[%s]", nic->if_name); snprintf(worker_name, 33, "[%s]", nic->eth.if_name);
spawn_worker_thread(e1000_init, worker_name, nic); spawn_worker_thread(e1000_init, worker_name, nic);
*(int*)found = 1; *(int*)found = 1;