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}
${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}
${CC} ${KERNEL_CFLAGS} -nostdlib -g -Iinclude -c -o $@ $<

View File

@ -9,6 +9,7 @@
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <net/if.h>
struct ethernet_packet {
uint8_t destination[6];
@ -261,7 +262,7 @@ static int configure_interface(const char * if_name) {
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);
return 1;
}
@ -353,7 +354,7 @@ static int configure_interface(const char * if_name) {
yiaddr = response->dhcp_header.yiaddr;
char yiaddr_ip[16];
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);
} else {
perror(_argv_0);
@ -371,7 +372,7 @@ static int configure_interface(const char * if_name) {
char addr[16];
ip_ntoa(ntohl(ip_data), 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) {
/* Gateway address - add this to a route table? */
uint32_t ip_data;
@ -379,6 +380,7 @@ static int configure_interface(const char * if_name) {
char addr[16];
ip_ntoa(ntohl(ip_data), addr);
printf("%s: %s: gateway %s\n", _argv_0, if_name, addr);
ioctl(netdev, SIOCSIFGATEWAY, &ip_data);
} else if (opt_type == 6) {
/* DNS server */
uint32_t ip_data;

View File

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

View File

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

View File

@ -32,20 +32,7 @@
#define INTS ((1 << 2) | (1 << 6) | (1 << 7) | (1 << 1) | (1 << 0))
struct e1000_nic {
/* This should be generic netif struct stuff... */
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;
struct EthernetDevice eth;
uint32_t pci_device;
uint16_t deviceid;
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) {
uint32_t low, high;
memcpy(&low, &device->mac[0], 4);
memcpy(&high,&device->mac[4], 2);
memcpy(&low, &device->eth.mac[0], 4);
memcpy(&high,&device->eth.mac[4], 2);
memset((uint8_t *)&high + 2, 0, 2);
high |= 0x80000000;
write_command(device, E1000_REG_RXADDR + 0, low);
@ -152,23 +139,23 @@ static void read_mac(struct e1000_nic * device) {
if (device->has_eeprom) {
uint32_t t;
t = eeprom_read(device, 0);
device->mac[0] = t & 0xFF;
device->mac[1] = t >> 8;
device->eth.mac[0] = t & 0xFF;
device->eth.mac[1] = t >> 8;
t = eeprom_read(device, 1);
device->mac[2] = t & 0xFF;
device->mac[3] = t >> 8;
device->eth.mac[2] = t & 0xFF;
device->eth.mac[3] = t >> 8;
t = eeprom_read(device, 2);
device->mac[4] = t & 0xFF;
device->mac[5] = t >> 8;
device->eth.mac[4] = t & 0xFF;
device->eth.mac[5] = t >> 8;
} else {
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);
device->mac[0] = (mac_addr_low >> 0 ) & 0xFF;
device->mac[1] = (mac_addr_low >> 8 ) & 0xFF;
device->mac[2] = (mac_addr_low >> 16) & 0xFF;
device->mac[3] = (mac_addr_low >> 24) & 0xFF;
device->mac[4] = (mac_addr_high>> 0 ) & 0xFF;
device->mac[5] = (mac_addr_high>> 8 ) & 0xFF;
device->eth.mac[0] = (mac_addr_low >> 0 ) & 0xFF;
device->eth.mac[1] = (mac_addr_low >> 8 ) & 0xFF;
device->eth.mac[2] = (mac_addr_low >> 16) & 0xFF;
device->eth.mac[3] = (mac_addr_low >> 24) & 0xFF;
device->eth.mac[4] = (mac_addr_high>> 0 ) & 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;
free(node);
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_unlock(nic->alert_lock);
@ -302,28 +289,35 @@ static int ioctl_e1000(fs_node_t * node, unsigned long request, void * argp) {
switch (request) {
case SIOCGIFHWADDR:
/* fill argp with mac */
memcpy(argp, nic->mac, 6);
memcpy(argp, nic->eth.mac, 6);
return 0;
case SIOCGIFADDR:
if (nic->ipv4_addr == 0) return -ENOENT;
memcpy(argp, &nic->ipv4_addr, sizeof(nic->ipv4_addr));
if (nic->eth.ipv4_addr == 0) return -ENOENT;
memcpy(argp, &nic->eth.ipv4_addr, sizeof(nic->eth.ipv4_addr));
return 0;
case SIOCSIFADDR:
memcpy(&nic->ipv4_addr, argp, sizeof(nic->ipv4_addr));
memcpy(&nic->eth.ipv4_addr, argp, sizeof(nic->eth.ipv4_addr));
return 0;
case SIOCGIFNETMASK:
if (nic->ipv4_subnet == 0) return -ENOENT;
memcpy(argp, &nic->ipv4_subnet, sizeof(nic->ipv4_subnet));
if (nic->eth.ipv4_subnet == 0) return -ENOENT;
memcpy(argp, &nic->eth.ipv4_subnet, sizeof(nic->eth.ipv4_subnet));
return 0;
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;
case SIOCGIFADDR6:
return -ENOENT;
case SIOCSIFADDR6:
memcpy(&nic->ipv6_addr, argp, sizeof(nic->ipv6_addr));
memcpy(&nic->eth.ipv6_addr, argp, sizeof(nic->eth.ipv6_addr));
return 0;
case SIOCGIFFLAGS: {
@ -338,7 +332,7 @@ static int ioctl_e1000(fs_node_t * node, unsigned long request, void * argp) {
case SIOCGIFMTU: {
uint32_t * mtu = argp;
*mtu = nic->mtu;
*mtu = nic->eth.mtu;
return 0;
}
@ -376,7 +370,7 @@ static int wait_e1000(fs_node_t *node, void * process) {
if (!list_find(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);
return 0;
}
@ -387,7 +381,7 @@ static void e1000_init(void * data) {
nic->rx_phys = mmu_allocate_a_frame() << 12;
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);
}
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) {
nic->rx[i].addr = mmu_allocate_n_frames(2) << 12;
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);
}
//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) {
nic->tx[i].addr = mmu_allocate_n_frames(2) << 12;
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);
}
//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);
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) {
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->device_node = calloc(sizeof(fs_node_t),1);
snprintf(nic->device_node->name, 100, "%s", nic->if_name);
nic->device_node->flags = FS_BLOCKDEVICE; /* NETDEVICE? */
nic->device_node->mask = 0666; /* temporary; shouldn't be doing this with these device files */
nic->device_node->ioctl = ioctl_e1000;
nic->device_node->write = write_e1000;
nic->device_node->read = read_e1000;
nic->device_node->selectcheck = check_e1000;
nic->device_node->selectwait = wait_e1000;
nic->device_node->device = nic;
nic->eth.device_node = calloc(sizeof(fs_node_t),1);
snprintf(nic->eth.device_node->name, 100, "%s", nic->eth.if_name);
nic->eth.device_node->flags = FS_BLOCKDEVICE; /* NETDEVICE? */
nic->eth.device_node->mask = 0666; /* temporary; shouldn't be doing this with these device files */
nic->eth.device_node->ioctl = ioctl_e1000;
nic->eth.device_node->write = write_e1000;
nic->eth.device_node->read = read_e1000;
nic->eth.device_node->selectcheck = check_e1000;
nic->eth.device_node->selectwait = wait_e1000;
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 */
while (1) {
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;
devices[device_count++] = nic;
snprintf(nic->if_name, 31,
snprintf(nic->eth.if_name, 31,
"enp%ds%d",
(int)pci_extract_bus(device),
(int)pci_extract_slot(device));
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);
*(int*)found = 1;