static int init_device(int devind, struct virtio_device *dev) { u32_t base, size; int iof, r; pci_reserve(devind); if ((r = pci_get_bar(devind, PCI_BAR, &base, &size, &iof)) != OK) { printf("%s: Could not get BAR (%d)", dev->name, r); return r; } if (!iof) { printf("%s: PCI not IO space?", dev->name); return EINVAL; } if (base & 0xFFFF0000) { printf("%s: IO port weird (%08x)", dev->name, base); return EINVAL; } /* store the I/O port */ dev->port = base; /* Reset the device */ virtio_write8(dev, VIRTIO_DEV_STATUS_OFF, 0); /* Read IRQ line */ dev->irq = pci_attr_r8(devind, PCI_ILR); return OK; }
struct network_dev *e1000_init() { struct network_dev *device = kcalloc(sizeof(*device), 1); struct e1000 *e = (struct e1000 *)kmalloc(sizeof(*e)); e1000_global = e; device->device = e; e->dev = device; e->pci = pci_get_device(INTEL_VEND, E1000_DEV); if(e->pci == NULL) { e->pci = pci_get_device(INTEL_VEND, 0x109a); } if(e->pci == NULL) { e->pci = pci_get_device(INTEL_VEND, 0x100f); } if(e->pci != NULL) { e->pci_hdr = e->pci->header; printf("Intel Pro/1000 Ethernet adapter Rev %i found at ", e->pci_hdr->rev); e->io_base = pci_get_bar(e->pci, PCI_BAR_IO) & ~1; printf("I/O base address %x\n",e->io_base); //e->mem_base = (uint8_t *)(pci_get_bar(e->pci, PCI_BAR_MEM) & ~3); //printf("mem base %x\n",e->mem_base); printf("IRQ %i PIN %i\n",e->pci_hdr->int_line, e->pci_hdr->int_pin); e1000_eeprom_gettype(e); e1000_getmac(e, (char *)device->mac); print_mac((char *)&device->mac); // for(int i = 0; i < 6; i++) // e1000_outb(e,0x5400 + i, device->mac[i]); pci_register_irq(e->pci, &e1000_handler, e); e1000_start(e); device->send = e1000_send; // device->receive = e1000_receive; uint32_t flags = e1000_inl(e, REG_RCTRL); e1000_outl(e, REG_RCTRL, flags | RCTRL_EN);//RCTRL_8192 | RCTRL_MPE | RCTRL_UPE |RCTRL_EN); } else { kfree(e); kfree(device); e = NULL; device = NULL; } return device; }
struct network_dev * rtl8139_init() { struct network_dev *device = kmalloc(sizeof(*device)); struct rtl8139 *rtl = (struct rtl8139 *)kmalloc(sizeof(*rtl)); global = rtl; device->device = rtl; rtl->dev = device; rtl->pci = pci_get_device(RTL8139_VEND, RTL8139_DEV); rtl->rx_buffer = pallocn(2);//kmalloc(RX_BUF_LEN + RX_BUF_PAD); //FIXME: Wat Wat Wat rtl->tx_buffers = (void *)P2V(0x3380000);//kmalloc((8192+16+1500)*4); if(rtl->pci != NULL) { rtl->pci_hdr = rtl->pci->header; rtl->io_base = pci_get_bar(rtl->pci, PCI_BAR_IO) & ~1; rtl->mem_base = (uint8_t *)(pci_get_bar(rtl->pci, PCI_BAR_MEM) & ~3); rtl8139_start(rtl); rtl8139_getmac(rtl,(char *)&device->mac); device->send = rtl8139_send; printf("Realtek 8139 Ethernet adapter Rev %i found\t", rtl->pci_hdr->rev); printf("io base %x ",rtl->io_base); printf("mem base %x\n",rtl->mem_base); // device->receive = rtl8139_receive; print_mac((char *)&device->mac); printf("%X\n",rtl->dev); } else { kfree(rtl->rx_buffer); kfree(rtl); rtl = NULL; device = NULL; } return device; }
/*===========================================================================* * atl2_init * *===========================================================================*/ static void atl2_init(int devind) { /* Initialize the device. */ u32_t bar; int r, flag; /* Initialize global state. */ state.devind = devind; state.mode = DL_NOMODE; state.flags = 0; state.recv_count = 0; memset(&state.stat, 0, sizeof(state.stat)); if ((r = pci_get_bar(devind, PCI_BAR, &bar, &state.size, &flag)) != OK) panic("unable to retrieve bar: %d", r); if (state.size < ATL2_MIN_MMAP_SIZE || flag) panic("invalid register bar"); state.base = vm_map_phys(SELF, (void *) bar, state.size); if (state.base == MAP_FAILED) panic("unable to map in registers"); if ((r = atl2_alloc_dma()) != OK) panic("unable to allocate DMA buffers: %d", r); state.irq = pci_attr_r8(devind, PCI_ILR); if ((r = sys_irqsetpolicy(state.irq, 0, &state.hook_id)) != OK) panic("unable to register IRQ: %d", r); if (!atl2_reset()) panic("unable to reset hardware"); if ((r = sys_irqenable(&state.hook_id)) != OK) panic("unable to enable IRQ: %d", r); atl2_get_hwaddr(); atl2_setup(); }
/* * Find a matching device. Return TRUE on success. */ static int e1000_probe(e1000_t * e, int skip) { int r, devind, ioflag; u16_t vid, did, cr; u32_t status; u32_t base, size; char *dname; E1000_DEBUG(3, ("%s: probe()\n", e->name)); /* Initialize communication to the PCI driver. */ pci_init(); /* Attempt to iterate the PCI bus. Start at the beginning. */ if ((r = pci_first_dev(&devind, &vid, &did)) == 0) return FALSE; /* Loop devices on the PCI bus. */ while (skip--) { E1000_DEBUG(3, ("%s: probe() devind %d vid 0x%x did 0x%x\n", e->name, devind, vid, did)); if (!(r = pci_next_dev(&devind, &vid, &did))) return FALSE; } /* We found a matching card. Set card-specific properties. */ e->eeprom_read = eeprom_eerd; switch (did) { case E1000_DEV_ID_ICH10_D_BM_LM: case E1000_DEV_ID_ICH10_R_BM_LF: e->eeprom_read = eeprom_ich; break; case E1000_DEV_ID_82540EM: case E1000_DEV_ID_82545EM: case E1000_DEV_ID_82540EP_LP: e->eeprom_done_bit = (1 << 4); e->eeprom_addr_off = 8; break; default: e->eeprom_done_bit = (1 << 1); e->eeprom_addr_off = 2; break; } /* Inform the user about the new card. */ if (!(dname = pci_dev_name(vid, did))) dname = "Intel Pro/1000 Gigabit Ethernet Card"; E1000_DEBUG(1, ("%s: %s (%04x/%04x) at %s\n", e->name, dname, vid, did, pci_slot_name(devind))); /* Reserve PCI resources found. */ pci_reserve(devind); /* Read PCI configuration. */ e->irq = pci_attr_r8(devind, PCI_ILR); if ((r = pci_get_bar(devind, PCI_BAR, &base, &size, &ioflag)) != OK) panic("failed to get PCI BAR: %d", r); if (ioflag) panic("PCI BAR is not for memory"); if ((e->regs = vm_map_phys(SELF, (void *)base, size)) == MAP_FAILED) panic("failed to map hardware registers from PCI"); /* Enable DMA bus mastering if necessary. */ cr = pci_attr_r16(devind, PCI_CR); if (!(cr & PCI_CR_MAST_EN)) pci_attr_w16(devind, PCI_CR, cr | PCI_CR_MAST_EN); /* Optionally map flash memory. */ e1000_map_flash(e, devind, did); /* Output debug information. */ status = e1000_reg_read(e, E1000_REG_STATUS); E1000_DEBUG(3, ("%s: MEM at %p, IRQ %d\n", e->name, e->regs, e->irq)); E1000_DEBUG(3, ("%s: link %s, %s duplex\n", e->name, status & 3 ? "up" : "down", status & 1 ? "full" : "half")); return TRUE; }