void e1000_turn_on(struct e1000_dev *dev) { int tx_control; int rx_control; uint32_t ims = 0; /* turn on the controller's receive engine */ rx_control = e1000_inl(dev, E1000_RCTL); rx_control |= (1 << 1); e1000_outl(dev, E1000_RCTL, rx_control); /* turn on the controller's transmit engine */ tx_control = e1000_inl(dev, E1000_TCTL); tx_control |= (1 << 1); e1000_outl(dev, E1000_TCTL, tx_control); /* enable the controller's interrupts */ e1000_outl(dev, E1000_ICR, 0xFFFFFFFF); e1000_outl(dev, E1000_IMC, 0xFFFFFFFF); ims |= 1 << 0; /* TXDW */ ims |= 1 << 1; /* TXQE */ ims |= 1 << 2; /* LSC */ ims |= 1 << 4; /* RXDMT0 */ ims |= 1 << 7; /* RXT0 */ e1000_outl(dev, E1000_IMS, ims); }
void e1000_turn_on(struct e1000_dev *dev) { int tx_control, rx_control; uint32_t ims = 0; // turn on the controller's receive engine rx_control = e1000_inl(dev, E1000_RCTL); rx_control |= (1<<1); e1000_outl(dev, E1000_RCTL, rx_control); // turn on the controller's transmit engine tx_control = e1000_inl(dev, E1000_TCTL); tx_control |= (1<<1); e1000_outl(dev, E1000_TCTL, tx_control); // enable the controller's interrupts e1000_outl(dev, E1000_ICR, 0xFFFFFFFF); e1000_outl(dev, E1000_IMC, 0xFFFFFFFF); ims |= 1<<0; // TXDW ims |= 1<<1; // TXQE ims |= 1<<2; // LSC ims |= 1<<4; // RXDMT0 ims |= 1<<7; // RXT0 e1000_outl(dev, E1000_IMS, ims); }
static irqreturn_t e1000_interrupt_handler(int irq, void *dev_id) { struct e1000_dev *e1000 = (struct e1000_dev *)dev_id; /* Get and clear interrupt status bits */ int intr_cause = e1000_inl(e1000, E1000_ICR); e1000_outl(e1000, E1000_ICR, intr_cause); // not for me if (intr_cause == 0) return IRQ_NONE; /* Handle interrupts according to status bit settings */ // Link status change if (intr_cause & (1<<2)) { if (e1000_inl(e1000, E1000_STATUS) & 2) e1000->bifup = true; else e1000->bifup = false; } /* Check if we received an incoming packet, if so, call skel_receive() */ // Rx-descriptor Timer expired if (intr_cause & (1<<7)) e1000_receive(e1000); // Tx queue empty if (intr_cause & (1<<1)) wd_cancel(e1000->txtimeout); /* Check is a packet transmission just completed. If so, call skel_txdone. * This may disable further Tx interrupts if there are no pending * tansmissions. */ // Tx-descriptor Written back if (intr_cause & (1<<0)) uip_poll(&e1000->uip_dev, e1000_uiptxpoll); // Rx-Descriptors Low if (intr_cause & (1<<4)) { int tail; tail = e1000->rx_ring.tail + e1000->rx_ring.free; tail %= CONFIG_E1000_N_RX_DESC; e1000->rx_ring.tail = tail; e1000->rx_ring.free = 0; e1000_outl(e1000, E1000_RDT, tail); } return IRQ_HANDLED; }
static int e1000_ifup(struct net_driver_s *dev) { struct e1000_dev *e1000 = (struct e1000_dev *)dev->d_private; ndbg("Bringing up: %d.%d.%d.%d\n", dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); /* Initialize PHYs, the Ethernet interface, and setup up Ethernet interrupts */ e1000_init(e1000); /* Set and activate a timer process */ (void)wd_start(e1000->txpoll, E1000_WDDELAY, e1000_polltimer, 1, (uint32_t)e1000); if (e1000_inl(e1000, E1000_STATUS) & 2) { e1000->bifup = true; } else { e1000->bifup = false; } return OK; }
void e1000_turn_off(struct e1000_dev *dev) { int tx_control, rx_control; // turn off the controller's receive engine rx_control = e1000_inl(dev, E1000_RCTL); rx_control &= ~(1<<1); e1000_outl(dev, E1000_RCTL, rx_control); // turn off the controller's transmit engine tx_control = e1000_inl(dev, E1000_TCTL); tx_control &= ~(1<<1); e1000_outl(dev, E1000_TCTL, tx_control); // turn off the controller's interrupts e1000_outl(dev, E1000_IMC, 0xFFFFFFFF); }
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; }
uint32_t e1000_eeprom_read(struct e1000 *e, uint8_t addr) { uint32_t val = 0; uint32_t test; if(e->is_e == 0) test = addr << 8; else test = addr << 2; e1000_outl(e, REG_EEPROM, test | 0x1); if(e->is_e == 0) while(!((val = e1000_inl(e, REG_EEPROM)) & (1<<4))) ;// printf("is %i val %x\n",e->is_e,val); else while(!((val = e1000_inl(e, REG_EEPROM)) & (1<<1))) ;// printf("is %i val %x\n",e->is_e,val); val >>= 16; return val; }
void e1000_eeprom_gettype(struct e1000 *e) { uint32_t val = 0; e1000_outl(e, REG_EEPROM, 0x1); for(int i = 0; i < 1000; i++)///while( val & 0x2 || val & 0x10) { val = e1000_inl(e, REG_EEPROM); if(val & 0x10) e->is_e = 0; else e->is_e = 1; } }
void e1000_handler(void *aux) { struct e1000 *e = aux; uint32_t status = e1000_inl(e, 0xc0); if(status & 0x04) { e1000_linkup(e); } if(status & 0x10) { printf("threshold good\n"); } if(status & 0x80) { e1000_received(e); } // printf("e1000 IRQ %x\n",status); // e1000_inl(e,0xc0); }
void e1000_init(struct e1000_dev *dev) { uint32_t rxd_phys, txd_phys, kmem_phys; uint32_t rx_control, tx_control; uint32_t pba; int i; e1000_reset(dev); // configure the controller's 'receive' engine rx_control = 0; rx_control |= (0<<1); // EN-bit (Enable) rx_control |= (0<<2); // SPB-bit (Store Bad Packets) rx_control |= (0<<3); // UPE-bit (Unicast Promiscuous Mode) rx_control |= (1<<4); // MPE-bit (Multicast Promiscuous Mode) rx_control |= (0<<5); // LPE-bit (Long Packet Enable) rx_control |= (0<<6); // LBM=0 (Loop-Back Mode) rx_control |= (0<<8); // RDMTS=0 (Rx Descriptor Min Threshold Size) rx_control |= (0<<10); // DTYPE=0 (Descriptor Type) rx_control |= (0<<12); // MO=0 (Multicast Offset) rx_control |= (1<<15); // BAM-bit (Broadcast Address Mode) rx_control |= (0<<16); // BSIZE=0 (Buffer Size = 2048) rx_control |= (0<<18); // VLE-bit (VLAN filter Enable) rx_control |= (0<<19); // CFIEN-bit (Canonical Form Indicator Enable) rx_control |= (0<<20); // CFI-bit (Canonical Form Indicator) rx_control |= (1<<22); // DPF-bit (Discard Pause Frames) rx_control |= (0<<23); // PMCF-bit (Pass MAC Control Frames) rx_control |= (0<<25); // BSEX=0 (Buffer Size EXtension) rx_control |= (1<<26); // SECRC-bit (Strip Ethernet CRC) rx_control |= (0<<27); // FLEXBUF=0 (Flexible Buffer size) e1000_outl(dev, E1000_RCTL, rx_control); // configure the controller's 'transmit' engine tx_control = 0; tx_control |= (0<<1); // EN-bit (Enable) tx_control |= (1<<3); // PSP-bit (Pad Short Packets) tx_control |= (15<<4); // CT=15 (Collision Threshold) tx_control |= (63<<12); // COLD=63 (Collision Distance) tx_control |= (0<<22); // SWXOFF-bit (Software XOFF) tx_control |= (1<<24); // RTLC-bit (Re-Transmit on Late Collision) tx_control |= (0<<25); // UNORTX-bit (Underrun No Re-Transmit) tx_control |= (0<<26); // TXCSCMT=0 (TxDesc Mininum Threshold) tx_control |= (0<<28); // MULR-bit (Multiple Request Support) e1000_outl(dev, E1000_TCTL, tx_control); // hardware flow control pba = e1000_inl(dev, E1000_PBA); // get receive FIFO size pba = (pba & 0x000000ff)<<10; e1000_outl(dev, E1000_FCAL, 0x00C28001); e1000_outl(dev, E1000_FCAH, 0x00000100); e1000_outl(dev, E1000_FCT, 0x00008808); e1000_outl(dev, E1000_FCTTV, 0x00000680); e1000_outl(dev, E1000_FCRTL, (pba*8/10)|0x80000000); e1000_outl(dev, E1000_FCRTH, pba*9/10); // setup tx rings txd_phys = PADDR((uintptr_t)dev->tx_ring.desc); kmem_phys = PADDR((uintptr_t)dev->tx_ring.buf); for (i=0; i<CONFIG_E1000_N_TX_DESC; i++,kmem_phys+=CONFIG_E1000_BUFF_SIZE) { dev->tx_ring.desc[i].base_address = kmem_phys; dev->tx_ring.desc[i].packet_length = 0; dev->tx_ring.desc[i].cksum_offset = 0; dev->tx_ring.desc[i].cksum_origin = 0; dev->tx_ring.desc[i].desc_status = 1; dev->tx_ring.desc[i].desc_command = (1<<0)|(1<<1)|(1<<3); dev->tx_ring.desc[i].special_info = 0; } dev->tx_ring.tail = 0; e1000_outl(dev, E1000_TDT, 0); e1000_outl(dev, E1000_TDH, 0); // tell controller the location, size, and fetch-policy for Tx queue e1000_outl(dev, E1000_TDBAL, txd_phys); e1000_outl(dev, E1000_TDBAH, 0x00000000); e1000_outl(dev, E1000_TDLEN, CONFIG_E1000_N_TX_DESC*16); e1000_outl(dev, E1000_TXDCTL, 0x01010000); // setup rx rings rxd_phys = PADDR((uintptr_t)dev->rx_ring.desc); kmem_phys = PADDR((uintptr_t)dev->rx_ring.buf); for (i=0; i<CONFIG_E1000_N_RX_DESC; i++,kmem_phys+=CONFIG_E1000_BUFF_SIZE) { dev->rx_ring.desc[i].base_address = kmem_phys; dev->rx_ring.desc[i].packet_length = 0; dev->rx_ring.desc[i].packet_cksum = 0; dev->rx_ring.desc[i].desc_status = 0; dev->rx_ring.desc[i].desc_errors = 0; dev->rx_ring.desc[i].vlan_tag = 0; } dev->rx_ring.head = 0; dev->rx_ring.tail = CONFIG_E1000_N_RX_DESC-1; dev->rx_ring.free = 0; // give the controller ownership of all receive descriptors e1000_outl(dev, E1000_RDH, 0); e1000_outl(dev, E1000_RDT, CONFIG_E1000_N_RX_DESC-1); // tell controller the location, size, and fetch-policy for RX queue e1000_outl(dev, E1000_RDBAL, rxd_phys); e1000_outl(dev, E1000_RDBAH, 0x00000000); e1000_outl(dev, E1000_RDLEN, CONFIG_E1000_N_RX_DESC*16); e1000_outl(dev, E1000_RXDCTL, 0x01010000); e1000_turn_on(dev); }
void e1000_interrupt_enable(struct e1000 *e) { e1000_outl(e,REG_IMASK ,0x1F6DC); e1000_outl(e,REG_IMASK ,0xff & ~4); e1000_inl(e,0xc0); }
void e1000_linkup(struct e1000 *e) { uint32_t val; val = e1000_inl(e,REG_CTRL); e1000_outl(e, REG_CTRL, val | ECTRL_SLU); }