David van Moolenbroek f7df02e747 libnetdriver: rewrite
This is a driver-breaking update to the netdriver library, which is
used by all network drivers.  The aim of this change is to make the
library more compatible with NetBSD, and in particular with various
features that are expected to be supported by the NetBSD userland.
The main changes made by this patch are the following:

- each network driver now has a NetBSD-style short device name;
- drivers are not expected to receive packets right after startup;
- extended support for receipt modes, including multicast lists;
- support for multiple parallel send, receive requests;
- embedding of I/O vectors in send and receive requests;
- support for capabilities, including checksum offloading;
- support for reporting link status updates to the TCP/IP stack;
- support for setting and retrieving media status;
- support for changing the hardware (MAC) address;
- support for NetBSD interface flags IFF_DEBUG, IFF_LINK[0-2];
- support for NetBSD error statistics;
- support for regular time-based ("tick") callbacks.

IMPORTANT: this patch applies a minimal update to the existing drivers
in order to make them work at all with the new netdriver library.  It
however does *not* change all drivers to make use of the new features.
In fact, strictly speaking, all drivers are now violating requirements
imposed by the new library in one way or another, most notably by
enabling packet receipt when starting the driver.  Changing all the
drivers to be compliant, and to support the newly added options, is
left to future patches.  The existing drivers should currently *not*
be taken as examples of how to implement a new network driver!

With that said, a few drivers have already been changed to make use of
some of the new features: fxp, e1000, rtl8139, and rtl8169 now report
link and media status, and the last three of those now support setting
the hardware MAC address on the fly.  In addition, dp8390 has been
changed to default to PCI autoconfiguration if no configuration is
specified through environment variables.

Change-Id: I4b3ea9c0b9bc25d5b0609c6ff256fb0db71cdc42
2017-04-30 13:15:28 +00:00

919 lines
22 KiB
C

