void e1000_getmac(struct e1000 *e, char *mac) { uint32_t temp; temp = e1000_eeprom_read(e, 0); mac[0] = temp &0xff; mac[1] = temp >> 8; temp = e1000_eeprom_read(e, 1); mac[2] = temp &0xff; mac[3] = temp >> 8; temp = e1000_eeprom_read(e, 2); mac[4] = temp &0xff; mac[5] = temp >> 8; }
struct e1000_device * e1000_init_hw(struct pci_device *pcidev) { struct e1000_device *dev; u16 m16; u32 m32; int i; dev = kmalloc(sizeof(struct e1000_device)); /* Assert */ if ( 0x8086 != pcidev->vendor_id ) { kfree(dev); return NULL; } /* Read MMIO */ dev->mmio = pci_read_mmio(pcidev->bus, pcidev->slot, pcidev->func); if ( 0 == dev->mmio ) { kfree(dev); return NULL; } /* Initialize */ mmio_write32(dev->mmio, E1000_REG_IMC, 0xffffffff); mmio_write32(dev->mmio, E1000_REG_CTRL, mmio_read32(dev->mmio, E1000_REG_CTRL) | E1000_CTRL_RST); arch_busy_usleep(100); mmio_write32(dev->mmio, E1000_REG_CTRL, mmio_read32(dev->mmio, E1000_REG_CTRL) | E1000_CTRL_SLU); mmio_write32(dev->mmio, E1000_REG_CTRL_EXT, mmio_read32(dev->mmio, E1000_REG_CTRL_EXT) & ~E1000_CTRL_EXT_LINK_MODE_MASK); #if 0 mmio_write32(dev->mmio, E1000_REG_TXDCTL, E1000_TXDCTL_GRAN_DESC | (128 << E1000_TXDCTL_HTHRESH_SHIFT) | (8 << E1000_TXDCTL_PTHRESH_SHIFT)); #endif switch ( pcidev->device_id ) { case E1000_PRO1000MT: case E1000_82545EM: /* Read MAC address */ m16 = e1000_eeprom_read_8254x(dev->mmio, 0); dev->macaddr[0] = m16 & 0xff; dev->macaddr[1] = (m16 >> 8) & 0xff; m16 = e1000_eeprom_read_8254x(dev->mmio, 1); dev->macaddr[2] = m16 & 0xff; dev->macaddr[3] = (m16 >> 8) & 0xff; m16 = e1000_eeprom_read_8254x(dev->mmio, 2); dev->macaddr[4] = m16 & 0xff; dev->macaddr[5] = (m16 >> 8) & 0xff; break; case E1000_82541PI: case E1000_82573L: /* Read MAC address */ m16 = e1000_eeprom_read(dev->mmio, 0); dev->macaddr[0] = m16 & 0xff; dev->macaddr[1] = (m16 >> 8) & 0xff; m16 = e1000_eeprom_read(dev->mmio, 1); dev->macaddr[2] = m16 & 0xff; dev->macaddr[3] = (m16 >> 8) & 0xff; m16 = e1000_eeprom_read(dev->mmio, 2); dev->macaddr[4] = m16 & 0xff; dev->macaddr[5] = (m16 >> 8) & 0xff; break; case E1000_82567LM: case E1000_82577LM: case E1000_82579LM: /* Read MAC address */ m32 = mmio_read32(dev->mmio, E1000_REG_RAL); dev->macaddr[0] = m32 & 0xff; dev->macaddr[1] = (m32 >> 8) & 0xff; dev->macaddr[2] = (m32 >> 16) & 0xff; dev->macaddr[3] = (m32 >> 24) & 0xff; m32 = mmio_read32(dev->mmio, E1000_REG_RAH); dev->macaddr[4] = m32 & 0xff; dev->macaddr[5] = (m32 >> 8) & 0xff; break; } /* Link up */ mmio_write32(dev->mmio, E1000_REG_CTRL, mmio_read32(dev->mmio, E1000_REG_CTRL) | E1000_CTRL_SLU | E1000_CTRL_VME); /* Multicast array table */ for ( i = 0; i < 128; i++ ) { mmio_write32(dev->mmio, E1000_REG_MTA + i * 4, 0); } /* Start TX/RX */ e1000_setup_rx_desc(dev); e1000_setup_tx_desc(dev); /* Store the parent device information */ dev->pci_device = pcidev; /* Enable interrupt (REG_IMS <- 0x1F6DC, then read REG_ICR ) */ mmio_write32(dev->mmio, E1000_REG_IMS, 0x908e); (void)mmio_read32(dev->mmio, E1000_REG_ICR); /* Register IRQ handler */ register_irq_handler((((pcidev->intr_pin -1) + pcidev->slot) % 4) + 0x10, &e1000_irq_handler, dev); #if 0 kprintf("PCI: %x %x %x %x %x\r\n", pcidev->intr_pin, pcidev->intr_line, (((pcidev->intr_pin -1) + pcidev->slot) % 4) + 1, mmio_read32(dev->mmio, E1000_REG_IMS), mmio_read32(dev->mmio, E1000_REG_ICR)); #endif /* http://msdn.microsoft.com/en-us/library/windows/hardware/ff538017(v=vs.85).aspx */ //mmio_write32(dev->mmio, E1000_REG_ICS, 0x908e); return dev; }