* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
DBGOUT(IO, "e1000_ioport_map addr=0x%04x size=0x%08x\n", addr, size);
}
-static void
-update_irqs(E1000State *s)
-{
- qemu_set_irq(s->dev.irq[0], (s->mac_reg[IMS] & s->mac_reg[ICR]) != 0);
-}
-
static void
set_interrupt_cause(E1000State *s, int index, uint32_t val)
{
if (val)
val |= E1000_ICR_INT_ASSERTED;
s->mac_reg[ICR] = val;
- update_irqs(s);
+ s->mac_reg[ICS] = val;
+ qemu_set_irq(s->dev.irq[0], (s->mac_reg[IMS] & s->mac_reg[ICR]) != 0);
}
static void
}
if (!(val & E1000_EECD_CS)) { // rising, no CS (EEPROM reset)
memset(&s->eecd_state, 0, sizeof s->eecd_state);
+ /*
+ * restore old_eecd's E1000_EECD_SK (known to be on)
+ * to avoid false detection of a clock edge
+ */
+ s->eecd_state.old_eecd = E1000_EECD_SK;
return;
}
s->eecd_state.val_in <<= 1;
{
unsigned int index, r = s->mac_reg[EERD] & ~E1000_EEPROM_RW_REG_START;
+ if ((s->mac_reg[EERD] & E1000_EEPROM_RW_REG_START) == 0)
+ return (s->mac_reg[EERD]);
+
if ((index = r >> E1000_EEPROM_RW_ADDR_SHIFT) > EEPROM_CHECKSUM_REG)
- return 0;
- return (s->eeprom_data[index] << E1000_EEPROM_RW_REG_DATA) |
- E1000_EEPROM_RW_REG_DONE | r;
+ return (E1000_EEPROM_RW_REG_DONE | r);
+
+ return ((s->eeprom_data[index] << E1000_EEPROM_RW_REG_DATA) |
+ E1000_EEPROM_RW_REG_DONE | r);
}
static void
getreg(WUFC), getreg(TDT), getreg(CTRL), getreg(LEDCTL),
getreg(MANC), getreg(MDIC), getreg(SWSM), getreg(STATUS),
getreg(TORL), getreg(TOTL), getreg(IMS), getreg(TCTL),
- getreg(RDH), getreg(RDT), getreg(VET),
+ getreg(RDH), getreg(RDT), getreg(VET), getreg(ICS),
[TOTH] = mac_read_clr8, [TORH] = mac_read_clr8, [GPRC] = mac_read_clr4,
[GPTC] = mac_read_clr4, [TPR] = mac_read_clr4, [TPT] = mac_read_clr4,
static void
nic_save(QEMUFile *f, void *opaque)
{
- E1000State *s = (E1000State *)opaque;
+ E1000State *s = opaque;
int i, j;
pci_device_save(&s->dev, f);
static int
nic_load(QEMUFile *f, void *opaque, int version_id)
{
- E1000State *s = (E1000State *)opaque;
+ E1000State *s = opaque;
int i, j, ret;
if ((ret = pci_device_load(&s->dev, f)) < 0)
for (j = 0; j < mac_regarraystosave[i].size; j++)
qemu_get_be32s(f,
s->mac_reg + mac_regarraystosave[i].array0 + j);
- update_irqs(s);
return 0;
}
/* PCI interface */
-static CPUWriteMemoryFunc *e1000_mmio_write[] = {
+static CPUWriteMemoryFunc * const e1000_mmio_write[] = {
e1000_mmio_writeb, e1000_mmio_writew, e1000_mmio_writel
};
-static CPUReadMemoryFunc *e1000_mmio_read[] = {
+static CPUReadMemoryFunc * const e1000_mmio_read[] = {
e1000_mmio_readb, e1000_mmio_readw, e1000_mmio_readl
};
e1000_mmio_map(PCIDevice *pci_dev, int region_num,
uint32_t addr, uint32_t size, int type)
{
- E1000State *d = (E1000State *)pci_dev;
+ E1000State *d = DO_UPCAST(E1000State, dev, pci_dev);
int i;
const uint32_t excluded_regs[] = {
E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS,
static int
pci_e1000_uninit(PCIDevice *dev)
{
- E1000State *d = (E1000State *) dev;
+ E1000State *d = DO_UPCAST(E1000State, dev, dev);
cpu_unregister_io_memory(d->mmio_index);
memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init);
d->rxbuf_min_shift = 1;
memset(&d->tx, 0, sizeof d->tx);
- update_irqs(d);
}
-static void pci_e1000_init(PCIDevice *pci_dev)
+static int pci_e1000_init(PCIDevice *pci_dev)
{
- E1000State *d = (E1000State *)pci_dev;
+ E1000State *d = DO_UPCAST(E1000State, dev, pci_dev);
uint8_t *pci_conf;
uint16_t checksum = 0;
static const char info_str[] = "e1000";
d->mmio_index = cpu_register_io_memory(e1000_mmio_read,
e1000_mmio_write, d);
- pci_register_io_region((PCIDevice *)d, 0, PNPMMIO_SIZE,
+ pci_register_bar((PCIDevice *)d, 0, PNPMMIO_SIZE,
PCI_ADDRESS_SPACE_MEM, e1000_mmio_map);
- pci_register_io_region((PCIDevice *)d, 1, IOPORT_SIZE,
+ pci_register_bar((PCIDevice *)d, 1, IOPORT_SIZE,
PCI_ADDRESS_SPACE_IO, ioport_map);
memmove(d->eeprom_data, e1000_eeprom_template,
register_savevm(info_str, -1, 2, nic_save, nic_load, d);
d->dev.unregister = pci_e1000_uninit;
- qemu_register_reset(e1000_reset, 0, d);
+ qemu_register_reset(e1000_reset, d);
e1000_reset(d);
+ return 0;
}
+static PCIDeviceInfo e1000_info = {
+ .qdev.name = "e1000",
+ .qdev.size = sizeof(E1000State),
+ .init = pci_e1000_init,
+};
+
static void e1000_register_devices(void)
{
- pci_qdev_register("e1000", sizeof(E1000State), pci_e1000_init);
+ pci_qdev_register(&e1000_info);
}
device_init(e1000_register_devices)