/* A device driver for Intel Pro/1000 Gigabit Ethernet Controllers. */
#include <minix/drivers.h>
#include <minix/netdriver.h>
#include <machine/pci.h>
#include <sys/mman.h>
#include "assert.h"
#include "e1000.h"
#include "e1000_hw.h"
#include "e1000_reg.h"
#include "e1000_pci.h"
static int e1000_init(unsigned int instance, netdriver_addr_t *addr,
uint32_t *caps, unsigned int *ticks);
static void e1000_stop(void);
static void e1000_set_mode(unsigned int, const netdriver_addr_t *,
unsigned int);
static void e1000_set_hwaddr(const netdriver_addr_t *);
static int e1000_send(struct netdriver_data *data, size_t size);
static ssize_t e1000_recv(struct netdriver_data *data, size_t max);
static unsigned int e1000_get_link(uint32_t *);
static void e1000_intr(unsigned int mask);
static void e1000_tick(void);
static int e1000_probe(e1000_t *e, int skip);
static void e1000_init_hw(e1000_t *e, netdriver_addr_t *addr);
static uint32_t e1000_reg_read(e1000_t *e, uint32_t reg);
static void e1000_reg_write(e1000_t *e, uint32_t reg, uint32_t value);
static void e1000_reg_set(e1000_t *e, uint32_t reg, uint32_t value);
static void e1000_reg_unset(e1000_t *e, uint32_t reg, uint32_t value);
static u16_t eeprom_eerd(e1000_t *e, int reg);
static u16_t eeprom_ich(e1000_t *e, int reg);
static int eeprom_ich_init(e1000_t *e);
static int eeprom_ich_cycle(e1000_t *e, u32_t timeout);
static int e1000_instance;
static e1000_t e1000_state;
static const struct netdriver e1000_table = {
.ndr_name = "em",
.ndr_init = e1000_init,
.ndr_stop = e1000_stop,
.ndr_set_mode = e1000_set_mode,
.ndr_set_hwaddr = e1000_set_hwaddr,
.ndr_recv = e1000_recv,
.ndr_send = e1000_send,
.ndr_get_link = e1000_get_link,
.ndr_intr = e1000_intr,
.ndr_tick = e1000_tick
};
/*
* The e1000 driver.
*/
int
main(int argc, char * argv[])
{
env_setargs(argc, argv);
/* Let the netdriver library take control. */
netdriver_task(&e1000_table);
return 0;
}
/*
* Initialize the e1000 driver and device.
*/
static int
e1000_init(unsigned int instance, netdriver_addr_t * addr, uint32_t * caps,
unsigned int * ticks)
{
e1000_t *e;
int r;
e1000_instance = instance;
/* Clear state. */
memset(&e1000_state, 0, sizeof(e1000_state));
e = &e1000_state;
/* Perform calibration. */
if ((r = tsc_calibrate()) != OK)
panic("tsc_calibrate failed: %d", r);
/* See if we can find a matching device. */
if (!e1000_probe(e, instance))
return ENXIO;
/* Initialize the hardware, and return its ethernet address. */
e1000_init_hw(e, addr);
*caps = NDEV_CAP_MCAST | NDEV_CAP_BCAST | NDEV_CAP_HWADDR;
*ticks = sys_hz() / 10; /* update statistics 10x/sec */
return OK;
}
/*
* Map flash memory. This step is optional.
*/
static void
e1000_map_flash(e1000_t * e, int devind, int did)
{
u32_t flash_addr, gfpreg, sector_base_addr;
size_t flash_size;
/* The flash memory is pointed to by BAR2. It may not be present. */
if ((flash_addr = pci_attr_r32(devind, PCI_BAR_2)) == 0)
return;
/* The default flash size. */
flash_size = 0x10000;
switch (did) {
case E1000_DEV_ID_82540EM:
case E1000_DEV_ID_82545EM:
case E1000_DEV_ID_82540EP:
case E1000_DEV_ID_82540EP_LP:
return; /* don't even try */
/* 82566/82567/82562V series support mapping 4kB of flash memory. */
case E1000_DEV_ID_ICH10_D_BM_LM:
case E1000_DEV_ID_ICH10_R_BM_LF:
flash_size = 0x1000;
break;
}
e->flash = vm_map_phys(SELF, (void *)flash_addr, flash_size);
if (e->flash == MAP_FAILED)
panic("e1000: couldn't map in flash");
/* sector_base_addr is a "sector"-aligned address (4096 bytes). */
gfpreg = E1000_READ_FLASH_REG(e, ICH_FLASH_GFPREG);
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;
}
/*
* 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;
const char *dname;
E1000_DEBUG(3, ("%s: probe()\n", netdriver_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",
netdriver_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",
netdriver_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", netdriver_name(),
e->regs, e->irq));
E1000_DEBUG(3, ("%s: link %s, %s duplex\n", netdriver_name(),
status & 3 ? "up" : "down", status & 1 ? "full" : "half"));
return TRUE;
}
/*
* Reset the card.
*/
static void
e1000_reset_hw(e1000_t * e)
{
/* Assert a Device Reset signal. */
e1000_reg_set(e, E1000_REG_CTRL, E1000_REG_CTRL_RST);
/* Wait one microsecond. */
tickdelay(1);
}
/*
* Initialize and return the card's ethernet address.
*/
static void
e1000_init_addr(e1000_t * e, netdriver_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->na_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->na_addr[i * 2] = (word & 0x00ff);
addr->na_addr[i * 2 + 1] = (word & 0xff00) >> 8;
}
}
/* Set Receive Address. */
e1000_set_hwaddr(addr);
E1000_DEBUG(3, ("%s: Ethernet Address %x:%x:%x:%x:%x:%x\n",
netdriver_name(),
addr->na_addr[0], addr->na_addr[1], addr->na_addr[2],
addr->na_addr[3], addr->na_addr[4], addr->na_addr[5]));
}
/*
* 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);
}
/*
* Initialize the hardware. Return the ethernet address.
*/
static void
e1000_init_hw(e1000_t * e, netdriver_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);
}
/*
* Set receive mode.
*/
static void
e1000_set_mode(unsigned int mode, const netdriver_addr_t * mcast_list __unused,
unsigned int mcast_count __unused)
{
e1000_t *e;
uint32_t rctl;
e = &e1000_state;
rctl = e1000_reg_read(e, E1000_REG_RCTL);
rctl &= ~(E1000_REG_RCTL_BAM | E1000_REG_RCTL_MPE |
E1000_REG_RCTL_UPE);
/* TODO: support for NDEV_MODE_DOWN and multicast lists */
if (mode & NDEV_MODE_BCAST)
rctl |= E1000_REG_RCTL_BAM;
if (mode & (NDEV_MODE_MCAST_LIST | NDEV_MODE_MCAST_ALL))
rctl |= E1000_REG_RCTL_MPE;
if (mode & NDEV_MODE_PROMISC)
rctl |= E1000_REG_RCTL_BAM | E1000_REG_RCTL_MPE |
E1000_REG_RCTL_UPE;
e1000_reg_write(e, E1000_REG_RCTL, rctl);
}
/*
* Set hardware address.
*/
static void
e1000_set_hwaddr(const netdriver_addr_t * hwaddr)
{
e1000_t *e;
e = &e1000_state;
e1000_reg_write(e, E1000_REG_RAL,
*(const u32_t *)(&hwaddr->na_addr[0]));
e1000_reg_write(e, E1000_REG_RAH,
*(const u16_t *)(&hwaddr->na_addr[4]));
e1000_reg_set(e, E1000_REG_RAH, E1000_REG_RAH_AV);
}
/*
* 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;
}
/*
* 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",
netdriver_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;
}
/*
* Return the link and media status.
*/
static unsigned int
e1000_get_link(uint32_t * media)
{
uint32_t status, type;
status = e1000_reg_read(&e1000_state, E1000_REG_STATUS);
if (!(status & E1000_REG_STATUS_LU))
return NDEV_LINK_DOWN;
if (status & E1000_REG_STATUS_FD)
type = IFM_ETHER | IFM_FDX;
else
type = IFM_ETHER | IFM_HDX;
switch (status & E1000_REG_STATUS_SPEED) {
case E1000_REG_STATUS_SPEED_10:
type |= IFM_10_T;
break;
case E1000_REG_STATUS_SPEED_100:
type |= IFM_100_TX;
break;
case E1000_REG_STATUS_SPEED_1000_A:
case E1000_REG_STATUS_SPEED_1000_B:
type |= IFM_1000_T;
break;
}
*media = type;
return NDEV_LINK_UP;
}
/*
* 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)
netdriver_link();
if (cause & (E1000_REG_ICR_RXO | E1000_REG_ICR_RXT))
netdriver_recv();
if (cause & (E1000_REG_ICR_TXQE | E1000_REG_ICR_TXDW))
netdriver_send();
}
}
/*
* Do regular processing.
*/
static void
e1000_tick(void)
{
e1000_t *e;
e = &e1000_state;
/* Update statistics. */
netdriver_stat_ierror(e1000_reg_read(e, E1000_REG_RXERRC));
netdriver_stat_ierror(e1000_reg_read(e, E1000_REG_CRCERRS));
netdriver_stat_ierror(e1000_reg_read(e, E1000_REG_MPC));
netdriver_stat_coll(e1000_reg_read(e, E1000_REG_COLC));
}
/*
* Stop the card.
*/
static void
e1000_stop(void)
{
e1000_t *e;
e = &e1000_state;
E1000_DEBUG(3, ("%s: stop()\n", netdriver_name()));
e1000_reset_hw(e);
}
/*
* Read from a register.
*/
static uint32_t
e1000_reg_read(e1000_t * e, uint32_t reg)
{
uint32_t value;
/* Assume a sane register. */
assert(reg < 0x1ffff);
/* Read from memory mapped register. */
value = *(volatile uint32_t *)(e->regs + reg);
/* Return the result. */
return value;
}
/*
* Write to a register.
*/
static void
e1000_reg_write(e1000_t * e, uint32_t reg, uint32_t value)
{
/* Assume a sane register. */
assert(reg < 0x1ffff);
/* Write to memory mapped register. */
*(volatile u32_t *)(e->regs + reg) = value;
}
/*
* Set bits in a register.
*/
static void
e1000_reg_set(e1000_t * e, uint32_t reg, uint32_t value)
{
uint32_t data;
/* First read the current value. */
data = e1000_reg_read(e, reg);
/* Set bits, and write back. */
e1000_reg_write(e, reg, data | value);
}
/*
* 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);
}
/*
* 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;
}
/*
* Initialize ICH8 flash.
*/
static int
eeprom_ich_init(e1000_t * e)
{
union ich8_hws_flash_status hsfsts;
int ret_val = -1;
int i = 0;
hsfsts.regval = E1000_READ_FLASH_REG16(e, ICH_FLASH_HSFSTS);
/* Check if the flash descriptor is valid */
if (hsfsts.hsf_status.fldesvalid == 0) {
E1000_DEBUG(3, ("Flash descriptor invalid. "
"SW Sequencing must be used."));
return ret_val;
}
/* Clear FCERR and DAEL in hw status by writing 1 */
hsfsts.hsf_status.flcerr = 1;
hsfsts.hsf_status.dael = 1;
E1000_WRITE_FLASH_REG16(e, ICH_FLASH_HSFSTS, hsfsts.regval);
/*
* Either we should have a hardware SPI cycle in progress bit to check
* against, in order to start a new cycle or FDONE bit should be
* changed in the hardware so that it is 1 after hardware reset, which
* can then be used as an indication whether a cycle is in progress or
* has been completed.
*/
if (hsfsts.hsf_status.flcinprog == 0) {
/*
* There is no cycle running at present, so we can start a
* cycle. Begin by setting Flash Cycle Done.
*/
hsfsts.hsf_status.flcdone = 1;
E1000_WRITE_FLASH_REG16(e, ICH_FLASH_HSFSTS, hsfsts.regval);
ret_val = 0;
} else {
/*
* Otherwise poll for sometime so the current cycle has a
* chance to end before giving up.
*/
for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) {
hsfsts.regval = E1000_READ_FLASH_REG16(e,
ICH_FLASH_HSFSTS);
if (hsfsts.hsf_status.flcinprog == 0) {
ret_val = 0;
break;
}
tickdelay(1);
}
if (ret_val == 0) {
/*
* Successful in waiting for previous cycle to timeout,
* now set the Flash Cycle Done.
*/
hsfsts.hsf_status.flcdone = 1;
E1000_WRITE_FLASH_REG16(e, ICH_FLASH_HSFSTS,
hsfsts.regval);
} else {
E1000_DEBUG(3,
("Flash controller busy, cannot get access"));
}
}
return ret_val;
}
/*
* Start ICH8 flash cycle.
*/
static int
eeprom_ich_cycle(e1000_t * e, u32_t timeout)
{
union ich8_hws_flash_ctrl hsflctl;
union ich8_hws_flash_status hsfsts;
int ret_val = -1;
u32_t i = 0;
E1000_DEBUG(3, ("e1000_flash_cycle_ich8lan"));
/* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
hsflctl.regval = E1000_READ_FLASH_REG16(e, ICH_FLASH_HSFCTL);
hsflctl.hsf_ctrl.flcgo = 1;
E1000_WRITE_FLASH_REG16(e, ICH_FLASH_HSFCTL, hsflctl.regval);
/* Wait till the FDONE bit is set to 1 */
do {
hsfsts.regval = E1000_READ_FLASH_REG16(e, ICH_FLASH_HSFSTS);
if (hsfsts.hsf_status.flcdone == 1)
break;
tickdelay(1);
} while (i++ < timeout);
if (hsfsts.hsf_status.flcdone == 1 && hsfsts.hsf_status.flcerr == 0)
ret_val = 0;
return ret_val;
}
/*
* Read from ICH8 flash.
*/
static u16_t
eeprom_ich(e1000_t * e, int reg)
{
union ich8_hws_flash_status hsfsts;
union ich8_hws_flash_ctrl hsflctl;
u32_t flash_linear_addr;
u32_t flash_data = 0;
int ret_val = -1;
u8_t count = 0;
u16_t data = 0;
E1000_DEBUG(3, ("e1000_read_flash_data_ich8lan"));
if (reg > ICH_FLASH_LINEAR_ADDR_MASK)
return data;
reg *= sizeof(u16_t);
flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & reg) +
e->flash_base_addr;
do {
tickdelay(1);
/* Steps */
ret_val = eeprom_ich_init(e);
if (ret_val != 0)
break;
hsflctl.regval = E1000_READ_FLASH_REG16(e, ICH_FLASH_HSFCTL);
/* 0b/1b corresponds to 1 or 2 byte size, respectively. */
hsflctl.hsf_ctrl.fldbcount = 1;
hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ;
E1000_WRITE_FLASH_REG16(e, ICH_FLASH_HSFCTL, hsflctl.regval);
E1000_WRITE_FLASH_REG(e, ICH_FLASH_FADDR, flash_linear_addr);
ret_val = eeprom_ich_cycle(e, ICH_FLASH_READ_COMMAND_TIMEOUT);
/*
* Check if FCERR is set to 1, if set to 1, clear it and try
* the whole sequence a few more times, else read in (shift in)
* the Flash Data0, the order is least significant byte first
* msb to lsb.
*/
if (ret_val == 0) {
flash_data = E1000_READ_FLASH_REG(e, ICH_FLASH_FDATA0);
data = (u16_t)(flash_data & 0x0000FFFF);
break;
} else {
/*
* If we've gotten here, then things are probably
* completely hosed, but if the error condition is
* detected, it won't hurt to give it another try...
* ICH_FLASH_CYCLE_REPEAT_COUNT times.
*/
hsfsts.regval = E1000_READ_FLASH_REG16(e,
ICH_FLASH_HSFSTS);
if (hsfsts.hsf_status.flcerr == 1) {
/* Repeat for some time before giving up. */
continue;
} else if (hsfsts.hsf_status.flcdone == 0) {
E1000_DEBUG(3, ("Timeout error - flash cycle "
"did not complete."));
break;
}
}
} while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
return data;
}