Beispiel #1
0
static uint16_t e1000_read_eeprom_bits(struct e1000_device *device)
{
    uint32_t eecd, i;
    uint16_t data;

    eecd = e1000_reg_read(device, REG_EECD);
    eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
    data = 0;

    for(i = 0; i < 16; i++)
    {
        data <<= 1;
        e1000_raise_eeprom_clock(device, &eecd);

        eecd = e1000_reg_read(device, REG_EECD);

        eecd &= ~E1000_EECD_DI;
        if(eecd & E1000_EECD_DO)
            data |= 1;

        e1000_lower_eeprom_clock(device, &eecd);
    }

    return data;
}
Beispiel #2
0
/*
 * Try to receive a packet.
 */
static ssize_t
e1000_recv(struct netdriver_data * data, size_t max)
{
	e1000_t *e;
	e1000_rx_desc_t *desc;
	unsigned int head, tail, cur;
	char *ptr;
	size_t size;

	e = &e1000_state;

	/* If the queue head and tail are equal, the queue is empty. */
	head = e1000_reg_read(e, E1000_REG_RDH);
	tail = e1000_reg_read(e, E1000_REG_RDT);

	E1000_DEBUG(4, ("%s: head=%u, tail=%u\n", e->name, head, tail));

	if (head == tail)
		return SUSPEND;

	/* Has a packet been received? */
	cur = (tail + 1) % e->rx_desc_count;
	desc = &e->rx_desc[cur];

	if (!(desc->status & E1000_RX_STATUS_DONE))
		return SUSPEND;

	/*
	 * HACK: we expect all packets to fit in a single receive buffer.
	 * Eventually, some sort of support to deal with packets spanning
	 * multiple receive descriptors should be added.  For now, we panic,
	 * so that we can continue after the restart; this is already an
	 * improvement over freezing (the old behavior of this driver).
	 */
	size = desc->length;

	if (!(desc->status & E1000_RX_STATUS_EOP))
		panic("received packet too large");

	/* Copy the packet to the caller. */
	ptr = e->rx_buffer + cur * E1000_IOBUF_SIZE;

	if (size > max)
		size = max;

	netdriver_copyout(data, 0, ptr, size);

	/* Reset the descriptor. */
	desc->status = 0;

	/* Increment tail. */
	e1000_reg_write(e, E1000_REG_RDT, cur);

	/* Return the size of the received packet. */
	return size;
}
Beispiel #3
0
/*
 * Handle an interrupt.
 */
static void
e1000_intr(unsigned int __unused mask)
{
	e1000_t *e;
	u32_t cause;

	E1000_DEBUG(3, ("e1000: interrupt\n"));

	e = &e1000_state;

	/* Reenable interrupts. */
	if (sys_irqenable(&e->irq_hook) != OK)
		panic("failed to re-enable IRQ");

	/* Read the Interrupt Cause Read register. */
	if ((cause = e1000_reg_read(e, E1000_REG_ICR)) != 0) {
		if (cause & E1000_REG_ICR_LSC)
			e1000_link_changed(e);

		if (cause & (E1000_REG_ICR_RXO | E1000_REG_ICR_RXT))
			netdriver_recv();

		if (cause & (E1000_REG_ICR_TXQE | E1000_REG_ICR_TXDW))
			netdriver_send();
	}
}
Beispiel #4
0
static void e1000_write_eeprom_bits(struct e1000_device *device, uint16_t data, uint16_t bitcount)
{
    uint32_t eecd, mask;

    mask = 0x1 << (bitcount - 1);
    eecd = e1000_reg_read(device, REG_EECD);
    eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
    do
    {
        eecd &= ~E1000_EECD_DI;
        if(data & mask)
            eecd |= E1000_EECD_DI;
        e1000_reg_write(device, REG_EECD, eecd);
        e1000_write_flush(device);

        cdi_sleep_ms(5);

        e1000_raise_eeprom_clock(device, &eecd);
        e1000_lower_eeprom_clock(device, &eecd);

        mask >>= 1;
    }
    while(mask);

    eecd &= ~E1000_EECD_DI;
    e1000_reg_write(device, REG_EECD, eecd);
}
Beispiel #5
0
static uint32_t e1000_read_uwire(struct e1000_device *device, uint16_t offset)
{
    uint32_t eecd, i = 0;
    int large_eeprom = 0;

    // TODO: check for post-82544 chip, only run this handling if so
    eecd = e1000_reg_read(device, REG_EECD);
    if(eecd & E1000_EECD_SIZE)
        large_eeprom = 1;
    eecd |= E1000_EECD_REQ;
    e1000_reg_write(device, REG_EECD, eecd);
    eecd = e1000_reg_read(device, REG_EECD);
    while((!(eecd & E1000_EECD_GNT)) && (i++ < 100))
    {
        cdi_sleep_ms(1);
        eecd = e1000_reg_read(device, REG_EECD);
    }
    if(!(eecd & E1000_EECD_GNT))
    {
        eecd &= ~E1000_EECD_REQ;
        e1000_reg_write(device, REG_EECD, eecd);
        return (uint32_t) -1;
    }

    e1000_prep_eeprom(device);

    e1000_write_eeprom_bits(device, EEPROM_READ_OPCODE, 3);
    if(large_eeprom)
        e1000_write_eeprom_bits(device, offset, 8);
    else
        e1000_write_eeprom_bits(device, offset, 6);

    uint32_t data = e1000_read_eeprom_bits(device);

    e1000_standby_eeprom(device);

    // TODO: check for post-82544 chip
    eecd = e1000_reg_read(device, REG_EECD);
    eecd &= ~E1000_EECD_REQ;
    e1000_reg_write(device, REG_EECD, eecd);

    return data;
}
Beispiel #6
0
static void e1000_prep_eeprom(struct e1000_device *device)
{
    uint32_t eecd = e1000_reg_read(device, REG_EECD);

    eecd &= ~(E1000_EECD_SK | E1000_EECD_DI);
    e1000_reg_write(device, REG_EECD, eecd);

    eecd |= E1000_EECD_CS;
    e1000_reg_write(device, REG_EECD, eecd);
}
Beispiel #7
0
/*
 * Try to send a packet.
 */
