Пример #1
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);
}
Пример #2
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);
}
Пример #3
0
static void e1000_lower_eeprom_clock(struct e1000_device *device, uint32_t *eecd)
{
    *eecd &= ~E1000_EECD_SK;
    e1000_reg_write(device, REG_EECD, *eecd);
    e1000_write_flush(device);
    cdi_sleep_ms(5);
}
Пример #4
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;
}
Пример #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;
}
Пример #6
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);
}
Пример #7
0
/*
 * Initialize and return the card's ethernet address.
 */
static void
e1000_init_addr(e1000_t * e, ether_addr_t * addr)
{
	static char eakey[] = E1000_ENVVAR "#_EA";
	static char eafmt[] = "x:x:x:x:x:x";
	u16_t word;
	int i;
	long v;

	/* Do we have a user defined ethernet address? */
	eakey[sizeof(E1000_ENVVAR)-1] = '0' + e1000_instance;

	for (i = 0; i < 6; i++) {
		if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
			break;
		else
			addr->ea_addr[i] = v;
	}

	/* If that fails, read Ethernet Address from EEPROM. */
	if (i != 6) {
		for (i = 0; i < 3; i++) {
			word = e->eeprom_read(e, i);
			addr->ea_addr[i * 2]     = (word & 0x00ff);
			addr->ea_addr[i * 2 + 1] = (word & 0xff00) >> 8;
		}
	}

	/* Set Receive Address. */
	e1000_reg_write(e, E1000_REG_RAL, *(u32_t *)(&addr->ea_addr[0]));
	e1000_reg_write(e, E1000_REG_RAH, *(u16_t *)(&addr->ea_addr[4]));
	e1000_reg_set(e, E1000_REG_RAH, E1000_REG_RAH_AV);
	e1000_reg_set(e, E1000_REG_RCTL, E1000_REG_RCTL_MPE);

	E1000_DEBUG(3, ("%s: Ethernet Address %x:%x:%x:%x:%x:%x\n", e->name,
	    addr->ea_addr[0], addr->ea_addr[1], addr->ea_addr[2],
	    addr->ea_addr[3], addr->ea_addr[4], addr->ea_addr[5]));
}
Пример #8
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;
}
Пример #9
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);
}
Пример #10
0
/*
 * Initialize the hardware.  Return the ethernet address.
 */
static void
e1000_init_hw(e1000_t * e, ether_addr_t * addr)
{
	int r, i;

	e->irq_hook = e->irq;

	/*
	 * Set the interrupt handler and policy.  Do not automatically
	 * reenable interrupts.  Return the IRQ line number on interrupts.
	 */
	if ((r = sys_irqsetpolicy(e->irq, 0, &e->irq_hook)) != OK)
		panic("sys_irqsetpolicy failed: %d", r);
	if ((r = sys_irqenable(&e->irq_hook)) != OK)
		panic("sys_irqenable failed: %d", r);

	/* Reset hardware. */
	e1000_reset_hw(e);

	/*
	 * Initialize appropriately, according to section 14.3 General
	 * Configuration of Intel's Gigabit Ethernet Controllers Software
	 * Developer's Manual.
	 */
	e1000_reg_set(e, E1000_REG_CTRL,
	    E1000_REG_CTRL_ASDE | E1000_REG_CTRL_SLU);
	e1000_reg_unset(e, E1000_REG_CTRL, E1000_REG_CTRL_LRST);
	e1000_reg_unset(e, E1000_REG_CTRL, E1000_REG_CTRL_PHY_RST);
	e1000_reg_unset(e, E1000_REG_CTRL, E1000_REG_CTRL_ILOS);
	e1000_reg_write(e, E1000_REG_FCAL, 0);
	e1000_reg_write(e, E1000_REG_FCAH, 0);
	e1000_reg_write(e, E1000_REG_FCT, 0);
	e1000_reg_write(e, E1000_REG_FCTTV, 0);
	e1000_reg_unset(e, E1000_REG_CTRL, E1000_REG_CTRL_VME);

	/* Clear Multicast Table Array (MTA). */
	for (i = 0; i < 128; i++)
		e1000_reg_write(e, E1000_REG_MTA + i * 4, 0);

	/* Initialize statistics registers. */
	for (i = 0; i < 64; i++)
		e1000_reg_write(e, E1000_REG_CRCERRS + i * 4, 0);

	/* Acquire MAC address and set up RX/TX buffers. */
	e1000_init_addr(e, addr);
	e1000_init_buf(e);

	/* Enable interrupts. */
	e1000_reg_set(e, E1000_REG_IMS, E1000_REG_IMS_LSC | E1000_REG_IMS_RXO |
	    E1000_REG_IMS_RXT | E1000_REG_IMS_TXQE | E1000_REG_IMS_TXDW);
}
Пример #11
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;
}
Пример #12
0
/*
 * Initialize receive and transmit buffers.
 */
