1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "qemu/osdep.h"
21#include "hw/net/igb_regs.h"
22#include "hw/net/mii.h"
23#include "hw/pci/pci_ids.h"
24#include "../libqtest.h"
25#include "pci-pc.h"
26#include "qemu/sockets.h"
27#include "qemu/iov.h"
28#include "qemu/module.h"
29#include "qemu/bitops.h"
30#include "libqos-malloc.h"
31#include "qgraph.h"
32#include "e1000e.h"
33
34#define IGB_IVAR_TEST_CFG \
35 ((E1000E_RX0_MSG_ID | E1000_IVAR_VALID) << (igb_ivar_entry_rx(0) * 8) | \
36 ((E1000E_TX0_MSG_ID | E1000_IVAR_VALID) << (igb_ivar_entry_tx(0) * 8)))
37
38#define E1000E_RING_LEN (0x1000)
39
40static void e1000e_foreach_callback(QPCIDevice *dev, int devfn, void *data)
41{
42 QPCIDevice *res = data;
43 memcpy(res, dev, sizeof(QPCIDevice));
44 g_free(dev);
45}
46
47static void e1000e_pci_destructor(QOSGraphObject *obj)
48{
49 QE1000E_PCI *epci = (QE1000E_PCI *) obj;
50 qpci_iounmap(&epci->pci_dev, epci->mac_regs);
51 qpci_msix_disable(&epci->pci_dev);
52}
53
54static void igb_pci_start_hw(QOSGraphObject *obj)
55{
56 static const uint8_t address[] = E1000E_ADDRESS;
57 QE1000E_PCI *d = (QE1000E_PCI *) obj;
58 uint32_t val;
59
60
61 qpci_device_enable(&d->pci_dev);
62
63
64 val = e1000e_macreg_read(&d->e1000e, E1000_CTRL);
65 e1000e_macreg_write(&d->e1000e, E1000_CTRL, val | E1000_CTRL_RST | E1000_CTRL_SLU);
66
67
68 e1000e_macreg_write(&d->e1000e, E1000_MDIC,
69 MII_BMCR_AUTOEN | MII_BMCR_ANRESTART |
70 (MII_BMCR << E1000_MDIC_REG_SHIFT) |
71 (1 << E1000_MDIC_PHY_SHIFT) |
72 E1000_MDIC_OP_WRITE);
73
74 qtest_clock_step(d->pci_dev.bus->qts, 900000000);
75
76
77 qpci_msix_enable(&d->pci_dev);
78 e1000e_macreg_write(&d->e1000e, E1000_IVAR0, IGB_IVAR_TEST_CFG);
79
80
81 val = e1000e_macreg_read(&d->e1000e, E1000_STATUS);
82 g_assert_cmphex(val & E1000_STATUS_LU, ==, E1000_STATUS_LU);
83
84
85 e1000e_macreg_write(&d->e1000e, E1000_RCTL, 0);
86 e1000e_macreg_write(&d->e1000e, E1000_TCTL, 0);
87
88 e1000e_macreg_write(&d->e1000e, E1000_TDBAL(0),
89 (uint32_t) d->e1000e.tx_ring);
90 e1000e_macreg_write(&d->e1000e, E1000_TDBAH(0),
91 (uint32_t) (d->e1000e.tx_ring >> 32));
92 e1000e_macreg_write(&d->e1000e, E1000_TDLEN(0), E1000E_RING_LEN);
93 e1000e_macreg_write(&d->e1000e, E1000_TDT(0), 0);
94 e1000e_macreg_write(&d->e1000e, E1000_TDH(0), 0);
95
96
97 e1000e_macreg_write(&d->e1000e, E1000_TCTL, E1000_TCTL_EN);
98
99 e1000e_macreg_write(&d->e1000e, E1000_RDBAL(0),
100 (uint32_t)d->e1000e.rx_ring);
101 e1000e_macreg_write(&d->e1000e, E1000_RDBAH(0),
102 (uint32_t)(d->e1000e.rx_ring >> 32));
103 e1000e_macreg_write(&d->e1000e, E1000_RDLEN(0), E1000E_RING_LEN);
104 e1000e_macreg_write(&d->e1000e, E1000_RDT(0), 0);
105 e1000e_macreg_write(&d->e1000e, E1000_RDH(0), 0);
106 e1000e_macreg_write(&d->e1000e, E1000_RA,
107 le32_to_cpu(*(uint32_t *)address));
108 e1000e_macreg_write(&d->e1000e, E1000_RA + 4,
109 E1000_RAH_AV | E1000_RAH_POOL_1 |
110 le16_to_cpu(*(uint16_t *)(address + 4)));
111
112
113 e1000e_macreg_write(&d->e1000e, E1000_RFCTL, E1000_RFCTL_EXTEN);
114 e1000e_macreg_write(&d->e1000e, E1000_RCTL, E1000_RCTL_EN);
115
116
117 e1000e_macreg_write(&d->e1000e, E1000_IMS, 0xFFFFFFFF);
118 e1000e_macreg_write(&d->e1000e, E1000_EIMS, 0xFFFFFFFF);
119
120}
121
122static void *igb_pci_get_driver(void *obj, const char *interface)
123{
124 QE1000E_PCI *epci = obj;
125 if (!g_strcmp0(interface, "igb-if")) {
126 return &epci->e1000e;
127 }
128
129
130 if (!g_strcmp0(interface, "pci-device")) {
131 return &epci->pci_dev;
132 }
133
134 fprintf(stderr, "%s not present in igb\n", interface);
135 g_assert_not_reached();
136}
137
138static void *igb_pci_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
139{
140 QE1000E_PCI *d = g_new0(QE1000E_PCI, 1);
141 QPCIBus *bus = pci_bus;
142 QPCIAddress *address = addr;
143
144 qpci_device_foreach(bus, address->vendor_id, address->device_id,
145 e1000e_foreach_callback, &d->pci_dev);
146
147
148 d->mac_regs = qpci_iomap(&d->pci_dev, 0, NULL);
149
150
151 d->e1000e.tx_ring = guest_alloc(alloc, E1000E_RING_LEN);
152 g_assert(d->e1000e.tx_ring != 0);
153
154
155 d->e1000e.rx_ring = guest_alloc(alloc, E1000E_RING_LEN);
156 g_assert(d->e1000e.rx_ring != 0);
157
158 d->obj.get_driver = igb_pci_get_driver;
159 d->obj.start_hw = igb_pci_start_hw;
160 d->obj.destructor = e1000e_pci_destructor;
161
162 return &d->obj;
163}
164
165static void igb_register_nodes(void)
166{
167 QPCIAddress addr = {
168 .vendor_id = PCI_VENDOR_ID_INTEL,
169 .device_id = E1000_DEV_ID_82576,
170 };
171
172
173
174
175
176 QOSGraphEdgeOptions opts = {
177 .extra_device_opts = "netdev=hs0",
178 };
179 add_qpci_address(&opts, &addr);
180
181 qos_node_create_driver("igb", igb_pci_create);
182 qos_node_consumes("igb", "pci-bus", &opts);
183}
184
185libqos_init(igb_register_nodes);
186