[dev][e1000] add an atomic counter to number the e1000s found

This commit is contained in:
Travis Geiselbrecht
2022-01-11 00:15:10 -08:00
parent 18330c5948
commit f3a337789c
2 changed files with 32 additions and 17 deletions

View File

@@ -5,6 +5,7 @@
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <arch/atomic.h>
#include <lk/init.h>
#include <lk/err.h>
#include <lk/cpp.h>
@@ -73,6 +74,10 @@ private:
void add_pktbuf_to_rxring(pktbuf_t *pkt);
void add_pktbuf_to_rxring_locked(pktbuf_t *pkt);
// counter of configured deices
static volatile int global_count_;
int unit_ = 0;
// main spinlock
spin_lock_t lock_ = SPIN_LOCK_INITIAL_VALUE;
@@ -133,6 +138,8 @@ uint16_t e1000::read_eeprom(uint8_t offset) {
return val >> 16;
}
volatile int e1000::global_count_ = 0;
e1000::e1000() = default;
e1000::~e1000() {
// TODO: free resources
@@ -301,20 +308,20 @@ void e1000::add_pktbuf_to_rxring(pktbuf_t *pkt) {
status_t e1000::init_device(pci_location_t loc, const e1000_id_features *id) {
loc_ = loc;
id_feat_ = id;
char str[32];
char str[14];
LTRACEF("pci location %s\n", pci_loc_string(loc_, str));
pci_bar_t bars[6];
size_t count;
status_t err = pci_bus_mgr_read_bars(loc_, bars, &count);
size_t bar_count;
status_t err = pci_bus_mgr_read_bars(loc_, bars, &bar_count);
if (err != NO_ERROR) return err;
if (count < 2) {
if (bar_count < 2) {
return ERR_NOT_FOUND;
}
LTRACEF("e1000 BARS:\n");
if (LOCAL_TRACE) pci_dump_bars(bars, count);
if (LOCAL_TRACE) pci_dump_bars(bars, bar_count);
if (!bars[0].valid) {
return ERR_NOT_FOUND;
@@ -322,8 +329,12 @@ status_t e1000::init_device(pci_location_t loc, const e1000_id_features *id) {
pci_bus_mgr_enable_device(loc_);
// allocate a unit number
unit_ = atomic_add(&global_count_, 1);
// map bar 0, main memory mapped register interface, 128KB
err = vmm_alloc_physical(vmm_get_kernel_aspace(), "e1000_bar0", 128*1024, &bar0_regs_, 0,
snprintf(str, sizeof(str), "e1000 %d bar0", unit_);
err = vmm_alloc_physical(vmm_get_kernel_aspace(), str, 128*1024, &bar0_regs_, 0,
bars[0].addr, /* vmm_flags */ 0, ARCH_MMU_FLAG_UNCACHED_DEVICE);
if (err != NO_ERROR) {
return ERR_NOT_FOUND;
@@ -343,11 +354,12 @@ status_t e1000::init_device(pci_location_t loc, const e1000_id_features *id) {
mac_addr_[4] = tmp & 0xff;
mac_addr_[5] = tmp >> 8;
printf("e1000: mac address %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr_[0], mac_addr_[1], mac_addr_[2],
printf("e1000 %d: mac address %02x:%02x:%02x:%02x:%02x:%02x\n", unit_, mac_addr_[0], mac_addr_[1], mac_addr_[2],
mac_addr_[3], mac_addr_[4], mac_addr_[5]);
// allocate and map space for the rx and tx ring
err = vmm_alloc_contiguous(vmm_get_kernel_aspace(), "e1000 rxring", rxring_len * sizeof(rdesc), (void **)&rxring_, 0, 0, ARCH_MMU_FLAG_UNCACHED);
snprintf(str, sizeof(str), "e1000 %d rxring", unit_);
err = vmm_alloc_contiguous(vmm_get_kernel_aspace(), str, rxring_len * sizeof(rdesc), (void **)&rxring_, 0, 0, ARCH_MMU_FLAG_UNCACHED);
if (err != NO_ERROR) {
return ERR_NOT_FOUND;
}
@@ -356,7 +368,8 @@ status_t e1000::init_device(pci_location_t loc, const e1000_id_features *id) {
paddr_t rxring_phys = vaddr_to_paddr(rxring_);
LTRACEF("rx ring at %p, physical %#lx\n", rxring_, rxring_phys);
err = vmm_alloc_contiguous(vmm_get_kernel_aspace(), "e1000 txring", txring_len * sizeof(tdesc), (void **)&txring_, 0, 0, ARCH_MMU_FLAG_UNCACHED);
snprintf(str, sizeof(str), "e1000 %d txring", unit_);
err = vmm_alloc_contiguous(vmm_get_kernel_aspace(), str, txring_len * sizeof(tdesc), (void **)&txring_, 0, 0, ARCH_MMU_FLAG_UNCACHED);
if (err != NO_ERROR) {
return ERR_NOT_FOUND;
}
@@ -366,7 +379,8 @@ status_t e1000::init_device(pci_location_t loc, const e1000_id_features *id) {
LTRACEF("tx ring at %p, physical %#lx\n", txring_, txring_phys);
// allocate a large array of contiguous buffers to receive into
err = vmm_alloc_contiguous(vmm_get_kernel_aspace(), "e1000 rx buffers", rxring_len * rxbuffer_len, (void **)&rx_buf_, 0, 0, 0);
snprintf(str, sizeof(str), "e1000 %d rx buffers", unit_);
err = vmm_alloc_contiguous(vmm_get_kernel_aspace(), str, rxring_len * rxbuffer_len, (void **)&rx_buf_, 0, 0, 0);
if (err != NO_ERROR) {
return ERR_NOT_FOUND;
}
@@ -392,10 +406,6 @@ status_t e1000::init_device(pci_location_t loc, const e1000_id_features *id) {
write_reg(e1000_reg::EITR4, 1000000 / irq_rate * 4);
}
// set up minip's macaddr
// TODO: move to something smarter
minip_set_macaddr(mac_addr_);
// disable tx and rx
write_reg(e1000_reg::RCTL, 0);
write_reg(e1000_reg::TCTL, 0);
@@ -422,6 +432,10 @@ status_t e1000::init_device(pci_location_t loc, const e1000_id_features *id) {
}
LTRACEF("IRQ number %#x\n", irq_base);
// set up minip's macaddr
// TODO: move to something smarter
minip_set_macaddr(mac_addr_);
unmask_interrupt(irq_base);
// set up the rx ring
@@ -466,7 +480,8 @@ status_t e1000::init_device(pci_location_t loc, const e1000_id_features *id) {
e1000 *e = (e1000 *)arg;
return e->rx_worker_routine();
};
rx_worker_thread_ = thread_create("e1000 rx worker", wrapper_lambda, this, HIGH_PRIORITY, DEFAULT_STACK_SIZE);
snprintf(str, sizeof(str), "e1000 %d rx worker", unit_);
rx_worker_thread_ = thread_create(str, wrapper_lambda, this, HIGH_PRIORITY, DEFAULT_STACK_SIZE);
thread_resume(rx_worker_thread_);
// start receiver

View File

@@ -113,8 +113,8 @@ if (( $DO_NET )); then
if (( ! $DO_NET_TAP )); then
ARGS+=" -netdev user,id=vmnic,hostname=qemu"
# quick note to enable tap interface
# IFNAME=qemu
# BRIDGE=br0
# IFNAME=qemu0
# BRIDGE=bridge0
# sudo tunctl -u $(whoami) -t ${IFNAME}
# sudo ifconfig ${IFNAME} up
# sudo ip link set ${IFNAME} master ${BRIDGE}