Esempio n. 1
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);
}
Esempio n. 2
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);
}
Esempio n. 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;
}
Esempio n. 4
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);
}
Esempio n. 5
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;

}
Esempio n. 6
0
size_t e1000_send(struct network_dev *dev, uint8_t *_buf, size_t length)
{
    struct e1000 *e = dev->device;
    e->tx_descs[e->tx_cur]->addr = (uint64_t)(uintptr_t)V2P(_buf);
    e->tx_descs[e->tx_cur]->length = length;
    e->tx_descs[e->tx_cur]->cmd = ((1 << 3) | 3);
    uint8_t old_cur = e->tx_cur;
    e->tx_cur = (e->tx_cur + 1) % NUM_TX_DESC;
    e1000_outl(e, REG_TXDESCTAIL, e->tx_cur);
    while(!(e->tx_descs[old_cur]->status & 0xff));
    return 0;
}
Esempio n. 7
0
void e1000_reset(struct e1000_dev *dev)
{
    uint32_t dev_control;

    // Reset the network controller hardware
    dev_control = 0;
    dev_control |= (1<<0);   // FD-bit (Full Duplex)
    dev_control |= (0<<2);   // GIOMD-bit (GIO Master Disable)
    dev_control |= (1<<3);   // LRST-bit (Link Reset)
    dev_control |= (1<<6);   // SLU-bit (Set Link Up)	
    dev_control |= (2<<8);   // SPEED=2 (1000Mbps)
    dev_control |= (0<<11);  // FRCSPD-bit (Force Speed)
    dev_control |= (0<<12);  // FRCDPLX-bit (Force Duplex)
    dev_control |= (0<<20);  // ADVD3WUC-bit (Advertise D3 Wake Up Cap)
    dev_control |= (1<<26);  // RST-bit (Device Reset)
    dev_control |= (1<<27);  // RFCE-bit (Receive Flow Control Enable)
    dev_control |= (1<<28);  // TFCE-bit (Transmit Flow Control Enable) 
    dev_control |= (0<<30);  // VME-bit (VLAN Mode Enable) 
    dev_control |= (0<<31);  // PHY_RST-bit (PHY Reset)

    e1000_outl(dev, E1000_IMC, 0xFFFFFFFF);
    e1000_outl(dev, E1000_STATUS, 0x00000000);
    e1000_outl(dev, E1000_CTRL, dev_control);
    dev_control &= ~(1<<26);  // clear RST-bit (Device Reset)
    e1000_outl(dev, E1000_CTRL, dev_control);	
    up_mdelay(10);
    e1000_outl(dev, E1000_CTRL_EXT, 0x001401C0);
    e1000_outl(dev, E1000_IMC, 0xFFFFFFFF);
}
Esempio n. 8
0
void e1000_txinit(struct e1000 *e)
{
    uintptr_t ptr;
    struct e1000_tx_desc *descs;
    ptr = (uintptr_t)(kmalloc(sizeof(struct e1000_tx_desc)*NUM_TX_DESC + 16));
    e->tx_free = (uint8_t *)ptr;
    if(ptr % 16 != 0)
        ptr = (ptr + 16) - (ptr % 16);
    descs = (struct e1000_tx_desc *)ptr;
    for(int i = 0; i < NUM_TX_DESC; i++)
    {
        e->tx_descs[i] = (struct e1000_tx_desc *)((uintptr_t)descs + i*16);
        e->tx_descs[i]->addr = 0;
        e->tx_descs[i]->cmd = 0;
    }

    //give the card the pointer to the descriptors
    e1000_outl(e, REG_TXDESCLO, V2P(ptr));
    e1000_outl(e, REG_TXDESCHI, 0);

    //now setup total length of descriptors
    e1000_outl(e, REG_TXDESCLEN, NUM_TX_DESC * 16);

    //setup numbers
    e1000_outl(e, REG_TXDESCHEAD, 0);
    e1000_outl(e, REG_TXDESCTAIL, NUM_TX_DESC);
    e->tx_cur = 0;

    e1000_outl(e, REG_TCTRL, (1 << 1) | (1 << 3));
}
Esempio n. 9
0
void e1000_rxinit(struct e1000 *e)
{
    uintptr_t ptr;
    struct e1000_rx_desc *descs;
    ptr = (uintptr_t)(kmalloc(sizeof(struct e1000_rx_desc)*NUM_RX_DESC + 16));
    e->rx_free = (uint8_t *)ptr;
    if(ptr % 16 != 0)
        ptr = (ptr + 16) - (ptr % 16);
    descs = (struct e1000_rx_desc *)ptr;
    for(int i = 0; i < NUM_RX_DESC; i++)
    {
        e->rx_descs[i] = (struct e1000_rx_desc *)((uintptr_t)descs + i*16);
        e->rx_descs[i]->addr = (uint64_t)(uintptr_t)V2P(kmalloc(8192 + 16));
        e->rx_descs[i]->status = 0;
    }

    //give the card the pointer to the descriptors
    e1000_outl(e, REG_RXDESCLO, V2P(ptr));
    e1000_outl(e, REG_RXDESCHI, 0);

    //now setup total length of descriptors
    e1000_outl(e, REG_RXDESCLEN, NUM_RX_DESC * 16);

    //setup numbers
    e1000_outl(e, REG_RXDESCHEAD, 0);
    e1000_outl(e, REG_RXDESCTAIL, NUM_RX_DESC);
    e->rx_cur = 0;

    //enable receiving
    //uint32_t flags = (2 << 16) | (1 << 25) | (1 << 26) | (1 << 15) | (1 << 5) | (0 << 8) | (1 << 4) | (1 << 3) | ( 1 << 2);
    uint32_t flags = (2 << 16) | (1 << 25) | (1 << 26) | (1 << 15) | (1 << 5) | (0 << 8) | (0 << 4) | (0 << 3) | ( 1 << 2);
//	uint32_t flags = (2 << 16) | (1 << 25) | (1 << 26) | (1 << 15) | (1 << 5) | (0 << 8) | (1 << 4) | ( 1 << 2);
//	e1000_outl(e, REG_RCTRL, RCTRL_8192 | RCTRL_MPE);
    e1000_outl(e, REG_RCTRL, flags);//RCTRL_8192 | RCTRL_MPE | RCTRL_UPE |RCTRL_EN);
}
Esempio n. 10
0
void e1000_start(struct e1000 *e)
{
    //set link up
    e1000_linkup(e);
    //have to clear out the multicast filter, otherwise shit breaks
    for(int i = 0; i < 0x80; i++)
        e1000_outl(e, 0x5200 + i*4, 0);

    e1000_interrupt_enable(e);

    e1000_rxinit(e);
    e1000_txinit(e);
}
Esempio n. 11
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;
    }
}
Esempio n. 12
0
void e1000_received(struct e1000 *e)
{
    struct sockbuf *sb;
    uint16_t old_cur;
    while((e->rx_descs[e->rx_cur]->status & 0x1))
    {
        uint8_t *buf = (void *)(uintptr_t)P2V(e->rx_descs[e->rx_cur]->addr);
        uint16_t len = e->rx_descs[e->rx_cur]->length;

        sb = sockbuf_alloc(e->dev, len);
        kmemcpy(sb->data, buf, len);
        network_received(sb);
        e->rx_descs[e->rx_cur]->status = 0;
        old_cur = e->rx_cur;
        e->rx_cur = (e->rx_cur + 1) % NUM_RX_DESC;
        e1000_outl(e, REG_RXDESCTAIL, old_cur ) ;
    }
}
Esempio n. 13
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;
}
Esempio n. 14
0
static int e1000_transmit(struct e1000_dev *e1000)
{
    int tail = e1000->tx_ring.tail;
    unsigned char *cp = (unsigned char *)
                        (e1000->tx_ring.buf + tail * CONFIG_E1000_BUFF_SIZE);
    int count = e1000->netdev.d_len;

    /* Verify that the hardware is ready to send another packet.  If we get
     * here, then we are committed to sending a packet; Higher level logic
     * must have assured that there is not transmission in progress.
     */

    if (!e1000->tx_ring.desc[tail].desc_status)
    {
        return -1;
    }

    /* Increment statistics */

    /* Send the packet: address=skel->sk_dev.d_buf, length=skel->sk_dev.d_len */

    memcpy(cp, e1000->netdev.d_buf, e1000->netdev.d_len);

    /* prepare the transmit-descriptor */

    e1000->tx_ring.desc[tail].packet_length = count < 60 ? 60 : count;
    e1000->tx_ring.desc[tail].desc_status = 0;

    /* give ownership of this descriptor to the network controller */

    tail = (tail + 1) % CONFIG_E1000_N_TX_DESC;
    e1000->tx_ring.tail = tail;
    e1000_outl(e1000, E1000_TDT, tail);

    /* Enable Tx interrupts */

    /* Setup the TX timeout watchdog (perhaps restarting the timer) */

    wd_start(e1000->txtimeout, E1000_TXTIMEOUT, e1000_txtimeout, 1, (uint32_t)e1000);
    return OK;
}
Esempio n. 15
0
void e1000_linkup(struct e1000 *e)
{
    uint32_t val;
    val = e1000_inl(e,REG_CTRL);
    e1000_outl(e, REG_CTRL, val | ECTRL_SLU);
}
Esempio n. 16
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);
}
Esempio n. 17
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);
}