Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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);
}
Пример #6
0
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;

}
Пример #7
0
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;
}
Пример #8
0
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;
    }
}
Пример #9
0
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);
}
Пример #10
0
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);
}
Пример #11
0
void e1000_interrupt_enable(struct e1000 *e)
{
    e1000_outl(e,REG_IMASK ,0x1F6DC);
    e1000_outl(e,REG_IMASK ,0xff & ~4);
    e1000_inl(e,0xc0);
}
Пример #12
0
void e1000_linkup(struct e1000 *e)
{
    uint32_t val;
    val = e1000_inl(e,REG_CTRL);
    e1000_outl(e, REG_CTRL, val | ECTRL_SLU);
}