static void
e1000_init_buf(e1000_t * e)
{
	phys_bytes rx_desc_p, rx_buff_p;
	phys_bytes tx_desc_p, tx_buff_p;
	int i;

	/* Number of descriptors. */
	e->rx_desc_count = E1000_RXDESC_NR;
	e->tx_desc_count = E1000_TXDESC_NR;

	/* Allocate receive descriptors. */
	if ((e->rx_desc = alloc_contig(sizeof(e1000_rx_desc_t) *
	    e->rx_desc_count, AC_ALIGN4K, &rx_desc_p)) == NULL)
		panic("failed to allocate RX descriptors");

	memset(e->rx_desc, 0, sizeof(e1000_rx_desc_t) * e->rx_desc_count);

	/* Allocate receive buffers. */
	e->rx_buffer_size = E1000_RXDESC_NR * E1000_IOBUF_SIZE;

	if ((e->rx_buffer = alloc_contig(e->rx_buffer_size, AC_ALIGN4K,
	    &rx_buff_p)) == NULL)
		panic("failed to allocate RX buffers");

	/* Set up receive descriptors. */
	for (i = 0; i < E1000_RXDESC_NR; i++)
		e->rx_desc[i].buffer = rx_buff_p + i * E1000_IOBUF_SIZE;

	/* Allocate transmit descriptors. */
	if ((e->tx_desc = alloc_contig(sizeof(e1000_tx_desc_t) *
	    e->tx_desc_count, AC_ALIGN4K, &tx_desc_p)) == NULL)
		panic("failed to allocate TX descriptors");

	memset(e->tx_desc, 0, sizeof(e1000_tx_desc_t) * e->tx_desc_count);

	/* Allocate transmit buffers. */
	e->tx_buffer_size = E1000_TXDESC_NR * E1000_IOBUF_SIZE;

	if ((e->tx_buffer = alloc_contig(e->tx_buffer_size, AC_ALIGN4K,
	    &tx_buff_p)) == NULL)
		panic("failed to allocate TX buffers");

	/* Set up transmit descriptors. */
	for (i = 0; i < E1000_TXDESC_NR; i++)
		e->tx_desc[i].buffer = tx_buff_p + i * E1000_IOBUF_SIZE;

	/* Set up the receive ring registers. */
	e1000_reg_write(e, E1000_REG_RDBAL, rx_desc_p);
	e1000_reg_write(e, E1000_REG_RDBAH, 0);
	e1000_reg_write(e, E1000_REG_RDLEN,
	    e->rx_desc_count * sizeof(e1000_rx_desc_t));
	e1000_reg_write(e, E1000_REG_RDH, 0);
	e1000_reg_write(e, E1000_REG_RDT, e->rx_desc_count - 1);
	e1000_reg_unset(e, E1000_REG_RCTL, E1000_REG_RCTL_BSIZE);
	e1000_reg_set(e, E1000_REG_RCTL, E1000_REG_RCTL_EN);

	/* Set up the transmit ring registers. */
	e1000_reg_write(e, E1000_REG_TDBAL, tx_desc_p);
	e1000_reg_write(e, E1000_REG_TDBAH, 0);
	e1000_reg_write(e, E1000_REG_TDLEN,
	    e->tx_desc_count * sizeof(e1000_tx_desc_t));
	e1000_reg_write(e, E1000_REG_TDH, 0);
	e1000_reg_write(e, E1000_REG_TDT, 0);
	e1000_reg_set(e, E1000_REG_TCTL,
	    E1000_REG_TCTL_EN | E1000_REG_TCTL_PSP);
}