static int
e1000_send(struct netdriver_data * data, size_t size)
{
	e1000_t *e;
	e1000_tx_desc_t *desc;
	unsigned int head, tail, next;
	char *ptr;

	e = &e1000_state;

	if (size > E1000_IOBUF_SIZE)
		panic("packet too large to send");

	/*
	 * The queue tail must not advance to the point that it is equal to the
	 * queue head, since this condition indicates that the queue is empty.
	 */
	head = e1000_reg_read(e, E1000_REG_TDH);
	tail = e1000_reg_read(e, E1000_REG_TDT);
	next = (tail + 1) % e->tx_desc_count;

	if (next == head)
		return SUSPEND;

	/* The descriptor to use is the one pointed to by the current tail. */
	desc = &e->tx_desc[tail];

	/* Copy the packet from the caller. */
	ptr = e->tx_buffer + tail * E1000_IOBUF_SIZE;

	netdriver_copyin(data, 0, ptr, size);

	/* Mark this descriptor ready. */
	desc->status = 0;
	desc->length = size;
	desc->command = E1000_TX_CMD_EOP | E1000_TX_CMD_FCS | E1000_TX_CMD_RS;

	/* Increment tail.  Start transmission. */
	e1000_reg_write(e, E1000_REG_TDT, next);

	return OK;
}
Beispiel #8
0
/*
 * Clear bits in a register.
 */
static void
e1000_reg_unset(e1000_t * e, uint32_t reg, uint32_t value)
{
	uint32_t data;

	/* First read the current value. */
	data = e1000_reg_read(e, reg);

	/* Unset bits, and write back. */
	e1000_reg_write(e, reg, data & ~value);
}
Beispiel #9
0
/*
 * Read from EEPROM.
 */
static u16_t
eeprom_eerd(e1000_t * e, int reg)
{
	u32_t data;

	/* Request EEPROM read. */
	e1000_reg_write(e, E1000_REG_EERD,
	    (reg << e->eeprom_addr_off) | (E1000_REG_EERD_START));

	/* Wait until ready. */
	while (!((data = (e1000_reg_read(e, E1000_REG_EERD))) &
	    e->eeprom_done_bit));

	return data >> 16;
}
Beispiel #10
0
static void e1000_standby_eeprom(struct e1000_device *device)
{
    uint32_t eecd = e1000_reg_read(device, REG_EECD);

    eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
    e1000_reg_write(device, REG_EECD, eecd);
    e1000_write_flush(device);
    cdi_sleep_ms(5);

    eecd |= E1000_EECD_SK;
    e1000_reg_write(device, REG_EECD, eecd);
    e1000_write_flush(device);
    cdi_sleep_ms(5);

    eecd |= E1000_EECD_CS;
    e1000_reg_write(device, REG_EECD, eecd);
    e1000_write_flush(device);
    cdi_sleep_ms(5);

    eecd &= ~(E1000_EECD_SK);
    e1000_reg_write(device, REG_EECD, eecd);
    e1000_write_flush(device);
    cdi_sleep_ms(5);
}
Beispiel #11
0
/*
 * Return statistics.
 */
