[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 3/4] e1000: Refactor to allow subclassing from other
From: |
Knut Omang |
Subject: |
[Qemu-devel] [PATCH 3/4] e1000: Refactor to allow subclassing from other source file |
Date: |
Fri, 29 Aug 2014 09:17:08 +0200 |
Signed-off-by: Knut Omang <address@hidden>
---
hw/net/e1000.c | 126 +++++++--------------------------------------------
hw/net/e1000.h | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 155 insertions(+), 110 deletions(-)
create mode 100644 hw/net/e1000.h
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 272df00..7afdcad 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -35,6 +35,7 @@
#include "qemu/iov.h"
#include "e1000_regs.h"
+#include "e1000.h"
#define E1000_DEBUG
@@ -75,101 +76,6 @@ static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL);
* Others never tested
*/
-typedef struct E1000State_st {
- /*< private >*/
- PCIDevice parent_obj;
- /*< public >*/
-
- NICState *nic;
- NICConf conf;
- MemoryRegion mmio;
- MemoryRegion io;
-
- uint32_t mac_reg[0x8000];
- uint16_t phy_reg[0x20];
- uint16_t eeprom_data[64];
-
- uint32_t rxbuf_size;
- uint32_t rxbuf_min_shift;
- struct e1000_tx {
- unsigned char header[256];
- unsigned char vlan_header[4];
- /* Fields vlan and data must not be reordered or separated. */
- unsigned char vlan[4];
- unsigned char data[0x10000];
- uint16_t size;
- unsigned char sum_needed;
- unsigned char vlan_needed;
- uint8_t ipcss;
- uint8_t ipcso;
- uint16_t ipcse;
- uint8_t tucss;
- uint8_t tucso;
- uint16_t tucse;
- uint8_t hdr_len;
- uint16_t mss;
- uint32_t paylen;
- uint16_t tso_frames;
- char tse;
- int8_t ip;
- int8_t tcp;
- char cptse; // current packet tse bit
- } tx;
-
- struct {
- uint32_t val_in; // shifted in from guest driver
- uint16_t bitnum_in;
- uint16_t bitnum_out;
- uint16_t reading;
- uint32_t old_eecd;
- } eecd_state;
-
- QEMUTimer *autoneg_timer;
-
- QEMUTimer *mit_timer; /* Mitigation timer. */
- bool mit_timer_on; /* Mitigation timer is running. */
- bool mit_irq_level; /* Tracks interrupt pin level. */
- uint32_t mit_ide; /* Tracks E1000_TXD_CMD_IDE bit. */
-
-/* Compatibility flags for migration to/from qemu 1.3.0 and older */
-#define E1000_FLAG_AUTONEG_BIT 0
-#define E1000_FLAG_MIT_BIT 1
-#define E1000_FLAG_AUTONEG (1 << E1000_FLAG_AUTONEG_BIT)
-#define E1000_FLAG_MIT (1 << E1000_FLAG_MIT_BIT)
- uint32_t compat_flags;
-} E1000State;
-
-typedef struct E1000BaseClass {
- PCIDeviceClass parent_class;
- uint16_t phy_id2;
-} E1000BaseClass;
-
-#define TYPE_E1000_BASE "e1000-base"
-
-#define E1000(obj) \
- OBJECT_CHECK(E1000State, (obj), TYPE_E1000_BASE)
-
-#define E1000_DEVICE_CLASS(klass) \
- OBJECT_CLASS_CHECK(E1000BaseClass, (klass), TYPE_E1000_BASE)
-#define E1000_DEVICE_GET_CLASS(obj) \
- OBJECT_GET_CLASS(E1000BaseClass, (obj), TYPE_E1000_BASE)
-
-#define defreg(x) x = (E1000_##x>>2)
-enum {
- defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC),
- defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC),
- defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC),
- defreg(MPC), defreg(PBA), defreg(RCTL), defreg(RDBAH),
- defreg(RDBAL), defreg(RDH), defreg(RDLEN), defreg(RDT),
- defreg(STATUS), defreg(SWSM), defreg(TCTL), defreg(TDBAH),
- defreg(TDBAL), defreg(TDH), defreg(TDLEN), defreg(TDT),
- defreg(TORH), defreg(TORL), defreg(TOTH), defreg(TOTL),
- defreg(TPR), defreg(TPT), defreg(TXDCTL), defreg(WUFC),
- defreg(RA), defreg(MTA), defreg(CRCERRS),defreg(VFTA),
- defreg(VET), defreg(RDTR), defreg(RADV), defreg(TADV),
- defreg(ITR),
-};
-
static void
e1000_link_down(E1000State *s)
{
@@ -398,7 +304,7 @@ rxbufsize(uint32_t v)
return 2048;
}
-static void e1000_reset(void *opaque)
+void e1000_reset(void *opaque)
{
E1000State *d = opaque;
E1000BaseClass *edc = E1000_DEVICE_GET_CLASS(d);
@@ -1507,8 +1413,7 @@ e1000_cleanup(NetClientState *nc)
s->nic = NULL;
}
-static void
-pci_e1000_uninit(PCIDevice *dev)
+void pci_e1000_uninit(PCIDevice *dev)
{
E1000State *d = E1000(dev);
@@ -1529,10 +1434,11 @@ static NetClientInfo net_e1000_info = {
.link_status_changed = e1000_set_link_status,
};
-static int pci_e1000_init(PCIDevice *pci_dev)
+int pci_e1000_init(PCIDevice *pci_dev)
{
DeviceState *dev = DEVICE(pci_dev);
E1000State *d = E1000(pci_dev);
+ E1000BaseClass *edc = E1000_DEVICE_GET_CLASS(d);
PCIDeviceClass *pdc = PCI_DEVICE_GET_CLASS(pci_dev);
uint8_t *pci_conf;
uint16_t checksum = 0;
@@ -1548,9 +1454,12 @@ static int pci_e1000_init(PCIDevice *pci_dev)
e1000_mmio_setup(d);
- pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
-
- pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io);
+ if (pci_dev->exp.is_vf) {
+ pcie_register_vf_bar(pci_dev, 0, &d->mmio);
+ } else {
+ pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
+ pci_register_bar(pci_dev, edc->io_bar, PCI_BASE_ADDRESS_SPACE_IO,
&d->io);
+ }
memmove(d->eeprom_data, e1000_eeprom_template,
sizeof e1000_eeprom_template);
@@ -1592,14 +1501,7 @@ static Property e1000_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
-typedef struct E1000Info {
- const char *name;
- uint16_t device_id;
- uint8_t revision;
- uint16_t phy_id2;
-} E1000Info;
-
-static void e1000_class_init(ObjectClass *klass, void *data)
+void e1000_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
@@ -1613,6 +1515,7 @@ static void e1000_class_init(ObjectClass *klass, void
*data)
k->device_id = info->device_id;
k->revision = info->revision;
e->phy_id2 = info->phy_id2;
+ e->io_bar = info->io_bar;
k->class_id = PCI_CLASS_NETWORK_ETHERNET;
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->desc = "Intel Gigabit Ethernet";
@@ -1634,18 +1537,21 @@ static const E1000Info e1000_devices[] = {
.name = "e1000-82540em",
.device_id = E1000_DEV_ID_82540EM,
.revision = 0x03,
+ .io_bar = 1,
.phy_id2 = E1000_PHY_ID2_8254xx_DEFAULT,
},
{
.name = "e1000-82544gc",
.device_id = E1000_DEV_ID_82544GC_COPPER,
.revision = 0x03,
+ .io_bar = 1,
.phy_id2 = E1000_PHY_ID2_82544x,
},
{
.name = "e1000-82545em",
.device_id = E1000_DEV_ID_82545EM_COPPER,
.revision = 0x03,
+ .io_bar = 1,
.phy_id2 = E1000_PHY_ID2_8254xx_DEFAULT,
},
};
diff --git a/hw/net/e1000.h b/hw/net/e1000.h
new file mode 100644
index 0000000..f215122
--- /dev/null
+++ b/hw/net/e1000.h
@@ -0,0 +1,139 @@
+/*
+ * QEMU e1000 emulation
+ *
+ * Software developer's manual:
+ * http://download.intel.com/design/network/manuals/8254x_GBe_SDM.pdf
+ *
+ * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
+ * Copyright (c) 2008 Qumranet
+ * Based on work done by:
+ * Copyright (c) 2007 Dan Aloni
+ * Copyright (c) 2004 Antony T Curtis
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "e1000_regs.h"
+
+typedef struct E1000State_st {
+ /*< private >*/
+ PCIDevice parent_obj;
+ /*< public >*/
+
+ NICState *nic;
+ NICConf conf;
+ MemoryRegion mmio;
+ MemoryRegion io;
+
+ uint32_t mac_reg[0x8000];
+ uint16_t phy_reg[0x20];
+ uint16_t eeprom_data[64];
+
+ uint32_t rxbuf_size;
+ uint32_t rxbuf_min_shift;
+ struct e1000_tx {
+ unsigned char header[256];
+ unsigned char vlan_header[4];
+ /* Fields vlan and data must not be reordered or separated. */
+ unsigned char vlan[4];
+ unsigned char data[0x10000];
+ uint16_t size;
+ unsigned char sum_needed;
+ unsigned char vlan_needed;
+ uint8_t ipcss;
+ uint8_t ipcso;
+ uint16_t ipcse;
+ uint8_t tucss;
+ uint8_t tucso;
+ uint16_t tucse;
+ uint8_t hdr_len;
+ uint16_t mss;
+ uint32_t paylen;
+ uint16_t tso_frames;
+ char tse;
+ int8_t ip;
+ int8_t tcp;
+ char cptse; // current packet tse bit
+ } tx;
+
+ struct {
+ uint32_t val_in; // shifted in from guest driver
+ uint16_t bitnum_in;
+ uint16_t bitnum_out;
+ uint16_t reading;
+ uint32_t old_eecd;
+ } eecd_state;
+
+ QEMUTimer *autoneg_timer;
+
+ QEMUTimer *mit_timer; /* Mitigation timer. */
+ bool mit_timer_on; /* Mitigation timer is running. */
+ bool mit_irq_level; /* Tracks interrupt pin level. */
+ uint32_t mit_ide; /* Tracks E1000_TXD_CMD_IDE bit. */
+
+/* Compatibility flags for migration to/from qemu 1.3.0 and older */
+#define E1000_FLAG_AUTONEG_BIT 0
+#define E1000_FLAG_MIT_BIT 1
+#define E1000_FLAG_AUTONEG (1 << E1000_FLAG_AUTONEG_BIT)
+#define E1000_FLAG_MIT (1 << E1000_FLAG_MIT_BIT)
+ uint32_t compat_flags;
+} E1000State;
+
+typedef struct E1000BaseClass {
+ PCIDeviceClass parent_class;
+ uint16_t phy_id2;
+ uint16_t io_bar; /* Which BAR register to use for the IO bar */
+} E1000BaseClass;
+
+#define TYPE_E1000_BASE "e1000-base"
+
+#define E1000(obj) \
+ OBJECT_CHECK(E1000State, (obj), TYPE_E1000_BASE)
+
+#define E1000_DEVICE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(E1000BaseClass, (klass), TYPE_E1000_BASE)
+#define E1000_DEVICE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(E1000BaseClass, (obj), TYPE_E1000_BASE)
+
+#define defreg(x) x = (E1000_##x>>2)
+enum {
+ defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC),
+ defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC),
+ defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC),
+ defreg(MPC), defreg(PBA), defreg(RCTL), defreg(RDBAH),
+ defreg(RDBAL), defreg(RDH), defreg(RDLEN), defreg(RDT),
+ defreg(STATUS), defreg(SWSM), defreg(TCTL), defreg(TDBAH),
+ defreg(TDBAL), defreg(TDH), defreg(TDLEN), defreg(TDT),
+ defreg(TORH), defreg(TORL), defreg(TOTH), defreg(TOTL),
+ defreg(TPR), defreg(TPT), defreg(TXDCTL), defreg(WUFC),
+ defreg(RA), defreg(MTA), defreg(CRCERRS),defreg(VFTA),
+ defreg(VET), defreg(RDTR), defreg(RADV), defreg(TADV),
+ defreg(ITR),
+};
+
+
+typedef struct E1000Info {
+ const char *name;
+ uint16_t device_id;
+ uint8_t revision;
+ uint8_t io_bar;
+ uint16_t phy_id2;
+} E1000Info;
+
+
+void e1000_class_init(ObjectClass *klass, void *data);
+
+int pci_e1000_init(PCIDevice *pci_dev);
+void pci_e1000_uninit(PCIDevice *dev);
+void e1000_reset(void *opaque);
--
1.9.0