static void
e1000_stat(eth_stat_t * stat)
{
	e1000_t *e = &e1000_state;

	E1000_DEBUG(3, ("e1000: stat()\n"));

	stat->ets_recvErr	= e1000_reg_read(e, E1000_REG_RXERRC);
	stat->ets_sendErr	= 0;
	stat->ets_OVW		= 0;
	stat->ets_CRCerr	= e1000_reg_read(e, E1000_REG_CRCERRS);
	stat->ets_frameAll	= 0;
	stat->ets_missedP	= e1000_reg_read(e, E1000_REG_MPC);
	stat->ets_packetR	= e1000_reg_read(e, E1000_REG_TPR);
	stat->ets_packetT	= e1000_reg_read(e, E1000_REG_TPT);
	stat->ets_collision	= e1000_reg_read(e, E1000_REG_COLC);
	stat->ets_transAb	= 0;
	stat->ets_carrSense	= 0;
	stat->ets_fifoUnder	= 0;
	stat->ets_fifoOver	= 0;
	stat->ets_CDheartbeat	= 0;
	stat->ets_OWC		= 0;
}
Beispiel #12
0
/*===========================================================================*
 *				e1000_probe				     *
 *===========================================================================*/
PRIVATE int e1000_probe(e1000_t *e, int skip)
{
    int i, r, devind;
    u16_t vid, did;
    u32_t status[2];
    u32_t gfpreg, sector_base_addr;
    char *dname;

    E1000_DEBUG(3, ("%s: probe()\n", e->name));

    /*
     * 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. */
    for(;;)
    {
	for (i = 0; pcitab_e1000[i] != 0; i++)
	{
	    if (vid != 0x8086)
		continue;
	
	    if (did != pcitab_e1000[i])
		continue;
	    else
		break;
	}
	if (pcitab_e1000[i] != 0)
	{
	    if (!skip)
		break;
	    skip--;
	}

	if (!(r = pci_next_dev(&devind, &vid, &did)))
	{
	    return FALSE;
	}
    }
    /*
     * Successfully detected an Intel Pro/1000 on the PCI bus.
     */
    e->status |= E1000_DETECTED;
    e->eeprom_read = eeprom_eerd;
    
    /*
     * Set card specific properties.
     */
    switch (did)
    {
        case E1000_DEV_ID_ICH10_R_BM_LF:
            e->eeprom_read = eeprom_ich;
            break;

    	case E1000_DEV_ID_82574L:
	case E1000_DEV_ID_82541GI_LF:
	    e->eeprom_done_bit = (1 << 1);
	    e->eeprom_addr_off =  2;
	    break;

	default:
	    e->eeprom_done_bit = (1 << 4);
	    e->eeprom_addr_off =  8;
	    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/%02x) at %s\n",
		     e->name, dname, vid, did, e->revision, 
		     pci_slot_name(devind)));

    /* Reserve PCI resources found. */
    if ((r = pci_reserve_ok(devind)) != OK)
    {
        panic("failed to reserve PCI device: %d", r);
    }
    /* Read PCI configuration. */
    e->irq   = pci_attr_r8(devind, PCI_ILR);
    e->regs  = vm_map_phys(SELF, (void *) pci_attr_r32(devind, PCI_BAR), 
			   0x20000);
			   
    /* Verify mapped registers. */
    if (e->regs == (u8_t *) -1) {
		panic("failed to map hardware registers from PCI");
    }
    /* Optionally map flash memory. */
    if (did != E1000_DEV_ID_82540EM &&
	did != E1000_DEV_ID_82540EP &&
	pci_attr_r32(devind, PCI_BAR_2))
    {
       if((e->flash = vm_map_phys(SELF,
         (void *) pci_attr_r32(devind, PCI_BAR_2), 0x10000)) == MAP_FAILED) {
               if((e->flash = vm_map_phys(SELF,
                       (void *) pci_attr_r32(devind, PCI_BAR_2), 0x1000))
                               == MAP_FAILED) {
                               panic("e1000: couldn't map in flash.");
               }
       }

	gfpreg = E1000_READ_FLASH_REG(e, ICH_FLASH_GFPREG);
        /*
         * sector_base_addr is a "sector"-aligned address (4096 bytes)
         */
        sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;

        /* flash_base_addr is byte-aligned */
        e->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT;
    }
    /*
     * Output debug information.
     */
    status[0] = 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[0] & 3 ? "up"   : "down",
			     status[0] & 1 ? "full" : "half"));
    return TRUE;
}
Beispiel #13
0
/*
 * 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;
}
Beispiel #14
0
static void e1000_write_flush(struct e1000_device *device)
{
    e1000_reg_read(device, REG_STATUS);
}